From d383f2bcdb6ff13cc562fce1ff55d826035debad Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Mon, 6 Mar 2023 17:36:31 +0100 Subject: Simplify source tree Now just use make in the root directory to build. --- .gitignore | 3 + AT91SAM7S256/SAM7S256/Include/AT91SAM7S256.h | 1920 ----- AT91SAM7S256/SAM7S256/Include/Cstartup.S | 477 -- AT91SAM7S256/SAM7S256/Include/Cstartup_SAM7.c | 93 - AT91SAM7S256/SAM7S256/Include/sam7s256.c | 34 - AT91SAM7S256/SAM7S256/Include/sam7s256.h | 64 - AT91SAM7S256/SAM7S256/gcc/.gitignore | 3 - AT91SAM7S256/SAM7S256/gcc/Makefile | 114 - AT91SAM7S256/SAM7S256/gcc/lib/abort.c | 32 - AT91SAM7S256/SAM7S256/gcc/lib/errno.c | 32 - AT91SAM7S256/SAM7S256/gcc/lib/sbrk.c | 44 - AT91SAM7S256/SAM7S256/gcc/lib/sscanf.c | 49 - AT91SAM7S256/SAM7S256/gcc/lib/strtod.c | 257 - AT91SAM7S256/SAM7S256/gcc/nxt.ld | 167 - AT91SAM7S256/Source/BtTest.inc | 1613 ---- AT91SAM7S256/Source/Connections.txt | 23 - AT91SAM7S256/Source/Cursor.txt | 13 - AT91SAM7S256/Source/Devices.txt | 23 - AT91SAM7S256/Source/Display.txt | 14 - AT91SAM7S256/Source/Fail.txt | 14 - AT91SAM7S256/Source/Font.txt | 17 - AT91SAM7S256/Source/Functions.inl | 4331 ----------- AT91SAM7S256/Source/Icons.txt | 293 - AT91SAM7S256/Source/Info.txt | 14 - AT91SAM7S256/Source/LowBattery.txt | 18 - AT91SAM7S256/Source/Mainmenu.rms | 72 - AT91SAM7S256/Source/Ok.txt | 13 - AT91SAM7S256/Source/Port.txt | 12 - AT91SAM7S256/Source/RCXintro_1.txt | 19 - AT91SAM7S256/Source/RCXintro_10.txt | 13 - AT91SAM7S256/Source/RCXintro_11.txt | 13 - AT91SAM7S256/Source/RCXintro_12.txt | 13 - AT91SAM7S256/Source/RCXintro_13.txt | 13 - AT91SAM7S256/Source/RCXintro_14.txt | 13 - AT91SAM7S256/Source/RCXintro_15.txt | 13 - AT91SAM7S256/Source/RCXintro_16.txt | 13 - AT91SAM7S256/Source/RCXintro_2.txt | 19 - AT91SAM7S256/Source/RCXintro_3.txt | 19 - AT91SAM7S256/Source/RCXintro_4.txt | 19 - AT91SAM7S256/Source/RCXintro_5.txt | 19 - AT91SAM7S256/Source/RCXintro_6.txt | 17 - AT91SAM7S256/Source/RCXintro_7.txt | 16 - AT91SAM7S256/Source/RCXintro_8.txt | 14 - AT91SAM7S256/Source/RCXintro_9.txt | 14 - AT91SAM7S256/Source/Running.txt | 59 - AT91SAM7S256/Source/Status.txt | 17 - AT91SAM7S256/Source/Step.txt | 19 - AT91SAM7S256/Source/Submenu01.rms | 128 - AT91SAM7S256/Source/Submenu02.rms | 401 - AT91SAM7S256/Source/Submenu03.rms | 233 - AT91SAM7S256/Source/Submenu04.rms | 163 - AT91SAM7S256/Source/Submenu05.rms | 128 - AT91SAM7S256/Source/Submenu06.rms | 51 - AT91SAM7S256/Source/Submenu07.rms | 142 - AT91SAM7S256/Source/Test1.txt | 19 - AT91SAM7S256/Source/Test2.txt | 19 - AT91SAM7S256/Source/Ui.txt | 72 - AT91SAM7S256/Source/Wait.txt | 14 - AT91SAM7S256/Source/c_button.c | 134 - AT91SAM7S256/Source/c_button.h | 37 - AT91SAM7S256/Source/c_button.iom | 61 - AT91SAM7S256/Source/c_cmd.c | 8020 -------------------- AT91SAM7S256/Source/c_cmd.h | 885 --- AT91SAM7S256/Source/c_cmd.iom | 202 - AT91SAM7S256/Source/c_cmd_bytecodes.h | 119 - AT91SAM7S256/Source/c_cmd_drawing.inc | 894 --- AT91SAM7S256/Source/c_comm.c | 3714 --------- AT91SAM7S256/Source/c_comm.h | 154 - AT91SAM7S256/Source/c_comm.iom | 223 - AT91SAM7S256/Source/c_display.c | 849 --- AT91SAM7S256/Source/c_display.h | 43 - AT91SAM7S256/Source/c_display.iom | 177 - AT91SAM7S256/Source/c_input.c | 1335 ---- AT91SAM7S256/Source/c_input.h | 67 - AT91SAM7S256/Source/c_input.iom | 175 - AT91SAM7S256/Source/c_ioctrl.c | 78 - AT91SAM7S256/Source/c_ioctrl.h | 28 - AT91SAM7S256/Source/c_ioctrl.iom | 35 - AT91SAM7S256/Source/c_loader.c | 464 -- AT91SAM7S256/Source/c_loader.h | 44 - AT91SAM7S256/Source/c_loader.iom | 85 - AT91SAM7S256/Source/c_lowspeed.c | 236 - AT91SAM7S256/Source/c_lowspeed.h | 61 - AT91SAM7S256/Source/c_lowspeed.iom | 95 - AT91SAM7S256/Source/c_output.c | 180 - AT91SAM7S256/Source/c_output.h | 31 - AT91SAM7S256/Source/c_output.iom | 94 - AT91SAM7S256/Source/c_sound.c | 309 - AT91SAM7S256/Source/c_sound.h | 44 - AT91SAM7S256/Source/c_sound.iom | 109 - AT91SAM7S256/Source/c_ui.c | 1944 ----- AT91SAM7S256/Source/c_ui.h | 387 - AT91SAM7S256/Source/c_ui.iom | 127 - AT91SAM7S256/Source/config.h | 10 - AT91SAM7S256/Source/d_bt.c | 452 -- AT91SAM7S256/Source/d_bt.h | 39 - AT91SAM7S256/Source/d_bt.r | 347 - AT91SAM7S256/Source/d_button.c | 36 - AT91SAM7S256/Source/d_button.h | 24 - AT91SAM7S256/Source/d_button.r | 189 - AT91SAM7S256/Source/d_display.c | 53 - AT91SAM7S256/Source/d_display.h | 39 - AT91SAM7S256/Source/d_display.r | 374 - AT91SAM7S256/Source/d_hispeed.c | 48 - AT91SAM7S256/Source/d_hispeed.h | 25 - AT91SAM7S256/Source/d_hispeed.r | 190 - AT91SAM7S256/Source/d_input.c | 152 - AT91SAM7S256/Source/d_input.h | 48 - AT91SAM7S256/Source/d_input.r | 312 - AT91SAM7S256/Source/d_ioctrl.c | 47 - AT91SAM7S256/Source/d_ioctrl.h | 25 - AT91SAM7S256/Source/d_ioctrl.r | 237 - AT91SAM7S256/Source/d_loader.c | 1480 ---- AT91SAM7S256/Source/d_loader.h | 109 - AT91SAM7S256/Source/d_loader.r | 117 - AT91SAM7S256/Source/d_lowspeed.c | 77 - AT91SAM7S256/Source/d_lowspeed.h | 28 - AT91SAM7S256/Source/d_lowspeed.r | 612 -- AT91SAM7S256/Source/d_output.c | 1415 ---- AT91SAM7S256/Source/d_output.h | 103 - AT91SAM7S256/Source/d_output.r | 306 - AT91SAM7S256/Source/d_sound.c | 70 - AT91SAM7S256/Source/d_sound.h | 42 - AT91SAM7S256/Source/d_sound.r | 515 -- AT91SAM7S256/Source/d_sound_adpcm.r | 158 - AT91SAM7S256/Source/d_timer.c | 62 - AT91SAM7S256/Source/d_timer.h | 32 - AT91SAM7S256/Source/d_timer.r | 76 - AT91SAM7S256/Source/d_usb.c | 946 --- AT91SAM7S256/Source/d_usb.h | 51 - AT91SAM7S256/Source/d_usb.r | 65 - AT91SAM7S256/Source/m_sched.c | 94 - AT91SAM7S256/Source/m_sched.h | 135 - AT91SAM7S256/Source/modules.h | 338 - AT91SAM7S256/Source/stdconst.h | 74 - AT91SAM7S256/armdebug/.gitignore | 41 - AT91SAM7S256/armdebug/.project | 11 - AT91SAM7S256/armdebug/AUTHORS | 6 - AT91SAM7S256/armdebug/COPYING | 9 - AT91SAM7S256/armdebug/Debugger/_c_arm_macros.h | 88 - AT91SAM7S256/armdebug/Debugger/abort_handler.S | 106 - AT91SAM7S256/armdebug/Debugger/debug_comm.S | 550 -- AT91SAM7S256/armdebug/Debugger/debug_hexutils.S | 459 -- AT91SAM7S256/armdebug/Debugger/debug_internals.h | 395 - AT91SAM7S256/armdebug/Debugger/debug_macros.h | 463 -- AT91SAM7S256/armdebug/Debugger/debug_opcodes.S | 1031 --- .../armdebug/Debugger/debug_runlooptasks.S | 411 - .../armdebug/Debugger/debug_runlooptasks.h | 81 - AT91SAM7S256/armdebug/Debugger/debug_stack.ld | 15 - AT91SAM7S256/armdebug/Debugger/debug_stub.S | 1579 ---- AT91SAM7S256/armdebug/Debugger/debug_stub.h | 165 - AT91SAM7S256/armdebug/Debugger/debug_test.S | 161 - AT91SAM7S256/armdebug/Debugger/debug_test.h | 50 - AT91SAM7S256/armdebug/Debugger/undef_handler.S | 144 - AT91SAM7S256/armdebug/Doxyfile | 243 - AT91SAM7S256/armdebug/GNU-GPLv2.txt | 340 - AT91SAM7S256/armdebug/Host/README | 26 - AT91SAM7S256/armdebug/Host/gdb-commands.txt | 43 - AT91SAM7S256/armdebug/Host/nxt-gdb-server.py | 254 - AT91SAM7S256/armdebug/LEGO_Open_Source_License.doc | Bin 40960 -> 0 bytes AT91SAM7S256/armdebug/README | 16 - AT91SAM7S256/armdebug/SConscript | 13 - AT91SAM7S256/armdebug/SConstruct | 182 - Makefile | 116 + README | 6 +- armdebug/.gitignore | 41 + armdebug/.project | 11 + armdebug/AUTHORS | 6 + armdebug/COPYING | 9 + armdebug/Debugger/_c_arm_macros.h | 88 + armdebug/Debugger/abort_handler.S | 106 + armdebug/Debugger/debug_comm.S | 550 ++ armdebug/Debugger/debug_hexutils.S | 459 ++ armdebug/Debugger/debug_internals.h | 395 + armdebug/Debugger/debug_macros.h | 463 ++ armdebug/Debugger/debug_opcodes.S | 1031 +++ armdebug/Debugger/debug_runlooptasks.S | 411 + armdebug/Debugger/debug_runlooptasks.h | 81 + armdebug/Debugger/debug_stack.ld | 15 + armdebug/Debugger/debug_stub.S | 1579 ++++ armdebug/Debugger/debug_stub.h | 165 + armdebug/Debugger/debug_test.S | 161 + armdebug/Debugger/debug_test.h | 50 + armdebug/Debugger/undef_handler.S | 144 + armdebug/Doxyfile | 243 + armdebug/GNU-GPLv2.txt | 340 + armdebug/Host/README | 26 + armdebug/Host/gdb-commands.txt | 43 + armdebug/Host/nxt-gdb-server.py | 254 + armdebug/LEGO_Open_Source_License.doc | Bin 0 -> 40960 bytes armdebug/README | 16 + armdebug/SConscript | 13 + armdebug/SConstruct | 182 + include/AT91SAM7S256.h | 1920 +++++ lib/abort.c | 32 + lib/errno.c | 32 + lib/nxt.ld | 167 + lib/sbrk.c | 44 + lib/sscanf.c | 49 + lib/strtod.c | 257 + src/BtTest.inc | 1613 ++++ src/Connections.txt | 23 + src/Cursor.txt | 13 + src/Devices.txt | 23 + src/Display.txt | 14 + src/Fail.txt | 14 + src/Font.txt | 17 + src/Functions.inl | 4331 +++++++++++ src/Icons.txt | 293 + src/Info.txt | 14 + src/LowBattery.txt | 18 + src/Mainmenu.rms | 72 + src/Ok.txt | 13 + src/Port.txt | 12 + src/RCXintro_1.txt | 19 + src/RCXintro_10.txt | 13 + src/RCXintro_11.txt | 13 + src/RCXintro_12.txt | 13 + src/RCXintro_13.txt | 13 + src/RCXintro_14.txt | 13 + src/RCXintro_15.txt | 13 + src/RCXintro_16.txt | 13 + src/RCXintro_2.txt | 19 + src/RCXintro_3.txt | 19 + src/RCXintro_4.txt | 19 + src/RCXintro_5.txt | 19 + src/RCXintro_6.txt | 17 + src/RCXintro_7.txt | 16 + src/RCXintro_8.txt | 14 + src/RCXintro_9.txt | 14 + src/Running.txt | 59 + src/Status.txt | 17 + src/Step.txt | 19 + src/Submenu01.rms | 128 + src/Submenu02.rms | 401 + src/Submenu03.rms | 233 + src/Submenu04.rms | 163 + src/Submenu05.rms | 128 + src/Submenu06.rms | 51 + src/Submenu07.rms | 142 + src/Test1.txt | 19 + src/Test2.txt | 19 + src/Ui.txt | 72 + src/Wait.txt | 14 + src/c_button.c | 134 + src/c_button.h | 37 + src/c_button.iom | 61 + src/c_cmd.c | 8020 ++++++++++++++++++++ src/c_cmd.h | 885 +++ src/c_cmd.iom | 202 + src/c_cmd_bytecodes.h | 119 + src/c_cmd_drawing.inc | 894 +++ src/c_comm.c | 3714 +++++++++ src/c_comm.h | 154 + src/c_comm.iom | 223 + src/c_display.c | 849 +++ src/c_display.h | 43 + src/c_display.iom | 177 + src/c_input.c | 1335 ++++ src/c_input.h | 67 + src/c_input.iom | 175 + src/c_ioctrl.c | 78 + src/c_ioctrl.h | 28 + src/c_ioctrl.iom | 35 + src/c_loader.c | 464 ++ src/c_loader.h | 44 + src/c_loader.iom | 85 + src/c_lowspeed.c | 236 + src/c_lowspeed.h | 61 + src/c_lowspeed.iom | 95 + src/c_output.c | 180 + src/c_output.h | 31 + src/c_output.iom | 94 + src/c_sound.c | 309 + src/c_sound.h | 44 + src/c_sound.iom | 109 + src/c_ui.c | 1944 +++++ src/c_ui.h | 387 + src/c_ui.iom | 127 + src/config.h | 10 + src/d_bt.c | 452 ++ src/d_bt.h | 39 + src/d_bt.r | 347 + src/d_button.c | 36 + src/d_button.h | 24 + src/d_button.r | 189 + src/d_display.c | 53 + src/d_display.h | 39 + src/d_display.r | 374 + src/d_hispeed.c | 48 + src/d_hispeed.h | 25 + src/d_hispeed.r | 190 + src/d_input.c | 152 + src/d_input.h | 48 + src/d_input.r | 312 + src/d_ioctrl.c | 47 + src/d_ioctrl.h | 25 + src/d_ioctrl.r | 237 + src/d_loader.c | 1480 ++++ src/d_loader.h | 109 + src/d_loader.r | 117 + src/d_lowspeed.c | 77 + src/d_lowspeed.h | 28 + src/d_lowspeed.r | 612 ++ src/d_output.c | 1415 ++++ src/d_output.h | 103 + src/d_output.r | 306 + src/d_sound.c | 70 + src/d_sound.h | 42 + src/d_sound.r | 515 ++ src/d_sound_adpcm.r | 158 + src/d_timer.c | 62 + src/d_timer.h | 32 + src/d_timer.r | 76 + src/d_usb.c | 946 +++ src/d_usb.h | 51 + src/d_usb.r | 65 + src/m_sched.c | 94 + src/m_sched.h | 135 + src/modules.h | 338 + src/sam7s256.c | 34 + src/sam7s256.h | 64 + src/stdconst.h | 74 + startup/Cstartup.S | 477 ++ startup/Cstartup_SAM7.c | 93 + 325 files changed, 49347 insertions(+), 49345 deletions(-) delete mode 100644 AT91SAM7S256/SAM7S256/Include/AT91SAM7S256.h delete mode 100644 AT91SAM7S256/SAM7S256/Include/Cstartup.S delete mode 100644 AT91SAM7S256/SAM7S256/Include/Cstartup_SAM7.c delete mode 100644 AT91SAM7S256/SAM7S256/Include/sam7s256.c delete mode 100644 AT91SAM7S256/SAM7S256/Include/sam7s256.h delete mode 100644 AT91SAM7S256/SAM7S256/gcc/.gitignore delete mode 100644 AT91SAM7S256/SAM7S256/gcc/Makefile delete mode 100644 AT91SAM7S256/SAM7S256/gcc/lib/abort.c delete mode 100644 AT91SAM7S256/SAM7S256/gcc/lib/errno.c delete mode 100644 AT91SAM7S256/SAM7S256/gcc/lib/sbrk.c delete mode 100644 AT91SAM7S256/SAM7S256/gcc/lib/sscanf.c delete mode 100644 AT91SAM7S256/SAM7S256/gcc/lib/strtod.c delete mode 100644 AT91SAM7S256/SAM7S256/gcc/nxt.ld delete mode 100644 AT91SAM7S256/Source/BtTest.inc delete mode 100644 AT91SAM7S256/Source/Connections.txt delete mode 100644 AT91SAM7S256/Source/Cursor.txt delete mode 100644 AT91SAM7S256/Source/Devices.txt delete mode 100644 AT91SAM7S256/Source/Display.txt delete mode 100644 AT91SAM7S256/Source/Fail.txt delete mode 100644 AT91SAM7S256/Source/Font.txt delete mode 100644 AT91SAM7S256/Source/Functions.inl delete mode 100644 AT91SAM7S256/Source/Icons.txt delete mode 100644 AT91SAM7S256/Source/Info.txt delete mode 100644 AT91SAM7S256/Source/LowBattery.txt delete mode 100644 AT91SAM7S256/Source/Mainmenu.rms delete mode 100644 AT91SAM7S256/Source/Ok.txt delete mode 100644 AT91SAM7S256/Source/Port.txt delete mode 100644 AT91SAM7S256/Source/RCXintro_1.txt delete mode 100644 AT91SAM7S256/Source/RCXintro_10.txt delete mode 100644 AT91SAM7S256/Source/RCXintro_11.txt delete mode 100644 AT91SAM7S256/Source/RCXintro_12.txt delete mode 100644 AT91SAM7S256/Source/RCXintro_13.txt delete mode 100644 AT91SAM7S256/Source/RCXintro_14.txt delete mode 100644 AT91SAM7S256/Source/RCXintro_15.txt delete mode 100644 AT91SAM7S256/Source/RCXintro_16.txt delete mode 100644 AT91SAM7S256/Source/RCXintro_2.txt delete mode 100644 AT91SAM7S256/Source/RCXintro_3.txt delete mode 100644 AT91SAM7S256/Source/RCXintro_4.txt delete mode 100644 AT91SAM7S256/Source/RCXintro_5.txt delete mode 100644 AT91SAM7S256/Source/RCXintro_6.txt delete mode 100644 AT91SAM7S256/Source/RCXintro_7.txt delete mode 100644 AT91SAM7S256/Source/RCXintro_8.txt delete mode 100644 AT91SAM7S256/Source/RCXintro_9.txt delete mode 100644 AT91SAM7S256/Source/Running.txt delete mode 100644 AT91SAM7S256/Source/Status.txt delete mode 100644 AT91SAM7S256/Source/Step.txt delete mode 100644 AT91SAM7S256/Source/Submenu01.rms delete mode 100644 AT91SAM7S256/Source/Submenu02.rms delete mode 100644 AT91SAM7S256/Source/Submenu03.rms delete mode 100644 AT91SAM7S256/Source/Submenu04.rms delete mode 100644 AT91SAM7S256/Source/Submenu05.rms delete mode 100644 AT91SAM7S256/Source/Submenu06.rms delete mode 100644 AT91SAM7S256/Source/Submenu07.rms delete mode 100644 AT91SAM7S256/Source/Test1.txt delete mode 100644 AT91SAM7S256/Source/Test2.txt delete mode 100644 AT91SAM7S256/Source/Ui.txt delete mode 100644 AT91SAM7S256/Source/Wait.txt delete mode 100644 AT91SAM7S256/Source/c_button.c delete mode 100644 AT91SAM7S256/Source/c_button.h delete mode 100644 AT91SAM7S256/Source/c_button.iom delete mode 100644 AT91SAM7S256/Source/c_cmd.c delete mode 100644 AT91SAM7S256/Source/c_cmd.h delete mode 100644 AT91SAM7S256/Source/c_cmd.iom delete mode 100644 AT91SAM7S256/Source/c_cmd_bytecodes.h delete mode 100644 AT91SAM7S256/Source/c_cmd_drawing.inc delete mode 100644 AT91SAM7S256/Source/c_comm.c delete mode 100644 AT91SAM7S256/Source/c_comm.h delete mode 100644 AT91SAM7S256/Source/c_comm.iom delete mode 100644 AT91SAM7S256/Source/c_display.c delete mode 100644 AT91SAM7S256/Source/c_display.h delete mode 100644 AT91SAM7S256/Source/c_display.iom delete mode 100644 AT91SAM7S256/Source/c_input.c delete mode 100644 AT91SAM7S256/Source/c_input.h delete mode 100644 AT91SAM7S256/Source/c_input.iom delete mode 100644 AT91SAM7S256/Source/c_ioctrl.c delete mode 100644 AT91SAM7S256/Source/c_ioctrl.h delete mode 100644 AT91SAM7S256/Source/c_ioctrl.iom delete mode 100644 AT91SAM7S256/Source/c_loader.c delete mode 100644 AT91SAM7S256/Source/c_loader.h delete mode 100644 AT91SAM7S256/Source/c_loader.iom delete mode 100644 AT91SAM7S256/Source/c_lowspeed.c delete mode 100644 AT91SAM7S256/Source/c_lowspeed.h delete mode 100644 AT91SAM7S256/Source/c_lowspeed.iom delete mode 100644 AT91SAM7S256/Source/c_output.c delete mode 100644 AT91SAM7S256/Source/c_output.h delete mode 100644 AT91SAM7S256/Source/c_output.iom delete mode 100644 AT91SAM7S256/Source/c_sound.c delete mode 100644 AT91SAM7S256/Source/c_sound.h delete mode 100644 AT91SAM7S256/Source/c_sound.iom delete mode 100644 AT91SAM7S256/Source/c_ui.c delete mode 100644 AT91SAM7S256/Source/c_ui.h delete mode 100644 AT91SAM7S256/Source/c_ui.iom delete mode 100644 AT91SAM7S256/Source/config.h delete mode 100644 AT91SAM7S256/Source/d_bt.c delete mode 100644 AT91SAM7S256/Source/d_bt.h delete mode 100644 AT91SAM7S256/Source/d_bt.r delete mode 100644 AT91SAM7S256/Source/d_button.c delete mode 100644 AT91SAM7S256/Source/d_button.h delete mode 100644 AT91SAM7S256/Source/d_button.r delete mode 100644 AT91SAM7S256/Source/d_display.c delete mode 100644 AT91SAM7S256/Source/d_display.h delete mode 100644 AT91SAM7S256/Source/d_display.r delete mode 100644 AT91SAM7S256/Source/d_hispeed.c delete mode 100644 AT91SAM7S256/Source/d_hispeed.h delete mode 100644 AT91SAM7S256/Source/d_hispeed.r delete mode 100644 AT91SAM7S256/Source/d_input.c delete mode 100644 AT91SAM7S256/Source/d_input.h delete mode 100644 AT91SAM7S256/Source/d_input.r delete mode 100644 AT91SAM7S256/Source/d_ioctrl.c delete mode 100644 AT91SAM7S256/Source/d_ioctrl.h delete mode 100644 AT91SAM7S256/Source/d_ioctrl.r delete mode 100644 AT91SAM7S256/Source/d_loader.c delete mode 100644 AT91SAM7S256/Source/d_loader.h delete mode 100644 AT91SAM7S256/Source/d_loader.r delete mode 100644 AT91SAM7S256/Source/d_lowspeed.c delete mode 100644 AT91SAM7S256/Source/d_lowspeed.h delete mode 100644 AT91SAM7S256/Source/d_lowspeed.r delete mode 100644 AT91SAM7S256/Source/d_output.c delete mode 100644 AT91SAM7S256/Source/d_output.h delete mode 100644 AT91SAM7S256/Source/d_output.r delete mode 100644 AT91SAM7S256/Source/d_sound.c delete mode 100644 AT91SAM7S256/Source/d_sound.h delete mode 100644 AT91SAM7S256/Source/d_sound.r delete mode 100644 AT91SAM7S256/Source/d_sound_adpcm.r delete mode 100644 AT91SAM7S256/Source/d_timer.c delete mode 100644 AT91SAM7S256/Source/d_timer.h delete mode 100644 AT91SAM7S256/Source/d_timer.r delete mode 100644 AT91SAM7S256/Source/d_usb.c delete mode 100644 AT91SAM7S256/Source/d_usb.h delete mode 100644 AT91SAM7S256/Source/d_usb.r delete mode 100644 AT91SAM7S256/Source/m_sched.c delete mode 100644 AT91SAM7S256/Source/m_sched.h delete mode 100644 AT91SAM7S256/Source/modules.h delete mode 100644 AT91SAM7S256/Source/stdconst.h delete mode 100644 AT91SAM7S256/armdebug/.gitignore delete mode 100644 AT91SAM7S256/armdebug/.project delete mode 100644 AT91SAM7S256/armdebug/AUTHORS delete mode 100644 AT91SAM7S256/armdebug/COPYING delete mode 100644 AT91SAM7S256/armdebug/Debugger/_c_arm_macros.h delete mode 100644 AT91SAM7S256/armdebug/Debugger/abort_handler.S delete mode 100644 AT91SAM7S256/armdebug/Debugger/debug_comm.S delete mode 100644 AT91SAM7S256/armdebug/Debugger/debug_hexutils.S delete mode 100644 AT91SAM7S256/armdebug/Debugger/debug_internals.h delete mode 100644 AT91SAM7S256/armdebug/Debugger/debug_macros.h delete mode 100644 AT91SAM7S256/armdebug/Debugger/debug_opcodes.S delete mode 100644 AT91SAM7S256/armdebug/Debugger/debug_runlooptasks.S delete mode 100644 AT91SAM7S256/armdebug/Debugger/debug_runlooptasks.h delete mode 100644 AT91SAM7S256/armdebug/Debugger/debug_stack.ld delete mode 100644 AT91SAM7S256/armdebug/Debugger/debug_stub.S delete mode 100644 AT91SAM7S256/armdebug/Debugger/debug_stub.h delete mode 100644 AT91SAM7S256/armdebug/Debugger/debug_test.S delete mode 100644 AT91SAM7S256/armdebug/Debugger/debug_test.h delete mode 100644 AT91SAM7S256/armdebug/Debugger/undef_handler.S delete mode 100644 AT91SAM7S256/armdebug/Doxyfile delete mode 100644 AT91SAM7S256/armdebug/GNU-GPLv2.txt delete mode 100644 AT91SAM7S256/armdebug/Host/README delete mode 100644 AT91SAM7S256/armdebug/Host/gdb-commands.txt delete mode 100755 AT91SAM7S256/armdebug/Host/nxt-gdb-server.py delete mode 100644 AT91SAM7S256/armdebug/LEGO_Open_Source_License.doc delete mode 100644 AT91SAM7S256/armdebug/README delete mode 100644 AT91SAM7S256/armdebug/SConscript delete mode 100644 AT91SAM7S256/armdebug/SConstruct create mode 100644 Makefile create mode 100644 armdebug/.gitignore create mode 100644 armdebug/.project create mode 100644 armdebug/AUTHORS create mode 100644 armdebug/COPYING create mode 100644 armdebug/Debugger/_c_arm_macros.h create mode 100644 armdebug/Debugger/abort_handler.S create mode 100644 armdebug/Debugger/debug_comm.S create mode 100644 armdebug/Debugger/debug_hexutils.S create mode 100644 armdebug/Debugger/debug_internals.h create mode 100644 armdebug/Debugger/debug_macros.h create mode 100644 armdebug/Debugger/debug_opcodes.S create mode 100644 armdebug/Debugger/debug_runlooptasks.S create mode 100644 armdebug/Debugger/debug_runlooptasks.h create mode 100644 armdebug/Debugger/debug_stack.ld create mode 100644 armdebug/Debugger/debug_stub.S create mode 100644 armdebug/Debugger/debug_stub.h create mode 100644 armdebug/Debugger/debug_test.S create mode 100644 armdebug/Debugger/debug_test.h create mode 100644 armdebug/Debugger/undef_handler.S create mode 100644 armdebug/Doxyfile create mode 100644 armdebug/GNU-GPLv2.txt create mode 100644 armdebug/Host/README create mode 100644 armdebug/Host/gdb-commands.txt create mode 100755 armdebug/Host/nxt-gdb-server.py create mode 100644 armdebug/LEGO_Open_Source_License.doc create mode 100644 armdebug/README create mode 100644 armdebug/SConscript create mode 100644 armdebug/SConstruct create mode 100644 include/AT91SAM7S256.h create mode 100644 lib/abort.c create mode 100644 lib/errno.c create mode 100644 lib/nxt.ld create mode 100644 lib/sbrk.c create mode 100644 lib/sscanf.c create mode 100644 lib/strtod.c create mode 100644 src/BtTest.inc create mode 100644 src/Connections.txt create mode 100644 src/Cursor.txt create mode 100644 src/Devices.txt create mode 100644 src/Display.txt create mode 100644 src/Fail.txt create mode 100644 src/Font.txt create mode 100644 src/Functions.inl create mode 100644 src/Icons.txt create mode 100644 src/Info.txt create mode 100644 src/LowBattery.txt create mode 100644 src/Mainmenu.rms create mode 100644 src/Ok.txt create mode 100644 src/Port.txt create mode 100644 src/RCXintro_1.txt create mode 100644 src/RCXintro_10.txt create mode 100644 src/RCXintro_11.txt create mode 100644 src/RCXintro_12.txt create mode 100644 src/RCXintro_13.txt create mode 100644 src/RCXintro_14.txt create mode 100644 src/RCXintro_15.txt create mode 100644 src/RCXintro_16.txt create mode 100644 src/RCXintro_2.txt create mode 100644 src/RCXintro_3.txt create mode 100644 src/RCXintro_4.txt create mode 100644 src/RCXintro_5.txt create mode 100644 src/RCXintro_6.txt create mode 100644 src/RCXintro_7.txt create mode 100644 src/RCXintro_8.txt create mode 100644 src/RCXintro_9.txt create mode 100644 src/Running.txt create mode 100644 src/Status.txt create mode 100644 src/Step.txt create mode 100644 src/Submenu01.rms create mode 100644 src/Submenu02.rms create mode 100644 src/Submenu03.rms create mode 100644 src/Submenu04.rms create mode 100644 src/Submenu05.rms create mode 100644 src/Submenu06.rms create mode 100644 src/Submenu07.rms create mode 100644 src/Test1.txt create mode 100644 src/Test2.txt create mode 100644 src/Ui.txt create mode 100644 src/Wait.txt create mode 100644 src/c_button.c create mode 100644 src/c_button.h create mode 100644 src/c_button.iom create mode 100644 src/c_cmd.c create mode 100644 src/c_cmd.h create mode 100644 src/c_cmd.iom create mode 100644 src/c_cmd_bytecodes.h create mode 100644 src/c_cmd_drawing.inc create mode 100644 src/c_comm.c create mode 100644 src/c_comm.h create mode 100644 src/c_comm.iom create mode 100644 src/c_display.c create mode 100644 src/c_display.h create mode 100644 src/c_display.iom create mode 100644 src/c_input.c create mode 100644 src/c_input.h create mode 100644 src/c_input.iom create mode 100644 src/c_ioctrl.c create mode 100644 src/c_ioctrl.h create mode 100644 src/c_ioctrl.iom create mode 100644 src/c_loader.c create mode 100644 src/c_loader.h create mode 100644 src/c_loader.iom create mode 100644 src/c_lowspeed.c create mode 100644 src/c_lowspeed.h create mode 100644 src/c_lowspeed.iom create mode 100644 src/c_output.c create mode 100644 src/c_output.h create mode 100644 src/c_output.iom create mode 100644 src/c_sound.c create mode 100644 src/c_sound.h create mode 100644 src/c_sound.iom create mode 100644 src/c_ui.c create mode 100644 src/c_ui.h create mode 100644 src/c_ui.iom create mode 100644 src/config.h create mode 100644 src/d_bt.c create mode 100644 src/d_bt.h create mode 100644 src/d_bt.r create mode 100644 src/d_button.c create mode 100644 src/d_button.h create mode 100644 src/d_button.r create mode 100644 src/d_display.c create mode 100644 src/d_display.h create mode 100644 src/d_display.r create mode 100644 src/d_hispeed.c create mode 100644 src/d_hispeed.h create mode 100644 src/d_hispeed.r create mode 100644 src/d_input.c create mode 100644 src/d_input.h create mode 100644 src/d_input.r create mode 100644 src/d_ioctrl.c create mode 100644 src/d_ioctrl.h create mode 100644 src/d_ioctrl.r create mode 100644 src/d_loader.c create mode 100644 src/d_loader.h create mode 100644 src/d_loader.r create mode 100644 src/d_lowspeed.c create mode 100644 src/d_lowspeed.h create mode 100644 src/d_lowspeed.r create mode 100644 src/d_output.c create mode 100644 src/d_output.h create mode 100644 src/d_output.r create mode 100644 src/d_sound.c create mode 100644 src/d_sound.h create mode 100644 src/d_sound.r create mode 100644 src/d_sound_adpcm.r create mode 100644 src/d_timer.c create mode 100644 src/d_timer.h create mode 100644 src/d_timer.r create mode 100644 src/d_usb.c create mode 100644 src/d_usb.h create mode 100644 src/d_usb.r create mode 100644 src/m_sched.c create mode 100644 src/m_sched.h create mode 100644 src/modules.h create mode 100644 src/sam7s256.c create mode 100644 src/sam7s256.h create mode 100644 src/stdconst.h create mode 100644 startup/Cstartup.S create mode 100644 startup/Cstartup_SAM7.c diff --git a/.gitignore b/.gitignore index 06741cc..d801ece 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,6 @@ *.sym *.elf tags +version.mak +nxt_firmware.bin +nxt_firmware.rfw diff --git a/AT91SAM7S256/SAM7S256/Include/AT91SAM7S256.h b/AT91SAM7S256/SAM7S256/Include/AT91SAM7S256.h deleted file mode 100644 index 168e5ac..0000000 --- a/AT91SAM7S256/SAM7S256/Include/AT91SAM7S256.h +++ /dev/null @@ -1,1920 +0,0 @@ -// ---------------------------------------------------------------------------- -// ATMEL Microcontroller Software Support - ROUSSET - -// ---------------------------------------------------------------------------- -// DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR -// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE -// DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, -// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// ---------------------------------------------------------------------------- -// File Name : AT91SAM7S256.h -// Object : AT91SAM7S256 definitions -// Generated : AT91 SW Application Group 03/08/2005 (15:46:13) -// -// CVS Reference : /AT91SAM7S256.pl/1.8/Wed Feb 9 15:29:26 2005// -// CVS Reference : /SYS_SAM7S.pl/1.2/Tue Feb 1 17:01:52 2005// -// CVS Reference : /MC_SAM7S.pl/1.2/Tue Feb 1 17:01:00 2005// -// CVS Reference : /PMC_SAM7S_USB.pl/1.4/Tue Feb 8 13:58:22 2005// -// CVS Reference : /RSTC_SAM7S.pl/1.1/Tue Feb 1 16:16:35 2005// -// CVS Reference : /RTTC_6081A.pl/1.2/Tue Nov 9 14:43:58 2004// -// CVS Reference : /PITC_6079A.pl/1.2/Tue Nov 9 14:43:56 2004// -// CVS Reference : /WDTC_6080A.pl/1.3/Tue Nov 9 14:44:00 2004// -// CVS Reference : /VREG_6085B.pl/1.1/Tue Feb 1 16:05:48 2005// -// CVS Reference : /UDP_6083C.pl/1.1/Mon Jan 31 13:01:46 2005// -// CVS Reference : /AIC_6075A.pl/1.1/Fri Jun 28 10:36:48 2002// -// CVS Reference : /PIO_6057A.pl/1.2/Thu Feb 3 10:18:28 2005// -// CVS Reference : /DBGU_6059D.pl/1.1/Mon Jan 31 13:15:32 2005// -// CVS Reference : /US_6089C.pl/1.1/Mon Jul 12 18:23:26 2004// -// CVS Reference : /SPI_6088D.pl/1.2/Mon Feb 14 07:24:18 2005// -// CVS Reference : /SSC_6078A.pl/1.1/Tue Jul 13 07:45:40 2004// -// CVS Reference : /TC_6082A.pl/1.6/Fri Feb 18 13:53:30 2005// -// CVS Reference : /TWI_6061A.pl/1.1/Tue Jul 13 07:38:06 2004// -// CVS Reference : /PDC_6074C.pl/1.2/Thu Feb 3 08:48:54 2005// -// CVS Reference : /ADC_6051C.pl/1.1/Fri Oct 17 09:12:38 2003// -// CVS Reference : /PWM_6044D.pl/1.1/Tue Apr 27 14:53:52 2004// -// ---------------------------------------------------------------------------- - -#ifndef AT91SAM7S256_H -#define AT91SAM7S256_H - -typedef volatile unsigned int AT91_REG;// Hardware register definition - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR System Peripherals -// ***************************************************************************** -typedef struct _AT91S_SYS { - AT91_REG AIC_SMR[32]; // Source Mode Register - AT91_REG AIC_SVR[32]; // Source Vector Register - AT91_REG AIC_IVR; // IRQ Vector Register - AT91_REG AIC_FVR; // FIQ Vector Register - AT91_REG AIC_ISR; // Interrupt Status Register - AT91_REG AIC_IPR; // Interrupt Pending Register - AT91_REG AIC_IMR; // Interrupt Mask Register - AT91_REG AIC_CISR; // Core Interrupt Status Register - AT91_REG Reserved0[2]; // - AT91_REG AIC_IECR; // Interrupt Enable Command Register - AT91_REG AIC_IDCR; // Interrupt Disable Command Register - AT91_REG AIC_ICCR; // Interrupt Clear Command Register - AT91_REG AIC_ISCR; // Interrupt Set Command Register - AT91_REG AIC_EOICR; // End of Interrupt Command Register - AT91_REG AIC_SPU; // Spurious Vector Register - AT91_REG AIC_DCR; // Debug Control Register (Protect) - AT91_REG Reserved1[1]; // - AT91_REG AIC_FFER; // Fast Forcing Enable Register - AT91_REG AIC_FFDR; // Fast Forcing Disable Register - AT91_REG AIC_FFSR; // Fast Forcing Status Register - AT91_REG Reserved2[45]; // - AT91_REG DBGU_CR; // Control Register - AT91_REG DBGU_MR; // Mode Register - AT91_REG DBGU_IER; // Interrupt Enable Register - AT91_REG DBGU_IDR; // Interrupt Disable Register - AT91_REG DBGU_IMR; // Interrupt Mask Register - AT91_REG DBGU_CSR; // Channel Status Register - AT91_REG DBGU_RHR; // Receiver Holding Register - AT91_REG DBGU_THR; // Transmitter Holding Register - AT91_REG DBGU_BRGR; // Baud Rate Generator Register - AT91_REG Reserved3[7]; // - AT91_REG DBGU_CIDR; // Chip ID Register - AT91_REG DBGU_EXID; // Chip ID Extension Register - AT91_REG DBGU_FNTR; // Force NTRST Register - AT91_REG Reserved4[45]; // - AT91_REG DBGU_RPR; // Receive Pointer Register - AT91_REG DBGU_RCR; // Receive Counter Register - AT91_REG DBGU_TPR; // Transmit Pointer Register - AT91_REG DBGU_TCR; // Transmit Counter Register - AT91_REG DBGU_RNPR; // Receive Next Pointer Register - AT91_REG DBGU_RNCR; // Receive Next Counter Register - AT91_REG DBGU_TNPR; // Transmit Next Pointer Register - AT91_REG DBGU_TNCR; // Transmit Next Counter Register - AT91_REG DBGU_PTCR; // PDC Transfer Control Register - AT91_REG DBGU_PTSR; // PDC Transfer Status Register - AT91_REG Reserved5[54]; // - AT91_REG PIOA_PER; // PIO Enable Register - AT91_REG PIOA_PDR; // PIO Disable Register - AT91_REG PIOA_PSR; // PIO Status Register - AT91_REG Reserved6[1]; // - AT91_REG PIOA_OER; // Output Enable Register - AT91_REG PIOA_ODR; // Output Disable Registerr - AT91_REG PIOA_OSR; // Output Status Register - AT91_REG Reserved7[1]; // - AT91_REG PIOA_IFER; // Input Filter Enable Register - AT91_REG PIOA_IFDR; // Input Filter Disable Register - AT91_REG PIOA_IFSR; // Input Filter Status Register - AT91_REG Reserved8[1]; // - AT91_REG PIOA_SODR; // Set Output Data Register - AT91_REG PIOA_CODR; // Clear Output Data Register - AT91_REG PIOA_ODSR; // Output Data Status Register - AT91_REG PIOA_PDSR; // Pin Data Status Register - AT91_REG PIOA_IER; // Interrupt Enable Register - AT91_REG PIOA_IDR; // Interrupt Disable Register - AT91_REG PIOA_IMR; // Interrupt Mask Register - AT91_REG PIOA_ISR; // Interrupt Status Register - AT91_REG PIOA_MDER; // Multi-driver Enable Register - AT91_REG PIOA_MDDR; // Multi-driver Disable Register - AT91_REG PIOA_MDSR; // Multi-driver Status Register - AT91_REG Reserved9[1]; // - AT91_REG PIOA_PPUDR; // Pull-up Disable Register - AT91_REG PIOA_PPUER; // Pull-up Enable Register - AT91_REG PIOA_PPUSR; // Pull-up Status Register - AT91_REG Reserved10[1]; // - AT91_REG PIOA_ASR; // Select A Register - AT91_REG PIOA_BSR; // Select B Register - AT91_REG PIOA_ABSR; // AB Select Status Register - AT91_REG Reserved11[9]; // - AT91_REG PIOA_OWER; // Output Write Enable Register - AT91_REG PIOA_OWDR; // Output Write Disable Register - AT91_REG PIOA_OWSR; // Output Write Status Register - AT91_REG Reserved12[469]; // - AT91_REG PMC_SCER; // System Clock Enable Register - AT91_REG PMC_SCDR; // System Clock Disable Register - AT91_REG PMC_SCSR; // System Clock Status Register - AT91_REG Reserved13[1]; // - AT91_REG PMC_PCER; // Peripheral Clock Enable Register - AT91_REG PMC_PCDR; // Peripheral Clock Disable Register - AT91_REG PMC_PCSR; // Peripheral Clock Status Register - AT91_REG Reserved14[1]; // - AT91_REG PMC_MOR; // Main Oscillator Register - AT91_REG PMC_MCFR; // Main Clock Frequency Register - AT91_REG Reserved15[1]; // - AT91_REG PMC_PLLR; // PLL Register - AT91_REG PMC_MCKR; // Master Clock Register - AT91_REG Reserved16[3]; // - AT91_REG PMC_PCKR[3]; // Programmable Clock Register - AT91_REG Reserved17[5]; // - AT91_REG PMC_IER; // Interrupt Enable Register - AT91_REG PMC_IDR; // Interrupt Disable Register - AT91_REG PMC_SR; // Status Register - AT91_REG PMC_IMR; // Interrupt Mask Register - AT91_REG Reserved18[36]; // - AT91_REG RSTC_RCR; // Reset Control Register - AT91_REG RSTC_RSR; // Reset Status Register - AT91_REG RSTC_RMR; // Reset Mode Register - AT91_REG Reserved19[5]; // - AT91_REG RTTC_RTMR; // Real-time Mode Register - AT91_REG RTTC_RTAR; // Real-time Alarm Register - AT91_REG RTTC_RTVR; // Real-time Value Register - AT91_REG RTTC_RTSR; // Real-time Status Register - AT91_REG PITC_PIMR; // Period Interval Mode Register - AT91_REG PITC_PISR; // Period Interval Status Register - AT91_REG PITC_PIVR; // Period Interval Value Register - AT91_REG PITC_PIIR; // Period Interval Image Register - AT91_REG WDTC_WDCR; // Watchdog Control Register - AT91_REG WDTC_WDMR; // Watchdog Mode Register - AT91_REG WDTC_WDSR; // Watchdog Status Register - AT91_REG Reserved20[5]; // - AT91_REG VREG_MR; // Voltage Regulator Mode Register -} AT91S_SYS, *AT91PS_SYS; - - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Advanced Interrupt Controller -// ***************************************************************************** -typedef struct _AT91S_AIC { - AT91_REG AIC_SMR[32]; // Source Mode Register - AT91_REG AIC_SVR[32]; // Source Vector Register - AT91_REG AIC_IVR; // IRQ Vector Register - AT91_REG AIC_FVR; // FIQ Vector Register - AT91_REG AIC_ISR; // Interrupt Status Register - AT91_REG AIC_IPR; // Interrupt Pending Register - AT91_REG AIC_IMR; // Interrupt Mask Register - AT91_REG AIC_CISR; // Core Interrupt Status Register - AT91_REG Reserved0[2]; // - AT91_REG AIC_IECR; // Interrupt Enable Command Register - AT91_REG AIC_IDCR; // Interrupt Disable Command Register - AT91_REG AIC_ICCR; // Interrupt Clear Command Register - AT91_REG AIC_ISCR; // Interrupt Set Command Register - AT91_REG AIC_EOICR; // End of Interrupt Command Register - AT91_REG AIC_SPU; // Spurious Vector Register - AT91_REG AIC_DCR; // Debug Control Register (Protect) - AT91_REG Reserved1[1]; // - AT91_REG AIC_FFER; // Fast Forcing Enable Register - AT91_REG AIC_FFDR; // Fast Forcing Disable Register - AT91_REG AIC_FFSR; // Fast Forcing Status Register -} AT91S_AIC, *AT91PS_AIC; - -// -------- AIC_SMR : (AIC Offset: 0x0) Control Register -------- -#define AT91C_AIC_PRIOR ((unsigned int) 0x7 << 0) // (AIC) Priority Level -#define AT91C_AIC_PRIOR_LOWEST ((unsigned int) 0x0) // (AIC) Lowest priority level -#define AT91C_AIC_PRIOR_HIGHEST ((unsigned int) 0x7) // (AIC) Highest priority level -#define AT91C_AIC_SRCTYPE ((unsigned int) 0x3 << 5) // (AIC) Interrupt Source Type -#define AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE ((unsigned int) 0x0 << 5) // (AIC) Internal Sources Code Label Level Sensitive -#define AT91C_AIC_SRCTYPE_INT_EDGE_TRIGGERED ((unsigned int) 0x1 << 5) // (AIC) Internal Sources Code Label Edge triggered -#define AT91C_AIC_SRCTYPE_EXT_HIGH_LEVEL ((unsigned int) 0x2 << 5) // (AIC) External Sources Code Label High-level Sensitive -#define AT91C_AIC_SRCTYPE_EXT_POSITIVE_EDGE ((unsigned int) 0x3 << 5) // (AIC) External Sources Code Label Positive Edge triggered -// -------- AIC_CISR : (AIC Offset: 0x114) AIC Core Interrupt Status Register -------- -#define AT91C_AIC_NFIQ ((unsigned int) 0x1 << 0) // (AIC) NFIQ Status -#define AT91C_AIC_NIRQ ((unsigned int) 0x1 << 1) // (AIC) NIRQ Status -// -------- AIC_DCR : (AIC Offset: 0x138) AIC Debug Control Register (Protect) -------- -#define AT91C_AIC_DCR_PROT ((unsigned int) 0x1 << 0) // (AIC) Protection Mode -#define AT91C_AIC_DCR_GMSK ((unsigned int) 0x1 << 1) // (AIC) General Mask - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Peripheral DMA Controller -// ***************************************************************************** -typedef struct _AT91S_PDC { - AT91_REG PDC_RPR; // Receive Pointer Register - AT91_REG PDC_RCR; // Receive Counter Register - AT91_REG PDC_TPR; // Transmit Pointer Register - AT91_REG PDC_TCR; // Transmit Counter Register - AT91_REG PDC_RNPR; // Receive Next Pointer Register - AT91_REG PDC_RNCR; // Receive Next Counter Register - AT91_REG PDC_TNPR; // Transmit Next Pointer Register - AT91_REG PDC_TNCR; // Transmit Next Counter Register - AT91_REG PDC_PTCR; // PDC Transfer Control Register - AT91_REG PDC_PTSR; // PDC Transfer Status Register -} AT91S_PDC, *AT91PS_PDC; - -// -------- PDC_PTCR : (PDC Offset: 0x20) PDC Transfer Control Register -------- -#define AT91C_PDC_RXTEN ((unsigned int) 0x1 << 0) // (PDC) Receiver Transfer Enable -#define AT91C_PDC_RXTDIS ((unsigned int) 0x1 << 1) // (PDC) Receiver Transfer Disable -#define AT91C_PDC_TXTEN ((unsigned int) 0x1 << 8) // (PDC) Transmitter Transfer Enable -#define AT91C_PDC_TXTDIS ((unsigned int) 0x1 << 9) // (PDC) Transmitter Transfer Disable -// -------- PDC_PTSR : (PDC Offset: 0x24) PDC Transfer Status Register -------- - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Debug Unit -// ***************************************************************************** -typedef struct _AT91S_DBGU { - AT91_REG DBGU_CR; // Control Register - AT91_REG DBGU_MR; // Mode Register - AT91_REG DBGU_IER; // Interrupt Enable Register - AT91_REG DBGU_IDR; // Interrupt Disable Register - AT91_REG DBGU_IMR; // Interrupt Mask Register - AT91_REG DBGU_CSR; // Channel Status Register - AT91_REG DBGU_RHR; // Receiver Holding Register - AT91_REG DBGU_THR; // Transmitter Holding Register - AT91_REG DBGU_BRGR; // Baud Rate Generator Register - AT91_REG Reserved0[7]; // - AT91_REG DBGU_CIDR; // Chip ID Register - AT91_REG DBGU_EXID; // Chip ID Extension Register - AT91_REG DBGU_FNTR; // Force NTRST Register - AT91_REG Reserved1[45]; // - AT91_REG DBGU_RPR; // Receive Pointer Register - AT91_REG DBGU_RCR; // Receive Counter Register - AT91_REG DBGU_TPR; // Transmit Pointer Register - AT91_REG DBGU_TCR; // Transmit Counter Register - AT91_REG DBGU_RNPR; // Receive Next Pointer Register - AT91_REG DBGU_RNCR; // Receive Next Counter Register - AT91_REG DBGU_TNPR; // Transmit Next Pointer Register - AT91_REG DBGU_TNCR; // Transmit Next Counter Register - AT91_REG DBGU_PTCR; // PDC Transfer Control Register - AT91_REG DBGU_PTSR; // PDC Transfer Status Register -} AT91S_DBGU, *AT91PS_DBGU; - -// -------- DBGU_CR : (DBGU Offset: 0x0) Debug Unit Control Register -------- -#define AT91C_US_RSTRX ((unsigned int) 0x1 << 2) // (DBGU) Reset Receiver -#define AT91C_US_RSTTX ((unsigned int) 0x1 << 3) // (DBGU) Reset Transmitter -#define AT91C_US_RXEN ((unsigned int) 0x1 << 4) // (DBGU) Receiver Enable -#define AT91C_US_RXDIS ((unsigned int) 0x1 << 5) // (DBGU) Receiver Disable -#define AT91C_US_TXEN ((unsigned int) 0x1 << 6) // (DBGU) Transmitter Enable -#define AT91C_US_TXDIS ((unsigned int) 0x1 << 7) // (DBGU) Transmitter Disable -#define AT91C_US_RSTSTA ((unsigned int) 0x1 << 8) // (DBGU) Reset Status Bits -// -------- DBGU_MR : (DBGU Offset: 0x4) Debug Unit Mode Register -------- -#define AT91C_US_PAR ((unsigned int) 0x7 << 9) // (DBGU) Parity type -#define AT91C_US_PAR_EVEN ((unsigned int) 0x0 << 9) // (DBGU) Even Parity -#define AT91C_US_PAR_ODD ((unsigned int) 0x1 << 9) // (DBGU) Odd Parity -#define AT91C_US_PAR_SPACE ((unsigned int) 0x2 << 9) // (DBGU) Parity forced to 0 (Space) -#define AT91C_US_PAR_MARK ((unsigned int) 0x3 << 9) // (DBGU) Parity forced to 1 (Mark) -#define AT91C_US_PAR_NONE ((unsigned int) 0x4 << 9) // (DBGU) No Parity -#define AT91C_US_PAR_MULTI_DROP ((unsigned int) 0x6 << 9) // (DBGU) Multi-drop mode -#define AT91C_US_CHMODE ((unsigned int) 0x3 << 14) // (DBGU) Channel Mode -#define AT91C_US_CHMODE_NORMAL ((unsigned int) 0x0 << 14) // (DBGU) Normal Mode: The USART channel operates as an RX/TX USART. -#define AT91C_US_CHMODE_AUTO ((unsigned int) 0x1 << 14) // (DBGU) Automatic Echo: Receiver Data Input is connected to the TXD pin. -#define AT91C_US_CHMODE_LOCAL ((unsigned int) 0x2 << 14) // (DBGU) Local Loopback: Transmitter Output Signal is connected to Receiver Input Signal. -#define AT91C_US_CHMODE_REMOTE ((unsigned int) 0x3 << 14) // (DBGU) Remote Loopback: RXD pin is internally connected to TXD pin. -// -------- DBGU_IER : (DBGU Offset: 0x8) Debug Unit Interrupt Enable Register -------- -#define AT91C_US_RXRDY ((unsigned int) 0x1 << 0) // (DBGU) RXRDY Interrupt -#define AT91C_US_TXRDY ((unsigned int) 0x1 << 1) // (DBGU) TXRDY Interrupt -#define AT91C_US_ENDRX ((unsigned int) 0x1 << 3) // (DBGU) End of Receive Transfer Interrupt -#define AT91C_US_ENDTX ((unsigned int) 0x1 << 4) // (DBGU) End of Transmit Interrupt -#define AT91C_US_OVRE ((unsigned int) 0x1 << 5) // (DBGU) Overrun Interrupt -#define AT91C_US_FRAME ((unsigned int) 0x1 << 6) // (DBGU) Framing Error Interrupt -#define AT91C_US_PARE ((unsigned int) 0x1 << 7) // (DBGU) Parity Error Interrupt -#define AT91C_US_TXEMPTY ((unsigned int) 0x1 << 9) // (DBGU) TXEMPTY Interrupt -#define AT91C_US_TXBUFE ((unsigned int) 0x1 << 11) // (DBGU) TXBUFE Interrupt -#define AT91C_US_RXBUFF ((unsigned int) 0x1 << 12) // (DBGU) RXBUFF Interrupt -#define AT91C_US_COMM_TX ((unsigned int) 0x1 << 30) // (DBGU) COMM_TX Interrupt -#define AT91C_US_COMM_RX ((unsigned int) 0x1 << 31) // (DBGU) COMM_RX Interrupt -// -------- DBGU_IDR : (DBGU Offset: 0xc) Debug Unit Interrupt Disable Register -------- -// -------- DBGU_IMR : (DBGU Offset: 0x10) Debug Unit Interrupt Mask Register -------- -// -------- DBGU_CSR : (DBGU Offset: 0x14) Debug Unit Channel Status Register -------- -// -------- DBGU_FNTR : (DBGU Offset: 0x48) Debug Unit FORCE_NTRST Register -------- -#define AT91C_US_FORCE_NTRST ((unsigned int) 0x1 << 0) // (DBGU) Force NTRST in JTAG - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Parallel Input Output Controler -// ***************************************************************************** -typedef struct _AT91S_PIO { - AT91_REG PIO_PER; // PIO Enable Register - AT91_REG PIO_PDR; // PIO Disable Register - AT91_REG PIO_PSR; // PIO Status Register - AT91_REG Reserved0[1]; // - AT91_REG PIO_OER; // Output Enable Register - AT91_REG PIO_ODR; // Output Disable Registerr - AT91_REG PIO_OSR; // Output Status Register - AT91_REG Reserved1[1]; // - AT91_REG PIO_IFER; // Input Filter Enable Register - AT91_REG PIO_IFDR; // Input Filter Disable Register - AT91_REG PIO_IFSR; // Input Filter Status Register - AT91_REG Reserved2[1]; // - AT91_REG PIO_SODR; // Set Output Data Register - AT91_REG PIO_CODR; // Clear Output Data Register - AT91_REG PIO_ODSR; // Output Data Status Register - AT91_REG PIO_PDSR; // Pin Data Status Register - AT91_REG PIO_IER; // Interrupt Enable Register - AT91_REG PIO_IDR; // Interrupt Disable Register - AT91_REG PIO_IMR; // Interrupt Mask Register - AT91_REG PIO_ISR; // Interrupt Status Register - AT91_REG PIO_MDER; // Multi-driver Enable Register - AT91_REG PIO_MDDR; // Multi-driver Disable Register - AT91_REG PIO_MDSR; // Multi-driver Status Register - AT91_REG Reserved3[1]; // - AT91_REG PIO_PPUDR; // Pull-up Disable Register - AT91_REG PIO_PPUER; // Pull-up Enable Register - AT91_REG PIO_PPUSR; // Pull-up Status Register - AT91_REG Reserved4[1]; // - AT91_REG PIO_ASR; // Select A Register - AT91_REG PIO_BSR; // Select B Register - AT91_REG PIO_ABSR; // AB Select Status Register - AT91_REG Reserved5[9]; // - AT91_REG PIO_OWER; // Output Write Enable Register - AT91_REG PIO_OWDR; // Output Write Disable Register - AT91_REG PIO_OWSR; // Output Write Status Register -} AT91S_PIO, *AT91PS_PIO; - - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Clock Generator Controler -// ***************************************************************************** -typedef struct _AT91S_CKGR { - AT91_REG CKGR_MOR; // Main Oscillator Register - AT91_REG CKGR_MCFR; // Main Clock Frequency Register - AT91_REG Reserved0[1]; // - AT91_REG CKGR_PLLR; // PLL Register -} AT91S_CKGR, *AT91PS_CKGR; - -// -------- CKGR_MOR : (CKGR Offset: 0x0) Main Oscillator Register -------- -#define AT91C_CKGR_MOSCEN ((unsigned int) 0x1 << 0) // (CKGR) Main Oscillator Enable -#define AT91C_CKGR_OSCBYPASS ((unsigned int) 0x1 << 1) // (CKGR) Main Oscillator Bypass -#define AT91C_CKGR_OSCOUNT ((unsigned int) 0xFF << 8) // (CKGR) Main Oscillator Start-up Time -// -------- CKGR_MCFR : (CKGR Offset: 0x4) Main Clock Frequency Register -------- -#define AT91C_CKGR_MAINF ((unsigned int) 0xFFFF << 0) // (CKGR) Main Clock Frequency -#define AT91C_CKGR_MAINRDY ((unsigned int) 0x1 << 16) // (CKGR) Main Clock Ready -// -------- CKGR_PLLR : (CKGR Offset: 0xc) PLL B Register -------- -#define AT91C_CKGR_DIV ((unsigned int) 0xFF << 0) // (CKGR) Divider Selected -#define AT91C_CKGR_DIV_0 ((unsigned int) 0x0) // (CKGR) Divider output is 0 -#define AT91C_CKGR_DIV_BYPASS ((unsigned int) 0x1) // (CKGR) Divider is bypassed -#define AT91C_CKGR_PLLCOUNT ((unsigned int) 0x3F << 8) // (CKGR) PLL Counter -#define AT91C_CKGR_OUT ((unsigned int) 0x3 << 14) // (CKGR) PLL Output Frequency Range -#define AT91C_CKGR_OUT_0 ((unsigned int) 0x0 << 14) // (CKGR) Please refer to the PLL datasheet -#define AT91C_CKGR_OUT_1 ((unsigned int) 0x1 << 14) // (CKGR) Please refer to the PLL datasheet -#define AT91C_CKGR_OUT_2 ((unsigned int) 0x2 << 14) // (CKGR) Please refer to the PLL datasheet -#define AT91C_CKGR_OUT_3 ((unsigned int) 0x3 << 14) // (CKGR) Please refer to the PLL datasheet -#define AT91C_CKGR_MUL ((unsigned int) 0x7FF << 16) // (CKGR) PLL Multiplier -#define AT91C_CKGR_USBDIV ((unsigned int) 0x3 << 28) // (CKGR) Divider for USB Clocks -#define AT91C_CKGR_USBDIV_0 ((unsigned int) 0x0 << 28) // (CKGR) Divider output is PLL clock output -#define AT91C_CKGR_USBDIV_1 ((unsigned int) 0x1 << 28) // (CKGR) Divider output is PLL clock output divided by 2 -#define AT91C_CKGR_USBDIV_2 ((unsigned int) 0x2 << 28) // (CKGR) Divider output is PLL clock output divided by 4 - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Power Management Controler -// ***************************************************************************** -typedef struct _AT91S_PMC { - AT91_REG PMC_SCER; // System Clock Enable Register - AT91_REG PMC_SCDR; // System Clock Disable Register - AT91_REG PMC_SCSR; // System Clock Status Register - AT91_REG Reserved0[1]; // - AT91_REG PMC_PCER; // Peripheral Clock Enable Register - AT91_REG PMC_PCDR; // Peripheral Clock Disable Register - AT91_REG PMC_PCSR; // Peripheral Clock Status Register - AT91_REG Reserved1[1]; // - AT91_REG PMC_MOR; // Main Oscillator Register - AT91_REG PMC_MCFR; // Main Clock Frequency Register - AT91_REG Reserved2[1]; // - AT91_REG PMC_PLLR; // PLL Register - AT91_REG PMC_MCKR; // Master Clock Register - AT91_REG Reserved3[3]; // - AT91_REG PMC_PCKR[3]; // Programmable Clock Register - AT91_REG Reserved4[5]; // - AT91_REG PMC_IER; // Interrupt Enable Register - AT91_REG PMC_IDR; // Interrupt Disable Register - AT91_REG PMC_SR; // Status Register - AT91_REG PMC_IMR; // Interrupt Mask Register -} AT91S_PMC, *AT91PS_PMC; - -// -------- PMC_SCER : (PMC Offset: 0x0) System Clock Enable Register -------- -#define AT91C_PMC_PCK ((unsigned int) 0x1 << 0) // (PMC) Processor Clock -#define AT91C_PMC_UDP ((unsigned int) 0x1 << 7) // (PMC) USB Device Port Clock -#define AT91C_PMC_PCK0 ((unsigned int) 0x1 << 8) // (PMC) Programmable Clock Output -#define AT91C_PMC_PCK1 ((unsigned int) 0x1 << 9) // (PMC) Programmable Clock Output -#define AT91C_PMC_PCK2 ((unsigned int) 0x1 << 10) // (PMC) Programmable Clock Output -// -------- PMC_SCDR : (PMC Offset: 0x4) System Clock Disable Register -------- -// -------- PMC_SCSR : (PMC Offset: 0x8) System Clock Status Register -------- -// -------- CKGR_MOR : (PMC Offset: 0x20) Main Oscillator Register -------- -// -------- CKGR_MCFR : (PMC Offset: 0x24) Main Clock Frequency Register -------- -// -------- CKGR_PLLR : (PMC Offset: 0x2c) PLL B Register -------- -// -------- PMC_MCKR : (PMC Offset: 0x30) Master Clock Register -------- -#define AT91C_PMC_CSS ((unsigned int) 0x3 << 0) // (PMC) Programmable Clock Selection -#define AT91C_PMC_CSS_SLOW_CLK ((unsigned int) 0x0) // (PMC) Slow Clock is selected -#define AT91C_PMC_CSS_MAIN_CLK ((unsigned int) 0x1) // (PMC) Main Clock is selected -#define AT91C_PMC_CSS_PLL_CLK ((unsigned int) 0x3) // (PMC) Clock from PLL is selected -#define AT91C_PMC_PRES ((unsigned int) 0x7 << 2) // (PMC) Programmable Clock Prescaler -#define AT91C_PMC_PRES_CLK ((unsigned int) 0x0 << 2) // (PMC) Selected clock -#define AT91C_PMC_PRES_CLK_2 ((unsigned int) 0x1 << 2) // (PMC) Selected clock divided by 2 -#define AT91C_PMC_PRES_CLK_4 ((unsigned int) 0x2 << 2) // (PMC) Selected clock divided by 4 -#define AT91C_PMC_PRES_CLK_8 ((unsigned int) 0x3 << 2) // (PMC) Selected clock divided by 8 -#define AT91C_PMC_PRES_CLK_16 ((unsigned int) 0x4 << 2) // (PMC) Selected clock divided by 16 -#define AT91C_PMC_PRES_CLK_32 ((unsigned int) 0x5 << 2) // (PMC) Selected clock divided by 32 -#define AT91C_PMC_PRES_CLK_64 ((unsigned int) 0x6 << 2) // (PMC) Selected clock divided by 64 -// -------- PMC_PCKR : (PMC Offset: 0x40) Programmable Clock Register -------- -// -------- PMC_IER : (PMC Offset: 0x60) PMC Interrupt Enable Register -------- -#define AT91C_PMC_MOSCS ((unsigned int) 0x1 << 0) // (PMC) MOSC Status/Enable/Disable/Mask -#define AT91C_PMC_LOCK ((unsigned int) 0x1 << 2) // (PMC) PLL Status/Enable/Disable/Mask -#define AT91C_PMC_MCKRDY ((unsigned int) 0x1 << 3) // (PMC) MCK_RDY Status/Enable/Disable/Mask -#define AT91C_PMC_PCK0RDY ((unsigned int) 0x1 << 8) // (PMC) PCK0_RDY Status/Enable/Disable/Mask -#define AT91C_PMC_PCK1RDY ((unsigned int) 0x1 << 9) // (PMC) PCK1_RDY Status/Enable/Disable/Mask -#define AT91C_PMC_PCK2RDY ((unsigned int) 0x1 << 10) // (PMC) PCK2_RDY Status/Enable/Disable/Mask -// -------- PMC_IDR : (PMC Offset: 0x64) PMC Interrupt Disable Register -------- -// -------- PMC_SR : (PMC Offset: 0x68) PMC Status Register -------- -// -------- PMC_IMR : (PMC Offset: 0x6c) PMC Interrupt Mask Register -------- - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Reset Controller Interface -// ***************************************************************************** -typedef struct _AT91S_RSTC { - AT91_REG RSTC_RCR; // Reset Control Register - AT91_REG RSTC_RSR; // Reset Status Register - AT91_REG RSTC_RMR; // Reset Mode Register -} AT91S_RSTC, *AT91PS_RSTC; - -// -------- RSTC_RCR : (RSTC Offset: 0x0) Reset Control Register -------- -#define AT91C_RSTC_PROCRST ((unsigned int) 0x1 << 0) // (RSTC) Processor Reset -#define AT91C_RSTC_PERRST ((unsigned int) 0x1 << 2) // (RSTC) Peripheral Reset -#define AT91C_RSTC_EXTRST ((unsigned int) 0x1 << 3) // (RSTC) External Reset -#define AT91C_RSTC_KEY ((unsigned int) 0xFF << 24) // (RSTC) Password -// -------- RSTC_RSR : (RSTC Offset: 0x4) Reset Status Register -------- -#define AT91C_RSTC_URSTS ((unsigned int) 0x1 << 0) // (RSTC) User Reset Status -#define AT91C_RSTC_BODSTS ((unsigned int) 0x1 << 1) // (RSTC) Brownout Detection Status -#define AT91C_RSTC_RSTTYP ((unsigned int) 0x7 << 8) // (RSTC) Reset Type -#define AT91C_RSTC_RSTTYP_POWERUP ((unsigned int) 0x0 << 8) // (RSTC) Power-up Reset. VDDCORE rising. -#define AT91C_RSTC_RSTTYP_WAKEUP ((unsigned int) 0x1 << 8) // (RSTC) WakeUp Reset. VDDCORE rising. -#define AT91C_RSTC_RSTTYP_WATCHDOG ((unsigned int) 0x2 << 8) // (RSTC) Watchdog Reset. Watchdog overflow occured. -#define AT91C_RSTC_RSTTYP_SOFTWARE ((unsigned int) 0x3 << 8) // (RSTC) Software Reset. Processor reset required by the software. -#define AT91C_RSTC_RSTTYP_USER ((unsigned int) 0x4 << 8) // (RSTC) User Reset. NRST pin detected low. -#define AT91C_RSTC_RSTTYP_BROWNOUT ((unsigned int) 0x5 << 8) // (RSTC) Brownout Reset occured. -#define AT91C_RSTC_NRSTL ((unsigned int) 0x1 << 16) // (RSTC) NRST pin level -#define AT91C_RSTC_SRCMP ((unsigned int) 0x1 << 17) // (RSTC) Software Reset Command in Progress. -// -------- RSTC_RMR : (RSTC Offset: 0x8) Reset Mode Register -------- -#define AT91C_RSTC_URSTEN ((unsigned int) 0x1 << 0) // (RSTC) User Reset Enable -#define AT91C_RSTC_URSTIEN ((unsigned int) 0x1 << 4) // (RSTC) User Reset Interrupt Enable -#define AT91C_RSTC_ERSTL ((unsigned int) 0xF << 8) // (RSTC) User Reset Enable -#define AT91C_RSTC_BODIEN ((unsigned int) 0x1 << 16) // (RSTC) Brownout Detection Interrupt Enable - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Real Time Timer Controller Interface -// ***************************************************************************** -typedef struct _AT91S_RTTC { - AT91_REG RTTC_RTMR; // Real-time Mode Register - AT91_REG RTTC_RTAR; // Real-time Alarm Register - AT91_REG RTTC_RTVR; // Real-time Value Register - AT91_REG RTTC_RTSR; // Real-time Status Register -} AT91S_RTTC, *AT91PS_RTTC; - -// -------- RTTC_RTMR : (RTTC Offset: 0x0) Real-time Mode Register -------- -#define AT91C_RTTC_RTPRES ((unsigned int) 0xFFFF << 0) // (RTTC) Real-time Timer Prescaler Value -#define AT91C_RTTC_ALMIEN ((unsigned int) 0x1 << 16) // (RTTC) Alarm Interrupt Enable -#define AT91C_RTTC_RTTINCIEN ((unsigned int) 0x1 << 17) // (RTTC) Real Time Timer Increment Interrupt Enable -#define AT91C_RTTC_RTTRST ((unsigned int) 0x1 << 18) // (RTTC) Real Time Timer Restart -// -------- RTTC_RTAR : (RTTC Offset: 0x4) Real-time Alarm Register -------- -#define AT91C_RTTC_ALMV ((unsigned int) 0x0 << 0) // (RTTC) Alarm Value -// -------- RTTC_RTVR : (RTTC Offset: 0x8) Current Real-time Value Register -------- -#define AT91C_RTTC_CRTV ((unsigned int) 0x0 << 0) // (RTTC) Current Real-time Value -// -------- RTTC_RTSR : (RTTC Offset: 0xc) Real-time Status Register -------- -#define AT91C_RTTC_ALMS ((unsigned int) 0x1 << 0) // (RTTC) Real-time Alarm Status -#define AT91C_RTTC_RTTINC ((unsigned int) 0x1 << 1) // (RTTC) Real-time Timer Increment - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Periodic Interval Timer Controller Interface -// ***************************************************************************** -typedef struct _AT91S_PITC { - AT91_REG PITC_PIMR; // Period Interval Mode Register - AT91_REG PITC_PISR; // Period Interval Status Register - AT91_REG PITC_PIVR; // Period Interval Value Register - AT91_REG PITC_PIIR; // Period Interval Image Register -} AT91S_PITC, *AT91PS_PITC; - -// -------- PITC_PIMR : (PITC Offset: 0x0) Periodic Interval Mode Register -------- -#define AT91C_PITC_PIV ((unsigned int) 0xFFFFF << 0) // (PITC) Periodic Interval Value -#define AT91C_PITC_PITEN ((unsigned int) 0x1 << 24) // (PITC) Periodic Interval Timer Enabled -#define AT91C_PITC_PITIEN ((unsigned int) 0x1 << 25) // (PITC) Periodic Interval Timer Interrupt Enable -// -------- PITC_PISR : (PITC Offset: 0x4) Periodic Interval Status Register -------- -#define AT91C_PITC_PITS ((unsigned int) 0x1 << 0) // (PITC) Periodic Interval Timer Status -// -------- PITC_PIVR : (PITC Offset: 0x8) Periodic Interval Value Register -------- -#define AT91C_PITC_CPIV ((unsigned int) 0xFFFFF << 0) // (PITC) Current Periodic Interval Value -#define AT91C_PITC_PICNT ((unsigned int) 0xFFF << 20) // (PITC) Periodic Interval Counter -// -------- PITC_PIIR : (PITC Offset: 0xc) Periodic Interval Image Register -------- - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Watchdog Timer Controller Interface -// ***************************************************************************** -typedef struct _AT91S_WDTC { - AT91_REG WDTC_WDCR; // Watchdog Control Register - AT91_REG WDTC_WDMR; // Watchdog Mode Register - AT91_REG WDTC_WDSR; // Watchdog Status Register -} AT91S_WDTC, *AT91PS_WDTC; - -// -------- WDTC_WDCR : (WDTC Offset: 0x0) Periodic Interval Image Register -------- -#define AT91C_WDTC_WDRSTT ((unsigned int) 0x1 << 0) // (WDTC) Watchdog Restart -#define AT91C_WDTC_KEY ((unsigned int) 0xFF << 24) // (WDTC) Watchdog KEY Password -// -------- WDTC_WDMR : (WDTC Offset: 0x4) Watchdog Mode Register -------- -#define AT91C_WDTC_WDV ((unsigned int) 0xFFF << 0) // (WDTC) Watchdog Timer Restart -#define AT91C_WDTC_WDFIEN ((unsigned int) 0x1 << 12) // (WDTC) Watchdog Fault Interrupt Enable -#define AT91C_WDTC_WDRSTEN ((unsigned int) 0x1 << 13) // (WDTC) Watchdog Reset Enable -#define AT91C_WDTC_WDRPROC ((unsigned int) 0x1 << 14) // (WDTC) Watchdog Timer Restart -#define AT91C_WDTC_WDDIS ((unsigned int) 0x1 << 15) // (WDTC) Watchdog Disable -#define AT91C_WDTC_WDD ((unsigned int) 0xFFF << 16) // (WDTC) Watchdog Delta Value -#define AT91C_WDTC_WDDBGHLT ((unsigned int) 0x1 << 28) // (WDTC) Watchdog Debug Halt -#define AT91C_WDTC_WDIDLEHLT ((unsigned int) 0x1 << 29) // (WDTC) Watchdog Idle Halt -// -------- WDTC_WDSR : (WDTC Offset: 0x8) Watchdog Status Register -------- -#define AT91C_WDTC_WDUNF ((unsigned int) 0x1 << 0) // (WDTC) Watchdog Underflow -#define AT91C_WDTC_WDERR ((unsigned int) 0x1 << 1) // (WDTC) Watchdog Error - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Voltage Regulator Mode Controller Interface -// ***************************************************************************** -typedef struct _AT91S_VREG { - AT91_REG VREG_MR; // Voltage Regulator Mode Register -} AT91S_VREG, *AT91PS_VREG; - -// -------- VREG_MR : (VREG Offset: 0x0) Voltage Regulator Mode Register -------- -#define AT91C_VREG_PSTDBY ((unsigned int) 0x1 << 0) // (VREG) Voltage Regulator Power Standby Mode - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Memory Controller Interface -// ***************************************************************************** -typedef struct _AT91S_MC { - AT91_REG MC_RCR; // MC Remap Control Register - AT91_REG MC_ASR; // MC Abort Status Register - AT91_REG MC_AASR; // MC Abort Address Status Register - AT91_REG Reserved0[21]; // - AT91_REG MC_FMR; // MC Flash Mode Register - AT91_REG MC_FCR; // MC Flash Command Register - AT91_REG MC_FSR; // MC Flash Status Register -} AT91S_MC, *AT91PS_MC; - -// -------- MC_RCR : (MC Offset: 0x0) MC Remap Control Register -------- -#define AT91C_MC_RCB ((unsigned int) 0x1 << 0) // (MC) Remap Command Bit -// -------- MC_ASR : (MC Offset: 0x4) MC Abort Status Register -------- -#define AT91C_MC_UNDADD ((unsigned int) 0x1 << 0) // (MC) Undefined Addess Abort Status -#define AT91C_MC_MISADD ((unsigned int) 0x1 << 1) // (MC) Misaligned Addess Abort Status -#define AT91C_MC_ABTSZ ((unsigned int) 0x3 << 8) // (MC) Abort Size Status -#define AT91C_MC_ABTSZ_BYTE ((unsigned int) 0x0 << 8) // (MC) Byte -#define AT91C_MC_ABTSZ_HWORD ((unsigned int) 0x1 << 8) // (MC) Half-word -#define AT91C_MC_ABTSZ_WORD ((unsigned int) 0x2 << 8) // (MC) Word -#define AT91C_MC_ABTTYP ((unsigned int) 0x3 << 10) // (MC) Abort Type Status -#define AT91C_MC_ABTTYP_DATAR ((unsigned int) 0x0 << 10) // (MC) Data Read -#define AT91C_MC_ABTTYP_DATAW ((unsigned int) 0x1 << 10) // (MC) Data Write -#define AT91C_MC_ABTTYP_FETCH ((unsigned int) 0x2 << 10) // (MC) Code Fetch -#define AT91C_MC_MST0 ((unsigned int) 0x1 << 16) // (MC) Master 0 Abort Source -#define AT91C_MC_MST1 ((unsigned int) 0x1 << 17) // (MC) Master 1 Abort Source -#define AT91C_MC_SVMST0 ((unsigned int) 0x1 << 24) // (MC) Saved Master 0 Abort Source -#define AT91C_MC_SVMST1 ((unsigned int) 0x1 << 25) // (MC) Saved Master 1 Abort Source -// -------- MC_FMR : (MC Offset: 0x60) MC Flash Mode Register -------- -#define AT91C_MC_FRDY ((unsigned int) 0x1 << 0) // (MC) Flash Ready -#define AT91C_MC_LOCKE ((unsigned int) 0x1 << 2) // (MC) Lock Error -#define AT91C_MC_PROGE ((unsigned int) 0x1 << 3) // (MC) Programming Error -#define AT91C_MC_NEBP ((unsigned int) 0x1 << 7) // (MC) No Erase Before Programming -#define AT91C_MC_FWS ((unsigned int) 0x3 << 8) // (MC) Flash Wait State -#define AT91C_MC_FWS_0FWS ((unsigned int) 0x0 << 8) // (MC) 1 cycle for Read, 2 for Write operations -#define AT91C_MC_FWS_1FWS ((unsigned int) 0x1 << 8) // (MC) 2 cycles for Read, 3 for Write operations -#define AT91C_MC_FWS_2FWS ((unsigned int) 0x2 << 8) // (MC) 3 cycles for Read, 4 for Write operations -#define AT91C_MC_FWS_3FWS ((unsigned int) 0x3 << 8) // (MC) 4 cycles for Read, 4 for Write operations -#define AT91C_MC_FMCN ((unsigned int) 0xFF << 16) // (MC) Flash Microsecond Cycle Number -// -------- MC_FCR : (MC Offset: 0x64) MC Flash Command Register -------- -#define AT91C_MC_FCMD ((unsigned int) 0xF << 0) // (MC) Flash Command -#define AT91C_MC_FCMD_START_PROG ((unsigned int) 0x1) // (MC) Starts the programming of th epage specified by PAGEN. -#define AT91C_MC_FCMD_LOCK ((unsigned int) 0x2) // (MC) Starts a lock sequence of the sector defined by the bits 4 to 7 of the field PAGEN. -#define AT91C_MC_FCMD_PROG_AND_LOCK ((unsigned int) 0x3) // (MC) The lock sequence automatically happens after the programming sequence is completed. -#define AT91C_MC_FCMD_UNLOCK ((unsigned int) 0x4) // (MC) Starts an unlock sequence of the sector defined by the bits 4 to 7 of the field PAGEN. -#define AT91C_MC_FCMD_ERASE_ALL ((unsigned int) 0x8) // (MC) Starts the erase of the entire flash.If at least a page is locked, the command is cancelled. -#define AT91C_MC_FCMD_SET_GP_NVM ((unsigned int) 0xB) // (MC) Set General Purpose NVM bits. -#define AT91C_MC_FCMD_CLR_GP_NVM ((unsigned int) 0xD) // (MC) Clear General Purpose NVM bits. -#define AT91C_MC_FCMD_SET_SECURITY ((unsigned int) 0xF) // (MC) Set Security Bit. -#define AT91C_MC_PAGEN ((unsigned int) 0x3FF << 8) // (MC) Page Number -#define AT91C_MC_KEY ((unsigned int) 0xFF << 24) // (MC) Writing Protect Key -// -------- MC_FSR : (MC Offset: 0x68) MC Flash Command Register -------- -#define AT91C_MC_SECURITY ((unsigned int) 0x1 << 4) // (MC) Security Bit Status -#define AT91C_MC_GPNVM0 ((unsigned int) 0x1 << 8) // (MC) Sector 0 Lock Status -#define AT91C_MC_GPNVM1 ((unsigned int) 0x1 << 9) // (MC) Sector 1 Lock Status -#define AT91C_MC_GPNVM2 ((unsigned int) 0x1 << 10) // (MC) Sector 2 Lock Status -#define AT91C_MC_GPNVM3 ((unsigned int) 0x1 << 11) // (MC) Sector 3 Lock Status -#define AT91C_MC_GPNVM4 ((unsigned int) 0x1 << 12) // (MC) Sector 4 Lock Status -#define AT91C_MC_GPNVM5 ((unsigned int) 0x1 << 13) // (MC) Sector 5 Lock Status -#define AT91C_MC_GPNVM6 ((unsigned int) 0x1 << 14) // (MC) Sector 6 Lock Status -#define AT91C_MC_GPNVM7 ((unsigned int) 0x1 << 15) // (MC) Sector 7 Lock Status -#define AT91C_MC_LOCKS0 ((unsigned int) 0x1 << 16) // (MC) Sector 0 Lock Status -#define AT91C_MC_LOCKS1 ((unsigned int) 0x1 << 17) // (MC) Sector 1 Lock Status -#define AT91C_MC_LOCKS2 ((unsigned int) 0x1 << 18) // (MC) Sector 2 Lock Status -#define AT91C_MC_LOCKS3 ((unsigned int) 0x1 << 19) // (MC) Sector 3 Lock Status -#define AT91C_MC_LOCKS4 ((unsigned int) 0x1 << 20) // (MC) Sector 4 Lock Status -#define AT91C_MC_LOCKS5 ((unsigned int) 0x1 << 21) // (MC) Sector 5 Lock Status -#define AT91C_MC_LOCKS6 ((unsigned int) 0x1 << 22) // (MC) Sector 6 Lock Status -#define AT91C_MC_LOCKS7 ((unsigned int) 0x1 << 23) // (MC) Sector 7 Lock Status -#define AT91C_MC_LOCKS8 ((unsigned int) 0x1 << 24) // (MC) Sector 8 Lock Status -#define AT91C_MC_LOCKS9 ((unsigned int) 0x1 << 25) // (MC) Sector 9 Lock Status -#define AT91C_MC_LOCKS10 ((unsigned int) 0x1 << 26) // (MC) Sector 10 Lock Status -#define AT91C_MC_LOCKS11 ((unsigned int) 0x1 << 27) // (MC) Sector 11 Lock Status -#define AT91C_MC_LOCKS12 ((unsigned int) 0x1 << 28) // (MC) Sector 12 Lock Status -#define AT91C_MC_LOCKS13 ((unsigned int) 0x1 << 29) // (MC) Sector 13 Lock Status -#define AT91C_MC_LOCKS14 ((unsigned int) 0x1 << 30) // (MC) Sector 14 Lock Status -#define AT91C_MC_LOCKS15 ((unsigned int) 0x1 << 31) // (MC) Sector 15 Lock Status - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Serial Parallel Interface -// ***************************************************************************** -typedef struct _AT91S_SPI { - AT91_REG SPI_CR; // Control Register - AT91_REG SPI_MR; // Mode Register - AT91_REG SPI_RDR; // Receive Data Register - AT91_REG SPI_TDR; // Transmit Data Register - AT91_REG SPI_SR; // Status Register - AT91_REG SPI_IER; // Interrupt Enable Register - AT91_REG SPI_IDR; // Interrupt Disable Register - AT91_REG SPI_IMR; // Interrupt Mask Register - AT91_REG Reserved0[4]; // - AT91_REG SPI_CSR[4]; // Chip Select Register - AT91_REG Reserved1[48]; // - AT91_REG SPI_RPR; // Receive Pointer Register - AT91_REG SPI_RCR; // Receive Counter Register - AT91_REG SPI_TPR; // Transmit Pointer Register - AT91_REG SPI_TCR; // Transmit Counter Register - AT91_REG SPI_RNPR; // Receive Next Pointer Register - AT91_REG SPI_RNCR; // Receive Next Counter Register - AT91_REG SPI_TNPR; // Transmit Next Pointer Register - AT91_REG SPI_TNCR; // Transmit Next Counter Register - AT91_REG SPI_PTCR; // PDC Transfer Control Register - AT91_REG SPI_PTSR; // PDC Transfer Status Register -} AT91S_SPI, *AT91PS_SPI; - -// -------- SPI_CR : (SPI Offset: 0x0) SPI Control Register -------- -#define AT91C_SPI_SPIEN ((unsigned int) 0x1 << 0) // (SPI) SPI Enable -#define AT91C_SPI_SPIDIS ((unsigned int) 0x1 << 1) // (SPI) SPI Disable -#define AT91C_SPI_SWRST ((unsigned int) 0x1 << 7) // (SPI) SPI Software reset -#define AT91C_SPI_LASTXFER ((unsigned int) 0x1 << 24) // (SPI) SPI Last Transfer -// -------- SPI_MR : (SPI Offset: 0x4) SPI Mode Register -------- -#define AT91C_SPI_MSTR ((unsigned int) 0x1 << 0) // (SPI) Master/Slave Mode -#define AT91C_SPI_PS ((unsigned int) 0x1 << 1) // (SPI) Peripheral Select -#define AT91C_SPI_PS_FIXED ((unsigned int) 0x0 << 1) // (SPI) Fixed Peripheral Select -#define AT91C_SPI_PS_VARIABLE ((unsigned int) 0x1 << 1) // (SPI) Variable Peripheral Select -#define AT91C_SPI_PCSDEC ((unsigned int) 0x1 << 2) // (SPI) Chip Select Decode -#define AT91C_SPI_FDIV ((unsigned int) 0x1 << 3) // (SPI) Clock Selection -#define AT91C_SPI_MODFDIS ((unsigned int) 0x1 << 4) // (SPI) Mode Fault Detection -#define AT91C_SPI_LLB ((unsigned int) 0x1 << 7) // (SPI) Clock Selection -#define AT91C_SPI_PCS ((unsigned int) 0xF << 16) // (SPI) Peripheral Chip Select -#define AT91C_SPI_DLYBCS ((unsigned int) 0xFF << 24) // (SPI) Delay Between Chip Selects -// -------- SPI_RDR : (SPI Offset: 0x8) Receive Data Register -------- -#define AT91C_SPI_RD ((unsigned int) 0xFFFF << 0) // (SPI) Receive Data -#define AT91C_SPI_RPCS ((unsigned int) 0xF << 16) // (SPI) Peripheral Chip Select Status -// -------- SPI_TDR : (SPI Offset: 0xc) Transmit Data Register -------- -#define AT91C_SPI_TD ((unsigned int) 0xFFFF << 0) // (SPI) Transmit Data -#define AT91C_SPI_TPCS ((unsigned int) 0xF << 16) // (SPI) Peripheral Chip Select Status -// -------- SPI_SR : (SPI Offset: 0x10) Status Register -------- -#define AT91C_SPI_RDRF ((unsigned int) 0x1 << 0) // (SPI) Receive Data Register Full -#define AT91C_SPI_TDRE ((unsigned int) 0x1 << 1) // (SPI) Transmit Data Register Empty -#define AT91C_SPI_MODF ((unsigned int) 0x1 << 2) // (SPI) Mode Fault Error -#define AT91C_SPI_OVRES ((unsigned int) 0x1 << 3) // (SPI) Overrun Error Status -#define AT91C_SPI_ENDRX ((unsigned int) 0x1 << 4) // (SPI) End of Receiver Transfer -#define AT91C_SPI_ENDTX ((unsigned int) 0x1 << 5) // (SPI) End of Receiver Transfer -#define AT91C_SPI_RXBUFF ((unsigned int) 0x1 << 6) // (SPI) RXBUFF Interrupt -#define AT91C_SPI_TXBUFE ((unsigned int) 0x1 << 7) // (SPI) TXBUFE Interrupt -#define AT91C_SPI_NSSR ((unsigned int) 0x1 << 8) // (SPI) NSSR Interrupt -#define AT91C_SPI_TXEMPTY ((unsigned int) 0x1 << 9) // (SPI) TXEMPTY Interrupt -#define AT91C_SPI_SPIENS ((unsigned int) 0x1 << 16) // (SPI) Enable Status -// -------- SPI_IER : (SPI Offset: 0x14) Interrupt Enable Register -------- -// -------- SPI_IDR : (SPI Offset: 0x18) Interrupt Disable Register -------- -// -------- SPI_IMR : (SPI Offset: 0x1c) Interrupt Mask Register -------- -// -------- SPI_CSR : (SPI Offset: 0x30) Chip Select Register -------- -#define AT91C_SPI_CPOL ((unsigned int) 0x1 << 0) // (SPI) Clock Polarity -#define AT91C_SPI_NCPHA ((unsigned int) 0x1 << 1) // (SPI) Clock Phase -#define AT91C_SPI_CSAAT ((unsigned int) 0x1 << 3) // (SPI) Chip Select Active After Transfer -#define AT91C_SPI_BITS ((unsigned int) 0xF << 4) // (SPI) Bits Per Transfer -#define AT91C_SPI_BITS_8 ((unsigned int) 0x0 << 4) // (SPI) 8 Bits Per transfer -#define AT91C_SPI_BITS_9 ((unsigned int) 0x1 << 4) // (SPI) 9 Bits Per transfer -#define AT91C_SPI_BITS_10 ((unsigned int) 0x2 << 4) // (SPI) 10 Bits Per transfer -#define AT91C_SPI_BITS_11 ((unsigned int) 0x3 << 4) // (SPI) 11 Bits Per transfer -#define AT91C_SPI_BITS_12 ((unsigned int) 0x4 << 4) // (SPI) 12 Bits Per transfer -#define AT91C_SPI_BITS_13 ((unsigned int) 0x5 << 4) // (SPI) 13 Bits Per transfer -#define AT91C_SPI_BITS_14 ((unsigned int) 0x6 << 4) // (SPI) 14 Bits Per transfer -#define AT91C_SPI_BITS_15 ((unsigned int) 0x7 << 4) // (SPI) 15 Bits Per transfer -#define AT91C_SPI_BITS_16 ((unsigned int) 0x8 << 4) // (SPI) 16 Bits Per transfer -#define AT91C_SPI_SCBR ((unsigned int) 0xFF << 8) // (SPI) Serial Clock Baud Rate -#define AT91C_SPI_DLYBS ((unsigned int) 0xFF << 16) // (SPI) Serial Clock Baud Rate -#define AT91C_SPI_DLYBCT ((unsigned int) 0xFF << 24) // (SPI) Delay Between Consecutive Transfers - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Analog to Digital Convertor -// ***************************************************************************** -typedef struct _AT91S_ADC { - AT91_REG ADC_CR; // ADC Control Register - AT91_REG ADC_MR; // ADC Mode Register - AT91_REG Reserved0[2]; // - AT91_REG ADC_CHER; // ADC Channel Enable Register - AT91_REG ADC_CHDR; // ADC Channel Disable Register - AT91_REG ADC_CHSR; // ADC Channel Status Register - AT91_REG ADC_SR; // ADC Status Register - AT91_REG ADC_LCDR; // ADC Last Converted Data Register - AT91_REG ADC_IER; // ADC Interrupt Enable Register - AT91_REG ADC_IDR; // ADC Interrupt Disable Register - AT91_REG ADC_IMR; // ADC Interrupt Mask Register - AT91_REG ADC_CDR0; // ADC Channel Data Register 0 - AT91_REG ADC_CDR1; // ADC Channel Data Register 1 - AT91_REG ADC_CDR2; // ADC Channel Data Register 2 - AT91_REG ADC_CDR3; // ADC Channel Data Register 3 - AT91_REG ADC_CDR4; // ADC Channel Data Register 4 - AT91_REG ADC_CDR5; // ADC Channel Data Register 5 - AT91_REG ADC_CDR6; // ADC Channel Data Register 6 - AT91_REG ADC_CDR7; // ADC Channel Data Register 7 - AT91_REG Reserved1[44]; // - AT91_REG ADC_RPR; // Receive Pointer Register - AT91_REG ADC_RCR; // Receive Counter Register - AT91_REG ADC_TPR; // Transmit Pointer Register - AT91_REG ADC_TCR; // Transmit Counter Register - AT91_REG ADC_RNPR; // Receive Next Pointer Register - AT91_REG ADC_RNCR; // Receive Next Counter Register - AT91_REG ADC_TNPR; // Transmit Next Pointer Register - AT91_REG ADC_TNCR; // Transmit Next Counter Register - AT91_REG ADC_PTCR; // PDC Transfer Control Register - AT91_REG ADC_PTSR; // PDC Transfer Status Register -} AT91S_ADC, *AT91PS_ADC; - -// -------- ADC_CR : (ADC Offset: 0x0) ADC Control Register -------- -#define AT91C_ADC_SWRST ((unsigned int) 0x1 << 0) // (ADC) Software Reset -#define AT91C_ADC_START ((unsigned int) 0x1 << 1) // (ADC) Start Conversion -// -------- ADC_MR : (ADC Offset: 0x4) ADC Mode Register -------- -#define AT91C_ADC_TRGEN ((unsigned int) 0x1 << 0) // (ADC) Trigger Enable -#define AT91C_ADC_TRGEN_DIS ((unsigned int) 0x0) // (ADC) Hradware triggers are disabled. Starting a conversion is only possible by software -#define AT91C_ADC_TRGEN_EN ((unsigned int) 0x1) // (ADC) Hardware trigger selected by TRGSEL field is enabled. -#define AT91C_ADC_TRGSEL ((unsigned int) 0x7 << 1) // (ADC) Trigger Selection -#define AT91C_ADC_TRGSEL_TIOA0 ((unsigned int) 0x0 << 1) // (ADC) Selected TRGSEL = TIAO0 -#define AT91C_ADC_TRGSEL_TIOA1 ((unsigned int) 0x1 << 1) // (ADC) Selected TRGSEL = TIAO1 -#define AT91C_ADC_TRGSEL_TIOA2 ((unsigned int) 0x2 << 1) // (ADC) Selected TRGSEL = TIAO2 -#define AT91C_ADC_TRGSEL_TIOA3 ((unsigned int) 0x3 << 1) // (ADC) Selected TRGSEL = TIAO3 -#define AT91C_ADC_TRGSEL_TIOA4 ((unsigned int) 0x4 << 1) // (ADC) Selected TRGSEL = TIAO4 -#define AT91C_ADC_TRGSEL_TIOA5 ((unsigned int) 0x5 << 1) // (ADC) Selected TRGSEL = TIAO5 -#define AT91C_ADC_TRGSEL_EXT ((unsigned int) 0x6 << 1) // (ADC) Selected TRGSEL = External Trigger -#define AT91C_ADC_LOWRES ((unsigned int) 0x1 << 4) // (ADC) Resolution. -#define AT91C_ADC_LOWRES_10_BIT ((unsigned int) 0x0 << 4) // (ADC) 10-bit resolution -#define AT91C_ADC_LOWRES_8_BIT ((unsigned int) 0x1 << 4) // (ADC) 8-bit resolution -#define AT91C_ADC_SLEEP ((unsigned int) 0x1 << 5) // (ADC) Sleep Mode -#define AT91C_ADC_SLEEP_NORMAL_MODE ((unsigned int) 0x0 << 5) // (ADC) Normal Mode -#define AT91C_ADC_SLEEP_MODE ((unsigned int) 0x1 << 5) // (ADC) Sleep Mode -#define AT91C_ADC_PRESCAL ((unsigned int) 0x3F << 8) // (ADC) Prescaler rate selection -#define AT91C_ADC_STARTUP ((unsigned int) 0x1F << 16) // (ADC) Startup Time -#define AT91C_ADC_SHTIM ((unsigned int) 0xF << 24) // (ADC) Sample & Hold Time -// -------- ADC_CHER : (ADC Offset: 0x10) ADC Channel Enable Register -------- -#define AT91C_ADC_CH0 ((unsigned int) 0x1 << 0) // (ADC) Channel 0 -#define AT91C_ADC_CH1 ((unsigned int) 0x1 << 1) // (ADC) Channel 1 -#define AT91C_ADC_CH2 ((unsigned int) 0x1 << 2) // (ADC) Channel 2 -#define AT91C_ADC_CH3 ((unsigned int) 0x1 << 3) // (ADC) Channel 3 -#define AT91C_ADC_CH4 ((unsigned int) 0x1 << 4) // (ADC) Channel 4 -#define AT91C_ADC_CH5 ((unsigned int) 0x1 << 5) // (ADC) Channel 5 -#define AT91C_ADC_CH6 ((unsigned int) 0x1 << 6) // (ADC) Channel 6 -#define AT91C_ADC_CH7 ((unsigned int) 0x1 << 7) // (ADC) Channel 7 -// -------- ADC_CHDR : (ADC Offset: 0x14) ADC Channel Disable Register -------- -// -------- ADC_CHSR : (ADC Offset: 0x18) ADC Channel Status Register -------- -// -------- ADC_SR : (ADC Offset: 0x1c) ADC Status Register -------- -#define AT91C_ADC_EOC0 ((unsigned int) 0x1 << 0) // (ADC) End of Conversion -#define AT91C_ADC_EOC1 ((unsigned int) 0x1 << 1) // (ADC) End of Conversion -#define AT91C_ADC_EOC2 ((unsigned int) 0x1 << 2) // (ADC) End of Conversion -#define AT91C_ADC_EOC3 ((unsigned int) 0x1 << 3) // (ADC) End of Conversion -#define AT91C_ADC_EOC4 ((unsigned int) 0x1 << 4) // (ADC) End of Conversion -#define AT91C_ADC_EOC5 ((unsigned int) 0x1 << 5) // (ADC) End of Conversion -#define AT91C_ADC_EOC6 ((unsigned int) 0x1 << 6) // (ADC) End of Conversion -#define AT91C_ADC_EOC7 ((unsigned int) 0x1 << 7) // (ADC) End of Conversion -#define AT91C_ADC_OVRE0 ((unsigned int) 0x1 << 8) // (ADC) Overrun Error -#define AT91C_ADC_OVRE1 ((unsigned int) 0x1 << 9) // (ADC) Overrun Error -#define AT91C_ADC_OVRE2 ((unsigned int) 0x1 << 10) // (ADC) Overrun Error -#define AT91C_ADC_OVRE3 ((unsigned int) 0x1 << 11) // (ADC) Overrun Error -#define AT91C_ADC_OVRE4 ((unsigned int) 0x1 << 12) // (ADC) Overrun Error -#define AT91C_ADC_OVRE5 ((unsigned int) 0x1 << 13) // (ADC) Overrun Error -#define AT91C_ADC_OVRE6 ((unsigned int) 0x1 << 14) // (ADC) Overrun Error -#define AT91C_ADC_OVRE7 ((unsigned int) 0x1 << 15) // (ADC) Overrun Error -#define AT91C_ADC_DRDY ((unsigned int) 0x1 << 16) // (ADC) Data Ready -#define AT91C_ADC_GOVRE ((unsigned int) 0x1 << 17) // (ADC) General Overrun -#define AT91C_ADC_ENDRX ((unsigned int) 0x1 << 18) // (ADC) End of Receiver Transfer -#define AT91C_ADC_RXBUFF ((unsigned int) 0x1 << 19) // (ADC) RXBUFF Interrupt -// -------- ADC_LCDR : (ADC Offset: 0x20) ADC Last Converted Data Register -------- -#define AT91C_ADC_LDATA ((unsigned int) 0x3FF << 0) // (ADC) Last Data Converted -// -------- ADC_IER : (ADC Offset: 0x24) ADC Interrupt Enable Register -------- -// -------- ADC_IDR : (ADC Offset: 0x28) ADC Interrupt Disable Register -------- -// -------- ADC_IMR : (ADC Offset: 0x2c) ADC Interrupt Mask Register -------- -// -------- ADC_CDR0 : (ADC Offset: 0x30) ADC Channel Data Register 0 -------- -#define AT91C_ADC_DATA ((unsigned int) 0x3FF << 0) // (ADC) Converted Data -// -------- ADC_CDR1 : (ADC Offset: 0x34) ADC Channel Data Register 1 -------- -// -------- ADC_CDR2 : (ADC Offset: 0x38) ADC Channel Data Register 2 -------- -// -------- ADC_CDR3 : (ADC Offset: 0x3c) ADC Channel Data Register 3 -------- -// -------- ADC_CDR4 : (ADC Offset: 0x40) ADC Channel Data Register 4 -------- -// -------- ADC_CDR5 : (ADC Offset: 0x44) ADC Channel Data Register 5 -------- -// -------- ADC_CDR6 : (ADC Offset: 0x48) ADC Channel Data Register 6 -------- -// -------- ADC_CDR7 : (ADC Offset: 0x4c) ADC Channel Data Register 7 -------- - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Synchronous Serial Controller Interface -// ***************************************************************************** -typedef struct _AT91S_SSC { - AT91_REG SSC_CR; // Control Register - AT91_REG SSC_CMR; // Clock Mode Register - AT91_REG Reserved0[2]; // - AT91_REG SSC_RCMR; // Receive Clock ModeRegister - AT91_REG SSC_RFMR; // Receive Frame Mode Register - AT91_REG SSC_TCMR; // Transmit Clock Mode Register - AT91_REG SSC_TFMR; // Transmit Frame Mode Register - AT91_REG SSC_RHR; // Receive Holding Register - AT91_REG SSC_THR; // Transmit Holding Register - AT91_REG Reserved1[2]; // - AT91_REG SSC_RSHR; // Receive Sync Holding Register - AT91_REG SSC_TSHR; // Transmit Sync Holding Register - AT91_REG Reserved2[2]; // - AT91_REG SSC_SR; // Status Register - AT91_REG SSC_IER; // Interrupt Enable Register - AT91_REG SSC_IDR; // Interrupt Disable Register - AT91_REG SSC_IMR; // Interrupt Mask Register - AT91_REG Reserved3[44]; // - AT91_REG SSC_RPR; // Receive Pointer Register - AT91_REG SSC_RCR; // Receive Counter Register - AT91_REG SSC_TPR; // Transmit Pointer Register - AT91_REG SSC_TCR; // Transmit Counter Register - AT91_REG SSC_RNPR; // Receive Next Pointer Register - AT91_REG SSC_RNCR; // Receive Next Counter Register - AT91_REG SSC_TNPR; // Transmit Next Pointer Register - AT91_REG SSC_TNCR; // Transmit Next Counter Register - AT91_REG SSC_PTCR; // PDC Transfer Control Register - AT91_REG SSC_PTSR; // PDC Transfer Status Register -} AT91S_SSC, *AT91PS_SSC; - -// -------- SSC_CR : (SSC Offset: 0x0) SSC Control Register -------- -#define AT91C_SSC_RXEN ((unsigned int) 0x1 << 0) // (SSC) Receive Enable -#define AT91C_SSC_RXDIS ((unsigned int) 0x1 << 1) // (SSC) Receive Disable -#define AT91C_SSC_TXEN ((unsigned int) 0x1 << 8) // (SSC) Transmit Enable -#define AT91C_SSC_TXDIS ((unsigned int) 0x1 << 9) // (SSC) Transmit Disable -#define AT91C_SSC_SWRST ((unsigned int) 0x1 << 15) // (SSC) Software Reset -// -------- SSC_RCMR : (SSC Offset: 0x10) SSC Receive Clock Mode Register -------- -#define AT91C_SSC_CKS ((unsigned int) 0x3 << 0) // (SSC) Receive/Transmit Clock Selection -#define AT91C_SSC_CKS_DIV ((unsigned int) 0x0) // (SSC) Divided Clock -#define AT91C_SSC_CKS_TK ((unsigned int) 0x1) // (SSC) TK Clock signal -#define AT91C_SSC_CKS_RK ((unsigned int) 0x2) // (SSC) RK pin -#define AT91C_SSC_CKO ((unsigned int) 0x7 << 2) // (SSC) Receive/Transmit Clock Output Mode Selection -#define AT91C_SSC_CKO_NONE ((unsigned int) 0x0 << 2) // (SSC) Receive/Transmit Clock Output Mode: None RK pin: Input-only -#define AT91C_SSC_CKO_CONTINOUS ((unsigned int) 0x1 << 2) // (SSC) Continuous Receive/Transmit Clock RK pin: Output -#define AT91C_SSC_CKO_DATA_TX ((unsigned int) 0x2 << 2) // (SSC) Receive/Transmit Clock only during data transfers RK pin: Output -#define AT91C_SSC_CKI ((unsigned int) 0x1 << 5) // (SSC) Receive/Transmit Clock Inversion -#define AT91C_SSC_START ((unsigned int) 0xF << 8) // (SSC) Receive/Transmit Start Selection -#define AT91C_SSC_START_CONTINOUS ((unsigned int) 0x0 << 8) // (SSC) Continuous, as soon as the receiver is enabled, and immediately after the end of transfer of the previous data. -#define AT91C_SSC_START_TX ((unsigned int) 0x1 << 8) // (SSC) Transmit/Receive start -#define AT91C_SSC_START_LOW_RF ((unsigned int) 0x2 << 8) // (SSC) Detection of a low level on RF input -#define AT91C_SSC_START_HIGH_RF ((unsigned int) 0x3 << 8) // (SSC) Detection of a high level on RF input -#define AT91C_SSC_START_FALL_RF ((unsigned int) 0x4 << 8) // (SSC) Detection of a falling edge on RF input -#define AT91C_SSC_START_RISE_RF ((unsigned int) 0x5 << 8) // (SSC) Detection of a rising edge on RF input -#define AT91C_SSC_START_LEVEL_RF ((unsigned int) 0x6 << 8) // (SSC) Detection of any level change on RF input -#define AT91C_SSC_START_EDGE_RF ((unsigned int) 0x7 << 8) // (SSC) Detection of any edge on RF input -#define AT91C_SSC_START_0 ((unsigned int) 0x8 << 8) // (SSC) Compare 0 -#define AT91C_SSC_STTDLY ((unsigned int) 0xFF << 16) // (SSC) Receive/Transmit Start Delay -#define AT91C_SSC_PERIOD ((unsigned int) 0xFF << 24) // (SSC) Receive/Transmit Period Divider Selection -// -------- SSC_RFMR : (SSC Offset: 0x14) SSC Receive Frame Mode Register -------- -#define AT91C_SSC_DATLEN ((unsigned int) 0x1F << 0) // (SSC) Data Length -#define AT91C_SSC_LOOP ((unsigned int) 0x1 << 5) // (SSC) Loop Mode -#define AT91C_SSC_MSBF ((unsigned int) 0x1 << 7) // (SSC) Most Significant Bit First -#define AT91C_SSC_DATNB ((unsigned int) 0xF << 8) // (SSC) Data Number per Frame -#define AT91C_SSC_FSLEN ((unsigned int) 0xF << 16) // (SSC) Receive/Transmit Frame Sync length -#define AT91C_SSC_FSOS ((unsigned int) 0x7 << 20) // (SSC) Receive/Transmit Frame Sync Output Selection -#define AT91C_SSC_FSOS_NONE ((unsigned int) 0x0 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: None RK pin Input-only -#define AT91C_SSC_FSOS_NEGATIVE ((unsigned int) 0x1 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Negative Pulse -#define AT91C_SSC_FSOS_POSITIVE ((unsigned int) 0x2 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Positive Pulse -#define AT91C_SSC_FSOS_LOW ((unsigned int) 0x3 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Driver Low during data transfer -#define AT91C_SSC_FSOS_HIGH ((unsigned int) 0x4 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Driver High during data transfer -#define AT91C_SSC_FSOS_TOGGLE ((unsigned int) 0x5 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Toggling at each start of data transfer -#define AT91C_SSC_FSEDGE ((unsigned int) 0x1 << 24) // (SSC) Frame Sync Edge Detection -// -------- SSC_TCMR : (SSC Offset: 0x18) SSC Transmit Clock Mode Register -------- -// -------- SSC_TFMR : (SSC Offset: 0x1c) SSC Transmit Frame Mode Register -------- -#define AT91C_SSC_DATDEF ((unsigned int) 0x1 << 5) // (SSC) Data Default Value -#define AT91C_SSC_FSDEN ((unsigned int) 0x1 << 23) // (SSC) Frame Sync Data Enable -// -------- SSC_SR : (SSC Offset: 0x40) SSC Status Register -------- -#define AT91C_SSC_TXRDY ((unsigned int) 0x1 << 0) // (SSC) Transmit Ready -#define AT91C_SSC_TXEMPTY ((unsigned int) 0x1 << 1) // (SSC) Transmit Empty -#define AT91C_SSC_ENDTX ((unsigned int) 0x1 << 2) // (SSC) End Of Transmission -#define AT91C_SSC_TXBUFE ((unsigned int) 0x1 << 3) // (SSC) Transmit Buffer Empty -#define AT91C_SSC_RXRDY ((unsigned int) 0x1 << 4) // (SSC) Receive Ready -#define AT91C_SSC_OVRUN ((unsigned int) 0x1 << 5) // (SSC) Receive Overrun -#define AT91C_SSC_ENDRX ((unsigned int) 0x1 << 6) // (SSC) End of Reception -#define AT91C_SSC_RXBUFF ((unsigned int) 0x1 << 7) // (SSC) Receive Buffer Full -#define AT91C_SSC_TXSYN ((unsigned int) 0x1 << 10) // (SSC) Transmit Sync -#define AT91C_SSC_RXSYN ((unsigned int) 0x1 << 11) // (SSC) Receive Sync -#define AT91C_SSC_TXENA ((unsigned int) 0x1 << 16) // (SSC) Transmit Enable -#define AT91C_SSC_RXENA ((unsigned int) 0x1 << 17) // (SSC) Receive Enable -// -------- SSC_IER : (SSC Offset: 0x44) SSC Interrupt Enable Register -------- -// -------- SSC_IDR : (SSC Offset: 0x48) SSC Interrupt Disable Register -------- -// -------- SSC_IMR : (SSC Offset: 0x4c) SSC Interrupt Mask Register -------- - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Usart -// ***************************************************************************** -typedef struct _AT91S_USART { - AT91_REG US_CR; // Control Register - AT91_REG US_MR; // Mode Register - AT91_REG US_IER; // Interrupt Enable Register - AT91_REG US_IDR; // Interrupt Disable Register - AT91_REG US_IMR; // Interrupt Mask Register - AT91_REG US_CSR; // Channel Status Register - AT91_REG US_RHR; // Receiver Holding Register - AT91_REG US_THR; // Transmitter Holding Register - AT91_REG US_BRGR; // Baud Rate Generator Register - AT91_REG US_RTOR; // Receiver Time-out Register - AT91_REG US_TTGR; // Transmitter Time-guard Register - AT91_REG Reserved0[5]; // - AT91_REG US_FIDI; // FI_DI_Ratio Register - AT91_REG US_NER; // Nb Errors Register - AT91_REG Reserved1[1]; // - AT91_REG US_IF; // IRDA_FILTER Register - AT91_REG Reserved2[44]; // - AT91_REG US_RPR; // Receive Pointer Register - AT91_REG US_RCR; // Receive Counter Register - AT91_REG US_TPR; // Transmit Pointer Register - AT91_REG US_TCR; // Transmit Counter Register - AT91_REG US_RNPR; // Receive Next Pointer Register - AT91_REG US_RNCR; // Receive Next Counter Register - AT91_REG US_TNPR; // Transmit Next Pointer Register - AT91_REG US_TNCR; // Transmit Next Counter Register - AT91_REG US_PTCR; // PDC Transfer Control Register - AT91_REG US_PTSR; // PDC Transfer Status Register -} AT91S_USART, *AT91PS_USART; - -// -------- US_CR : (USART Offset: 0x0) Debug Unit Control Register -------- -#define AT91C_US_STTBRK ((unsigned int) 0x1 << 9) // (USART) Start Break -#define AT91C_US_STPBRK ((unsigned int) 0x1 << 10) // (USART) Stop Break -#define AT91C_US_STTTO ((unsigned int) 0x1 << 11) // (USART) Start Time-out -#define AT91C_US_SENDA ((unsigned int) 0x1 << 12) // (USART) Send Address -#define AT91C_US_RSTIT ((unsigned int) 0x1 << 13) // (USART) Reset Iterations -#define AT91C_US_RSTNACK ((unsigned int) 0x1 << 14) // (USART) Reset Non Acknowledge -#define AT91C_US_RETTO ((unsigned int) 0x1 << 15) // (USART) Rearm Time-out -#define AT91C_US_DTREN ((unsigned int) 0x1 << 16) // (USART) Data Terminal ready Enable -#define AT91C_US_DTRDIS ((unsigned int) 0x1 << 17) // (USART) Data Terminal ready Disable -#define AT91C_US_RTSEN ((unsigned int) 0x1 << 18) // (USART) Request to Send enable -#define AT91C_US_RTSDIS ((unsigned int) 0x1 << 19) // (USART) Request to Send Disable -// -------- US_MR : (USART Offset: 0x4) Debug Unit Mode Register -------- -#define AT91C_US_USMODE ((unsigned int) 0xF << 0) // (USART) Usart mode -#define AT91C_US_USMODE_NORMAL ((unsigned int) 0x0) // (USART) Normal -#define AT91C_US_USMODE_RS485 ((unsigned int) 0x1) // (USART) RS485 -#define AT91C_US_USMODE_HWHSH ((unsigned int) 0x2) // (USART) Hardware Handshaking -#define AT91C_US_USMODE_MODEM ((unsigned int) 0x3) // (USART) Modem -#define AT91C_US_USMODE_ISO7816_0 ((unsigned int) 0x4) // (USART) ISO7816 protocol: T = 0 -#define AT91C_US_USMODE_ISO7816_1 ((unsigned int) 0x6) // (USART) ISO7816 protocol: T = 1 -#define AT91C_US_USMODE_IRDA ((unsigned int) 0x8) // (USART) IrDA -#define AT91C_US_USMODE_SWHSH ((unsigned int) 0xC) // (USART) Software Handshaking -#define AT91C_US_CLKS ((unsigned int) 0x3 << 4) // (USART) Clock Selection (Baud Rate generator Input Clock -#define AT91C_US_CLKS_CLOCK ((unsigned int) 0x0 << 4) // (USART) Clock -#define AT91C_US_CLKS_FDIV1 ((unsigned int) 0x1 << 4) // (USART) fdiv1 -#define AT91C_US_CLKS_SLOW ((unsigned int) 0x2 << 4) // (USART) slow_clock (ARM) -#define AT91C_US_CLKS_EXT ((unsigned int) 0x3 << 4) // (USART) External (SCK) -#define AT91C_US_CHRL ((unsigned int) 0x3 << 6) // (USART) Clock Selection (Baud Rate generator Input Clock -#define AT91C_US_CHRL_5_BITS ((unsigned int) 0x0 << 6) // (USART) Character Length: 5 bits -#define AT91C_US_CHRL_6_BITS ((unsigned int) 0x1 << 6) // (USART) Character Length: 6 bits -#define AT91C_US_CHRL_7_BITS ((unsigned int) 0x2 << 6) // (USART) Character Length: 7 bits -#define AT91C_US_CHRL_8_BITS ((unsigned int) 0x3 << 6) // (USART) Character Length: 8 bits -#define AT91C_US_SYNC ((unsigned int) 0x1 << 8) // (USART) Synchronous Mode Select -#define AT91C_US_NBSTOP ((unsigned int) 0x3 << 12) // (USART) Number of Stop bits -#define AT91C_US_NBSTOP_1_BIT ((unsigned int) 0x0 << 12) // (USART) 1 stop bit -#define AT91C_US_NBSTOP_15_BIT ((unsigned int) 0x1 << 12) // (USART) Asynchronous (SYNC=0) 2 stop bits Synchronous (SYNC=1) 2 stop bits -#define AT91C_US_NBSTOP_2_BIT ((unsigned int) 0x2 << 12) // (USART) 2 stop bits -#define AT91C_US_MSBF ((unsigned int) 0x1 << 16) // (USART) Bit Order -#define AT91C_US_MODE9 ((unsigned int) 0x1 << 17) // (USART) 9-bit Character length -#define AT91C_US_CKLO ((unsigned int) 0x1 << 18) // (USART) Clock Output Select -#define AT91C_US_OVER ((unsigned int) 0x1 << 19) // (USART) Over Sampling Mode -#define AT91C_US_INACK ((unsigned int) 0x1 << 20) // (USART) Inhibit Non Acknowledge -#define AT91C_US_DSNACK ((unsigned int) 0x1 << 21) // (USART) Disable Successive NACK -#define AT91C_US_MAX_ITER ((unsigned int) 0x1 << 24) // (USART) Number of Repetitions -#define AT91C_US_FILTER ((unsigned int) 0x1 << 28) // (USART) Receive Line Filter -// -------- US_IER : (USART Offset: 0x8) Debug Unit Interrupt Enable Register -------- -#define AT91C_US_RXBRK ((unsigned int) 0x1 << 2) // (USART) Break Received/End of Break -#define AT91C_US_TIMEOUT ((unsigned int) 0x1 << 8) // (USART) Receiver Time-out -#define AT91C_US_ITERATION ((unsigned int) 0x1 << 10) // (USART) Max number of Repetitions Reached -#define AT91C_US_NACK ((unsigned int) 0x1 << 13) // (USART) Non Acknowledge -#define AT91C_US_RIIC ((unsigned int) 0x1 << 16) // (USART) Ring INdicator Input Change Flag -#define AT91C_US_DSRIC ((unsigned int) 0x1 << 17) // (USART) Data Set Ready Input Change Flag -#define AT91C_US_DCDIC ((unsigned int) 0x1 << 18) // (USART) Data Carrier Flag -#define AT91C_US_CTSIC ((unsigned int) 0x1 << 19) // (USART) Clear To Send Input Change Flag -// -------- US_IDR : (USART Offset: 0xc) Debug Unit Interrupt Disable Register -------- -// -------- US_IMR : (USART Offset: 0x10) Debug Unit Interrupt Mask Register -------- -// -------- US_CSR : (USART Offset: 0x14) Debug Unit Channel Status Register -------- -#define AT91C_US_RI ((unsigned int) 0x1 << 20) // (USART) Image of RI Input -#define AT91C_US_DSR ((unsigned int) 0x1 << 21) // (USART) Image of DSR Input -#define AT91C_US_DCD ((unsigned int) 0x1 << 22) // (USART) Image of DCD Input -#define AT91C_US_CTS ((unsigned int) 0x1 << 23) // (USART) Image of CTS Input - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Two-wire Interface -// ***************************************************************************** -typedef struct _AT91S_TWI { - AT91_REG TWI_CR; // Control Register - AT91_REG TWI_MMR; // Master Mode Register - AT91_REG Reserved0[1]; // - AT91_REG TWI_IADR; // Internal Address Register - AT91_REG TWI_CWGR; // Clock Waveform Generator Register - AT91_REG Reserved1[3]; // - AT91_REG TWI_SR; // Status Register - AT91_REG TWI_IER; // Interrupt Enable Register - AT91_REG TWI_IDR; // Interrupt Disable Register - AT91_REG TWI_IMR; // Interrupt Mask Register - AT91_REG TWI_RHR; // Receive Holding Register - AT91_REG TWI_THR; // Transmit Holding Register -} AT91S_TWI, *AT91PS_TWI; - -// -------- TWI_CR : (TWI Offset: 0x0) TWI Control Register -------- -#define AT91C_TWI_START ((unsigned int) 0x1 << 0) // (TWI) Send a START Condition -#define AT91C_TWI_STOP ((unsigned int) 0x1 << 1) // (TWI) Send a STOP Condition -#define AT91C_TWI_MSEN ((unsigned int) 0x1 << 2) // (TWI) TWI Master Transfer Enabled -#define AT91C_TWI_MSDIS ((unsigned int) 0x1 << 3) // (TWI) TWI Master Transfer Disabled -#define AT91C_TWI_SWRST ((unsigned int) 0x1 << 7) // (TWI) Software Reset -// -------- TWI_MMR : (TWI Offset: 0x4) TWI Master Mode Register -------- -#define AT91C_TWI_IADRSZ ((unsigned int) 0x3 << 8) // (TWI) Internal Device Address Size -#define AT91C_TWI_IADRSZ_NO ((unsigned int) 0x0 << 8) // (TWI) No internal device address -#define AT91C_TWI_IADRSZ_1_BYTE ((unsigned int) 0x1 << 8) // (TWI) One-byte internal device address -#define AT91C_TWI_IADRSZ_2_BYTE ((unsigned int) 0x2 << 8) // (TWI) Two-byte internal device address -#define AT91C_TWI_IADRSZ_3_BYTE ((unsigned int) 0x3 << 8) // (TWI) Three-byte internal device address -#define AT91C_TWI_MREAD ((unsigned int) 0x1 << 12) // (TWI) Master Read Direction -#define AT91C_TWI_DADR ((unsigned int) 0x7F << 16) // (TWI) Device Address -// -------- TWI_CWGR : (TWI Offset: 0x10) TWI Clock Waveform Generator Register -------- -#define AT91C_TWI_CLDIV ((unsigned int) 0xFF << 0) // (TWI) Clock Low Divider -#define AT91C_TWI_CHDIV ((unsigned int) 0xFF << 8) // (TWI) Clock High Divider -#define AT91C_TWI_CKDIV ((unsigned int) 0x7 << 16) // (TWI) Clock Divider -// -------- TWI_SR : (TWI Offset: 0x20) TWI Status Register -------- -#define AT91C_TWI_TXCOMP ((unsigned int) 0x1 << 0) // (TWI) Transmission Completed -#define AT91C_TWI_RXRDY ((unsigned int) 0x1 << 1) // (TWI) Receive holding register ReaDY -#define AT91C_TWI_TXRDY ((unsigned int) 0x1 << 2) // (TWI) Transmit holding register ReaDY -#define AT91C_TWI_OVRE ((unsigned int) 0x1 << 6) // (TWI) Overrun Error -#define AT91C_TWI_UNRE ((unsigned int) 0x1 << 7) // (TWI) Underrun Error -#define AT91C_TWI_NACK ((unsigned int) 0x1 << 8) // (TWI) Not Acknowledged -// -------- TWI_IER : (TWI Offset: 0x24) TWI Interrupt Enable Register -------- -// -------- TWI_IDR : (TWI Offset: 0x28) TWI Interrupt Disable Register -------- -// -------- TWI_IMR : (TWI Offset: 0x2c) TWI Interrupt Mask Register -------- - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Timer Counter Channel Interface -// ***************************************************************************** -typedef struct _AT91S_TC { - AT91_REG TC_CCR; // Channel Control Register - AT91_REG TC_CMR; // Channel Mode Register (Capture Mode / Waveform Mode) - AT91_REG Reserved0[2]; // - AT91_REG TC_CV; // Counter Value - AT91_REG TC_RA; // Register A - AT91_REG TC_RB; // Register B - AT91_REG TC_RC; // Register C - AT91_REG TC_SR; // Status Register - AT91_REG TC_IER; // Interrupt Enable Register - AT91_REG TC_IDR; // Interrupt Disable Register - AT91_REG TC_IMR; // Interrupt Mask Register -} AT91S_TC, *AT91PS_TC; - -// -------- TC_CCR : (TC Offset: 0x0) TC Channel Control Register -------- -#define AT91C_TC_CLKEN ((unsigned int) 0x1 << 0) // (TC) Counter Clock Enable Command -#define AT91C_TC_CLKDIS ((unsigned int) 0x1 << 1) // (TC) Counter Clock Disable Command -#define AT91C_TC_SWTRG ((unsigned int) 0x1 << 2) // (TC) Software Trigger Command -// -------- TC_CMR : (TC Offset: 0x4) TC Channel Mode Register: Capture Mode / Waveform Mode -------- -#define AT91C_TC_CLKS ((unsigned int) 0x7 << 0) // (TC) Clock Selection -#define AT91C_TC_CLKS_TIMER_DIV1_CLOCK ((unsigned int) 0x0) // (TC) Clock selected: TIMER_DIV1_CLOCK -#define AT91C_TC_CLKS_TIMER_DIV2_CLOCK ((unsigned int) 0x1) // (TC) Clock selected: TIMER_DIV2_CLOCK -#define AT91C_TC_CLKS_TIMER_DIV3_CLOCK ((unsigned int) 0x2) // (TC) Clock selected: TIMER_DIV3_CLOCK -#define AT91C_TC_CLKS_TIMER_DIV4_CLOCK ((unsigned int) 0x3) // (TC) Clock selected: TIMER_DIV4_CLOCK -#define AT91C_TC_CLKS_TIMER_DIV5_CLOCK ((unsigned int) 0x4) // (TC) Clock selected: TIMER_DIV5_CLOCK -#define AT91C_TC_CLKS_XC0 ((unsigned int) 0x5) // (TC) Clock selected: XC0 -#define AT91C_TC_CLKS_XC1 ((unsigned int) 0x6) // (TC) Clock selected: XC1 -#define AT91C_TC_CLKS_XC2 ((unsigned int) 0x7) // (TC) Clock selected: XC2 -#define AT91C_TC_CLKI ((unsigned int) 0x1 << 3) // (TC) Clock Invert -#define AT91C_TC_BURST ((unsigned int) 0x3 << 4) // (TC) Burst Signal Selection -#define AT91C_TC_BURST_NONE ((unsigned int) 0x0 << 4) // (TC) The clock is not gated by an external signal -#define AT91C_TC_BURST_XC0 ((unsigned int) 0x1 << 4) // (TC) XC0 is ANDed with the selected clock -#define AT91C_TC_BURST_XC1 ((unsigned int) 0x2 << 4) // (TC) XC1 is ANDed with the selected clock -#define AT91C_TC_BURST_XC2 ((unsigned int) 0x3 << 4) // (TC) XC2 is ANDed with the selected clock -#define AT91C_TC_CPCSTOP ((unsigned int) 0x1 << 6) // (TC) Counter Clock Stopped with RC Compare -#define AT91C_TC_LDBSTOP ((unsigned int) 0x1 << 6) // (TC) Counter Clock Stopped with RB Loading -#define AT91C_TC_CPCDIS ((unsigned int) 0x1 << 7) // (TC) Counter Clock Disable with RC Compare -#define AT91C_TC_LDBDIS ((unsigned int) 0x1 << 7) // (TC) Counter Clock Disabled with RB Loading -#define AT91C_TC_ETRGEDG ((unsigned int) 0x3 << 8) // (TC) External Trigger Edge Selection -#define AT91C_TC_ETRGEDG_NONE ((unsigned int) 0x0 << 8) // (TC) Edge: None -#define AT91C_TC_ETRGEDG_RISING ((unsigned int) 0x1 << 8) // (TC) Edge: rising edge -#define AT91C_TC_ETRGEDG_FALLING ((unsigned int) 0x2 << 8) // (TC) Edge: falling edge -#define AT91C_TC_ETRGEDG_BOTH ((unsigned int) 0x3 << 8) // (TC) Edge: each edge -#define AT91C_TC_EEVTEDG ((unsigned int) 0x3 << 8) // (TC) External Event Edge Selection -#define AT91C_TC_EEVTEDG_NONE ((unsigned int) 0x0 << 8) // (TC) Edge: None -#define AT91C_TC_EEVTEDG_RISING ((unsigned int) 0x1 << 8) // (TC) Edge: rising edge -#define AT91C_TC_EEVTEDG_FALLING ((unsigned int) 0x2 << 8) // (TC) Edge: falling edge -#define AT91C_TC_EEVTEDG_BOTH ((unsigned int) 0x3 << 8) // (TC) Edge: each edge -#define AT91C_TC_EEVT ((unsigned int) 0x3 << 10) // (TC) External Event Selection -#define AT91C_TC_EEVT_TIOB ((unsigned int) 0x0 << 10) // (TC) Signal selected as external event: TIOB TIOB direction: input -#define AT91C_TC_EEVT_XC0 ((unsigned int) 0x1 << 10) // (TC) Signal selected as external event: XC0 TIOB direction: output -#define AT91C_TC_EEVT_XC1 ((unsigned int) 0x2 << 10) // (TC) Signal selected as external event: XC1 TIOB direction: output -#define AT91C_TC_EEVT_XC2 ((unsigned int) 0x3 << 10) // (TC) Signal selected as external event: XC2 TIOB direction: output -#define AT91C_TC_ABETRG ((unsigned int) 0x1 << 10) // (TC) TIOA or TIOB External Trigger Selection -#define AT91C_TC_ENETRG ((unsigned int) 0x1 << 12) // (TC) External Event Trigger enable -#define AT91C_TC_WAVESEL ((unsigned int) 0x3 << 13) // (TC) Waveform Selection -#define AT91C_TC_WAVESEL_UP ((unsigned int) 0x0 << 13) // (TC) UP mode without atomatic trigger on RC Compare -#define AT91C_TC_WAVESEL_UPDOWN ((unsigned int) 0x1 << 13) // (TC) UPDOWN mode without automatic trigger on RC Compare -#define AT91C_TC_WAVESEL_UP_AUTO ((unsigned int) 0x2 << 13) // (TC) UP mode with automatic trigger on RC Compare -#define AT91C_TC_WAVESEL_UPDOWN_AUTO ((unsigned int) 0x3 << 13) // (TC) UPDOWN mode with automatic trigger on RC Compare -#define AT91C_TC_CPCTRG ((unsigned int) 0x1 << 14) // (TC) RC Compare Trigger Enable -#define AT91C_TC_WAVE ((unsigned int) 0x1 << 15) // (TC) -#define AT91C_TC_ACPA ((unsigned int) 0x3 << 16) // (TC) RA Compare Effect on TIOA -#define AT91C_TC_ACPA_NONE ((unsigned int) 0x0 << 16) // (TC) Effect: none -#define AT91C_TC_ACPA_SET ((unsigned int) 0x1 << 16) // (TC) Effect: set -#define AT91C_TC_ACPA_CLEAR ((unsigned int) 0x2 << 16) // (TC) Effect: clear -#define AT91C_TC_ACPA_TOGGLE ((unsigned int) 0x3 << 16) // (TC) Effect: toggle -#define AT91C_TC_LDRA ((unsigned int) 0x3 << 16) // (TC) RA Loading Selection -#define AT91C_TC_LDRA_NONE ((unsigned int) 0x0 << 16) // (TC) Edge: None -#define AT91C_TC_LDRA_RISING ((unsigned int) 0x1 << 16) // (TC) Edge: rising edge of TIOA -#define AT91C_TC_LDRA_FALLING ((unsigned int) 0x2 << 16) // (TC) Edge: falling edge of TIOA -#define AT91C_TC_LDRA_BOTH ((unsigned int) 0x3 << 16) // (TC) Edge: each edge of TIOA -#define AT91C_TC_ACPC ((unsigned int) 0x3 << 18) // (TC) RC Compare Effect on TIOA -#define AT91C_TC_ACPC_NONE ((unsigned int) 0x0 << 18) // (TC) Effect: none -#define AT91C_TC_ACPC_SET ((unsigned int) 0x1 << 18) // (TC) Effect: set -#define AT91C_TC_ACPC_CLEAR ((unsigned int) 0x2 << 18) // (TC) Effect: clear -#define AT91C_TC_ACPC_TOGGLE ((unsigned int) 0x3 << 18) // (TC) Effect: toggle -#define AT91C_TC_LDRB ((unsigned int) 0x3 << 18) // (TC) RB Loading Selection -#define AT91C_TC_LDRB_NONE ((unsigned int) 0x0 << 18) // (TC) Edge: None -#define AT91C_TC_LDRB_RISING ((unsigned int) 0x1 << 18) // (TC) Edge: rising edge of TIOA -#define AT91C_TC_LDRB_FALLING ((unsigned int) 0x2 << 18) // (TC) Edge: falling edge of TIOA -#define AT91C_TC_LDRB_BOTH ((unsigned int) 0x3 << 18) // (TC) Edge: each edge of TIOA -#define AT91C_TC_AEEVT ((unsigned int) 0x3 << 20) // (TC) External Event Effect on TIOA -#define AT91C_TC_AEEVT_NONE ((unsigned int) 0x0 << 20) // (TC) Effect: none -#define AT91C_TC_AEEVT_SET ((unsigned int) 0x1 << 20) // (TC) Effect: set -#define AT91C_TC_AEEVT_CLEAR ((unsigned int) 0x2 << 20) // (TC) Effect: clear -#define AT91C_TC_AEEVT_TOGGLE ((unsigned int) 0x3 << 20) // (TC) Effect: toggle -#define AT91C_TC_ASWTRG ((unsigned int) 0x3 << 22) // (TC) Software Trigger Effect on TIOA -#define AT91C_TC_ASWTRG_NONE ((unsigned int) 0x0 << 22) // (TC) Effect: none -#define AT91C_TC_ASWTRG_SET ((unsigned int) 0x1 << 22) // (TC) Effect: set -#define AT91C_TC_ASWTRG_CLEAR ((unsigned int) 0x2 << 22) // (TC) Effect: clear -#define AT91C_TC_ASWTRG_TOGGLE ((unsigned int) 0x3 << 22) // (TC) Effect: toggle -#define AT91C_TC_BCPB ((unsigned int) 0x3 << 24) // (TC) RB Compare Effect on TIOB -#define AT91C_TC_BCPB_NONE ((unsigned int) 0x0 << 24) // (TC) Effect: none -#define AT91C_TC_BCPB_SET ((unsigned int) 0x1 << 24) // (TC) Effect: set -#define AT91C_TC_BCPB_CLEAR ((unsigned int) 0x2 << 24) // (TC) Effect: clear -#define AT91C_TC_BCPB_TOGGLE ((unsigned int) 0x3 << 24) // (TC) Effect: toggle -#define AT91C_TC_BCPC ((unsigned int) 0x3 << 26) // (TC) RC Compare Effect on TIOB -#define AT91C_TC_BCPC_NONE ((unsigned int) 0x0 << 26) // (TC) Effect: none -#define AT91C_TC_BCPC_SET ((unsigned int) 0x1 << 26) // (TC) Effect: set -#define AT91C_TC_BCPC_CLEAR ((unsigned int) 0x2 << 26) // (TC) Effect: clear -#define AT91C_TC_BCPC_TOGGLE ((unsigned int) 0x3 << 26) // (TC) Effect: toggle -#define AT91C_TC_BEEVT ((unsigned int) 0x3 << 28) // (TC) External Event Effect on TIOB -#define AT91C_TC_BEEVT_NONE ((unsigned int) 0x0 << 28) // (TC) Effect: none -#define AT91C_TC_BEEVT_SET ((unsigned int) 0x1 << 28) // (TC) Effect: set -#define AT91C_TC_BEEVT_CLEAR ((unsigned int) 0x2 << 28) // (TC) Effect: clear -#define AT91C_TC_BEEVT_TOGGLE ((unsigned int) 0x3 << 28) // (TC) Effect: toggle -#define AT91C_TC_BSWTRG ((unsigned int) 0x3 << 30) // (TC) Software Trigger Effect on TIOB -#define AT91C_TC_BSWTRG_NONE ((unsigned int) 0x0 << 30) // (TC) Effect: none -#define AT91C_TC_BSWTRG_SET ((unsigned int) 0x1 << 30) // (TC) Effect: set -#define AT91C_TC_BSWTRG_CLEAR ((unsigned int) 0x2 << 30) // (TC) Effect: clear -#define AT91C_TC_BSWTRG_TOGGLE ((unsigned int) 0x3 << 30) // (TC) Effect: toggle -// -------- TC_SR : (TC Offset: 0x20) TC Channel Status Register -------- -#define AT91C_TC_COVFS ((unsigned int) 0x1 << 0) // (TC) Counter Overflow -#define AT91C_TC_LOVRS ((unsigned int) 0x1 << 1) // (TC) Load Overrun -#define AT91C_TC_CPAS ((unsigned int) 0x1 << 2) // (TC) RA Compare -#define AT91C_TC_CPBS ((unsigned int) 0x1 << 3) // (TC) RB Compare -#define AT91C_TC_CPCS ((unsigned int) 0x1 << 4) // (TC) RC Compare -#define AT91C_TC_LDRAS ((unsigned int) 0x1 << 5) // (TC) RA Loading -#define AT91C_TC_LDRBS ((unsigned int) 0x1 << 6) // (TC) RB Loading -#define AT91C_TC_ETRGS ((unsigned int) 0x1 << 7) // (TC) External Trigger -#define AT91C_TC_CLKSTA ((unsigned int) 0x1 << 16) // (TC) Clock Enabling -#define AT91C_TC_MTIOA ((unsigned int) 0x1 << 17) // (TC) TIOA Mirror -#define AT91C_TC_MTIOB ((unsigned int) 0x1 << 18) // (TC) TIOA Mirror -// -------- TC_IER : (TC Offset: 0x24) TC Channel Interrupt Enable Register -------- -// -------- TC_IDR : (TC Offset: 0x28) TC Channel Interrupt Disable Register -------- -// -------- TC_IMR : (TC Offset: 0x2c) TC Channel Interrupt Mask Register -------- - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Timer Counter Interface -// ***************************************************************************** -typedef struct _AT91S_TCB { - AT91S_TC TCB_TC0; // TC Channel 0 - AT91_REG Reserved0[4]; // - AT91S_TC TCB_TC1; // TC Channel 1 - AT91_REG Reserved1[4]; // - AT91S_TC TCB_TC2; // TC Channel 2 - AT91_REG Reserved2[4]; // - AT91_REG TCB_BCR; // TC Block Control Register - AT91_REG TCB_BMR; // TC Block Mode Register -} AT91S_TCB, *AT91PS_TCB; - -// -------- TCB_BCR : (TCB Offset: 0xc0) TC Block Control Register -------- -#define AT91C_TCB_SYNC ((unsigned int) 0x1 << 0) // (TCB) Synchro Command -// -------- TCB_BMR : (TCB Offset: 0xc4) TC Block Mode Register -------- -#define AT91C_TCB_TC0XC0S ((unsigned int) 0x3 << 0) // (TCB) External Clock Signal 0 Selection -#define AT91C_TCB_TC0XC0S_TCLK0 ((unsigned int) 0x0) // (TCB) TCLK0 connected to XC0 -#define AT91C_TCB_TC0XC0S_NONE ((unsigned int) 0x1) // (TCB) None signal connected to XC0 -#define AT91C_TCB_TC0XC0S_TIOA1 ((unsigned int) 0x2) // (TCB) TIOA1 connected to XC0 -#define AT91C_TCB_TC0XC0S_TIOA2 ((unsigned int) 0x3) // (TCB) TIOA2 connected to XC0 -#define AT91C_TCB_TC1XC1S ((unsigned int) 0x3 << 2) // (TCB) External Clock Signal 1 Selection -#define AT91C_TCB_TC1XC1S_TCLK1 ((unsigned int) 0x0 << 2) // (TCB) TCLK1 connected to XC1 -#define AT91C_TCB_TC1XC1S_NONE ((unsigned int) 0x1 << 2) // (TCB) None signal connected to XC1 -#define AT91C_TCB_TC1XC1S_TIOA0 ((unsigned int) 0x2 << 2) // (TCB) TIOA0 connected to XC1 -#define AT91C_TCB_TC1XC1S_TIOA2 ((unsigned int) 0x3 << 2) // (TCB) TIOA2 connected to XC1 -#define AT91C_TCB_TC2XC2S ((unsigned int) 0x3 << 4) // (TCB) External Clock Signal 2 Selection -#define AT91C_TCB_TC2XC2S_TCLK2 ((unsigned int) 0x0 << 4) // (TCB) TCLK2 connected to XC2 -#define AT91C_TCB_TC2XC2S_NONE ((unsigned int) 0x1 << 4) // (TCB) None signal connected to XC2 -#define AT91C_TCB_TC2XC2S_TIOA0 ((unsigned int) 0x2 << 4) // (TCB) TIOA0 connected to XC2 -#define AT91C_TCB_TC2XC2S_TIOA1 ((unsigned int) 0x3 << 4) // (TCB) TIOA2 connected to XC2 - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR PWMC Channel Interface -// ***************************************************************************** -typedef struct _AT91S_PWMC_CH { - AT91_REG PWMC_CMR; // Channel Mode Register - AT91_REG PWMC_CDTYR; // Channel Duty Cycle Register - AT91_REG PWMC_CPRDR; // Channel Period Register - AT91_REG PWMC_CCNTR; // Channel Counter Register - AT91_REG PWMC_CUPDR; // Channel Update Register - AT91_REG PWMC_Reserved[3]; // Reserved -} AT91S_PWMC_CH, *AT91PS_PWMC_CH; - -// -------- PWMC_CMR : (PWMC_CH Offset: 0x0) PWMC Channel Mode Register -------- -#define AT91C_PWMC_CPRE ((unsigned int) 0xF << 0) // (PWMC_CH) Channel Pre-scaler : PWMC_CLKx -#define AT91C_PWMC_CPRE_MCK ((unsigned int) 0x0) // (PWMC_CH) -#define AT91C_PWMC_CPRE_MCKA ((unsigned int) 0xB) // (PWMC_CH) -#define AT91C_PWMC_CPRE_MCKB ((unsigned int) 0xC) // (PWMC_CH) -#define AT91C_PWMC_CALG ((unsigned int) 0x1 << 8) // (PWMC_CH) Channel Alignment -#define AT91C_PWMC_CPOL ((unsigned int) 0x1 << 9) // (PWMC_CH) Channel Polarity -#define AT91C_PWMC_CPD ((unsigned int) 0x1 << 10) // (PWMC_CH) Channel Update Period -// -------- PWMC_CDTYR : (PWMC_CH Offset: 0x4) PWMC Channel Duty Cycle Register -------- -#define AT91C_PWMC_CDTY ((unsigned int) 0x0 << 0) // (PWMC_CH) Channel Duty Cycle -// -------- PWMC_CPRDR : (PWMC_CH Offset: 0x8) PWMC Channel Period Register -------- -#define AT91C_PWMC_CPRD ((unsigned int) 0x0 << 0) // (PWMC_CH) Channel Period -// -------- PWMC_CCNTR : (PWMC_CH Offset: 0xc) PWMC Channel Counter Register -------- -#define AT91C_PWMC_CCNT ((unsigned int) 0x0 << 0) // (PWMC_CH) Channel Counter -// -------- PWMC_CUPDR : (PWMC_CH Offset: 0x10) PWMC Channel Update Register -------- -#define AT91C_PWMC_CUPD ((unsigned int) 0x0 << 0) // (PWMC_CH) Channel Update - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Pulse Width Modulation Controller Interface -// ***************************************************************************** -typedef struct _AT91S_PWMC { - AT91_REG PWMC_MR; // PWMC Mode Register - AT91_REG PWMC_ENA; // PWMC Enable Register - AT91_REG PWMC_DIS; // PWMC Disable Register - AT91_REG PWMC_SR; // PWMC Status Register - AT91_REG PWMC_IER; // PWMC Interrupt Enable Register - AT91_REG PWMC_IDR; // PWMC Interrupt Disable Register - AT91_REG PWMC_IMR; // PWMC Interrupt Mask Register - AT91_REG PWMC_ISR; // PWMC Interrupt Status Register - AT91_REG Reserved0[55]; // - AT91_REG PWMC_VR; // PWMC Version Register - AT91_REG Reserved1[64]; // - AT91S_PWMC_CH PWMC_CH[32]; // PWMC Channel 0 -} AT91S_PWMC, *AT91PS_PWMC; - -// -------- PWMC_MR : (PWMC Offset: 0x0) PWMC Mode Register -------- -#define AT91C_PWMC_DIVA ((unsigned int) 0xFF << 0) // (PWMC) CLKA divide factor. -#define AT91C_PWMC_PREA ((unsigned int) 0xF << 8) // (PWMC) Divider Input Clock Prescaler A -#define AT91C_PWMC_PREA_MCK ((unsigned int) 0x0 << 8) // (PWMC) -#define AT91C_PWMC_DIVB ((unsigned int) 0xFF << 16) // (PWMC) CLKB divide factor. -#define AT91C_PWMC_PREB ((unsigned int) 0xF << 24) // (PWMC) Divider Input Clock Prescaler B -#define AT91C_PWMC_PREB_MCK ((unsigned int) 0x0 << 24) // (PWMC) -// -------- PWMC_ENA : (PWMC Offset: 0x4) PWMC Enable Register -------- -#define AT91C_PWMC_CHID0 ((unsigned int) 0x1 << 0) // (PWMC) Channel ID 0 -#define AT91C_PWMC_CHID1 ((unsigned int) 0x1 << 1) // (PWMC) Channel ID 1 -#define AT91C_PWMC_CHID2 ((unsigned int) 0x1 << 2) // (PWMC) Channel ID 2 -#define AT91C_PWMC_CHID3 ((unsigned int) 0x1 << 3) // (PWMC) Channel ID 3 -#define AT91C_PWMC_CHID4 ((unsigned int) 0x1 << 4) // (PWMC) Channel ID 4 -#define AT91C_PWMC_CHID5 ((unsigned int) 0x1 << 5) // (PWMC) Channel ID 5 -#define AT91C_PWMC_CHID6 ((unsigned int) 0x1 << 6) // (PWMC) Channel ID 6 -#define AT91C_PWMC_CHID7 ((unsigned int) 0x1 << 7) // (PWMC) Channel ID 7 -// -------- PWMC_DIS : (PWMC Offset: 0x8) PWMC Disable Register -------- -// -------- PWMC_SR : (PWMC Offset: 0xc) PWMC Status Register -------- -// -------- PWMC_IER : (PWMC Offset: 0x10) PWMC Interrupt Enable Register -------- -// -------- PWMC_IDR : (PWMC Offset: 0x14) PWMC Interrupt Disable Register -------- -// -------- PWMC_IMR : (PWMC Offset: 0x18) PWMC Interrupt Mask Register -------- -// -------- PWMC_ISR : (PWMC Offset: 0x1c) PWMC Interrupt Status Register -------- - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR USB Device Interface -// ***************************************************************************** -typedef struct _AT91S_UDP { - AT91_REG UDP_NUM; // Frame Number Register - AT91_REG UDP_GLBSTATE; // Global State Register - AT91_REG UDP_FADDR; // Function Address Register - AT91_REG Reserved0[1]; // - AT91_REG UDP_IER; // Interrupt Enable Register - AT91_REG UDP_IDR; // Interrupt Disable Register - AT91_REG UDP_IMR; // Interrupt Mask Register - AT91_REG UDP_ISR; // Interrupt Status Register - AT91_REG UDP_ICR; // Interrupt Clear Register - AT91_REG Reserved1[1]; // - AT91_REG UDP_RSTEP; // Reset Endpoint Register - AT91_REG Reserved2[1]; // - AT91_REG UDP_CSR[8]; // Endpoint Control and Status Register - AT91_REG UDP_FDR[8]; // Endpoint FIFO Data Register - AT91_REG Reserved3[1]; // - AT91_REG UDP_TXVC; // Transceiver Control Register -} AT91S_UDP, *AT91PS_UDP; - -// -------- UDP_FRM_NUM : (UDP Offset: 0x0) USB Frame Number Register -------- -#define AT91C_UDP_FRM_NUM ((unsigned int) 0x7FF << 0) // (UDP) Frame Number as Defined in the Packet Field Formats -#define AT91C_UDP_FRM_ERR ((unsigned int) 0x1 << 16) // (UDP) Frame Error -#define AT91C_UDP_FRM_OK ((unsigned int) 0x1 << 17) // (UDP) Frame OK -// -------- UDP_GLB_STATE : (UDP Offset: 0x4) USB Global State Register -------- -#define AT91C_UDP_FADDEN ((unsigned int) 0x1 << 0) // (UDP) Function Address Enable -#define AT91C_UDP_CONFG ((unsigned int) 0x1 << 1) // (UDP) Configured -#define AT91C_UDP_ESR ((unsigned int) 0x1 << 2) // (UDP) Enable Send Resume -#define AT91C_UDP_RSMINPR ((unsigned int) 0x1 << 3) // (UDP) A Resume Has Been Sent to the Host -#define AT91C_UDP_RMWUPE ((unsigned int) 0x1 << 4) // (UDP) Remote Wake Up Enable -// -------- UDP_FADDR : (UDP Offset: 0x8) USB Function Address Register -------- -#define AT91C_UDP_FADD ((unsigned int) 0xFF << 0) // (UDP) Function Address Value -#define AT91C_UDP_FEN ((unsigned int) 0x1 << 8) // (UDP) Function Enable -// -------- UDP_IER : (UDP Offset: 0x10) USB Interrupt Enable Register -------- -#define AT91C_UDP_EPINT0 ((unsigned int) 0x1 << 0) // (UDP) Endpoint 0 Interrupt -#define AT91C_UDP_EPINT1 ((unsigned int) 0x1 << 1) // (UDP) Endpoint 0 Interrupt -#define AT91C_UDP_EPINT2 ((unsigned int) 0x1 << 2) // (UDP) Endpoint 2 Interrupt -#define AT91C_UDP_EPINT3 ((unsigned int) 0x1 << 3) // (UDP) Endpoint 3 Interrupt -#define AT91C_UDP_EPINT4 ((unsigned int) 0x1 << 4) // (UDP) Endpoint 4 Interrupt -#define AT91C_UDP_EPINT5 ((unsigned int) 0x1 << 5) // (UDP) Endpoint 5 Interrupt -#define AT91C_UDP_EPINT6 ((unsigned int) 0x1 << 6) // (UDP) Endpoint 6 Interrupt -#define AT91C_UDP_EPINT7 ((unsigned int) 0x1 << 7) // (UDP) Endpoint 7 Interrupt -#define AT91C_UDP_RXSUSP ((unsigned int) 0x1 << 8) // (UDP) USB Suspend Interrupt -#define AT91C_UDP_RXRSM ((unsigned int) 0x1 << 9) // (UDP) USB Resume Interrupt -#define AT91C_UDP_EXTRSM ((unsigned int) 0x1 << 10) // (UDP) USB External Resume Interrupt -#define AT91C_UDP_SOFINT ((unsigned int) 0x1 << 11) // (UDP) USB Start Of frame Interrupt -#define AT91C_UDP_WAKEUP ((unsigned int) 0x1 << 13) // (UDP) USB Resume Interrupt -// -------- UDP_IDR : (UDP Offset: 0x14) USB Interrupt Disable Register -------- -// -------- UDP_IMR : (UDP Offset: 0x18) USB Interrupt Mask Register -------- -// -------- UDP_ISR : (UDP Offset: 0x1c) USB Interrupt Status Register -------- -#define AT91C_UDP_ENDBUSRES ((unsigned int) 0x1 << 12) // (UDP) USB End Of Bus Reset Interrupt -// -------- UDP_ICR : (UDP Offset: 0x20) USB Interrupt Clear Register -------- -// -------- UDP_RST_EP : (UDP Offset: 0x28) USB Reset Endpoint Register -------- -#define AT91C_UDP_EP0 ((unsigned int) 0x1 << 0) // (UDP) Reset Endpoint 0 -#define AT91C_UDP_EP1 ((unsigned int) 0x1 << 1) // (UDP) Reset Endpoint 1 -#define AT91C_UDP_EP2 ((unsigned int) 0x1 << 2) // (UDP) Reset Endpoint 2 -#define AT91C_UDP_EP3 ((unsigned int) 0x1 << 3) // (UDP) Reset Endpoint 3 -#define AT91C_UDP_EP4 ((unsigned int) 0x1 << 4) // (UDP) Reset Endpoint 4 -#define AT91C_UDP_EP5 ((unsigned int) 0x1 << 5) // (UDP) Reset Endpoint 5 -#define AT91C_UDP_EP6 ((unsigned int) 0x1 << 6) // (UDP) Reset Endpoint 6 -#define AT91C_UDP_EP7 ((unsigned int) 0x1 << 7) // (UDP) Reset Endpoint 7 -// -------- UDP_CSR : (UDP Offset: 0x30) USB Endpoint Control and Status Register -------- -#define AT91C_UDP_TXCOMP ((unsigned int) 0x1 << 0) // (UDP) Generates an IN packet with data previously written in the DPR -#define AT91C_UDP_RX_DATA_BK0 ((unsigned int) 0x1 << 1) // (UDP) Receive Data Bank 0 -#define AT91C_UDP_RXSETUP ((unsigned int) 0x1 << 2) // (UDP) Sends STALL to the Host (Control endpoints) -#define AT91C_UDP_ISOERROR ((unsigned int) 0x1 << 3) // (UDP) Isochronous error (Isochronous endpoints) -#define AT91C_UDP_TXPKTRDY ((unsigned int) 0x1 << 4) // (UDP) Transmit Packet Ready -#define AT91C_UDP_FORCESTALL ((unsigned int) 0x1 << 5) // (UDP) Force Stall (used by Control, Bulk and Isochronous endpoints). -#define AT91C_UDP_RX_DATA_BK1 ((unsigned int) 0x1 << 6) // (UDP) Receive Data Bank 1 (only used by endpoints with ping-pong attributes). -#define AT91C_UDP_DIR ((unsigned int) 0x1 << 7) // (UDP) Transfer Direction -#define AT91C_UDP_EPTYPE ((unsigned int) 0x7 << 8) // (UDP) Endpoint type -#define AT91C_UDP_EPTYPE_CTRL ((unsigned int) 0x0 << 8) // (UDP) Control -#define AT91C_UDP_EPTYPE_ISO_OUT ((unsigned int) 0x1 << 8) // (UDP) Isochronous OUT -#define AT91C_UDP_EPTYPE_BULK_OUT ((unsigned int) 0x2 << 8) // (UDP) Bulk OUT -#define AT91C_UDP_EPTYPE_INT_OUT ((unsigned int) 0x3 << 8) // (UDP) Interrupt OUT -#define AT91C_UDP_EPTYPE_ISO_IN ((unsigned int) 0x5 << 8) // (UDP) Isochronous IN -#define AT91C_UDP_EPTYPE_BULK_IN ((unsigned int) 0x6 << 8) // (UDP) Bulk IN -#define AT91C_UDP_EPTYPE_INT_IN ((unsigned int) 0x7 << 8) // (UDP) Interrupt IN -#define AT91C_UDP_DTGLE ((unsigned int) 0x1 << 11) // (UDP) Data Toggle -#define AT91C_UDP_EPEDS ((unsigned int) 0x1 << 15) // (UDP) Endpoint Enable Disable -#define AT91C_UDP_RXBYTECNT ((unsigned int) 0x7FF << 16) // (UDP) Number Of Bytes Available in the FIFO -// -------- UDP_TXVC : (UDP Offset: 0x74) Transceiver Control Register -------- -#define AT91C_UDP_TXVDIS ((unsigned int) 0x1 << 8) // (UDP) -#define AT91C_UDP_PUON ((unsigned int) 0x1 << 9) // (UDP) Pull-up ON - -// ***************************************************************************** -// REGISTER ADDRESS DEFINITION FOR AT91SAM7S256 -// ***************************************************************************** -// ========== Register definition for SYS peripheral ========== -// ========== Register definition for AIC peripheral ========== -#define AT91C_AIC_IVR ((AT91_REG *) 0xFFFFF100) // (AIC) IRQ Vector Register -#define AT91C_AIC_SMR ((AT91_REG *) 0xFFFFF000) // (AIC) Source Mode Register -#define AT91C_AIC_FVR ((AT91_REG *) 0xFFFFF104) // (AIC) FIQ Vector Register -#define AT91C_AIC_DCR ((AT91_REG *) 0xFFFFF138) // (AIC) Debug Control Register (Protect) -#define AT91C_AIC_EOICR ((AT91_REG *) 0xFFFFF130) // (AIC) End of Interrupt Command Register -#define AT91C_AIC_SVR ((AT91_REG *) 0xFFFFF080) // (AIC) Source Vector Register -#define AT91C_AIC_FFSR ((AT91_REG *) 0xFFFFF148) // (AIC) Fast Forcing Status Register -#define AT91C_AIC_ICCR ((AT91_REG *) 0xFFFFF128) // (AIC) Interrupt Clear Command Register -#define AT91C_AIC_ISR ((AT91_REG *) 0xFFFFF108) // (AIC) Interrupt Status Register -#define AT91C_AIC_IMR ((AT91_REG *) 0xFFFFF110) // (AIC) Interrupt Mask Register -#define AT91C_AIC_IPR ((AT91_REG *) 0xFFFFF10C) // (AIC) Interrupt Pending Register -#define AT91C_AIC_FFER ((AT91_REG *) 0xFFFFF140) // (AIC) Fast Forcing Enable Register -#define AT91C_AIC_IECR ((AT91_REG *) 0xFFFFF120) // (AIC) Interrupt Enable Command Register -#define AT91C_AIC_ISCR ((AT91_REG *) 0xFFFFF12C) // (AIC) Interrupt Set Command Register -#define AT91C_AIC_FFDR ((AT91_REG *) 0xFFFFF144) // (AIC) Fast Forcing Disable Register -#define AT91C_AIC_CISR ((AT91_REG *) 0xFFFFF114) // (AIC) Core Interrupt Status Register -#define AT91C_AIC_IDCR ((AT91_REG *) 0xFFFFF124) // (AIC) Interrupt Disable Command Register -#define AT91C_AIC_SPU ((AT91_REG *) 0xFFFFF134) // (AIC) Spurious Vector Register -// ========== Register definition for PDC_DBGU peripheral ========== -#define AT91C_DBGU_TCR ((AT91_REG *) 0xFFFFF30C) // (PDC_DBGU) Transmit Counter Register -#define AT91C_DBGU_RNPR ((AT91_REG *) 0xFFFFF310) // (PDC_DBGU) Receive Next Pointer Register -#define AT91C_DBGU_TNPR ((AT91_REG *) 0xFFFFF318) // (PDC_DBGU) Transmit Next Pointer Register -#define AT91C_DBGU_TPR ((AT91_REG *) 0xFFFFF308) // (PDC_DBGU) Transmit Pointer Register -#define AT91C_DBGU_RPR ((AT91_REG *) 0xFFFFF300) // (PDC_DBGU) Receive Pointer Register -#define AT91C_DBGU_RCR ((AT91_REG *) 0xFFFFF304) // (PDC_DBGU) Receive Counter Register -#define AT91C_DBGU_RNCR ((AT91_REG *) 0xFFFFF314) // (PDC_DBGU) Receive Next Counter Register -#define AT91C_DBGU_PTCR ((AT91_REG *) 0xFFFFF320) // (PDC_DBGU) PDC Transfer Control Register -#define AT91C_DBGU_PTSR ((AT91_REG *) 0xFFFFF324) // (PDC_DBGU) PDC Transfer Status Register -#define AT91C_DBGU_TNCR ((AT91_REG *) 0xFFFFF31C) // (PDC_DBGU) Transmit Next Counter Register -// ========== Register definition for DBGU peripheral ========== -#define AT91C_DBGU_EXID ((AT91_REG *) 0xFFFFF244) // (DBGU) Chip ID Extension Register -#define AT91C_DBGU_BRGR ((AT91_REG *) 0xFFFFF220) // (DBGU) Baud Rate Generator Register -#define AT91C_DBGU_IDR ((AT91_REG *) 0xFFFFF20C) // (DBGU) Interrupt Disable Register -#define AT91C_DBGU_CSR ((AT91_REG *) 0xFFFFF214) // (DBGU) Channel Status Register -#define AT91C_DBGU_CIDR ((AT91_REG *) 0xFFFFF240) // (DBGU) Chip ID Register -#define AT91C_DBGU_MR ((AT91_REG *) 0xFFFFF204) // (DBGU) Mode Register -#define AT91C_DBGU_IMR ((AT91_REG *) 0xFFFFF210) // (DBGU) Interrupt Mask Register -#define AT91C_DBGU_CR ((AT91_REG *) 0xFFFFF200) // (DBGU) Control Register -#define AT91C_DBGU_FNTR ((AT91_REG *) 0xFFFFF248) // (DBGU) Force NTRST Register -#define AT91C_DBGU_THR ((AT91_REG *) 0xFFFFF21C) // (DBGU) Transmitter Holding Register -#define AT91C_DBGU_RHR ((AT91_REG *) 0xFFFFF218) // (DBGU) Receiver Holding Register -#define AT91C_DBGU_IER ((AT91_REG *) 0xFFFFF208) // (DBGU) Interrupt Enable Register -// ========== Register definition for PIOA peripheral ========== -#define AT91C_PIOA_ODR ((AT91_REG *) 0xFFFFF414) // (PIOA) Output Disable Registerr -#define AT91C_PIOA_SODR ((AT91_REG *) 0xFFFFF430) // (PIOA) Set Output Data Register -#define AT91C_PIOA_ISR ((AT91_REG *) 0xFFFFF44C) // (PIOA) Interrupt Status Register -#define AT91C_PIOA_ABSR ((AT91_REG *) 0xFFFFF478) // (PIOA) AB Select Status Register -#define AT91C_PIOA_IER ((AT91_REG *) 0xFFFFF440) // (PIOA) Interrupt Enable Register -#define AT91C_PIOA_PPUDR ((AT91_REG *) 0xFFFFF460) // (PIOA) Pull-up Disable Register -#define AT91C_PIOA_IMR ((AT91_REG *) 0xFFFFF448) // (PIOA) Interrupt Mask Register -#define AT91C_PIOA_PER ((AT91_REG *) 0xFFFFF400) // (PIOA) PIO Enable Register -#define AT91C_PIOA_IFDR ((AT91_REG *) 0xFFFFF424) // (PIOA) Input Filter Disable Register -#define AT91C_PIOA_OWDR ((AT91_REG *) 0xFFFFF4A4) // (PIOA) Output Write Disable Register -#define AT91C_PIOA_MDSR ((AT91_REG *) 0xFFFFF458) // (PIOA) Multi-driver Status Register -#define AT91C_PIOA_IDR ((AT91_REG *) 0xFFFFF444) // (PIOA) Interrupt Disable Register -#define AT91C_PIOA_ODSR ((AT91_REG *) 0xFFFFF438) // (PIOA) Output Data Status Register -#define AT91C_PIOA_PPUSR ((AT91_REG *) 0xFFFFF468) // (PIOA) Pull-up Status Register -#define AT91C_PIOA_OWSR ((AT91_REG *) 0xFFFFF4A8) // (PIOA) Output Write Status Register -#define AT91C_PIOA_BSR ((AT91_REG *) 0xFFFFF474) // (PIOA) Select B Register -#define AT91C_PIOA_OWER ((AT91_REG *) 0xFFFFF4A0) // (PIOA) Output Write Enable Register -#define AT91C_PIOA_IFER ((AT91_REG *) 0xFFFFF420) // (PIOA) Input Filter Enable Register -#define AT91C_PIOA_PDSR ((AT91_REG *) 0xFFFFF43C) // (PIOA) Pin Data Status Register -#define AT91C_PIOA_PPUER ((AT91_REG *) 0xFFFFF464) // (PIOA) Pull-up Enable Register -#define AT91C_PIOA_OSR ((AT91_REG *) 0xFFFFF418) // (PIOA) Output Status Register -#define AT91C_PIOA_ASR ((AT91_REG *) 0xFFFFF470) // (PIOA) Select A Register -#define AT91C_PIOA_MDDR ((AT91_REG *) 0xFFFFF454) // (PIOA) Multi-driver Disable Register -#define AT91C_PIOA_CODR ((AT91_REG *) 0xFFFFF434) // (PIOA) Clear Output Data Register -#define AT91C_PIOA_MDER ((AT91_REG *) 0xFFFFF450) // (PIOA) Multi-driver Enable Register -#define AT91C_PIOA_PDR ((AT91_REG *) 0xFFFFF404) // (PIOA) PIO Disable Register -#define AT91C_PIOA_IFSR ((AT91_REG *) 0xFFFFF428) // (PIOA) Input Filter Status Register -#define AT91C_PIOA_OER ((AT91_REG *) 0xFFFFF410) // (PIOA) Output Enable Register -#define AT91C_PIOA_PSR ((AT91_REG *) 0xFFFFF408) // (PIOA) PIO Status Register -// ========== Register definition for CKGR peripheral ========== -#define AT91C_CKGR_MOR ((AT91_REG *) 0xFFFFFC20) // (CKGR) Main Oscillator Register -#define AT91C_CKGR_PLLR ((AT91_REG *) 0xFFFFFC2C) // (CKGR) PLL Register -#define AT91C_CKGR_MCFR ((AT91_REG *) 0xFFFFFC24) // (CKGR) Main Clock Frequency Register -// ========== Register definition for PMC peripheral ========== -#define AT91C_PMC_IDR ((AT91_REG *) 0xFFFFFC64) // (PMC) Interrupt Disable Register -#define AT91C_PMC_MOR ((AT91_REG *) 0xFFFFFC20) // (PMC) Main Oscillator Register -#define AT91C_PMC_PLLR ((AT91_REG *) 0xFFFFFC2C) // (PMC) PLL Register -#define AT91C_PMC_PCER ((AT91_REG *) 0xFFFFFC10) // (PMC) Peripheral Clock Enable Register -#define AT91C_PMC_PCKR ((AT91_REG *) 0xFFFFFC40) // (PMC) Programmable Clock Register -#define AT91C_PMC_MCKR ((AT91_REG *) 0xFFFFFC30) // (PMC) Master Clock Register -#define AT91C_PMC_SCDR ((AT91_REG *) 0xFFFFFC04) // (PMC) System Clock Disable Register -#define AT91C_PMC_PCDR ((AT91_REG *) 0xFFFFFC14) // (PMC) Peripheral Clock Disable Register -#define AT91C_PMC_SCSR ((AT91_REG *) 0xFFFFFC08) // (PMC) System Clock Status Register -#define AT91C_PMC_PCSR ((AT91_REG *) 0xFFFFFC18) // (PMC) Peripheral Clock Status Register -#define AT91C_PMC_MCFR ((AT91_REG *) 0xFFFFFC24) // (PMC) Main Clock Frequency Register -#define AT91C_PMC_SCER ((AT91_REG *) 0xFFFFFC00) // (PMC) System Clock Enable Register -#define AT91C_PMC_IMR ((AT91_REG *) 0xFFFFFC6C) // (PMC) Interrupt Mask Register -#define AT91C_PMC_IER ((AT91_REG *) 0xFFFFFC60) // (PMC) Interrupt Enable Register -#define AT91C_PMC_SR ((AT91_REG *) 0xFFFFFC68) // (PMC) Status Register -// ========== Register definition for RSTC peripheral ========== -#define AT91C_RSTC_RCR ((AT91_REG *) 0xFFFFFD00) // (RSTC) Reset Control Register -#define AT91C_RSTC_RMR ((AT91_REG *) 0xFFFFFD08) // (RSTC) Reset Mode Register -#define AT91C_RSTC_RSR ((AT91_REG *) 0xFFFFFD04) // (RSTC) Reset Status Register -// ========== Register definition for RTTC peripheral ========== -#define AT91C_RTTC_RTSR ((AT91_REG *) 0xFFFFFD2C) // (RTTC) Real-time Status Register -#define AT91C_RTTC_RTMR ((AT91_REG *) 0xFFFFFD20) // (RTTC) Real-time Mode Register -#define AT91C_RTTC_RTVR ((AT91_REG *) 0xFFFFFD28) // (RTTC) Real-time Value Register -#define AT91C_RTTC_RTAR ((AT91_REG *) 0xFFFFFD24) // (RTTC) Real-time Alarm Register -// ========== Register definition for PITC peripheral ========== -#define AT91C_PITC_PIVR ((AT91_REG *) 0xFFFFFD38) // (PITC) Period Interval Value Register -#define AT91C_PITC_PISR ((AT91_REG *) 0xFFFFFD34) // (PITC) Period Interval Status Register -#define AT91C_PITC_PIIR ((AT91_REG *) 0xFFFFFD3C) // (PITC) Period Interval Image Register -#define AT91C_PITC_PIMR ((AT91_REG *) 0xFFFFFD30) // (PITC) Period Interval Mode Register -// ========== Register definition for WDTC peripheral ========== -#define AT91C_WDTC_WDCR ((AT91_REG *) 0xFFFFFD40) // (WDTC) Watchdog Control Register -#define AT91C_WDTC_WDSR ((AT91_REG *) 0xFFFFFD48) // (WDTC) Watchdog Status Register -#define AT91C_WDTC_WDMR ((AT91_REG *) 0xFFFFFD44) // (WDTC) Watchdog Mode Register -// ========== Register definition for VREG peripheral ========== -#define AT91C_VREG_MR ((AT91_REG *) 0xFFFFFD60) // (VREG) Voltage Regulator Mode Register -// ========== Register definition for MC peripheral ========== -#define AT91C_MC_ASR ((AT91_REG *) 0xFFFFFF04) // (MC) MC Abort Status Register -#define AT91C_MC_RCR ((AT91_REG *) 0xFFFFFF00) // (MC) MC Remap Control Register -#define AT91C_MC_FCR ((AT91_REG *) 0xFFFFFF64) // (MC) MC Flash Command Register -#define AT91C_MC_AASR ((AT91_REG *) 0xFFFFFF08) // (MC) MC Abort Address Status Register -#define AT91C_MC_FSR ((AT91_REG *) 0xFFFFFF68) // (MC) MC Flash Status Register -#define AT91C_MC_FMR ((AT91_REG *) 0xFFFFFF60) // (MC) MC Flash Mode Register -// ========== Register definition for PDC_SPI peripheral ========== -#define AT91C_SPI_PTCR ((AT91_REG *) 0xFFFE0120) // (PDC_SPI) PDC Transfer Control Register -#define AT91C_SPI_TPR ((AT91_REG *) 0xFFFE0108) // (PDC_SPI) Transmit Pointer Register -#define AT91C_SPI_TCR ((AT91_REG *) 0xFFFE010C) // (PDC_SPI) Transmit Counter Register -#define AT91C_SPI_RCR ((AT91_REG *) 0xFFFE0104) // (PDC_SPI) Receive Counter Register -#define AT91C_SPI_PTSR ((AT91_REG *) 0xFFFE0124) // (PDC_SPI) PDC Transfer Status Register -#define AT91C_SPI_RNPR ((AT91_REG *) 0xFFFE0110) // (PDC_SPI) Receive Next Pointer Register -#define AT91C_SPI_RPR ((AT91_REG *) 0xFFFE0100) // (PDC_SPI) Receive Pointer Register -#define AT91C_SPI_TNCR ((AT91_REG *) 0xFFFE011C) // (PDC_SPI) Transmit Next Counter Register -#define AT91C_SPI_RNCR ((AT91_REG *) 0xFFFE0114) // (PDC_SPI) Receive Next Counter Register -#define AT91C_SPI_TNPR ((AT91_REG *) 0xFFFE0118) // (PDC_SPI) Transmit Next Pointer Register -// ========== Register definition for SPI peripheral ========== -#define AT91C_SPI_IER ((AT91_REG *) 0xFFFE0014) // (SPI) Interrupt Enable Register -#define AT91C_SPI_SR ((AT91_REG *) 0xFFFE0010) // (SPI) Status Register -#define AT91C_SPI_IDR ((AT91_REG *) 0xFFFE0018) // (SPI) Interrupt Disable Register -#define AT91C_SPI_CR ((AT91_REG *) 0xFFFE0000) // (SPI) Control Register -#define AT91C_SPI_MR ((AT91_REG *) 0xFFFE0004) // (SPI) Mode Register -#define AT91C_SPI_IMR ((AT91_REG *) 0xFFFE001C) // (SPI) Interrupt Mask Register -#define AT91C_SPI_TDR ((AT91_REG *) 0xFFFE000C) // (SPI) Transmit Data Register -#define AT91C_SPI_RDR ((AT91_REG *) 0xFFFE0008) // (SPI) Receive Data Register -#define AT91C_SPI_CSR ((AT91_REG *) 0xFFFE0030) // (SPI) Chip Select Register -// ========== Register definition for PDC_ADC peripheral ========== -#define AT91C_ADC_PTSR ((AT91_REG *) 0xFFFD8124) // (PDC_ADC) PDC Transfer Status Register -#define AT91C_ADC_PTCR ((AT91_REG *) 0xFFFD8120) // (PDC_ADC) PDC Transfer Control Register -#define AT91C_ADC_TNPR ((AT91_REG *) 0xFFFD8118) // (PDC_ADC) Transmit Next Pointer Register -#define AT91C_ADC_TNCR ((AT91_REG *) 0xFFFD811C) // (PDC_ADC) Transmit Next Counter Register -#define AT91C_ADC_RNPR ((AT91_REG *) 0xFFFD8110) // (PDC_ADC) Receive Next Pointer Register -#define AT91C_ADC_RNCR ((AT91_REG *) 0xFFFD8114) // (PDC_ADC) Receive Next Counter Register -#define AT91C_ADC_RPR ((AT91_REG *) 0xFFFD8100) // (PDC_ADC) Receive Pointer Register -#define AT91C_ADC_TCR ((AT91_REG *) 0xFFFD810C) // (PDC_ADC) Transmit Counter Register -#define AT91C_ADC_TPR ((AT91_REG *) 0xFFFD8108) // (PDC_ADC) Transmit Pointer Register -#define AT91C_ADC_RCR ((AT91_REG *) 0xFFFD8104) // (PDC_ADC) Receive Counter Register -// ========== Register definition for ADC peripheral ========== -#define AT91C_ADC_CDR2 ((AT91_REG *) 0xFFFD8038) // (ADC) ADC Channel Data Register 2 -#define AT91C_ADC_CDR3 ((AT91_REG *) 0xFFFD803C) // (ADC) ADC Channel Data Register 3 -#define AT91C_ADC_CDR0 ((AT91_REG *) 0xFFFD8030) // (ADC) ADC Channel Data Register 0 -#define AT91C_ADC_CDR5 ((AT91_REG *) 0xFFFD8044) // (ADC) ADC Channel Data Register 5 -#define AT91C_ADC_CHDR ((AT91_REG *) 0xFFFD8014) // (ADC) ADC Channel Disable Register -#define AT91C_ADC_SR ((AT91_REG *) 0xFFFD801C) // (ADC) ADC Status Register -#define AT91C_ADC_CDR4 ((AT91_REG *) 0xFFFD8040) // (ADC) ADC Channel Data Register 4 -#define AT91C_ADC_CDR1 ((AT91_REG *) 0xFFFD8034) // (ADC) ADC Channel Data Register 1 -#define AT91C_ADC_LCDR ((AT91_REG *) 0xFFFD8020) // (ADC) ADC Last Converted Data Register -#define AT91C_ADC_IDR ((AT91_REG *) 0xFFFD8028) // (ADC) ADC Interrupt Disable Register -#define AT91C_ADC_CR ((AT91_REG *) 0xFFFD8000) // (ADC) ADC Control Register -#define AT91C_ADC_CDR7 ((AT91_REG *) 0xFFFD804C) // (ADC) ADC Channel Data Register 7 -#define AT91C_ADC_CDR6 ((AT91_REG *) 0xFFFD8048) // (ADC) ADC Channel Data Register 6 -#define AT91C_ADC_IER ((AT91_REG *) 0xFFFD8024) // (ADC) ADC Interrupt Enable Register -#define AT91C_ADC_CHER ((AT91_REG *) 0xFFFD8010) // (ADC) ADC Channel Enable Register -#define AT91C_ADC_CHSR ((AT91_REG *) 0xFFFD8018) // (ADC) ADC Channel Status Register -#define AT91C_ADC_MR ((AT91_REG *) 0xFFFD8004) // (ADC) ADC Mode Register -#define AT91C_ADC_IMR ((AT91_REG *) 0xFFFD802C) // (ADC) ADC Interrupt Mask Register -// ========== Register definition for PDC_SSC peripheral ========== -#define AT91C_SSC_TNCR ((AT91_REG *) 0xFFFD411C) // (PDC_SSC) Transmit Next Counter Register -#define AT91C_SSC_RPR ((AT91_REG *) 0xFFFD4100) // (PDC_SSC) Receive Pointer Register -#define AT91C_SSC_RNCR ((AT91_REG *) 0xFFFD4114) // (PDC_SSC) Receive Next Counter Register -#define AT91C_SSC_TPR ((AT91_REG *) 0xFFFD4108) // (PDC_SSC) Transmit Pointer Register -#define AT91C_SSC_PTCR ((AT91_REG *) 0xFFFD4120) // (PDC_SSC) PDC Transfer Control Register -#define AT91C_SSC_TCR ((AT91_REG *) 0xFFFD410C) // (PDC_SSC) Transmit Counter Register -#define AT91C_SSC_RCR ((AT91_REG *) 0xFFFD4104) // (PDC_SSC) Receive Counter Register -#define AT91C_SSC_RNPR ((AT91_REG *) 0xFFFD4110) // (PDC_SSC) Receive Next Pointer Register -#define AT91C_SSC_TNPR ((AT91_REG *) 0xFFFD4118) // (PDC_SSC) Transmit Next Pointer Register -#define AT91C_SSC_PTSR ((AT91_REG *) 0xFFFD4124) // (PDC_SSC) PDC Transfer Status Register -// ========== Register definition for SSC peripheral ========== -#define AT91C_SSC_RHR ((AT91_REG *) 0xFFFD4020) // (SSC) Receive Holding Register -#define AT91C_SSC_RSHR ((AT91_REG *) 0xFFFD4030) // (SSC) Receive Sync Holding Register -#define AT91C_SSC_TFMR ((AT91_REG *) 0xFFFD401C) // (SSC) Transmit Frame Mode Register -#define AT91C_SSC_IDR ((AT91_REG *) 0xFFFD4048) // (SSC) Interrupt Disable Register -#define AT91C_SSC_THR ((AT91_REG *) 0xFFFD4024) // (SSC) Transmit Holding Register -#define AT91C_SSC_RCMR ((AT91_REG *) 0xFFFD4010) // (SSC) Receive Clock ModeRegister -#define AT91C_SSC_IER ((AT91_REG *) 0xFFFD4044) // (SSC) Interrupt Enable Register -#define AT91C_SSC_TSHR ((AT91_REG *) 0xFFFD4034) // (SSC) Transmit Sync Holding Register -#define AT91C_SSC_SR ((AT91_REG *) 0xFFFD4040) // (SSC) Status Register -#define AT91C_SSC_CMR ((AT91_REG *) 0xFFFD4004) // (SSC) Clock Mode Register -#define AT91C_SSC_TCMR ((AT91_REG *) 0xFFFD4018) // (SSC) Transmit Clock Mode Register -#define AT91C_SSC_CR ((AT91_REG *) 0xFFFD4000) // (SSC) Control Register -#define AT91C_SSC_IMR ((AT91_REG *) 0xFFFD404C) // (SSC) Interrupt Mask Register -#define AT91C_SSC_RFMR ((AT91_REG *) 0xFFFD4014) // (SSC) Receive Frame Mode Register -// ========== Register definition for PDC_US1 peripheral ========== -#define AT91C_US1_RNCR ((AT91_REG *) 0xFFFC4114) // (PDC_US1) Receive Next Counter Register -#define AT91C_US1_PTCR ((AT91_REG *) 0xFFFC4120) // (PDC_US1) PDC Transfer Control Register -#define AT91C_US1_TCR ((AT91_REG *) 0xFFFC410C) // (PDC_US1) Transmit Counter Register -#define AT91C_US1_PTSR ((AT91_REG *) 0xFFFC4124) // (PDC_US1) PDC Transfer Status Register -#define AT91C_US1_TNPR ((AT91_REG *) 0xFFFC4118) // (PDC_US1) Transmit Next Pointer Register -#define AT91C_US1_RCR ((AT91_REG *) 0xFFFC4104) // (PDC_US1) Receive Counter Register -#define AT91C_US1_RNPR ((AT91_REG *) 0xFFFC4110) // (PDC_US1) Receive Next Pointer Register -#define AT91C_US1_RPR ((AT91_REG *) 0xFFFC4100) // (PDC_US1) Receive Pointer Register -#define AT91C_US1_TNCR ((AT91_REG *) 0xFFFC411C) // (PDC_US1) Transmit Next Counter Register -#define AT91C_US1_TPR ((AT91_REG *) 0xFFFC4108) // (PDC_US1) Transmit Pointer Register -// ========== Register definition for US1 peripheral ========== -#define AT91C_US1_IF ((AT91_REG *) 0xFFFC404C) // (US1) IRDA_FILTER Register -#define AT91C_US1_NER ((AT91_REG *) 0xFFFC4044) // (US1) Nb Errors Register -#define AT91C_US1_RTOR ((AT91_REG *) 0xFFFC4024) // (US1) Receiver Time-out Register -#define AT91C_US1_CSR ((AT91_REG *) 0xFFFC4014) // (US1) Channel Status Register -#define AT91C_US1_IDR ((AT91_REG *) 0xFFFC400C) // (US1) Interrupt Disable Register -#define AT91C_US1_IER ((AT91_REG *) 0xFFFC4008) // (US1) Interrupt Enable Register -#define AT91C_US1_THR ((AT91_REG *) 0xFFFC401C) // (US1) Transmitter Holding Register -#define AT91C_US1_TTGR ((AT91_REG *) 0xFFFC4028) // (US1) Transmitter Time-guard Register -#define AT91C_US1_RHR ((AT91_REG *) 0xFFFC4018) // (US1) Receiver Holding Register -#define AT91C_US1_BRGR ((AT91_REG *) 0xFFFC4020) // (US1) Baud Rate Generator Register -#define AT91C_US1_IMR ((AT91_REG *) 0xFFFC4010) // (US1) Interrupt Mask Register -#define AT91C_US1_FIDI ((AT91_REG *) 0xFFFC4040) // (US1) FI_DI_Ratio Register -#define AT91C_US1_CR ((AT91_REG *) 0xFFFC4000) // (US1) Control Register -#define AT91C_US1_MR ((AT91_REG *) 0xFFFC4004) // (US1) Mode Register -// ========== Register definition for PDC_US0 peripheral ========== -#define AT91C_US0_TNPR ((AT91_REG *) 0xFFFC0118) // (PDC_US0) Transmit Next Pointer Register -#define AT91C_US0_RNPR ((AT91_REG *) 0xFFFC0110) // (PDC_US0) Receive Next Pointer Register -#define AT91C_US0_TCR ((AT91_REG *) 0xFFFC010C) // (PDC_US0) Transmit Counter Register -#define AT91C_US0_PTCR ((AT91_REG *) 0xFFFC0120) // (PDC_US0) PDC Transfer Control Register -#define AT91C_US0_PTSR ((AT91_REG *) 0xFFFC0124) // (PDC_US0) PDC Transfer Status Register -#define AT91C_US0_TNCR ((AT91_REG *) 0xFFFC011C) // (PDC_US0) Transmit Next Counter Register -#define AT91C_US0_TPR ((AT91_REG *) 0xFFFC0108) // (PDC_US0) Transmit Pointer Register -#define AT91C_US0_RCR ((AT91_REG *) 0xFFFC0104) // (PDC_US0) Receive Counter Register -#define AT91C_US0_RPR ((AT91_REG *) 0xFFFC0100) // (PDC_US0) Receive Pointer Register -#define AT91C_US0_RNCR ((AT91_REG *) 0xFFFC0114) // (PDC_US0) Receive Next Counter Register -// ========== Register definition for US0 peripheral ========== -#define AT91C_US0_BRGR ((AT91_REG *) 0xFFFC0020) // (US0) Baud Rate Generator Register -#define AT91C_US0_NER ((AT91_REG *) 0xFFFC0044) // (US0) Nb Errors Register -#define AT91C_US0_CR ((AT91_REG *) 0xFFFC0000) // (US0) Control Register -#define AT91C_US0_IMR ((AT91_REG *) 0xFFFC0010) // (US0) Interrupt Mask Register -#define AT91C_US0_FIDI ((AT91_REG *) 0xFFFC0040) // (US0) FI_DI_Ratio Register -#define AT91C_US0_TTGR ((AT91_REG *) 0xFFFC0028) // (US0) Transmitter Time-guard Register -#define AT91C_US0_MR ((AT91_REG *) 0xFFFC0004) // (US0) Mode Register -#define AT91C_US0_RTOR ((AT91_REG *) 0xFFFC0024) // (US0) Receiver Time-out Register -#define AT91C_US0_CSR ((AT91_REG *) 0xFFFC0014) // (US0) Channel Status Register -#define AT91C_US0_RHR ((AT91_REG *) 0xFFFC0018) // (US0) Receiver Holding Register -#define AT91C_US0_IDR ((AT91_REG *) 0xFFFC000C) // (US0) Interrupt Disable Register -#define AT91C_US0_THR ((AT91_REG *) 0xFFFC001C) // (US0) Transmitter Holding Register -#define AT91C_US0_IF ((AT91_REG *) 0xFFFC004C) // (US0) IRDA_FILTER Register -#define AT91C_US0_IER ((AT91_REG *) 0xFFFC0008) // (US0) Interrupt Enable Register -// ========== Register definition for TWI peripheral ========== -#define AT91C_TWI_IER ((AT91_REG *) 0xFFFB8024) // (TWI) Interrupt Enable Register -#define AT91C_TWI_CR ((AT91_REG *) 0xFFFB8000) // (TWI) Control Register -#define AT91C_TWI_SR ((AT91_REG *) 0xFFFB8020) // (TWI) Status Register -#define AT91C_TWI_IMR ((AT91_REG *) 0xFFFB802C) // (TWI) Interrupt Mask Register -#define AT91C_TWI_THR ((AT91_REG *) 0xFFFB8034) // (TWI) Transmit Holding Register -#define AT91C_TWI_IDR ((AT91_REG *) 0xFFFB8028) // (TWI) Interrupt Disable Register -#define AT91C_TWI_IADR ((AT91_REG *) 0xFFFB800C) // (TWI) Internal Address Register -#define AT91C_TWI_MMR ((AT91_REG *) 0xFFFB8004) // (TWI) Master Mode Register -#define AT91C_TWI_CWGR ((AT91_REG *) 0xFFFB8010) // (TWI) Clock Waveform Generator Register -#define AT91C_TWI_RHR ((AT91_REG *) 0xFFFB8030) // (TWI) Receive Holding Register -// ========== Register definition for TC0 peripheral ========== -#define AT91C_TC0_SR ((AT91_REG *) 0xFFFA0020) // (TC0) Status Register -#define AT91C_TC0_RC ((AT91_REG *) 0xFFFA001C) // (TC0) Register C -#define AT91C_TC0_RB ((AT91_REG *) 0xFFFA0018) // (TC0) Register B -#define AT91C_TC0_CCR ((AT91_REG *) 0xFFFA0000) // (TC0) Channel Control Register -#define AT91C_TC0_CMR ((AT91_REG *) 0xFFFA0004) // (TC0) Channel Mode Register (Capture Mode / Waveform Mode) -#define AT91C_TC0_IER ((AT91_REG *) 0xFFFA0024) // (TC0) Interrupt Enable Register -#define AT91C_TC0_RA ((AT91_REG *) 0xFFFA0014) // (TC0) Register A -#define AT91C_TC0_IDR ((AT91_REG *) 0xFFFA0028) // (TC0) Interrupt Disable Register -#define AT91C_TC0_CV ((AT91_REG *) 0xFFFA0010) // (TC0) Counter Value -#define AT91C_TC0_IMR ((AT91_REG *) 0xFFFA002C) // (TC0) Interrupt Mask Register -// ========== Register definition for TC1 peripheral ========== -#define AT91C_TC1_RB ((AT91_REG *) 0xFFFA0058) // (TC1) Register B -#define AT91C_TC1_CCR ((AT91_REG *) 0xFFFA0040) // (TC1) Channel Control Register -#define AT91C_TC1_IER ((AT91_REG *) 0xFFFA0064) // (TC1) Interrupt Enable Register -#define AT91C_TC1_IDR ((AT91_REG *) 0xFFFA0068) // (TC1) Interrupt Disable Register -#define AT91C_TC1_SR ((AT91_REG *) 0xFFFA0060) // (TC1) Status Register -#define AT91C_TC1_CMR ((AT91_REG *) 0xFFFA0044) // (TC1) Channel Mode Register (Capture Mode / Waveform Mode) -#define AT91C_TC1_RA ((AT91_REG *) 0xFFFA0054) // (TC1) Register A -#define AT91C_TC1_RC ((AT91_REG *) 0xFFFA005C) // (TC1) Register C -#define AT91C_TC1_IMR ((AT91_REG *) 0xFFFA006C) // (TC1) Interrupt Mask Register -#define AT91C_TC1_CV ((AT91_REG *) 0xFFFA0050) // (TC1) Counter Value -// ========== Register definition for TC2 peripheral ========== -#define AT91C_TC2_CMR ((AT91_REG *) 0xFFFA0084) // (TC2) Channel Mode Register (Capture Mode / Waveform Mode) -#define AT91C_TC2_CCR ((AT91_REG *) 0xFFFA0080) // (TC2) Channel Control Register -#define AT91C_TC2_CV ((AT91_REG *) 0xFFFA0090) // (TC2) Counter Value -#define AT91C_TC2_RA ((AT91_REG *) 0xFFFA0094) // (TC2) Register A -#define AT91C_TC2_RB ((AT91_REG *) 0xFFFA0098) // (TC2) Register B -#define AT91C_TC2_IDR ((AT91_REG *) 0xFFFA00A8) // (TC2) Interrupt Disable Register -#define AT91C_TC2_IMR ((AT91_REG *) 0xFFFA00AC) // (TC2) Interrupt Mask Register -#define AT91C_TC2_RC ((AT91_REG *) 0xFFFA009C) // (TC2) Register C -#define AT91C_TC2_IER ((AT91_REG *) 0xFFFA00A4) // (TC2) Interrupt Enable Register -#define AT91C_TC2_SR ((AT91_REG *) 0xFFFA00A0) // (TC2) Status Register -// ========== Register definition for TCB peripheral ========== -#define AT91C_TCB_BMR ((AT91_REG *) 0xFFFA00C4) // (TCB) TC Block Mode Register -#define AT91C_TCB_BCR ((AT91_REG *) 0xFFFA00C0) // (TCB) TC Block Control Register -// ========== Register definition for PWMC_CH3 peripheral ========== -#define AT91C_PWMC_CH3_CUPDR ((AT91_REG *) 0xFFFCC270) // (PWMC_CH3) Channel Update Register -#define AT91C_PWMC_CH3_Reserved ((AT91_REG *) 0xFFFCC274) // (PWMC_CH3) Reserved -#define AT91C_PWMC_CH3_CPRDR ((AT91_REG *) 0xFFFCC268) // (PWMC_CH3) Channel Period Register -#define AT91C_PWMC_CH3_CDTYR ((AT91_REG *) 0xFFFCC264) // (PWMC_CH3) Channel Duty Cycle Register -#define AT91C_PWMC_CH3_CCNTR ((AT91_REG *) 0xFFFCC26C) // (PWMC_CH3) Channel Counter Register -#define AT91C_PWMC_CH3_CMR ((AT91_REG *) 0xFFFCC260) // (PWMC_CH3) Channel Mode Register -// ========== Register definition for PWMC_CH2 peripheral ========== -#define AT91C_PWMC_CH2_Reserved ((AT91_REG *) 0xFFFCC254) // (PWMC_CH2) Reserved -#define AT91C_PWMC_CH2_CMR ((AT91_REG *) 0xFFFCC240) // (PWMC_CH2) Channel Mode Register -#define AT91C_PWMC_CH2_CCNTR ((AT91_REG *) 0xFFFCC24C) // (PWMC_CH2) Channel Counter Register -#define AT91C_PWMC_CH2_CPRDR ((AT91_REG *) 0xFFFCC248) // (PWMC_CH2) Channel Period Register -#define AT91C_PWMC_CH2_CUPDR ((AT91_REG *) 0xFFFCC250) // (PWMC_CH2) Channel Update Register -#define AT91C_PWMC_CH2_CDTYR ((AT91_REG *) 0xFFFCC244) // (PWMC_CH2) Channel Duty Cycle Register -// ========== Register definition for PWMC_CH1 peripheral ========== -#define AT91C_PWMC_CH1_Reserved ((AT91_REG *) 0xFFFCC234) // (PWMC_CH1) Reserved -#define AT91C_PWMC_CH1_CUPDR ((AT91_REG *) 0xFFFCC230) // (PWMC_CH1) Channel Update Register -#define AT91C_PWMC_CH1_CPRDR ((AT91_REG *) 0xFFFCC228) // (PWMC_CH1) Channel Period Register -#define AT91C_PWMC_CH1_CCNTR ((AT91_REG *) 0xFFFCC22C) // (PWMC_CH1) Channel Counter Register -#define AT91C_PWMC_CH1_CDTYR ((AT91_REG *) 0xFFFCC224) // (PWMC_CH1) Channel Duty Cycle Register -#define AT91C_PWMC_CH1_CMR ((AT91_REG *) 0xFFFCC220) // (PWMC_CH1) Channel Mode Register -// ========== Register definition for PWMC_CH0 peripheral ========== -#define AT91C_PWMC_CH0_Reserved ((AT91_REG *) 0xFFFCC214) // (PWMC_CH0) Reserved -#define AT91C_PWMC_CH0_CPRDR ((AT91_REG *) 0xFFFCC208) // (PWMC_CH0) Channel Period Register -#define AT91C_PWMC_CH0_CDTYR ((AT91_REG *) 0xFFFCC204) // (PWMC_CH0) Channel Duty Cycle Register -#define AT91C_PWMC_CH0_CMR ((AT91_REG *) 0xFFFCC200) // (PWMC_CH0) Channel Mode Register -#define AT91C_PWMC_CH0_CUPDR ((AT91_REG *) 0xFFFCC210) // (PWMC_CH0) Channel Update Register -#define AT91C_PWMC_CH0_CCNTR ((AT91_REG *) 0xFFFCC20C) // (PWMC_CH0) Channel Counter Register -// ========== Register definition for PWMC peripheral ========== -#define AT91C_PWMC_IDR ((AT91_REG *) 0xFFFCC014) // (PWMC) PWMC Interrupt Disable Register -#define AT91C_PWMC_DIS ((AT91_REG *) 0xFFFCC008) // (PWMC) PWMC Disable Register -#define AT91C_PWMC_IER ((AT91_REG *) 0xFFFCC010) // (PWMC) PWMC Interrupt Enable Register -#define AT91C_PWMC_VR ((AT91_REG *) 0xFFFCC0FC) // (PWMC) PWMC Version Register -#define AT91C_PWMC_ISR ((AT91_REG *) 0xFFFCC01C) // (PWMC) PWMC Interrupt Status Register -#define AT91C_PWMC_SR ((AT91_REG *) 0xFFFCC00C) // (PWMC) PWMC Status Register -#define AT91C_PWMC_IMR ((AT91_REG *) 0xFFFCC018) // (PWMC) PWMC Interrupt Mask Register -#define AT91C_PWMC_MR ((AT91_REG *) 0xFFFCC000) // (PWMC) PWMC Mode Register -#define AT91C_PWMC_ENA ((AT91_REG *) 0xFFFCC004) // (PWMC) PWMC Enable Register -// ========== Register definition for UDP peripheral ========== -#define AT91C_UDP_IMR ((AT91_REG *) 0xFFFB0018) // (UDP) Interrupt Mask Register -#define AT91C_UDP_FADDR ((AT91_REG *) 0xFFFB0008) // (UDP) Function Address Register -#define AT91C_UDP_NUM ((AT91_REG *) 0xFFFB0000) // (UDP) Frame Number Register -#define AT91C_UDP_FDR ((AT91_REG *) 0xFFFB0050) // (UDP) Endpoint FIFO Data Register -#define AT91C_UDP_ISR ((AT91_REG *) 0xFFFB001C) // (UDP) Interrupt Status Register -#define AT91C_UDP_CSR ((AT91_REG *) 0xFFFB0030) // (UDP) Endpoint Control and Status Register -#define AT91C_UDP_IDR ((AT91_REG *) 0xFFFB0014) // (UDP) Interrupt Disable Register -#define AT91C_UDP_ICR ((AT91_REG *) 0xFFFB0020) // (UDP) Interrupt Clear Register -#define AT91C_UDP_RSTEP ((AT91_REG *) 0xFFFB0028) // (UDP) Reset Endpoint Register -#define AT91C_UDP_TXVC ((AT91_REG *) 0xFFFB0074) // (UDP) Transceiver Control Register -#define AT91C_UDP_GLBSTATE ((AT91_REG *) 0xFFFB0004) // (UDP) Global State Register -#define AT91C_UDP_IER ((AT91_REG *) 0xFFFB0010) // (UDP) Interrupt Enable Register - -// ***************************************************************************** -// PIO DEFINITIONS FOR AT91SAM7S256 -// ***************************************************************************** -#define AT91C_PIO_PA0 ((unsigned int) 1 << 0) // Pin Controlled by PA0 -#define AT91C_PA0_PWM0 ((unsigned int) AT91C_PIO_PA0) // PWM Channel 0 -#define AT91C_PA0_TIOA0 ((unsigned int) AT91C_PIO_PA0) // Timer Counter 0 Multipurpose Timer I/O Pin A -#define AT91C_PIO_PA1 ((unsigned int) 1 << 1) // Pin Controlled by PA1 -#define AT91C_PA1_PWM1 ((unsigned int) AT91C_PIO_PA1) // PWM Channel 1 -#define AT91C_PA1_TIOB0 ((unsigned int) AT91C_PIO_PA1) // Timer Counter 0 Multipurpose Timer I/O Pin B -#define AT91C_PIO_PA10 ((unsigned int) 1 << 10) // Pin Controlled by PA10 -#define AT91C_PA10_DTXD ((unsigned int) AT91C_PIO_PA10) // DBGU Debug Transmit Data -#define AT91C_PA10_NPCS2 ((unsigned int) AT91C_PIO_PA10) // SPI Peripheral Chip Select 2 -#define AT91C_PIO_PA11 ((unsigned int) 1 << 11) // Pin Controlled by PA11 -#define AT91C_PA11_NPCS0 ((unsigned int) AT91C_PIO_PA11) // SPI Peripheral Chip Select 0 -#define AT91C_PA11_PWM0 ((unsigned int) AT91C_PIO_PA11) // PWM Channel 0 -#define AT91C_PIO_PA12 ((unsigned int) 1 << 12) // Pin Controlled by PA12 -#define AT91C_PA12_MISO ((unsigned int) AT91C_PIO_PA12) // SPI Master In Slave -#define AT91C_PA12_PWM1 ((unsigned int) AT91C_PIO_PA12) // PWM Channel 1 -#define AT91C_PIO_PA13 ((unsigned int) 1 << 13) // Pin Controlled by PA13 -#define AT91C_PA13_MOSI ((unsigned int) AT91C_PIO_PA13) // SPI Master Out Slave -#define AT91C_PA13_PWM2 ((unsigned int) AT91C_PIO_PA13) // PWM Channel 2 -#define AT91C_PIO_PA14 ((unsigned int) 1 << 14) // Pin Controlled by PA14 -#define AT91C_PA14_SPCK ((unsigned int) AT91C_PIO_PA14) // SPI Serial Clock -#define AT91C_PA14_PWM3 ((unsigned int) AT91C_PIO_PA14) // PWM Channel 3 -#define AT91C_PIO_PA15 ((unsigned int) 1 << 15) // Pin Controlled by PA15 -#define AT91C_PA15_TF ((unsigned int) AT91C_PIO_PA15) // SSC Transmit Frame Sync -#define AT91C_PA15_TIOA1 ((unsigned int) AT91C_PIO_PA15) // Timer Counter 1 Multipurpose Timer I/O Pin A -#define AT91C_PIO_PA16 ((unsigned int) 1 << 16) // Pin Controlled by PA16 -#define AT91C_PA16_TK ((unsigned int) AT91C_PIO_PA16) // SSC Transmit Clock -#define AT91C_PA16_TIOB1 ((unsigned int) AT91C_PIO_PA16) // Timer Counter 1 Multipurpose Timer I/O Pin B -#define AT91C_PIO_PA17 ((unsigned int) 1 << 17) // Pin Controlled by PA17 -#define AT91C_PA17_TD ((unsigned int) AT91C_PIO_PA17) // SSC Transmit data -#define AT91C_PA17_PCK1 ((unsigned int) AT91C_PIO_PA17) // PMC Programmable Clock Output 1 -#define AT91C_PIO_PA18 ((unsigned int) 1 << 18) // Pin Controlled by PA18 -#define AT91C_PA18_RD ((unsigned int) AT91C_PIO_PA18) // SSC Receive Data -#define AT91C_PA18_PCK2 ((unsigned int) AT91C_PIO_PA18) // PMC Programmable Clock Output 2 -#define AT91C_PIO_PA19 ((unsigned int) 1 << 19) // Pin Controlled by PA19 -#define AT91C_PA19_RK ((unsigned int) AT91C_PIO_PA19) // SSC Receive Clock -#define AT91C_PA19_FIQ ((unsigned int) AT91C_PIO_PA19) // AIC Fast Interrupt Input -#define AT91C_PIO_PA2 ((unsigned int) 1 << 2) // Pin Controlled by PA2 -#define AT91C_PA2_PWM2 ((unsigned int) AT91C_PIO_PA2) // PWM Channel 2 -#define AT91C_PA2_SCK0 ((unsigned int) AT91C_PIO_PA2) // USART 0 Serial Clock -#define AT91C_PIO_PA20 ((unsigned int) 1 << 20) // Pin Controlled by PA20 -#define AT91C_PA20_RF ((unsigned int) AT91C_PIO_PA20) // SSC Receive Frame Sync -#define AT91C_PA20_IRQ0 ((unsigned int) AT91C_PIO_PA20) // External Interrupt 0 -#define AT91C_PIO_PA21 ((unsigned int) 1 << 21) // Pin Controlled by PA21 -#define AT91C_PA21_RXD1 ((unsigned int) AT91C_PIO_PA21) // USART 1 Receive Data -#define AT91C_PA21_PCK1 ((unsigned int) AT91C_PIO_PA21) // PMC Programmable Clock Output 1 -#define AT91C_PIO_PA22 ((unsigned int) 1 << 22) // Pin Controlled by PA22 -#define AT91C_PA22_TXD1 ((unsigned int) AT91C_PIO_PA22) // USART 1 Transmit Data -#define AT91C_PA22_NPCS3 ((unsigned int) AT91C_PIO_PA22) // SPI Peripheral Chip Select 3 -#define AT91C_PIO_PA23 ((unsigned int) 1 << 23) // Pin Controlled by PA23 -#define AT91C_PA23_SCK1 ((unsigned int) AT91C_PIO_PA23) // USART 1 Serial Clock -#define AT91C_PA23_PWM0 ((unsigned int) AT91C_PIO_PA23) // PWM Channel 0 -#define AT91C_PIO_PA24 ((unsigned int) 1 << 24) // Pin Controlled by PA24 -#define AT91C_PA24_RTS1 ((unsigned int) AT91C_PIO_PA24) // USART 1 Ready To Send -#define AT91C_PA24_PWM1 ((unsigned int) AT91C_PIO_PA24) // PWM Channel 1 -#define AT91C_PIO_PA25 ((unsigned int) 1 << 25) // Pin Controlled by PA25 -#define AT91C_PA25_CTS1 ((unsigned int) AT91C_PIO_PA25) // USART 1 Clear To Send -#define AT91C_PA25_PWM2 ((unsigned int) AT91C_PIO_PA25) // PWM Channel 2 -#define AT91C_PIO_PA26 ((unsigned int) 1 << 26) // Pin Controlled by PA26 -#define AT91C_PA26_DCD1 ((unsigned int) AT91C_PIO_PA26) // USART 1 Data Carrier Detect -#define AT91C_PA26_TIOA2 ((unsigned int) AT91C_PIO_PA26) // Timer Counter 2 Multipurpose Timer I/O Pin A -#define AT91C_PIO_PA27 ((unsigned int) 1 << 27) // Pin Controlled by PA27 -#define AT91C_PA27_DTR1 ((unsigned int) AT91C_PIO_PA27) // USART 1 Data Terminal ready -#define AT91C_PA27_TIOB2 ((unsigned int) AT91C_PIO_PA27) // Timer Counter 2 Multipurpose Timer I/O Pin B -#define AT91C_PIO_PA28 ((unsigned int) 1 << 28) // Pin Controlled by PA28 -#define AT91C_PA28_DSR1 ((unsigned int) AT91C_PIO_PA28) // USART 1 Data Set ready -#define AT91C_PA28_TCLK1 ((unsigned int) AT91C_PIO_PA28) // Timer Counter 1 external clock input -#define AT91C_PIO_PA29 ((unsigned int) 1 << 29) // Pin Controlled by PA29 -#define AT91C_PA29_RI1 ((unsigned int) AT91C_PIO_PA29) // USART 1 Ring Indicator -#define AT91C_PA29_TCLK2 ((unsigned int) AT91C_PIO_PA29) // Timer Counter 2 external clock input -#define AT91C_PIO_PA3 ((unsigned int) 1 << 3) // Pin Controlled by PA3 -#define AT91C_PA3_TWD ((unsigned int) AT91C_PIO_PA3) // TWI Two-wire Serial Data -#define AT91C_PA3_NPCS3 ((unsigned int) AT91C_PIO_PA3) // SPI Peripheral Chip Select 3 -#define AT91C_PIO_PA30 ((unsigned int) 1 << 30) // Pin Controlled by PA30 -#define AT91C_PA30_IRQ1 ((unsigned int) AT91C_PIO_PA30) // External Interrupt 1 -#define AT91C_PA30_NPCS2 ((unsigned int) AT91C_PIO_PA30) // SPI Peripheral Chip Select 2 -#define AT91C_PIO_PA31 ((unsigned int) 1 << 31) // Pin Controlled by PA31 -#define AT91C_PA31_NPCS1 ((unsigned int) AT91C_PIO_PA31) // SPI Peripheral Chip Select 1 -#define AT91C_PA31_PCK2 ((unsigned int) AT91C_PIO_PA31) // PMC Programmable Clock Output 2 -#define AT91C_PIO_PA4 ((unsigned int) 1 << 4) // Pin Controlled by PA4 -#define AT91C_PA4_TWCK ((unsigned int) AT91C_PIO_PA4) // TWI Two-wire Serial Clock -#define AT91C_PA4_TCLK0 ((unsigned int) AT91C_PIO_PA4) // Timer Counter 0 external clock input -#define AT91C_PIO_PA5 ((unsigned int) 1 << 5) // Pin Controlled by PA5 -#define AT91C_PA5_RXD0 ((unsigned int) AT91C_PIO_PA5) // USART 0 Receive Data -#define AT91C_PA5_NPCS3 ((unsigned int) AT91C_PIO_PA5) // SPI Peripheral Chip Select 3 -#define AT91C_PIO_PA6 ((unsigned int) 1 << 6) // Pin Controlled by PA6 -#define AT91C_PA6_TXD0 ((unsigned int) AT91C_PIO_PA6) // USART 0 Transmit Data -#define AT91C_PA6_PCK0 ((unsigned int) AT91C_PIO_PA6) // PMC Programmable Clock Output 0 -#define AT91C_PIO_PA7 ((unsigned int) 1 << 7) // Pin Controlled by PA7 -#define AT91C_PA7_RTS0 ((unsigned int) AT91C_PIO_PA7) // USART 0 Ready To Send -#define AT91C_PA7_PWM3 ((unsigned int) AT91C_PIO_PA7) // PWM Channel 3 -#define AT91C_PIO_PA8 ((unsigned int) 1 << 8) // Pin Controlled by PA8 -#define AT91C_PA8_CTS0 ((unsigned int) AT91C_PIO_PA8) // USART 0 Clear To Send -#define AT91C_PA8_ADTRG ((unsigned int) AT91C_PIO_PA8) // ADC External Trigger -#define AT91C_PIO_PA9 ((unsigned int) 1 << 9) // Pin Controlled by PA9 -#define AT91C_PA9_DRXD ((unsigned int) AT91C_PIO_PA9) // DBGU Debug Receive Data -#define AT91C_PA9_NPCS1 ((unsigned int) AT91C_PIO_PA9) // SPI Peripheral Chip Select 1 - -// ***************************************************************************** -// PERIPHERAL ID DEFINITIONS FOR AT91SAM7S256 -// ***************************************************************************** -#define AT91C_ID_FIQ ((unsigned int) 0) // Advanced Interrupt Controller (FIQ) -#define AT91C_ID_SYS ((unsigned int) 1) // System Peripheral -#define AT91C_ID_PIOA ((unsigned int) 2) // Parallel IO Controller -#define AT91C_ID_3_Reserved ((unsigned int) 3) // Reserved -#define AT91C_ID_ADC ((unsigned int) 4) // Analog-to-Digital Converter -#define AT91C_ID_SPI ((unsigned int) 5) // Serial Peripheral Interface -#define AT91C_ID_US0 ((unsigned int) 6) // USART 0 -#define AT91C_ID_US1 ((unsigned int) 7) // USART 1 -#define AT91C_ID_SSC ((unsigned int) 8) // Serial Synchronous Controller -#define AT91C_ID_TWI ((unsigned int) 9) // Two-Wire Interface -#define AT91C_ID_PWMC ((unsigned int) 10) // PWM Controller -#define AT91C_ID_UDP ((unsigned int) 11) // USB Device Port -#define AT91C_ID_TC0 ((unsigned int) 12) // Timer Counter 0 -#define AT91C_ID_TC1 ((unsigned int) 13) // Timer Counter 1 -#define AT91C_ID_TC2 ((unsigned int) 14) // Timer Counter 2 -#define AT91C_ID_15_Reserved ((unsigned int) 15) // Reserved -#define AT91C_ID_16_Reserved ((unsigned int) 16) // Reserved -#define AT91C_ID_17_Reserved ((unsigned int) 17) // Reserved -#define AT91C_ID_18_Reserved ((unsigned int) 18) // Reserved -#define AT91C_ID_19_Reserved ((unsigned int) 19) // Reserved -#define AT91C_ID_20_Reserved ((unsigned int) 20) // Reserved -#define AT91C_ID_21_Reserved ((unsigned int) 21) // Reserved -#define AT91C_ID_22_Reserved ((unsigned int) 22) // Reserved -#define AT91C_ID_23_Reserved ((unsigned int) 23) // Reserved -#define AT91C_ID_24_Reserved ((unsigned int) 24) // Reserved -#define AT91C_ID_25_Reserved ((unsigned int) 25) // Reserved -#define AT91C_ID_26_Reserved ((unsigned int) 26) // Reserved -#define AT91C_ID_27_Reserved ((unsigned int) 27) // Reserved -#define AT91C_ID_28_Reserved ((unsigned int) 28) // Reserved -#define AT91C_ID_29_Reserved ((unsigned int) 29) // Reserved -#define AT91C_ID_IRQ0 ((unsigned int) 30) // Advanced Interrupt Controller (IRQ0) -#define AT91C_ID_IRQ1 ((unsigned int) 31) // Advanced Interrupt Controller (IRQ1) - -// ***************************************************************************** -// BASE ADDRESS DEFINITIONS FOR AT91SAM7S256 -// ***************************************************************************** -#define AT91C_BASE_SYS ((AT91PS_SYS) 0xFFFFF000) // (SYS) Base Address -#define AT91C_BASE_AIC ((AT91PS_AIC) 0xFFFFF000) // (AIC) Base Address -#define AT91C_BASE_PDC_DBGU ((AT91PS_PDC) 0xFFFFF300) // (PDC_DBGU) Base Address -#define AT91C_BASE_DBGU ((AT91PS_DBGU) 0xFFFFF200) // (DBGU) Base Address -#define AT91C_BASE_PIOA ((AT91PS_PIO) 0xFFFFF400) // (PIOA) Base Address -#define AT91C_BASE_CKGR ((AT91PS_CKGR) 0xFFFFFC20) // (CKGR) Base Address -#define AT91C_BASE_PMC ((AT91PS_PMC) 0xFFFFFC00) // (PMC) Base Address -#define AT91C_BASE_RSTC ((AT91PS_RSTC) 0xFFFFFD00) // (RSTC) Base Address -#define AT91C_BASE_RTTC ((AT91PS_RTTC) 0xFFFFFD20) // (RTTC) Base Address -#define AT91C_BASE_PITC ((AT91PS_PITC) 0xFFFFFD30) // (PITC) Base Address -#define AT91C_BASE_WDTC ((AT91PS_WDTC) 0xFFFFFD40) // (WDTC) Base Address -#define AT91C_BASE_VREG ((AT91PS_VREG) 0xFFFFFD60) // (VREG) Base Address -#define AT91C_BASE_MC ((AT91PS_MC) 0xFFFFFF00) // (MC) Base Address -#define AT91C_BASE_PDC_SPI ((AT91PS_PDC) 0xFFFE0100) // (PDC_SPI) Base Address -#define AT91C_BASE_SPI ((AT91PS_SPI) 0xFFFE0000) // (SPI) Base Address -#define AT91C_BASE_PDC_ADC ((AT91PS_PDC) 0xFFFD8100) // (PDC_ADC) Base Address -#define AT91C_BASE_ADC ((AT91PS_ADC) 0xFFFD8000) // (ADC) Base Address -#define AT91C_BASE_PDC_SSC ((AT91PS_PDC) 0xFFFD4100) // (PDC_SSC) Base Address -#define AT91C_BASE_SSC ((AT91PS_SSC) 0xFFFD4000) // (SSC) Base Address -#define AT91C_BASE_PDC_US1 ((AT91PS_PDC) 0xFFFC4100) // (PDC_US1) Base Address -#define AT91C_BASE_US1 ((AT91PS_USART) 0xFFFC4000) // (US1) Base Address -#define AT91C_BASE_PDC_US0 ((AT91PS_PDC) 0xFFFC0100) // (PDC_US0) Base Address -#define AT91C_BASE_US0 ((AT91PS_USART) 0xFFFC0000) // (US0) Base Address -#define AT91C_BASE_TWI ((AT91PS_TWI) 0xFFFB8000) // (TWI) Base Address -#define AT91C_BASE_TC0 ((AT91PS_TC) 0xFFFA0000) // (TC0) Base Address -#define AT91C_BASE_TC1 ((AT91PS_TC) 0xFFFA0040) // (TC1) Base Address -#define AT91C_BASE_TC2 ((AT91PS_TC) 0xFFFA0080) // (TC2) Base Address -#define AT91C_BASE_TCB ((AT91PS_TCB) 0xFFFA0000) // (TCB) Base Address -#define AT91C_BASE_PWMC_CH3 ((AT91PS_PWMC_CH) 0xFFFCC260) // (PWMC_CH3) Base Address -#define AT91C_BASE_PWMC_CH2 ((AT91PS_PWMC_CH) 0xFFFCC240) // (PWMC_CH2) Base Address -#define AT91C_BASE_PWMC_CH1 ((AT91PS_PWMC_CH) 0xFFFCC220) // (PWMC_CH1) Base Address -#define AT91C_BASE_PWMC_CH0 ((AT91PS_PWMC_CH) 0xFFFCC200) // (PWMC_CH0) Base Address -#define AT91C_BASE_PWMC ((AT91PS_PWMC) 0xFFFCC000) // (PWMC) Base Address -#define AT91C_BASE_UDP ((AT91PS_UDP) 0xFFFB0000) // (UDP) Base Address - -// ***************************************************************************** -// MEMORY MAPPING DEFINITIONS FOR AT91SAM7S256 -// ***************************************************************************** -#define AT91C_ISRAM ((char *) 0x00200000) // Internal SRAM base address -#define AT91C_ISRAM_SIZE ((unsigned int) 0x00010000) // Internal SRAM size in byte (64 Kbyte) -#define AT91C_IFLASH ((char *) 0x00100000) // Internal ROM base address -#define AT91C_IFLASH_SIZE ((unsigned int) 0x00040000) // Internal ROM size in byte (256 Kbyte) - -#endif diff --git a/AT91SAM7S256/SAM7S256/Include/Cstartup.S b/AT91SAM7S256/SAM7S256/Include/Cstartup.S deleted file mode 100644 index 0293251..0000000 --- a/AT91SAM7S256/SAM7S256/Include/Cstartup.S +++ /dev/null @@ -1,477 +0,0 @@ -/*------------------------------------------------------------------------------ -//*- ATMEL Microcontroller Software Support - ROUSSET - -//*------------------------------------------------------------------------------ -//* The software is delivered "AS IS" without warranty or condition of any -//* kind, either express, implied or statutory. This includes without -//* limitation any warranty or condition with respect to merchantability or -//* fitness for any particular purpose, or against the infringements of -//* intellectual property rights of others. -//*----------------------------------------------------------------------------- -//*- File source : Cstartup.s -//*- Object : Generic CStartup for KEIL and GCC -//*- Compilation flag : None -//*- -//*- 1.0 18/Oct/04 JPP : Creation -//*- 1.1 21/Feb/05 JPP : Set Interrupt -//*- 1.1 01/Apr/05 JPP : save SPSR -//* -//*- WinARM/arm-elf-gcc-version by Martin Thomas - Modifications: -//* remapping-support, vector-location, stack-position and more... -//*-----------------------------------------------------------------------------*/ - -/* - 20060902 (mth) : moved IRQ-Handler from section .vect* to - .init/.fastrun - 20061101 (mth) : update IRQ-Handler - FIQ-stack init -*/ - -/* check configuration-options and map to "assembler symbols": */ - -/*#include "AT91SAM7S256_inc.h"*/ - -#ifdef ROM_RUN -.set RAM_MODE, 0 -#ifdef VECTORS_IN_RAM -.set REMAP, 1 -.set VECTREMAPPED, 1 -#else -.set REMAP, 0 -.set VECTREMAPPED, 0 -#endif -#endif - -#ifdef RAM_RUN -.set RAM_MODE, 1 -.set REMAP, 1 -.set VECTREMAPPED, 0 -#endif - -.set VECTREMAPPED_AUTODETECT, 0 -.set CPP_CONSTRUCTORS, 0 - - -.if (RAM_MODE) -.print "RAM_MODE enabled" -.else -.print "ROM_MODE enabled" -.endif - -.if (REMAP) -.print "remapping enabled" -.endif - -.if (VECTREMAPPED) -.print "Vectors at start of RAM" -.else -.print "Vectors at start of Code" -.endif - - .equ AIC_IVR, (256) - .equ AIC_FVR, (260) - .equ AIC_EOICR, (304) - .equ AT91C_BASE_AIC, (0xFFFFF000) - -/*------------------------------------------------------------------------------ -//*- Exception vectors -//*-------------------- -//*- These vectors can be read at address 0 or at RAM address -//*- They ABSOLUTELY requires to be in relative addresssing mode in order to -//*- guarantee a valid jump. For the moment, all are just looping. -//*- If an exception occurs before remap, this would result in an infinite loop. -//*- To ensure if a exeption occurs before start application to infinite loop. -//*------------------------------------------------------------------------------*/ - -.if (VECTREMAPPED) -.print "Vectors in section .vectmapped -> .data" -.section .vectmapped, "ax" -.else -.print "Vectors in section .vectorg -> .text" -.section .vectorg, "ax" -.endif - - LDR PC,Reset_Addr /* 0x00 Reset handler */ - LDR PC,Undef_Addr /* 0x04 Undefined Instruction */ - LDR PC,SWI_Addr /* 0x08 Software Interrupt */ - LDR PC,PAbt_Addr /* 0x0C Prefetch Abort */ - LDR PC,DAbt_Addr /* 0x10 Data Abort */ - NOP /* 0x14 reserved */ - LDR PC,IRQ_Addr /* 0x18 IRQ */ -fiqvec: /* 0x1c FIQ */ -/*------------------------------------------------------------------------------ -//*- Function : FIQ_Handler_Entry -//*- Treatments : FIQ Controller Interrupt Handler. -//*- Called Functions : AIC_FVR[interrupt] -//*------------------------------------------------------------------------------*/ - -FIQ_Handler_Entry: - -/*- Switch in SVC/User Mode to allow User Stack access for C code */ -/* because the FIQ is not yet acknowledged*/ - -/*- Save and r0 in FIQ_Register */ - mov r9,r0 - ldr r0 , [r8, #AIC_FVR] - msr CPSR_c,#I_BIT | F_BIT | ARM_MODE_SVC - -/*- Save scratch/used registers and LR in User Stack */ - stmfd sp!, { r1-r3, r12, lr} - -/*- Branch to the routine pointed by the AIC_FVR */ - mov r14, pc - bx r0 - -/*- Restore scratch/used registers and LR from User Stack */ - ldmia sp!, { r1-r3, r12, lr} - -/*- Leave Interrupts disabled and switch back in FIQ mode */ - msr CPSR_c, #I_BIT | F_BIT | ARM_MODE_FIQ - -/*- Restore the R0 ARM_MODE_SVC register */ - mov r0,r9 - -/*- Restore the Program Counter using the LR_fiq directly in the PC */ - subs pc,lr,#4 - -/* end of fiqhandler */ - -Reset_Addr: .word InitReset -#ifdef ARMDEBUG -Undef_Addr: .word undef_handler /* BKPT instruction trap */ -#else -Undef_Addr: .word Undef_Handler -#endif -SWI_Addr: .word SWI_Handler -/*SWI_Addr: .word SoftwareInterruptASM*/ /*in swi_handler.S */ -#ifdef ARMDEBUG -PAbt_Addr: .word prefetch_abort_handler -DAbt_Addr: .word data_abort_handler -#else -PAbt_Addr: .word PAbt_Handler -DAbt_Addr: .word DAbt_Handler -#endif -IRQ_Addr: .word IRQ_Handler_Entry - - .global default_undef_handler -default_undef_handler: -Undef_Handler: B Undef_Handler -SWI_Handler: B SWI_Handler - .global default_prefetch_abort_handler -default_prefetch_abort_handler: -PAbt_Handler: B PAbt_Handler - .global default_data_abort_handler -default_data_abort_handler: -DAbt_Handler: B DAbt_Handler - - - .arm - .section .init, "ax" - .global _startup - .func _startup -_startup: -reset: - -.if (VECTREMAPPED) -/* mthomas: Dummy used during startup */ - LDR PC, Reset_Addr_F - NOP - NOP - NOP - NOP - NOP /*.word 0xdeadbeef*/ /* Reserved Address */ - NOP - NOP -Reset_Addr_F: .word InitReset -.endif - -.RAM_TOP: - .word __TOP_STACK - -InitReset: - -/*------------------------------------------------------------------------------ -/*- Remapping -/*------------------------------------------------------------------------------*/ -.if (VECTREMAPPED) - .print "RCR setting for remapping enabled" - .equ MC_BASE,0xFFFFFF00 /* MC Base Address */ - .equ MC_RCR, 0x00 /* MC_RCR Offset */ - - -.if (VECTREMAPPED_AUTODETECT) - /* store first word in RAM into r4 */ - ldr r0,=__FIRST_IN_RAM - ldr r4,[r0] - /* load value at address 0 into R2 */ - ldr r1,=0x00000000 - ldr r2,[r1] - /* xor value from address 0 (flip all bits), store in R3 */ - ldr r3,=0xffffffff - eor r3, r2, r3 - /* write xored value to first word in RAM - if already remapped this will also change - the value at 0 */ - str r3,[r0] - /* load from address 0 again into R3 */ - ldr r3,[r1] - /* restore first value in RAM */ - str r4,[r0] - - /* compare */ - cmp r3, r2 - bne already_remapped -.endif - - /* if both values have been equal the change of the - RAM-value had no effect on the value at 0x00000000 - so we are not remapping yet -> remap now: */ - LDR R0, =MC_BASE - MOV R1, #1 - STR R1, [R0, #MC_RCR] - -already_remapped: -.endif - - -/*------------------------------------------------------------------------------ -/*- Low level Init (PMC, AIC, ? ....) by C function AT91F_LowLevelInit -/*------------------------------------------------------------------------------*/ - .extern AT91F_LowLevelInit -/*- minumum C initialization */ -/*- call AT91F_LowLevelInit( void) */ - - ldr sp, .RAM_TOP /* temporary stack in internal RAM (**) */ -/*--Call Low level init function in ABSOLUTE through the Interworking */ - ldr r0,=AT91F_LowLevelInit - mov lr, pc - bx r0 -/*------------------------------------------------------------------------------ -//*- Stack Sizes Definition -//*------------------------ -//*- Interrupt Stack requires 2 words x 8 priority level x 4 bytes when using -//*- the vectoring. This assume that the IRQ management. -//*- The Interrupt Stack must be adjusted depending on the interrupt handlers. -//*- Fast Interrupt not requires stack If in your application it required you must -//*- be definehere. -//*- The System stack size is not defined and is limited by the free internal -//*- SRAM. -//*------------------------------------------------------------------------------*/ - -/*------------------------------------------------------------------------------ -//*- Top of Stack Definition -//*------------------------- -//*- Interrupt and Supervisor Stack are located at the top of internal memory in -//*- order to speed the exception handling context saving and restoring. -//*- ARM_MODE_SVC (Application, C) Stack is located at the top of the external memory. -//*------------------------------------------------------------------------------*/ - - .EQU IRQ_STACK_SIZE, (3*8*4) - .EQU FIQ_STACK_SIZE, (3*8*4) - .EQU ARM_MODE_FIQ, 0x11 - .EQU ARM_MODE_IRQ, 0x12 - .EQU ARM_MODE_SVC, 0x13 - .EQU ARM_MODE_ABT, 0x17 - - .EQU I_BIT, 0x80 - .EQU F_BIT, 0x40 - -/*------------------------------------------------------------------------------ -//*- Setup the stack for each mode -//*-------------------------------*/ - mov r0, sp /* see (**) */ - -#ifdef ARMDEBUG -/*- Set up Abort Mode Stack for Debugger*/ - msr CPSR_c, #ARM_MODE_ABT | I_BIT | F_BIT - ldr sp, =__abort_stack_top__ -#endif - -/*- Set up Fast Interrupt Mode and set FIQ Mode Stack*/ - msr CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT - mov sp, r0 - sub r0, r0, #FIQ_STACK_SIZE -/*- Init the FIQ register*/ - ldr r8, =AT91C_BASE_AIC - -/*- Set up Interrupt Mode and set IRQ Mode Stack*/ - msr CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT - mov sp, r0 /* Init stack IRQ */ - sub r0, r0, #IRQ_STACK_SIZE - -/*- Set up Supervisor Mode and set Supervisor Mode Stack*/ -// /* start with INT and FIQ enabled */ - msr CPSR_c, #ARM_MODE_SVC - - /* start with INT and FIQ disabled */ -// msr CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT - - mov sp, r0 /* Init stack Sup */ - - -/*- Enable interrupt & Set up Supervisor Mode and set Supervisor Mode Stack*/ - -/* Relocate .data section (Copy from ROM to RAM) - This will also copy the .vectmapped and .fastrun */ - LDR R1, =_etext - LDR R2, =_data - LDR R3, =_edata -LoopRel: CMP R2, R3 - LDRLO R0, [R1], #4 - STRLO R0, [R2], #4 - BLO LoopRel - -/* Clear .bss section (Zero init) */ - MOV R0, #0 - LDR R1, =__bss_start__ - LDR R2, =__bss_end__ -LoopZI: CMP R1, R2 - STRLO R0, [R1], #4 - BLO LoopZI - - -.if (CPP_CONSTRUCTORS) -/* call C++ constructors of global objects */ - LDR r0, =__ctors_start__ - LDR r1, =__ctors_end__ -ctor_loop: - CMP r0, r1 - BEQ ctor_end - LDR r2, [r0], #4 - STMFD sp!, {r0-r1} - MOV lr, pc -/* MOV pc, r2 */ - BX r2 /* mthomas 8/2006 */ - LDMFD sp!, {r0-r1} - B ctor_loop -ctor_end: -.endif - - -/* call main() */ - ldr lr,=exit - ldr r0,=main - bx r0 - - .size _startup, . - _startup - .endfunc - -/* "exit" dummy added by mthomas to avoid sbrk write read etc. needed - by the newlib default "exit" */ - .global exit - .func exit -exit: - b . - .size exit, . - exit - .endfunc - - - - -/*------------------------------------------------------------------------------ -//*- Manage exception -//*--------------- -//*- This module The exception must be ensure in ARM mode -//*------------------------------------------------------------------------------ -//*------------------------------------------------------------------------------ -//*- Function : IRQ_Handler_Entry -//*- Treatments : IRQ Controller Interrupt Handler. -//*- Called Functions : AIC_IVR[interrupt] -//*------------------------------------------------------------------------------*/ - -.if (VECTREMAPPED) -.print "IRQ_Handler_Entry in section .fastrun -> .data" -.section .fastrun, "ax" -.else -.print "IRQ_Handler_Entry in section .init -> .text" -.section .init, "ax" -.endif - - .global IRQ_Handler_Entry - .func IRQ_Handler_Entry -IRQ_Handler_Entry: -/*---- Adjust and save return address on the stack */ - sub lr, lr, #4 - stmfd sp!, {lr} - -/*---- Save r0 and SPSR on the stack */ - mrs r14, SPSR - stmfd sp!, {r0, r14} - -/*---- Write in the IVR to support Protect mode */ -/*---- No effect in Normal Mode */ -/*---- De-assert NIRQ and clear the source in Protect mode */ - ldr r14, =AT91C_BASE_AIC - ldr r0, [r14, #AIC_IVR] - str r14, [r14, #AIC_IVR] - -/*---- Enable nested interrupts and switch to Supervisor mode */ - msr CPSR_c, #ARM_MODE_SVC - -/*---- Save scratch/used registers and LR on the stack */ - stmfd sp!, {r1-r3, r12, r14} - -/*---- Branch to the routine pointed by AIC_IVR */ - mov r14, pc - bx r0 - -/*---- Restore scratch/used registers and LR from the stack */ - ldmia sp!, {r1-r3, r12, r14} - -/*---- Disable nested interrupts and switch back to IRQ mode */ - msr CPSR_c, #I_BIT | ARM_MODE_IRQ - -/*---- Acknowledge interrupt by writing AIC_EOICR */ - ldr r14, =AT91C_BASE_AIC - str r14, [r14, #AIC_EOICR] - -/*---- Restore SPSR and r0 from the stack */ - ldmia sp!, {r0, r14} - msr SPSR_cxsf, r14 - -/*---- Return from interrupt handler */ - ldmia sp!, {pc}^ - - .size IRQ_Handler_Entry, . - IRQ_Handler_Entry - .endfunc - - -/*--------------------------------------------------------------- -//* ?EXEPTION_VECTOR -//* This module is only linked if needed for closing files. -//*---------------------------------------------------------------*/ - .global AT91F_Default_FIQ_handler - .func AT91F_Default_FIQ_handler -AT91F_Default_FIQ_handler: - b AT91F_Default_FIQ_handler - .size AT91F_Default_FIQ_handler, . - AT91F_Default_FIQ_handler - .endfunc - - .global AT91F_Default_IRQ_handler - .func AT91F_Default_IRQ_handler -AT91F_Default_IRQ_handler: - b AT91F_Default_IRQ_handler - .size AT91F_Default_IRQ_handler, . - AT91F_Default_IRQ_handler - .endfunc - - .global AT91F_Spurious_handler - .func AT91F_Spurious_handler -AT91F_Spurious_handler: - b AT91F_Spurious_handler - .size AT91F_Spurious_handler, . - AT91F_Spurious_handler - .endfunc - -/*------------------------------------------------------------------------------ -//*- Various debugger stacks. -//*-------------------------------*/ - -#ifdef ARMDEBUG -.section .stack.abort, "aw", %nobits - .space 0x80; /* 128 byte abort mode stack. */ -.section .stack.debugger, "aw", %nobits - .space 0x48; /* 16 user mode registers + SPSR + UNDEF Next Instruction Address */ -.section .breakpoints, "aw", %nobits - .space 0x40; /* Single Stepping Breakpoint + 7 Breakpoints */ -#endif - - .end - diff --git a/AT91SAM7S256/SAM7S256/Include/Cstartup_SAM7.c b/AT91SAM7S256/SAM7S256/Include/Cstartup_SAM7.c deleted file mode 100644 index c0a7da4..0000000 --- a/AT91SAM7S256/SAM7S256/Include/Cstartup_SAM7.c +++ /dev/null @@ -1,93 +0,0 @@ -//*---------------------------------------------------------------------------- -//* ATMEL Microcontroller Software Support - ROUSSET - -//*---------------------------------------------------------------------------- -//* The software is delivered "AS IS" without warranty or condition of any -//* kind, either express, implied or statutory. This includes without -//* limitation any warranty or condition with respect to merchantability or -//* fitness for any particular purpose, or against the infringements of -//* intellectual property rights of others. -//*---------------------------------------------------------------------------- -//* File Name : Cstartup_SAM7.c -//* Object : Low level initializations written in C for IAR Tools -//* Creation : 12/Jun/04 -//* 1.2 28/Feb/05 JPP : LIB change AT91C_WDTC_WDDIS & PLL -//* 1.3 21/Mar/05 JPP : Change PLL Wait time -//*---------------------------------------------------------------------------- - -// Include the board file description -#include "AT91SAM7S256.h" - -// The following functions must be write in ARM mode this function called directly -// by exception vector -extern void AT91F_Spurious_handler(void); -extern void AT91F_Default_IRQ_handler(void); -extern void AT91F_Default_FIQ_handler(void); - -#ifdef __IAR_SYSTEMS_ICC__ -# define SECTION_ICODE @ "ICODE" -#else -# define SECTION_ICODE -#endif -//*---------------------------------------------------------------------------- -//* \fn AT91F_LowLevelInit -//* \brief This function performs very low level HW initialization -//* this function can be use a Stack, depending the compilation -//* optimization mode -//*---------------------------------------------------------------------------- -void AT91F_LowLevelInit( void) SECTION_ICODE -{ - int i; - AT91PS_PMC pPMC = AT91C_BASE_PMC; - - //* Set Flash Waite sate - // Single Cycle Access at Up to 30 MHz, or 40 - // if MCK = 47923200 I have 72 Cycle for 1,5 usecond ( flied MC_FMR->FMCN - AT91C_BASE_MC->MC_FMR = ((AT91C_MC_FMCN)&(72 <<16)) | AT91C_MC_FWS_1FWS ; - - //* Watchdog Disable - AT91C_BASE_WDTC->WDTC_WDMR= AT91C_WDTC_WDDIS; - - //* Set MCK at 47 923 200 - // 1 Enabling the Main Oscillator: - // SCK = 1/32768 = 30.51 uSecond - // Start up time = 8 * 6 / SCK = 56 * 30.51 = 1,46484375 ms - pPMC->PMC_MOR = (( AT91C_CKGR_OSCOUNT & (0x06 <<8) | AT91C_CKGR_MOSCEN )); - - // Wait the startup time - while(!(pPMC->PMC_SR & AT91C_PMC_MOSCS)); - - // 2 Checking the Main Oscillator Frequency (Optional) - // 3 Setting PLL and divider: - // - div by 14 Fin = 1.3165 =(18,432 / 14) - // - Mul 72+1: Fout = 96.1097 =(3,6864 *73) - // for 96 MHz the erroe is 0.11% - // Field out NOT USED = 0 - // PLLCOUNT pll startup time estimate at : 0.844 ms - // PLLCOUNT 28 = 0.000844 /(1/32768) - pPMC->PMC_PLLR = ((AT91C_CKGR_DIV & 14) | - (AT91C_CKGR_PLLCOUNT & (28<<8)) | - (AT91C_CKGR_MUL & (72<<16))); - - // Wait the startup time - while(!(pPMC->PMC_SR & AT91C_PMC_LOCK)); - while(!(pPMC->PMC_SR & AT91C_PMC_MCKRDY)); - - // 4. Selection of Master Clock and Processor Clock - // select the PLL clock divided by 2 - pPMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2 ; - while(!(pPMC->PMC_SR & AT91C_PMC_MCKRDY)); - - pPMC->PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK ; - while(!(pPMC->PMC_SR & AT91C_PMC_MCKRDY)); - - // Set up the default interrupts handler vectors - AT91C_BASE_AIC->AIC_SVR[0] = (int) AT91F_Default_FIQ_handler ; - for (i=1;i < 31; i++) - { - AT91C_BASE_AIC->AIC_SVR[i] = (int) AT91F_Default_IRQ_handler ; - } - AT91C_BASE_AIC->AIC_SPU = (int) AT91F_Spurious_handler ; -} - - - diff --git a/AT91SAM7S256/SAM7S256/Include/sam7s256.c b/AT91SAM7S256/SAM7S256/Include/sam7s256.c deleted file mode 100644 index b2657d5..0000000 --- a/AT91SAM7S256/SAM7S256/Include/sam7s256.c +++ /dev/null @@ -1,34 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 10-12-07 14:29 $ -// -// Filename $Workfile:: sam7s256.c $ -// -// Version $Revision:: 3 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Sam7s256/Incl $ -// -// Platform C -// -#ifdef ARMDEBUG -#include "debug_stub.h" -#endif - -void main(void) -{ - while(TRUE) - { - HARDWAREInit; - mSchedInit(); -#ifdef ARMDEBUG - dbg__bkpt_init(); -#endif - while(TRUE == mSchedCtrl()) - { - OSWatchdogWrite; - } - mSchedExit(); - HARDWAREExit; - } -} diff --git a/AT91SAM7S256/SAM7S256/Include/sam7s256.h b/AT91SAM7S256/SAM7S256/Include/sam7s256.h deleted file mode 100644 index 0118c40..0000000 --- a/AT91SAM7S256/SAM7S256/Include/sam7s256.h +++ /dev/null @@ -1,64 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 24-04-08 14:33 $ -// -// Filename $Workfile:: sam7s256.h $ -// -// Version $Revision:: 5 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Sam7s256/Incl $ -// -// Platform C -// - -#ifndef SAM7S256_H -#define SAM7S256_H - -#ifdef __IAR_SYSTEMS_ICC__ -#include "ioat91sam7s256.h" -#else -#include "AT91SAM7S256.h" -#endif - -#define SAM7S256 - -#define HARDWAREInit {\ - ULONG TmpReset;\ - *AT91C_RSTC_RMR = 0xA5000401;\ - *AT91C_AIC_DCR = 1;\ - *AT91C_PITC_PIMR = (0x000FFFFF | 0x01000000);\ - TmpReset = *AT91C_PITC_PIVR;\ - TmpReset = TmpReset;/* Suppress warning*/\ - *AT91C_PMC_PCER = (1L</dev/null \ - || LC_ALL=C date -u -r "$(SOURCE_DATE_EPOCH)" "$(DATE_FMT)" 2>/dev/null \ - || LC_ALL=C date -u "$(DATE_FMT)") - -TARGET = nxt_firmware - -# Set to 'y' to enable embedded debuger. -ARMDEBUG = n - -ARM_SOURCES = -THUMB_SOURCES = c_button.c c_cmd.c c_comm.c c_display.c c_input.c c_ioctrl.c \ - c_loader.c c_lowspeed.c c_output.c c_sound.c c_ui.c \ - d_bt.c d_button.c d_display.c d_hispeed.c d_input.c \ - d_ioctrl.c d_loader.c d_lowspeed.c d_output.c d_sound.c \ - d_timer.c d_usb.c \ - m_sched.c \ - abort.c errno.c sbrk.c strtod.c sscanf.c \ - Cstartup_SAM7.c - -ASM_ARM_SOURCE = Cstartup.S -ASM_THUMB_SOURCE = - -vpath %.c $(SRCDIR) -vpath %.c $(CPUINCDIR) -vpath %.c lib -vpath %.S $(CPUINCDIR) - -INCLUDES = - -MCU = arm7tdmi -STARTOFUSERFLASH_DEFINES = -DSTARTOFUSERFLASH_FROM_LINKER=1 -VERSION_DEFINES = -D'BUILD_DATE="$(BUILD_DATE)"' -DEFINES = -DPROTOTYPE_PCB_4 -DNEW_MENU -DROM_RUN -DVECTORS_IN_RAM \ - $(STARTOFUSERFLASH_DEFINES) $(VERSION_DEFINES) -OPTIMIZE = -Os -fno-strict-aliasing \ - -ffunction-sections -fdata-sections -WARNINGS = -Wall -W -Wundef -Wno-unused -Wno-format -THUMB_INTERWORK = -mthumb-interwork -CFLAGS = -g -mcpu=$(MCU) $(THUMB) $(THUMB_INTERWORK) $(WARNINGS) $(OPTIMIZE) -ASFLAGS = -g -mcpu=$(MCU) $(THUMB) $(THUMB_INTERWORK) -CPPFLAGS = $(INCLUDES) $(DEFINES) -MMD -LDSCRIPT = nxt.ld -LDFLAGS = -nostdlib -T $(LDSCRIPT) -Wl,--gc-sections -LDLIBS = -lc -lm -lgcc -lnosys - -ifeq ($(ARMDEBUG),y) -ASM_ARM_SOURCE += abort_handler.S undef_handler.S debug_hexutils.S \ - debug_stub.S debug_comm.S debug_opcodes.S \ - debug_runlooptasks.S -vpath %.S $(DBGDIR) -DEFINES += -DARMDEBUG -INCLUDES += -I../../armdebug/Debugger -endif - -CROSS_COMPILE = arm-none-eabi- -CC = $(CROSS_COMPILE)gcc -OBJDUMP = $(CROSS_COMPILE)objdump -OBJCOPY = $(CROSS_COMPILE)objcopy - -FWFLASH = fwflash - -ARM_OBJECTS = $(ARM_SOURCES:%.c=%.o) $(ASM_ARM_SOURCE:%.S=%.o) -THUMB_OBJECTS = $(THUMB_SOURCES:%.c=%.o) $(THUMB_ARM_SOURCE:%.S=%.o) -OBJECTS = $(ARM_OBJECTS) $(THUMB_OBJECTS) - -all: bin - -elf: $(TARGET).elf -bin: $(TARGET).bin -sym: $(TARGET).sym -lst: $(TARGET).lst - -$(TARGET).elf: THUMB = -mthumb -$(TARGET).elf: $(OBJECTS) $(LDSCRIPT) - $(LINK.c) $(OBJECTS) $(LOADLIBES) $(LDLIBS) -o $@ - -%.bin: %.elf - $(OBJCOPY) --pad-to=0x140000 --gap-fill=0xff -O binary $< $@ - -%.sym: %.elf - $(OBJDUMP) -h -t $< > $@ - -%.lst: %.elf - $(OBJDUMP) -S $< > $@ - -$(THUMB_OBJECTS): THUMB = -mthumb - --include $(OBJECTS:%.o=%.d) - -LAST_BUILD_DATE=none --include version.mak -ifneq ($(LAST_BUILD_DATE),$(BUILD_DATE)) -.PHONY: version.mak -version.mak: - echo "LAST_BUILD_DATE = $(BUILD_DATE)" > $@ -endif - -c_ui.o: version.mak - -program: $(TARGET).bin - $(FWFLASH) $(TARGET).bin - -clean: - rm -f $(TARGET).elf $(TARGET).bin $(TARGET).sym $(TARGET).lst \ - $(OBJECTS) $(OBJECTS:%.o=%.d) version.mak diff --git a/AT91SAM7S256/SAM7S256/gcc/lib/abort.c b/AT91SAM7S256/SAM7S256/gcc/lib/abort.c deleted file mode 100644 index 26d47e7..0000000 --- a/AT91SAM7S256/SAM7S256/gcc/lib/abort.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2011 Nicolas Schodet - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -/* Provide an abort function, could be used by various library function. */ - -void -abort (void) -{ - /* Wait for ever, nothing better to do. */ - while (1) - ; -} - diff --git a/AT91SAM7S256/SAM7S256/gcc/lib/errno.c b/AT91SAM7S256/SAM7S256/gcc/lib/errno.c deleted file mode 100644 index 3eb52ac..0000000 --- a/AT91SAM7S256/SAM7S256/gcc/lib/errno.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2010 Nicolas Schodet - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -/* This is needed for libm. Provide a non thread safe errno. */ - -static int __the_errno; - -int * -__errno (void) -{ - return &__the_errno; -} - diff --git a/AT91SAM7S256/SAM7S256/gcc/lib/sbrk.c b/AT91SAM7S256/SAM7S256/gcc/lib/sbrk.c deleted file mode 100644 index 317a94b..0000000 --- a/AT91SAM7S256/SAM7S256/gcc/lib/sbrk.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2010 Nicolas Schodet - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -/* The newlib sprintf use dynamic allocation for floating point. Therefore, - * the sbrk syscall should be provided. - * - * This works by taking memory above BSS and below stack. There is no - * collision detection as it whould not known what to do then. */ - -extern char _end; - -void * -_sbrk (int incr) -{ - static char *heap = 0; - char *base; - /* Initialise if first call. */ - if (heap == 0) - heap = &_end; - /* Increment and return old heap base. */ - base = heap; - heap += incr; - return base; -} - diff --git a/AT91SAM7S256/SAM7S256/gcc/lib/sscanf.c b/AT91SAM7S256/SAM7S256/gcc/lib/sscanf.c deleted file mode 100644 index a4f5e64..0000000 --- a/AT91SAM7S256/SAM7S256/gcc/lib/sscanf.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2010 Nicolas Schodet - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -/* NXT source code is using sscanf to parse a float. Newlib sscanf will pull - * too many code, so here is a stub which implement just what is used. */ -#include -#include -#include - -int -sscanf (const char *str, const char *fmt, ...) -{ - va_list ap; - float *f; - char *tailptr; - /* Only support use in NXT source code. */ - if (fmt[0] != '%' || fmt[1] != 'f' || fmt[2] != '\0') - return 0; - /* Retrieve float pointer. */ - va_start (ap, fmt); - f = va_arg (ap, float *); - va_end (ap); - /* Parse using the nice strtod. */ - *f = strtod (str, &tailptr); - if (str == tailptr) - return 0; - else - return 1; -} - diff --git a/AT91SAM7S256/SAM7S256/gcc/lib/strtod.c b/AT91SAM7S256/SAM7S256/gcc/lib/strtod.c deleted file mode 100644 index 49d02a2..0000000 --- a/AT91SAM7S256/SAM7S256/gcc/lib/strtod.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * strtod.c -- - * - * Source code for the "strtod" library procedure. - * - * Copyright (c) 1988-1993 The Regents of the University of California. - * Copyright (c) 1994 Sun Microsystems, Inc. - * - * Permission to use, copy, modify, and distribute this - * software and its documentation for any purpose and without - * fee is hereby granted, provided that the above copyright - * notice appear in all copies. The University of California - * makes no representations about the suitability of this - * software for any purpose. It is provided "as is" without - * express or implied warranty. - */ - -#include -#include -#include - -#ifndef TRUE -#define TRUE 1 -#define FALSE 0 -#endif -#ifndef NULL -#define NULL 0 -#endif - -static int maxExponent = 511; /* Largest possible base 10 exponent. Any - * exponent larger than this will already - * produce underflow or overflow, so there's - * no need to worry about additional digits. - */ -static double powersOf10[] = { /* Table giving binary powers of 10. Entry */ - 10., /* is 10^2^i. Used to convert decimal */ - 100., /* exponents into floating-point numbers. */ - 1.0e4, - 1.0e8, - 1.0e16, - 1.0e32, - 1.0e64, - 1.0e128, - 1.0e256 -}; - -/* - *---------------------------------------------------------------------- - * - * strtod -- - * - * This procedure converts a floating-point number from an ASCII - * decimal representation to internal double-precision format. - * - * Results: - * The return value is the double-precision floating-point - * representation of the characters in string. If endPtr isn't - * NULL, then *endPtr is filled in with the address of the - * next character after the last one that was part of the - * floating-point number. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -double -strtod(string, endPtr) - const char *string; /* A decimal ASCII floating-point number, - * optionally preceded by white space. - * Must have form "-I.FE-X", where I is the - * integer part of the mantissa, F is the - * fractional part of the mantissa, and X - * is the exponent. Either of the signs - * may be "+", "-", or omitted. Either I - * or F may be omitted, or both. The decimal - * point isn't necessary unless F is present. - * The "E" may actually be an "e". E and X - * may both be omitted (but not just one). - */ - char **endPtr; /* If non-NULL, store terminating character's - * address here. */ -{ - int sign, expSign = FALSE; - double fraction, dblExp, *d; - register const char *p; - register int c; - int exp = 0; /* Exponent read from "EX" field. */ - int fracExp = 0; /* Exponent that derives from the fractional - * part. Under normal circumstatnces, it is - * the negative of the number of digits in F. - * However, if I is very long, the last digits - * of I get dropped (otherwise a long I with a - * large negative exponent could cause an - * unnecessary overflow on I alone). In this - * case, fracExp is incremented one for each - * dropped digit. */ - int mantSize; /* Number of digits in mantissa. */ - int decPt; /* Number of mantissa digits BEFORE decimal - * point. */ - const char *pExp; /* Temporarily holds location of exponent - * in string. */ - - /* - * Strip off leading blanks and check for a sign. - */ - - p = string; - while (isspace(*p)) { - p += 1; - } - if (*p == '-') { - sign = TRUE; - p += 1; - } else { - if (*p == '+') { - p += 1; - } - sign = FALSE; - } - - /* - * Count the number of digits in the mantissa (including the decimal - * point), and also locate the decimal point. - */ - - decPt = -1; - for (mantSize = 0; ; mantSize += 1) - { - c = *p; - if (!isdigit(c)) { - if ((c != '.') || (decPt >= 0)) { - break; - } - decPt = mantSize; - } - p += 1; - } - - /* - * Now suck up the digits in the mantissa. Use two integers to - * collect 9 digits each (this is faster than using floating-point). - * If the mantissa has more than 18 digits, ignore the extras, since - * they can't affect the value anyway. - */ - - pExp = p; - p -= mantSize; - if (decPt < 0) { - decPt = mantSize; - } else { - mantSize -= 1; /* One of the digits was the point. */ - } - if (mantSize > 18) { - fracExp = decPt - 18; - mantSize = 18; - } else { - fracExp = decPt - mantSize; - } - if (mantSize == 0) { - fraction = 0.0; - p = string; - goto done; - } else { - int frac1, frac2; - frac1 = 0; - for ( ; mantSize > 9; mantSize -= 1) - { - c = *p; - p += 1; - if (c == '.') { - c = *p; - p += 1; - } - frac1 = 10*frac1 + (c - '0'); - } - frac2 = 0; - for (; mantSize > 0; mantSize -= 1) - { - c = *p; - p += 1; - if (c == '.') { - c = *p; - p += 1; - } - frac2 = 10*frac2 + (c - '0'); - } - fraction = (1.0e9 * frac1) + frac2; - } - - /* - * Skim off the exponent. - */ - - p = pExp; - if ((*p == 'E') || (*p == 'e')) { - p += 1; - if (*p == '-') { - expSign = TRUE; - p += 1; - } else { - if (*p == '+') { - p += 1; - } - expSign = FALSE; - } - while (isdigit(*p)) { - exp = exp * 10 + (*p - '0'); - p += 1; - } - } - if (expSign) { - exp = fracExp - exp; - } else { - exp = fracExp + exp; - } - - /* - * Generate a floating-point number that represents the exponent. - * Do this by processing the exponent one bit at a time to combine - * many powers of 2 of 10. Then combine the exponent with the - * fraction. - */ - - if (exp < 0) { - expSign = TRUE; - exp = -exp; - } else { - expSign = FALSE; - } - if (exp > maxExponent) { - exp = maxExponent; - errno = ERANGE; - } - dblExp = 1.0; - for (d = powersOf10; exp != 0; exp >>= 1, d += 1) { - if (exp & 01) { - dblExp *= *d; - } - } - if (expSign) { - fraction /= dblExp; - } else { - fraction *= dblExp; - } - -done: - if (endPtr != NULL) { - *endPtr = (char *) p; - } - - if (sign) { - return -fraction; - } - return fraction; -} diff --git a/AT91SAM7S256/SAM7S256/gcc/nxt.ld b/AT91SAM7S256/SAM7S256/gcc/nxt.ld deleted file mode 100644 index e54bc5d..0000000 --- a/AT91SAM7S256/SAM7S256/gcc/nxt.ld +++ /dev/null @@ -1,167 +0,0 @@ - -MEMORY -{ - CODE (rx) : ORIGIN = 0x00100000, LENGTH = 256k - DATA (rwx) : ORIGIN = 0x00200000, LENGTH = 64k -} - -__FIRST_IN_RAM = ORIGIN(DATA); -__TOP_STACK = ORIGIN(DATA) + LENGTH(DATA); - -/* Section Definitions */ - -SECTIONS -{ - /* first section is .text which is used for code */ - . = ORIGIN(CODE); - - .text : - { - KEEP(*(.vectorg)) - . = ALIGN(4); - KEEP(*(.init)) - *(.text .text.*) /* remaining code */ - *(.gnu.linkonce.t.*) - *(.glue_7) - *(.glue_7t) - *(.gcc_except_table) - *(.rodata) /* read-only data (constants) */ - *(.rodata.*) - *(.gnu.linkonce.r.*) - . = ALIGN(4); - } >CODE - - . = ALIGN(4); - - /* .ctors .dtors are used for c++ constructors/destructors */ - - .ctors : - { - PROVIDE(__ctors_start__ = .); - KEEP(*(SORT(.ctors.*))) - KEEP(*(.ctors)) - PROVIDE(__ctors_end__ = .); - } >CODE - - .dtors : - { - PROVIDE(__dtors_start__ = .); - KEEP(*(SORT(.dtors.*))) - KEEP(*(.dtors)) - PROVIDE(__dtors_end__ = .); - } >CODE - - __exidx_start = . ; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } >CODE - __exidx_end = . ; - - . = ALIGN(4); - - _etext = . ; - PROVIDE (etext = .); - - /* .data section which is used for initialized data */ - .data : AT (_etext) - { - _data = . ; - KEEP(*(.vectmapped)) - . = ALIGN(4); - *(.fastrun .fastrun.*) - . = ALIGN(4); - SORT(CONSTRUCTORS) - . = ALIGN(4); - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - . = ALIGN(4); - } >DATA - - . = ALIGN(4); - - _edata = . ; - PROVIDE (edata = .); - - __STARTOFUSERFLASH_FROM_LINKER = - ALIGN (LOADADDR (.data) + SIZEOF (.data), 0x100); - - /* - * The various debugger stacks. - */ - .stack : ALIGN(8) { - /* abort stack */ - __abort_stack_bottom__ = . ; - KEEP(*(.stack.abort)) - __abort_stack__ = . ; - __abort_stack_top__ = . ; - - /* debugger state */ - __debugger_stack_bottom__ = . ; - KEEP(*(.stack.debugger)) - __debugger_stack__ = . ; - __debugger_stack_top__ = . ; - - /* breakpoints */ - __breakpoints_start__ = . ; - KEEP(*(.breakpoints)) - __breakpoints_end__ = . ; - } > DATA - - __breakpoints_num__ = (__breakpoints_end__ - __breakpoints_start__) / 8; - - /* .bss section which is used for uninitialized data */ - .bss (NOLOAD) : - { - __bss_start = . ; - __bss_start__ = . ; - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - *(COMMON) - . = ALIGN(4); - } >DATA - - . = ALIGN(4); - - __bss_end__ = . ; - - _end = .; - PROVIDE (end = .); - - /* Stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } - /* DWARF debug sections. - Symbols in the DWARF debugging sections are relative to the beginning - of the section so we begin them at 0. */ - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } - -} diff --git a/AT91SAM7S256/Source/BtTest.inc b/AT91SAM7S256/Source/BtTest.inc deleted file mode 100644 index 65575af..0000000 --- a/AT91SAM7S256/Source/BtTest.inc +++ /dev/null @@ -1,1613 +0,0 @@ -//******* TestPrg ************************************************************ - -//#define TESTPRG // If defined the test program will be included - -#ifndef BUILD_DATE -# define BUILD_DATE "" -#endif - -#ifdef TESTPRG -#include "Test1.txt" -#include "Test2.txt" -#endif - -extern void BtIo(void); - -void GetProtocolVersion(UBYTE *String) -{ - char Tmp[DISPLAYLINE_LENGTH + 1]; - snprintf(Tmp, sizeof(Tmp), "%d.%d.%d", (FIRMWAREVERSION >> 8) & 0xFF, FIRMWAREVERSION & 0xFF, FIRMWAREPATCH); - snprintf((char*)String, DISPLAYLINE_LENGTH + 1, "FWi %*s", DISPLAYLINE_LENGTH - 4, Tmp); -} - - -void GetARMBuild(UBYTE *String) -{ - snprintf((char*)String, DISPLAYLINE_LENGTH + 1, "%s", BUILD_DATE); -} - - -void GetBC4Build(UBYTE *String) -{ - sprintf((char*)String,"BC4 %2X.%02X",pMapComm->BrickData.BluecoreVersion[1],pMapComm->BrickData.BluecoreVersion[0]); -} - - -void GetAVRBuild(UBYTE *String) -{ - sprintf((char*)String,"AVR %1u.%02u",((IoFromAvr.Battery >> 13) & 3),((IoFromAvr.Battery >> 10) & 7)); -} - - -void GetBC4Address(UBYTE *String) -{ - UWORD Count; - UBYTE Tmp; - - Count = (UWORD)sprintf((char*)String,"ID "); - for (Tmp = 0;(Tmp < (SIZE_OF_BDADDR - 1)) && (Count <= (DISPLAYLINE_LENGTH - 2));Tmp++) - { - Count += (UWORD)sprintf((char*)&String[Count],"%02X",(UWORD)(pMapComm->BrickData.BdAddr[Tmp]) & 0xFF); - } -} - - -enum TSTPRG -{ - SYSTEM_INIT = 1, - SYSTEM_UNLOCK_INIT, - SYSTEM_UNLOCK, - SYSTEM_PAGE, - TIMER_INIT, - TIMER_SHOW, - TIMER_HOLD, - BT_PAGE, - BT_RESET, - BT_RESETTING, - BT_LIST_INIT, - BT_LIST, - BT_CONN_INIT, - BT_CONN, - BT_UPDATE_FW, - TSTPRG_INIT, - TSTPRG_SELECT_SUBTEST, - - TSTPRG_SENSOR_INIT, - TSTPRG_SELECT_SENSOR, - TSTPRG_TOUCH_SENSOR_INIT, - TSTPRG_TOUCH_SENSOR, - TSTPRG_SOUND_SENSOR_SELECT, - TSTPRG_SOUND_SENSOR_INIT, - TSTPRG_SOUND_SENSOR, - TSTPRG_LIGHT_SENSOR_SELECT, - TSTPRG_LIGHT_SENSOR_INIT, - TSTPRG_LIGHT_SENSOR, - TSTPRG_SKIP_SENSOR, - - TSTPRG_RCX_INIT, - TSTPRG_RCX_SELECT, - TSTPRG_RCX_DISPLAY_INIT, - TSTPRG_RCX_DISPLAY, - TSTPRG_RCX_INPUT_SELECT, - TSTPRG_RCX_INPUT_INIT, - TSTPRG_RCX_INPUT, - TSTPRG_RCX_DIGITAL_INIT, - TSTPRG_RCX_DIGITAL_OK, - TSTPRG_RCX_DIGITAL_FAIL, - TSTPRG_RCX_DIGITAL, - TSTPRG_RCX_MOTOR_INIT, - TSTPRG_RCX_MOTOR, - TSTPRG_SKIP_RCX_MOTOR, - TSTPRG_SKIP_RCX, - - TSTPRG_MOTOR_INIT, - TSTPRG_MOTOR, - TSTPRG_SKIP_MOTOR, - - TSTPRG_SKIP, - TSTPRG_WAIT -}; - -const UBYTE TXT_EMPTY[] = " "; -const UBYTE TXT_LINE[] = "----------------"; - -#ifdef TESTPRG - -const UBYTE TXT_TEST[] = "Timer Test Bt "; - -const UBYTE TXT_TIMER[] = "Reset Hold "; -const UBYTE TXT_TIMER_HOLD[] = " Continue "; - -const UBYTE TXT_LAST[] = "Last UI->BT Cmd."; -const UBYTE TXT_BT_PAGE[] = "Reset List BtIo"; - -const UBYTE TXT_RESETTING[] = " Resetting! "; - -const UBYTE TXT_BT_LIST[] = "Down ConTab Up "; -const UBYTE TXT_BT_CONN[] = "Down Update Up "; - -const UBYTE TXT_BTUPDATE[] = "BT update mode !"; -const UBYTE TXT_DONE[] = " When done "; -const UBYTE TXT_RESET[] = " activate reset "; -const UBYTE TXT_REBOOT[] = "button to reboot"; - -const UBYTE TXT_TESTPRG[] = " TestPrg V0.08 "; -const UBYTE TXT_SELECT[] = "Select sub test "; -const UBYTE TXT_SUBTEST[] = "Sens. RCX Motor"; - -const UBYTE TXT_SELECT_SENSOR[] = " Select sensor "; -const UBYTE TXT_SENSORS[] = "Touch Snd. Light"; - -const UBYTE TXT_SELECT_TYPE[] = " Select type "; -const UBYTE TXT_SOUND_SENSORS[] = " DB DBA "; -const UBYTE TXT_LIGHT_SENSORS[] = "Pasive Active"; - -const UBYTE TXT_SENSOR_TOUCH[] = "Touch Sensor Tst"; -const UBYTE TXT_SENSOR_SOUND_DB[] = "DB Sound Sens."; -const UBYTE TXT_SENSOR_SOUND_DBA[] = "DBA Sound Sens."; -const UBYTE TXT_SOUND_STOP[] = "440Hz Stop 4KHz"; -const UBYTE TXT_SENSOR_LIGHT_PASIVE[] = "Pas. Light Sens."; -const UBYTE TXT_SENSOR_LIGHT_ACTIVE[] = "Act. Light Sens."; - -const UBYTE TXT_SUBTEST_STOP[] = " Stop "; - -const UBYTE TXT_MOTOR[] = " Motor test "; -const UBYTE TXT_MOTOR_HEADER[] = "Outp Set Cnt"; -const UBYTE TXT_MOTOR_STOP[] = "Bwd Stop Fwd"; - -const UBYTE TXT_RCX[] = " RCX test "; -const UBYTE TXT_RCX_STOP[] = "Inp Disp Outp"; -const UBYTE TXT_RCX_INPUT_PASIVE[] = "Input pasive Tst"; -const UBYTE TXT_RCX_INPUT_ACTIVE[] = "Input active Tst"; -const UBYTE TXT_RCX_INPUT_SELECT[] = "Pas. Act. Dig."; -const UBYTE TXT_RCX_INPUT_DIGITAL[] = "Digital I/O Tst"; -const UBYTE TXT_RCX_DIGITAL_OK[] = " OK "; -const UBYTE TXT_RCX_DIGITAL_FAIL[] = " FAIL "; -const UBYTE TXT_MOTOR_NEXT[] = "Bwd Next Fwd"; - - -void TestPrgRunMotor(UBYTE No,SBYTE Speed) -{ - pMapOutPut->Outputs[No].Mode = MOTORON | BRAKE; - pMapOutPut->Outputs[No].Speed = Speed; - pMapOutPut->Outputs[No].TachoLimit = 0; - pMapOutPut->Outputs[No].RunState = MOTOR_RUN_STATE_RUNNING; - pMapOutPut->Outputs[No].Flags = UPDATE_MODE | UPDATE_SPEED | UPDATE_TACHO_LIMIT; -} - -void TestPrgFloatMotor(UBYTE No) -{ - pMapOutPut->Outputs[No].Mode = 0; - pMapOutPut->Outputs[No].Speed = 0; - pMapOutPut->Outputs[No].TachoLimit = 0; - pMapOutPut->Outputs[No].RunState = MOTOR_RUN_STATE_RUNNING; - pMapOutPut->Outputs[No].Flags = UPDATE_MODE | UPDATE_SPEED | UPDATE_TACHO_LIMIT; -} - -SBYTE TestPrgReadMotor(UBYTE No) -{ - return ((SBYTE)(pMapOutPut->Outputs[No].TachoCnt / 360)); -} - -#endif - - -UBYTE TestPrg(UBYTE Dummy) -{ - static UWORD Count; - static UBYTE TxtBuffer[TEXTLINES][DISPLAYLINE_LENGTH + 1]; - static UBYTE State = SYSTEM_INIT; -#ifdef TESTPRG - static UWORD Pointer; - static UWORD InputValues[NO_OF_INPUTS]; - static SWORD OutputValues[NO_OF_OUTPUTS]; - static UBYTE VolumeSave; - static UBYTE Timer; - static UBYTE SubState = 0; - UBYTE Tmp; -#endif - - Dummy = Dummy; - switch (State) - { - case SYSTEM_INIT : - { - GetProtocolVersion(TxtBuffer[0]); - GetARMBuild(TxtBuffer[1]); - GetAVRBuild(TxtBuffer[2]); - GetBC4Build(TxtBuffer[3]); - GetBC4Address(TxtBuffer[4]); - - pMapDisplay->pTextLines[TEXTLINE_3] = (UBYTE*)TxtBuffer[0]; - pMapDisplay->pTextLines[TEXTLINE_4] = (UBYTE*)TxtBuffer[1]; - pMapDisplay->pTextLines[TEXTLINE_5] = (UBYTE*)TxtBuffer[2]; - pMapDisplay->pTextLines[TEXTLINE_6] = (UBYTE*)TxtBuffer[3]; - pMapDisplay->pTextLines[TEXTLINE_7] = (UBYTE*)TxtBuffer[4]; - pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_EMPTY; - pMapDisplay->UpdateMask |= (TEXTLINE_BIT(TEXTLINE_3) | TEXTLINE_BIT(TEXTLINE_4) | TEXTLINE_BIT(TEXTLINE_5) | TEXTLINE_BIT(TEXTLINE_6) | TEXTLINE_BIT(TEXTLINE_7) | TEXTLINE_BIT(TEXTLINE_8)); - -#ifdef TESTPRG - SubState = 0; -#endif - State = SYSTEM_UNLOCK_INIT; - } - break; - -#ifndef TESTPRG - - case SYSTEM_UNLOCK_INIT : // ENTER * 1 + LEFT * 3 + RIGHT * 2 + ENTER * 1 = TEST MENU - { - if (cUiReadButtons() != BUTTON_NONE) - { - State = TSTPRG_SKIP; - } - } - break; - -#else - - case SYSTEM_UNLOCK_INIT : // ENTER * 1 + LEFT * 3 + RIGHT * 2 + ENTER * 1 = TEST MENU - { - Tmp = cUiReadButtons(); - switch (Tmp) - { - case BUTTON_ENTER : - { - switch (SubState) - { - case 0 : - { - SubState = 1; - Pointer = 0; - Count = 0; - } - break; - - case 3 : - { - State = SYSTEM_UNLOCK; - } - break; - - default : - { - Tmp = BUTTON_EXIT; - } - break; - - } - } - break; - - case BUTTON_NONE : - { - } - break; - - default : - { - switch (SubState) - { - case 0 : - { - Tmp = BUTTON_EXIT; - } - break; - - case 1 : - { - if (Tmp == BUTTON_LEFT) - { - if (++Count >= 3) - { - Count = 0; - SubState = 2; - } - Pointer = 0; - } - else - { - Tmp = BUTTON_EXIT; - } - } - break; - - case 2 : - { - if (Tmp == BUTTON_RIGHT) - { - if (++Count >= 2) - { - SubState = 3; - } - Pointer = 0; - } - else - { - Tmp = BUTTON_EXIT; - } - } - break; - - } - } - break; - - } - Pointer++; - if (((SubState) && (Pointer > 500)) || (Tmp == BUTTON_EXIT)) - { - State = TSTPRG_SKIP; - } - } - break; - - case SYSTEM_UNLOCK : - { - pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_TEST; - pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_8); - State = SYSTEM_PAGE; - } - break; - - case SYSTEM_PAGE : - { - switch (cUiReadButtons()) - { - case BUTTON_ENTER : - { - IOMapUi.Flags &= ~UI_ENABLE_STATUS_UPDATE; - pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_BACKGROUND); - State = TSTPRG_INIT; - } - break; - - case BUTTON_EXIT : - { - Count = 0; - State = TSTPRG_SKIP; - } - break; - - case BUTTON_LEFT : - { - IOMapUi.Flags &= ~UI_ENABLE_STATUS_UPDATE; - pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_BACKGROUND); - pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_2] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_3] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_4] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_5] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_6] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_7] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_TIMER; - pMapDisplay->EraseMask |= TEXTLINE_BITS; - pMapDisplay->UpdateMask |= TEXTLINE_BITS; - State = TIMER_INIT; - } - break; - - case BUTTON_RIGHT : - { - IOMapUi.Flags &= ~UI_ENABLE_STATUS_UPDATE; - pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_BACKGROUND); - pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_2] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_3] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_4] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_5] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_6] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_7] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_BT_PAGE; - if (DISPLAYLINE_LENGTH >= 16) - { - sprintf((char*)TxtBuffer[2],"Command %02X",(UWORD)VarsUi.BTCommand & 0xFF); - sprintf((char*)TxtBuffer[3],"Parameter 1 %02X",(UWORD)VarsUi.BTPar1 & 0xFF); - sprintf((char*)TxtBuffer[4],"Parameter 2 %02X",(UWORD)VarsUi.BTPar2 & 0xFF); - sprintf((char*)TxtBuffer[5],"Result %04X",(UWORD)VarsUi.BTResult); - pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_LAST; - pMapDisplay->pTextLines[TEXTLINE_2] = (UBYTE*)TXT_LINE; - pMapDisplay->pTextLines[TEXTLINE_3] = TxtBuffer[2]; - pMapDisplay->pTextLines[TEXTLINE_4] = TxtBuffer[3]; - pMapDisplay->pTextLines[TEXTLINE_5] = TxtBuffer[4]; - pMapDisplay->pTextLines[TEXTLINE_6] = TxtBuffer[5]; - } - pMapDisplay->EraseMask |= TEXTLINE_BITS; - pMapDisplay->UpdateMask |= TEXTLINE_BITS; - State = BT_PAGE; - } - break; - - } - } - break; - - case TIMER_INIT : - { - State = TIMER_SHOW; - } - break; - - case TIMER_SHOW : - { - sprintf((char*)TxtBuffer[2]," %10lu mS ",VarsUi.CRPasskey); - pMapDisplay->pTextLines[TEXTLINE_3] = TxtBuffer[2]; - pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3); - - switch (cUiReadButtons()) - { - case BUTTON_ENTER : - { - pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_TIMER_HOLD; - pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_8); - State = TIMER_HOLD; - } - break; - - case BUTTON_LEFT : - { - pMapDisplay->EraseMask |= TEXTLINE_BIT(TEXTLINE_3); - VarsUi.CRPasskey = 0L; - } - break; - - case BUTTON_EXIT : - { - State = TSTPRG_SKIP; - } - break; - - } - } - break; - - case TIMER_HOLD : - { - switch (cUiReadButtons()) - { - case BUTTON_ENTER : - { - pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_TIMER; - pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_8); - State = TIMER_SHOW; - } - break; - - case BUTTON_EXIT : - { - State = TSTPRG_SKIP; - } - break; - - } - } - break; - - case BT_PAGE : - { - switch (cUiReadButtons()) - { - case BUTTON_ENTER : - { - for (Count = 0;Count < TEXTLINES;Count++) - { - strcpy((char*)TxtBuffer[Count],(char*)TXT_EMPTY); - pMapDisplay->pTextLines[TEXTLINE_1 + Count] = TxtBuffer[Count]; - } - pMapDisplay->pTextLines[TEXTLINE_2] = (UBYTE*)TXT_LINE; - pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_BT_LIST; - pMapDisplay->EraseMask |= TEXTLINE_BITS; - pMapDisplay->UpdateMask |= TEXTLINE_BITS; - Pointer = 0; - State = BT_LIST_INIT; - } - break; - - case BUTTON_EXIT : - { - Count = 0; - State = TSTPRG_SKIP; - } - break; - - case BUTTON_LEFT : - { - State = BT_RESET; - } - break; - - case BUTTON_RIGHT : - { - pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_BTUPDATE; - pMapDisplay->pTextLines[TEXTLINE_2] = (UBYTE*)TXT_LINE; - pMapDisplay->pTextLines[TEXTLINE_3] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_4] = (UBYTE*)TXT_DONE; - pMapDisplay->pTextLines[TEXTLINE_5] = (UBYTE*)TXT_RESET; - pMapDisplay->pTextLines[TEXTLINE_6] = (UBYTE*)TXT_REBOOT; - pMapDisplay->pTextLines[TEXTLINE_7] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_EMPTY; - pMapDisplay->EraseMask |= TEXTLINE_BITS; - pMapDisplay->UpdateMask |= TEXTLINE_BITS; - Timer = 0; - State = BT_UPDATE_FW; - } - break; - - } - } - break; - - case BT_RESET : - { - VarsUi.BTCommand = (UBYTE)FACTORYRESET; - VarsUi.BTPar1 = (UBYTE)0; - VarsUi.BTPar2 = (UBYTE)0; - if (pMapComm->pFunc(VarsUi.BTCommand,VarsUi.BTPar1,VarsUi.BTPar2,0,NULL,&(VarsUi.BTResult)) == SUCCESS) - { - pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_2] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_3] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_4] = (UBYTE*)TXT_RESETTING; - pMapDisplay->pTextLines[TEXTLINE_5] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_6] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_7] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_EMPTY; - pMapDisplay->EraseMask |= TEXTLINE_BITS; - pMapDisplay->UpdateMask |= TEXTLINE_BITS; - State = BT_RESETTING; - } - else - { - State = TSTPRG_SKIP; - } - } - break; - - case BT_RESETTING : - { - if (VarsUi.BTResult != INPROGRESS) - { - State = TSTPRG_SKIP; - } - } - break; - - case BT_UPDATE_FW : - { - if (++Timer >= 100) - { - BtIo(); - } - } - break; - - case BT_LIST_INIT : - { - sprintf((char*)TxtBuffer[0],"DeviceTable No%2u",Pointer); - sprintf((char*)TxtBuffer[2],"%-*.*s",DISPLAYLINE_LENGTH,DISPLAYLINE_LENGTH,(char*)pMapComm->BtDeviceTable[Pointer].Name); - Count = (UWORD)sprintf((char*)TxtBuffer[3],"COD="); - for (Tmp = 0;(Tmp < SIZE_OF_CLASS_OF_DEVICE) && (Count < (DISPLAYLINE_LENGTH - 2));Tmp++) - { - Count += (UWORD)sprintf((char*)&TxtBuffer[3][Count],"%02X",(UWORD)(pMapComm->BtDeviceTable[Pointer].ClassOfDevice[Tmp]) & 0xFF); - } - Count = (UWORD)sprintf((char*)TxtBuffer[4],"A="); - for (Tmp = 0;(Tmp < SIZE_OF_BDADDR) && (Count <= (DISPLAYLINE_LENGTH - 2));Tmp++) - { - Count += (UWORD)sprintf((char*)&TxtBuffer[4][Count],"%02X",(UWORD)(pMapComm->BtDeviceTable[Pointer].BdAddr[Tmp]) & 0xFF); - } - sprintf((char*)TxtBuffer[5],"Status=%02X",(UWORD)(pMapComm->BtDeviceTable[Pointer].DeviceStatus) & 0xFF); - pMapDisplay->EraseMask |= TEXTLINE_BITS; - pMapDisplay->UpdateMask |= TEXTLINE_BITS; - State = BT_LIST; - } - break; - - case BT_LIST : - { - switch (cUiReadButtons()) - { - case BUTTON_ENTER : - { - for (Count = 0;Count < TEXTLINES;Count++) - { - strcpy((char*)TxtBuffer[Count],(char*)TXT_EMPTY); - pMapDisplay->pTextLines[TEXTLINE_1 + Count] = TxtBuffer[Count]; - } - pMapDisplay->pTextLines[TEXTLINE_2] = (UBYTE*)TXT_LINE; - pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_BT_CONN; - pMapDisplay->EraseMask |= TEXTLINE_BITS; - pMapDisplay->UpdateMask |= TEXTLINE_BITS; - Pointer = 0; - State = BT_CONN_INIT; - } - break; - - case BUTTON_EXIT : - { - State = SYSTEM_INIT; - } - break; - - case BUTTON_LEFT : - { - if (Pointer) - { - Pointer--; - } - else - { - Pointer = (SIZE_OF_BT_DEVICE_TABLE - 1); - } - State = BT_LIST_INIT; - } - break; - - case BUTTON_RIGHT : - { - if (Pointer < (SIZE_OF_BT_DEVICE_TABLE - 1)) - { - Pointer++; - } - else - { - Pointer = 0; - } - State = BT_LIST_INIT; - } - break; - - } - } - break; - - case BT_CONN_INIT : - { - sprintf((char*)TxtBuffer[0],"Conn. Table No%2u",Pointer); - sprintf((char*)TxtBuffer[2],"%-*.*s",DISPLAYLINE_LENGTH,DISPLAYLINE_LENGTH,(char*)pMapComm->BtConnectTable[Pointer].Name); - Count = (UWORD)sprintf((char*)TxtBuffer[3],"COD="); - for (Tmp = 0;(Tmp < SIZE_OF_CLASS_OF_DEVICE) && (Count < (DISPLAYLINE_LENGTH - 2));Tmp++) - { - Count += (UWORD)sprintf((char*)&TxtBuffer[3][Count],"%02X",(UWORD)(pMapComm->BtConnectTable[Pointer].ClassOfDevice[Tmp]) & 0xFF); - } - Count = (UWORD)sprintf((char*)TxtBuffer[4],"A="); - for (Tmp = 0;(Tmp < SIZE_OF_BDADDR) && (Count <= (DISPLAYLINE_LENGTH - 2));Tmp++) - { - Count += (UWORD)sprintf((char*)&TxtBuffer[4][Count],"%02X",(UWORD)(pMapComm->BtConnectTable[Pointer].BdAddr[Tmp]) & 0xFF); - } - sprintf((char*)TxtBuffer[5],"%-*.*s",DISPLAYLINE_LENGTH,DISPLAYLINE_LENGTH,(char*)pMapComm->BtConnectTable[Pointer].PinCode); - if (DISPLAYLINE_LENGTH >= 16) - { - sprintf((char*)TxtBuffer[6],"H=%02X S=%02X Q=%02X",(UWORD)(pMapComm->BtConnectTable[Pointer].HandleNr) & 0xFF,(UWORD)(pMapComm->BtConnectTable[Pointer].StreamStatus) & 0xFF,(UWORD)(pMapComm->BtConnectTable[Pointer].LinkQuality) & 0xFF); - } - pMapDisplay->EraseMask |= TEXTLINE_BITS; - pMapDisplay->UpdateMask |= TEXTLINE_BITS; - State = BT_CONN; - } - break; - - case BT_CONN : - { - switch (cUiReadButtons()) - { - case BUTTON_ENTER : - { - State = BT_CONN_INIT; - } - break; - - case BUTTON_EXIT : - { - State = SYSTEM_INIT; - } - break; - - case BUTTON_LEFT : - { - if (Pointer) - { - Pointer--; - } - else - { - Pointer = (SIZE_OF_BT_CONNECT_TABLE - 1); - } - State = BT_CONN_INIT; - } - break; - - case BUTTON_RIGHT : - { - if (Pointer < (SIZE_OF_BT_CONNECT_TABLE - 1)) - { - Pointer++; - } - else - { - Pointer = 0; - } - State = BT_CONN_INIT; - } - break; - - } - } - break; - - case TSTPRG_INIT : - { - IOMapUi.Flags &= ~UI_ENABLE_STATUS_UPDATE; - - pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_BACKGROUND); - - pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_TESTPRG; - pMapDisplay->pTextLines[TEXTLINE_2] = (UBYTE*)TXT_LINE; - pMapDisplay->pTextLines[TEXTLINE_3] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_4] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_5] = (UBYTE*)TXT_SELECT; - pMapDisplay->pTextLines[TEXTLINE_6] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_7] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_SUBTEST; - pMapDisplay->UpdateMask |= TEXTLINE_BITS; - - State = TSTPRG_SELECT_SUBTEST; - } - break; - - case TSTPRG_SELECT_SUBTEST : - { - switch (cUiReadButtons()) - { - case BUTTON_LEFT : - { - State = TSTPRG_SENSOR_INIT; - } - break; - - case BUTTON_RIGHT : - { - State = TSTPRG_MOTOR_INIT; - } - break; - - case BUTTON_ENTER : - { - State = TSTPRG_RCX_INIT; - } - break; - - case BUTTON_EXIT : - { - Count = 0; - State = TSTPRG_SKIP; - } - break; - - } - } - break; - - case TSTPRG_SENSOR_INIT : - { - pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_TESTPRG; - pMapDisplay->pTextLines[TEXTLINE_2] = (UBYTE*)TXT_LINE; - pMapDisplay->pTextLines[TEXTLINE_3] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_4] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_5] = (UBYTE*)TXT_SELECT_SENSOR; - pMapDisplay->pTextLines[TEXTLINE_6] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_7] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_SENSORS; - pMapDisplay->UpdateMask |= TEXTLINE_BITS; - - for (Count = 0;Count < NO_OF_INPUTS;Count++) - { - InputValues[Count] = 0x7FFF; - strcpy((char*)TxtBuffer[Count]," "); - } - - State = TSTPRG_SELECT_SENSOR; - } - break; - - case TSTPRG_SELECT_SENSOR : - { - switch (cUiReadButtons()) - { - case BUTTON_LEFT : - { - State = TSTPRG_TOUCH_SENSOR_INIT; - } - break; - - case BUTTON_ENTER : - { - pMapDisplay->pTextLines[TEXTLINE_5] = (UBYTE*)TXT_SELECT_TYPE; - pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_SOUND_SENSORS; - pMapDisplay->UpdateMask |= TEXTLINE_BITS; - State = TSTPRG_SOUND_SENSOR_SELECT; - } - break; - - case BUTTON_RIGHT : - { - pMapDisplay->pTextLines[TEXTLINE_5] = (UBYTE*)TXT_SELECT_TYPE; - pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_LIGHT_SENSORS; - pMapDisplay->UpdateMask |= TEXTLINE_BITS; - State = TSTPRG_LIGHT_SENSOR_SELECT; - } - break; - - case BUTTON_EXIT : - { - State = TSTPRG_INIT; - } - break; - - } - } - break; - - case TSTPRG_TOUCH_SENSOR_INIT : - { - for (Count = 0;Count < NO_OF_INPUTS;Count++) - { - pMapDisplay->pTextLines[TEXTLINE_3 + Count] = TxtBuffer[Count]; - } - pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_SENSOR_TOUCH; - pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_SUBTEST_STOP; - pMapDisplay->UpdateMask |= TEXTLINE_BITS; - for (Count = 0;Count < NO_OF_INPUTS;Count++) - { - pMapInput->Inputs[Count].SensorType = SWITCH; - } - State = TSTPRG_TOUCH_SENSOR; - } - break; - - case TSTPRG_TOUCH_SENSOR : - { - for (Count = 0;Count < NO_OF_INPUTS;Count++) - { - if (InputValues[Count] != pMapInput->Inputs[Count].ADRaw) - { - InputValues[Count] = pMapInput->Inputs[Count].ADRaw; - sprintf((char*)TxtBuffer[Count]," Input %u = %4u ",(UWORD)Count + 1,(UWORD)InputValues[Count]); - pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3 + Count); - } - } - if (cUiReadButtons() != BUTTON_NONE) - { - State = TSTPRG_SKIP_SENSOR; - } - } - break; - - case TSTPRG_SOUND_SENSOR_SELECT : - { - switch (cUiReadButtons()) - { - case BUTTON_LEFT : - { - pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_SENSOR_SOUND_DB; - for (Count = 0;Count < NO_OF_INPUTS;Count++) - { - pMapInput->Inputs[Count].SensorType = SOUND_DB; - } - State = TSTPRG_SOUND_SENSOR_INIT; - } - break; - - case BUTTON_ENTER : - { - State = TSTPRG_SKIP_SENSOR; - } - break; - - case BUTTON_EXIT : - { - State = TSTPRG_SKIP_SENSOR; - } - break; - - case BUTTON_RIGHT : - { - pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_SENSOR_SOUND_DBA; - for (Count = 0;Count < NO_OF_INPUTS;Count++) - { - pMapInput->Inputs[Count].SensorType = SOUND_DBA; - } - State = TSTPRG_SOUND_SENSOR_INIT; - } - break; - - } - } - break; - - case TSTPRG_SOUND_SENSOR_INIT : - { - VolumeSave = pMapSound->Volume; - pMapSound->Volume = MAX_VOLUME; - for (Count = 0;Count < NO_OF_INPUTS;Count++) - { - pMapDisplay->pTextLines[TEXTLINE_3 + Count] = TxtBuffer[Count]; - } - pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_SOUND_STOP; - pMapDisplay->UpdateMask |= TEXTLINE_BITS; - State = TSTPRG_SOUND_SENSOR; - } - break; - - case TSTPRG_SOUND_SENSOR : - { - for (Count = 0;Count < NO_OF_INPUTS;Count++) - { - if (InputValues[Count] != pMapInput->Inputs[Count].ADRaw) - { - InputValues[Count] = pMapInput->Inputs[Count].ADRaw; - sprintf((char*)TxtBuffer[Count]," Input %u = %4u ",(UWORD)Count + 1,(UWORD)InputValues[Count]); - pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3 + Count); - } - } - switch (cUiReadButtons()) - { - case BUTTON_LEFT : - { - pMapSound->Freq = 440; - pMapSound->Duration = 2000; - pMapSound->Mode = SOUND_TONE; - pMapSound->Flags |= SOUND_UPDATE; - } - break; - - case BUTTON_ENTER : - { - pMapSound->State = SOUND_STOP; - pMapSound->Volume = VolumeSave; - State = TSTPRG_SKIP_SENSOR; - } - break; - - case BUTTON_EXIT : - { - pMapSound->State = SOUND_STOP; - pMapSound->Volume = VolumeSave; - State = TSTPRG_SKIP_SENSOR; - } - break; - - case BUTTON_RIGHT : - { - pMapSound->Freq = 4000; - pMapSound->Duration = 2000; - pMapSound->Mode = SOUND_TONE; - pMapSound->Flags |= SOUND_UPDATE; - } - break; - - } - } - break; - - case TSTPRG_LIGHT_SENSOR_SELECT : - { - switch (cUiReadButtons()) - { - case BUTTON_LEFT : - { - pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_SENSOR_LIGHT_PASIVE; - for (Count = 0;Count < NO_OF_INPUTS;Count++) - { - pMapInput->Inputs[Count].SensorType = LIGHT_INACTIVE; - } - State = TSTPRG_LIGHT_SENSOR_INIT; - } - break; - - case BUTTON_ENTER : - { - State = TSTPRG_SKIP_SENSOR; - } - break; - - case BUTTON_EXIT : - { - State = TSTPRG_SKIP_SENSOR; - } - break; - - case BUTTON_RIGHT : - { - pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_SENSOR_LIGHT_ACTIVE; - for (Count = 0;Count < NO_OF_INPUTS;Count++) - { - pMapInput->Inputs[Count].SensorType = LIGHT_ACTIVE; - } - State = TSTPRG_LIGHT_SENSOR_INIT; - } - break; - - } - } - break; - - case TSTPRG_LIGHT_SENSOR_INIT : - { - for (Count = 0;Count < NO_OF_INPUTS;Count++) - { - pMapDisplay->pTextLines[TEXTLINE_3 + Count] = TxtBuffer[Count]; - } - pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_SUBTEST_STOP; - pMapDisplay->UpdateMask |= TEXTLINE_BITS; - State = TSTPRG_LIGHT_SENSOR; - } - break; - - case TSTPRG_LIGHT_SENSOR : - { - for (Count = 0;Count < NO_OF_INPUTS;Count++) - { - if (InputValues[Count] != pMapInput->Inputs[Count].ADRaw) - { - InputValues[Count] = pMapInput->Inputs[Count].ADRaw; - sprintf((char*)TxtBuffer[Count]," Input %u = %4u ",(UWORD)Count + 1,(UWORD)InputValues[Count]); - pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3 + Count); - } - } - if (cUiReadButtons() != BUTTON_NONE) - { - State = TSTPRG_SKIP_SENSOR; - } - } - break; - - case TSTPRG_SKIP_SENSOR : - { - for (Count = 0;Count < NO_OF_INPUTS;Count++) - { - pMapInput->Inputs[Count].SensorType = NO_SENSOR; - } - State = TSTPRG_SENSOR_INIT; - } - break; - - case TSTPRG_MOTOR_INIT : - { - pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_MOTOR; - pMapDisplay->pTextLines[TEXTLINE_2] = (UBYTE*)TXT_LINE; - pMapDisplay->pTextLines[TEXTLINE_3] = (UBYTE*)TXT_MOTOR_HEADER; - pMapDisplay->pTextLines[TEXTLINE_4] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_5] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_6] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_7] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_MOTOR_STOP; - - for (Count = 0;Count < NO_OF_OUTPUTS;Count++) - { - OutputValues[Count] = 0x7FFF; - TestPrgRunMotor(Count,0); - strcpy((char*)TxtBuffer[Count]," "); - pMapDisplay->pTextLines[TEXTLINE_4 + Count] = TxtBuffer[Count]; - } - - pMapDisplay->UpdateMask |= TEXTLINE_BITS; - State = TSTPRG_MOTOR; - } - break; - - case TSTPRG_MOTOR : - { - for (Count = 0;Count < NO_OF_OUTPUTS;Count++) - { - if (OutputValues[Count] != (SWORD)TestPrgReadMotor(Count)) - { - OutputValues[Count] = (SWORD)TestPrgReadMotor(Count); - sprintf((char*)TxtBuffer[Count]," %c %-4d %4d",(char)Count + 'A',(SWORD)pMapOutPut->Outputs[Count].Speed,OutputValues[Count]); - pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_4 + Count); - } - } - switch (cUiReadButtons()) - { - case BUTTON_LEFT : - { - for (Count = 0;Count < NO_OF_OUTPUTS;Count++) - { - OutputValues[Count] = 0x7FFF; - TestPrgRunMotor(Count,-50); - } - } - break; - - case BUTTON_ENTER : - { - for (Count = 0;Count < NO_OF_OUTPUTS;Count++) - { - OutputValues[Count] = 0x7FFF; - TestPrgRunMotor(Count,0); - } - } - break; - - case BUTTON_EXIT : - { - State = TSTPRG_SKIP_MOTOR; - } - break; - - case BUTTON_RIGHT : - { - for (Count = 0;Count < NO_OF_OUTPUTS;Count++) - { - OutputValues[Count] = 0x7FFF; - TestPrgRunMotor(Count,50); - } - } - break; - - } - } - break; - - case TSTPRG_SKIP_MOTOR : - { - for (Count = 0;Count < NO_OF_OUTPUTS;Count++) - { - TestPrgFloatMotor(Count); - } - State = TSTPRG_INIT; - } - break; - - case TSTPRG_RCX_INIT : - { - pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_RCX; - pMapDisplay->pTextLines[TEXTLINE_2] = (UBYTE*)TXT_LINE; - pMapDisplay->pTextLines[TEXTLINE_3] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_4] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_5] = (UBYTE*)TXT_SELECT; - pMapDisplay->pTextLines[TEXTLINE_6] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_7] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_RCX_STOP; - - pMapDisplay->UpdateMask |= TEXTLINE_BITS; - State = TSTPRG_RCX_SELECT; - } - break; - - case TSTPRG_RCX_SELECT : - { - switch (cUiReadButtons()) - { - case BUTTON_LEFT : - { - pMapDisplay->pTextLines[TEXTLINE_5] = (UBYTE*)TXT_SELECT_TYPE; - pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_RCX_INPUT_SELECT; - pMapDisplay->UpdateMask |= TEXTLINE_BITS; - for (Count = 0;Count < NO_OF_INPUTS;Count++) - { - InputValues[Count] = 0x7FFF; - strcpy((char*)TxtBuffer[Count]," "); - } - State = TSTPRG_RCX_INPUT_SELECT; - } - break; - - case BUTTON_ENTER : - { - State = TSTPRG_RCX_DISPLAY_INIT; - } - break; - - case BUTTON_RIGHT : - { - State = TSTPRG_RCX_MOTOR_INIT; - } - break; - - case BUTTON_EXIT : - { - State = TSTPRG_INIT; - } - break; - - } - } - break; - - case TSTPRG_RCX_DISPLAY_INIT : - { - Count = 0; - pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_BACKGROUND); - State = TSTPRG_RCX_DISPLAY; - } - break; - - case TSTPRG_RCX_DISPLAY : - { - if ((Count & 0x7FF) == 0x000) - { - pMapDisplay->pScreens[SCREEN_BACKGROUND] = (BMPMAP*)Test1; - pMapDisplay->UpdateMask |= SCREEN_BIT(SCREEN_BACKGROUND); - } - if ((Count & 0x7FF) == 0x3FF) - { - pMapDisplay->pScreens[SCREEN_BACKGROUND] = (BMPMAP*)Test2; - pMapDisplay->UpdateMask |= SCREEN_BIT(SCREEN_BACKGROUND); - } - Count++; - if (cUiReadButtons() != BUTTON_NONE) - { - State = TSTPRG_SKIP_RCX; - } - } - break; - - case TSTPRG_RCX_INPUT_SELECT : - { - switch (cUiReadButtons()) - { - case BUTTON_LEFT : - { - pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_RCX_INPUT_PASIVE; - for (Count = 0;Count < NO_OF_INPUTS;Count++) - { - pMapInput->Inputs[Count].SensorType = SWITCH; - } - State = TSTPRG_RCX_INPUT_INIT; - } - break; - - case BUTTON_ENTER : - { - pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_RCX_INPUT_ACTIVE; - for (Count = 0;Count < NO_OF_INPUTS;Count++) - { - pMapInput->Inputs[Count].SensorType = REFLECTION; - } - State = TSTPRG_RCX_INPUT_INIT; - } - break; - - case BUTTON_EXIT : - { - State = TSTPRG_SKIP_RCX; - } - break; - - case BUTTON_RIGHT : - { - pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_RCX_INPUT_DIGITAL; - pMapDisplay->pTextLines[TEXTLINE_2] = (UBYTE*)TXT_LINE; - pMapDisplay->pTextLines[TEXTLINE_3] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_4] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_5] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_6] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_7] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_SUBTEST_STOP; - pMapDisplay->UpdateMask |= TEXTLINE_BITS; - for (Count = 0;Count < NO_OF_INPUTS;Count++) - { - pMapInput->Inputs[Count].SensorType = CUSTOM; - } - SubState = 0; - Timer = 0; - State = TSTPRG_RCX_DIGITAL_INIT; - } - break; - - } - } - break; - - case TSTPRG_RCX_INPUT_INIT : - { - for (Count = 0;Count < NO_OF_INPUTS;Count++) - { - pMapDisplay->pTextLines[TEXTLINE_3 + Count] = TxtBuffer[Count]; - } - pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_SUBTEST_STOP; - pMapDisplay->UpdateMask |= TEXTLINE_BITS; - State = TSTPRG_RCX_INPUT; - Timer = 0; - } - break; - - case TSTPRG_RCX_INPUT : - { - if (++Timer >= 250) - { - Timer = 0; - for (Count = 0;Count < NO_OF_INPUTS;Count++) - { - if (InputValues[Count] != pMapInput->Inputs[Count].ADRaw) - { - InputValues[Count] = pMapInput->Inputs[Count].ADRaw; - sprintf((char*)TxtBuffer[Count]," Input %u = %4u ",(UWORD)Count + 1,(UWORD)InputValues[Count]); - pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3 + Count); - } - } - } - if (cUiReadButtons() != BUTTON_NONE) - { - State = TSTPRG_SKIP_RCX; - } - } - break; - - case TSTPRG_RCX_DIGITAL_INIT : - { - if (++Timer >= 20) - { - Timer = 0; - switch (SubState) - { - case 0 : - { - pMapInput->Inputs[0].DigiPinsDir |= DIGI0; // Digi 1-0 output -, - pMapInput->Inputs[0].DigiPinsDir &= ~DIGI1; // Digi 1-1 input -, | - pMapInput->Inputs[2].DigiPinsDir &= ~DIGI0; // Digi 3-0 input | -' - pMapInput->Inputs[2].DigiPinsDir |= DIGI1; // Digi 3-1 output -' - - pMapInput->Inputs[0].DigiPinsOut |= DIGI0; // Digi 1-0 output high - pMapInput->Inputs[2].DigiPinsOut &= ~DIGI1; // Digi 3-1 output low - - SubState++; - } - break; - - case 1 : - { - if ((pMapInput->Inputs[2].DigiPinsIn & DIGI0) && !(pMapInput->Inputs[0].DigiPinsIn & DIGI1)) - { - pMapInput->Inputs[0].DigiPinsOut &= ~DIGI0; // Digi 1-0 output low - pMapInput->Inputs[2].DigiPinsOut |= DIGI1; // Digi 3-1 output high - - SubState++; - } - else - { - State = TSTPRG_RCX_DIGITAL_FAIL; - } - } - break; - - case 2 : - { - if (!(pMapInput->Inputs[2].DigiPinsIn & DIGI0) && (pMapInput->Inputs[0].DigiPinsIn & DIGI1)) - { - pMapInput->Inputs[0].DigiPinsDir &= ~DIGI0; // Digi 1-0 input - pMapInput->Inputs[0].DigiPinsDir &= ~DIGI1; // Digi 1-1 input - pMapInput->Inputs[2].DigiPinsDir &= ~DIGI0; // Digi 3-0 input - pMapInput->Inputs[2].DigiPinsDir &= ~DIGI1; // Digi 3-1 input - - pMapInput->Inputs[1].DigiPinsDir |= DIGI0; // Digi 2-0 output -, - pMapInput->Inputs[1].DigiPinsDir &= ~DIGI1; // Digi 2-1 input -, | - pMapInput->Inputs[3].DigiPinsDir &= ~DIGI0; // Digi 4-0 input | -' - pMapInput->Inputs[3].DigiPinsDir |= DIGI1; // Digi 4-1 output -' - - pMapInput->Inputs[1].DigiPinsOut |= DIGI0; // Digi 2-0 output high - pMapInput->Inputs[3].DigiPinsOut &= ~DIGI1; // Digi 4-1 output low - - SubState++; - } - else - { - State = TSTPRG_RCX_DIGITAL_FAIL; - } - } - break; - - case 3 : - { - if ((pMapInput->Inputs[3].DigiPinsIn & DIGI0) && !(pMapInput->Inputs[1].DigiPinsIn & DIGI1)) - { - pMapInput->Inputs[1].DigiPinsOut &= ~DIGI0; // Digi 2-0 output low - pMapInput->Inputs[3].DigiPinsOut |= DIGI1; // Digi 4-1 output high - - SubState++; - } - else - { - State = TSTPRG_RCX_DIGITAL_FAIL; - } - } - break; - - case 4 : - { - if (!(pMapInput->Inputs[3].DigiPinsIn & DIGI0) && (pMapInput->Inputs[1].DigiPinsIn & DIGI1)) - { - pMapInput->Inputs[1].DigiPinsDir &= ~DIGI0; // Digi 2-0 input - pMapInput->Inputs[1].DigiPinsDir &= ~DIGI1; // Digi 2-1 input - pMapInput->Inputs[3].DigiPinsDir &= ~DIGI0; // Digi 4-0 input - pMapInput->Inputs[3].DigiPinsDir &= ~DIGI1; // Digi 4-1 input - - State = TSTPRG_RCX_DIGITAL_OK; - } - else - { - State = TSTPRG_RCX_DIGITAL_FAIL; - } - } - break; - - } - } - } - break; - - case TSTPRG_RCX_DIGITAL_OK : - { - pMapDisplay->pTextLines[TEXTLINE_5] = (UBYTE*)TXT_RCX_DIGITAL_OK; - pMapDisplay->UpdateMask |= TEXTLINE_BITS; - State = TSTPRG_RCX_DIGITAL; - } - break; - - case TSTPRG_RCX_DIGITAL_FAIL : - { - pMapDisplay->pTextLines[TEXTLINE_5] = (UBYTE*)TXT_RCX_DIGITAL_FAIL; - pMapDisplay->UpdateMask |= TEXTLINE_BITS; - State = TSTPRG_RCX_DIGITAL; - } - break; - - case TSTPRG_RCX_DIGITAL : - { - if (cUiReadButtons() != BUTTON_NONE) - { - State = TSTPRG_SKIP_RCX; - } - } - break; - - case TSTPRG_RCX_MOTOR_INIT : - { - pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_MOTOR; - pMapDisplay->pTextLines[TEXTLINE_2] = (UBYTE*)TXT_LINE; - pMapDisplay->pTextLines[TEXTLINE_3] = (UBYTE*)TXT_MOTOR_HEADER; - pMapDisplay->pTextLines[TEXTLINE_4] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_5] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_6] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_7] = (UBYTE*)TXT_EMPTY; - pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_MOTOR_NEXT; - - for (Count = 0;Count < NO_OF_OUTPUTS;Count++) - { - OutputValues[Count] = 0x7FFF; - TestPrgRunMotor(Count,0); - strcpy((char*)TxtBuffer[Count]," "); - pMapDisplay->pTextLines[TEXTLINE_4 + Count] = TxtBuffer[Count]; - } - - Pointer = 0; - pMapDisplay->UpdateMask |= TEXTLINE_BITS; - State = TSTPRG_RCX_MOTOR; - } - break; - - case TSTPRG_RCX_MOTOR : - { - for (Count = 0;Count < NO_OF_OUTPUTS;Count++) - { - if (OutputValues[Count] != (SWORD)TestPrgReadMotor(Count)) - { - OutputValues[Count] = (SWORD)TestPrgReadMotor(Count); - if (Pointer == Count) - { - sprintf((char*)TxtBuffer[Count],"> %c %-4d %4d",(char)Count + 'A',(SWORD)pMapOutPut->Outputs[Count].Speed,OutputValues[Count]); - } - else - { - sprintf((char*)TxtBuffer[Count]," %c %-4d %4d",(char)Count + 'A',(SWORD)pMapOutPut->Outputs[Count].Speed,OutputValues[Count]); - } - pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_4 + Count); - } - } - switch (cUiReadButtons()) - { - case BUTTON_LEFT : - { - for (Count = 0;Count < NO_OF_OUTPUTS;Count++) - { - OutputValues[Count] = 0x7FFF; - if (Pointer == Count) - { - TestPrgRunMotor(Count,-50); - } - else - { - TestPrgRunMotor(Count,0); - } - } - } - break; - - case BUTTON_ENTER : - { - for (Count = 0;Count < NO_OF_OUTPUTS;Count++) - { - OutputValues[Count] = 0x7FFF; - TestPrgRunMotor(Count,0); - } - if (++Pointer >= NO_OF_OUTPUTS) - { - State = TSTPRG_SKIP_RCX_MOTOR; - } - } - break; - - case BUTTON_EXIT : - { - State = TSTPRG_SKIP_RCX_MOTOR; - } - break; - - case BUTTON_RIGHT : - { - for (Count = 0;Count < NO_OF_OUTPUTS;Count++) - { - OutputValues[Count] = 0x7FFF; - if (Pointer == Count) - { - TestPrgRunMotor(Count,50); - } - else - { - TestPrgRunMotor(Count,0); - } - } - } - break; - - } - } - break; - - case TSTPRG_SKIP_RCX_MOTOR : - { - for (Count = 0;Count < NO_OF_OUTPUTS;Count++) - { - TestPrgFloatMotor(Count); - } - State = TSTPRG_RCX_INIT; - } - break; - - case TSTPRG_SKIP_RCX : - { - for (Count = 0;Count < NO_OF_INPUTS;Count++) - { - pMapInput->Inputs[Count].SensorType = NO_SENSOR; - } - pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_BACKGROUND); - State = TSTPRG_RCX_INIT; - } - break; - -#endif - - case TSTPRG_SKIP : - { - Count++; - if (Count == 100) - { - pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_BACKGROUND); - } - if (Count >= 200) - { - IOMapUi.Flags |= UI_REDRAW_STATUS; - State = 0; - } - } - break; - - default : - { - State = SYSTEM_INIT; - } - break; - - } - - return (State); -} diff --git a/AT91SAM7S256/Source/Connections.txt b/AT91SAM7S256/Source/Connections.txt deleted file mode 100644 index 3c20ed0..0000000 --- a/AT91SAM7S256/Source/Connections.txt +++ /dev/null @@ -1,23 +0,0 @@ -DEFINE_DATA(ICON, Connections) = -{ - 0x04,0x00, // Graphics Format - 0x01,0x20, // Graphics DataSize - 0x01, // Graphics Count X - 0x04, // Graphics Count Y - 0x18, // Graphics Width - 0x18, // Graphics Height -BEGIN_DATA - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x00,0x40,0x40,0x00,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xDB,0x00,0x00,0x7E,0x81,0x81,0x7E,0x00,0x00,0xDB,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x00,0x02,0x02,0x00,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x00,0x40,0x40,0x00,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xDB,0x00,0x00,0x00,0x82,0xFF,0x80,0x00,0x00,0xDB,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x00,0x02,0x02,0x00,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x00,0x40,0x40,0x00,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xDB,0x00,0x00,0xE2,0x91,0x89,0x86,0x00,0x00,0xDB,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x00,0x02,0x02,0x00,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x00,0x40,0x40,0x00,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xDB,0x00,0x00,0x42,0x81,0x89,0x76,0x00,0x00,0xDB,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x00,0x02,0x02,0x00,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 -END_DATA -}; diff --git a/AT91SAM7S256/Source/Cursor.txt b/AT91SAM7S256/Source/Cursor.txt deleted file mode 100644 index 69037cd..0000000 --- a/AT91SAM7S256/Source/Cursor.txt +++ /dev/null @@ -1,13 +0,0 @@ -#define sizeof_Cursor 15 -DEFINE_DATA(BMPMAP, Cursor) = -{ - 0x02,0x00, // Graphics Format - 0x00,0x08, // Graphics DataSize - 0x00, // Graphics Start X - 0x00, // Graphics Start Y - 0x07, // Graphics Width - 0x08, // Graphics Height -BEGIN_DATA - 0x21,0x31,0x39,0x3D,0x39,0x31,0x21 -END_DATA -}; diff --git a/AT91SAM7S256/Source/Devices.txt b/AT91SAM7S256/Source/Devices.txt deleted file mode 100644 index cbfd564..0000000 --- a/AT91SAM7S256/Source/Devices.txt +++ /dev/null @@ -1,23 +0,0 @@ -DEFINE_DATA(ICON, Devices) = -{ - 0x04,0x00, // Graphics Format - 0x01,0x20, // Graphics DataSize - 0x01, // Graphics Count X - 0x04, // Graphics Count Y - 0x18, // Graphics Width - 0x18, // Graphics Height -BEGIN_DATA - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x82,0x44,0x28,0xFF,0x11,0xAA,0x44,0x00,0x00,0x06,0x01,0x00,0x40,0x20,0x11,0x0E,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x48,0x48,0x78,0x48,0x48,0x78,0x48,0x48,0x78,0x48,0x48,0xF8,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x9E,0x91,0x51,0x51,0x51,0x91,0x9E,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x24,0x24,0x24,0x3C,0x25,0x25,0x25,0x3C,0x24,0x24,0x24,0x3F,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x70,0x08,0x30,0x40,0x40,0x40,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x4E,0x91,0x51,0x91,0x51,0x8E,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x10,0x11,0x12,0x11,0x12,0x11,0x12,0x10,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xBF,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xBF,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x06,0x07,0x05,0x06,0x05,0x06,0x05,0x06,0x05,0x06,0x05,0x06,0x05,0x07,0x06,0x00,0x00,0x00,0x00 -END_DATA -}; diff --git a/AT91SAM7S256/Source/Display.txt b/AT91SAM7S256/Source/Display.txt deleted file mode 100644 index d1c2136..0000000 --- a/AT91SAM7S256/Source/Display.txt +++ /dev/null @@ -1,14 +0,0 @@ -DEFINE_DATA(BMPMAP, Display) = -{ - 0x02,0x00, // Graphics Format - 0x00,0xD8, // Graphics DataSize - 0x0E, // Graphics Start X - 0x10, // Graphics Start Y - 0x48, // Graphics Width - 0x18, // Graphics Height -BEGIN_DATA - 0xF8,0xFC,0x0E,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0E,0xFC,0xF8,0xC0, - 0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF, - 0x0F,0x1F,0x38,0x30,0x30,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x78,0x7F,0x3F,0x1F -END_DATA -}; diff --git a/AT91SAM7S256/Source/Fail.txt b/AT91SAM7S256/Source/Fail.txt deleted file mode 100644 index a213ec5..0000000 --- a/AT91SAM7S256/Source/Fail.txt +++ /dev/null @@ -1,14 +0,0 @@ -DEFINE_DATA(BMPMAP, Fail) = -{ - 0x02,0x00, // Graphics Format - 0x00,0x48, // Graphics DataSize - 0x00, // Graphics Start X - 0x08, // Graphics Start Y - 0x18, // Graphics Width - 0x18, // Graphics Height -BEGIN_DATA - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x60,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x30,0x0C,0x03,0x00,0x7C,0x00,0x03,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x04,0x04,0x04,0x04,0x04,0x05,0x04,0x04,0x04,0x04,0x04,0x03,0x00,0x00,0x00,0x00,0x00 -END_DATA -}; diff --git a/AT91SAM7S256/Source/Font.txt b/AT91SAM7S256/Source/Font.txt deleted file mode 100644 index 0aa4303..0000000 --- a/AT91SAM7S256/Source/Font.txt +++ /dev/null @@ -1,17 +0,0 @@ -DEFINE_DATA(ICON, Font) = -{ - 0x04,0x00, // Graphics Format - 0x02,0x40, // Graphics DataSize - 0x10, // Graphics Count X - 0x06, // Graphics Count Y - 0x06, // Graphics Width - 0x08, // Graphics Height -BEGIN_DATA - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x5F,0x06,0x00,0x00,0x07,0x03,0x00,0x07,0x03,0x00,0x24,0x7E,0x24,0x7E,0x24,0x00,0x24,0x2B,0x6A,0x12,0x00,0x00,0x63,0x13,0x08,0x64,0x63,0x00,0x30,0x4C,0x52,0x22,0x50,0x00,0x00,0x07,0x03,0x00,0x00,0x00,0x00,0x3E,0x41,0x00,0x00,0x00,0x00,0x41,0x3E,0x00,0x00,0x00,0x08,0x3E,0x1C,0x3E,0x08,0x00,0x08,0x08,0x3E,0x08,0x08,0x00,0x80,0x60,0x60,0x00,0x00,0x00,0x08,0x08,0x08,0x08,0x08,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x00, - 0x3E,0x51,0x49,0x45,0x3E,0x00,0x00,0x42,0x7F,0x40,0x00,0x00,0x62,0x51,0x49,0x49,0x46,0x00,0x22,0x49,0x49,0x49,0x36,0x00,0x18,0x14,0x12,0x7F,0x10,0x00,0x2F,0x49,0x49,0x49,0x31,0x00,0x3C,0x4A,0x49,0x49,0x30,0x00,0x01,0x71,0x09,0x05,0x03,0x00,0x36,0x49,0x49,0x49,0x36,0x00,0x06,0x49,0x49,0x29,0x1E,0x00,0x00,0x6C,0x6C,0x00,0x00,0x00,0x00,0xEC,0x6C,0x00,0x00,0x00,0x08,0x14,0x22,0x41,0x00,0x00,0x24,0x24,0x24,0x24,0x24,0x00,0x00,0x41,0x22,0x14,0x08,0x00,0x02,0x01,0x59,0x09,0x06,0x00, - 0x3E,0x41,0x5D,0x55,0x1E,0x00,0x7E,0x11,0x11,0x11,0x7E,0x00,0x7F,0x49,0x49,0x49,0x36,0x00,0x3E,0x41,0x41,0x41,0x22,0x00,0x7F,0x41,0x41,0x41,0x3E,0x00,0x7F,0x49,0x49,0x49,0x41,0x00,0x7F,0x09,0x09,0x09,0x01,0x00,0x3E,0x41,0x49,0x49,0x7A,0x00,0x7F,0x08,0x08,0x08,0x7F,0x00,0x00,0x41,0x7F,0x41,0x00,0x00,0x30,0x40,0x40,0x40,0x3F,0x00,0x7F,0x08,0x14,0x22,0x41,0x00,0x7F,0x40,0x40,0x40,0x40,0x00,0x7F,0x02,0x04,0x02,0x7F,0x00,0x7F,0x02,0x04,0x08,0x7F,0x00,0x3E,0x41,0x41,0x41,0x3E,0x00, - 0x7F,0x09,0x09,0x09,0x06,0x00,0x3E,0x41,0x51,0x21,0x5E,0x00,0x7F,0x09,0x09,0x19,0x66,0x00,0x26,0x49,0x49,0x49,0x32,0x00,0x01,0x01,0x7F,0x01,0x01,0x00,0x3F,0x40,0x40,0x40,0x3F,0x00,0x1F,0x20,0x40,0x20,0x1F,0x00,0x3F,0x40,0x3C,0x40,0x3F,0x00,0x63,0x14,0x08,0x14,0x63,0x00,0x07,0x08,0x70,0x08,0x07,0x00,0x71,0x49,0x45,0x43,0x00,0x00,0x00,0x7F,0x41,0x41,0x00,0x00,0x02,0x04,0x08,0x10,0x20,0x00,0x00,0x41,0x41,0x7F,0x00,0x00,0x04,0x02,0x01,0x02,0x04,0x00,0x80,0x80,0x80,0x80,0x80,0x00, - 0x00,0x02,0x05,0x02,0x00,0x00,0x20,0x54,0x54,0x54,0x78,0x00,0x7F,0x44,0x44,0x44,0x38,0x00,0x38,0x44,0x44,0x44,0x28,0x00,0x38,0x44,0x44,0x44,0x7F,0x00,0x38,0x54,0x54,0x54,0x08,0x00,0x08,0x7E,0x09,0x09,0x00,0x00,0x18,0x24,0xA4,0xA4,0xFC,0x00,0x7F,0x04,0x04,0x78,0x00,0x00,0x00,0x00,0x7D,0x40,0x00,0x00,0x40,0x80,0x84,0x7D,0x00,0x00,0x7F,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x7F,0x40,0x00,0x00,0x7C,0x04,0x18,0x04,0x78,0x00,0x7C,0x04,0x04,0x78,0x00,0x00,0x38,0x44,0x44,0x44,0x38,0x00, - 0xFC,0x44,0x44,0x44,0x38,0x00,0x38,0x44,0x44,0x44,0xFC,0x00,0x44,0x78,0x44,0x04,0x08,0x00,0x08,0x54,0x54,0x54,0x20,0x00,0x04,0x3E,0x44,0x24,0x00,0x00,0x3C,0x40,0x20,0x7C,0x00,0x00,0x1C,0x20,0x40,0x20,0x1C,0x00,0x3C,0x60,0x30,0x60,0x3C,0x00,0x6C,0x10,0x10,0x6C,0x00,0x00,0x9C,0xA0,0x60,0x3C,0x00,0x00,0x64,0x54,0x54,0x4C,0x00,0x00,0x08,0x3E,0x41,0x41,0x00,0x00,0x00,0x00,0x77,0x00,0x00,0x00,0x00,0x41,0x41,0x3E,0x08,0x00,0x02,0x01,0x02,0x01,0x00,0x00,0x10,0x20,0x40,0x38,0x07,0x00 -END_DATA -}; diff --git a/AT91SAM7S256/Source/Functions.inl b/AT91SAM7S256/Source/Functions.inl deleted file mode 100644 index 1424721..0000000 --- a/AT91SAM7S256/Source/Functions.inl +++ /dev/null @@ -1,4331 +0,0 @@ -// -// Programmer -// -// Date init 26.04.2005 -// -// Reviser $Author:: Dktochpe $ -// -// Revision date $Date:: $ -// -// Filename $Workfile:: $ -// -// Version $Revision:: $ -// -// Archive $Archive:: $ -// -// Platform C -// - -//******* cUiBtTest ********************************************************** - -const UBYTE NONVOLATILE_NAME[] = UI_NONVOLATILE; // Non volatile filename without extention -const UBYTE DEFAULT_PROGRAM_NAME[] = UI_PROGRAM_DEFAULT; // On brick programming filename without extention -const UBYTE TEMP_PROGRAM_FILENAME[] = UI_PROGRAM_TEMP; // On brick programming tmp filename without extention -const UBYTE VM_PROGRAM_READER[] = UI_PROGRAM_READER; // On brick programming script reader filename without extention -const UBYTE TEMP_DATALOG_FILENAME[] = UI_DATALOG_TEMP; // On brick datalog tmp filename without extention -const UBYTE DEFAULT_DATALOG_NAME[] = UI_DATALOG_DEFAULT; // On brick datalog filename without extention -const UBYTE DEFAULT_PIN_CODE[] = UI_PINCODE_DEFAULT; // Default blue tooth pin code -const UBYTE TXT_INVALID_SENSOR[] = "??????????????"; // Display invalid sensor data - - -#define SENSORS (MENU_SENSOR_INVALID - MENU_SENSOR_EMPTY) - -const UBYTE SENSORTYPE[SENSORS] = // for view and datalog -{ - 0, // MENU_SENSOR_EMPTY - SOUND_DB, // MENU_SENSOR_SOUND_DB - SOUND_DBA, // MENU_SENSOR_SOUND_DBA - LIGHT_ACTIVE, // MENU_SENSOR_LIGHT - LIGHT_INACTIVE, // MENU_SENSOR_LIGHT_AMB - SWITCH, // MENU_SENSOR_TOUCH - 0, // MENU_SENSOR_MOTOR_DEG - 0, // MENU_SENSOR_MOTOR_ROT - LOWSPEED_9V, // MENU_SENSOR_ULTRASONIC_IN - LOWSPEED_9V, // MENU_SENSOR_ULTRASONIC_CM - LOWSPEED_9V, // MENU_SENSOR_IIC_TEMP_C - LOWSPEED_9V, // MENU_SENSOR_IIC_TEMP_F - COLORFULL // MENU_SENSOR_COLOR -}; - -const UBYTE SENSORMODE[SENSORS] = // for view and datalog -{ - 0, // MENU_SENSOR_EMPTY - PCTFULLSCALEMODE, // MENU_SENSOR_SOUND_DB - PCTFULLSCALEMODE, // MENU_SENSOR_SOUND_DBA - PCTFULLSCALEMODE, // MENU_SENSOR_LIGHT - PCTFULLSCALEMODE, // MENU_SENSOR_LIGHT_AMB - BOOLEANMODE, // MENU_SENSOR_TOUCH - 0, // MENU_SENSOR_MOTOR_DEG - 0, // MENU_SENSOR_MOTOR_ROT - 0, // MENU_SENSOR_ULTRASONIC_IN - 0, // MENU_SENSOR_ULTRASONIC_CM - 0, // MENU_SENSOR_IIC_TEMP_C - 0, // MENU_SENSOR_IIC_TEMP_F - 0 // MENU_SENSOR_COLOR -}; - -const UBYTE SENSORFORMAT[SENSORS][9] = -{ - "", // MENU_SENSOR_EMPTY - "%3.0f %%", // MENU_SENSOR_SOUND_DB - "%3.0f %%", // MENU_SENSOR_SOUND_DBA - "%3.0f %%", // MENU_SENSOR_LIGHT - "%3.0f %%", // MENU_SENSOR_LIGHT_AMB - "%1.0f", // MENU_SENSOR_TOUCH - "%8.0f `", // MENU_SENSOR_MOTOR_DEG - "%8.0f R", // MENU_SENSOR_MOTOR_ROT - "%3.0f In", // MENU_SENSOR_ULTRASONIC_IN - "%3.0f cm", // MENU_SENSOR_ULTRASONIC_CM - "%5.1f `C", // MENU_SENSOR_IIC_TEMP_C - "%5.1f `F", // MENU_SENSOR_IIC_TEMP_F - "%9.0f" // MENU_SENSOR_COLOR (no of characters) -}; - -const float SENSORDIVIDER[SENSORS] = -{ - 1.0f, // MENU_SENSOR_EMPTY - 1.0f, // MENU_SENSOR_SOUND_DB - 1.0f, // MENU_SENSOR_SOUND_DBA - 1.0f, // MENU_SENSOR_LIGHT - 1.0f, // MENU_SENSOR_LIGHT_AMB - 1.0f, // MENU_SENSOR_TOUCH - 1.0f, // MENU_SENSOR_MOTOR_DEG - 360.0f, // MENU_SENSOR_MOTOR_ROT - 2.54f, // MENU_SENSOR_ULTRASONIC_IN - 1.0f, // MENU_SENSOR_ULTRASONIC_CM - 10.0f, // MENU_SENSOR_IIC_TEMP_C - 10.0f, // MENU_SENSOR_IIC_TEMP_F - 1.0f // MENU_SENSOR_COLOR -}; - - -#define SENSORSYNCDATA "Sync data" -#define SENSORSDATA "Sdata" -#define SENSORTIME "Time" - - -const UBYTE SENSORDIRNAME[SENSORS - 1][19] = -{ - "Sound Sensor", // MENU_SENSOR_SOUND_DB - "Sound Sensor", // MENU_SENSOR_SOUND_DBA - "Light Sensor", // MENU_SENSOR_LIGHT - "Light Sensor", // MENU_SENSOR_LIGHT_AMB - "Bumper", // MENU_SENSOR_TOUCH - "FP Rotation Sensor", // MENU_SENSOR_MOTOR_DEG - "FP Rotation Sensor", // MENU_SENSOR_MOTOR_ROT - "Distance Sensor", // MENU_SENSOR_ULTRASONIC_IN - "Distance Sensor", // MENU_SENSOR_ULTRASONIC_CM - "NXT Temp Sensor", // MENU_SENSOR_IIC_TEMP_C - "NXT Temp Sensor", // MENU_SENSOR_IIC_TEMP_F - "Color Detector" // MENU_SENSOR_COLOR -}; - -const UBYTE SENSORUNITNAME[SENSORS - 1][5] = -{ - "_dB", // MENU_SENSOR_SOUND_DB - "_dBa", // MENU_SENSOR_SOUND_DBA - "_on", // MENU_SENSOR_LIGHT - "_off", // MENU_SENSOR_LIGHT_AMB - "", // MENU_SENSOR_TOUCH - "_deg", // MENU_SENSOR_MOTOR_DEG - "_rot", // MENU_SENSOR_MOTOR_ROT - "_in", // MENU_SENSOR_ULTRASONIC_IN - "_cm", // MENU_SENSOR_ULTRASONIC_CM - "_C", // MENU_SENSOR_IIC_TEMP_C - "_F", // MENU_SENSOR_IIC_TEMP_F - "_0", // MENU_SENSOR_COLOR -}; - -const UBYTE SENSORFORMAT2[SENSORS - 1][6] = -{ - "\t%.0f", // MENU_SENSOR_SOUND_DB - "\t%.0f", // MENU_SENSOR_SOUND_DBA - "\t%.0f", // MENU_SENSOR_LIGHT - "\t%.0f", // MENU_SENSOR_LIGHT_AMB - "\t%.0f", // MENU_SENSOR_TOUCH - "\t%.0f", // MENU_SENSOR_MOTOR_DEG - "\t%.0f", // MENU_SENSOR_MOTOR_ROT - "\t%.0f", // MENU_SENSOR_ULTRASONIC_IN - "\t%.0f", // MENU_SENSOR_ULTRASONIC_CM - "\t%.1f", // MENU_SENSOR_IIC_TEMP_C - "\t%.1f", // MENU_SENSOR_IIC_TEMP_F - "\t%.0f" // MENU_SENSOR_COLOR -}; - - -//******* cUiWriteLowspeed *************************************************** - -void cUiWriteLowspeed(UBYTE Port,UBYTE TxBytes,UBYTE *TxBuf,UBYTE RxBytes) -{ - Port -= MENU_PORT_1; - pMapLowSpeed->OutBuf[Port].InPtr = 0; - pMapLowSpeed->OutBuf[Port].OutPtr = 0; - - while (TxBytes) - { - pMapLowSpeed->OutBuf[Port].Buf[pMapLowSpeed->OutBuf[Port].InPtr] = *TxBuf; - pMapLowSpeed->OutBuf[Port].InPtr++; - TxBuf++; - TxBytes--; - } - pMapLowSpeed->InBuf[Port].BytesToRx = RxBytes; - pMapLowSpeed->ChannelState[Port] = LOWSPEED_INIT; - pMapLowSpeed->State |= (COM_CHANNEL_ONE_ACTIVE << Port); -} - - -//******* cUiReadLowspeed **************************************************** - -#define IIC_READY 0 -#define IIC_BUSY 1 -#define IIC_ERROR 2 - -UBYTE cUiReadLowspeed(UBYTE Port,UBYTE RxBytes,UWORD *Value) -{ - UBYTE Result; - - *Value = 0; - Port -= MENU_PORT_1; - if ((pMapLowSpeed->ChannelState[Port] == LOWSPEED_IDLE) || (pMapLowSpeed->ChannelState[Port] == LOWSPEED_DONE)) - { - while (RxBytes) - { - (*Value) <<= 8; - (*Value) |= (UWORD)(pMapLowSpeed->InBuf[Port].Buf[pMapLowSpeed->InBuf[Port].OutPtr]); - pMapLowSpeed->InBuf[Port].OutPtr++; - if (pMapLowSpeed->InBuf[Port].OutPtr >= SIZE_OF_LSBUF) - { - pMapLowSpeed->InBuf[Port].OutPtr = 0; - } - RxBytes--; - } - Result = IIC_READY; - } - else - { - if (pMapLowSpeed->ErrorType[Port] == LOWSPEED_CH_NOT_READY) - { - Result = IIC_ERROR; - } - else - { - Result = IIC_BUSY; - } - } - - return (Result); -} - - -//******* cUiUpdateSensor **************************************************** - -#define SENSOR_SETUP 0 -#define SENSOR_ACQUIRE 3 -#define SENSOR_READ 8 -#define SENSOR_STATES 10 - -void cUiUpdateSensor(SWORD Time) -{ - UBYTE Port; - UBYTE Sensor; - UBYTE Result; - SWORD Tmp; - - if (VarsUi.SensorReset == TRUE) - { - for (Port = MENU_PORT_1;Port < MENU_PORT_INVALID;Port++) - { - VarsUi.DatalogSampleValid[Port - MENU_PORT_1] = FALSE; - } - VarsUi.SensorTimer = (MIN_SENSOR_READ_TIME / SENSOR_STATES); - VarsUi.SensorState = SENSOR_SETUP; - } - - VarsUi.SensorTimer += Time; - if (VarsUi.SensorTimer >= (MIN_SENSOR_READ_TIME / SENSOR_STATES)) - { - VarsUi.SensorTimer -= (MIN_SENSOR_READ_TIME / SENSOR_STATES); - - for (Port = MENU_PORT_1;Port < MENU_PORT_INVALID;Port++) - { - Sensor = VarsUi.DatalogPort[Port - MENU_PORT_1]; - - if (Sensor != MENU_SENSOR_EMPTY) - { - if ((Sensor == MENU_SENSOR_MOTOR_DEG) || (Sensor == MENU_SENSOR_MOTOR_ROT)) - { - if (VarsUi.SensorReset == TRUE) - { - pMapOutPut->Outputs[Port - MENU_PORT_A].Mode &= ~(BRAKE | MOTORON); - pMapOutPut->Outputs[Port - MENU_PORT_A].Flags |= UPDATE_MODE | UPDATE_SPEED | UPDATE_RESET_COUNT; - pMapOutPut->Outputs[Port - MENU_PORT_A].TachoCnt = 0; - } - if (VarsUi.SensorState == SENSOR_READ) - { - VarsUi.DatalogSampleValue[Port - MENU_PORT_1] = pMapOutPut->Outputs[Port - MENU_PORT_A].TachoCnt; - VarsUi.DatalogSampleValid[Port - MENU_PORT_1] = TRUE; - } - } - else - { - pMapInput->Inputs[Port - MENU_PORT_1].SensorType = SENSORTYPE[Sensor - MENU_SENSOR_EMPTY]; - pMapInput->Inputs[Port - MENU_PORT_1].SensorMode = SENSORMODE[Sensor - MENU_SENSOR_EMPTY]; - if ((Sensor == MENU_SENSOR_ULTRASONIC_IN) || (Sensor == MENU_SENSOR_ULTRASONIC_CM)) - { - if (VarsUi.SensorReset == TRUE) - { - cUiWriteLowspeed(Port,3,"\x02\x41\x02",0); - } - if (VarsUi.SensorState == SENSOR_ACQUIRE) - { - cUiWriteLowspeed(Port,2,"\x02\x42",1); - } - if (VarsUi.SensorState == SENSOR_READ) - { - Result = cUiReadLowspeed(Port,1,(UWORD*)&Tmp); - if (Result == IIC_READY) - { - if ((UBYTE)Tmp != 0xFF) - { - VarsUi.DatalogSampleValue[Port - MENU_PORT_1] = (SLONG)Tmp; - VarsUi.DatalogSampleValid[Port - MENU_PORT_1] = TRUE; - } - else - { - VarsUi.DatalogSampleValid[Port - MENU_PORT_1] = FALSE; - } - } - else - { - VarsUi.DatalogSampleValid[Port - MENU_PORT_1] = FALSE; - } - } - } - else - { - if ((Sensor == MENU_SENSOR_IIC_TEMP_C) || (Sensor == MENU_SENSOR_IIC_TEMP_F)) - { - if (VarsUi.SensorState == SENSOR_SETUP) - { - cUiWriteLowspeed(Port,3,"\x98\x01\x60",0); - } - if (VarsUi.SensorState == SENSOR_ACQUIRE) - { - cUiWriteLowspeed(Port,2,"\x98\x00",2); - } - if (VarsUi.SensorState == SENSOR_READ) - { - Result = cUiReadLowspeed(Port,2,(UWORD*)&Tmp); - if (Result == IIC_READY) - { -// if (Tmp >= -14080) - { - if (Sensor == MENU_SENSOR_IIC_TEMP_F) - { - VarsUi.DatalogSampleValue[Port - MENU_PORT_1] = (SLONG)((float)(Tmp + 4544) / 14.2f); - } - else - { - VarsUi.DatalogSampleValue[Port - MENU_PORT_1] = (SLONG)((float)Tmp / 25.6f); - } - VarsUi.DatalogSampleValid[Port - MENU_PORT_1] = TRUE; - } - } - else - { - if (Result == IIC_ERROR) - { - VarsUi.DatalogSampleValid[Port - MENU_PORT_1] = FALSE; - } - } - } - } - else - { - if (VarsUi.SensorState == SENSOR_READ) - { - if (pMapInput->Inputs[Port - MENU_PORT_1].InvalidData != INVALID_DATA) - { - VarsUi.DatalogSampleValue[Port - MENU_PORT_1] = pMapInput->Inputs[Port - MENU_PORT_1].SensorValue; - VarsUi.DatalogSampleValid[Port - MENU_PORT_1] = TRUE; - } - else - { - VarsUi.DatalogSampleValid[Port - MENU_PORT_1] = FALSE; - } - } - } - } - } - } - } - - VarsUi.SensorState++; - if (VarsUi.SensorState >= SENSOR_STATES) - { - VarsUi.SensorState = SENSOR_SETUP; - } - - VarsUi.SensorReset = FALSE; - } -} - - -//******* cUiGetCustomPctFullScale ******************************************* - - -UBYTE cUiGetCustomPctFullScale(UBYTE Port,UBYTE Sensor) -{ - UBYTE Result = 0; - - if ((Sensor != MENU_SENSOR_MOTOR_DEG) && (Sensor != MENU_SENSOR_MOTOR_ROT)) - { - Result = (UBYTE)pMapInput->Inputs[Port - MENU_PORT_1].CustomPctFullScale; - } - - return (Result); -} - - - -//******* cUiGetCustomActiveStatus ******************************************* - - -UBYTE cUiGetCustomActiveStatus(UBYTE Port,UBYTE Sensor) -{ - UBYTE Result = 0; - - if ((Sensor != MENU_SENSOR_MOTOR_DEG) && (Sensor != MENU_SENSOR_MOTOR_ROT)) - { - Result = (UBYTE)pMapInput->Inputs[Port - MENU_PORT_1].CustomActiveStatus; - } - - return (Result); -} - - - -//******* cUiPrintSensorInDisplayBuffer ************************************** - -#define COLORNAMES 6 - -const UBYTE COLORNAME[COLORNAMES][10] = -{ - "1. Black ", - "2. Blue ", - "3. Green ", - "4. Yellow", - "5. Red ", - "6. White " -}; - - -void cUiPrintSensorInDisplayBuffer(UBYTE Port) -{ - UBYTE Sensor; - float Value; - SWORD Size; - SWORD Index; - - Port -= MENU_PORT_1; - Sensor = VarsUi.DatalogPort[Port] - MENU_SENSOR_EMPTY; - Value = (float)VarsUi.DatalogSampleValue[Port] / (float)SENSORDIVIDER[Sensor]; - Size = sprintf((char*)VarsUi.DisplayBuffer,(char*)SENSORFORMAT[Sensor],(float)0); - sprintf((char*)VarsUi.DisplayBuffer,"%*.*s",Size,Size,(char*)TXT_INVALID_SENSOR); - - if (VarsUi.DatalogSampleValid[Port] == TRUE) - { - if (Sensor == (MENU_SENSOR_COLOR - MENU_SENSOR_EMPTY)) - { - Index = (SWORD)Value - 1; - if ((Index >= 0) && (Index < COLORNAMES)) - { - sprintf((char*)VarsUi.DisplayBuffer,(char*)COLORNAME[Index]); - } - } - else - { - if (Size < sprintf((char*)VarsUi.DisplayBuffer,(char*)SENSORFORMAT[Sensor],Value)) - { - sprintf((char*)VarsUi.DisplayBuffer,"%*.*s",Size,Size,(char*)TXT_INVALID_SENSOR); - } - } - } -} - - -//******* cUiReleaseSensors ************************************************** - -void cUiReleaseSensors(void) -{ - UBYTE Tmp; - - for (Tmp = 0;Tmp < NO_OF_INPUTS;Tmp++) - { - pMapInput->Inputs[Tmp].SensorType = NO_SENSOR; - } -} - - - -//******* cUiBtCommand ******************************************************* - -enum -{ - UI_BT_CTRL, - - UI_BT_GET_DEVICES, // (UI_BT_GET_DEVICES,Known,*pDevices,NULL) [Known = 0,1] - UI_BT_GET_DEVICE_NAME, // (UI_BT_GET_DEVICE_NAME,Known,*pIndex,*pDeviceName) [Known = 0,1] - UI_BT_GET_DEVICE_TYPE, // (UI_BT_GET_DEVICE_TYPE,Known,*pIndex,*pDeviceType) [Known = 0,1] - - UI_BT_GET_CONNECTION_NAME, // (UI_BT_GET_CONNECTION_NAME,NULL,*pConnection,*pConnectionName) - UI_BT_GET_CONNECTION_TYPE, // (UI_BT_GET_CONNECTION_TYPE,NULL,*pConnection,*pConnectionType) - UI_BT_GET_CONNECTION_VALID, // (UI_BT_GET_CONNECTION_NAME,NULL,*pConnection,NULL) - - UI_BT_DUMMY -}; - - -#define UI_BT_FAILED 0x8200 // General command failed -#define UI_BT_SUCCES 0x0000 // Command executed succesfully - - -UBYTE cUiBTGetDeviceType(UBYTE *pCOD) -{ - ULONG COD; - UBYTE Result; - UBYTE Tmp; - - COD = 0; - for (Tmp = 0;Tmp < SIZE_OF_CLASS_OF_DEVICE;Tmp++) - { - COD <<= 8; - COD |= (ULONG)*pCOD; - pCOD++; - } - - Result = DEVICETYPE_UNKNOWN; - if ((COD & 0x00001FFF) == 0x00000804) - { - Result = DEVICETYPE_NXT; - } - if ((COD & 0x00001F00) == 0x00000200) - { - Result = DEVICETYPE_PHONE; - } - if ((COD & 0x00001F00) == 0x00000100) - { - Result = DEVICETYPE_PC; - } - - return (Result); -} - - -UBYTE cUiBTGetDeviceIndex(UBYTE Known,UBYTE No,UBYTE *pIndex) -{ - UBYTE Result = 0; - UBYTE Tmp; - - *pIndex = 0; - if (Known) - { - for (Tmp = 0;(Tmp < SIZE_OF_BT_DEVICE_TABLE) && (Result == 0);Tmp++) - { - if ((pMapComm->BtDeviceTable[Tmp].DeviceStatus & BT_DEVICE_KNOWN)) - { - if (No == *pIndex) - { - *pIndex = Tmp; - Result = ~0; - } - else - { - (*pIndex)++; - } - } - } - } - else - { - for (Tmp = 0;(Tmp < SIZE_OF_BT_DEVICE_TABLE) && (Result == 0);Tmp++) - { - if ((pMapComm->BtDeviceTable[Tmp].DeviceStatus & BT_DEVICE_UNKNOWN) || (pMapComm->BtDeviceTable[Tmp].DeviceStatus & BT_DEVICE_KNOWN)) - { - if (No == *pIndex) - { - *pIndex = Tmp; - Result = ~0; - } - else - { - (*pIndex)++; - } - } - } - } - - return (Result); -} - - -UWORD cUiBTCommand(UBYTE Cmd,UBYTE Flag,UBYTE *pParam1,UBYTE *pParam2) -{ - UWORD Result = UI_BT_FAILED; - - switch(Cmd) - { - case UI_BT_GET_DEVICES : - { - cUiBTGetDeviceIndex(Flag,SIZE_OF_BT_DEVICE_TABLE,pParam1); - Result = UI_BT_SUCCES; - } - break; - - case UI_BT_GET_DEVICE_NAME : - { - if ((*pParam1 < SIZE_OF_BT_DEVICE_TABLE) && (pParam2 != NULL)) - { - pParam2[0] = 0; - if (cUiBTGetDeviceIndex(Flag,*pParam1,&VarsUi.BTTmpIndex)) - { - sprintf((char*)pParam2,"%.*s",DISPLAYLINE_LENGTH,(char*)pMapComm->BtDeviceTable[VarsUi.BTTmpIndex].Name); - Result = UI_BT_SUCCES; - } - } - } - break; - - case UI_BT_GET_DEVICE_TYPE : - { - if ((*pParam1 < SIZE_OF_BT_DEVICE_TABLE) && (pParam2 != NULL)) - { - pParam2[0] = 0; - if (cUiBTGetDeviceIndex(Flag,*pParam1,&VarsUi.BTTmpIndex)) - { - pParam2[0] = cUiBTGetDeviceType(pMapComm->BtDeviceTable[VarsUi.BTTmpIndex].ClassOfDevice); - Result = UI_BT_SUCCES; - } - } - } - break; - - case UI_BT_GET_CONNECTION_NAME : - { - if (*pParam1 < SIZE_OF_BT_CONNECT_TABLE) - { - if (pMapComm->BtConnectTable[*pParam1].Name[0]) - { - if (pParam2 != NULL) - { - sprintf((char*)pParam2,"%.*s",DISPLAYLINE_LENGTH,(char*)pMapComm->BtConnectTable[*pParam1].Name); - } - Result = UI_BT_SUCCES; - } - else - { - if (pParam2 != NULL) - { - pParam2[0] = 0; - } - } - } - } - break; - - case UI_BT_GET_CONNECTION_TYPE : - { - if ((*pParam1 < SIZE_OF_BT_CONNECT_TABLE) && (pParam2 != NULL)) - { - pParam2[0] = 0; - if (pMapComm->BtConnectTable[*pParam1].Name[0]) - { - pParam2[0] = cUiBTGetDeviceType(pMapComm->BtConnectTable[*pParam1].ClassOfDevice); - Result = UI_BT_SUCCES; - } - } - } - break; - - case UI_BT_GET_CONNECTION_VALID : - { - if (*pParam1 < SIZE_OF_BT_CONNECT_TABLE) - { - if (pMapComm->BtConnectTable[*pParam1].Name[0]) - { - Result = UI_BT_SUCCES; - } - } - } - break; - - } - - return (Result); -} - - - -#include "BtTest.inc" - -//******* cUiNVxxxxx ********************************************************* - -void cUiNVWrite(void) -{ - sprintf((char*)VarsUi.NVFilename,"%s.%s",(char*)NONVOLATILE_NAME,(char*)TXT_SYS_EXT); - VarsUi.NVTmpHandle = pMapLoader->pFunc(FINDFIRST,VarsUi.NVFilename,VarsUi.SearchFilenameBuffer,&VarsUi.NVTmpLength); - if (!(VarsUi.NVTmpHandle & 0x8000)) - { - pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.NVTmpHandle,NULL,NULL); - pMapLoader->pFunc(DELETE,VarsUi.NVFilename,NULL,NULL); - } - VarsUi.NVTmpLength = sizeof(NVDATA); - VarsUi.NVTmpHandle = pMapLoader->pFunc(OPENWRITE,VarsUi.NVFilename,NULL,&VarsUi.NVTmpLength); - pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.NVTmpHandle,(UBYTE*)&VarsUi.NVData,&VarsUi.NVTmpLength); - pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.NVTmpHandle,NULL,NULL); -} - - -void cUiNVRead(void) -{ - VarsUi.NVData.CheckByte = 0; - sprintf((char*)VarsUi.NVFilename,"%s.%s",(char*)NONVOLATILE_NAME,(char*)TXT_SYS_EXT); - VarsUi.NVTmpHandle = pMapLoader->pFunc(OPENREAD,VarsUi.NVFilename,NULL,&VarsUi.NVTmpLength); - if (!(VarsUi.NVTmpHandle & 0x8000)) - { - VarsUi.NVTmpLength = sizeof(NVDATA); - pMapLoader->pFunc(READ,(UBYTE*)&VarsUi.NVTmpHandle,(UBYTE*)&VarsUi.NVData,&VarsUi.NVTmpLength); - pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.NVTmpHandle,NULL,NULL); - } - if (VarsUi.NVData.CheckByte != CHECKBYTE) - { - VarsUi.NVData.DatalogEnabled = DATALOGENABLED; - VarsUi.NVData.VolumeStep = MAX_VOLUME; - VarsUi.NVData.PowerdownCode = POWER_OFF_TIME_DEFAULT; - VarsUi.NVData.DatalogNumber = 0; - VarsUi.NVData.CheckByte = CHECKBYTE; - cUiNVWrite(); - } -} - - -//******* cUiFeedback ******************************************************** - -UBYTE cUiFeedback(BMPMAP *Bitmap,UBYTE TextNo1,UBYTE TextNo2,UWORD Time) // Show bimap and text -{ -// if ((VarsUi.FBState == 0) || ((pMapDisplay->Flags & DISPLAY_POPUP) == 0)) - { - switch (VarsUi.FBState) - { - case 0 : // Set busy - { - VarsUi.FBState++; - } - break; - - case 1 : // Clear line 2,3,4 - { - if (DISPLAY_IDLE) - { - pMapDisplay->EraseMask |= (TEXTLINE_BIT(TEXTLINE_2) | TEXTLINE_BIT(TEXTLINE_3) | TEXTLINE_BIT(TEXTLINE_4)); - VarsUi.FBState++; - } - } - break; - - case 2 : // Show bitmap if pressent - { - if (DISPLAY_IDLE) - { - if (Bitmap != NULL) - { - pMapDisplay->pBitmaps[BITMAP_1] = Bitmap; - pMapDisplay->UpdateMask |= BITMAP_BIT(BITMAP_1); - } - VarsUi.FBState++; - } - } - break; - - case 3 : // Get text string - { - if (DISPLAY_IDLE) - { - pMapDisplay->UpdateMask |= SPECIAL_BIT(TOPLINE); - VarsUi.FBText = cUiGetString(TextNo1); - VarsUi.FBPointer = 0; - if (TextNo2) - { - VarsUi.FBState = 5; - } - else - { - VarsUi.FBState++; - } - } - } - break; - - case 4 : // Show text string - { - if ((VarsUi.FBText[VarsUi.FBPointer]) && (VarsUi.FBPointer < NO_OF_FEEDBACK_CHARS)) - { - pMapDisplay->pFunc(DISPLAY_CHAR,TRUE,24 + VarsUi.FBPointer * 6,16,VarsUi.FBText[VarsUi.FBPointer],0); - VarsUi.FBPointer++; - } - else - { - VarsUi.FBTimer = 0; - VarsUi.FBState = 7; - } - } - break; - - case 5 : // Show text string - { - if ((VarsUi.FBText[VarsUi.FBPointer]) && (VarsUi.FBPointer < NO_OF_FEEDBACK_CHARS)) - { - pMapDisplay->pFunc(DISPLAY_CHAR,TRUE,24 + VarsUi.FBPointer * 6,12,VarsUi.FBText[VarsUi.FBPointer],0); - VarsUi.FBPointer++; - } - else - { - if (TextNo2 == 0xFF) - { - VarsUi.FBText = VarsUi.SelectedFilename; - } - else - { - VarsUi.FBText = cUiGetString(TextNo2); - } - VarsUi.FBPointer = 0; - VarsUi.FBState++; - } - } - break; - - case 6 : // Show text string - { - if ((VarsUi.FBText[VarsUi.FBPointer]) && (VarsUi.FBPointer < NO_OF_FEEDBACK_CHARS)) - { - pMapDisplay->pFunc(DISPLAY_CHAR,TRUE,24 + VarsUi.FBPointer * 6,20,VarsUi.FBText[VarsUi.FBPointer],0); - VarsUi.FBPointer++; - } - else - { - VarsUi.FBTimer = 0; - VarsUi.FBState++; - } - } - break; - - case 7 : // Wait if time provided - { - if (++VarsUi.FBTimer >= (Time + 100)) - { - VarsUi.FBState++; - } - } - break; - - default : // Exit - { - VarsUi.FBState = 0; - } - break; - - } - } - - return (VarsUi.FBState); -} - - - -//******* cUiFileList ******************************************************** - -UBYTE cUiFindNoOfFiles(UBYTE FileType,UBYTE *NoOfFiles) -{ - switch (VarsUi.FNOFState) - { - case 0 : - { - *NoOfFiles = 0; - - if (FileType >= FILETYPES) - { - FileType = FILETYPE_ALL; - } - sprintf((char*)VarsUi.FNOFSearchBuffer,"*.%s",TXT_FILE_EXT[FileType]); - - VarsUi.FNOFHandle = pMapLoader->pFunc(FINDFIRST,VarsUi.FNOFSearchBuffer,VarsUi.FNOFNameBuffer,&VarsUi.FNOFLength); - if (!(VarsUi.FNOFHandle & 0x8000)) - { - *NoOfFiles = 1; - VarsUi.FNOFState++; - } - } - break; - - case 1 : - { - VarsUi.FNOFHandle = pMapLoader->pFunc(FINDNEXT,(UBYTE*)&VarsUi.FNOFHandle,VarsUi.FNOFNameBuffer,&VarsUi.FNOFLength); - if (!(VarsUi.FNOFHandle & 0x8000)) - { - *NoOfFiles += 1; - } - else - { - pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.FNOFHandle,NULL,NULL); - VarsUi.FNOFState = 0; - } - } - break; - - } - - return (VarsUi.FNOFState); -} - - -UBYTE cUiFindNameForFileNo(UBYTE FileType,UBYTE FileNo,UBYTE *Name) -{ - switch (VarsUi.FNOFState) - { - case 0 : - { - Name[0] = 0; - - if (FileNo) - { - if (FileType >= FILETYPES) - { - FileType = FILETYPE_ALL; - } - sprintf((char*)VarsUi.FNOFSearchBuffer,"*.%s",TXT_FILE_EXT[FileType]); - - VarsUi.FNOFHandle = pMapLoader->pFunc(FINDFIRST,VarsUi.FNOFSearchBuffer,Name,&VarsUi.FNOFLength); - if (!(VarsUi.FNOFHandle & 0x8000)) - { - if (FileNo != 1) - { - VarsUi.FNOFFileNo = 1; - VarsUi.FNOFState++; - } - else - { - pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.FNOFHandle,NULL,NULL); - } - } - } - } - break; - - case 1 : - { - VarsUi.FNOFHandle = pMapLoader->pFunc(FINDNEXT,(UBYTE*)&VarsUi.FNOFHandle,Name,&VarsUi.FNOFLength); - if (!(VarsUi.FNOFHandle & 0x8000)) - { - VarsUi.FNOFFileNo++; - if (FileNo == VarsUi.FNOFFileNo) - { - pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.FNOFHandle,NULL,NULL); - VarsUi.FNOFState = 0; - } - } - else - { - pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.FNOFHandle,NULL,NULL); - VarsUi.FNOFState = 0; - } - } - break; - - } - - return (VarsUi.FNOFState); -} - - -UBYTE cUiFileList(UBYTE Action) // Show files and select -{ - switch (Action) - { - case MENU_INIT : - { - if (!VarsUi.State) - { - VarsUi.FileCenter = 1; - VarsUi.NextState = IOMapUi.State; - } - Action = MENU_DRAW; - } - break; - - case MENU_LEFT : - { - if (!VarsUi.State) - { - cUiListLeft(VarsUi.NoOfFiles,&VarsUi.FileCenter); - VarsUi.NextState = TEST_BUTTONS; - } - Action = MENU_DRAW; - } - break; - - case MENU_RIGHT : - { - if (!VarsUi.State) - { - cUiListRight(VarsUi.NoOfFiles,&VarsUi.FileCenter); - VarsUi.NextState = TEST_BUTTONS; - } - Action = MENU_DRAW; - } - break; - - case MENU_SELECT : - { - } - break; - - default : - { - if (Action < FILETYPES) - { - if (!VarsUi.State) - { - VarsUi.FileType = Action; - VarsUi.FileCenter = 1; - VarsUi.NextState = IOMapUi.State; - } - Action = MENU_DRAW; - } - else - { - IOMapUi.State = EXIT_PRESSED; - VarsUi.State = 0; - } - } - break; - - } - - if (Action == MENU_DRAW) - { - switch (VarsUi.State) - { - case 0 : - { - VarsUi.FNOFState = 0; - VarsUi.State++; - } - break; - - case 1 : - { - if (cUiFindNoOfFiles(VarsUi.FileType,&VarsUi.NoOfFiles) == 0) - { - if (VarsUi.NoOfFiles) - { - cUiListCalc(VarsUi.NoOfFiles,&VarsUi.FileCenter,&VarsUi.FileLeft,&VarsUi.FileRight); - VarsUi.State++; - } - else - { - VarsUi.State = 0; - IOMapUi.State = EXIT_PRESSED; - } - } - } - break; - - case 2 : - { - if (cUiFindNameForFileNo(VarsUi.FileType,VarsUi.FileCenter,VarsUi.SelectedFilename) == 0) - { - VarsUi.State++; - } - } - break; - - default : - { - pMapDisplay->pMenuIcons[MENUICON_LEFT] = NULL; - pMapDisplay->pMenuIcons[MENUICON_CENTER] = NULL; - pMapDisplay->pMenuIcons[MENUICON_RIGHT] = NULL; - - if (VarsUi.FileLeft) - { - pMapDisplay->pMenuIcons[MENUICON_LEFT] = (UBYTE*)&Icons->Data[(VarsUi.FileType + ALLFILES) * Icons->ItemPixelsX * (Icons->ItemPixelsY / 8)]; - pMapDisplay->UpdateMask |= MENUICON_BIT(MENUICON_LEFT); - } - if (VarsUi.FileCenter) - { - pMapDisplay->pMenuIcons[MENUICON_CENTER] = (UBYTE*)&Icons->Data[(VarsUi.FileType + ALLFILES) * Icons->ItemPixelsX * (Icons->ItemPixelsY / 8)]; - pMapDisplay->UpdateMask |= MENUICON_BIT(MENUICON_CENTER); - } - if (VarsUi.FileRight) - { - pMapDisplay->pMenuIcons[MENUICON_RIGHT] = (UBYTE*)&Icons->Data[(VarsUi.FileType + ALLFILES) * Icons->ItemPixelsX * (Icons->ItemPixelsY / 8)]; - pMapDisplay->UpdateMask |= MENUICON_BIT(MENUICON_RIGHT); - } - - pMapDisplay->EraseMask |= TEXTLINE_BIT(TEXTLINE_5); - - // Search forward for termination - VarsUi.Tmp = 0; - while ((VarsUi.SelectedFilename[VarsUi.Tmp]) && (VarsUi.Tmp < FILENAME_LENGTH)) - { - VarsUi.Tmp++; - } - - // Search backward for "." - while ((VarsUi.Tmp) && (VarsUi.SelectedFilename[VarsUi.Tmp] != '.')) - { - VarsUi.Tmp--; - } - - if (VarsUi.Tmp > DISPLAYLINE_LENGTH) - { - VarsUi.Tmp = DISPLAYLINE_LENGTH; - } - - VarsUi.DisplayBuffer[VarsUi.Tmp] = 0; - - // Copy only name not ext - while (VarsUi.Tmp) - { - VarsUi.Tmp--; - VarsUi.DisplayBuffer[VarsUi.Tmp] = VarsUi.SelectedFilename[VarsUi.Tmp]; - } - - pMapDisplay->pMenuText = VarsUi.DisplayBuffer; - pMapDisplay->EraseMask |= MENUICON_BITS; - pMapDisplay->UpdateMask |= (SPECIAL_BIT(FRAME_SELECT) | SPECIAL_BIT(MENUTEXT)); - - IOMapUi.State = VarsUi.NextState; - VarsUi.State = 0; - } - break; - - } - } - - return (VarsUi.State); -} - - - -//******* cUiVolume ********************************************************** - -UBYTE cUiVolume(UBYTE Action) // MENU_INIT,MENU_LEFT,MENU_RIGHT,MENU_EXIT -{ - switch (Action) - { - case MENU_INIT : // Init time counter and cursor bitmap - { - VarsUi.Counter = VarsUi.NVData.VolumeStep + 1; - - VarsUi.pTmp = (UBYTE*)Cursor; - for (VarsUi.Tmp = 0;(VarsUi.Tmp < SIZE_OF_CURSOR) && (VarsUi.Tmp < (UBYTE)SIZEOF_DATA(Cursor));VarsUi.Tmp++) - { - VarsUi.CursorTmp[VarsUi.Tmp] = *VarsUi.pTmp; - VarsUi.pTmp++; - } - Action = MENU_DRAW; - } - break; - - case MENU_LEFT : // Dec - { - cUiListLeft(MAX_VOLUME + 1,&VarsUi.Counter); - IOMapUi.Volume = VarsUi.Counter - 1; - Action = MENU_DRAW; - } - break; - - case MENU_RIGHT : // Inc - { - cUiListRight(MAX_VOLUME + 1,&VarsUi.Counter); - IOMapUi.Volume = VarsUi.Counter - 1; - Action = MENU_DRAW; - } - break; - - case MENU_ENTER : // Enter - { - VarsUi.NVData.VolumeStep = VarsUi.Counter - 1; - cUiNVWrite(); - IOMapUi.Volume = VarsUi.NVData.VolumeStep; - pMapSound->Volume = IOMapUi.Volume; - Action = MENU_EXIT; - } - break; - - case MENU_EXIT : // Leave - { - IOMapUi.Volume = VarsUi.NVData.VolumeStep; - } - break; - - } - if (Action == MENU_DRAW) - { - sprintf((char*)VarsUi.DisplayBuffer,"%u",(UWORD)VarsUi.Counter - 1); - pMapDisplay->pTextLines[TEXTLINE_3] = VarsUi.DisplayBuffer; - - pMapDisplay->pBitmaps[BITMAP_1] = (BMPMAP*)VarsUi.CursorTmp; - VarsUi.CursorTmp[4] = 46; - VarsUi.CursorTmp[5] = 24; - pMapDisplay->EraseMask |= (TEXTLINE_BIT(TEXTLINE_3) | TEXTLINE_BIT(TEXTLINE_4)); - pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_3); - pMapDisplay->UpdateMask |= (TEXTLINE_BIT(TEXTLINE_3) | BITMAP_BIT(BITMAP_1)); - } - if (Action == MENU_EXIT) - { - IOMapUi.State = EXIT_PRESSED; - } - - return (0); -} - - - -//******* cUiGetUserString *************************************************** - -#define STRINGTYPES 2 - -#define TOPTEXT_LINE TEXTLINE_3 -#define STRING_LINE TEXTLINE_5 - -typedef struct -{ - const UBYTE Text; - const UBYTE *Figures; - const UBYTE NoOfFigures; - const UBYTE MaxStringLength; - const UBYTE WindowSize; - const SBYTE DefaultPointer; -} -STRSETS; - -const UBYTE Figures[] = { "0987654321" "\x7F" "abcdefghijklmnopqrstuvwxyz " }; - -const STRSETS StrSets[STRINGTYPES] = -{ - { TXT_GETUSERSTRING_PIN, Figures, 37, SIZE_OF_BT_PINCODE - 1, 15, 10 }, - { TXT_GETUSERSTRING_FILENAME, Figures, 37, FILENAME_LENGTH - 4 , 15, 10 } -}; - - -UBYTE cUiGetUserString(UBYTE Type) // 0=Pincode, 1=filename -{ - UBYTE Tmp1; - SBYTE Tmp2; - - if (Type < STRINGTYPES) - { - switch (VarsUi.GUSState) - { - case 0 : // Init screen - { - // Disable update and prepare screen - pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_LARGE); - pMapDisplay->pBitmaps[BITMAP_1] = (BMPMAP*)Ok; - - // Set figure pointer to default - VarsUi.FigurePointer = (SBYTE)StrSets[Type].DefaultPointer; - - // Calculate cursor from default string - VarsUi.GUSCursor = 0; - while ((VarsUi.GUSCursor < DISPLAYLINE_LENGTH) && VarsUi.UserString[VarsUi.GUSCursor]) - { - VarsUi.GUSCursor++; - } - VarsUi.GUSNoname = TRUE; - - VarsUi.GUSState++; - } - break; - - case 1 : // Update user string - { - if (!(pMapDisplay->EraseMask & SCREEN_BIT(SCREEN_LARGE))) - { - // Display top text - pMapDisplay->pTextLines[TOPTEXT_LINE] = cUiGetString(StrSets[Type].Text); - pMapDisplay->UpdateMask |= TEXTLINE_BIT(TOPTEXT_LINE); - - Tmp1 = 0; - while (VarsUi.UserString[Tmp1] && (Tmp1 < StrSets[Type].MaxStringLength)) - { - VarsUi.DisplayText[Tmp1] = VarsUi.UserString[Tmp1]; - Tmp1++; - } - if (Tmp1 < StrSets[Type].MaxStringLength) - { - VarsUi.DisplayText[Tmp1] = '_'; - Tmp1++; - } - while (Tmp1 < StrSets[Type].MaxStringLength) - { - VarsUi.DisplayText[Tmp1] = ' '; - Tmp1++; - } - VarsUi.DisplayText[Tmp1] = 0; - - pMapDisplay->pTextLines[STRING_LINE] = VarsUi.DisplayText; - pMapDisplay->UpdateMask |= (TEXTLINE_BIT(STRING_LINE) | SPECIAL_BIT(TOPLINE)); - pMapDisplay->EraseMask |= BITMAP_BIT(BITMAP_1); - VarsUi.GUSState++; - } - } - break; - - case 2 : // Update figure string - { - if (!(pMapDisplay->EraseMask & BITMAP_BIT(BITMAP_1))) - { - Tmp2 = VarsUi.FigurePointer; - - for (Tmp1 = 0;Tmp1 < 3;Tmp1++) - { - if (Tmp2) - { - Tmp2--; - } - else - { - Tmp2 = StrSets[Type].NoOfFigures - 1; - } - } - for (Tmp1 = 0;Tmp1 < 7;Tmp1++) - { - if ((Tmp1 == 3) && (StrSets[Type].Figures[Tmp2] == 0x7F)) - { - pMapDisplay->UpdateMask |= BITMAP_BIT(BITMAP_1); - } - else - { - pMapDisplay->pFunc(DISPLAY_CHAR,TRUE,5 + Tmp1 * 14,52,StrSets[Type].Figures[Tmp2],0); - } - if (Tmp2 < (StrSets[Type].NoOfFigures - 1)) - { - Tmp2++; - } - else - { - Tmp2 = 0; - } - } - pMapDisplay->pFunc(DISPLAY_HORISONTAL_LINE,TRUE,42,47,57,0); - pMapDisplay->pFunc(DISPLAY_VERTICAL_LINE,TRUE,42,47,0,63); - pMapDisplay->pFunc(DISPLAY_VERTICAL_LINE,TRUE,57,47,0,63); - - VarsUi.GUSState++; - } - } - break; - - case 3 : // Get user input - { - if ((pMapButton->State[BTN4] & LONG_PRESSED_EV)) - { - if (VarsUi.GUSCursor) - { - if ((VarsUi.UserString[VarsUi.GUSCursor - 1] >= 'a') && (VarsUi.UserString[VarsUi.GUSCursor - 1] <= 'z')) - { - VarsUi.UserString[VarsUi.GUSCursor - 1] -= ' '; - VarsUi.GUSState -= 2; - } - } - } - - switch (cUiReadButtons()) - { - case BUTTON_LEFT : - { - if (VarsUi.FigurePointer) - { - VarsUi.FigurePointer--; - } - else - { - VarsUi.FigurePointer = StrSets[Type].NoOfFigures - 1; - } - pMapDisplay->EraseMask |= BITMAP_BIT(BITMAP_1); - VarsUi.GUSState -= 2; - } - break; - - case BUTTON_ENTER : - { - switch (StrSets[Type].Figures[VarsUi.FigurePointer]) - { - case 0x7F : - { - VarsUi.GUSState = 100; - } - break; - - default : - { - VarsUi.GUSNoname = FALSE; - if (VarsUi.GUSCursor < StrSets[Type].MaxStringLength) - { - VarsUi.UserString[VarsUi.GUSCursor] = StrSets[Type].Figures[VarsUi.FigurePointer]; - VarsUi.GUSCursor++; - VarsUi.UserString[VarsUi.GUSCursor] = 0; - VarsUi.GUSState -= 2; - } - } - break; - - } - } - break; - - case BUTTON_RIGHT : - { - if (VarsUi.FigurePointer < (StrSets[Type].NoOfFigures - 1)) - { - VarsUi.FigurePointer++; - } - else - { - VarsUi.FigurePointer = 0; - } - pMapDisplay->EraseMask |= BITMAP_BIT(BITMAP_1); - VarsUi.GUSState -= 2; - } - break; - - case BUTTON_EXIT : - { - if (VarsUi.GUSCursor) - { - if (VarsUi.GUSNoname == TRUE) - { - VarsUi.GUSNoname = FALSE; - while (VarsUi.GUSCursor) - { - VarsUi.UserString[VarsUi.GUSCursor] = 0; - VarsUi.GUSCursor--; - } - } - else - { - VarsUi.GUSCursor--; - } - VarsUi.UserString[VarsUi.GUSCursor] = 0; - VarsUi.GUSState -= 2; - } - else - { - VarsUi.UserString[0] = 0; - VarsUi.GUSState = 100; - } - } - break; - - } - } - break; - - default : // Clean up screen - { - pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_BACKGROUND); - pMapDisplay->UpdateMask = 0; - IOMapUi.Flags |= UI_REDRAW_STATUS; - VarsUi.GUSState = 0; - } - break; - } - } - - return (VarsUi.GUSState); -} - - - -//******* cUiDataLogging ***************************************************** - -void cUiDrawPortNo(UBYTE *Bitmap,UBYTE MenuIconNo,UBYTE PortNo) -{ - UBYTE Tmp; - - Bitmap[0] = (UBYTE)(FILEFORMAT_BITMAP >> 8); - Bitmap[1] = (UBYTE)(FILEFORMAT_BITMAP); - Bitmap[2] = (UBYTE)(SIZE_OF_PORTBITMAP >> 8); - Bitmap[3] = (UBYTE)(SIZE_OF_PORTBITMAP); - Bitmap[4] = DISPLAY_MENUICONS_X_OFFS + DISPLAY_MENUICONS_X_DIFF * MenuIconNo + 2; - Bitmap[5] = DISPLAY_MENUICONS_Y; - Bitmap[6] = Port[0].ItemPixelsX; - Bitmap[7] = Port[0].ItemPixelsY; - - Tmp = 0; - while (Tmp < Bitmap[6]) - { - Bitmap[Tmp + FILEHEADER_LENGTH] = Port[0].Data[Tmp + PortNo * Bitmap[6]]; - Tmp++; - } - -} - -UBYTE cUiDataLogging(UBYTE Action) -{ - SBYTE TmpBuffer[DATALOGBUFFERSIZE + 1]; - - switch (Action) - { - case MENU_INIT : // Initialize all ports to empty - { -// Show select - pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_VIEW_SELECT); - pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_3); - pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3); - pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_SMALL); - -// Init ports - for (VarsUi.Tmp = 0;VarsUi.Tmp < DATALOGPORTS;VarsUi.Tmp++) - { - VarsUi.DatalogPort[VarsUi.Tmp] = MENU_SENSOR_EMPTY; - } - } - break; - - case MENU_EXIT : // Initialize all ports to empty - { -// Show select - pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_VIEW_SELECT); - pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_3); - pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3); - pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_SMALL); - } - break; - - case MENU_TEXT : // Write text - { -// Init selected sensor and port to none - VarsUi.SelectedSensor = MENU_SENSOR_EMPTY; - VarsUi.SelectedPort = MENU_PORT_EMPTY; -// Count ports - VarsUi.Counter = 0; - for (VarsUi.Tmp = 0;VarsUi.Tmp < DATALOGPORTS;VarsUi.Tmp++) - { - if (MENU_SENSOR_EMPTY != VarsUi.DatalogPort[VarsUi.Tmp]) - { -// Find default port to view - if (VarsUi.SelectedPort == MENU_PORT_EMPTY) - { - VarsUi.SelectedPort = VarsUi.Tmp + MENU_PORT_1; - } - VarsUi.Counter++; - } - } - if (VarsUi.Counter) - { -// Display text - pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_DATALOGGING_PRESS_EXIT_TO); - pMapDisplay->pTextLines[TEXTLINE_4] = cUiGetString(TXT_DATALOGGING_STOP_DATALOGGING); - - pMapDisplay->TextLinesCenterFlags |= (TEXTLINE_BIT(TEXTLINE_3) | TEXTLINE_BIT(TEXTLINE_4)); - pMapDisplay->UpdateMask |= (TEXTLINE_BIT(TEXTLINE_3) | TEXTLINE_BIT(TEXTLINE_4)); - } - else - { - cUiMenuPrevFile(); - IOMapUi.State = NEXT_MENU; - VarsUi.State = 0; - } - } - break; - - case MENU_RUN : // Run data logging - { - switch (VarsUi.State) - { - case 0 : // Init log - { -// Save menu text - VarsUi.MenuIconTextSave = pMapDisplay->pMenuText; - -// Delete file if exist - sprintf((char*)VarsUi.FilenameBuffer,"%s.%s",(char*)TEMP_DATALOG_FILENAME,(char*)TXT_FILE_EXT[FILETYPE_DATALOG]); - VarsUi.TmpHandle = pMapLoader->pFunc(FINDFIRST,VarsUi.FilenameBuffer,VarsUi.SearchFilenameBuffer,&VarsUi.TmpLength); - if (!(VarsUi.TmpHandle & 0x8000)) - { - pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.TmpHandle,NULL,NULL); - pMapLoader->pFunc(DELETE,VarsUi.FilenameBuffer,NULL,NULL); - } - -// Open file - VarsUi.TmpLength = pMapLoader->FreeUserFlash; - sprintf((char*)VarsUi.FilenameBuffer,"%s.%s",(char*)TEMP_DATALOG_FILENAME,(char*)TXT_FILE_EXT[FILETYPE_DATALOG]); - VarsUi.TmpHandle = pMapLoader->pFunc(OPENWRITEDATA,VarsUi.FilenameBuffer,NULL,&VarsUi.TmpLength); - VarsUi.DatalogError = VarsUi.TmpHandle; - if (!(VarsUi.DatalogError & 0x8000)) - { - VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"%s\t%lu",SENSORSYNCDATA,pMapCmd->SyncTime); - VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); - - VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"\t%lu",pMapCmd->SyncTick); - VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); - - VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"\t%lu",pMapCmd->Tick); - VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); - - VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"\t%lu\t-1\r\n",DATALOG_DEFAULT_SAMPLE_TIME); - VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); - - VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"%s",SENSORSDATA); - VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); - for (VarsUi.Tmp = 0;(VarsUi.Tmp < DATALOGPORTS) && (!(VarsUi.DatalogError & 0x8000));VarsUi.Tmp++) - { - if (MENU_SENSOR_EMPTY != VarsUi.DatalogPort[VarsUi.Tmp]) - { - VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"\t%u_%s%s",(UWORD)(VarsUi.Tmp + 1),(char*)SENSORDIRNAME[(VarsUi.DatalogPort[VarsUi.Tmp] - MENU_SENSOR_EMPTY) - 1],(char*)SENSORUNITNAME[(VarsUi.DatalogPort[VarsUi.Tmp] - MENU_SENSOR_EMPTY) - 1]); - VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); - } - } - VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"\r\n"); - VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); - VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"%s",SENSORTIME); - VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); - for (VarsUi.Tmp = 0;(VarsUi.Tmp < DATALOGPORTS) && (!(VarsUi.DatalogError & 0x8000));VarsUi.Tmp++) - { - if (MENU_SENSOR_EMPTY != VarsUi.DatalogPort[VarsUi.Tmp]) - { - VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"\t%s",(char*)SENSORDIRNAME[(VarsUi.DatalogPort[VarsUi.Tmp] - MENU_SENSOR_EMPTY) - 1]); - VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); - } - } - VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"\r\n"); - VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); - if (!(VarsUi.DatalogError & 0x8000)) - { - VarsUi.DatalogTimer = 0; - VarsUi.DatalogSampleTime = DATALOG_DEFAULT_SAMPLE_TIME; - VarsUi.DatalogSampleTimer = 0; - VarsUi.Timer = 0; - VarsUi.Update = TRUE; - IOMapUi.Flags |= UI_BUSY; - VarsUi.DatalogOldTick = pMapCmd->Tick; - VarsUi.SensorReset = TRUE; - VarsUi.State++; - } - else - { - pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_SMALL); - pMapDisplay->pBitmaps[BITMAP_1] = NULL; - VarsUi.State = 4; - } - } - else - { -// File error - pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_SMALL); - pMapDisplay->pBitmaps[BITMAP_1] = NULL; - VarsUi.State = 3; - } - } - break; - - case 1 : - { -// Get real time since last - VarsUi.DatalogRTC = (pMapCmd->Tick - VarsUi.DatalogOldTick); - VarsUi.DatalogOldTick = pMapCmd->Tick; -// Update all timers - VarsUi.DatalogTimer += VarsUi.DatalogRTC; - VarsUi.DatalogSampleTimer += VarsUi.DatalogRTC; - VarsUi.ReadoutTimer += VarsUi.DatalogRTC; -// Update sensor values - cUiUpdateSensor((SWORD)VarsUi.DatalogRTC); -// Check for select change - if (VarsUi.Update == TRUE) - { - VarsUi.Update = FALSE; - VarsUi.SelectedSensor = VarsUi.DatalogPort[VarsUi.SelectedPort - MENU_PORT_1]; - pMapDisplay->pMenuIcons[MENUICON_CENTER] = cUiMenuGetIconImage(cUiMenuSearchSensorIcon(VarsUi.SelectedSensor)); - pMapDisplay->pMenuIcons[MENUICON_LEFT] = NULL; - pMapDisplay->pMenuIcons[MENUICON_RIGHT] = NULL; - - pMapDisplay->EraseMask = SCREEN_BIT(SCREEN_LARGE); - pMapDisplay->pBitmaps[BITMAP_1] = (BMPMAP*)Display; - pMapDisplay->UpdateMask = (BITMAP_BIT(BITMAP_1) | MENUICON_BITS | SPECIAL_BIT(TOPLINE) | SPECIAL_BIT(FRAME_SELECT)); - - pMapDisplay->pBitmaps[BITMAP_2] = (BMPMAP*)VarsUi.PortBitmapLeft; - pMapDisplay->pBitmaps[BITMAP_3] = (BMPMAP*)VarsUi.PortBitmapCenter; - pMapDisplay->pBitmaps[BITMAP_4] = (BMPMAP*)VarsUi.PortBitmapRight; - - cUiDrawPortNo(VarsUi.PortBitmapCenter,MENUICON_CENTER,VarsUi.SelectedPort - MENU_PORT_EMPTY); - pMapDisplay->UpdateMask |= BITMAP_BIT(BITMAP_3); - - - - if (VarsUi.Counter == 2) - { - VarsUi.Tmp = VarsUi.SelectedPort; - do - { - VarsUi.Tmp++; - if (VarsUi.Tmp >= MENU_PORT_INVALID) - { - VarsUi.Tmp = MENU_PORT_1; - } - } - while (VarsUi.DatalogPort[VarsUi.Tmp - MENU_PORT_1] == MENU_SENSOR_EMPTY); - if (VarsUi.Tmp > VarsUi.SelectedPort) - { - pMapDisplay->pMenuIcons[MENUICON_RIGHT] = cUiMenuGetIconImage(cUiMenuSearchSensorIcon(VarsUi.DatalogPort[VarsUi.Tmp - MENU_PORT_1])); - cUiDrawPortNo(VarsUi.PortBitmapRight,MENUICON_RIGHT,VarsUi.Tmp - MENU_PORT_EMPTY); - pMapDisplay->UpdateMask |= BITMAP_BIT(BITMAP_4); - } - else - { - pMapDisplay->pMenuIcons[MENUICON_LEFT] = cUiMenuGetIconImage(cUiMenuSearchSensorIcon(VarsUi.DatalogPort[VarsUi.Tmp - MENU_PORT_1])); - cUiDrawPortNo(VarsUi.PortBitmapLeft,MENUICON_LEFT,VarsUi.Tmp - MENU_PORT_EMPTY); - pMapDisplay->UpdateMask |= BITMAP_BIT(BITMAP_2); - } - } - if (VarsUi.Counter > 2) - { - VarsUi.Tmp = VarsUi.SelectedPort; - do - { - VarsUi.Tmp++; - if (VarsUi.Tmp >= MENU_PORT_INVALID) - { - VarsUi.Tmp = MENU_PORT_1; - } - } - while (VarsUi.DatalogPort[VarsUi.Tmp - MENU_PORT_1] == MENU_SENSOR_EMPTY); - pMapDisplay->pMenuIcons[MENUICON_RIGHT] = cUiMenuGetIconImage(cUiMenuSearchSensorIcon(VarsUi.DatalogPort[VarsUi.Tmp - MENU_PORT_1])); - cUiDrawPortNo(VarsUi.PortBitmapRight,MENUICON_RIGHT,VarsUi.Tmp - MENU_PORT_EMPTY); - pMapDisplay->UpdateMask |= BITMAP_BIT(BITMAP_4); - - VarsUi.Tmp = VarsUi.SelectedPort; - do - { - VarsUi.Tmp--; - if (VarsUi.Tmp <= MENU_PORT_EMPTY) - { - VarsUi.Tmp = MENU_PORT_INVALID - 1; - } - } - while (VarsUi.DatalogPort[VarsUi.Tmp - MENU_PORT_1] == MENU_SENSOR_EMPTY); - pMapDisplay->pMenuIcons[MENUICON_LEFT] = cUiMenuGetIconImage(cUiMenuSearchSensorIcon(VarsUi.DatalogPort[VarsUi.Tmp - MENU_PORT_1])); - cUiDrawPortNo(VarsUi.PortBitmapLeft,MENUICON_LEFT,VarsUi.Tmp - MENU_PORT_EMPTY); - pMapDisplay->UpdateMask |= BITMAP_BIT(BITMAP_2); - - - } - VarsUi.ReadoutTimer = DISPLAY_VIEW_UPDATE; - } -// Write sample if timeout - if (VarsUi.DatalogSampleTimer >= VarsUi.DatalogSampleTime) - { - VarsUi.DatalogSampleTimer -= VarsUi.DatalogSampleTime; - - VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"%lu",VarsUi.DatalogTimer - VarsUi.DatalogSampleTime); - VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); - for (VarsUi.Tmp = 0;(VarsUi.Tmp < DATALOGPORTS) && (!(VarsUi.DatalogError & 0x8000));VarsUi.Tmp++) - { - if (MENU_SENSOR_EMPTY != VarsUi.DatalogPort[VarsUi.Tmp]) - { - if (VarsUi.DatalogSampleValid[VarsUi.Tmp] == TRUE) - { - VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,(char*)SENSORFORMAT2[(VarsUi.DatalogPort[VarsUi.Tmp] - MENU_SENSOR_EMPTY) - 1],(float)VarsUi.DatalogSampleValue[VarsUi.Tmp] / SENSORDIVIDER[VarsUi.DatalogPort[VarsUi.Tmp] - MENU_SENSOR_EMPTY]); - VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); - } - else - { - VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"\t-"); - VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); - } - } - } - VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"\r\n"); - VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); - } -// Refresh display - if (++VarsUi.ReadoutTimer >= DISPLAY_VIEW_UPDATE) - { - VarsUi.ReadoutTimer = 0; - -// Display sensor value - cUiPrintSensorInDisplayBuffer(VarsUi.SelectedPort); - pMapDisplay->pTextLines[TEXTLINE_4] = VarsUi.DisplayBuffer; - pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_4); - pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_4); - } - -// Test for file error - if ((VarsUi.DatalogError & 0x8000)) - { - pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_SMALL); - pMapDisplay->pBitmaps[BITMAP_1] = NULL; - VarsUi.State = 4; - } - -// Test for break; - switch (cUiReadButtons()) - { - case BUTTON_EXIT : - { - VarsUi.State++; - } - break; - - case BUTTON_LEFT : - { - VarsUi.Tmp = VarsUi.SelectedPort; - do - { - VarsUi.Tmp--; - if (VarsUi.Tmp <= MENU_PORT_EMPTY) - { - VarsUi.Tmp = MENU_PORT_INVALID - 1; - } - } - while (VarsUi.DatalogPort[VarsUi.Tmp - MENU_PORT_1] == MENU_SENSOR_EMPTY); - if ((VarsUi.Counter > 2) || (VarsUi.Tmp < VarsUi.SelectedPort)) - { - VarsUi.SelectedPort = VarsUi.Tmp; - } - VarsUi.Update = TRUE; - } - break; - - case BUTTON_RIGHT : - { - VarsUi.Tmp = VarsUi.SelectedPort; - do - { - VarsUi.Tmp++; - if (VarsUi.Tmp >= MENU_PORT_INVALID) - { - VarsUi.Tmp = MENU_PORT_1; - } - } - while (VarsUi.DatalogPort[VarsUi.Tmp - MENU_PORT_1] == MENU_SENSOR_EMPTY); - if ((VarsUi.Counter > 2) || (VarsUi.Tmp > VarsUi.SelectedPort)) - { - VarsUi.SelectedPort = VarsUi.Tmp; - } - VarsUi.Update = TRUE; - } - break; - - } - IOMapUi.Flags |= UI_RESET_SLEEP_TIMER; - } - break; - - case 2 : - { -// Close file - pMapLoader->pFunc(CROPDATAFILE,(UBYTE*)&VarsUi.TmpHandle,NULL,NULL); - -// Clean up - pMapDisplay->pMenuText = VarsUi.MenuIconTextSave; - cUiReleaseSensors(); - - IOMapUi.Flags &= ~UI_BUSY; - IOMapUi.State = RIGHT_PRESSED; - VarsUi.State = 0; - } - break; - - case 3 : // Display memory full text - { - if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_DL_ERROR_MEMORY_FULL_1,TXT_FB_DL_ERROR_MEMORY_FULL_2,DISPLAY_SHOW_ERROR_TIME)) - { - cUiMenuPrevFile(); - IOMapUi.State = NEXT_MENU; - VarsUi.State = 0; - } - } - break; - - case 4 : // Display memory full text - { - if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_DL_ERROR_MEMORY_FULL_1,TXT_FB_DL_ERROR_MEMORY_FULL_2,DISPLAY_SHOW_ERROR_TIME)) - { - VarsUi.State = 2; - } - } - break; - - } - } - break; - - case MENU_SAVE : // Save datalog file - { - switch (VarsUi.State) - { - case 0 : - { - VarsUi.NVData.DatalogNumber++; - if (VarsUi.NVData.DatalogNumber > MAX_DATALOGS) - { - VarsUi.NVData.DatalogNumber = 1; - } - cUiNVWrite(); - sprintf((char*)VarsUi.SelectedFilename,"%s%u.%s",(char*)UI_DATALOG_FILENAME,VarsUi.NVData.DatalogNumber,TXT_FILE_EXT[FILETYPE_DATALOG]); - VarsUi.State++; - } - break; - - case 1 : - { -// Rename TEMP_DATALOG_FILENAME to VarsUi.SelectedFilename(user filename) - sprintf((char*)VarsUi.FilenameBuffer,"%s.%s",(char*)TEMP_DATALOG_FILENAME,(char*)TXT_FILE_EXT[FILETYPE_DATALOG]); - VarsUi.TmpHandle = pMapLoader->pFunc(RENAMEFILE,VarsUi.FilenameBuffer,VarsUi.SelectedFilename,&VarsUi.TmpLength); - VarsUi.State++; - } - break; - - case 2 : // Display saved text - { - if (!cUiFeedback((BMPMAP*)Info,TXT_FB_DL_FILE_SAVED_INFO,0xFF,DISPLAY_SHOW_FILENAME_TIME)) - { - VarsUi.State++; - } - } - break; - - default : - { - cUiMenuPrevFile(); - IOMapUi.State = NEXT_MENU; - VarsUi.State = 0; - } - break; - - } - } - break; - - case MENU_DELETE : // Delete datalog file - { - switch (VarsUi.State) - { - case 0 : - { -// Delete file if exist - sprintf((char*)VarsUi.FilenameBuffer,"%s.%s",(char*)TEMP_DATALOG_FILENAME,(char*)TXT_FILE_EXT[FILETYPE_DATALOG]); - pMapLoader->pFunc(DELETE,VarsUi.FilenameBuffer,NULL,NULL); - VarsUi.State++; - } - break; - - case 1 : - { - pMapDisplay->EraseMask |= (TEXTLINE_BIT(TEXTLINE_3) | TEXTLINE_BIT(TEXTLINE_4) | TEXTLINE_BIT(TEXTLINE_5) | MENUICON_BITS | SPECIAL_BIT(MENUTEXT)); - VarsUi.Timer = DISPLAY_SHOW_TIME; - VarsUi.State++; - } - break; - - case 2 : - { - if (++VarsUi.Timer >= DISPLAY_SHOW_TIME) - { - pMapDisplay->EraseMask |= TEXTLINE_BIT(TEXTLINE_3); - VarsUi.State++; - } - } - break; - - default : - { - VarsUi.State = 0; - } - break; - - } - } - break; - - case MENU_SELECT : // Save sensor - { - pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_VIEW_SELECT); - pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_3); - pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3); - - VarsUi.DatalogPort[VarsUi.SelectedPort - MENU_PORT_1] = VarsUi.SelectedSensor; - IOMapUi.State = EXIT_PRESSED; - } - break; - - default : - { - switch (VarsUi.State) - { - case 0 : - { - if ((Action > MENU_SENSOR_EMPTY) && (Action < MENU_SENSOR_INVALID)) - { - VarsUi.SelectedSensor = Action; - } - if ((Action > MENU_PORT_EMPTY) && (Action < MENU_PORT_INVALID)) - { - VarsUi.SelectedPort = Action; - if (VarsUi.DatalogPort[VarsUi.SelectedPort - MENU_PORT_1] != MENU_SENSOR_EMPTY) - { - - // Port occupied - pMapDisplay->pTextLines[TEXTLINE_4] = cUiGetString(TXT_DATALOGGING_PORT_OCCUPIED); - pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_4); - pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_4); - VarsUi.Timer = 0; - VarsUi.State++; - } - } - } - break; - - default : - { - if ((++VarsUi.Timer >= DISPLAY_SHOW_TIME) || (BUTTON_NONE != cUiReadButtons())) - { - pMapDisplay->EraseMask |= TEXTLINE_BIT(TEXTLINE_4); - cUiMenuPrev(); - IOMapUi.State = NEXT_MENU; - VarsUi.State = 0; - } - } - break; - - } - } - break; - - } - - return (VarsUi.State); -} - - -//******* cUiRunning ********************************************************** - -void cUiRunning(UBYTE Action) -{ - switch (Action) - { - case MENU_INIT : - { - VarsUi.RunIconSave = pMapDisplay->pMenuIcons[MENUICON_CENTER]; - VarsUi.RunBitmapPointer = 0; - VarsUi.RunTimer = 0; - pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_LARGE); - pMapDisplay->UpdateMask |= SPECIAL_BIT(TOPLINE); - } - break; - - case MENU_RUN : - { - if ((IOMapUi.Flags & UI_ENABLE_STATUS_UPDATE)) - { - if (++VarsUi.RunTimer >= RUN_BITMAP_CHANGE_TIME) - { - VarsUi.RunTimer = 0; - if (++VarsUi.RunBitmapPointer >= Running->ItemsY ) - { - VarsUi.RunBitmapPointer = 0; - } - pMapDisplay->pMenuIcons[MENUICON_CENTER] = (UBYTE*)&Running->Data[VarsUi.RunBitmapPointer * Running->ItemPixelsX * (Running->ItemPixelsY / 8)]; - pMapDisplay->EraseMask |= MENUICON_BIT(MENUICON_CENTER); - pMapDisplay->UpdateMask |= MENUICON_BIT(MENUICON_CENTER); - } - } - } - break; - - case MENU_UPDATE : - { - pMapDisplay->pMenuIcons[MENUICON_CENTER] = (UBYTE*)&Running->Data[VarsUi.RunBitmapPointer * Running->ItemPixelsX * (Running->ItemPixelsY / 8)]; - pMapDisplay->UpdateMask |= MENUICON_BIT(MENUICON_CENTER); - } - break; - - case MENU_EXIT : - { - pMapDisplay->pMenuIcons[MENUICON_CENTER] = VarsUi.RunIconSave; - pMapDisplay->UpdateMask = MENUICON_BITS | SPECIAL_BIT(MENUTEXT); - } - break; - - } -} - -//******* cUiOnBrickProgramming ********************************************** - -UBYTE cUiOnBrickProgramming(UBYTE Action) // On brick programming -{ - switch (Action) - { - case MENU_INIT : // Show motor / sensor text - { - pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_ONBRICKPROGRAMMING_PLEASE_USE_PORT); - pMapDisplay->pTextLines[TEXTLINE_4] = cUiGetString(TXT_ONBRICKPROGRAMMING_1_TOUCH_SENSOR); - pMapDisplay->pTextLines[TEXTLINE_5] = cUiGetString(TXT_ONBRICKPROGRAMMING_2_SOUND_SENSOR); - pMapDisplay->pTextLines[TEXTLINE_6] = cUiGetString(TXT_ONBRICKPROGRAMMING_3_LIGHT_SENSOR); - pMapDisplay->pTextLines[TEXTLINE_7] = cUiGetString(TXT_ONBRICKPROGRAMMING_4_ULTRA_SONIC); - pMapDisplay->pTextLines[TEXTLINE_8] = cUiGetString(TXT_ONBRICKPROGRAMMING_BC_LR_MOTORS); - pMapDisplay->EraseMask |= (TEXTLINE_BIT(TEXTLINE_3) | TEXTLINE_BIT(TEXTLINE_4) | TEXTLINE_BIT(TEXTLINE_5) | TEXTLINE_BIT(TEXTLINE_6) | TEXTLINE_BIT(TEXTLINE_7) | TEXTLINE_BIT(TEXTLINE_8)); - pMapDisplay->UpdateMask &= ~SPECIAL_BIT(FRAME_SELECT); - pMapDisplay->UpdateMask |= (TEXTLINE_BIT(TEXTLINE_3) | TEXTLINE_BIT(TEXTLINE_4) | TEXTLINE_BIT(TEXTLINE_5) | TEXTLINE_BIT(TEXTLINE_6) | TEXTLINE_BIT(TEXTLINE_7) | TEXTLINE_BIT(TEXTLINE_8) | SPECIAL_BIT(TOPLINE)); - pMapDisplay->TextLinesCenterFlags |= (TEXTLINE_BIT(TEXTLINE_3) | TEXTLINE_BIT(TEXTLINE_4) | TEXTLINE_BIT(TEXTLINE_5) | TEXTLINE_BIT(TEXTLINE_6) | TEXTLINE_BIT(TEXTLINE_7) | TEXTLINE_BIT(TEXTLINE_8)); - IOMapUi.State = TEST_BUTTONS; - } - break; - - case MENU_TEXT : // Show empty program steps - { - pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_LARGE); - - VarsUi.pTmp = (UBYTE*)Cursor; - for (VarsUi.Tmp = 0;(VarsUi.Tmp < SIZE_OF_CURSOR) && (VarsUi.Tmp < (UBYTE)SIZEOF_DATA(Cursor));VarsUi.Tmp++) - { - VarsUi.CursorTmp[VarsUi.Tmp] = *VarsUi.pTmp; - VarsUi.pTmp++; - } - - for (VarsUi.ProgramStepPointer = 0;VarsUi.ProgramStepPointer < ON_BRICK_PROGRAMSTEPS;VarsUi.ProgramStepPointer++) - { - VarsUi.ProgramSteps[VarsUi.ProgramStepPointer] = MENU_ACTION_EMPTY; - } - VarsUi.ProgramStepPointer = 0; - Action = MENU_DRAW; - } - break; - - case MENU_EXIT : // Delete one steps and exit at the end - { - if (VarsUi.ProgramStepPointer) - { - if (VarsUi.ProgramStepPointer < ON_BRICK_PROGRAMSTEPS) - { - VarsUi.ProgramSteps[VarsUi.ProgramStepPointer] = MENU_ACTION_EMPTY; - } - VarsUi.ProgramStepPointer--; - } - else - { - IOMapUi.State = NEXT_MENU; - } - Action = MENU_DRAW; - } - break; - - case MENU_RUN : // Run program steps until end or user press exit button - { - switch (VarsUi.State) - { - case 0 : - { - VarsUi.pTmp = (UBYTE*)Cursor; - for (VarsUi.Tmp = 0;(VarsUi.Tmp < SIZE_OF_CURSOR) && (VarsUi.Tmp < (UBYTE)SIZEOF_DATA(Cursor));VarsUi.Tmp++) - { - VarsUi.CursorTmp[VarsUi.Tmp] = *VarsUi.pTmp; - VarsUi.pTmp++; - } - pMapDisplay->pBitmaps[BITMAP_1] = (BMPMAP*)VarsUi.CursorTmp; - cUiRunning(MENU_INIT); - Action = MENU_DRAW; - VarsUi.State++; - } - break; - - case 1 : // If sound finished -> Init text and program pointer - { - if (SOUND_IDLE == pMapSound->State) - { - VarsUi.ProgramStepPointer = ON_BRICK_PROGRAMSTEPS; - VarsUi.MenuIconTextSave = pMapDisplay->pMenuText; - pMapDisplay->EraseMask |= SPECIAL_BIT(MENUTEXT); - VarsUi.State++; - } - } - break; - - case 2 : // load file to run - { - if (PROG_IDLE == pMapCmd->ProgStatus) - { - sprintf((char*)pMapCmd->FileName,"%s.%s",(char*)VM_PROGRAM_READER,(char*)TXT_SYS_EXT); - pMapCmd->ActivateFlag = TRUE; - VarsUi.State++; - } - } - break; - - case 3 : // Wait for end of file - { - if (PROG_RUNNING != pMapCmd->ProgStatus) - { - pMapCmd->ProgStatus = PROG_RESET; - VarsUi.State = 99; - VarsUi.ProgramStepPointer = ON_BRICK_PROGRAMSTEPS; - } - else - { - if (VarsUi.OBPTimer >= MIN_DISPLAY_UPDATE_TIME) - { - if (IOMapUi.OBPPointer != VarsUi.ProgramStepPointer) - { - VarsUi.ProgramStepPointer = IOMapUi.OBPPointer; - Action = MENU_DRAW; - } - } - } - } - break; - - default : // Program stopped - { - pMapDisplay->pMenuText = VarsUi.MenuIconTextSave; - pMapDisplay->UpdateMask |= SPECIAL_BIT(MENUTEXT); - Action = MENU_DRAW; - VarsUi.State = 0; - } - break; - - } - if (VarsUi.State) - { - cUiRunning(MENU_RUN); - } - else - { - cUiRunning(MENU_EXIT); - } - } - break; - - case MENU_LEFT : // NA - { - IOMapUi.State = TEST_BUTTONS; - } - break; - - case MENU_RIGHT : // NA - { - IOMapUi.State = TEST_BUTTONS; - } - break; - - case MENU_UPDATE : // NA - { - Action = MENU_DRAW; - } - break; - - case MENU_SAVE : // Save NXT program - { - switch (VarsUi.State) - { - case 0 : - { - // Suggest default filename to user - strcpy((char*)VarsUi.UserString,(char*)DEFAULT_PROGRAM_NAME); - VarsUi.State++; - } - break; - - case 1 : - { - if (!cUiGetUserString(1)) - { - if (VarsUi.UserString[0]) - { - sprintf((char*)VarsUi.SelectedFilename,"%s.%s",VarsUi.UserString,TXT_FILE_EXT[FILETYPE_NXT]); - - // If tmp file exist -> ask for overwrite - VarsUi.TmpHandle = pMapLoader->pFunc(FINDFIRST,(UBYTE*)VarsUi.SelectedFilename,VarsUi.FilenameBuffer,&VarsUi.TmpLength); - if (!(VarsUi.TmpHandle & 0x8000)) - { - pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.TmpHandle,NULL,NULL); - VarsUi.State++; - } - else - { - VarsUi.State += 2; - } - } - else - { - VarsUi.State = 99; - } - } - } - break; - - case 2 : - { - if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_OBP_FILE_EXIST_FAIL,TXT_FB_OBP_OVERWRITE_FAIL,0)) - { - VarsUi.State = 0; - } - } - break; - - case 3 : - { - // Rename TEMP_PROGRAM_FILENAME to VarsUi.SelectedFilename(user filename) - sprintf((char*)VarsUi.FilenameBuffer,"%s.%s",(char*)TEMP_PROGRAM_FILENAME,(char*)TXT_TMP_EXT); - VarsUi.TmpHandle = pMapLoader->pFunc(RENAMEFILE,VarsUi.FilenameBuffer,VarsUi.SelectedFilename,&VarsUi.TmpLength); - pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.TmpHandle,NULL,NULL); - VarsUi.State++; - } - break; - - case 4 : // Display saved text - { - if (!cUiFeedback((BMPMAP*)Info,TXT_FB_OBP_FILE_SAVED_INFO,0,DISPLAY_SHOW_TIME)) - { - VarsUi.State++; - } - } - break; - - default : - { - cUiMenuPrevFile(); - IOMapUi.State = NEXT_MENU; - VarsUi.State = 0; - } - break; - - } - } - break; - - case MENU_OVERWRITE : // Over write existing file - { - switch (VarsUi.State) - { - case 0 : - { - // Delete VarsUi.SelectedFilename(user filename) - VarsUi.TmpHandle = pMapLoader->pFunc(FINDFIRST,(UBYTE*)VarsUi.SelectedFilename,VarsUi.FilenameBuffer,&VarsUi.TmpLength); - if (!(VarsUi.TmpHandle & 0x8000)) - { - pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.TmpHandle,NULL,NULL); - pMapLoader->pFunc(DELETE,VarsUi.SelectedFilename,NULL,NULL); - } - - // Rename TEMP_PROGRAM_FILENAME to VarsUi.SelectedFilename(user filename) - sprintf((char*)VarsUi.FilenameBuffer,"%s.%s",(char*)TEMP_PROGRAM_FILENAME,(char*)TXT_TMP_EXT); - VarsUi.TmpHandle = pMapLoader->pFunc(RENAMEFILE,VarsUi.FilenameBuffer,VarsUi.SelectedFilename,&VarsUi.TmpLength); - pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.TmpHandle,NULL,NULL); - VarsUi.State++; - } - break; - - default : // Display saved text - { - if (!cUiFeedback((BMPMAP*)Info,TXT_FB_OBP_FILE_SAVED_INFO,0,DISPLAY_SHOW_TIME)) - { - VarsUi.State = 0; - } - } - break; - - } - - } - break; - - default : // Insert selected action/waitfor in program and save if finished - { - switch (VarsUi.State) - { - case 0 : - { - VarsUi.ProgramSteps[VarsUi.ProgramStepPointer] = Action; - if (VarsUi.ProgramStepPointer < ON_BRICK_PROGRAMSTEPS) - { - VarsUi.ProgramStepPointer++; - } - if (VarsUi.ProgramStepPointer == ON_BRICK_PROGRAMSTEPS) - { - // If tmp file exist -> delete it - sprintf((char*)VarsUi.FilenameBuffer,"%s.%s",(char*)TEMP_PROGRAM_FILENAME,(char*)TXT_TMP_EXT); - VarsUi.TmpHandle = pMapLoader->pFunc(FINDFIRST,VarsUi.FilenameBuffer,VarsUi.SearchFilenameBuffer,&VarsUi.TmpLength); - if (!(VarsUi.TmpHandle & 0x8000)) - { - pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.TmpHandle,NULL,NULL); - pMapLoader->pFunc(DELETE,VarsUi.FilenameBuffer,NULL,NULL); - } - - // Save program as tmp file - VarsUi.TmpLength = FILEHEADER_LENGTH + ON_BRICK_PROGRAMSTEPS; - VarsUi.TmpHandle = pMapLoader->pFunc(OPENWRITE,VarsUi.FilenameBuffer,NULL,&VarsUi.TmpLength); - if (!(VarsUi.TmpHandle & 0x8000)) - { - VarsUi.FileHeader[0] = (UBYTE)(FILEFORMAT_PROGRAM >> 8); - VarsUi.FileHeader[1] = (UBYTE)(FILEFORMAT_PROGRAM); - VarsUi.FileHeader[2] = (UBYTE)(ON_BRICK_PROGRAMSTEPS >> 8); - VarsUi.FileHeader[3] = (UBYTE)(ON_BRICK_PROGRAMSTEPS); - VarsUi.FileHeader[4] = (UBYTE)(ON_BRICK_PROGRAMSTEPS); - VarsUi.FileHeader[5] = (UBYTE)0; - VarsUi.FileHeader[6] = (UBYTE)0; - VarsUi.FileHeader[7] = (UBYTE)0; - VarsUi.TmpLength = FILEHEADER_LENGTH; - pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)VarsUi.FileHeader,&VarsUi.TmpLength); - VarsUi.TmpLength = ON_BRICK_PROGRAMSTEPS; - pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)VarsUi.ProgramSteps,&VarsUi.TmpLength); - pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.TmpHandle,NULL,NULL); - } - else - { - VarsUi.State++; - } - } - Action = MENU_DRAW; - } - break; - - default : // Display memory error text - { - if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_OBP_MEMORY_FULL_FAIL,0,DISPLAY_SHOW_ERROR_TIME)) - { - cUiMenuPrevFile(); - IOMapUi.State = NEXT_MENU; - VarsUi.State = 0; - } - } - break; - - } - } - break; - - } - - // Update display screen - if (Action == MENU_DRAW) - { - VarsUi.OBPTimer = 0; - - for (VarsUi.Pointer = 0;VarsUi.Pointer < ON_BRICK_PROGRAMSTEPS;VarsUi.Pointer++) - { - VarsUi.Tmp = VarsUi.ProgramSteps[VarsUi.Pointer]; - if ((VarsUi.Tmp >= MENU_ACTION_EMPTY) && (VarsUi.Tmp < MENU_ACTION_INVALID)) - { - VarsUi.Tmp -= MENU_ACTION_EMPTY; - pMapDisplay->StepIcons[VarsUi.Pointer] = VarsUi.Tmp + 1; - } - if ((VarsUi.Tmp >= MENU_WAIT_EMPTY) && (VarsUi.Tmp < MENU_WAIT_INVALID)) - { - VarsUi.Tmp -= MENU_WAIT_EMPTY; - pMapDisplay->StepIcons[VarsUi.Pointer] = VarsUi.Tmp + 1 + 16; - } - if (VarsUi.Tmp == MENU_LOOP) - { - pMapDisplay->StepIcons[VarsUi.Pointer] = 31; - } - if (VarsUi.Tmp == MENU_STOP) - { - pMapDisplay->StepIcons[VarsUi.Pointer] = 32; - } - pMapDisplay->UpdateMask |= STEPICON_BIT(STEPICON_1 + VarsUi.Pointer); - } - - // and cursor - pMapDisplay->pBitmaps[BITMAP_1] = (BMPMAP*)VarsUi.CursorTmp; - if (VarsUi.ProgramStepPointer < ON_BRICK_PROGRAMSTEPS) - { - VarsUi.CursorTmp[4] = 13 + (VarsUi.ProgramStepPointer * 17); - VarsUi.CursorTmp[5] = 24; - pMapDisplay->UpdateMask |= BITMAP_BIT(BITMAP_1); - } - if (PROG_RUNNING != pMapCmd->ProgStatus) - { - pMapDisplay->EraseMask |= (TEXTLINE_BIT(TEXTLINE_3) | TEXTLINE_BIT(TEXTLINE_2)); - } - pMapDisplay->EraseMask |= TEXTLINE_BIT(TEXTLINE_4); - pMapDisplay->UpdateMask |= (SPECIAL_BIT(STEPLINE) | SPECIAL_BIT(TOPLINE)); - } - - return (VarsUi.State); -} - - - -//******* cUiFileRun ********************************************************** - -UBYTE cUiFindFileType(UBYTE *Filename) // Find file type number -{ - UBYTE Ext[FILENAME_LENGTH + 1]; - UBYTE Result; - UBYTE Tmp1; - UBYTE Tmp2; - - Result = FILETYPE_ALL; - - Tmp1 = 0; - while ((Filename[Tmp1]) && (Tmp1 < FILENAME_LENGTH)) // Search forward for termination - { - Tmp1++; - } - - while ((Tmp1) && (Filename[Tmp1] != '.')) // Search backward for "." - { - Tmp1--; - } - - if (Filename[Tmp1] == '.') // If "." - { - Tmp1++; - Tmp2 = 0; - - while ((Filename[Tmp1]) && (Tmp1 < FILENAME_LENGTH)) // Convert to upper to Ext - { - Ext[Tmp2] = tolower(Filename[Tmp1]); - Tmp1++; - Tmp2++; - } - Ext[Tmp2] = 0; // Inser termination - - // Calculate type - for (Tmp1 = FILETYPE_ALL;(Tmp1 < FILETYPES) && (Result == FILETYPE_ALL);Tmp1++) - { - if (strcmp((char*)TXT_FILE_EXT[Tmp1],(char*)Ext) == 0) - { - Result = Tmp1; - } - } - } - - return (Result); -} - - -#define FILERUN_FILENAMELINE TEXTLINE_4 -#define FILERUN_TEXTLINE TEXTLINE_5 - -UBYTE cUiFileRun(UBYTE Action) // Run selected file -{ - switch (Action) - { - - case MENU_INIT : - { - VarsUi.Tmp = 0; - while ((VarsUi.SelectedFilename[VarsUi.Tmp]) && (VarsUi.Tmp < FILENAME_LENGTH)) // Search forward for termination - { - VarsUi.Tmp++; - } - - while ((VarsUi.Tmp) && (VarsUi.SelectedFilename[VarsUi.Tmp] != '.')) // Search backward for "." - { - VarsUi.Tmp--; - } - - if (VarsUi.Tmp > DISPLAYLINE_LENGTH) - { - VarsUi.Tmp = DISPLAYLINE_LENGTH; - } - - VarsUi.DisplayBuffer[VarsUi.Tmp] = 0; - - while (VarsUi.Tmp) // Copy only name not ext - { - VarsUi.Tmp--; - VarsUi.DisplayBuffer[VarsUi.Tmp] = VarsUi.SelectedFilename[VarsUi.Tmp]; - } - - pMapDisplay->pTextLines[FILERUN_FILENAMELINE] = (UBYTE*)VarsUi.DisplayBuffer; - pMapDisplay->TextLinesCenterFlags = TEXTLINE_BIT(FILERUN_FILENAMELINE); - pMapDisplay->UpdateMask = TEXTLINE_BIT(FILERUN_FILENAMELINE); - } - break; - - case MENU_RUN : - { - if (VarsUi.Timer < DISPLAY_SHOW_TIME) - { - VarsUi.Timer++; - } - - switch (VarsUi.State) - { - case 0 : - { - IOMapUi.Flags |= UI_BUSY; - VarsUi.State++; - } - break; - - case 1 : // Set state from extention when sound is ready - { - if (SOUND_IDLE == pMapSound->State) - { - pMapDisplay->pTextLines[FILERUN_TEXTLINE] = cUiGetString(TXT_FILERUN_RUNNING); - pMapDisplay->UpdateMask = (TEXTLINE_BIT(FILERUN_TEXTLINE) | TEXTLINE_BIT(FILERUN_FILENAMELINE)); - pMapDisplay->TextLinesCenterFlags = (TEXTLINE_BIT(FILERUN_TEXTLINE) | TEXTLINE_BIT(FILERUN_FILENAMELINE)); - cUiRunning(MENU_INIT); - VarsUi.State++; - } - } - break; - - case 2 : - { - if ((!pMapDisplay->EraseMask) && (!pMapDisplay->UpdateMask)) - { - VarsUi.State = 10 * cUiFindFileType(VarsUi.SelectedFilename); - if (VarsUi.State == (FILETYPE_TRYME * 10)) - { - VarsUi.State = FILETYPE_LMS * 10; - } - } - } - break; - - case (FILETYPE_SOUND * 10 + 0) : // Start sound file (*.snd, *.rso) Wait for sound idle - { - strcpy((char*)pMapSound->SoundFilename,(char*)VarsUi.SelectedFilename); - pMapSound->Volume = IOMapUi.Volume; - pMapSound->Mode = SOUND_ONCE; - pMapSound->Flags |= SOUND_UPDATE; - VarsUi.State++; - } - break; - - case (FILETYPE_SOUND * 10 + 1) : // Wait for stop or user break - { - cUiRunning(MENU_RUN); - - if (SOUND_IDLE == pMapSound->State) - { - pMapDisplay->pTextLines[FILERUN_TEXTLINE] = cUiGetString(TXT_FILERUN_ENDED); - VarsUi.State = 99; - } - if (BUTTON_EXIT == cUiReadButtons()) - { - pMapSound->Flags &= ~SOUND_UPDATE; - pMapSound->State = SOUND_STOP; - pMapDisplay->pTextLines[FILERUN_TEXTLINE] = cUiGetString(TXT_FILERUN_ABORTED); - VarsUi.State = 99; - } - } - break; - - case (FILETYPE_LMS * 10 + 0) : // Start LMS file (*.rxe) - { - if ((!pMapDisplay->EraseMask) && (pMapCmd->ProgStatus == PROG_IDLE) && (!pMapButton->State[BTN4])) - { - strcpy((char*)pMapCmd->FileName,(char*)VarsUi.SelectedFilename); - pMapCmd->ActivateFlag = TRUE; - VarsUi.State++; - } - } - break; - - case (FILETYPE_LMS * 10 + 1) : // Wait for program stop or user break - { - cUiRunning(MENU_RUN); - - if ((IOMapUi.Flags & UI_REDRAW_STATUS) && (IOMapUi.Flags & UI_ENABLE_STATUS_UPDATE)) - { - pMapDisplay->pTextLines[FILERUN_FILENAMELINE] = (UBYTE*)VarsUi.DisplayBuffer; - pMapDisplay->TextLinesCenterFlags = TEXTLINE_BIT(FILERUN_FILENAMELINE); - pMapDisplay->UpdateMask = TEXTLINE_BIT(FILERUN_FILENAMELINE); - pMapDisplay->pTextLines[FILERUN_TEXTLINE] = cUiGetString(TXT_FILERUN_RUNNING); - pMapDisplay->UpdateMask = (TEXTLINE_BIT(FILERUN_TEXTLINE) | TEXTLINE_BIT(FILERUN_FILENAMELINE)); - pMapDisplay->TextLinesCenterFlags = (TEXTLINE_BIT(FILERUN_TEXTLINE) | TEXTLINE_BIT(FILERUN_FILENAMELINE)); - } - - switch (pMapCmd->ProgStatus) - { - case PROG_RUNNING : - { - } - break; - - case PROG_OK : - { - pMapDisplay->pTextLines[FILERUN_TEXTLINE] = cUiGetString(TXT_FILERUN_ENDED); - VarsUi.State = 99; - } - break; - - case PROG_ABORT : - { - pMapDisplay->pTextLines[FILERUN_TEXTLINE] = cUiGetString(TXT_FILERUN_ABORTED); - VarsUi.State = 99; - } - break; - - default : - { - pMapDisplay->pTextLines[FILERUN_TEXTLINE] = cUiGetString(TXT_FILERUN_FILE_ERROR); - VarsUi.State = 99; - } - break; - - } - } - break; - - case (FILETYPE_NXT * 10 + 0) :// Start Program file (*.prg) - { - VarsUi.TmpHandle = pMapLoader->pFunc(OPENREAD,VarsUi.SelectedFilename,NULL,&VarsUi.TmpLength); - if (!(VarsUi.TmpHandle & 0x8000)) - { - VarsUi.TmpLength = FILEHEADER_LENGTH; - pMapLoader->pFunc(READ,(UBYTE*)&VarsUi.TmpHandle,VarsUi.FileHeader,&VarsUi.TmpLength); - VarsUi.TmpLength = ON_BRICK_PROGRAMSTEPS; - pMapLoader->pFunc(READ,(UBYTE*)&VarsUi.TmpHandle,VarsUi.ProgramSteps,&VarsUi.TmpLength); - pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.TmpHandle,NULL,NULL); - } - if ((ON_BRICK_PROGRAMSTEPS == VarsUi.TmpLength) && (VarsUi.FileHeader[0] == (UBYTE)(FILEFORMAT_PROGRAM >> 8)) && (VarsUi.FileHeader[1] == (UBYTE)(FILEFORMAT_PROGRAM))) - { - // If tmp file exist -> delete it - sprintf((char*)VarsUi.FilenameBuffer,"%s.%s",(char*)TEMP_PROGRAM_FILENAME,(char*)TXT_TMP_EXT); - VarsUi.TmpHandle = pMapLoader->pFunc(FINDFIRST,VarsUi.FilenameBuffer,VarsUi.SearchFilenameBuffer,&VarsUi.TmpLength); - if (!(VarsUi.TmpHandle & 0x8000)) - { - pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.TmpHandle,NULL,NULL); - pMapLoader->pFunc(DELETE,VarsUi.FilenameBuffer,NULL,NULL); - } - - // Save program as tmp file - VarsUi.TmpLength = FILEHEADER_LENGTH + ON_BRICK_PROGRAMSTEPS; - VarsUi.TmpHandle = pMapLoader->pFunc(OPENWRITE,VarsUi.FilenameBuffer,NULL,&VarsUi.TmpLength); - if (!(VarsUi.TmpHandle & 0x8000)) - { - VarsUi.TmpLength = FILEHEADER_LENGTH; - pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)VarsUi.FileHeader,&VarsUi.TmpLength); - VarsUi.TmpLength = ON_BRICK_PROGRAMSTEPS; - pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)VarsUi.ProgramSteps,&VarsUi.TmpLength); - pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.TmpHandle,NULL,NULL); - } - - pMapDisplay->UpdateMask &= ~TEXTLINE_BIT(FILERUN_FILENAMELINE); - pMapDisplay->EraseMask |= TEXTLINE_BIT(FILERUN_FILENAMELINE); - VarsUi.State++; - } - else - { - pMapDisplay->pTextLines[FILERUN_TEXTLINE] = cUiGetString(TXT_FILERUN_FILE_ERROR); - VarsUi.State = 99; - } - VarsUi.GUSState = 0; - } - break; - - case (FILETYPE_NXT * 10 + 1) : // Wait for program stop or user break - { - VarsUi.State = VarsUi.GUSState; - cUiOnBrickProgramming(MENU_RUN); - VarsUi.GUSState = VarsUi.State; - if (VarsUi.State) - { - VarsUi.State = (FILETYPE_NXT * 10 + 1); - } - else - { - pMapDisplay->pTextLines[FILERUN_TEXTLINE] = cUiGetString(TXT_FILERUN_ENDED); - VarsUi.State = 99; - } - } - break; - - case 99 : // Wait for display show time or user action - { - pMapDisplay->EraseMask = SCREEN_BIT(SCREEN_LARGE); - pMapDisplay->UpdateMask = (TEXTLINE_BIT(FILERUN_TEXTLINE) | TEXTLINE_BIT(FILERUN_FILENAMELINE)); - pMapDisplay->TextLinesCenterFlags = (TEXTLINE_BIT(FILERUN_TEXTLINE) | TEXTLINE_BIT(FILERUN_FILENAMELINE)); - IOMapUi.Flags |= UI_REDRAW_STATUS | UI_ENABLE_STATUS_UPDATE; - cUiRunning(MENU_UPDATE); - VarsUi.Timer = 0; - VarsUi.State++; - } - break; - - default : - { - if ((++VarsUi.Timer >= DISPLAY_SHOW_TIME) || (BUTTON_NONE != cUiReadButtons())) - { - if (pMapCmd->ProgStatus != PROG_IDLE) - pMapCmd->ProgStatus = PROG_RESET; - pMapDisplay->UpdateMask = 0; - pMapDisplay->TextLinesCenterFlags = 0; - cUiRunning(MENU_EXIT); - pMapDisplay->EraseMask = TEXTLINE_BIT(FILERUN_TEXTLINE); - pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(FILERUN_FILENAMELINE); - pMapDisplay->UpdateMask |= TEXTLINE_BIT(FILERUN_FILENAMELINE); - IOMapUi.Flags &= ~UI_BUSY; - VarsUi.State = 0; - } - } - break; - - } - } - break; - - } - - return (VarsUi.State); -} - - - -//******* cUiFileDelete ******************************************************* - -UBYTE cUiFileDelete(UBYTE Action) -{ - if (MENU_INIT == Action) - { - switch (VarsUi.State) - { - case 0 : - { - VarsUi.State++; - } - break; - - case 1 : - { - if (SOUND_IDLE == pMapSound->State) - { - VarsUi.State++; - } - } - break; - - case 2 : - { - pMapLoader->pFunc(DELETE,VarsUi.SelectedFilename,NULL,NULL); - VarsUi.State++; - } - break; - - default : // Display deleted text - { - if (!cUiFeedback((BMPMAP*)Info,TXT_FB_FD_FILE_DELETED_INFO,0,DISPLAY_SHOW_TIME)) - { - IOMapUi.State = EXIT_PRESSED; - VarsUi.State = 0; - } - } - break; - - } - } - - return (VarsUi.State); -} - - -//******* cUiView ************************************************************ - -UBYTE cUiView(UBYTE Action) // MENU_INIT -{ - switch (VarsUi.State) - { - case 0 : - { - switch (Action) - { - case MENU_INIT : // Init - { - pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_VIEW_SELECT); - pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_3); - pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3); - pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_SMALL); -// Init ports - for (VarsUi.Tmp = 0;VarsUi.Tmp < DATALOGPORTS;VarsUi.Tmp++) - { - VarsUi.DatalogPort[VarsUi.Tmp] = MENU_SENSOR_EMPTY; - } - } - break; - - default : - { - if ((Action > MENU_SENSOR_EMPTY) && (Action < MENU_SENSOR_INVALID)) - { - VarsUi.SelectedSensor = Action; - } - if ((Action >= MENU_PORT_1) && (Action <= MENU_PORT_C)) - { - VarsUi.SelectedPort = Action; - - VarsUi.DatalogPort[VarsUi.SelectedPort - MENU_PORT_1] = VarsUi.SelectedSensor; - - IOMapUi.Flags |= UI_BUSY; - pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_LARGE); - pMapDisplay->pBitmaps[BITMAP_1] = (BMPMAP*)Display; - pMapDisplay->UpdateMask = BITMAP_BIT(BITMAP_1); - IOMapUi.Flags |= UI_REDRAW_STATUS; - VarsUi.ReadoutTimer = 0;; - VarsUi.State++; - - VarsUi.SensorReset = TRUE; - } - } - break; - - } - } - break; - - case 1 : - { - VarsUi.ReadoutTimer++; - cUiUpdateSensor(1); - if (VarsUi.ReadoutTimer >= DISPLAY_VIEW_UPDATE) - { - VarsUi.ReadoutTimer = 0; - cUiPrintSensorInDisplayBuffer(VarsUi.SelectedPort); - pMapDisplay->pTextLines[TEXTLINE_4] = VarsUi.DisplayBuffer; - pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_4); - pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_4); - } - - VarsUi.Tmp = cUiReadButtons(); - if (VarsUi.Tmp == BUTTON_EXIT) - { - pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_VIEW_SELECT); - pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_3); - pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3); - pMapDisplay->UpdateMask &= ~TEXTLINE_BIT(TEXTLINE_4); - pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_SMALL); - VarsUi.State++; - } - if (VarsUi.Tmp == BUTTON_ENTER) - { - VarsUi.SensorReset = TRUE; - } - } - break; - - default : - { - cUiReleaseSensors(); - IOMapUi.Flags &= ~UI_BUSY; - VarsUi.State = 0; - IOMapUi.State = EXIT_PRESSED; - } - break; - - } - - return (VarsUi.State); -} - - - -//******* cUiBtOn ************************************************************ - -UBYTE cUiBtOn(UBYTE Action) -{ - switch (Action) - { - case MENU_ON : - { - switch (VarsUi.State) - { - case 0 : // Turn BT on - { - VarsUi.BTCommand = (UBYTE)BTON; - VarsUi.BTPar1 = (UBYTE)0; - VarsUi.BTPar2 = (UBYTE)0; - if (pMapComm->pFunc(VarsUi.BTCommand,VarsUi.BTPar1,VarsUi.BTPar2,0,NULL,&(VarsUi.BTResult)) == SUCCESS) - { - VarsUi.State++; - } - else - { - VarsUi.State = 99; - } - } - break; - - case 1 : // Display turning on text - { - if (!cUiFeedback((BMPMAP*)Wait,TXT_FB_BT_TURNING_ON_WAIT,0,0)) - { - VarsUi.State++; - } - } - break; - - case 2 : // Check result - { - if (VarsUi.BTResult != INPROGRESS) - { - if (VarsUi.BTResult == SUCCESS) - { - Action = MENU_EXIT; - } - else - { - VarsUi.State++; - } - } - } - break; - - default : // Display fail text - { - if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_BT_TURNING_ON_FAIL,0,DISPLAY_SHOW_ERROR_TIME)) - { - Action = MENU_EXIT; - } - } - break; - - } - } - break; - - case MENU_OFF : - { - switch (VarsUi.State) - { - case 0 : // Turn BT off - { - VarsUi.BTCommand = (UBYTE)BTOFF; - VarsUi.BTPar1 = (UBYTE)0; - VarsUi.BTPar2 = (UBYTE)0; - if (pMapComm->pFunc(VarsUi.BTCommand,VarsUi.BTPar1,VarsUi.BTPar2,0,NULL,&(VarsUi.BTResult)) == SUCCESS) - { - VarsUi.State++; - } - else - { - VarsUi.State = 99; - } - } - break; - - case 1 : // Display turning off text - { - if (!cUiFeedback((BMPMAP*)Wait,TXT_FB_BT_TURNING_OFF_WAIT,0,0)) - { - VarsUi.State++; - } - } - break; - - case 2 : // Check result - { - if (VarsUi.BTResult != INPROGRESS) - { - if (VarsUi.BTResult == SUCCESS) - { - Action = MENU_EXIT; - } - else - { - VarsUi.State++; - } - } - } - break; - - default : // Display fail text - { - if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_BT_TURNING_OFF_FAIL,0,DISPLAY_SHOW_ERROR_TIME)) - { - Action = MENU_EXIT; - } - } - break; - - } - } - break; - - } - if (Action == MENU_EXIT) - { - VarsUi.State = 0; - IOMapUi.State = EXIT_PRESSED; - } - - return (VarsUi.State); -} - - - -//******* cUiBtVisiability *************************************************** - -UBYTE cUiBtVisiability(UBYTE Action) // Visibility on/off -{ - switch (Action) - { - case MENU_ON : // Set visible - { - switch (VarsUi.State) - { - case 0 : - { - VarsUi.BTCommand = (UBYTE)VISIBILITY; - VarsUi.BTPar1 = (UBYTE)1; - VarsUi.BTPar2 = (UBYTE)0; - if (pMapComm->pFunc(VarsUi.BTCommand,VarsUi.BTPar1,VarsUi.BTPar2,0,NULL,&(VarsUi.BTResult)) == SUCCESS) - { - VarsUi.State++; - } - else - { - Action = MENU_EXIT; - } - } - break; - - default : - { - if (VarsUi.BTResult != INPROGRESS) - { - Action = MENU_EXIT; - } - } - break; - - } - } - break; - - case MENU_OFF : // Set invisible - { - switch (VarsUi.State) - { - case 0 : - { - VarsUi.BTCommand = (UBYTE)VISIBILITY; - VarsUi.BTPar1 = (UBYTE)0; - VarsUi.BTPar2 = (UBYTE)0; - if (pMapComm->pFunc(VarsUi.BTCommand,VarsUi.BTPar1,VarsUi.BTPar2,0,NULL,&(VarsUi.BTResult)) == SUCCESS) - { - VarsUi.State++; - } - else - { - Action = MENU_EXIT; - } - } - break; - - default : - { - if (VarsUi.BTResult != INPROGRESS) - { - Action = MENU_EXIT; - } - } - break; - - } - } - break; - - } - if (Action == MENU_EXIT) - { - VarsUi.State = 0; - IOMapUi.State = EXIT_PRESSED; - } - - return (VarsUi.State); -} - - - -//******* cUiBtSearch ******************************************************** - -UBYTE cUiBtSearch(UBYTE Action) // Search for devices -{ - if (Action == MENU_INIT) // Init - { - switch (VarsUi.State) - { - case 0 : // Show three menu icons - { - pMapDisplay->pMenuIcons[MENUICON_LEFT] = pMapDisplay->pMenuIcons[MENUICON_CENTER]; - pMapDisplay->pMenuIcons[MENUICON_RIGHT] = pMapDisplay->pMenuIcons[MENUICON_CENTER]; - pMapDisplay->UpdateMask |= MENUICON_BITS; - VarsUi.State++; - } - break; - - case 1 : // Display wait text and start search - { - if (!cUiFeedback((BMPMAP*)Wait,TXT_FB_BT_SEARCHING_WAIT,0,0)) - { - VarsUi.BTCommand = (UBYTE)SEARCH; - VarsUi.BTPar1 = (UBYTE)1; - VarsUi.BTPar2 = (UBYTE)0; - if (pMapComm->pFunc(VarsUi.BTCommand,VarsUi.BTPar1,VarsUi.BTPar2,0,NULL,&(VarsUi.BTResult)) == SUCCESS) - { - VarsUi.DisplayBuffer[0] = 0; - pMapDisplay->pMenuText = VarsUi.DisplayBuffer; - pMapDisplay->UpdateMask |= SPECIAL_BIT(MENUTEXT); - VarsUi.NoOfNames = 0; - VarsUi.NoOfDevices = 0; - VarsUi.State++; - } - else - { - VarsUi.State = 99; - } - } - } - break; - - case 2 : // Wait for search finished - { - if (VarsUi.NoOfNames != pMapComm->BtDeviceNameCnt) - { - VarsUi.NoOfNames = pMapComm->BtDeviceNameCnt; - - if ((VarsUi.NoOfNames) && (VarsUi.NoOfNames <= DISPLAYLINE_LENGTH)) - { - sprintf((char*)VarsUi.DisplayBuffer,"%.*s",VarsUi.NoOfNames,"****************"); - pMapDisplay->pMenuText = VarsUi.DisplayBuffer; - pMapDisplay->UpdateMask |= SPECIAL_BIT(MENUTEXT); - } - } - if (VarsUi.NoOfDevices != pMapComm->BtDeviceCnt) - { - VarsUi.NoOfDevices = pMapComm->BtDeviceCnt; - - if ((VarsUi.NoOfDevices) && (VarsUi.NoOfDevices <= DISPLAYLINE_LENGTH)) - { - sprintf((char*)VarsUi.DisplayBuffer,"%.*s",VarsUi.NoOfDevices,"????????????????"); - pMapDisplay->pMenuText = VarsUi.DisplayBuffer; - pMapDisplay->UpdateMask |= SPECIAL_BIT(MENUTEXT); - } - } - - if (VarsUi.BTResult != INPROGRESS) - { - cUiBTCommand(UI_BT_GET_DEVICES,0,&VarsUi.Devices,NULL); - if (VarsUi.Devices) - { - VarsUi.State++; - } - else - { - VarsUi.State = 99; - } - } - - if (cUiReadButtons() == BUTTON_EXIT) - { - VarsUi.BTCommand = (UBYTE)STOPSEARCH; - VarsUi.BTPar1 = (UBYTE)0; - VarsUi.BTPar2 = (UBYTE)0; - pMapComm->pFunc(VarsUi.BTCommand,VarsUi.BTPar1,VarsUi.BTPar2,0,NULL,&(VarsUi.BTResult)); - VarsUi.State = 4; - } - } - break; - - case 3 : // Auto enter to next menu - { - IOMapUi.State = ENTER_PRESSED; - VarsUi.State = 0; - } - break; - - case 4 : // Display info text - { - if (!cUiFeedback((BMPMAP*)Info,TXT_FB_BT_SEARCH_ABORTED_INFO,0,DISPLAY_SHOW_TIME)) - { - VarsUi.State++; - } - } - break; - - case 5 : // Wait for abort - { - if (VarsUi.BTResult != INPROGRESS) - { - cUiBTCommand(UI_BT_GET_DEVICES,0,&VarsUi.Devices,NULL); - if (VarsUi.Devices) - { - VarsUi.State++; - } - else - { - VarsUi.State = 99; - } - } - } - break; - - case 6 : // Auto enter to next menu - { - IOMapUi.State = ENTER_PRESSED; - VarsUi.State = 0; - } - break; - - default : // Display fail text - { - if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_BT_SEARCHING_FAIL,0,DISPLAY_SHOW_ERROR_TIME)) - { - VarsUi.State = 0; - IOMapUi.State = EXIT_PRESSED; - } - } - break; - - } - } - - return (VarsUi.State); -} - - - -//******* cUiBtDeviceList **************************************************** - -UBYTE cUiBtDeviceList(UBYTE Action) // Show devices -{ - switch (Action) - { - case MENU_INIT : // Init "Search" list - { - VarsUi.SelectedDevice = 0; - VarsUi.DevicesKnown = 0; - cUiBTCommand(UI_BT_GET_DEVICES,VarsUi.DevicesKnown,&VarsUi.Devices,NULL); - if (VarsUi.Devices) - { - pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_BTDEVICELIST_SELECT); - pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_3); - pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3); - VarsUi.MenuIconTextSave = pMapDisplay->pMenuText; - VarsUi.DeviceCenter = 1; - Action = MENU_DRAW; - IOMapUi.State = TEST_BUTTONS; - } - else - { - Action = MENU_EXIT; - } - } - break; - - case MENU_INIT_ALTERNATIVE : // Init only "My contacts" - { - VarsUi.SelectedDevice = 0; - VarsUi.DevicesKnown = 1; - cUiBTCommand(UI_BT_GET_DEVICES,VarsUi.DevicesKnown,&VarsUi.Devices,NULL); - if (VarsUi.Devices) - { - pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_BTDEVICELIST_SELECT); - pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_3); - pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3); - VarsUi.MenuIconTextSave = pMapDisplay->pMenuText; - VarsUi.DeviceCenter = 1; - Action = MENU_DRAW; - IOMapUi.State = TEST_BUTTONS; - } - else - { - Action = MENU_EXIT; - } - } - break; - - case MENU_LEFT : // Left button - { - cUiListLeft(VarsUi.Devices,&VarsUi.DeviceCenter); - Action = MENU_DRAW; - IOMapUi.State = TEST_BUTTONS; - } - break; - - case MENU_RIGHT : // Right button - { - cUiListRight(VarsUi.Devices,&VarsUi.DeviceCenter); - Action = MENU_DRAW; - IOMapUi.State = TEST_BUTTONS; - } - break; - - case MENU_SELECT : // Select for connection - { - VarsUi.SelectedDevice = VarsUi.DeviceCenter; - pMapDisplay->pMenuText = VarsUi.MenuIconTextSave; - IOMapUi.State = NEXT_MENU; - } - break; - - case MENU_DELETE : // Remove device from "My contacts" - { - switch (VarsUi.State) - { - case 0 : - { - if (VarsUi.SelectedDevice) - { - if (cUiBTGetDeviceIndex(VarsUi.DevicesKnown,VarsUi.SelectedDevice - 1,&VarsUi.BTIndex)) - { - VarsUi.BTCommand = (UBYTE)REMOVEDEVICE; - VarsUi.BTPar1 = (UBYTE)VarsUi.BTIndex; - VarsUi.BTPar2 = (UBYTE)0; - if (pMapComm->pFunc(VarsUi.BTCommand,VarsUi.BTPar1,VarsUi.BTPar2,0,NULL,&(VarsUi.BTResult)) == SUCCESS) - { - VarsUi.State++; - } - else - { - VarsUi.State = 99; - } - } - else - { - Action = MENU_EXIT; - } - VarsUi.SelectedDevice = 0; - } - else - { - Action = MENU_EXIT; - } - } - break; - - case 1 : - { - if (VarsUi.BTResult != INPROGRESS) - { - if (VarsUi.BTResult == SUCCESS) - { - Action = MENU_EXIT; - } - else - { - VarsUi.State = 99; - } - } - } - break; - - default : // Display fail text - { - if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_BT_REMOVE_FAIL,0,DISPLAY_SHOW_ERROR_TIME)) - { - Action = MENU_EXIT; - } - } - break; - - } - } - break; - - } - - if (Action == MENU_DRAW) - { - cUiListCalc(VarsUi.Devices,&VarsUi.DeviceCenter,&VarsUi.DeviceLeft,&VarsUi.DeviceRight); - - pMapDisplay->pMenuIcons[MENUICON_LEFT] = NULL; - pMapDisplay->pMenuIcons[MENUICON_CENTER] = NULL; - pMapDisplay->pMenuIcons[MENUICON_RIGHT] = NULL; - - if (VarsUi.DeviceLeft) - { - VarsUi.Tmp = VarsUi.DeviceLeft - 1; - cUiBTCommand(UI_BT_GET_DEVICE_TYPE,VarsUi.DevicesKnown,&VarsUi.Tmp,&VarsUi.DeviceType); - pMapDisplay->pMenuIcons[MENUICON_LEFT] = (UBYTE*)&Devices->Data[VarsUi.DeviceType * Devices->ItemPixelsX * (Devices->ItemPixelsY / 8)]; - pMapDisplay->UpdateMask |= MENUICON_BIT(MENUICON_LEFT); - } - if (VarsUi.DeviceCenter) - { - VarsUi.Tmp = VarsUi.DeviceCenter - 1; - cUiBTCommand(UI_BT_GET_DEVICE_TYPE,VarsUi.DevicesKnown,&VarsUi.Tmp,&VarsUi.DeviceType); - pMapDisplay->pMenuIcons[MENUICON_CENTER] = (UBYTE*)&Devices->Data[VarsUi.DeviceType * Devices->ItemPixelsX * (Devices->ItemPixelsY / 8)]; - pMapDisplay->UpdateMask |= MENUICON_BIT(MENUICON_CENTER); - } - if (VarsUi.DeviceRight) - { - VarsUi.Tmp = VarsUi.DeviceRight - 1; - cUiBTCommand(UI_BT_GET_DEVICE_TYPE,VarsUi.DevicesKnown,&VarsUi.Tmp,&VarsUi.DeviceType); - pMapDisplay->pMenuIcons[MENUICON_RIGHT] = (UBYTE*)&Devices->Data[VarsUi.DeviceType * Devices->ItemPixelsX * (Devices->ItemPixelsY / 8)]; - pMapDisplay->UpdateMask |= MENUICON_BIT(MENUICON_RIGHT); - } - - pMapDisplay->EraseMask |= TEXTLINE_BIT(TEXTLINE_5); - - VarsUi.Tmp = VarsUi.DeviceCenter - 1; - cUiBTCommand(UI_BT_GET_DEVICE_NAME,VarsUi.DevicesKnown,&VarsUi.Tmp,VarsUi.DisplayBuffer); - - pMapDisplay->pMenuText = VarsUi.DisplayBuffer; - pMapDisplay->EraseMask |= MENUICON_BITS; - pMapDisplay->UpdateMask |= (SPECIAL_BIT(FRAME_SELECT) | SPECIAL_BIT(MENUTEXT)); - } - if (Action == MENU_EXIT) - { - VarsUi.State = 0; - IOMapUi.State = EXIT_PRESSED; - } - - return (VarsUi.State); -} - - -//******* cUiBtConnectList *************************************************** - -UBYTE cUiBtConnectList(UBYTE Action) // Show connections and maybe disconnect -{ - switch (Action) - { - case MENU_INIT : // Init - { - VarsUi.Slots = SIZE_OF_BT_CONNECT_TABLE; - VarsUi.SlotCenter = 2; - Action = MENU_DRAW; - IOMapUi.State = TEST_BUTTONS; - } - break; - - case MENU_LEFT : // Left button - { - cUiListLeft(VarsUi.Slots,&VarsUi.SlotCenter); - Action = MENU_DRAW; - IOMapUi.State = TEST_BUTTONS; - } - break; - - case MENU_RIGHT : // Right button - { - cUiListRight(VarsUi.Slots,&VarsUi.SlotCenter); - Action = MENU_DRAW; - IOMapUi.State = TEST_BUTTONS; - } - break; - - case MENU_UPDATE : // Check connection valid - { - VarsUi.Tmp = VarsUi.SlotCenter - 1; - if (cUiBTCommand(UI_BT_GET_CONNECTION_VALID,NULL,&VarsUi.Tmp,NULL) != UI_BT_SUCCES) - { - Action = MENU_EXIT; - } - } - break; - - case MENU_DISCONNECT : // Disconnect - { - switch (VarsUi.State) - { - case 0 : - { - VarsUi.SelectedSlot = VarsUi.SlotCenter - 1; - VarsUi.BTCommand = (UBYTE)DISCONNECT; - VarsUi.BTPar1 = (UBYTE)VarsUi.SelectedSlot; - VarsUi.BTPar2 = (UBYTE)0; - if (pMapComm->pFunc(VarsUi.BTCommand,VarsUi.BTPar1,VarsUi.BTPar2,0,NULL,&(VarsUi.BTResult)) == SUCCESS) - { - VarsUi.State++; - } - else - { - VarsUi.State = 99; - } - } - break; - - case 1 : - { - if (VarsUi.BTResult != INPROGRESS) - { - if (VarsUi.BTResult == SUCCESS) - { - Action = MENU_EXIT; - } - else - { - VarsUi.State = 99; - } - } - } - break; - - default : // Display fail text - { - if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_BT_DISCONNECT_FAIL,0,DISPLAY_SHOW_ERROR_TIME)) - { - Action = MENU_EXIT; - } - } - break; - - } - } - break; - - } - if (Action == MENU_DRAW) - { - cUiListCalc(VarsUi.Slots,&VarsUi.SlotCenter,&VarsUi.SlotLeft,&VarsUi.SlotRight); - - pMapDisplay->pBitmaps[BITMAP_2] = (BMPMAP*)VarsUi.PortBitmapLeft; - pMapDisplay->pBitmaps[BITMAP_3] = (BMPMAP*)VarsUi.PortBitmapCenter; - pMapDisplay->pBitmaps[BITMAP_4] = (BMPMAP*)VarsUi.PortBitmapRight; - - VarsUi.Tmp = VarsUi.SlotLeft - 1; - if (cUiBTCommand(UI_BT_GET_CONNECTION_VALID,NULL,&VarsUi.Tmp,NULL) == UI_BT_SUCCES) - { - cUiBTCommand(UI_BT_GET_CONNECTION_TYPE,NULL,&VarsUi.Tmp,&VarsUi.DeviceType); - pMapDisplay->pMenuIcons[MENUICON_LEFT] = (UBYTE*)&Devices->Data[VarsUi.DeviceType * Devices->ItemPixelsX * (Devices->ItemPixelsY / 8)]; - cUiDrawPortNo(VarsUi.PortBitmapLeft,MENUICON_LEFT,VarsUi.Tmp); - pMapDisplay->UpdateMask |= BITMAP_BIT(BITMAP_2); - } - else - { - pMapDisplay->pMenuIcons[MENUICON_LEFT] = (UBYTE*)&Connections->Data[VarsUi.Tmp * Connections->ItemPixelsX * (Connections->ItemPixelsY / 8)]; - } - - VarsUi.Tmp = VarsUi.SlotCenter - 1; - cUiBTCommand(UI_BT_GET_CONNECTION_NAME,NULL,&VarsUi.Tmp,VarsUi.DisplayBuffer); - pMapDisplay->EraseMask |= TEXTLINE_BIT(TEXTLINE_5); - pMapDisplay->pMenuText = VarsUi.DisplayBuffer; - - if (cUiBTCommand(UI_BT_GET_CONNECTION_VALID,NULL,&VarsUi.Tmp,NULL) == UI_BT_SUCCES) - { - cUiBTCommand(UI_BT_GET_CONNECTION_TYPE,NULL,&VarsUi.Tmp,&VarsUi.DeviceType); - pMapDisplay->pMenuIcons[MENUICON_CENTER] = (UBYTE*)&Devices->Data[VarsUi.DeviceType * Devices->ItemPixelsX * (Devices->ItemPixelsY / 8)]; - cUiDrawPortNo(VarsUi.PortBitmapCenter,MENUICON_CENTER,VarsUi.Tmp); - pMapDisplay->UpdateMask |= BITMAP_BIT(BITMAP_3); - } - else - { - pMapDisplay->pMenuIcons[MENUICON_CENTER] = (UBYTE*)&Connections->Data[VarsUi.Tmp * Connections->ItemPixelsX * (Connections->ItemPixelsY / 8)]; - } - VarsUi.Tmp = VarsUi.SlotRight - 1; - if (cUiBTCommand(UI_BT_GET_CONNECTION_VALID,NULL,&VarsUi.Tmp,NULL) == UI_BT_SUCCES) - { - cUiBTCommand(UI_BT_GET_CONNECTION_TYPE,NULL,&VarsUi.Tmp,&VarsUi.DeviceType); - pMapDisplay->pMenuIcons[MENUICON_RIGHT] = (UBYTE*)&Devices->Data[VarsUi.DeviceType * Devices->ItemPixelsX * (Devices->ItemPixelsY / 8)]; - cUiDrawPortNo(VarsUi.PortBitmapRight,MENUICON_RIGHT,VarsUi.Tmp); - pMapDisplay->UpdateMask |= BITMAP_BIT(BITMAP_4); - } - else - { - pMapDisplay->pMenuIcons[MENUICON_RIGHT] = (UBYTE*)&Connections->Data[VarsUi.Tmp * Connections->ItemPixelsX * (Connections->ItemPixelsY / 8)]; - } - pMapDisplay->EraseMask &= ~SCREEN_BIT(SCREEN_LARGE); - pMapDisplay->EraseMask |= MENUICON_BITS; - pMapDisplay->UpdateMask |= (MENUICON_BITS | SPECIAL_BIT(FRAME_SELECT) | SPECIAL_BIT(MENUTEXT)); - } - if (Action == MENU_EXIT) - { - VarsUi.State = 0; - IOMapUi.State = EXIT_PRESSED; - } - - - return (VarsUi.State); -} - - -UBYTE cUiBtConnect(UBYTE Action) // Select connection no and insert device -{ - switch (Action) - { - case MENU_INIT : // Init - { - VarsUi.Slots = SIZE_OF_BT_CONNECT_TABLE - 1; - VarsUi.SlotCenter = 1; - Action = MENU_DRAW; - IOMapUi.State = TEST_BUTTONS; - } - break; - - case MENU_LEFT : // Left button - { - cUiListLeft(VarsUi.Slots,&VarsUi.SlotCenter); - Action = MENU_DRAW; - IOMapUi.State = TEST_BUTTONS; - } - break; - - case MENU_RIGHT : // Right button - { - cUiListRight(VarsUi.Slots,&VarsUi.SlotCenter); - Action = MENU_DRAW; - IOMapUi.State = TEST_BUTTONS; - } - break; - - case MENU_CONNECT : // Insert device - { - switch (VarsUi.State) - { - case 0 : // Check selected device - { - VarsUi.SelectedSlot = (UBYTE)VarsUi.SlotCenter; - if (VarsUi.SelectedDevice) - { - VarsUi.State++; - } - else - { - Action = MENU_EXIT; - } - } - break; - - case 1 : // Display wait text - { - if (!cUiFeedback((BMPMAP*)Wait,TXT_FB_BT_CONNECTING_WAIT,0,0)) - { - if (cUiBTGetDeviceIndex(VarsUi.DevicesKnown,VarsUi.SelectedDevice - 1,&VarsUi.BTIndex)) - { - VarsUi.BTCommand = (UBYTE)CONNECT; - VarsUi.BTPar1 = (UBYTE)VarsUi.BTIndex; - VarsUi.BTPar2 = (UBYTE)VarsUi.SelectedSlot; - if (pMapComm->pFunc(VarsUi.BTCommand,VarsUi.BTPar1,VarsUi.BTPar2,0,NULL,&(VarsUi.BTResult)) == SUCCESS) - { - VarsUi.State++; - } - else - { - VarsUi.State = 99; - } - } - else - { - VarsUi.State = 99; - } - } - } - break; - - case 2 : // Wait for result - { - if (VarsUi.BTResult != INPROGRESS) - { - if (VarsUi.BTResult == SUCCESS) - { - Action = MENU_EXIT; - } - else - { - if (VarsUi.BTResult == REQPIN) - { - sprintf((char*)pMapSound->SoundFilename,"%s.%s",(char*)UI_ATTENTION_SOUND,(char*)TXT_FILE_EXT[FILETYPE_SOUND]); - pMapSound->Volume = IOMapUi.Volume; - pMapSound->Mode = SOUND_ONCE; - pMapSound->Flags |= SOUND_UPDATE; - strcpy((char*)VarsUi.UserString,(char*)DEFAULT_PIN_CODE); - VarsUi.State++; - } - else - { - VarsUi.State = 6; - } - } - } - } - break; - - case 3 : // Get pincode and send - { - if (!cUiGetUserString(0)) - { - if (VarsUi.UserString[0] == 0) - { - sprintf((char*)VarsUi.UserString,"%08lX",VarsUi.CRPasskey); - Action = MENU_EXIT; - } - else - { - VarsUi.State++; - } - pMapComm->pFunc2(VarsUi.UserString); - } - } - break; - - case 4 : // Display wait text - { - if (!cUiFeedback((BMPMAP*)Wait,TXT_FB_BT_CONNECTING_WAIT,0,0)) - { - VarsUi.State++; - } - } - break; - - case 5 : // Wait for result - { - if (VarsUi.BTResult != INPROGRESS) - { - if (VarsUi.BTResult == SUCCESS) - { - Action = MENU_EXIT; - } - else - { - VarsUi.State = 6; - } - } - } - break; - - case 6 : // Display busy text - { - if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_BT_CONNECT_BUSY_FAIL,0,DISPLAY_SHOW_ERROR_TIME)) - { - Action = MENU_EXIT; - } - } - break; - - default : // Display fail text - { - if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_BT_CONNECTING_FAIL,0,DISPLAY_SHOW_ERROR_TIME)) - { - Action = MENU_EXIT; - } - } - break; - - } - } - break; - - case MENU_SEND : - { - switch (VarsUi.State) - { - case 0 : // Check connection - { - VarsUi.SelectedSlot = (UBYTE)VarsUi.SlotCenter; - if (VarsUi.SelectedFilename[0] && (cUiBTCommand(UI_BT_GET_CONNECTION_NAME,NULL,&VarsUi.SelectedSlot,NULL) == UI_BT_SUCCES)) - { - VarsUi.State += 2; - } - else - { - VarsUi.State++; - } - } - break; - - case 1 : // Display fail text - { - if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_BT_SENDING_NO_CONN_FAIL,0,DISPLAY_SHOW_ERROR_TIME)) - { - Action = MENU_EXIT; - } - } - break; - - case 2 : // Display wait text and send file - { - if (!cUiFeedback((BMPMAP*)Wait,TXT_FB_BT_SENDING_WAIT,0,0)) - { - VarsUi.BTCommand = (UBYTE)SENDFILE; - VarsUi.BTPar1 = (UBYTE)VarsUi.SelectedSlot; - VarsUi.BTPar2 = (UBYTE)0; - if (pMapComm->pFunc(VarsUi.BTCommand,VarsUi.BTPar1,VarsUi.BTPar2,0,VarsUi.SelectedFilename,&(VarsUi.BTResult)) == SUCCESS) - { - VarsUi.Timer = 0; - VarsUi.State++; - } - else - { - VarsUi.State = 4; - } - } - } - break; - - case 3 : // Wait for result - { - if (VarsUi.BTResult != INPROGRESS) - { - if (VarsUi.BTResult == SUCCESS) - { - VarsUi.State += 2; - } - else - { - VarsUi.State++; - } - } - VarsUi.Timer++; - } - break; - - case 4 : // Display fail text - { - if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_BT_SENDING_FAIL,0,DISPLAY_SHOW_ERROR_TIME)) - { - Action = MENU_EXIT; - } - } - break; - - case 5 : // Wait min. "DISPLAY_SHOW_TIME" to show "TXT_FB_BT_SENDING_WAIT" - { - if (++VarsUi.Timer >= DISPLAY_SHOW_TIME) - { - Action = MENU_EXIT; - } - } - break; - - } - } - break; - - } - if (Action == MENU_DRAW) // Update display - { - cUiListCalc(VarsUi.Slots,&VarsUi.SlotCenter,&VarsUi.SlotLeft,&VarsUi.SlotRight); - - pMapDisplay->pBitmaps[BITMAP_2] = (BMPMAP*)VarsUi.PortBitmapLeft; - pMapDisplay->pBitmaps[BITMAP_3] = (BMPMAP*)VarsUi.PortBitmapCenter; - pMapDisplay->pBitmaps[BITMAP_4] = (BMPMAP*)VarsUi.PortBitmapRight; - - VarsUi.Tmp = VarsUi.SlotLeft; - if (cUiBTCommand(UI_BT_GET_CONNECTION_VALID,NULL,&VarsUi.Tmp,NULL) == UI_BT_SUCCES) - { - cUiBTCommand(UI_BT_GET_CONNECTION_TYPE,NULL,&VarsUi.Tmp,&VarsUi.DeviceType); - pMapDisplay->pMenuIcons[MENUICON_LEFT] = (UBYTE*)&Devices->Data[VarsUi.DeviceType * Devices->ItemPixelsX * (Devices->ItemPixelsY / 8)]; - cUiDrawPortNo(VarsUi.PortBitmapLeft,MENUICON_LEFT,VarsUi.Tmp); - pMapDisplay->UpdateMask |= BITMAP_BIT(BITMAP_2); - } - else - { - pMapDisplay->pMenuIcons[MENUICON_LEFT] = (UBYTE*)&Connections->Data[VarsUi.Tmp * Connections->ItemPixelsX * (Connections->ItemPixelsY / 8)]; - } - - VarsUi.Tmp = VarsUi.SlotCenter; - cUiBTCommand(UI_BT_GET_CONNECTION_NAME,NULL,&VarsUi.Tmp,VarsUi.DisplayBuffer); - pMapDisplay->EraseMask |= TEXTLINE_BIT(TEXTLINE_5); - pMapDisplay->pMenuText = VarsUi.DisplayBuffer; - - if (cUiBTCommand(UI_BT_GET_CONNECTION_VALID,NULL,&VarsUi.Tmp,NULL) == UI_BT_SUCCES) - { - cUiBTCommand(UI_BT_GET_CONNECTION_TYPE,NULL,&VarsUi.Tmp,&VarsUi.DeviceType); - pMapDisplay->pMenuIcons[MENUICON_CENTER] = (UBYTE*)&Devices->Data[VarsUi.DeviceType * Devices->ItemPixelsX * (Devices->ItemPixelsY / 8)]; - cUiDrawPortNo(VarsUi.PortBitmapCenter,MENUICON_CENTER,VarsUi.Tmp); - pMapDisplay->UpdateMask |= BITMAP_BIT(BITMAP_3); - } - else - { - pMapDisplay->pMenuIcons[MENUICON_CENTER] = (UBYTE*)&Connections->Data[VarsUi.Tmp * Connections->ItemPixelsX * (Connections->ItemPixelsY / 8)]; - } - VarsUi.Tmp = VarsUi.SlotRight; - if (cUiBTCommand(UI_BT_GET_CONNECTION_VALID,NULL,&VarsUi.Tmp,NULL) == UI_BT_SUCCES) - { - cUiBTCommand(UI_BT_GET_CONNECTION_TYPE,NULL,&VarsUi.Tmp,&VarsUi.DeviceType); - pMapDisplay->pMenuIcons[MENUICON_RIGHT] = (UBYTE*)&Devices->Data[VarsUi.DeviceType * Devices->ItemPixelsX * (Devices->ItemPixelsY / 8)]; - cUiDrawPortNo(VarsUi.PortBitmapRight,MENUICON_RIGHT,VarsUi.Tmp); - pMapDisplay->UpdateMask |= BITMAP_BIT(BITMAP_4); - } - else - { - pMapDisplay->pMenuIcons[MENUICON_RIGHT] = (UBYTE*)&Connections->Data[VarsUi.Tmp * Connections->ItemPixelsX * (Connections->ItemPixelsY / 8)]; - } - pMapDisplay->EraseMask &= ~SCREEN_BIT(SCREEN_LARGE); - pMapDisplay->EraseMask |= MENUICON_BITS; - pMapDisplay->UpdateMask |= (MENUICON_BITS | SPECIAL_BIT(FRAME_SELECT) | SPECIAL_BIT(MENUTEXT)); - } - if (Action == MENU_EXIT) - { - IOMapUi.State = EXIT_PRESSED; - VarsUi.State = 0; - } - - return (VarsUi.State); -} - - - -//******* cUiPowerOffTime **************************************************** - -UBYTE cUiPowerOffTime(UBYTE Action) // MENU_INIT,MENU_LEFT,MENU_RIGHT,MENU_EXIT -{ - switch (Action) - { - case MENU_INIT : // Init time counter and cursor bitmap - { - VarsUi.Counter = VarsUi.NVData.PowerdownCode + 1; - - VarsUi.pTmp = (UBYTE*)Cursor; - for (VarsUi.Tmp = 0;(VarsUi.Tmp < SIZE_OF_CURSOR) && (VarsUi.Tmp < (UBYTE)SIZEOF_DATA(Cursor));VarsUi.Tmp++) - { - VarsUi.CursorTmp[VarsUi.Tmp] = *VarsUi.pTmp; - VarsUi.pTmp++; - } - Action = MENU_DRAW; - } - break; - - case MENU_LEFT : // Dec - { - cUiListLeft(POWER_OFF_TIME_STEPS,&VarsUi.Counter); - Action = MENU_DRAW; - } - break; - - case MENU_RIGHT : // Inc - { - cUiListRight(POWER_OFF_TIME_STEPS,&VarsUi.Counter); - Action = MENU_DRAW; - } - break; - - case MENU_ENTER : // Enter - { - VarsUi.NVData.PowerdownCode = VarsUi.Counter - 1; - cUiNVWrite(); - IOMapUi.SleepTimeout = PowerOffTimeSteps[VarsUi.NVData.PowerdownCode]; - Action = MENU_EXIT; - } - break; - - } - - if (Action == MENU_DRAW) - { - if (VarsUi.Counter > 1) - { - sprintf((char*)VarsUi.DisplayBuffer,"%u",(UWORD)PowerOffTimeSteps[VarsUi.Counter - 1]); - } - else - { - sprintf((char*)VarsUi.DisplayBuffer,(char*)cUiGetString(TXT_POWEROFFTIME_NEVER)); - } - pMapDisplay->pTextLines[TEXTLINE_3] = VarsUi.DisplayBuffer; - - pMapDisplay->pBitmaps[BITMAP_1] = (BMPMAP*)VarsUi.CursorTmp; - VarsUi.CursorTmp[4] = 46; - VarsUi.CursorTmp[5] = 24; - pMapDisplay->EraseMask |= (TEXTLINE_BIT(TEXTLINE_3) | TEXTLINE_BIT(TEXTLINE_4)); - pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_3); - pMapDisplay->UpdateMask |= (TEXTLINE_BIT(TEXTLINE_3) | BITMAP_BIT(BITMAP_1)); - } - if (Action == MENU_EXIT) - { - IOMapUi.State = EXIT_PRESSED; - } - - return (0); -} - - - -//******* cUiBTConnectRequest ************************************************ - -UBYTE cUiBTConnectRequest(UBYTE Action) -{ - switch (Action) - { - case MENU_INIT : - { - switch (VarsUi.CRState) - { - case 0 : - { - sprintf((char*)pMapSound->SoundFilename,"%s.%s",(char*)UI_ATTENTION_SOUND,(char*)TXT_FILE_EXT[FILETYPE_SOUND]); - pMapSound->Volume = IOMapUi.Volume; - pMapSound->Mode = SOUND_ONCE; - pMapSound->Flags |= SOUND_UPDATE; - VarsUi.CRState++; - } - break; - - case 1 : - { - if (DISPLAY_IDLE) - { - pMapDisplay->Flags |= DISPLAY_POPUP; - VarsUi.CRState++; - } - } - break; - - case 2 : - { - strcpy((char*)VarsUi.UserString,(char*)DEFAULT_PIN_CODE); - IOMapUi.Flags |= UI_REDRAW_STATUS; - VarsUi.CRState++; - } - break; - - case 3 : // Get pincode and send - { - if (!cUiGetUserString(0)) - { - if (VarsUi.UserString[0] == 0) - { - sprintf((char*)VarsUi.UserString,"%08lX",VarsUi.CRPasskey); - } - pMapComm->pFunc2(VarsUi.UserString); - VarsUi.CRState++; - } - } - break; - - case 4 : - { - if (DISPLAY_IDLE) - { - pMapDisplay->Flags &= ~DISPLAY_POPUP; - VarsUi.CRState = 0; - } - } - break; - - } - } - break; - - } - - return (VarsUi.CRState); -} - - - -//******* cUiFilesDelete ***************************************************** - -UBYTE cUiFilesDelete(UBYTE Action) -{ - switch (Action) - { - case MENU_INIT : - { - pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_FILESDELETE_DELETING_ALL); - pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_3); - pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3); - sprintf((char*)VarsUi.DisplayBuffer,(char*)cUiGetString(TXT_FILESDELETE_S_FILES),(char*)cUiGetString(TXT_FILETYPE[VarsUi.SelectedType])); - pMapDisplay->pTextLines[TEXTLINE_4] = VarsUi.DisplayBuffer; - pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_4); - pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_4); - IOMapUi.State = TEST_BUTTONS; - } - break; - - case MENU_DELETE : - { - switch (VarsUi.State) - { - case 0 : - { - if (VarsUi.SelectedType < FILETYPES) - { - sprintf((char*)VarsUi.FilenameBuffer,"*.%s",TXT_FILE_EXT[VarsUi.SelectedType]); - } - else - { - sprintf((char*)VarsUi.FilenameBuffer,"*.*"); - } - VarsUi.State++; - } - break; - - case 1 : - { - if (SOUND_IDLE == pMapSound->State) - { - VarsUi.State++; - } - } - break; - - case 2 : // Delete files - { - VarsUi.TmpHandle = pMapLoader->pFunc(FINDFIRST,VarsUi.FilenameBuffer,VarsUi.SelectedFilename,&VarsUi.TmpLength); - if (!(VarsUi.TmpHandle & 0x8000)) - { - pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.TmpHandle,NULL,NULL); - pMapLoader->pFunc(DELETE,VarsUi.SelectedFilename,NULL,NULL); - } - else - { - pMapDisplay->EraseMask |= MENUICON_BITS; - pMapDisplay->EraseMask |= SPECIAL_BIT(MENUTEXT); - VarsUi.State++; - } - } - break; - - default : // Display Files deleted text - { - if (!cUiFeedback((BMPMAP*)Info,TXT_FB_FD_FILES_INFO,TXT_FB_FD_DELETED_INFO,DISPLAY_SHOW_TIME)) - { - IOMapUi.State = EXIT_PRESSED; - VarsUi.State = 0; - } - } - break; - - } - } - break; - - default : - { - if (Action < FILETYPES) - { - VarsUi.SelectedType = Action; - } - else - { - VarsUi.SelectedType = FILETYPE_ALL; - } - } - break; - - } - - return (VarsUi.State); -} - - -//******* cUiOff ************************************************************* - -UBYTE cUiOff(UBYTE Action) // Tell AVR to turn off ARM -{ - if (Action == MENU_INIT) - { - switch (VarsUi.State) - { - case 0 : // Stop VM if running - { - if (pMapCmd->ProgStatus == PROG_RUNNING) - { - pMapCmd->DeactivateFlag = TRUE; - } - VarsUi.State++; - } - break; - - case 1 : // When VM is stopped -> Display off and close all connections - { - if (pMapCmd->ProgStatus != PROG_RUNNING) - { - pMapDisplay->Flags &= ~DISPLAY_ON; - VarsUi.BTCommand = (UBYTE)DISCONNECTALL; - VarsUi.BTPar1 = (UBYTE)0; - VarsUi.BTPar2 = (UBYTE)0; - pMapComm->pFunc(VarsUi.BTCommand,VarsUi.BTPar1,VarsUi.BTPar2,0,NULL,&(VarsUi.BTResult)); - VarsUi.State++; - } - } - break; - - case 2 : // Send off command to AVR - { - if (VarsUi.BTResult != INPROGRESS) - { - pMapIoCtrl->PowerOn = POWERDOWN; - VarsUi.Timer = 0; - VarsUi.State++; - } - } - break; - - case 3 : // Wait for power off - { - if (++VarsUi.Timer >= ARM_WAIT_FOR_POWER_OFF) - { - VarsUi.State++; - } - } - break; - - case 4 : // Vitual off state (if still power) wait for on button - { - pMapIoCtrl->PowerOn = 0; - if (BUTTON_ENTER == cUiReadButtons()) - { - VarsUi.State++; - } - } - break; - - default : // Turn on again - { - IOMapUi.State = INIT_DISPLAY; - VarsUi.State = 0; - } - break; - - } - } - - return (VarsUi.State); -} - - - -//******* FUNCTIONS ********************************************************** - -enum FUNC_NO // Must reffer to entry in Functions -{ // used in Menus to repressent function - FUNC_NO_NOT_USED = 0x00, - FUNC_NO_TEST_PROGRAM = 0x01, - FUNC_NO_OFF = 0x02, - FUNC_NO_BT_ON = 0x03, - FUNC_NO_POWER_OFF_TIME = 0x04, - FUNC_NO_FILES_DELETE = 0x05, - FUNC_NO_FILE_LIST = 0x06, - FUNC_NO_VOLUME = 0x07, - FUNC_NO_FILE_RUN = 0x08, - FUNC_NO_FILE_DELETE = 0x09, - FUNC_NO_FREE1 = 0x0A, - FUNC_NO_ON_BRICK_PROGRAMMING = 0x0B, - FUNC_NO_FREE2 = 0x0C, - FUNC_NO_BT_CONNECT_REQUEST = 0x0D, - FUNC_NO_VIEW = 0x0E, - FUNC_NO_GET_USER_STRING = 0x0F, - FUNC_NO_BT_CONNECT = 0x10, - FUNC_NO_BT_VISIABILITY = 0x11, - FUNC_NO_BT_SEARCH = 0x12, - FUNC_NO_BT_DEVICE_LIST = 0x13, - FUNC_NO_BT_CONNECT_LIST = 0x14, - FUNC_NO_MAX -}; - -FUNCTION Functions[] = // Use same index as FUNC_NO -{ - 0, - TestPrg, - cUiOff, - cUiBtOn, - cUiPowerOffTime, - cUiFilesDelete, - cUiFileList, - cUiVolume, - cUiFileRun, - cUiFileDelete, - cUiDataLogging, - cUiOnBrickProgramming, - 0, - cUiBTConnectRequest, - cUiView, - cUiGetUserString, - cUiBtConnect, - cUiBtVisiability, - cUiBtSearch, - cUiBtDeviceList, - cUiBtConnectList -}; - - diff --git a/AT91SAM7S256/Source/Icons.txt b/AT91SAM7S256/Source/Icons.txt deleted file mode 100644 index 459b078..0000000 --- a/AT91SAM7S256/Source/Icons.txt +++ /dev/null @@ -1,293 +0,0 @@ -DEFINE_DATA(ICON, Icons) = -{ - 0x04,0x00, // Graphics Format - 0x1A,0x70, // Graphics DataSize - 0x01, // Graphics Count X - 0x5E, // Graphics Count Y - 0x18, // Graphics Width - 0x18, // Graphics Height -BEGIN_DATA - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xA0,0x50,0xB0,0x50,0xB0,0x50,0xA0,0xC0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x20,0x10,0x88,0x47,0x2F,0x1F,0x1E,0x1F,0x1E,0x1D,0x0E,0x07,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x06,0x09,0x08,0x04,0x02,0x01,0x08,0x14,0x1F,0x00,0x1F,0x15,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xA0,0x50,0xB0,0x50,0xB0,0x50,0xA0,0xC0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x20,0x10,0x88,0x47,0x2F,0x1F,0x1E,0x1F,0x1E,0x1D,0x0E,0x07,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x06,0x09,0x08,0x04,0x02,0x01,0x08,0x14,0x1F,0x00,0x1F,0x15,0x0A,0x00,0x1E,0x09,0x1E,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x40,0x40,0x20,0x20,0x20,0x40,0x40,0x98,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x02,0x42,0x20,0x07,0x18,0x60,0x80,0x00,0x00,0x00,0x80,0x60,0x18,0x07,0x00,0x10,0x22,0x02,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x15,0x35,0x25,0x35,0x15,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0xC0,0x60,0xA0,0x60,0xC0,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x1A,0x75,0xAA,0x55,0xAA,0x55,0xAA,0x75,0x1A,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x15,0x35,0x25,0x35,0x15,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xFE,0x02,0xC3,0xC2,0xC2,0x02,0xC3,0x42,0xC2,0x03,0x02,0x02,0x02,0x03,0x02,0xFE,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x1F,0x1C,0x1D,0x1D,0x1D,0x1C,0x1D,0x1D,0x1D,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1F,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00, - 0x00,0x00,0x08,0x04,0x04,0x02,0x09,0x09,0x4C,0x4E,0xCB,0xC8,0xC8,0xC8,0xC8,0x70,0x00,0x00,0xF8,0x04,0xFF,0x00,0x00,0x00, - 0x00,0x00,0x18,0x18,0x30,0x30,0x30,0x34,0x35,0x1D,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x0F,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x80,0xC0,0x80,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x10,0xBA,0xC6,0x01,0x11,0x38,0x6C,0x38,0x11,0x01,0xC6,0xBA,0x10,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x01,0x02,0x06,0x02,0x01,0x03,0x00,0x00,0x1E,0x12,0x0C,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x80,0xC0,0x80,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x10,0xBA,0xC6,0x01,0x11,0x38,0x6C,0x38,0x11,0x01,0xC6,0xBA,0x10,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x01,0x02,0x06,0x02,0x01,0x03,0x00,0x00,0x1E,0x0A,0x14,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xF8,0x06,0x01,0x01,0x00,0x03,0x01,0x00,0x00,0x01,0x01,0x06,0xF8,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x04,0x04,0x08,0x08,0x08,0x08,0x08,0x04,0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x20,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xE0,0x3C,0xC3,0x00,0x00,0x00,0xFF,0x10,0x10,0x82,0x6C,0x10,0x01,0xC6,0x38,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x01,0x02,0x04,0x07,0x00,0x00,0x1C,0x00,0x1C,0x05,0x08,0x1C,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x20,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xE0,0x3C,0xC3,0x00,0x00,0x00,0xFF,0x10,0x10,0x82,0x6C,0x10,0x01,0xC6,0x38,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x01,0x02,0x04,0x07,0x00,0x1C,0x14,0x00,0x1C,0x05,0x08,0x04,0x1C,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x30,0x48,0x48,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xC0,0x40,0x40,0x40,0x4F,0xD0,0x50,0x50,0x49,0x40,0xFC,0x04,0x07,0x05,0x05,0x05,0x07,0x04,0x04,0x07,0x00,0x00, - 0x00,0x00,0x07,0x06,0x06,0x06,0x06,0x07,0x04,0x04,0x04,0x04,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x30,0x48,0x48,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xC0,0x40,0x40,0x40,0x5F,0xC4,0x44,0x40,0x40,0x40,0xFC,0x04,0x07,0x05,0x05,0x05,0x07,0x04,0x04,0x07,0x00,0x00, - 0x00,0x00,0x07,0x06,0x06,0x06,0x06,0x07,0x04,0x04,0x04,0x04,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x08,0xF0,0x00,0x00,0x00,0x00,0x60,0x90,0x90,0x60,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x7F,0x04,0x7F,0x80,0x00,0x00,0x00,0xC0,0x20,0x20,0x40,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x08,0x10,0x10,0x10,0x08,0x07,0x00,0x00,0x03,0x04,0x04,0x02,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x08,0xF0,0x00,0x00,0x00,0x00,0x60,0x90,0x90,0x60,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x7F,0x04,0x7F,0x80,0x00,0x00,0x00,0xE0,0x20,0x20,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x08,0x10,0x10,0x10,0x08,0x07,0x00,0x00,0x07,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x40,0xA0,0x60,0xA0,0x40,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xC0,0x30,0x18,0x0F,0x0A,0x0D,0x1A,0x35,0xEA,0xF5,0xFA,0xFF,0xF8,0xF8,0xF0,0xE0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x01,0x06,0x04,0x08,0x08,0x08,0x04,0x06,0x01,0x03,0x07,0x07,0x07,0x07,0x03,0x01,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x48,0x48,0x78,0x48,0x48,0x78,0x48,0x48,0x78,0x48,0x48,0xF8,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x9E,0x91,0x51,0x51,0x51,0x91,0x9E,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3C,0x3C,0x3C,0x24,0x25,0x3D,0x25,0x24,0x3C,0x24,0x24,0x3F,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x48,0x48,0x78,0x48,0x48,0x78,0x48,0x48,0x78,0x48,0x48,0xF8,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x9E,0x91,0x51,0x51,0x51,0x91,0x9E,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x24,0x24,0x3C,0x3C,0x3D,0x3D,0x25,0x24,0x3C,0x24,0x24,0x3F,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x48,0x48,0x78,0x48,0x48,0x78,0x48,0x48,0x78,0x48,0x48,0xF8,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x9E,0x91,0x51,0x51,0x51,0x91,0x9E,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x24,0x24,0x3C,0x24,0x25,0x3D,0x3D,0x3C,0x3C,0x24,0x24,0x3F,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x48,0x48,0x78,0x48,0x48,0x78,0x48,0x48,0x78,0x48,0x48,0xF8,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x9E,0x91,0x51,0x51,0x51,0x91,0x9E,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x24,0x24,0x3C,0x24,0x25,0x3D,0x25,0x24,0x3C,0x3C,0x3C,0x3F,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x78,0x78,0x78,0x48,0x48,0x78,0x48,0x48,0x78,0x48,0x48,0xF8,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x9E,0x91,0x51,0x51,0x51,0x91,0x9E,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x24,0x24,0x3C,0x24,0x25,0x3D,0x25,0x24,0x3C,0x24,0x24,0x3F,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x48,0x48,0x78,0x78,0x78,0x78,0x48,0x48,0x78,0x48,0x48,0xF8,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x9E,0x91,0x51,0x51,0x51,0x91,0x9E,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x24,0x24,0x3C,0x24,0x25,0x3D,0x25,0x24,0x3C,0x24,0x24,0x3F,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x48,0x48,0x78,0x48,0x48,0x78,0x78,0x78,0x78,0x48,0x48,0xF8,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x9E,0x91,0x51,0x51,0x51,0x91,0x9E,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x24,0x24,0x3C,0x24,0x25,0x3D,0x25,0x24,0x3C,0x24,0x24,0x3F,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xF0,0x10,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xF0,0x10,0xF0,0x00,0x00,0x00, - 0x00,0x00,0x00,0xFF,0x00,0x1F,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x1F,0x00,0xFF,0x00,0x00,0x00, - 0x00,0x00,0x00,0x07,0x08,0x10,0x10,0x10,0x10,0x1F,0x11,0x1D,0x1D,0x11,0x11,0x11,0x1F,0x10,0x10,0x10,0x0F,0x00,0x00,0x00, - 0x00,0x00,0x00,0xF0,0x10,0xF0,0x10,0x10,0x10,0x10,0x90,0x90,0x50,0x50,0xD0,0x10,0x10,0x10,0xF0,0x10,0xF0,0x00,0x00,0x00, - 0x00,0x00,0x00,0xFF,0x00,0x1F,0x20,0x20,0x20,0x2C,0x2F,0x20,0x20,0x26,0x27,0x20,0x20,0x20,0x1F,0x00,0xFF,0x00,0x00,0x00, - 0x00,0x00,0x00,0x07,0x08,0x10,0x10,0x10,0x10,0x1F,0x11,0x1D,0x1D,0x11,0x11,0x11,0x1F,0x10,0x10,0x10,0x0F,0x00,0x00,0x00, - 0x00,0x00,0x00,0xF0,0x10,0xF0,0x10,0x10,0x10,0xD0,0x50,0x50,0x50,0x50,0xD0,0x10,0x10,0x10,0xF0,0x10,0xF0,0x00,0x00,0x00, - 0x00,0x00,0x00,0xFF,0x00,0x1F,0x20,0x20,0x20,0x2F,0x28,0x23,0x23,0x28,0x2F,0x20,0x20,0x20,0x1F,0x00,0xFF,0x00,0x00,0x00, - 0x00,0x00,0x00,0x07,0x08,0x10,0x10,0x10,0x10,0x1F,0x11,0x1D,0x1D,0x11,0x11,0x11,0x1F,0x10,0x10,0x10,0x0F,0x00,0x00,0x00, - 0x00,0x00,0x00,0xF0,0x10,0xF0,0x10,0xD0,0x50,0xD0,0x90,0x50,0x50,0x90,0xD0,0x50,0xD0,0x10,0xF0,0x10,0xF0,0x00,0x00,0x00, - 0x00,0x00,0x00,0xFF,0x00,0x3F,0x40,0x41,0x41,0x41,0x40,0x41,0x41,0x40,0x41,0x41,0x41,0x40,0x3F,0x00,0xFF,0x00,0x00,0x00, - 0x00,0x00,0x00,0x07,0x08,0x10,0x10,0x10,0x10,0x1F,0x11,0x1D,0x1D,0x11,0x11,0x11,0x1F,0x10,0x10,0x10,0x0F,0x00,0x00,0x00, - 0x00,0x00,0x00,0xF0,0x10,0xF0,0x10,0x10,0x10,0x90,0x50,0x70,0x50,0x70,0x50,0x90,0x10,0x10,0xF0,0x10,0xF0,0x00,0x00,0x00, - 0x00,0x00,0x00,0xFF,0x00,0x1F,0x20,0x20,0x20,0x2F,0x30,0x25,0x28,0x25,0x30,0x2F,0x20,0x20,0x1F,0x00,0xFF,0x00,0x00,0x00, - 0x00,0x00,0x00,0x07,0x08,0x10,0x10,0x10,0x10,0x1F,0x11,0x1D,0x1D,0x11,0x11,0x11,0x1F,0x10,0x10,0x10,0x0F,0x00,0x00,0x00, - 0x00,0x00,0x00,0xF0,0x10,0xF0,0x90,0xD0,0x90,0x10,0x10,0x10,0x10,0x10,0x50,0x10,0x10,0x10,0xF0,0x10,0xF0,0x00,0x00,0x00, - 0x00,0x00,0x00,0xFF,0x00,0x3F,0x40,0x5F,0x50,0x54,0x50,0x52,0x50,0x51,0x50,0x78,0x50,0x40,0x3F,0x00,0xFF,0x00,0x00,0x00, - 0x00,0x00,0x00,0x07,0x08,0x10,0x10,0x10,0x10,0x1F,0x11,0x1D,0x1D,0x11,0x11,0x11,0x1F,0x10,0x10,0x10,0x0F,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x06,0xFD,0x00,0x00,0x00,0x00,0xFD,0x06,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x10,0x10,0x10,0x10,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x40,0x80,0x00,0x00,0x00,0x58,0x68,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x06,0xFD,0x00,0x00,0x00,0x00,0xFD,0x06,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x10,0x10,0x10,0x10,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x20,0x20,0x20,0x20,0xE0,0x00,0x68,0x58,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x60,0x90,0x08,0x04,0x0E,0x08,0x08,0x0F,0x00,0x00,0x00,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x07,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0xE0,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x06,0x09,0x10,0x20,0x70,0x10,0x10,0xF0,0x00,0x00,0x00,0x01,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x04,0x04,0x04,0x04,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0xE0,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x68,0x58,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x06,0x09,0x10,0x20,0x70,0x10,0x10,0xF0,0x00,0x00,0x00,0x01,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x04,0x04,0x04,0x04,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x20,0x20,0x20,0x20,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x00,0x00,0x00,0x0F,0x08,0x08,0x0E,0x04,0x08,0x90,0x60,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x07,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0xE0,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x01,0x00,0x00,0x00,0xF0,0x10,0x10,0x70,0x20,0x10,0x09,0x06,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x04,0x04,0x04,0x04,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x68,0x58,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0xE0,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x01,0x00,0x00,0x00,0xF0,0x10,0x10,0x70,0x20,0x10,0x09,0x06,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x04,0x04,0x04,0x04,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x20,0x20,0x20,0x20,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x60,0x90,0x08,0x04,0x0E,0x08,0x08,0x0F,0x00,0x00,0x00,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x07,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x03,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0x40,0x40,0x00,0x00,0x00,0xC0,0x60,0x20,0x20,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x7F,0x00,0x00,0x80,0xC0,0xC0,0xC0,0xBF,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x03,0x03,0x01,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x40,0x40,0x40,0x40,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x05,0x08,0x10,0x10,0x08,0x05,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x40,0x40,0x40,0x40,0xC0,0x00,0x00,0x58,0x68,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x05,0x08,0x10,0x10,0x08,0x05,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x68,0x58,0x00,0xE0,0x20,0x20,0x20,0x20,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x00,0x00,0x00,0x0F,0x08,0x08,0x0E,0x04,0x08,0x90,0x60,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x07,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x40,0xA0,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x20,0x10,0xA0,0x40,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x82,0x44,0x28,0x11,0x82,0x44,0x82,0x11,0x28,0x44,0x82,0x01,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x04,0x0A,0x11,0x08,0x04,0x02,0x01,0x00,0x00,0x00,0x01,0x02,0x04,0x08,0x11,0x0A,0x04,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x10,0x90,0x60,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xC0,0x20,0x20,0x40,0x40,0x80,0x80,0x80,0x60,0x18,0x86,0x61,0x18,0x06,0x01,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x03,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x18,0x06,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xE0,0xF0,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x38,0xF0,0xE0,0x00,0x00,0x00, - 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, - 0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00, - 0x00,0x00,0x00,0xA8,0xA8,0x54,0x54,0x2A,0x2A,0x00,0x3F,0x21,0x32,0x2C,0x24,0x24,0x24,0x2C,0x32,0x21,0x3F,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x40,0x40,0x60,0x60,0x60,0x40,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x08,0x0F,0x08,0x0F,0x08,0x0F,0x08,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x01,0x01,0x02,0x02,0x04,0x04,0x88,0x88,0x50,0x50,0x20,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x08,0x04,0x04,0x02,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x20,0x50,0x50,0x88,0x88,0x04,0x04,0x02,0x02,0x01,0x01,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x04,0x04,0x08,0x0F,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xFF,0x01,0x01,0x01,0x01,0x7F,0x40,0x48,0x4C,0x7A,0x01,0x00,0x00,0x01,0xFA,0x0C,0x08,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x03,0x04,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x04,0x03,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0xC0,0xC0,0xC0,0xC0,0xC0,0x80,0x80,0x60,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xF8,0xFE,0x07,0x21,0x21,0x20,0x20,0xE0,0x00,0x00,0x01,0x01,0x07,0xFE,0xF9,0x01,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x03,0x07,0x0C,0x0C,0x18,0x18,0x1B,0x18,0x18,0x0C,0x0C,0x07,0x03,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x80,0x00,0x20,0xC0,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x78,0x48,0x48,0x84,0x02,0x01,0xFF,0x00,0x00,0x86,0x78,0x01,0x86,0x78,0x01,0x86,0x78,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x07,0x00,0x00,0x01,0x00,0x06,0x01,0x10,0x0E,0x01,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0xE0,0xE0,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x78,0xFE,0x87,0x01,0x01,0x00,0x07,0x07,0x00,0x01,0x01,0x87,0xFE,0x78,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x06,0x06,0x0C,0x0C,0x0C,0x0C,0x06,0x06,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xF8,0x08,0xF8,0x48,0xC8,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x78,0x48,0xF8,0x40,0xC0,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x02,0xFE,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x03,0x02,0xFF,0x02,0xFE,0x00,0x00,0x00, - 0x00,0x00,0x00,0x01,0x07,0x08,0x3F,0x40,0x80,0x81,0xF9,0x89,0xE9,0x89,0x89,0x89,0xF9,0x81,0x80,0x80,0x7F,0x00,0x00,0x00, - 0x00,0x00,0x00,0xE0,0x20,0x20,0x20,0xE0,0x80,0x80,0xE0,0x20,0x20,0x20,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x03,0x02,0x02,0x02,0x03,0x00,0x00,0x03,0x02,0x82,0xCA,0xFB,0x78,0x78,0xF8,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x7C,0x44,0x44,0x44,0x7C,0x00,0x03,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x08,0xFC,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x06,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x1F,0x10,0x10,0x13,0x13,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x10,0x00,0x00, - 0x00,0x00,0x00,0xE0,0x30,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x30,0xE0,0x00,0x00,0x00, - 0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x80,0xC0,0xA0,0x90,0x08,0x08,0x90,0xA0,0xC0,0x80,0x00,0x00,0x00,0xFF,0x00,0x00,0x00, - 0x00,0x00,0x00,0x01,0x03,0x02,0x02,0x02,0x02,0x02,0x1F,0x10,0x10,0x1F,0x02,0x02,0x02,0x02,0x02,0x03,0x01,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xFE,0xFF,0xFF,0xE3,0xE1,0xE0,0xF0,0x78,0x38,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x1C,0x1E,0x1F,0x0F,0x07,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0xE0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xFE,0x01,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x01,0xFE,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x0F,0x10,0x20,0x20,0x20,0x22,0x24,0x24,0x24,0x24,0x22,0x20,0x20,0x20,0x10,0x0F,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xF8,0x06,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0xF8,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x03,0x04,0x08,0x08,0x10,0x10,0x10,0x10,0x10,0x08,0x08,0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x20,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xE0,0x3C,0xC3,0x00,0x00,0x00,0xFF,0x10,0x10,0x82,0x6C,0x10,0x01,0xC6,0x38,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x01,0x02,0x04,0x07,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xA0,0x50,0xB0,0x50,0xB0,0x50,0xA0,0xC0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x20,0x10,0x88,0x47,0x2F,0x1F,0x1F,0x1F,0x1E,0x1F,0x0E,0x07,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x06,0x09,0x08,0x04,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00, - 0x00,0x00,0x08,0x04,0x04,0x02,0x09,0x09,0x4C,0x4E,0xCB,0xC8,0xC8,0xC8,0xC8,0x70,0x00,0x00,0xF8,0x04,0xFF,0x00,0x00,0x00, - 0x00,0x00,0x18,0x18,0x30,0x30,0x30,0x34,0x35,0x1D,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x0F,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x38,0xC8,0x08,0x08,0x08,0x08,0xA8,0x68,0x08,0x08,0x08,0x08,0xC8,0x38,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x42,0x24,0x98,0x85,0x85,0x98,0x24,0x42,0x81,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x1C,0x13,0x14,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x14,0x13,0x1C,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x38,0xC8,0x08,0x08,0x08,0x08,0x68,0xA8,0x08,0x08,0x08,0x08,0xC8,0x38,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x42,0x24,0x18,0x05,0x05,0x18,0x24,0x42,0x81,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x1C,0x13,0x14,0x16,0x17,0x17,0x17,0x17,0x17,0x17,0x16,0x14,0x13,0x1C,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x38,0xC8,0x08,0x08,0x48,0xE8,0x08,0xC8,0x28,0xC8,0x08,0x08,0xC8,0x38,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x42,0x24,0x19,0x04,0x04,0x19,0x24,0x42,0x81,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x1C,0x13,0x18,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x18,0x13,0x1C,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xF8,0x06,0xF9,0x56,0xAA,0x55,0xAB,0x55,0xAB,0x55,0xAA,0x56,0xF9,0x06,0xF8,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x03,0x04,0x0B,0x0A,0x15,0x16,0x15,0x16,0x15,0x0A,0x0B,0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xFF,0x00,0x5C,0x74,0x00,0x04,0x7C,0x04,0x00,0x38,0x44,0x38,0x00,0x7C,0x14,0x08,0x00,0xFF,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x08,0x04,0x02,0x01,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x40,0x40,0x60,0xFC,0xF8,0xF0,0x60,0x00,0x00,0x40,0x40,0x80,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xFC,0x03,0x00,0x00,0x00,0x00,0x00,0x03,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x81,0x7E,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x03,0x04,0x04,0x00,0x00,0x0C,0x1E,0x3F,0x7F,0x04,0x04,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x48,0x48,0x78,0x48,0x48,0x78,0x48,0x48,0x78,0x48,0x48,0xF8,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x9E,0x91,0x51,0x51,0x51,0x91,0x9E,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x24,0x24,0x24,0x3C,0x25,0x25,0x25,0x3C,0x24,0x24,0x24,0x3F,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0x60,0x30,0x10,0x10,0x90,0x10,0x10,0x30,0x60,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x82,0x44,0x28,0xFF,0x11,0xAA,0x44,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x03,0x06,0x0C,0x18,0x10,0x10,0x13,0x11,0x10,0x18,0x0C,0x06,0x03,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xE0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x40,0xC0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xE0,0x00,0x00,0x00, - 0x00,0x00,0x00,0xFF,0x00,0x55,0x00,0x55,0x55,0x55,0x00,0x55,0xFF,0x00,0x01,0x00,0x01,0x01,0x01,0x00,0xFF,0x00,0x00,0x00, - 0x00,0x00,0x00,0x0F,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x12,0x15,0x17,0x12,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0F,0x00,0x00,0x00, - 0x00,0x00,0x80,0x80,0x80,0x80,0x40,0x40,0x40,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x04,0x04,0x02,0x42,0xC6,0x88,0x10,0x60,0xC0,0x01,0x81,0x81,0x81,0x00,0x00, - 0x00,0x00,0x01,0x01,0x01,0x02,0x04,0x08,0x0A,0x0C,0x09,0x0B,0x0E,0x0C,0x05,0x07,0x02,0x03,0x01,0x01,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0x60,0xE2,0xB2,0xF6,0xF6,0x76,0x2C,0x6C,0xDC,0x9C,0x38,0x30,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x04,0x05,0x05,0x05,0x04,0x02,0x02,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0xE0,0xE0,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x78,0x86,0x01,0x00,0x88,0x50,0xFD,0xA9,0x50,0x00,0x00,0x01,0x86,0x78,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x04,0x04,0x08,0x09,0x08,0x08,0x04,0x04,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xC0,0xE0,0x70,0x38,0x98,0x18,0xD8,0x98,0x18,0x38,0x70,0xE0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x1F,0x3F,0x70,0xE0,0xC8,0xC5,0xDF,0xCA,0xC5,0x60,0x70,0xFF,0xCF,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x07,0x0E,0x1C,0x18,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x82,0x44,0x28,0xFF,0x11,0xAA,0x44,0x00,0x00,0x06,0x01,0x00,0x40,0x20,0x11,0x0E,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x82,0x44,0x28,0xFF,0x11,0xAA,0x44,0x00,0x00,0x00,0x00,0x01,0x82,0x44,0x28,0x10,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x83,0xC6,0x6C,0xFF,0x39,0xBA,0x6C,0xC6,0x83,0x01,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x03,0x01,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0x60,0xE2,0xB2,0xF6,0xF6,0x76,0x2C,0x6C,0xDC,0x9C,0x38,0x30,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x04,0x05,0x05,0x05,0x04,0x02,0x02,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xC0,0xE0,0x80,0x00,0x02,0x02,0x06,0x06,0x06,0x0C,0x0C,0x9C,0xDC,0xB8,0x30,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x03,0x02,0x02,0x02,0x02,0x02,0x03,0x03,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0xE0,0xE0,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x78,0x86,0x01,0x00,0x88,0x50,0xFD,0xA9,0x50,0x00,0x00,0x01,0x86,0x78,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x04,0x04,0x08,0x09,0x08,0x08,0x04,0x04,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x80,0x40,0x20,0x10,0x20,0x40,0x80,0xE0,0xE0,0x00,0x80,0x40,0x20,0x10,0x20,0x40,0x80,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x79,0x86,0x44,0x28,0x10,0x00,0x01,0x83,0x01,0x00,0x10,0x28,0x44,0xFA,0x01,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x02,0x05,0x08,0x10,0x08,0x04,0x0A,0x09,0x08,0x09,0x06,0x04,0x08,0x10,0x08,0x05,0x02,0x00,0x00,0x00 -END_DATA -}; diff --git a/AT91SAM7S256/Source/Info.txt b/AT91SAM7S256/Source/Info.txt deleted file mode 100644 index 7e2b639..0000000 --- a/AT91SAM7S256/Source/Info.txt +++ /dev/null @@ -1,14 +0,0 @@ -DEFINE_DATA(BMPMAP, Info) = -{ - 0x02,0x00, // Graphics Format - 0x00,0x48, // Graphics DataSize - 0x00, // Graphics Start X - 0x08, // Graphics Start Y - 0x18, // Graphics Width - 0x18, // Graphics Height -BEGIN_DATA - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x40,0xA0,0x90,0x20,0x20,0x40,0x40,0x30,0x8C,0x73,0x0C,0x03,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x02,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 -END_DATA -}; diff --git a/AT91SAM7S256/Source/LowBattery.txt b/AT91SAM7S256/Source/LowBattery.txt deleted file mode 100644 index 51b8ddb..0000000 --- a/AT91SAM7S256/Source/LowBattery.txt +++ /dev/null @@ -1,18 +0,0 @@ -DEFINE_DATA(BMPMAP, LowBattery) = -{ - 0x02,0x00, // Graphics Format - 0x02,0xA0, // Graphics DataSize - 0x02, // Graphics Start X - 0x08, // Graphics Start Y - 0x60, // Graphics Width - 0x38, // Graphics Height -BEGIN_DATA - 0x02,0xF2,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0xF2,0x82,0x02, - 0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x20,0x18,0x04,0x02,0x02,0x01,0x01,0x01,0x00,0xF0,0xF8,0xFC,0xFC,0xF8,0xF0,0x00,0x01,0x01,0x01,0x02,0x02,0x04,0x18,0x20,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00, - 0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x7F,0xFF,0xFF,0x7F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00, - 0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x0E,0x10,0x60,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xF0,0xF0,0xF0,0xF0,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x10,0x0E,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00, - 0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x00,0xE0,0x10,0x10,0x10,0xE0,0x00,0xF0,0x00,0xC0,0x00,0xF0,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0xF2,0x92,0x92,0x94,0x64,0x04,0xE4,0x14,0x14,0x14,0xE4,0x02,0x12,0x12,0xF1,0x11,0x10,0x00,0x10,0x10,0xF0,0x10,0x10,0x00,0xF0,0x90,0x90,0x90,0x10,0x00,0xF0,0x90,0x90,0x90,0x60,0x00,0x70,0x80,0x00,0x80,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00, - 0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x04,0x04,0x04,0x04,0x00,0x03,0x04,0x04,0x04,0x03,0x00,0x03,0x04,0x03,0x04,0x03,0x00,0x00,0x00,0x00,0xC0,0x40,0xF0,0x17,0x14,0x14,0x14,0x13,0x10,0x17,0x11,0x11,0x11,0x17,0x10,0x10,0xD0,0xD7,0x10,0xF0,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x04,0x04,0x04,0x04,0x00,0x07,0x00,0x00,0x01,0x06,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00, - 0x00,0x3F,0x20,0x20,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x63,0x62,0x6F,0x68,0x68,0x68,0x68,0x68,0x68,0x68,0x68,0x68,0x68,0x68,0x68,0x68,0x6B,0x6B,0x68,0x6F,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x7F,0x7F,0x00 -END_DATA -}; diff --git a/AT91SAM7S256/Source/Mainmenu.rms b/AT91SAM7S256/Source/Mainmenu.rms deleted file mode 100644 index 2e014fb..0000000 --- a/AT91SAM7S256/Source/Mainmenu.rms +++ /dev/null @@ -1,72 +0,0 @@ -const UBYTE MAINMENU[] = -{ - 0x07,0x00, // Menu Format - 0x01,0x05, // Menu DataSize - 0x1D, // Menu item size - 0x09, // Menu items - 0x18, // Menu icon Width - 0x18, // Menu icon Height - - // Turn_off? - 0x00,0x00,0x00,0x01, // 0x00000001 - 0x10,0x20,0x04,0x01, // 0x10200401 - 0x02,0x00,0x00,0x01, // 2 ,0 ,0 ,1 - 0x54,0x75,0x72,0x6E,0x20,0x6F,0x66,0x66,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x31, // 31 - - // Turn_off? - 0x00,0x00,0x00,0x02, // 0x00000002 - 0x10,0x20,0x00,0x01, // 0x10200001 - 0x00,0x00,0x00,0x01, // 0 ,0 ,0 ,1 - 0x54,0x75,0x72,0x6E,0x20,0x6F,0x66,0x66,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x30, // 30 - - // My_Files - 0x00,0x00,0x00,0x11, // 0x00000011 - 0x01,0x04,0x00,0x00, // 0x01040000 - 0x00,0x00,0x01,0x01, // 0 ,0 ,1 ,1 - 0x4D,0x79,0x20,0x46,0x69,0x6C,0x65,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x3B, // 3B - - // NXT_Program - 0x00,0x00,0x00,0x21, // 0x00000021 - 0x01,0x04,0x00,0x00, // 0x01040000 - 0x00,0x00,0x02,0x01, // 0 ,0 ,2 ,1 - 0x4E,0x58,0x54,0x20,0x50,0x72,0x6F,0x67,0x72,0x61,0x6D,0x00,0x00,0x00,0x00,0x00, - 0x3C, // 3C - - // NXT_Datalog - 0x00,0x00,0x00,0x31, // 0x00000031 - 0x01,0x84,0x00,0x00, // 0x01840000 - 0x0A,0x00,0x03,0x01, // 10 ,0 ,3 ,1 - 0x4E,0x58,0x54,0x20,0x44,0x61,0x74,0x61,0x6C,0x6F,0x67,0x00,0x00,0x00,0x00,0x00, - 0x3D, // 3D - - // View - 0x00,0x00,0x00,0x41, // 0x00000041 - 0x01,0x04,0x00,0x00, // 0x01040000 - 0x0E,0x00,0x04,0x01, // 14 ,0 ,4 ,1 - 0x56,0x69,0x65,0x77,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x3E, // 3E - - // Bluetooth - 0x00,0x00,0x00,0x51, // 0x00000051 - 0x01,0x04,0x00,0x00, // 0x01040000 - 0x00,0x00,0x07,0x02, // 0 ,0 ,7 ,2 - 0x42,0x6C,0x75,0x65,0x74,0x6F,0x6F,0x74,0x68,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x51, // 51 - - // Settings - 0x00,0x00,0x00,0x61, // 0x00000061 - 0x01,0x04,0x00,0x00, // 0x01040000 - 0x00,0x00,0x05,0x01, // 0 ,0 ,5 ,1 - 0x53,0x65,0x74,0x74,0x69,0x6E,0x67,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x3F, // 3F - - // Try_Me - 0x00,0x00,0x00,0x71, // 0x00000071 - 0x01,0x04,0x00,0x00, // 0x01040000 - 0x00,0x00,0x06,0x01, // 0 ,0 ,6 ,1 - 0x54,0x72,0x79,0x20,0x4D,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x40, // 40 -}; diff --git a/AT91SAM7S256/Source/Ok.txt b/AT91SAM7S256/Source/Ok.txt deleted file mode 100644 index 32bad41..0000000 --- a/AT91SAM7S256/Source/Ok.txt +++ /dev/null @@ -1,13 +0,0 @@ -DEFINE_DATA(BMPMAP, Ok) = -{ - 0x02,0x00, // Graphics Format - 0x00,0x20, // Graphics DataSize - 0x2A, // Graphics Start X - 0x30, // Graphics Start Y - 0x10, // Graphics Width - 0x10, // Graphics Height -BEGIN_DATA - 0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x38,0xC4,0x34,0x08,0x00,0xFF, - 0xFF,0x04,0x0A,0x19,0x12,0x22,0x24,0x24,0x23,0x18,0x07,0x00,0x00,0x00,0x00,0xFF -END_DATA -}; diff --git a/AT91SAM7S256/Source/Port.txt b/AT91SAM7S256/Source/Port.txt deleted file mode 100644 index 292fccc..0000000 --- a/AT91SAM7S256/Source/Port.txt +++ /dev/null @@ -1,12 +0,0 @@ -DEFINE_DATA(ICON, Port) = -{ - 0x04,0x00, // Graphics Format - 0x00,0x18, // Graphics DataSize - 0x08, // Graphics Count X - 0x01, // Graphics Count Y - 0x03, // Graphics Width - 0x08, // Graphics Height -BEGIN_DATA - 0x70,0x88,0x70,0x90,0xF8,0x80,0xC8,0xA8,0x90,0x88,0xA8,0x50,0x38,0x20,0xF8,0xF0,0x28,0xF0,0xF8,0xA8,0x50,0x70,0x88,0x50 -END_DATA -}; diff --git a/AT91SAM7S256/Source/RCXintro_1.txt b/AT91SAM7S256/Source/RCXintro_1.txt deleted file mode 100644 index 456a63d..0000000 --- a/AT91SAM7S256/Source/RCXintro_1.txt +++ /dev/null @@ -1,19 +0,0 @@ -DEFINE_DATA(BMPMAP, RCXintro_1) = -{ - 0x02,0x00, // Graphics Format - 0x02,0x00, // Graphics DataSize - 0x10, // Graphics Start X - 0x00, // Graphics Start Y - 0x40, // Graphics Width - 0x40, // Graphics Height -BEGIN_DATA - 0xFF,0x01,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0x01,0xFF, - 0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0xFF, - 0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x1F,0x8F,0xC7,0xE7,0x67,0x33,0x33,0x33,0x67,0xE7,0x8F,0xCF,0xE7,0x67,0x63,0x33,0x33,0x33,0x33,0x33,0x27,0x67,0xCF,0xCF,0xE7,0x67,0x63,0x33,0x33,0x33,0x33,0x33,0x63,0x67,0xC7,0x8F,0x8F,0xCF,0x67,0x67,0x23,0x33,0x33,0x33,0x33,0x63,0x67,0xC7,0x8F,0x1F,0x33,0xF3,0xFF,0x00,0xFF, - 0xFF,0x00,0xFF,0xFF,0x7F,0x0F,0x83,0xE0,0x78,0x1E,0x07,0x01,0x00,0x00,0x80,0xE0,0xF8,0x7E,0x1F,0x07,0x01,0x00,0x00,0x00,0x18,0x18,0x18,0xF8,0xF8,0x1C,0x06,0x03,0x00,0x00,0xC0,0x70,0x3C,0x3C,0x30,0x20,0x20,0xE0,0xF0,0x3D,0x0F,0x03,0x00,0x00,0xC0,0xF0,0xFC,0x3C,0x00,0x00,0x00,0x00,0xC0,0xFF,0x1E,0x00,0xC0,0xFF,0x00,0xFF, - 0xFF,0x00,0xFF,0x01,0x00,0xFC,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x0E,0x0F,0xFF,0xC7,0x00,0x00,0x00,0x00,0x00,0x0E,0x0E,0x0E,0x0E,0xFE,0xC7,0x80,0x00,0x00,0x00,0x00,0x1F,0x1F,0x0E,0x00,0x00,0x80,0xC0,0xF0,0xFF,0x83,0x00,0x00,0x00,0x1C,0x1F,0x0F,0x03,0x00,0x80,0xC0,0xE0,0x78,0x1E,0x87,0xC1,0xF0,0xFE,0xFF,0xFF,0x00,0xFF, - 0xFF,0x00,0xFF,0xFE,0xFC,0xF8,0xF3,0xF3,0xE6,0xE6,0xE6,0xE6,0xE6,0xF2,0xF3,0xF9,0xF9,0xF3,0xF6,0xE6,0xE6,0xE6,0xE6,0xE6,0xF3,0xF3,0xF9,0xF9,0xF3,0xF3,0xE6,0xE6,0xE6,0xE6,0xE6,0xE6,0xF3,0xF3,0xF9,0xFC,0xFC,0xF9,0xF3,0xF3,0xE6,0xE6,0xE6,0xE6,0xE6,0xE6,0xF3,0xF3,0xF9,0xF8,0xFC,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0xFF, - 0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0xFF, - 0xFF,0x80,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0x80,0xFF -END_DATA -}; diff --git a/AT91SAM7S256/Source/RCXintro_10.txt b/AT91SAM7S256/Source/RCXintro_10.txt deleted file mode 100644 index 5f98538..0000000 --- a/AT91SAM7S256/Source/RCXintro_10.txt +++ /dev/null @@ -1,13 +0,0 @@ -DEFINE_DATA(BMPMAP, RCXintro_10) = -{ - 0x02,0x00, // Graphics Format - 0x00,0x20, // Graphics DataSize - 0x38, // Graphics Start X - 0x20, // Graphics Start Y - 0x0A, // Graphics Width - 0x10, // Graphics Height -BEGIN_DATA - 0xFE,0xFE,0x06,0x06,0x66,0x66,0x06,0x06,0xFE,0xFE, - 0x07,0x07,0x06,0x06,0x00,0x00,0x06,0x06,0x07,0x07 -END_DATA -}; diff --git a/AT91SAM7S256/Source/RCXintro_11.txt b/AT91SAM7S256/Source/RCXintro_11.txt deleted file mode 100644 index 6afaabd..0000000 --- a/AT91SAM7S256/Source/RCXintro_11.txt +++ /dev/null @@ -1,13 +0,0 @@ -DEFINE_DATA(BMPMAP, RCXintro_11) = -{ - 0x02,0x00, // Graphics Format - 0x00,0x10, // Graphics DataSize - 0x3A, // Graphics Start X - 0x20, // Graphics Start Y - 0x08, // Graphics Width - 0x10, // Graphics Height -BEGIN_DATA - 0xF8,0xF8,0x18,0xD8,0xD8,0x18,0xF8,0xF8, - 0x07,0x07,0x06,0x00,0x00,0x06,0x07,0x07 -END_DATA -}; diff --git a/AT91SAM7S256/Source/RCXintro_12.txt b/AT91SAM7S256/Source/RCXintro_12.txt deleted file mode 100644 index b89f65c..0000000 --- a/AT91SAM7S256/Source/RCXintro_12.txt +++ /dev/null @@ -1,13 +0,0 @@ -DEFINE_DATA(BMPMAP, RCXintro_12) = -{ - 0x02,0x00, // Graphics Format - 0x00,0xC0, // Graphics DataSize - 0x03, // Graphics Start X - 0x20, // Graphics Start Y - 0x5E, // Graphics Width - 0x10, // Graphics Height -BEGIN_DATA - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xF8,0x18,0xD8,0xD8,0x18,0xF8,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x06,0x06,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x06,0x00,0x00,0x06,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x06,0x06,0x00,0x00,0x00,0x07,0x07 -END_DATA -}; diff --git a/AT91SAM7S256/Source/RCXintro_13.txt b/AT91SAM7S256/Source/RCXintro_13.txt deleted file mode 100644 index ee512ea..0000000 --- a/AT91SAM7S256/Source/RCXintro_13.txt +++ /dev/null @@ -1,13 +0,0 @@ -DEFINE_DATA(BMPMAP, RCXintro_13) = -{ - 0x02,0x00, // Graphics Format - 0x00,0xC0, // Graphics DataSize - 0x03, // Graphics Start X - 0x20, // Graphics Start Y - 0x5E, // Graphics Width - 0x10, // Graphics Height -BEGIN_DATA - 0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x00,0x00,0x00,0x00,0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x00,0x00,0x00,0x00,0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0xF8,0xF8,0x18,0xD8,0xD8,0x18,0xF8,0xF8,0x00,0x00,0xE0,0xE0,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x00,0x00,0x00,0xC0,0xC0, - 0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x06,0x06,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x06,0x00,0x00,0x06,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x06,0x06,0x00,0x00,0x00,0x07,0x07 -END_DATA -}; diff --git a/AT91SAM7S256/Source/RCXintro_14.txt b/AT91SAM7S256/Source/RCXintro_14.txt deleted file mode 100644 index feb4cd7..0000000 --- a/AT91SAM7S256/Source/RCXintro_14.txt +++ /dev/null @@ -1,13 +0,0 @@ -DEFINE_DATA(BMPMAP, RCXintro_14) = -{ - 0x02,0x00, // Graphics Format - 0x00,0xC0, // Graphics DataSize - 0x03, // Graphics Start X - 0x20, // Graphics Start Y - 0x5E, // Graphics Width - 0x10, // Graphics Height -BEGIN_DATA - 0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x00,0x00,0x00,0x00,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x00,0x00,0x00,0x00,0xFE,0xFE,0x00,0x00,0xF8,0xF8,0x00,0x00,0x00,0xD8,0xD8,0x00,0x00,0x00,0x00,0x00,0xF8,0xF8,0x00,0x00,0x00,0x00,0x00,0xF8,0xF8,0x18,0xD8,0xD8,0x18,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x00,0x00,0x00,0x00,0x38,0x38,0x00,0x00,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x00,0x00,0x00,0xD8,0xD8, - 0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x06,0x06,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x06,0x00,0x00,0x06,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x06,0x06,0x00,0x00,0x00,0x07,0x07 -END_DATA -}; diff --git a/AT91SAM7S256/Source/RCXintro_15.txt b/AT91SAM7S256/Source/RCXintro_15.txt deleted file mode 100644 index 71f51e0..0000000 --- a/AT91SAM7S256/Source/RCXintro_15.txt +++ /dev/null @@ -1,13 +0,0 @@ -DEFINE_DATA(BMPMAP, RCXintro_15) = -{ - 0x02,0x00, // Graphics Format - 0x00,0xC0, // Graphics DataSize - 0x03, // Graphics Start X - 0x20, // Graphics Start Y - 0x5E, // Graphics Width - 0x10, // Graphics Height -BEGIN_DATA - 0xF8,0xF8,0x18,0x00,0xF8,0xF8,0x18,0x00,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x18,0x18,0x00,0x00,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x18,0x18,0x00,0x00,0xFE,0xFE,0x00,0x00,0xF8,0xF8,0x18,0x00,0xC0,0xD8,0xD8,0x00,0x00,0x18,0x18,0x00,0xF8,0xF8,0x18,0x00,0x00,0x00,0x00,0xF8,0xF8,0x18,0xD8,0xD8,0x18,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x18,0x00,0x00,0x18,0x38,0x38,0x00,0x00,0xF8,0xF8,0x18,0x00,0xF8,0xF8,0x18,0x00,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x18,0x00,0xC0,0xD8,0xD8, - 0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x06,0x06,0x07,0x07,0x00,0x00,0x06,0x06,0x06,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x06,0x00,0x00,0x06,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x06,0x06,0x06,0x00,0x00,0x07,0x07 -END_DATA -}; diff --git a/AT91SAM7S256/Source/RCXintro_16.txt b/AT91SAM7S256/Source/RCXintro_16.txt deleted file mode 100644 index 9cf470c..0000000 --- a/AT91SAM7S256/Source/RCXintro_16.txt +++ /dev/null @@ -1,13 +0,0 @@ -DEFINE_DATA(BMPMAP, RCXintro_16) = -{ - 0x02,0x00, // Graphics Format - 0x00,0xC0, // Graphics DataSize - 0x03, // Graphics Start X - 0x20, // Graphics Start Y - 0x5E, // Graphics Width - 0x10, // Graphics Height -BEGIN_DATA - 0xF8,0xF8,0x18,0x18,0xF8,0xF8,0x18,0x18,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x18,0x18,0x18,0x18,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x18,0x18,0x18,0x18,0xFE,0xFE,0x00,0x00,0xF8,0xF8,0xD8,0xD8,0xD8,0xD8,0xD8,0x00,0x00,0x18,0x18,0x18,0xF8,0xF8,0x18,0x18,0x18,0x00,0x00,0xF8,0xF8,0x18,0xD8,0xD8,0x18,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x18,0x18,0x18,0x18,0x38,0x38,0x00,0x00,0xF8,0xF8,0x18,0x18,0xF8,0xF8,0x18,0x18,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0xD8,0xD8,0xD8,0xD8,0xD8, - 0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x06,0x06,0x06,0x06,0x07,0x07,0x00,0x00,0x06,0x06,0x06,0x06,0x06,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x06,0x00,0x00,0x06,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x06,0x06,0x06,0x06,0x06,0x07,0x07 -END_DATA -}; diff --git a/AT91SAM7S256/Source/RCXintro_2.txt b/AT91SAM7S256/Source/RCXintro_2.txt deleted file mode 100644 index addecb2..0000000 --- a/AT91SAM7S256/Source/RCXintro_2.txt +++ /dev/null @@ -1,19 +0,0 @@ -DEFINE_DATA(BMPMAP, RCXintro_2) = -{ - 0x02,0x00, // Graphics Format - 0x02,0x00, // Graphics DataSize - 0x10, // Graphics Start X - 0x00, // Graphics Start Y - 0x40, // Graphics Width - 0x40, // Graphics Height -BEGIN_DATA - 0xFC,0x02,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0x02,0xFC, - 0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x3F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x3F,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0xFF, - 0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x1F,0x8F,0xC7,0xE7,0x67,0x30,0x30,0x30,0x60,0xE0,0x80,0xC0,0xE0,0x60,0x60,0x30,0x30,0x30,0x30,0x30,0x20,0x60,0xC0,0xC0,0xE0,0x60,0x60,0x30,0x30,0x30,0x30,0x30,0x60,0x60,0xC0,0x80,0x80,0xC0,0x60,0x60,0x20,0x33,0x33,0x33,0x33,0x63,0x67,0xC7,0x8F,0x1F,0x33,0xF3,0xFF,0x00,0xFF, - 0xFF,0x00,0xFF,0xFF,0x7F,0x0F,0x83,0xE0,0x78,0x1E,0x07,0x01,0x00,0x00,0x80,0xE0,0xF8,0x7E,0x1F,0x07,0x01,0x00,0x00,0x00,0x18,0x18,0x18,0xF8,0xF8,0x1C,0x06,0x03,0x00,0x00,0xC0,0x70,0x3C,0x3C,0x30,0x20,0x20,0xE0,0xF0,0x3D,0x0F,0x03,0x00,0x00,0xC0,0xF0,0xFC,0x3C,0x00,0x00,0x00,0x00,0xC0,0xFF,0x1E,0x00,0xC0,0xFF,0x00,0xFF, - 0xFF,0x00,0xFF,0x01,0x00,0xFC,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x0E,0x0F,0xFF,0xC7,0x00,0x00,0x00,0x00,0x00,0x0E,0x0E,0x0E,0x0E,0xFE,0xC7,0x80,0x00,0x00,0x00,0x00,0x1F,0x1F,0x0E,0x00,0x00,0x80,0xC0,0xF0,0xFF,0x83,0x00,0x00,0x00,0x1C,0x1F,0x0F,0x03,0x00,0x80,0xC0,0xE0,0x78,0x1E,0xC7,0xE1,0xF8,0xFF,0xFF,0xFF,0x00,0xFF, - 0xFF,0x00,0xFF,0xFE,0xFE,0xFC,0xF3,0xF3,0xE6,0xE6,0xE6,0xE6,0xE6,0xF2,0x83,0x01,0x01,0x03,0x06,0x06,0x06,0x06,0x06,0x06,0x03,0x03,0x01,0x01,0x03,0x03,0x06,0x06,0x06,0x06,0x06,0x06,0x03,0x03,0x01,0x00,0x00,0x01,0x03,0x03,0x06,0x06,0x06,0x06,0x06,0x86,0xF3,0xFB,0xF9,0xFC,0xFE,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0xFF, - 0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFC,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0xFF, - 0x3F,0x40,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0x40,0x3F -END_DATA -}; diff --git a/AT91SAM7S256/Source/RCXintro_3.txt b/AT91SAM7S256/Source/RCXintro_3.txt deleted file mode 100644 index eba6710..0000000 --- a/AT91SAM7S256/Source/RCXintro_3.txt +++ /dev/null @@ -1,19 +0,0 @@ -DEFINE_DATA(BMPMAP, RCXintro_3) = -{ - 0x02,0x00, // Graphics Format - 0x02,0x00, // Graphics DataSize - 0x10, // Graphics Start X - 0x00, // Graphics Start Y - 0x40, // Graphics Width - 0x40, // Graphics Height -BEGIN_DATA - 0xFC,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFC, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x3F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x3F,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x1F,0x07,0x07,0xC3,0xF1,0x79,0x1F,0x00,0x00,0x00,0x00,0xF8,0x7E,0x07,0x03,0x19,0x18,0xF8,0xFC,0xFC,0xFC,0xFF,0xFF,0xFF,0xFF,0xFD,0xFD,0xFC,0xF8,0x31,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x30,0x0C,0x07,0x81,0xE0,0x3C,0x01,0x01,0xC3,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC3,0x80,0x80,0x80,0x80,0x8F,0xDF,0x70,0x00,0x00,0x00,0x00,0x00,0x7F,0xC0,0x80,0x80,0xCE,0xCE,0x5F,0x7F,0xFF,0xFF,0xBF,0xBF,0x3F,0x3F,0x3F,0x3F,0xBF,0xDF,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x63,0xC0,0x80,0xC6,0xE3,0xC0,0xE0,0xF8,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFC,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xFC,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0x3F,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x3F -END_DATA -}; diff --git a/AT91SAM7S256/Source/RCXintro_4.txt b/AT91SAM7S256/Source/RCXintro_4.txt deleted file mode 100644 index dc15847..0000000 --- a/AT91SAM7S256/Source/RCXintro_4.txt +++ /dev/null @@ -1,19 +0,0 @@ -DEFINE_DATA(BMPMAP, RCXintro_4) = -{ - 0x02,0x00, // Graphics Format - 0x02,0x00, // Graphics DataSize - 0x10, // Graphics Start X - 0x00, // Graphics Start Y - 0x40, // Graphics Width - 0x40, // Graphics Height -BEGIN_DATA - 0xFC,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFC, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x3F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x3F,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFC,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xFC,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0x3F,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x3F -END_DATA -}; diff --git a/AT91SAM7S256/Source/RCXintro_5.txt b/AT91SAM7S256/Source/RCXintro_5.txt deleted file mode 100644 index efd3cb9..0000000 --- a/AT91SAM7S256/Source/RCXintro_5.txt +++ /dev/null @@ -1,19 +0,0 @@ -DEFINE_DATA(BMPMAP, RCXintro_5) = -{ - 0x02,0x00, // Graphics Format - 0x01,0xC0, // Graphics DataSize - 0x17, // Graphics Start X - 0x00, // Graphics Start Y - 0x34, // Graphics Width - 0x40, // Graphics Height -BEGIN_DATA - 0x80,0xC0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xC0,0x80, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF0,0xE0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xE0,0xF0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F, - 0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00 -END_DATA -}; diff --git a/AT91SAM7S256/Source/RCXintro_6.txt b/AT91SAM7S256/Source/RCXintro_6.txt deleted file mode 100644 index 4ab152a..0000000 --- a/AT91SAM7S256/Source/RCXintro_6.txt +++ /dev/null @@ -1,17 +0,0 @@ -DEFINE_DATA(BMPMAP, RCXintro_6) = -{ - 0x02,0x00, // Graphics Format - 0x01,0x20, // Graphics DataSize - 0x1C, // Graphics Start X - 0x08, // Graphics Start Y - 0x2C, // Graphics Width - 0x30, // Graphics Height -BEGIN_DATA - 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x07,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x03,0x07,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x03,0x03,0x03,0x03,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFC,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xFC,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0x07,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x07 -END_DATA -}; diff --git a/AT91SAM7S256/Source/RCXintro_7.txt b/AT91SAM7S256/Source/RCXintro_7.txt deleted file mode 100644 index cabcc7b..0000000 --- a/AT91SAM7S256/Source/RCXintro_7.txt +++ /dev/null @@ -1,16 +0,0 @@ -DEFINE_DATA(BMPMAP, RCXintro_7) = -{ - 0x02,0x00, // Graphics Format - 0x00,0xC8, // Graphics DataSize - 0x23, // Graphics Start X - 0x10, // Graphics Start Y - 0x22, // Graphics Width - 0x28, // Graphics Height -BEGIN_DATA - 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xC0,0xC0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x0F,0x0F,0x0F,0x0F,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,0xF8,0xF8,0xF8,0xF8,0xF8,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xF8,0xF8,0xF8,0xF8,0xF8,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0x01,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x01 -END_DATA -}; diff --git a/AT91SAM7S256/Source/RCXintro_8.txt b/AT91SAM7S256/Source/RCXintro_8.txt deleted file mode 100644 index d062714..0000000 --- a/AT91SAM7S256/Source/RCXintro_8.txt +++ /dev/null @@ -1,14 +0,0 @@ -DEFINE_DATA(BMPMAP, RCXintro_8) = -{ - 0x02,0x00, // Graphics Format - 0x00,0x48, // Graphics DataSize - 0x2C, // Graphics Start X - 0x18, // Graphics Start Y - 0x16, // Graphics Width - 0x18, // Graphics Height -BEGIN_DATA - 0xFE,0xFF,0xFF,0xFF,0x1F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x1F,0xFF,0xFF,0xFF,0xFE, - 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x1E,0x1E,0x1E,0x1E,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF, - 0x1F,0x3F,0x3F,0x3F,0x3E,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x3E,0x3F,0x3F,0x3F,0x1F -END_DATA -}; diff --git a/AT91SAM7S256/Source/RCXintro_9.txt b/AT91SAM7S256/Source/RCXintro_9.txt deleted file mode 100644 index 3952437..0000000 --- a/AT91SAM7S256/Source/RCXintro_9.txt +++ /dev/null @@ -1,14 +0,0 @@ -DEFINE_DATA(BMPMAP, RCXintro_9) = -{ - 0x02,0x00, // Graphics Format - 0x00,0x30, // Graphics DataSize - 0x34, // Graphics Start X - 0x18, // Graphics Start Y - 0x0E, // Graphics Width - 0x18, // Graphics Height -BEGIN_DATA - 0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0, - 0xFF,0xFF,0xFF,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0xFF,0xFF,0xFF, - 0x07,0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x07 -END_DATA -}; diff --git a/AT91SAM7S256/Source/Running.txt b/AT91SAM7S256/Source/Running.txt deleted file mode 100644 index 6bea492..0000000 --- a/AT91SAM7S256/Source/Running.txt +++ /dev/null @@ -1,59 +0,0 @@ -DEFINE_DATA(ICON, Running) = -{ - 0x04,0x00, // Graphics Format - 0x04,0x80, // Graphics DataSize - 0x01, // Graphics Count X - 0x10, // Graphics Count Y - 0x18, // Graphics Width - 0x18, // Graphics Height -BEGIN_DATA - 0x00,0x00,0x00,0xE0,0xF0,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x38,0xF0,0xE0,0x00,0x00,0x00, - 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, - 0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,0x00,0x00, - 0x00,0x00,0x00,0xE0,0xF0,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x38,0xF0,0xE0,0x00,0x00,0x00, - 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, - 0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,0x00,0x00, - 0x00,0x00,0x00,0xE0,0xF0,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x38,0xF0,0xE0,0x00,0x00,0x00, - 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, - 0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,0x00,0x00, - 0x00,0x00,0x00,0xE0,0xF0,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x38,0xF0,0xE0,0x00,0x00,0x00, - 0x00,0x00,0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, - 0x00,0x00,0x00,0x06,0x0E,0x1C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,0x00,0x00, - 0x00,0x00,0x00,0xE0,0xF0,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x38,0xF0,0xE0,0x00,0x00,0x00, - 0x00,0x00,0x00,0xC3,0xC3,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, - 0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,0x00,0x00, - 0x00,0x00,0x00,0x60,0x70,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x38,0xF0,0xE0,0x00,0x00,0x00, - 0x00,0x00,0x00,0xF8,0xF8,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, - 0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,0x00,0x00, - 0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x38,0xF0,0xE0,0x00,0x00,0x00, - 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, - 0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,0x00,0x00, - 0x00,0x00,0x00,0xE0,0xF0,0x38,0x18,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x38,0xF0,0xE0,0x00,0x00,0x00, - 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, - 0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,0x00,0x00, - 0x00,0x00,0x00,0xE0,0xF0,0x38,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x38,0xF0,0xE0,0x00,0x00,0x00, - 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, - 0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,0x00,0x00, - 0x00,0x00,0x00,0xE0,0xF0,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x18,0x38,0xF0,0xE0,0x00,0x00,0x00, - 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, - 0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,0x00,0x00, - 0x00,0x00,0x00,0xE0,0xF0,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x80,0x80,0x00,0x00,0x00, - 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, - 0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,0x00,0x00, - 0x00,0x00,0x00,0xE0,0xF0,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x38,0x70,0x60,0x00,0x00,0x00, - 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0xF8,0xF8,0x00,0x00,0x00, - 0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,0x00,0x00, - 0x00,0x00,0x00,0xE0,0xF0,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x38,0xF0,0xE0,0x00,0x00,0x00, - 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0xC3,0xC3,0x00,0x00,0x00, - 0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,0x00,0x00, - 0x00,0x00,0x00,0xE0,0xF0,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x38,0xF0,0xE0,0x00,0x00,0x00, - 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0x1F,0x1F,0x00,0x00,0x00, - 0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1C,0x0E,0x06,0x00,0x00,0x00, - 0x00,0x00,0x00,0xE0,0xF0,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x38,0xF0,0xE0,0x00,0x00,0x00, - 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, - 0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x01,0x01,0x00,0x00,0x00, - 0x00,0x00,0x00,0xE0,0xF0,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x38,0xF0,0xE0,0x00,0x00,0x00, - 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, - 0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x18,0x1C,0x0F,0x07,0x00,0x00,0x00 -END_DATA -}; diff --git a/AT91SAM7S256/Source/Status.txt b/AT91SAM7S256/Source/Status.txt deleted file mode 100644 index 6d1d5bd..0000000 --- a/AT91SAM7S256/Source/Status.txt +++ /dev/null @@ -1,17 +0,0 @@ -DEFINE_DATA(ICON, Status) = -{ - 0x04,0x00, // Graphics Format - 0x01,0xB0, // Graphics DataSize - 0x06, // Graphics Count X - 0x06, // Graphics Count Y - 0x0C, // Graphics Width - 0x08, // Graphics Height -BEGIN_DATA - 0x00,0x00,0x7E,0x81,0x81,0x19,0x19,0x81,0x81,0x7E,0x00,0x00,0x00,0x00,0x7E,0x01,0x01,0x99,0x99,0x81,0x81,0x7E,0x00,0x00,0x00,0x00,0x1E,0x81,0x81,0x99,0x99,0x81,0x81,0x7E,0x00,0x00,0x00,0x00,0x66,0x81,0x81,0x99,0x99,0x81,0x81,0x7E,0x00,0x00,0x00,0x00,0x78,0x81,0x81,0x99,0x99,0x81,0x81,0x7E,0x00,0x00,0x00,0x00,0x7E,0x80,0x80,0x99,0x99,0x81,0x81,0x7E,0x00,0x00, - 0x00,0x00,0x7E,0x81,0x81,0x98,0x98,0x81,0x81,0x7E,0x00,0x00,0x00,0x00,0x7E,0x81,0x81,0x99,0x99,0x80,0x80,0x7E,0x00,0x00,0x00,0x00,0x7E,0x81,0x81,0x99,0x99,0x81,0x81,0x78,0x00,0x00,0x00,0x00,0x7E,0x81,0x81,0x99,0x99,0x81,0x81,0x66,0x00,0x00,0x00,0x00,0x7E,0x81,0x81,0x99,0x99,0x81,0x81,0x1E,0x00,0x00,0x00,0x00,0x7E,0x81,0x81,0x99,0x99,0x01,0x01,0x7E,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x24,0x24,0x24,0x24,0x24,0x3C,0x3C,0x00,0x00,0x00,0x00,0x18,0x24,0x24,0x24,0x24,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x18,0x24,0x24,0x3C,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x18,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x24,0x24,0x24,0x24,0x24,0x3C,0x3C,0x00,0x00,0x00,0x00,0x18,0x24,0x24,0x24,0x24,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x18,0x24,0x24,0x3C,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x18,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x22,0x14,0x7F,0x2A,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x22,0x14,0x7F,0x2A,0x14,0x00,0x08,0x14,0x22,0x00,0x00,0x00,0x22,0x14,0x7F,0x2A,0x14,0x00,0x00,0x00,0x22,0x14,0x08,0x00,0x22,0x14,0x7F,0x2A,0x14,0x00,0x08,0x14,0x22,0x14,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x22,0x1C,0x00,0x3E,0x0A,0x02,0x00,0x3E,0x20,0x3E,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x14,0x1C,0x08,0x08,0x08,0x08,0x08,0x1C,0x14,0x14,0x00,0x3E,0x20,0x3E,0x00,0x2E,0x2A,0x3A,0x00,0x3E,0x2A,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 -END_DATA -}; diff --git a/AT91SAM7S256/Source/Step.txt b/AT91SAM7S256/Source/Step.txt deleted file mode 100644 index cba0c0d..0000000 --- a/AT91SAM7S256/Source/Step.txt +++ /dev/null @@ -1,19 +0,0 @@ -DEFINE_DATA(ICON, Step) = -{ - 0x04,0x00, // Graphics Format - 0x02,0xC0, // Graphics DataSize - 0x08, // Graphics Count X - 0x04, // Graphics Count Y - 0x0B, // Graphics Width - 0x10, // Graphics Height -BEGIN_DATA - 0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0xFF,0x01,0x01,0x11,0x19,0x7D,0x19,0x11,0x01,0x01,0xFF,0xFF,0x01,0x01,0x11,0x19,0x7D,0x19,0x11,0x05,0x01,0xFF,0xFF,0x01,0x11,0x39,0x7D,0x11,0x1D,0x01,0x05,0x01,0xFF,0xFF,0x01,0x11,0x39,0x7D,0x11,0x71,0x01,0x01,0x01,0xFF,0xFF,0x01,0x11,0x39,0x7D,0x11,0x71,0x01,0x05,0x01,0xFF,0xFF,0x01,0x01,0x01,0x1D,0x11,0x7D,0x39,0x11,0x01,0xFF,0xFF,0x01,0x01,0x01,0x71,0x11,0x7D,0x39,0x11,0x01,0xFF, - 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, - 0xFF,0x01,0x05,0x01,0x71,0x11,0x7D,0x39,0x11,0x01,0xFF,0xFF,0x01,0x11,0x39,0x7D,0x11,0x1D,0x01,0x01,0x01,0xFF,0xFF,0x01,0x01,0x21,0x71,0x71,0x3D,0x01,0x01,0x01,0xFF,0xFF,0x01,0x01,0x21,0x71,0x71,0x3D,0x01,0x01,0x01,0xFF,0xFF,0x01,0x01,0x11,0x31,0x7D,0x31,0x11,0x01,0x01,0xFF,0xFF,0x01,0x01,0x11,0x31,0x7D,0x31,0x11,0x05,0x01,0xFF,0xFF,0x01,0x05,0x01,0x1D,0x11,0x7D,0x39,0x11,0x01,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0xFF,0x01,0x01,0x39,0x45,0x45,0x45,0x39,0x01,0x01,0xFF,0xFF,0x01,0xF1,0x39,0x45,0xFF,0x11,0x45,0x39,0x01,0xFF,0xFF,0x01,0x39,0x29,0x29,0x39,0x45,0x45,0x39,0x01,0xFF,0xFF,0x01,0x01,0x01,0x01,0x01,0x39,0x45,0xFF,0x01,0xFF,0xFF,0x01,0x01,0xC7,0xAB,0x93,0xAB,0xC7,0x01,0x01,0xFF,0xFF,0x01,0x01,0xC7,0xAB,0x93,0xAB,0xC7,0x01,0x01,0xFF,0xFF,0x01,0x01,0xC7,0xAB,0x93,0xAB,0xC7,0x01,0x01,0xFF, - 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, - 0xFF,0x01,0x01,0x39,0x7D,0x7D,0x7D,0x39,0x01,0x01,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x01,0x39,0x41,0x45,0x4F,0x45,0x39,0x01,0x01,0xFF,0xFF,0x01,0x49,0x55,0x25,0x01,0x05,0x7D,0x05,0x01,0xFF, - 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 -END_DATA -}; diff --git a/AT91SAM7S256/Source/Submenu01.rms b/AT91SAM7S256/Source/Submenu01.rms deleted file mode 100644 index aadf93d..0000000 --- a/AT91SAM7S256/Source/Submenu01.rms +++ /dev/null @@ -1,128 +0,0 @@ -const UBYTE SUBMENU01[] = -{ - 0x07,0x00, // Menu Format - 0x01,0xED, // Menu DataSize - 0x1D, // Menu item size - 0x11, // Menu items - 0x18, // Menu icon Width - 0x18, // Menu icon Height - - // Software_files - 0x00,0x00,0x00,0x01, // 0x00000001 - 0x10,0x00,0x80,0x01, // 0x10008001 - 0x06,0x02,0x00,0x01, // 6 ,2 ,0 ,1 - 0x53,0x6F,0x66,0x74,0x77,0x61,0x72,0x65,0x20,0x66,0x69,0x6C,0x65,0x73,0x00,0x00, - 0x1C, // 1C - - // NXT_files - 0x00,0x00,0x00,0x02, // 0x00000002 - 0x10,0x00,0x80,0x01, // 0x10008001 - 0x06,0x03,0x00,0x01, // 6 ,3 ,0 ,1 - 0x4E,0x58,0x54,0x20,0x66,0x69,0x6C,0x65,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x1D, // 1D - - // Sound_files - 0x00,0x00,0x00,0x03, // 0x00000003 - 0x10,0x00,0x80,0x01, // 0x10008001 - 0x06,0x01,0x00,0x01, // 6 ,1 ,0 ,1 - 0x53,0x6F,0x75,0x6E,0x64,0x20,0x66,0x69,0x6C,0x65,0x73,0x00,0x00,0x00,0x00,0x00, - 0x1B, // 1B - - // Datalog_files - 0x00,0x00,0x00,0x04, // 0x00000004 - 0x00,0x80,0x80,0x00, // 0x00808000 - 0x06,0x05,0x00,0x02, // 6 ,5 ,0 ,2 - 0x44,0x61,0x74,0x61,0x6C,0x6F,0x67,0x20,0x66,0x69,0x6C,0x65,0x73,0x00,0x00,0x00, - 0x1F, // 1F - - // _ - 0x00,0x00,0x00,0x11, // 0x00000011 - 0x00,0x00,0x03,0x00, // 0x00000300 - 0x06,0xF2,0x00,0x01, // 6 ,242,0 ,1 - 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00, // 00 - - // _ - 0x00,0x00,0x00,0x14, // 0x00000014 - 0x00,0x00,0x03,0x00, // 0x00000300 - 0x06,0xF2,0x00,0x01, // 6 ,242,0 ,1 - 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00, // 00 - - // Run - 0x00,0x00,0x01,0x11, // 0x00000111 - 0x00,0x00,0x01,0x20, // 0x00000120 - 0x08,0xF8,0x00,0x00, // 8 ,248,0 ,0 - 0x52,0x75,0x6E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x32, // 32 - - // Send - 0x00,0x00,0x02,0x11, // 0x00000211 - 0x00,0x40,0x00,0x00, // 0x00400000 - 0x00,0x00,0x00,0x01, // 0 ,0 ,0 ,1 - 0x53,0x65,0x6E,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x33, // 33 - - // Delete - 0x00,0x00,0x03,0x11, // 0x00000311 - 0x00,0x00,0x00,0x00, // 0x00000000 - 0x00,0x00,0x00,0x02, // 0 ,0 ,0 ,2 - 0x44,0x65,0x6C,0x65,0x74,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x34, // 34 - - // Delete - 0x00,0x00,0x01,0x14, // 0x00000114 - 0x00,0x00,0x00,0x00, // 0x00000000 - 0x00,0x00,0x00,0x02, // 0 ,0 ,0 ,2 - 0x44,0x65,0x6C,0x65,0x74,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x34, // 34 - - // Send - 0x00,0x00,0x02,0x14, // 0x00000214 - 0x00,0x40,0x00,0x00, // 0x00400000 - 0x00,0x00,0x00,0x01, // 0 ,0 ,0 ,1 - 0x53,0x65,0x6E,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x33, // 33 - - // _ - 0x00,0x00,0x12,0x11, // 0x00001211 - 0x00,0x00,0x03,0x00, // 0x00000300 - 0x10,0xF9,0x00,0x00, // 16 ,249,0 ,0 - 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00, // 00 - - // Are_you_sure? - 0x00,0x00,0x13,0x11, // 0x00001311 - 0x00,0x00,0x00,0x08, // 0x00000008 - 0x09,0x00,0x00,0x00, // 9 ,0 ,0 ,0 - 0x41,0x72,0x65,0x20,0x79,0x6F,0x75,0x20,0x73,0x75,0x72,0x65,0x3F,0x00,0x00,0x00, - 0x31, // 31 - - // Are_you_sure? - 0x00,0x00,0x23,0x11, // 0x00002311 - 0x00,0x00,0x00,0x04, // 0x00000004 - 0x00,0x00,0x00,0x00, // 0 ,0 ,0 ,0 - 0x41,0x72,0x65,0x20,0x79,0x6F,0x75,0x20,0x73,0x75,0x72,0x65,0x3F,0x00,0x00,0x00, - 0x30, // 30 - - // Are_you_sure? - 0x00,0x00,0x11,0x14, // 0x00001114 - 0x00,0x00,0x00,0x08, // 0x00000008 - 0x09,0x00,0x00,0x00, // 9 ,0 ,0 ,0 - 0x41,0x72,0x65,0x20,0x79,0x6F,0x75,0x20,0x73,0x75,0x72,0x65,0x3F,0x00,0x00,0x00, - 0x31, // 31 - - // Are_you_sure? - 0x00,0x00,0x21,0x14, // 0x00002114 - 0x00,0x00,0x00,0x04, // 0x00000004 - 0x00,0x00,0x00,0x00, // 0 ,0 ,0 ,0 - 0x41,0x72,0x65,0x20,0x79,0x6F,0x75,0x20,0x73,0x75,0x72,0x65,0x3F,0x00,0x00,0x00, - 0x30, // 30 - - // _ - 0x00,0x00,0x12,0x14, // 0x00001214 - 0x00,0x00,0x03,0x00, // 0x00000300 - 0x10,0xF9,0x00,0x00, // 16 ,249,0 ,0 - 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00, // 00 -}; diff --git a/AT91SAM7S256/Source/Submenu02.rms b/AT91SAM7S256/Source/Submenu02.rms deleted file mode 100644 index a30478f..0000000 --- a/AT91SAM7S256/Source/Submenu02.rms +++ /dev/null @@ -1,401 +0,0 @@ -const UBYTE SUBMENU02[] = -{ - 0x07,0x00, // Menu Format - 0x06,0x58, // Menu DataSize - 0x1D, // Menu item size - 0x38, // Menu items - 0x18, // Menu icon Width - 0x18, // Menu icon Height - - // _ - 0x00,0x00,0x00,0x01, // 0x00000001 - 0x00,0x00,0x03,0x00, // 0x00000300 - 0x0B,0xF7,0x00,0x01, // 11 ,247,0 ,1 - 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00, // 00 - - // Forward_5 - 0x00,0x00,0x00,0x11, // 0x00000011 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x23,0x00,0x01, // 11 ,35 ,0 ,1 - 0x46,0x6F,0x72,0x77,0x61,0x72,0x64,0x20,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x23, // 23 - - // Forward - 0x00,0x00,0x00,0x21, // 0x00000021 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x22,0x00,0x01, // 11 ,34 ,0 ,1 - 0x46,0x6F,0x72,0x77,0x61,0x72,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x22, // 22 - - // Turn_right_2 - 0x00,0x00,0x00,0x31, // 0x00000031 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x29,0x00,0x01, // 11 ,41 ,0 ,1 - 0x54,0x75,0x72,0x6E,0x20,0x72,0x69,0x67,0x68,0x74,0x20,0x32,0x00,0x00,0x00,0x00, - 0x29, // 29 - - // Turn_right - 0x00,0x00,0x00,0x41, // 0x00000041 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x28,0x00,0x01, // 11 ,40 ,0 ,1 - 0x54,0x75,0x72,0x6E,0x20,0x72,0x69,0x67,0x68,0x74,0x00,0x00,0x00,0x00,0x00,0x00, - 0x28, // 28 - - // Back_right_2 - 0x00,0x00,0x00,0x51, // 0x00000051 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x2F,0x00,0x01, // 11 ,47 ,0 ,1 - 0x42,0x61,0x63,0x6B,0x20,0x72,0x69,0x67,0x68,0x74,0x20,0x32,0x00,0x00,0x00,0x00, - 0x2F, // 2F - - // Back_right - 0x00,0x00,0x00,0x61, // 0x00000061 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x27,0x00,0x01, // 11 ,39 ,0 ,1 - 0x42,0x61,0x63,0x6B,0x20,0x72,0x69,0x67,0x68,0x74,0x00,0x00,0x00,0x00,0x00,0x00, - 0x27, // 27 - - // Tone_1 - 0x00,0x00,0x00,0x71, // 0x00000071 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x2B,0x00,0x01, // 11 ,43 ,0 ,1 - 0x54,0x6F,0x6E,0x65,0x20,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x2B, // 2B - - // Tone_2 - 0x00,0x00,0x00,0x81, // 0x00000081 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x2C,0x00,0x01, // 11 ,44 ,0 ,1 - 0x54,0x6F,0x6E,0x65,0x20,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x2C, // 2C - - // Back_left_2 - 0x00,0x00,0x00,0x91, // 0x00000091 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x24,0x00,0x01, // 11 ,36 ,0 ,1 - 0x42,0x61,0x63,0x6B,0x20,0x6C,0x65,0x66,0x74,0x20,0x32,0x00,0x00,0x00,0x00,0x00, - 0x24, // 24 - - // Back_left - 0x00,0x00,0x00,0xA1, // 0x000000A1 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x2A,0x00,0x01, // 11 ,42 ,0 ,1 - 0x42,0x61,0x63,0x6B,0x20,0x6C,0x65,0x66,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x2A, // 2A - - // Turn_left - 0x00,0x00,0x00,0xB1, // 0x000000B1 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x25,0x00,0x01, // 11 ,37 ,0 ,1 - 0x54,0x75,0x72,0x6E,0x20,0x6C,0x65,0x66,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x25, // 25 - - // Turn_left_2 - 0x00,0x00,0x00,0xC1, // 0x000000C1 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x26,0x00,0x01, // 11 ,38 ,0 ,1 - 0x54,0x75,0x72,0x6E,0x20,0x6C,0x65,0x66,0x74,0x20,0x32,0x00,0x00,0x00,0x00,0x00, - 0x26, // 26 - - // Empty - 0x00,0x00,0x00,0xD1, // 0x000000D1 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x21,0x00,0x01, // 11 ,33 ,0 ,1 - 0x45,0x6D,0x70,0x74,0x79,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x21, // 21 - - // Backward - 0x00,0x00,0x00,0xE1, // 0x000000E1 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x2D,0x00,0x01, // 11 ,45 ,0 ,1 - 0x42,0x61,0x63,0x6B,0x77,0x61,0x72,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x2D, // 2D - - // Backward_5 - 0x00,0x00,0x00,0xF1, // 0x000000F1 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x2E,0x00,0x01, // 11 ,46 ,0 ,1 - 0x42,0x61,0x63,0x6B,0x77,0x61,0x72,0x64,0x20,0x35,0x00,0x00,0x00,0x00,0x00,0x00, - 0x2E, // 2E - - // Empty - 0x00,0x00,0x01,0x11, // 0x00000111 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x41,0x00,0x01, // 11 ,65 ,0 ,1 - 0x45,0x6D,0x70,0x74,0x79,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x21, // 21 - - // Wait_2 - 0x00,0x00,0x02,0x11, // 0x00000211 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x46,0x00,0x01, // 11 ,70 ,0 ,1 - 0x57,0x61,0x69,0x74,0x20,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x46, // 46 - - // Wait_5 - 0x00,0x00,0x03,0x11, // 0x00000311 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x47,0x00,0x01, // 11 ,71 ,0 ,1 - 0x57,0x61,0x69,0x74,0x20,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x47, // 47 - - // Wait_10 - 0x00,0x00,0x04,0x11, // 0x00000411 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x48,0x00,0x01, // 11 ,72 ,0 ,1 - 0x57,0x61,0x69,0x74,0x20,0x31,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x48, // 48 - - // Object - 0x00,0x00,0x05,0x11, // 0x00000511 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x43,0x00,0x01, // 11 ,67 ,0 ,1 - 0x4F,0x62,0x6A,0x65,0x63,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x43, // 43 - - // Sound - 0x00,0x00,0x06,0x11, // 0x00000611 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x44,0x00,0x01, // 11 ,68 ,0 ,1 - 0x53,0x6F,0x75,0x6E,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x44, // 44 - - // Light - 0x00,0x00,0x07,0x11, // 0x00000711 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x42,0x00,0x01, // 11 ,66 ,0 ,1 - 0x4C,0x69,0x67,0x68,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x42, // 42 - - // Dark - 0x00,0x00,0x08,0x11, // 0x00000811 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x49,0x00,0x01, // 11 ,73 ,0 ,1 - 0x44,0x61,0x72,0x6B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x49, // 49 - - // Touch - 0x00,0x00,0x09,0x11, // 0x00000911 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x45,0x00,0x01, // 11 ,69 ,0 ,1 - 0x54,0x6F,0x75,0x63,0x68,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x45, // 45 - - // Forward_5 - 0x00,0x00,0x11,0x11, // 0x00001111 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x23,0x00,0x01, // 11 ,35 ,0 ,1 - 0x46,0x6F,0x72,0x77,0x61,0x72,0x64,0x20,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x23, // 23 - - // Forward - 0x00,0x00,0x21,0x11, // 0x00002111 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x22,0x00,0x01, // 11 ,34 ,0 ,1 - 0x46,0x6F,0x72,0x77,0x61,0x72,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x22, // 22 - - // Turn_right_2 - 0x00,0x00,0x31,0x11, // 0x00003111 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x29,0x00,0x01, // 11 ,41 ,0 ,1 - 0x54,0x75,0x72,0x6E,0x20,0x72,0x69,0x67,0x68,0x74,0x20,0x32,0x00,0x00,0x00,0x00, - 0x29, // 29 - - // Turn_right - 0x00,0x00,0x41,0x11, // 0x00004111 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x28,0x00,0x01, // 11 ,40 ,0 ,1 - 0x54,0x75,0x72,0x6E,0x20,0x72,0x69,0x67,0x68,0x74,0x00,0x00,0x00,0x00,0x00,0x00, - 0x28, // 28 - - // Back_right_2 - 0x00,0x00,0x51,0x11, // 0x00005111 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x2F,0x00,0x01, // 11 ,47 ,0 ,1 - 0x42,0x61,0x63,0x6B,0x20,0x72,0x69,0x67,0x68,0x74,0x20,0x32,0x00,0x00,0x00,0x00, - 0x2F, // 2F - - // Back_right - 0x00,0x00,0x61,0x11, // 0x00006111 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x27,0x00,0x01, // 11 ,39 ,0 ,1 - 0x42,0x61,0x63,0x6B,0x20,0x72,0x69,0x67,0x68,0x74,0x00,0x00,0x00,0x00,0x00,0x00, - 0x27, // 27 - - // Tone_1 - 0x00,0x00,0x71,0x11, // 0x00007111 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x2B,0x00,0x01, // 11 ,43 ,0 ,1 - 0x54,0x6F,0x6E,0x65,0x20,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x2B, // 2B - - // Tone_2 - 0x00,0x00,0x81,0x11, // 0x00008111 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x2C,0x00,0x01, // 11 ,44 ,0 ,1 - 0x54,0x6F,0x6E,0x65,0x20,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x2C, // 2C - - // Back_left_2 - 0x00,0x00,0x91,0x11, // 0x00009111 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x24,0x00,0x01, // 11 ,36 ,0 ,1 - 0x42,0x61,0x63,0x6B,0x20,0x6C,0x65,0x66,0x74,0x20,0x32,0x00,0x00,0x00,0x00,0x00, - 0x24, // 24 - - // Back_left - 0x00,0x00,0xA1,0x11, // 0x0000A111 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x2A,0x00,0x01, // 11 ,42 ,0 ,1 - 0x42,0x61,0x63,0x6B,0x20,0x6C,0x65,0x66,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x2A, // 2A - - // Turn_left - 0x00,0x00,0xB1,0x11, // 0x0000B111 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x25,0x00,0x01, // 11 ,37 ,0 ,1 - 0x54,0x75,0x72,0x6E,0x20,0x6C,0x65,0x66,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x25, // 25 - - // Turn_left_2 - 0x00,0x00,0xC1,0x11, // 0x0000C111 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x26,0x00,0x01, // 11 ,38 ,0 ,1 - 0x54,0x75,0x72,0x6E,0x20,0x6C,0x65,0x66,0x74,0x20,0x32,0x00,0x00,0x00,0x00,0x00, - 0x26, // 26 - - // Empty - 0x00,0x00,0xD1,0x11, // 0x0000D111 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x21,0x00,0x01, // 11 ,33 ,0 ,1 - 0x45,0x6D,0x70,0x74,0x79,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x21, // 21 - - // Backward - 0x00,0x00,0xE1,0x11, // 0x0000E111 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x2D,0x00,0x01, // 11 ,45 ,0 ,1 - 0x42,0x61,0x63,0x6B,0x77,0x61,0x72,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x2D, // 2D - - // Backward_5 - 0x00,0x00,0xF1,0x11, // 0x0000F111 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x2E,0x00,0x01, // 11 ,46 ,0 ,1 - 0x42,0x61,0x63,0x6B,0x77,0x61,0x72,0x64,0x20,0x35,0x00,0x00,0x00,0x00,0x00,0x00, - 0x2E, // 2E - - // Empty - 0x00,0x01,0x11,0x11, // 0x00011111 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x41,0x00,0x01, // 11 ,65 ,0 ,1 - 0x45,0x6D,0x70,0x74,0x79,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x21, // 21 - - // Wait_2 - 0x00,0x02,0x11,0x11, // 0x00021111 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x46,0x00,0x01, // 11 ,70 ,0 ,1 - 0x57,0x61,0x69,0x74,0x20,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x46, // 46 - - // Wait_5 - 0x00,0x03,0x11,0x11, // 0x00031111 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x47,0x00,0x01, // 11 ,71 ,0 ,1 - 0x57,0x61,0x69,0x74,0x20,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x47, // 47 - - // Wait_10 - 0x00,0x04,0x11,0x11, // 0x00041111 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x48,0x00,0x01, // 11 ,72 ,0 ,1 - 0x57,0x61,0x69,0x74,0x20,0x31,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x48, // 48 - - // Object - 0x00,0x05,0x11,0x11, // 0x00051111 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x43,0x00,0x01, // 11 ,67 ,0 ,1 - 0x4F,0x62,0x6A,0x65,0x63,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x43, // 43 - - // Sound - 0x00,0x06,0x11,0x11, // 0x00061111 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x44,0x00,0x01, // 11 ,68 ,0 ,1 - 0x53,0x6F,0x75,0x6E,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x44, // 44 - - // Light - 0x00,0x07,0x11,0x11, // 0x00071111 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x42,0x00,0x01, // 11 ,66 ,0 ,1 - 0x4C,0x69,0x67,0x68,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x42, // 42 - - // Dark - 0x00,0x08,0x11,0x11, // 0x00081111 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x49,0x00,0x01, // 11 ,73 ,0 ,1 - 0x44,0x61,0x72,0x6B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x49, // 49 - - // Touch - 0x00,0x09,0x11,0x11, // 0x00091111 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0x45,0x00,0x01, // 11 ,69 ,0 ,1 - 0x54,0x6F,0x75,0x63,0x68,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x45, // 45 - - // Stop - 0x00,0x11,0x11,0x11, // 0x00111111 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0xFB,0x00,0x01, // 11 ,251,0 ,1 - 0x53,0x74,0x6F,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x4D, // 4D - - // Loop - 0x00,0x21,0x11,0x11, // 0x00211111 - 0x10,0x00,0x00,0x61, // 0x10000061 - 0x0B,0xFC,0x00,0x01, // 11 ,252,0 ,1 - 0x4C,0x6F,0x6F,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x4E, // 4E - - // Run - 0x01,0x11,0x11,0x11, // 0x01111111 - 0x00,0x00,0x00,0x60, // 0x00000060 - 0x0B,0xF8,0x00,0x00, // 11 ,248,0 ,0 - 0x52,0x75,0x6E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x32, // 32 - - // Main_menu - 0x02,0x11,0x11,0x11, // 0x02111111 - 0x00,0x00,0x20,0x60, // 0x00002060 - 0x00,0x00,0x00,0x00, // 0 ,0 ,0 ,0 - 0x4D,0x61,0x69,0x6E,0x20,0x6D,0x65,0x6E,0x75,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x37, // 37 - - // Save - 0x04,0x11,0x11,0x11, // 0x04111111 - 0x00,0x00,0x00,0x60, // 0x00000060 - 0x0B,0xFA,0x00,0x02, // 11 ,250,0 ,2 - 0x53,0x61,0x76,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x1D, // 1D - - // Yes - 0x14,0x11,0x11,0x11, // 0x14111111 - 0x00,0x00,0x20,0x20, // 0x00002020 - 0x0B,0xED,0x00,0x00, // 11 ,237,0 ,0 - 0x59,0x65,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x31, // 31 - - // No - 0x24,0x11,0x11,0x11, // 0x24111111 - 0x00,0x08,0x00,0x24, // 0x00080024 - 0x0B,0xF6,0x00,0x00, // 11 ,246,0 ,0 - 0x4E,0x6F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x30, // 30 -}; diff --git a/AT91SAM7S256/Source/Submenu03.rms b/AT91SAM7S256/Source/Submenu03.rms deleted file mode 100644 index cb7830b..0000000 --- a/AT91SAM7S256/Source/Submenu03.rms +++ /dev/null @@ -1,233 +0,0 @@ -const UBYTE SUBMENU03[] = -{ - 0x07,0x00, // Menu Format - 0x03,0xA0, // Menu DataSize - 0x1D, // Menu item size - 0x20, // Menu items - 0x18, // Menu icon Width - 0x18, // Menu icon Height - - // Temperature_`C - 0x00,0x00,0x00,0x01, // 0x00000001 - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0A,0x0B,0x00,0x01, // 10 ,11 ,0 ,1 - 0x54,0x65,0x6D,0x70,0x65,0x72,0x61,0x74,0x75,0x72,0x65,0x20,0x60,0x43,0x00,0x00, - 0x0F, // 0F - - // Temperature_`F - 0x00,0x00,0x00,0x02, // 0x00000002 - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0A,0x0C,0x00,0x01, // 10 ,12 ,0 ,1 - 0x54,0x65,0x6D,0x70,0x65,0x72,0x61,0x74,0x75,0x72,0x65,0x20,0x60,0x46,0x00,0x00, - 0x10, // 10 - - // Sound_dB - 0x00,0x00,0x00,0x03, // 0x00000003 - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0A,0x02,0x00,0x01, // 10 ,2 ,0 ,1 - 0x53,0x6F,0x75,0x6E,0x64,0x20,0x64,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x02, // 02 - - // Sound_dBA - 0x00,0x00,0x00,0x04, // 0x00000004 - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0A,0x03,0x00,0x01, // 10 ,3 ,0 ,1 - 0x53,0x6F,0x75,0x6E,0x64,0x20,0x64,0x42,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x03, // 03 - - // Reflected_light - 0x00,0x00,0x00,0x05, // 0x00000005 - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0A,0x04,0x00,0x01, // 10 ,4 ,0 ,1 - 0x52,0x65,0x66,0x6C,0x65,0x63,0x74,0x65,0x64,0x20,0x6C,0x69,0x67,0x68,0x74,0x00, - 0x04, // 04 - - // Ambient_light - 0x00,0x00,0x00,0x06, // 0x00000006 - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0A,0x05,0x00,0x01, // 10 ,5 ,0 ,1 - 0x41,0x6D,0x62,0x69,0x65,0x6E,0x74,0x20,0x6C,0x69,0x67,0x68,0x74,0x00,0x00,0x00, - 0x05, // 05 - - // Motor_Rotations - 0x00,0x00,0x00,0x07, // 0x00000007 - 0x00,0x00,0x00,0x20, // 0x00000020 - 0x0A,0x08,0x00,0x01, // 10 ,8 ,0 ,1 - 0x4D,0x6F,0x74,0x6F,0x72,0x20,0x52,0x6F,0x74,0x61,0x74,0x69,0x6F,0x6E,0x73,0x00, - 0x09, // 09 - - // Motor_Degrees - 0x00,0x00,0x00,0x08, // 0x00000008 - 0x00,0x00,0x00,0x20, // 0x00000020 - 0x0A,0x07,0x00,0x01, // 10 ,7 ,0 ,1 - 0x4D,0x6F,0x74,0x6F,0x72,0x20,0x44,0x65,0x67,0x72,0x65,0x65,0x73,0x00,0x00,0x00, - 0x08, // 08 - - // Touch - 0x00,0x00,0x00,0x09, // 0x00000009 - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0A,0x06,0x00,0x01, // 10 ,6 ,0 ,1 - 0x54,0x6F,0x75,0x63,0x68,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x07, // 07 - - // UltraSonic_inch - 0x00,0x00,0x00,0x0A, // 0x0000000A - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0A,0x09,0x00,0x01, // 10 ,9 ,0 ,1 - 0x55,0x6C,0x74,0x72,0x61,0x53,0x6F,0x6E,0x69,0x63,0x20,0x69,0x6E,0x63,0x68,0x00, - 0x0B, // 0B - - // UltraSonic_cm - 0x00,0x00,0x00,0x0B, // 0x0000000B - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0A,0x0A,0x00,0x01, // 10 ,10 ,0 ,1 - 0x55,0x6C,0x74,0x72,0x61,0x53,0x6F,0x6E,0x69,0x63,0x20,0x63,0x6D,0x00,0x00,0x00, - 0x0C, // 0C - - // Color - 0x00,0x00,0x00,0x0C, // 0x0000000C - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0A,0x0D,0x00,0x01, // 10 ,13 ,0 ,1 - 0x43,0x6F,0x6C,0x6F,0x72,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x11, // 11 - - // Done - 0x00,0x00,0x00,0x0D, // 0x0000000D - 0x00,0x00,0x00,0x20, // 0x00000020 - 0x0A,0xEE,0x00,0x01, // 10 ,238,0 ,1 - 0x44,0x6F,0x6E,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x31, // 31 - - // Port_1 - 0x00,0x00,0x00,0x11, // 0x00000011 - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0A,0x12,0x00,0x01, // 10 ,18 ,0 ,1 - 0x50,0x6F,0x72,0x74,0x20,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x12, // 12 - - // Port_2 - 0x00,0x00,0x00,0x21, // 0x00000021 - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0A,0x13,0x00,0x01, // 10 ,19 ,0 ,1 - 0x50,0x6F,0x72,0x74,0x20,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x13, // 13 - - // Port_3 - 0x00,0x00,0x00,0x31, // 0x00000031 - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0A,0x14,0x00,0x01, // 10 ,20 ,0 ,1 - 0x50,0x6F,0x72,0x74,0x20,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x14, // 14 - - // Port_4 - 0x00,0x00,0x00,0x41, // 0x00000041 - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0A,0x15,0x00,0x01, // 10 ,21 ,0 ,1 - 0x50,0x6F,0x72,0x74,0x20,0x34,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x15, // 15 - - // Port_A - 0x00,0x00,0x00,0x17, // 0x00000017 - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0A,0x16,0x00,0x01, // 10 ,22 ,0 ,1 - 0x50,0x6F,0x72,0x74,0x20,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x16, // 16 - - // Port_B - 0x00,0x00,0x00,0x27, // 0x00000027 - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0A,0x17,0x00,0x01, // 10 ,23 ,0 ,1 - 0x50,0x6F,0x72,0x74,0x20,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x17, // 17 - - // Port_C - 0x00,0x00,0x00,0x37, // 0x00000037 - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0A,0x18,0x00,0x01, // 10 ,24 ,0 ,1 - 0x50,0x6F,0x72,0x74,0x20,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x18, // 18 - - // Port_A - 0x00,0x00,0x00,0x18, // 0x00000018 - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0A,0x16,0x00,0x01, // 10 ,22 ,0 ,1 - 0x50,0x6F,0x72,0x74,0x20,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x16, // 16 - - // Port_B - 0x00,0x00,0x00,0x28, // 0x00000028 - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0A,0x17,0x00,0x01, // 10 ,23 ,0 ,1 - 0x50,0x6F,0x72,0x74,0x20,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x17, // 17 - - // Port_C - 0x00,0x00,0x00,0x38, // 0x00000038 - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0A,0x18,0x00,0x01, // 10 ,24 ,0 ,1 - 0x50,0x6F,0x72,0x74,0x20,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x17, // 17 - - // _ - 0x00,0x00,0x00,0x1D, // 0x0000001D - 0x00,0x00,0x10,0x00, // 0x00001000 - 0x0A,0xF7,0x00,0x01, // 10 ,247,0 ,1 - 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00, // 00 - - // _ - 0x00,0x00,0x01,0x11, // 0x00000111 - 0x0D,0x05,0x10,0x00, // 0x0D051000 - 0x0A,0xF2,0x00,0x00, // 10 ,242,0 ,0 - 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00, // 00 - - // _ - 0x00,0x00,0x01,0x17, // 0x00000117 - 0x0D,0x05,0x10,0x00, // 0x0D051000 - 0x0A,0xF2,0x00,0x00, // 10 ,242,0 ,0 - 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00, // 00 - - // _ - 0x00,0x00,0x01,0x18, // 0x00000118 - 0x0D,0x05,0x10,0x00, // 0x0D051000 - 0x0A,0xF2,0x00,0x00, // 10 ,242,0 ,0 - 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00, // 00 - - // Run - 0x00,0x00,0x01,0x1D, // 0x0000011D - 0x00,0x00,0x00,0x68, // 0x00000068 - 0x0A,0xF8,0x00,0x02, // 10 ,248,0 ,2 - 0x52,0x75,0x6E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x32, // 32 - - // Main_menu - 0x00,0x00,0x11,0x1D, // 0x0000111D - 0x00,0x02,0x20,0x00, // 0x00022000 - 0x0A,0xF1,0x00,0x00, // 10 ,241,0 ,0 - 0x4D,0x61,0x69,0x6E,0x20,0x6D,0x65,0x6E,0x75,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x37, // 37 - - // Save - 0x00,0x00,0x21,0x1D, // 0x0000211D - 0x00,0x02,0x00,0x00, // 0x00020000 - 0x0A,0xFA,0x00,0x02, // 10 ,250,0 ,2 - 0x53,0x61,0x76,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x1F, // 1F - - // Yes - 0x00,0x01,0x21,0x1D, // 0x0001211D - 0x00,0x00,0x20,0x20, // 0x00002020 - 0x0A,0xED,0x00,0x00, // 10 ,237,0 ,0 - 0x59,0x65,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x31, // 31 - - // No - 0x00,0x02,0x21,0x1D, // 0x0002211D - 0x00,0x08,0x00,0x24, // 0x00080024 - 0x00,0x00,0x00,0x00, // 0 ,0 ,0 ,0 - 0x4E,0x6F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x30, // 30 -}; diff --git a/AT91SAM7S256/Source/Submenu04.rms b/AT91SAM7S256/Source/Submenu04.rms deleted file mode 100644 index 273e456..0000000 --- a/AT91SAM7S256/Source/Submenu04.rms +++ /dev/null @@ -1,163 +0,0 @@ -const UBYTE SUBMENU04[] = -{ - 0x07,0x00, // Menu Format - 0x02,0x7E, // Menu DataSize - 0x1D, // Menu item size - 0x16, // Menu items - 0x18, // Menu icon Width - 0x18, // Menu icon Height - - // Sound_dB - 0x00,0x00,0x00,0x01, // 0x00000001 - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0E,0x02,0x00,0x01, // 14 ,2 ,0 ,1 - 0x53,0x6F,0x75,0x6E,0x64,0x20,0x64,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x02, // 02 - - // Sound_dBA - 0x00,0x00,0x00,0x02, // 0x00000002 - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0E,0x03,0x00,0x01, // 14 ,3 ,0 ,1 - 0x53,0x6F,0x75,0x6E,0x64,0x20,0x64,0x42,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x03, // 03 - - // Reflected_light - 0x00,0x00,0x00,0x03, // 0x00000003 - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0E,0x04,0x00,0x01, // 14 ,4 ,0 ,1 - 0x52,0x65,0x66,0x6C,0x65,0x63,0x74,0x65,0x64,0x20,0x6C,0x69,0x67,0x68,0x74,0x00, - 0x04, // 04 - - // Ambient_light - 0x00,0x00,0x00,0x04, // 0x00000004 - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0E,0x05,0x00,0x01, // 14 ,5 ,0 ,1 - 0x41,0x6D,0x62,0x69,0x65,0x6E,0x74,0x20,0x6C,0x69,0x67,0x68,0x74,0x00,0x00,0x00, - 0x05, // 05 - - // Temperature_`C - 0x00,0x00,0x00,0x05, // 0x00000005 - 0x10,0x00,0x01,0x21, // 0x10000121 - 0x0E,0x0B,0x00,0x01, // 14 ,11 ,0 ,1 - 0x54,0x65,0x6D,0x70,0x65,0x72,0x61,0x74,0x75,0x72,0x65,0x20,0x60,0x43,0x00,0x00, - 0x0F, // 0F - - // Temperature_`F - 0x00,0x00,0x00,0x06, // 0x00000006 - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0E,0x0C,0x00,0x01, // 14 ,12 ,0 ,1 - 0x54,0x65,0x6D,0x70,0x65,0x72,0x61,0x74,0x75,0x72,0x65,0x20,0x60,0x46,0x00,0x00, - 0x10, // 10 - - // Motor_rotations - 0x00,0x00,0x00,0x07, // 0x00000007 - 0x00,0x00,0x00,0x20, // 0x00000020 - 0x0E,0x08,0x00,0x01, // 14 ,8 ,0 ,1 - 0x4D,0x6F,0x74,0x6F,0x72,0x20,0x72,0x6F,0x74,0x61,0x74,0x69,0x6F,0x6E,0x73,0x00, - 0x09, // 09 - - // Motor_degrees - 0x00,0x00,0x00,0x08, // 0x00000008 - 0x00,0x00,0x00,0x20, // 0x00000020 - 0x0E,0x07,0x00,0x01, // 14 ,7 ,0 ,1 - 0x4D,0x6F,0x74,0x6F,0x72,0x20,0x64,0x65,0x67,0x72,0x65,0x65,0x73,0x00,0x00,0x00, - 0x08, // 08 - - // Touch - 0x00,0x00,0x00,0x09, // 0x00000009 - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0E,0x06,0x00,0x01, // 14 ,6 ,0 ,1 - 0x54,0x6F,0x75,0x63,0x68,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x07, // 07 - - // Ultrasonic_inch - 0x00,0x00,0x00,0x0A, // 0x0000000A - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0E,0x09,0x00,0x01, // 14 ,9 ,0 ,1 - 0x55,0x6C,0x74,0x72,0x61,0x73,0x6F,0x6E,0x69,0x63,0x20,0x69,0x6E,0x63,0x68,0x00, - 0x0B, // 0B - - // Ultrasonic_cm - 0x00,0x00,0x00,0x0B, // 0x0000000B - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0E,0x0A,0x00,0x01, // 14 ,10 ,0 ,1 - 0x55,0x6C,0x74,0x72,0x61,0x73,0x6F,0x6E,0x69,0x63,0x20,0x63,0x6D,0x00,0x00,0x00, - 0x0C, // 0C - - // Color - 0x00,0x00,0x00,0x0C, // 0x0000000C - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0E,0x0D,0x00,0x01, // 14 ,13 ,0 ,1 - 0x43,0x6F,0x6C,0x6F,0x72,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x11, // 11 - - // Port_1 - 0x00,0x00,0x00,0x11, // 0x00000011 - 0x00,0x00,0x00,0x20, // 0x00000020 - 0x0E,0x12,0x00,0x00, // 14 ,18 ,0 ,0 - 0x50,0x6F,0x72,0x74,0x20,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x12, // 12 - - // Port_2 - 0x00,0x00,0x00,0x21, // 0x00000021 - 0x00,0x00,0x00,0x20, // 0x00000020 - 0x0E,0x13,0x00,0x00, // 14 ,19 ,0 ,0 - 0x50,0x6F,0x72,0x74,0x20,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x13, // 13 - - // Port_3 - 0x00,0x00,0x00,0x31, // 0x00000031 - 0x00,0x00,0x00,0x20, // 0x00000020 - 0x0E,0x14,0x00,0x00, // 14 ,20 ,0 ,0 - 0x50,0x6F,0x72,0x74,0x20,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x14, // 14 - - // Port_4 - 0x00,0x00,0x00,0x41, // 0x00000041 - 0x00,0x00,0x00,0x20, // 0x00000020 - 0x0E,0x15,0x00,0x00, // 14 ,21 ,0 ,0 - 0x50,0x6F,0x72,0x74,0x20,0x34,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x15, // 15 - - // Port_A - 0x00,0x00,0x00,0x17, // 0x00000017 - 0x00,0x00,0x00,0x20, // 0x00000020 - 0x0E,0x16,0x00,0x00, // 14 ,22 ,0 ,0 - 0x50,0x6F,0x72,0x74,0x20,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x16, // 16 - - // Port_B - 0x00,0x00,0x00,0x27, // 0x00000027 - 0x00,0x00,0x00,0x20, // 0x00000020 - 0x0E,0x17,0x00,0x00, // 14 ,23 ,0 ,0 - 0x50,0x6F,0x72,0x74,0x20,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x17, // 17 - - // Port_C - 0x00,0x00,0x00,0x37, // 0x00000037 - 0x00,0x00,0x00,0x20, // 0x00000020 - 0x0E,0x18,0x00,0x00, // 14 ,24 ,0 ,0 - 0x50,0x6F,0x72,0x74,0x20,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x18, // 18 - - // Port_A - 0x00,0x00,0x00,0x18, // 0x00000018 - 0x00,0x00,0x00,0x20, // 0x00000020 - 0x0E,0x16,0x00,0x00, // 14 ,22 ,0 ,0 - 0x50,0x6F,0x72,0x74,0x20,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x16, // 16 - - // Port_B - 0x00,0x00,0x00,0x28, // 0x00000028 - 0x00,0x00,0x00,0x20, // 0x00000020 - 0x0E,0x17,0x00,0x00, // 14 ,23 ,0 ,0 - 0x50,0x6F,0x72,0x74,0x20,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x17, // 17 - - // Port_C - 0x00,0x00,0x00,0x38, // 0x00000038 - 0x00,0x00,0x00,0x20, // 0x00000020 - 0x0E,0x18,0x00,0x00, // 14 ,24 ,0 ,0 - 0x50,0x6F,0x72,0x74,0x20,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x18, // 18 -}; diff --git a/AT91SAM7S256/Source/Submenu05.rms b/AT91SAM7S256/Source/Submenu05.rms deleted file mode 100644 index 5e03396..0000000 --- a/AT91SAM7S256/Source/Submenu05.rms +++ /dev/null @@ -1,128 +0,0 @@ -const UBYTE SUBMENU05[] = -{ - 0x07,0x00, // Menu Format - 0x01,0xED, // Menu DataSize - 0x1D, // Menu item size - 0x11, // Menu items - 0x18, // Menu icon Width - 0x18, // Menu icon Height - - // Volume - 0x00,0x00,0x00,0x01, // 0x00000001 - 0x00,0x00,0x80,0x00, // 0x00008000 - 0x00,0x00,0x00,0x01, // 0 ,0 ,0 ,1 - 0x56,0x6F,0x6C,0x75,0x6D,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x39, // 39 - - // Sleep - 0x00,0x00,0x00,0x02, // 0x00000002 - 0x00,0x00,0x80,0x00, // 0x00008000 - 0x00,0x00,0x00,0x01, // 0 ,0 ,0 ,1 - 0x53,0x6C,0x65,0x65,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x3A, // 3A - - // NXT_Version - 0x00,0x00,0x00,0x03, // 0x00000003 - 0x00,0x00,0x00,0x00, // 0x00000000 - 0x01,0x00,0x00,0x00, // 1 ,0 ,0 ,0 - 0x4E,0x58,0x54,0x20,0x56,0x65,0x72,0x73,0x69,0x6F,0x6E,0x00,0x00,0x00,0x00,0x00, - 0x4F, // 4F - - // Delete_files - 0x00,0x00,0x00,0x04, // 0x00000004 - 0x00,0x00,0x80,0x00, // 0x00008000 - 0x00,0x00,0x00,0x01, // 0 ,0 ,0 ,1 - 0x44,0x65,0x6C,0x65,0x74,0x65,0x20,0x66,0x69,0x6C,0x65,0x73,0x00,0x00,0x00,0x00, - 0x34, // 34 - - // _ - 0x00,0x00,0x00,0x11, // 0x00000011 - 0x00,0x00,0x03,0x60, // 0x00000360 - 0x07,0xEF,0x00,0x00, // 7 ,239,0 ,0 - 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x39, // 39 - - // _ - 0x00,0x00,0x00,0x21, // 0x00000021 - 0x00,0x00,0x00,0x00, // 0x00000000 - 0x00,0x00,0x00,0x00, // 0 ,0 ,0 ,0 - 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x35, // 35 - - // _ - 0x00,0x00,0x00,0x31, // 0x00000031 - 0x00,0x00,0x00,0x00, // 0x00000000 - 0x00,0x00,0x00,0x00, // 0 ,0 ,0 ,0 - 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x36, // 36 - - // _ - 0x00,0x00,0x00,0x12, // 0x00000012 - 0x00,0x00,0x03,0x20, // 0x00000320 - 0x04,0xEF,0x00,0x00, // 4 ,239,0 ,0 - 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x3A, // 3A - - // _ - 0x00,0x00,0x00,0x22, // 0x00000022 - 0x00,0x00,0x00,0x00, // 0x00000000 - 0x00,0x00,0x00,0x00, // 0 ,0 ,0 ,0 - 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x35, // 35 - - // _ - 0x00,0x00,0x00,0x32, // 0x00000032 - 0x00,0x00,0x00,0x00, // 0x00000000 - 0x00,0x00,0x00,0x00, // 0 ,0 ,0 ,0 - 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x36, // 36 - - // Software_files - 0x00,0x00,0x00,0x14, // 0x00000014 - 0x10,0x00,0x00,0x01, // 0x10000001 - 0x05,0x02,0x00,0x02, // 5 ,2 ,0 ,2 - 0x53,0x6F,0x66,0x74,0x77,0x61,0x72,0x65,0x20,0x66,0x69,0x6C,0x65,0x73,0x00,0x00, - 0x1C, // 1C - - // NXT_files - 0x00,0x00,0x00,0x24, // 0x00000024 - 0x10,0x00,0x00,0x01, // 0x10000001 - 0x05,0x03,0x00,0x02, // 5 ,3 ,0 ,2 - 0x4E,0x58,0x54,0x20,0x66,0x69,0x6C,0x65,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x1D, // 1D - - // Sound_files - 0x00,0x00,0x00,0x34, // 0x00000034 - 0x10,0x00,0x00,0x01, // 0x10000001 - 0x05,0x01,0x00,0x02, // 5 ,1 ,0 ,2 - 0x53,0x6F,0x75,0x6E,0x64,0x20,0x66,0x69,0x6C,0x65,0x73,0x00,0x00,0x00,0x00,0x00, - 0x1B, // 1B - - // Datalog_files - 0x00,0x00,0x00,0x44, // 0x00000044 - 0x10,0x80,0x00,0x01, // 0x10800001 - 0x05,0x05,0x00,0x02, // 5 ,5 ,0 ,2 - 0x44,0x61,0x74,0x61,0x6C,0x6F,0x67,0x20,0x66,0x69,0x6C,0x65,0x73,0x00,0x00,0x00, - 0x1F, // 1F - - // Try_me_files - 0x00,0x00,0x00,0x54, // 0x00000054 - 0x10,0x00,0x00,0x01, // 0x10000001 - 0x05,0x04,0x00,0x02, // 5 ,4 ,0 ,2 - 0x54,0x72,0x79,0x20,0x6D,0x65,0x20,0x66,0x69,0x6C,0x65,0x73,0x00,0x00,0x00,0x00, - 0x1E, // 1E - - // Are_you_sure? - 0x00,0x00,0x01,0x14, // 0x00000114 - 0x00,0x00,0x01,0x08, // 0x00000108 - 0x05,0xF1,0x00,0x00, // 5 ,241,0 ,0 - 0x41,0x72,0x65,0x20,0x79,0x6F,0x75,0x20,0x73,0x75,0x72,0x65,0x3F,0x00,0x00,0x00, - 0x31, // 31 - - // Are_you_sure? - 0x00,0x00,0x02,0x14, // 0x00000214 - 0x00,0x00,0x01,0x04, // 0x00000104 - 0x05,0x00,0x00,0x00, // 5 ,0 ,0 ,0 - 0x41,0x72,0x65,0x20,0x79,0x6F,0x75,0x20,0x73,0x75,0x72,0x65,0x3F,0x00,0x00,0x00, - 0x30, // 30 -}; diff --git a/AT91SAM7S256/Source/Submenu06.rms b/AT91SAM7S256/Source/Submenu06.rms deleted file mode 100644 index 5cd1b06..0000000 --- a/AT91SAM7S256/Source/Submenu06.rms +++ /dev/null @@ -1,51 +0,0 @@ -const UBYTE SUBMENU06[] = -{ - 0x07,0x00, // Menu Format - 0x00,0xAE, // Menu DataSize - 0x1D, // Menu item size - 0x06, // Menu items - 0x18, // Menu icon Width - 0x18, // Menu icon Height - - // _ - 0x00,0x00,0x00,0x01, // 0x00000001 - 0x00,0x00,0x10,0x00, // 0x00001000 - 0x06,0x04,0x00,0x01, // 6 ,4 ,0 ,1 - 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x1E, // 1E - - // _ - 0x00,0x00,0x00,0x11, // 0x00000011 - 0x00,0x00,0x03,0x80, // 0x00000380 - 0x06,0xF2,0x00,0x02, // 6 ,242,0 ,2 - 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x1E, // 1E - - // Delete - 0x00,0x00,0x01,0x11, // 0x00000111 - 0x00,0x00,0x00,0x00, // 0x00000000 - 0x00,0x00,0x00,0x02, // 0 ,0 ,0 ,2 - 0x44,0x65,0x6C,0x65,0x74,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x34, // 34 - - // Run - 0x00,0x00,0x02,0x11, // 0x00000211 - 0x00,0x00,0x01,0x20, // 0x00000120 - 0x08,0xF8,0x00,0x00, // 8 ,248,0 ,0 - 0x52,0x75,0x6E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x32, // 32 - - // Are_you_sure? - 0x00,0x00,0x11,0x11, // 0x00001111 - 0x00,0x00,0x00,0x08, // 0x00000008 - 0x09,0x00,0x00,0x00, // 9 ,0 ,0 ,0 - 0x41,0x72,0x65,0x20,0x79,0x6F,0x75,0x20,0x73,0x75,0x72,0x65,0x3F,0x00,0x00,0x00, - 0x31, // 31 - - // Are_you_sure? - 0x00,0x00,0x21,0x11, // 0x00002111 - 0x00,0x00,0x00,0x04, // 0x00000004 - 0x00,0x00,0x00,0x00, // 0 ,0 ,0 ,0 - 0x41,0x72,0x65,0x20,0x79,0x6F,0x75,0x20,0x73,0x75,0x72,0x65,0x3F,0x00,0x00,0x00, - 0x30, // 30 -}; diff --git a/AT91SAM7S256/Source/Submenu07.rms b/AT91SAM7S256/Source/Submenu07.rms deleted file mode 100644 index 43c292e..0000000 --- a/AT91SAM7S256/Source/Submenu07.rms +++ /dev/null @@ -1,142 +0,0 @@ -const UBYTE SUBMENU07[] = -{ - 0x07,0x00, // Menu Format - 0x02,0x27, // Menu DataSize - 0x1D, // Menu item size - 0x13, // Menu items - 0x18, // Menu icon Width - 0x18, // Menu icon Height - - // Search - 0x00,0x00,0x00,0x01, // 0x00000001 - 0x00,0x40,0x80,0x00, // 0x00408000 - 0x00,0x00,0x00,0x01, // 0 ,0 ,0 ,1 - 0x53,0x65,0x61,0x72,0x63,0x68,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x56, // 56 - - // My_contacts - 0x00,0x00,0x00,0x02, // 0x00000002 - 0x00,0x40,0x80,0x00, // 0x00408000 - 0x00,0x00,0x00,0x01, // 0 ,0 ,0 ,1 - 0x4D,0x79,0x20,0x63,0x6F,0x6E,0x74,0x61,0x63,0x74,0x73,0x00,0x00,0x00,0x00,0x00, - 0x52, // 52 - - // Connections - 0x00,0x00,0x00,0x03, // 0x00000003 - 0x00,0x40,0x80,0x00, // 0x00408000 - 0x00,0x00,0x00,0x01, // 0 ,0 ,0 ,1 - 0x43,0x6F,0x6E,0x6E,0x65,0x63,0x74,0x69,0x6F,0x6E,0x73,0x00,0x00,0x00,0x00,0x00, - 0x53, // 53 - - // Visibility - 0x00,0x00,0x00,0x04, // 0x00000004 - 0x00,0x40,0x80,0x00, // 0x00408000 - 0x00,0x00,0x00,0x01, // 0 ,0 ,0 ,1 - 0x56,0x69,0x73,0x69,0x62,0x69,0x6C,0x69,0x74,0x79,0x00,0x00,0x00,0x00,0x00,0x00, - 0x54, // 54 - - // On/Off - 0x00,0x00,0x00,0x05, // 0x00000005 - 0x00,0x00,0x80,0x00, // 0x00008000 - 0x00,0x00,0x00,0x01, // 0 ,0 ,0 ,1 - 0x4F,0x6E,0x2F,0x4F,0x66,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x55, // 55 - - // _ - 0x00,0x00,0x00,0x11, // 0x00000011 - 0x00,0x00,0x03,0x00, // 0x00000300 - 0x12,0xFF,0x00,0x01, // 18 ,255,0 ,1 - 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x57, // 57 - - // _ - 0x00,0x00,0x00,0x12, // 0x00000012 - 0x00,0x00,0x10,0x00, // 0x00001000 - 0x00,0x00,0x00,0x01, // 0 ,0 ,0 ,1 - 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x57, // 57 - - // _ - 0x00,0x00,0x00,0x13, // 0x00000013 - 0x00,0x00,0x03,0x00, // 0x00000300 - 0x14,0xF6,0x00,0x01, // 20 ,246,0 ,1 - 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x57, // 57 - - // Visible - 0x00,0x00,0x00,0x14, // 0x00000014 - 0x00,0x00,0x00,0x00, // 0x00000000 - 0x11,0xEB,0x00,0x00, // 17 ,235,0 ,0 - 0x56,0x69,0x73,0x69,0x62,0x6C,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x5A, // 5A - - // Invisible - 0x00,0x00,0x00,0x24, // 0x00000024 - 0x00,0x00,0x00,0x00, // 0x00000000 - 0x11,0xEA,0x00,0x00, // 17 ,234,0 ,0 - 0x49,0x6E,0x76,0x69,0x73,0x69,0x62,0x6C,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x5B, // 5B - - // On - 0x00,0x00,0x00,0x15, // 0x00000015 - 0x00,0x00,0x00,0x80, // 0x00000080 - 0x03,0xEB,0x00,0x00, // 3 ,235,0 ,0 - 0x4F,0x6E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x5C, // 5C - - // Off - 0x00,0x00,0x00,0x25, // 0x00000025 - 0x00,0x40,0x00,0x80, // 0x00400080 - 0x03,0xEA,0x00,0x00, // 3 ,234,0 ,0 - 0x4F,0x66,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x5D, // 5D - - // _ - 0x00,0x00,0x01,0x11, // 0x00000111 - 0x00,0x00,0x03,0x08, // 0x00000308 - 0x13,0xF2,0x00,0x01, // 19 ,242,0 ,1 - 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x57, // 57 - - // _ - 0x00,0x00,0x01,0x12, // 0x00000112 - 0x00,0x10,0x02,0x08, // 0x00100208 - 0x13,0xF2,0x00,0x02, // 19 ,242,0 ,2 - 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x57, // 57 - - // Disconnect - 0x00,0x00,0x01,0x13, // 0x00000113 - 0x00,0x00,0x00,0x00, // 0x00000000 - 0x14,0xF0,0x00,0x00, // 20 ,240,0 ,0 - 0x44,0x69,0x73,0x63,0x6F,0x6E,0x6E,0x65,0x63,0x74,0x00,0x00,0x00,0x00,0x00,0x00, - 0x59, // 59 - - // _ - 0x00,0x00,0x11,0x11, // 0x00001111 - 0x00,0x00,0x03,0x00, // 0x00000300 - 0x10,0xF5,0x00,0x00, // 16 ,245,0 ,0 - 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x57, // 57 - - // Delete - 0x00,0x00,0x11,0x12, // 0x00001112 - 0x00,0x00,0x00,0x00, // 0x00000000 - 0x13,0xF1,0x00,0x00, // 19 ,241,0 ,0 - 0x44,0x65,0x6C,0x65,0x74,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x34, // 34 - - // Connect - 0x00,0x00,0x21,0x12, // 0x00002112 - 0x00,0x00,0x00,0x00, // 0x00000000 - 0x00,0x00,0x00,0x01, // 0 ,0 ,0 ,1 - 0x43,0x6F,0x6E,0x6E,0x65,0x63,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x58, // 58 - - // _ - 0x00,0x01,0x21,0x12, // 0x00012112 - 0x00,0x00,0x03,0x08, // 0x00000308 - 0x10,0xF5,0x00,0x00, // 16 ,245,0 ,0 - 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x57, // 57 -}; diff --git a/AT91SAM7S256/Source/Test1.txt b/AT91SAM7S256/Source/Test1.txt deleted file mode 100644 index 018d27d..0000000 --- a/AT91SAM7S256/Source/Test1.txt +++ /dev/null @@ -1,19 +0,0 @@ -DEFINE_DATA(BMPMAP, Test1) = -{ - 0x02,0x00, // Graphics Format - 0x04,0x00, // Graphics DataSize - 0x00, // Graphics Start X - 0x00, // Graphics Start Y - 0x80, // Graphics Width - 0x40, // Graphics Height -BEGIN_DATA - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF -END_DATA -}; diff --git a/AT91SAM7S256/Source/Test2.txt b/AT91SAM7S256/Source/Test2.txt deleted file mode 100644 index 2553335..0000000 --- a/AT91SAM7S256/Source/Test2.txt +++ /dev/null @@ -1,19 +0,0 @@ -DEFINE_DATA(BMPMAP, Test2) = -{ - 0x02,0x00, // Graphics Format - 0x04,0x00, // Graphics DataSize - 0x00, // Graphics Start X - 0x00, // Graphics Start Y - 0x80, // Graphics Width - 0x40, // Graphics Height -BEGIN_DATA - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 -END_DATA -}; diff --git a/AT91SAM7S256/Source/Ui.txt b/AT91SAM7S256/Source/Ui.txt deleted file mode 100644 index 2cf47aa..0000000 --- a/AT91SAM7S256/Source/Ui.txt +++ /dev/null @@ -1,72 +0,0 @@ -DEFINE_DATA(TXT, Ui) = -{ - 0x05,0x00, // Text Format - 0x04,0x0D, // Text DataSize - 0x01, // ItemsX - 0x3D, // ItemsY - 0x11, // ItemCharsX - 0x01, // ItemCharsY -BEGIN_DATA - 'C','o','n','n','e','c','t','i','n','g', 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'L','i','n','e',' ','i','s',' ','b','u','s','y', 0 , 0 , 0 , 0 , 0 , - 'F','a','i','l','e','d','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'C','o','n','n','e','c','t','i','o','n','?', 0 , 0 , 0 , 0 , 0 , 0 , - 'S','e','n','d','i','n','g',' ','f','i','l','e', 0 , 0 , 0 , 0 , 0 , - 'F','a','i','l','e','d','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'T','u','r','n','i','n','g',' ','o','n', 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'F','a','i','l','e','d','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'T','u','r','n','i','n','g',' ','o','f','f', 0 , 0 , 0 , 0 , 0 , 0 , - 'F','a','i','l','e','d','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'S','e','a','r','c','h','i','n','g', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'A','b','o','r','t','e','d','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'F','a','i','l','e','d','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'F','a','i','l','e','d','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'F','a','i','l','e','d','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'M','e','m','o','r','y',' ','f','u','l','l','!', 0 , 0 , 0 , 0 , 0 , - 'F','i','l','e',' ','s','a','v','e','d', 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'F','i','l','e',' ','e','x','i','s','t','s', 0 , 0 , 0 , 0 , 0 , 0 , - 'o','v','e','r','w','r','i','t','e','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'S','a','v','e','d',' ','a','s', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'F','i','l','e',' ','e','x','i','s','t', 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'o','v','e','r','w','r','i','t','e','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'F','i','l','e',' ','d','e','l','e','t','e','d', 0 , 0 , 0 , 0 , 0 , - 'F','i','l','e','s', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'd','e','l','e','t','e','d', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'R','u','n','n','i','n','g', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'A','b','o','r','t','e','d','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'D','o','n','e', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'F','i','l','e',' ','e','r','r','o','r','!', 0 , 0 , 0 , 0 , 0 , 0 , - 'D','e','l','e','t','i','n','g',' ','a','l','l', 0 , 0 , 0 , 0 , 0 , - '%','s',' ','f','i','l','e','s','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'P','r','e','s','s',' ','C','l','e','a','r',' ','t','o', 0 , 0 , 0 , - 's','t','o','p',' ','D','a','t','a','L','o','g','g','i','n','g', 0 , - 'P','o','r','t',' ','o','c','c','u','p','i','e','d','!', 0 , 0 , 0 , - 'H',':','M','M',':','S','S',':','0','0', 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'H','H',':','M','M',':','S','S', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'S','o','u','n','d', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'S','o','f','t','w','a','r','e', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'N','X','T', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'T','r','y',' ','M','e', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'D','a','t','a','l','o','g', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'P','a','s','s','k','e','y',':', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'F','i','l','e',' ','n','a','m','e',':', 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'P','l','e','a','s','e',' ','u','s','e',' ','p','o','r','t',':', 0 , - '1',' ','-',' ','T','o','u','c','h',' ','S','e','n','s','o','r', 0 , - '2',' ','-',' ','S','o','u','n','d',' ','S','e','n','s','o','r', 0 , - '3',' ','-',' ','L','i','g','h','t',' ','S','e','n','s','o','r', 0 , - '4',' ','-',' ','U','l','t','r','a','s','o','n','i','c',' ',' ', 0 , - 'B','/','C',' ','-',' ','L','/','R',' ','m','o','t','o','r','s', 0 , - 'S','e','l','e','c','t', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'S','e','l','e','c','t', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'S','e','l','e','c','t', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'B','T',' ','s','a','v','e',' ','d','a','t','a', 0 , 0 , 0 , 0 , 0 , - 'e','r','r','o','r','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'B','T',' ','s','t','o','r','e',' ','i','s', 0 , 0 , 0 , 0 , 0 , 0 , - 'f','u','l','l',' ','e','r','r','o','r','!', 0 , 0 , 0 , 0 , 0 , 0 , - 'B','T',' ','u','n','k','n','o','w','n', 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'a','d','d','r','.',' ','e','r','r','o','r','!', 0 , 0 , 0 , 0 , 0 , - 'M','e','m','o','r','y',' ','i','s', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'f','u','l','l','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 'N','e','v','e','r', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 -END_DATA -}; diff --git a/AT91SAM7S256/Source/Wait.txt b/AT91SAM7S256/Source/Wait.txt deleted file mode 100644 index abdbd43..0000000 --- a/AT91SAM7S256/Source/Wait.txt +++ /dev/null @@ -1,14 +0,0 @@ -DEFINE_DATA(BMPMAP, Wait) = -{ - 0x02,0x00, // Graphics Format - 0x00,0x48, // Graphics DataSize - 0x00, // Graphics Start X - 0x08, // Graphics Start Y - 0x18, // Graphics Width - 0x18, // Graphics Height -BEGIN_DATA - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC3,0x24,0x98,0xC2,0x98,0x24,0xC3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 -END_DATA -}; diff --git a/AT91SAM7S256/Source/c_button.c b/AT91SAM7S256/Source/c_button.c deleted file mode 100644 index 3145d8f..0000000 --- a/AT91SAM7S256/Source/c_button.c +++ /dev/null @@ -1,134 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: c_button.c $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_butt $ -// -// Platform C -// - -#include "stdconst.h" -#include "modules.h" -#include "c_button.h" -#include "c_button.iom" -#include "c_button.h" -#include "d_button.h" - -#define BTN_PRESCALER 2 - -enum -{ - LONG_TIME = (2000/BTN_PRESCALER) -}; - -static IOMAPBUTTON IOMapButton; -static VARSBUTTON VarsButton; -static UBYTE BtnCnt; - -const HEADER cButton = -{ - 0x00040001L, - "Button", - cButtonInit, - cButtonCtrl, - cButtonExit, - (void *)&IOMapButton, - (void *)&VarsButton, - (UWORD)sizeof(IOMapButton), - (UWORD)sizeof(VarsButton), - 0x0000 //Code size - not used so far -}; - - -void cButtonInit(void* pHeader) -{ - UBYTE Tmp; - - for (Tmp = 0; Tmp < NO_OF_BTNS; Tmp++) - { - IOMapButton.State[Tmp] = 0; - IOMapButton.BtnCnt[Tmp].PressedCnt = 0; - IOMapButton.BtnCnt[Tmp].LongPressCnt = 0; - IOMapButton.BtnCnt[Tmp].ShortRelCnt = 0; - IOMapButton.BtnCnt[Tmp].LongRelCnt = 0; - VarsButton.Cnt[Tmp] = 0; - } - VarsButton.OldState = 0; - BtnCnt = 0; - dButtonInit(BTN_PRESCALER); -} - -void cButtonCtrl(void) -{ - UBYTE ButtonState, Tmp, ButtonNo; - - for (Tmp = 0; Tmp < NO_OF_BTNS; Tmp++) - { - IOMapButton.State[Tmp] &= ~PRESSED_EV; - } - if (++BtnCnt >= BTN_PRESCALER) - { - BtnCnt = 0; - dButtonRead(&ButtonState); - - ButtonNo = 0x01; - for (Tmp = 0; Tmp < NO_OF_BTNS; Tmp++) - { - if (ButtonState & ButtonNo) - { - if (LONG_TIME >= (VarsButton.Cnt[Tmp])) - { - (VarsButton.Cnt[Tmp])++; - } - IOMapButton.State[Tmp] = PRESSED_STATE; - if (!((VarsButton.OldState) & ButtonNo)) - { - - /* Button just pressed */ - (IOMapButton.State[Tmp]) |= PRESSED_EV; - (IOMapButton.BtnCnt[Tmp].PressedCnt)++; - VarsButton.Cnt[Tmp] = 0; - } - else - { - if (LONG_TIME == VarsButton.Cnt[Tmp]) - { - IOMapButton.State[Tmp] |= LONG_PRESSED_EV; - (IOMapButton.BtnCnt[Tmp].LongPressCnt)++; - } - } - } - else - { - IOMapButton.State[Tmp] = 0x00; - if ((VarsButton.OldState) & ButtonNo) - { - if (VarsButton.Cnt[Tmp] > LONG_TIME) - { - IOMapButton.State[Tmp] = LONG_RELEASED_EV; - (IOMapButton.BtnCnt[Tmp].LongRelCnt)++; - - } - else - { - IOMapButton.State[Tmp] = SHORT_RELEASED_EV; - (IOMapButton.BtnCnt[Tmp].ShortRelCnt)++; - } - } - } - ButtonNo <<= 1; - IOMapButton.BtnCnt[Tmp].RelCnt = ((IOMapButton.BtnCnt[Tmp].ShortRelCnt) + (IOMapButton.BtnCnt[Tmp].LongRelCnt)); - } - VarsButton.OldState = ButtonState; - } -} - -void cButtonExit(void) -{ - dButtonExit(); -} diff --git a/AT91SAM7S256/Source/c_button.h b/AT91SAM7S256/Source/c_button.h deleted file mode 100644 index c33b24d..0000000 --- a/AT91SAM7S256/Source/c_button.h +++ /dev/null @@ -1,37 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: c_button.h $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_butt $ -// -// Platform C -// - -#ifndef C_BUTTON -#define C_BUTTON - -#ifdef INCLUDE_OS -extern const HEADER cButton; -#endif - -#include "c_button.iom" - - -typedef struct -{ - UWORD Cnt[NO_OF_BTNS]; - UBYTE OldState; -}VARSBUTTON; - -void cButtonInit(void* pHeader); -void cButtonCtrl(void); -void cButtonExit(void); - -extern const HEADER cButton; - -#endif diff --git a/AT91SAM7S256/Source/c_button.iom b/AT91SAM7S256/Source/c_button.iom deleted file mode 100644 index 640a7cd..0000000 --- a/AT91SAM7S256/Source/c_button.iom +++ /dev/null @@ -1,61 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: c_button.iom $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_butt $ -// -// Platform C -// - -#ifndef CBUTTON_IOM -#define CBUTTON_IOM - -#define pMapButton ((IOMAPBUTTON*)(pHeaders[ENTRY_BUTTON]->pIOMap)) - -enum -{ - BTN1, - BTN2, - BTN3, - BTN4, - NO_OF_BTNS -}; - -/* Costants related to State */ -enum -{ - PRESSED_EV = 0x01, - SHORT_RELEASED_EV = 0x02, - LONG_PRESSED_EV = 0x04, - LONG_RELEASED_EV = 0x08, - PRESSED_STATE = 0x80 -}; - -typedef struct -{ - UBYTE PressedCnt; - UBYTE LongPressCnt; - UBYTE ShortRelCnt; - UBYTE LongRelCnt; - UBYTE RelCnt; - UBYTE SpareOne; - UBYTE SpareTwo; - UBYTE SpareThree; -}BTNCNT; - -typedef struct -{ - BTNCNT BtnCnt[NO_OF_BTNS]; - UBYTE State[NO_OF_BTNS]; -}IOMAPBUTTON; - - -#endif - - - diff --git a/AT91SAM7S256/Source/c_cmd.c b/AT91SAM7S256/Source/c_cmd.c deleted file mode 100644 index 87b3e24..0000000 --- a/AT91SAM7S256/Source/c_cmd.c +++ /dev/null @@ -1,8020 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date: 24-06-09 8:53 $ -// -// Filename $Workfile:: c_cmd.c $ -// -// Version $Revision: 14 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_cmd. $ -// -// Platform C -// - -// -// File Description: -// This file contains the virtual machine implementation to run bytecode -// programs compatible with LEGO MINDSTORMS NXT Software 2.0. -// -// This module (c_cmd) is also responsible for reading the system timer -// (d_timer) and returning on 1 ms timer boundaries. -// - -#include "stdconst.h" -#include "modules.h" - -#include "c_cmd.iom" -#include "c_output.iom" -#include "c_input.iom" -#include "c_loader.iom" -#include "c_ui.iom" -#include "c_sound.iom" -#include "c_button.iom" -#include "c_display.iom" -#include "c_comm.iom" -#include "c_lowspeed.iom" -#include "m_sched.h" - -#include "c_cmd.h" -#include "c_cmd_bytecodes.h" -#include "d_timer.h" -#include -#include -#include -#include // for sqrt, abs, and trig stuff - -#define VMProfilingCode 0 - -static IOMAPCMD IOMapCmd; -static VARSCMD VarsCmd; -static HEADER **pHeaders; -static ULONG gInstrsToExecute; -static SLONG gPCDelta; -#define NUM_INTERP_FUNCS 16 -#define NUM_SHORT_INTERP_FUNCS 8 -#define VAR_INSTR_SIZE 0xE -// important to cast since most args are assigned from signed value, and locals may be ULONG -#define GetDataArg(arg) ((UWORD)(arg)) -#if VMProfilingCode -static ULONG ExecutedInstrs= 0, CmdCtrlTime= 0, OverheadTime= 0, CmdCtrlCalls= 0, LeaveTime= 0, NotFirstCall= 0, LastAvgCount= 0; -static ULONG CmdCtrlClumpTime[256]; -typedef struct { - ULONG Time; - ULONG Count; - ULONG Avg; - ULONG Max; -} VMInstrProfileInfo; -static VMInstrProfileInfo InstrProfile[OPCODE_COUNT]; -static VMInstrProfileInfo SysCallProfile[SYSCALL_COUNT]; -static VMInstrProfileInfo InterpFuncProfile[NUM_INTERP_FUNCS]; -static VMInstrProfileInfo ShortInstrProfile[NUM_SHORT_OPCODE_COUNT]; -#endif - -#define cCmdDSType(Arg) (VarsCmd.pDataspaceTOC[(Arg)].TypeCode) -#define cCmdDSScalarPtr(DSElementID, Offset) (VarsCmd.pDataspace + VarsCmd.pDataspaceTOC[DSElementID].DSOffset + Offset) -#define cCmdSizeOf(TC) (TC_Size_Table[(TC)]) - -#define scalarBinopDispatchMask 0x1 -#define scalarUnop2DispatchMask 0x2 - -const HEADER cCmd = -{ - 0x00010001L, - "Command", - cCmdInit, - cCmdCtrl, - cCmdExit, - (void *)&IOMapCmd, - (void *)&VarsCmd, - (UWORD)sizeof(IOMapCmd), - (UWORD)sizeof(VarsCmd), - 0x0000 //Code size - not used so far -}; - -#if ENABLE_VM - -// c_cmd_drawing.inc is just another C source file -// (the graphics implementation was split off for practical file management reasons) -#include "c_cmd_drawing.inc" - -// -//Function pointers to sub-interpreters -//This table is indexed by instr size -//Unary operations can have arity of 1 or 2 (some need a destination) -//All instructions taking 4 or more operands are handled as "Other" -// Table uses NoArg for illegal instr sizes such as zero and odd sizes -// -static pInterp InterpFuncs[NUM_INTERP_FUNCS] = -{ - cCmdInterpNoArg, - cCmdInterpNoArg, - cCmdInterpNoArg, // size 2 - cCmdInterpNoArg, - cCmdInterpUnop1, // size 4 - cCmdInterpNoArg, - cCmdInterpUnop2, // size 6 general poly is cCmdInterpUnop2, scalar is cCmdInterpScalarUnop2 - cCmdInterpNoArg, - cCmdInterpBinop, // size 8, general poly is cCmdInterpBinop, scalar is cCmdInterpScalarBinop - cCmdInterpNoArg, - cCmdInterpOther, // size 10 - cCmdInterpNoArg, - cCmdInterpOther, // size 12 - cCmdInterpNoArg, - cCmdInterpOther, // size 14 - cCmdInterpNoArg -}; - -static pInterpShort ShortInterpFuncs[NUM_SHORT_INTERP_FUNCS] = -{ - cCmdInterpShortMove, - cCmdInterpShortAcquire, - cCmdInterpShortRelease, - cCmdInterpShortSubCall, - cCmdInterpShortError, - cCmdInterpShortError, - cCmdInterpShortError, - cCmdInterpShortError -}; - -ULONG TC_Size_Table[]= { - 0, // void - SIZE_UBYTE, - SIZE_SBYTE, - SIZE_UWORD, - SIZE_SWORD, - SIZE_ULONG, - SIZE_SLONG, - SIZE_UWORD, // array - 0, // cluster - SIZE_MUTEX, - SIZE_FLOAT -}; - - -// -//Function pointers to SysCall implementations -//See interpreter for OP_SYSCALL -// -static pSysCall SysCallFuncs[SYSCALL_COUNT] = -{ - cCmdWrapFileOpenRead, - cCmdWrapFileOpenWrite, - cCmdWrapFileOpenAppend, - cCmdWrapFileRead, - cCmdWrapFileWrite, - cCmdWrapFileClose, // 5 - cCmdWrapFileResolveHandle, - cCmdWrapFileRename, - cCmdWrapFileDelete, - cCmdWrapSoundPlayFile, - cCmdWrapSoundPlayTone, // 10 - cCmdWrapSoundGetState, - cCmdWrapSoundSetState, - cCmdWrapDrawText, - cCmdWrapDrawPoint, - cCmdWrapDrawLine, // 15 - cCmdWrapDrawCircle, - cCmdWrapDrawRect, - cCmdWrapDrawPicture, - cCmdWrapSetScreenMode, - cCmdWrapReadButton, // 20 - cCmdWrapCommLSWrite, - cCmdWrapCommLSRead, - cCmdWrapCommLSCheckStatus, - cCmdWrapRandomNumber, - cCmdWrapGetStartTick, // 25 - cCmdWrapMessageWrite, - cCmdWrapMessageRead, - cCmdWrapCommBTCheckStatus, - cCmdWrapCommBTWrite, - cCmdWrapCommBTRead, // 30 - cCmdWrapKeepAlive, - cCmdWrapIOMapRead, - cCmdWrapIOMapWrite, - cCmdWrapColorSensorRead, - cCmdWrapCommBTOnOff, // 35 - cCmdWrapCommBTConnection, - cCmdWrapCommHSWrite, - cCmdWrapCommHSRead, - cCmdWrapCommHSCheckStatus, - cCmdWrapReadSemData, //40 - cCmdWrapWriteSemData, - cCmdWrapComputeCalibValue, - cCmdWrapUpdateCalibCacheInfo, - cCmdWrapDatalogWrite, - cCmdWrapDatalogGetTimes, //45 - cCmdWrapSetSleepTimeout, - cCmdWrapListFiles //47 - - // don't forget to update SYSCALL_COUNT in c_cmd.h -}; - -// -//Next set of arrays are lookup tables for IOM access bytecodes -// -TYPE_CODE IO_TYPES_IN[IO_IN_FIELD_COUNT] = -{ - //IO_IN0 - TC_UBYTE, //IO_IN_TYPE - TC_UBYTE, //IO_IN_MODE - TC_UWORD, //IO_IN_ADRAW - TC_UWORD, //IO_IN_NORMRAW - TC_SWORD, //IO_IN_SCALED_VAL - TC_UBYTE, //IO_IN_INVALID_DATA - - //IO_IN1 - TC_UBYTE, //IO_IN_TYPE - TC_UBYTE, //IO_IN_MODE - TC_UWORD, //IO_IN_ADRAW - TC_UWORD, //IO_IN_NORMRAW - TC_SWORD, //IO_IN_SCALED_VAL - TC_UBYTE, //IO_IN_INVALID_DATA - - //IO_IN2 - TC_UBYTE, //IO_IN_TYPE - TC_UBYTE, //IO_IN_MODE - TC_UWORD, //IO_IN_ADRAW - TC_UWORD, //IO_IN_NORMRAW - TC_SWORD, //IO_IN_SCALED_VAL - TC_UBYTE, //IO_IN_INVALID_DATA - - //IO_IN3 - TC_UBYTE, //IO_IN_TYPE - TC_UBYTE, //IO_IN_MODE - TC_UWORD, //IO_IN_ADRAW - TC_UWORD, //IO_IN_NORMRAW - TC_SWORD, //IO_IN_SCALED_VAL - TC_UBYTE, //IO_IN_INVALID_DATA -}; - -TYPE_CODE IO_TYPES_OUT[IO_OUT_FIELD_COUNT] = -{ - //IO_OUT0 - TC_UBYTE, //IO_OUT_FLAGS - TC_UBYTE, //IO_OUT_MODE - TC_SBYTE, //IO_OUT_SPEED - TC_SBYTE, //IO_OUT_ACTUAL_SPEED - TC_SLONG, //IO_OUT_TACH_COUNT - TC_ULONG, //IO_OUT_TACH_LIMIT - TC_UBYTE, //IO_OUT_RUN_STATE - TC_SBYTE, //IO_OUT_TURN_RATIO - TC_UBYTE, //IO_OUT_REG_MODE - TC_UBYTE, //IO_OUT_OVERLOAD - TC_UBYTE, //IO_OUT_REG_P_VAL - TC_UBYTE, //IO_OUT_REG_I_VAL - TC_UBYTE, //IO_OUT_REG_D_VAL - TC_SLONG, //IO_OUT_BLOCK_TACH_COUNT - TC_SLONG, //IO_OUT_ROTATION_COUNT - TC_UBYTE, //IO_OUT_OPTIONS - TC_SBYTE, //IO_OUT_MAX_SPEED - TC_SBYTE, //IO_OUT_MAX_ACCELERATION - - //IO_OUT1 - TC_UBYTE, //IO_OUT_FLAGS - TC_UBYTE, //IO_OUT_MODE - TC_SBYTE, //IO_OUT_SPEED - TC_SBYTE, //IO_OUT_ACTUAL_SPEED - TC_SLONG, //IO_OUT_TACH_COUNT - TC_ULONG, //IO_OUT_TACH_LIMIT - TC_UBYTE, //IO_OUT_RUN_STATE - TC_SBYTE, //IO_OUT_TURN_RATIO - TC_UBYTE, //IO_OUT_REG_MODE - TC_UBYTE, //IO_OUT_OVERLOAD - TC_UBYTE, //IO_OUT_REG_P_VAL - TC_UBYTE, //IO_OUT_REG_I_VAL - TC_UBYTE, //IO_OUT_REG_D_VAL - TC_SLONG, //IO_OUT_BLOCK_TACH_COUNT - TC_SLONG, //IO_OUT_ROTATION_COUNT - TC_UBYTE, //IO_OUT_OPTIONS - TC_SBYTE, //IO_OUT_MAX_SPEED - TC_SBYTE, //IO_OUT_MAX_ACCELERATION - - //IO_OUT2 - TC_UBYTE, //IO_OUT_FLAGS - TC_UBYTE, //IO_OUT_MODE - TC_SBYTE, //IO_OUT_SPEED - TC_SBYTE, //IO_OUT_ACTUAL_SPEED - TC_SLONG, //IO_OUT_TACH_COUNT - TC_ULONG, //IO_OUT_TACH_LIMIT - TC_UBYTE, //IO_OUT_RUN_STATE - TC_SBYTE, //IO_OUT_TURN_RATIO - TC_UBYTE, //IO_OUT_REG_MODE - TC_UBYTE, //IO_OUT_OVERLOAD - TC_UBYTE, //IO_OUT_REG_P_VAL - TC_UBYTE, //IO_OUT_REG_I_VAL - TC_UBYTE, //IO_OUT_REG_D_VAL - TC_SLONG, //IO_OUT_BLOCK_TACH_COUNT - TC_SLONG, //IO_OUT_ROTATION_COUNT - TC_UBYTE, //IO_OUT_OPTIONS - TC_SBYTE, //IO_OUT_MAX_SPEED - TC_SBYTE, //IO_OUT_MAX_ACCELERATION -}; - - -TYPE_CODE * IO_TYPES[2] = -{ - IO_TYPES_IN, - IO_TYPES_OUT -}; - -//Actual pointers filled in during cCmdInit() -void * IO_PTRS_IN[IO_IN_FIELD_COUNT]; -void * IO_PTRS_OUT[IO_OUT_FIELD_COUNT]; - -void ** IO_PTRS[2] = -{ - IO_PTRS_IN, - IO_PTRS_OUT -}; - -// Data used to indicate usage of motor ports, or usage requests -UBYTE gUsageSemData, gRequestSemData; - -UBYTE cCmdBTGetDeviceType(UBYTE *pCOD) -{ - ULONG COD; - UBYTE Result; - UBYTE Tmp; - - COD = 0; - for (Tmp = 0;Tmp < SIZE_OF_CLASS_OF_DEVICE;Tmp++) - { - COD <<= 8; - COD |= (ULONG)*pCOD; - pCOD++; - } - - Result = DEVICETYPE_UNKNOWN; - if ((COD & 0x00001FFF) == 0x00000804) - { - Result = DEVICETYPE_NXT; - } - if ((COD & 0x00001F00) == 0x00000200) - { - Result = DEVICETYPE_PHONE; - } - if ((COD & 0x00001F00) == 0x00000100) - { - Result = DEVICETYPE_PC; - } - - return (Result); -} - -//cCmdHandleRemoteCommands is the registered handler for "direct" command protocol packets -//It is only intended to be called via c_comm's main protocol handler -UWORD cCmdHandleRemoteCommands(UBYTE * pInBuf, UBYTE * pOutBuf, UBYTE * pLen) -{ - NXT_STATUS RCStatus = NO_ERR; - //Response packet length. Always includes RCStatus byte. - ULONG ResponseLen = 1; - //Boolean flag to send a response. TRUE unless overridden below. - ULONG SendResponse = TRUE; - //Boolean flag if we are handling a reply telegram. FALSE unless overridden. - ULONG IncomingReply = FALSE; - ULONG i, FirstPort, LastPort; - UWORD LStatus; - UWORD Count, QueueID; - UBYTE * pData; - - //Illegal call, give up - if (pInBuf == NULL || pLen == NULL) - { - NXT_BREAK; - return (0xFFFF); - } - - //No output buffer provided, so skip any work related to returning a response - if (pOutBuf == NULL) - SendResponse = FALSE; - - //If first byte identifies this as a reply telegram, we have different work to do. - if (pInBuf[0] == 0x02) - { - IncomingReply = TRUE; - //Reply telegrams never get responses, even if caller provided a buffer. - SendResponse = FALSE; - } - - //Advance pInBuf past command type byte - pInBuf++; - - if (!IncomingReply) - { - switch(pInBuf[0]) - { - case RC_START_PROGRAM: - { - //Check that file exists. If not, return error - //!!! Should return standard loader file error in cases like this?? - //!!! Proper solution would also check file mode to avoid confusing errors - if (LOADER_ERR(LStatus = pMapLoader->pFunc(FINDFIRST, (&pInBuf[1]), NULL, NULL)) != SUCCESS) - { - RCStatus = ERR_RC_ILLEGAL_VAL; - break; - } - - //Close file handle returned by FINDFIRST - pMapLoader->pFunc(CLOSE, LOADER_HANDLE_P(LStatus), NULL, NULL); - - //File must exist, so inform UI to attempt execution in the usual way (enables consistent feedback) - pMapUi->Flags |= UI_EXECUTE_LMS_FILE; - strncpy((PSZ)(pMapUi->LMSfilename), (PSZ)(&pInBuf[1]), FILENAME_LENGTH + 1); - } - break; - - case RC_STOP_PROGRAM: - { - if (VarsCmd.ActiveProgHandle == NOT_A_HANDLE) - { - RCStatus = ERR_NO_PROG; - break; - } - - IOMapCmd.DeactivateFlag = TRUE; - } - break; - - case RC_PLAY_SOUND_FILE: - { - if (LOADER_ERR(LStatus = pMapLoader->pFunc(FINDFIRST, (&pInBuf[2]), NULL, NULL)) != SUCCESS) - { - RCStatus = ERR_RC_ILLEGAL_VAL; - break; - } - - //Close file handle returned by FINDFIRST - pMapLoader->pFunc(CLOSE, LOADER_HANDLE_P(LStatus), NULL, NULL); - - if (pInBuf[1] == FALSE) - pMapSound->Mode = SOUND_ONCE; - else //Any non-zero value treated as TRUE - pMapSound->Mode = SOUND_LOOP; - - strncpy((PSZ)pMapSound->SoundFilename, (PSZ)(&pInBuf[2]), FILENAME_LENGTH + 1); - pMapSound->Flags |= SOUND_UPDATE; - } - break; - - case RC_PLAY_TONE: - { - pMapSound->Mode = SOUND_TONE; - //!!! Range check valid values? - memcpy((PSZ)(&(pMapSound->Freq)), (PSZ)(&pInBuf[1]), 2); - memcpy((PSZ)(&(pMapSound->Duration)), (PSZ)(&pInBuf[3]), 2); - - pMapSound->Flags |= SOUND_UPDATE; - } - break; - - case RC_SET_OUT_STATE: - { - UBYTE Port = pInBuf[1]; - //Don't do anything if illegal port specification is made - if (Port >= NO_OF_OUTPUTS && Port != 0xFF) - { - RCStatus = ERR_RC_ILLEGAL_VAL; - break; - } - - //0xFF is protocol defined to mean "all ports". - if (Port == 0xFF) - { - FirstPort = 0; - LastPort = NO_OF_OUTPUTS - 1; - } - else - FirstPort = LastPort = Port; - - for (i = FirstPort; i <= LastPort; i++) - { - OUTPUT * pOut = &(pMapOutPut->Outputs[i]); - pOut->Speed = pInBuf[2]; - pOut->Mode = pInBuf[3]; - pOut->RegMode = pInBuf[4]; - pOut->SyncTurnParameter = pInBuf[5]; - pOut->RunState = pInBuf[6]; - pOut->Options = pOut->Mode & REG_METHOD; - memcpy((PSZ)(&(pOut->TachoLimit)), (PSZ)(&pInBuf[7]), 4); - - pOut->Flags |= UPDATE_MODE | UPDATE_SPEED | UPDATE_TACHO_LIMIT; - } - } - break; - - case RC_SET_IN_MODE: - { - i = pInBuf[1]; - - //Don't do anything if illegal port specification is made - //!!! Should check against legal Types and Modes? (bitmask for Modes?) - if (i >= NO_OF_INPUTS) - { - RCStatus = ERR_RC_ILLEGAL_VAL; - break; - } - INPUTSTRUCT * pIn = &(pMapInput->Inputs[i]); - - pIn->SensorType = pInBuf[2]; - pIn->SensorMode = pInBuf[3]; - - //Set InvalidData flag automatically since type may have changed - pIn->InvalidData = TRUE; - } - break; - - case RC_GET_OUT_STATE: - { - if (SendResponse == TRUE) - { - i = pInBuf[1]; - - //Return error and all zeros if illegal port specification is made - if (i >= NO_OF_OUTPUTS) - { - RCStatus = ERR_RC_ILLEGAL_VAL; - memset(&(pOutBuf[ResponseLen]), 0, 22); - ResponseLen += 22; - break; - } - OUTPUT * pOut = &(pMapOutPut->Outputs[i]); - - //Echo port - pOutBuf[ResponseLen] = i; - ResponseLen++; - - //Power - pOutBuf[ResponseLen] = pOut->Speed; - ResponseLen++; - - //Mode - pOutBuf[ResponseLen] = pOut->Mode; - ResponseLen++; - - //RegMode - pOutBuf[ResponseLen] = pOut->RegMode; - ResponseLen++; - - //TurnRatio - pOutBuf[ResponseLen] = pOut->SyncTurnParameter; - ResponseLen++; - - //RunState - pOutBuf[ResponseLen] = pOut->RunState; - ResponseLen++; - - //TachoLimit ULONG - memcpy((PSZ)&(pOutBuf[ResponseLen]), (PSZ)(&(pOut->TachoLimit)), 4); - ResponseLen += 4; - - //TachoCount SLONG - memcpy((PSZ)&(pOutBuf[ResponseLen]), (PSZ)(&(pOut->TachoCnt)), 4); - ResponseLen += 4; - - //BlockTachoCount SLONG - memcpy((PSZ)&(pOutBuf[ResponseLen]), (PSZ)(&(pOut->BlockTachoCount)), 4); - ResponseLen += 4; - - //RotationCount SLONG - memcpy((PSZ)&(pOutBuf[ResponseLen]), (PSZ)(&(pOut->RotationCount)), 4); - ResponseLen += 4; - - NXT_ASSERT(ResponseLen == 23); - } - } - break; - - case RC_GET_IN_VALS: - { - if (SendResponse == TRUE) - { - i = pInBuf[1]; - - //Return error and all zeros if illegal port specification is made - if (i >= NO_OF_INPUTS) - { - RCStatus = ERR_RC_ILLEGAL_VAL; - memset(&(pOutBuf[ResponseLen]), 0, 13); - ResponseLen += 13; - break; - } - - //Echo port - pOutBuf[ResponseLen] = i; - ResponseLen++; - - INPUTSTRUCT * pIn = &(pMapInput->Inputs[i]); - - //Set "Valid?" boolean - if (pIn->InvalidData) - pOutBuf[ResponseLen] = FALSE; - else - pOutBuf[ResponseLen] = TRUE; - - ResponseLen++; - - //Set "Calibrated?" boolean - //!!! "Calibrated?" is a placeholder in the protocol. Always FALSE for now. - pOutBuf[ResponseLen] = FALSE; - ResponseLen++; - - pOutBuf[ResponseLen] = pIn->SensorType; - ResponseLen++; - - pOutBuf[ResponseLen] = pIn->SensorMode; - ResponseLen++; - - //Set Raw, Normalized, and Scaled values - memcpy((PSZ)&(pOutBuf[ResponseLen]), (PSZ)(&(pIn->ADRaw)), 2); - ResponseLen += 2; - - memcpy((PSZ)&(pOutBuf[ResponseLen]), (PSZ)(&(pIn->SensorRaw)), 2); - ResponseLen += 2; - - memcpy((PSZ)&(pOutBuf[ResponseLen]), (PSZ)(&(pIn->SensorValue)), 2); - ResponseLen += 2; - - //!!! Return normalized raw value in place of calibrated value for now -- see comment above - memcpy((PSZ)&(pOutBuf[ResponseLen]), (PSZ)(&(pIn->SensorRaw)), 2); - ResponseLen += 2; - - NXT_ASSERT(ResponseLen == 14); - } - } - break; - - case RC_RESET_IN_VAL: - { - i = pInBuf[1]; - - //Don't do anything if illegal port specification is made - if (i >= NO_OF_INPUTS) - { - RCStatus = ERR_RC_ILLEGAL_VAL; - break; - } - - //Clear SensorValue to zero. Leave Raw and Normalized as-is, since they never accumulate running values. - pMapInput->Inputs[i].SensorValue = 0; - } - break; - - case RC_MESSAGE_WRITE: - { - QueueID = pInBuf[1]; - Count = pInBuf[2]; - pData = &(pInBuf[3]); - - //If Count is illegal or MsgData is not null-terminated, - // we can't accept it as a valid string - if (Count == 0 || Count > MAX_MESSAGE_SIZE || pData[Count - 1] != 0x00) - { - RCStatus = ERR_RC_ILLEGAL_VAL; - break; - } - - RCStatus = cCmdMessageWrite(QueueID, pData, Count); - - //ERR_MEM here means we must compact the dataspace and retry message write - if (RCStatus == ERR_MEM) - { - cCmdDSCompact(); - RCStatus = cCmdMessageWrite(QueueID, pData, Count); - } - } - break; - - case RC_RESET_POSITION: - { - i = pInBuf[1]; - - //Don't do anything if illegal port specification is made - if (i >= NO_OF_OUTPUTS) - { - RCStatus = ERR_RC_ILLEGAL_VAL; - break; - } - - //pInBuf[2] is a selector - //FALSE: Position relative to start of last program - //TRUE: Position relative to start of last motor control block - pMapOutPut->Outputs[i].Flags |= (pInBuf[2] ? UPDATE_RESET_BLOCK_COUNT : UPDATE_RESET_ROTATION_COUNT); - } - break; - - case RC_GET_BATT_LVL: - { - if (SendResponse == TRUE) - { - //Return BatteryVoltage directly from IOMapUI, in mV - memcpy((PSZ)&(pOutBuf[ResponseLen]), (PSZ)&(pMapUi->BatteryVoltage), 2); - ResponseLen += 2; - } - } - break; - - case RC_STOP_SOUND: - { - //Tell sound module to stop playback, no questions asked - pMapSound->State = SOUND_STOP; - } - break; - - case RC_KEEP_ALIVE: - { - pMapUi->Flags |= UI_RESET_SLEEP_TIMER; - - if (SendResponse == TRUE) - { - //Convert to milliseconds to match external conventions - i = (pMapUi->SleepTimeout * 60 * 1000); - memcpy((PSZ)&(pOutBuf[ResponseLen]), (PSZ)&i, 4); - ResponseLen += 4; - } - } - break; - - case RC_LS_GET_STATUS: - { - if (SendResponse == TRUE) - { - i = pInBuf[1]; - - //Don't do anything if illegal port specification is made - if (i >= NO_OF_LOWSPEED_COM_CHANNEL) - { - RCStatus = ERR_RC_ILLEGAL_VAL; - break; - } - - RCStatus = cCmdLSCheckStatus(i); - - pOutBuf[ResponseLen] = cCmdLSCalcBytesReady(i); - ResponseLen++; - } - } - break; - - case RC_LS_WRITE: - { - i = pInBuf[1]; - Count = pInBuf[2]; - - //Don't do anything if illegal port specification is made - if (i >= NO_OF_LOWSPEED_COM_CHANNEL) - { - RCStatus = ERR_RC_ILLEGAL_VAL; - break; - } - - RCStatus = cCmdLSWrite(i, Count, &(pInBuf[4]), pInBuf[3]); - } - break; - - case RC_LS_READ: - { - if (SendResponse == TRUE) - { - i = pInBuf[1]; - - //Don't do anything if illegal port specification is made - if (i >= NO_OF_LOWSPEED_COM_CHANNEL) - { - RCStatus = ERR_RC_ILLEGAL_VAL; - break; - } - - //Get channel status and number of bytes available to read - RCStatus = cCmdLSCheckStatus(i); - Count = cCmdLSCalcBytesReady(i); - - pOutBuf[ResponseLen] = (UBYTE)Count; - ResponseLen++; - - //If channel is ready and has data ready for us, put the data into outgoing buffer - if (!IS_ERR(RCStatus) && Count > 0) - { - RCStatus = cCmdLSRead(i, (UBYTE)Count, &(pOutBuf[ResponseLen])); - ResponseLen += Count; - } - - //Pad remaining data bytes with zeroes - Count = 16 - Count; - memset(&(pOutBuf[ResponseLen]), 0, Count); - ResponseLen += Count; - } - } - break; - - case RC_GET_CURR_PROGRAM: - { - if (SendResponse == TRUE) - { - //If there's no active program, return error and empty name buffer - if (VarsCmd.ActiveProgHandle == NOT_A_HANDLE) - { - RCStatus = ERR_NO_PROG; - memset(&(pOutBuf[ResponseLen]), 0, FILENAME_LENGTH + 1); - } - //Else, copy out stashed program name - else - { - strncpy((PSZ)(&(pOutBuf[ResponseLen])), (PSZ)(VarsCmd.ActiveProgName), FILENAME_LENGTH + 1); - } - - //Regardless, we've copied out a filename's worth of bytes... - ResponseLen += FILENAME_LENGTH + 1; - } - } - break; - - case RC_MESSAGE_READ: - { - if (SendResponse == TRUE) - { - QueueID = pInBuf[1]; - - //Fill in response with remote mailbox number so remote device knows where to store this message. - pOutBuf[ResponseLen] = pInBuf[2]; - ResponseLen++; - - RCStatus = cCmdMessageGetSize(QueueID, &Count); - pOutBuf[ResponseLen] = Count; - ResponseLen++; - - if (!IS_ERR(RCStatus) && Count > 0) - { - pData = &(pOutBuf[ResponseLen]); - RCStatus = cCmdMessageRead(QueueID, pData, Count, (pInBuf[3])); - //If cCmdMessageRead encountered an error, there is no real data in the buffer, so clear it out (below) - if (IS_ERR(RCStatus)) - Count = 0; - else - ResponseLen += Count; - } - - //Pad remaining data bytes with zeroes - Count = MAX_MESSAGE_SIZE - Count; - memset(&(pOutBuf[ResponseLen]), 0, Count); - ResponseLen += Count; - } - } - break; - - // remote-only command to read from datalog buffer - // pInBuf[1] = Remove? (bool) - case RC_DATALOG_READ: - { - if (SendResponse == TRUE) - { - RCStatus = cCmdDatalogGetSize(&Count); - pOutBuf[ResponseLen] = Count; - ResponseLen++; - - if (!IS_ERR(RCStatus) && Count > 0) - { - pData = &(pOutBuf[ResponseLen]); - RCStatus = cCmdDatalogRead(pData, Count, (pInBuf[1])); - //If cCmdDatalogRead encountered an error, there is no real data in the buffer, so clear it out (below) - if (IS_ERR(RCStatus)) - Count = 0; - else - ResponseLen += Count; - } - - //Pad remaining data bytes with zeroes - Count = MAX_DATALOG_SIZE - Count; - memset(&(pOutBuf[ResponseLen]), 0, Count); - ResponseLen += Count; - } - } - break; - case RC_DATALOG_SET_TIMES: - { - //SyncTime SLONG - memcpy((PSZ)&IOMapCmd.SyncTime, (PSZ)&(pInBuf[1]), 4); - IOMapCmd.SyncTick= dTimerReadNoPoll(); - } - break; - - case RC_BT_GET_CONN_COUNT: - if (SendResponse == TRUE) { - pOutBuf[ResponseLen]= SIZE_OF_BT_CONNECT_TABLE; - ResponseLen++; - } - break; - case RC_BT_GET_CONN_NAME: // param in is index, param out is name - if (SendResponse == TRUE) { // get index from inbuf - i = pInBuf[1]; - if(i < SIZE_OF_BT_CONNECT_TABLE) { // unsigned, so guaranteed >= 0 - pOutBuf[ResponseLen] = cCmdBTGetDeviceType(pMapComm->BtConnectTable[i].ClassOfDevice); - memcpy((PSZ)(&(pOutBuf[ResponseLen+1])), (PSZ)(pMapComm->BtConnectTable[i].Name), SIZE_OF_BT_NAME + 1); - ResponseLen += SIZE_OF_BT_NAME + 2; - } - else { - pOutBuf[ResponseLen] = 0; - ResponseLen += SIZE_OF_BT_NAME + 2; - } - } - break; - case RC_BT_GET_CONTACT_COUNT: - if (SendResponse == TRUE) { - pOutBuf[ResponseLen]= SIZE_OF_BT_DEVICE_TABLE; - ResponseLen++; - } - break; - case RC_BT_GET_CONTACT_NAME: - if (SendResponse == TRUE) { // get index from inbuf - i = pInBuf[1]; - if(i < SIZE_OF_BT_DEVICE_TABLE && (pMapComm->BtDeviceTable[i].DeviceStatus & BT_DEVICE_KNOWN)) { // unsigned, so guaranteed >= 0 - (pOutBuf[ResponseLen])= cCmdBTGetDeviceType(pMapComm->BtDeviceTable[i].ClassOfDevice); - memcpy((PSZ)(&(pOutBuf[ResponseLen+1])), (PSZ)(pMapComm->BtDeviceTable[i].Name), SIZE_OF_BT_NAME + 1); - ResponseLen += SIZE_OF_BT_NAME + 2; - } - else - { - pOutBuf[ResponseLen] = 0; - memset((PSZ)(&(pOutBuf[ResponseLen+1])), 0, SIZE_OF_BT_NAME + 1); - ResponseLen += SIZE_OF_BT_NAME + 2; - } - } - break; - case RC_SET_PROPERTY: // label/value pairs - i = pInBuf[1]; - switch(i) { - case RC_PROP_BTONOFF: { - UWORD retVal, status; - if(pInBuf[2]) - status= pMapComm->pFunc(BTON, 0, 0, 0, NULL, &retVal); - else - status= pMapComm->pFunc(BTOFF, 0, 0, 0, NULL, &retVal); - - RCStatus= (status == SUCCESS) ? retVal : status; - } - break; - case RC_PROP_SOUND_LEVEL: { - UBYTE volume= pInBuf[2]; - if(volume > 4) - volume= 4; - pMapSound->Volume= volume; // apparently stored in two places - pMapUi->Volume= volume; - } - break; - case RC_PROP_SLEEP_TIMEOUT: { // ulong millisecs to sleep - ULONG value; - memcpy((PSZ)&value, (PSZ)&(pInBuf[2]), 4); - pMapUi->SleepTimeout= value / 60000; - } - break; - default: - //Unknown property -- still inform client to not expect any response bytes - NXT_BREAK; - RCStatus = ERR_RC_UNKNOWN_CMD; - break; - } - break; - case RC_GET_PROPERTY: // label/value pairs - if (SendResponse == TRUE) { // get index from inbuf - i = pInBuf[1]; - switch(i) { - case RC_PROP_BTONOFF: - pOutBuf[ResponseLen]= pMapUi->BluetoothState != BT_STATE_OFF; - ResponseLen++; - break; - case RC_PROP_SOUND_LEVEL: { - pOutBuf[ResponseLen]= pMapSound->Volume; - ResponseLen++; - } - break; - case RC_PROP_SLEEP_TIMEOUT: { - ULONG value= (pMapUi->SleepTimeout * 60 * 1000); - memcpy((PSZ)&(pOutBuf[ResponseLen]), (PSZ)&value, 4); - ResponseLen += 4; - } - break; - default: - //Unknown property -- still inform client to not expect any response bytes - NXT_BREAK; - RCStatus = ERR_RC_UNKNOWN_CMD; - break; - } - } - break; - case RC_UPDATE_RESET_COUNT: - { - i = pInBuf[1]; - - //Don't do anything if illegal port specification is made - if (i >= NO_OF_OUTPUTS) - { - RCStatus = ERR_RC_ILLEGAL_VAL; - break; - } - - pMapOutPut->Outputs[i].Flags |= UPDATE_RESET_COUNT; - } - break; - default: - { - //Unknown remote command -- still inform client to not expect any response bytes - NXT_BREAK; - RCStatus = ERR_RC_UNKNOWN_CMD; - } - break; - }; - } - //Handle reply telegrams - else - { - switch(pInBuf[0]) - { - case RC_MESSAGE_READ: - { - QueueID = pInBuf[2]; - Count = pInBuf[3]; - pData = &(pInBuf[4]); - - //This is a response to our request to read a message from a remote mailbox. - //If telegram looks valid, write the resulting message into our local mailbox. - //(If MsgData is not null-terminated, we can't accept it as a valid string.) - if (!IS_ERR((SBYTE)(pInBuf[1])) - && Count > 0 - && Count <= MAX_MESSAGE_SIZE - && pData[Count - 1] == 0x00) - { - RCStatus = cCmdMessageWrite(QueueID, pData, Count); - - //ERR_MEM here means we must compact the dataspace - if (RCStatus == ERR_MEM) - { - cCmdDSCompact(); - RCStatus = cCmdMessageWrite(QueueID, pData, Count); - } - } - - //If telegram doesn't check out, do nothing. No errors are ever returned for reply telegrams. - } - break; - - default: - { - //Unhandled reply telegram. Do nothing. - //!!! Could/should stash unhandled/all replies somewhere so a syscall could read them - } - break; - }; - } - - if (SendResponse == TRUE) - { - //Return response length (pointer checked above) - *pLen = (UBYTE)ResponseLen; - //Fill in status byte - pOutBuf[0] = (UBYTE)(RCStatus); - } - else - *pLen = 0; - - return (0); -} - - -// -// Standard interface functions -// - -void cCmdInit(void* pHeader) -{ - ULONG i; - - pHeaders = pHeader; - - IOMapCmd.pRCHandler = &cCmdHandleRemoteCommands; - -#if defined(ARM_DEBUG) - //Init run-time assert tracking variables - VarsCmd.AssertFlag = FALSE; - VarsCmd.AssertLine = 0; -#endif - - //Initialize IO_PTRS_OUT - for (i = 0; i < NO_OF_OUTPUTS; i++) - { - OUTPUT * pOut = &(pMapOutPut->Outputs[i]); - IO_PTRS_OUT[IO_OUT_FLAGS + i * IO_OUT_FPP] = (void*)&(pOut->Flags); - IO_PTRS_OUT[IO_OUT_MODE + i * IO_OUT_FPP] = (void*)&(pOut->Mode); - IO_PTRS_OUT[IO_OUT_SPEED + i * IO_OUT_FPP] = (void*)&(pOut->Speed); - IO_PTRS_OUT[IO_OUT_ACTUAL_SPEED + i * IO_OUT_FPP] = (void*)&(pOut->ActualSpeed); - IO_PTRS_OUT[IO_OUT_TACH_COUNT + i * IO_OUT_FPP] = (void*)&(pOut->TachoCnt); - IO_PTRS_OUT[IO_OUT_TACH_LIMIT + i * IO_OUT_FPP] = (void*)&(pOut->TachoLimit); - IO_PTRS_OUT[IO_OUT_RUN_STATE + i * IO_OUT_FPP] = (void*)&(pOut->RunState); - IO_PTRS_OUT[IO_OUT_TURN_RATIO + i * IO_OUT_FPP] = (void*)&(pOut->SyncTurnParameter); - IO_PTRS_OUT[IO_OUT_REG_MODE + i * IO_OUT_FPP] = (void*)&(pOut->RegMode); - IO_PTRS_OUT[IO_OUT_OVERLOAD + i * IO_OUT_FPP] = (void*)&(pOut->Overloaded); - IO_PTRS_OUT[IO_OUT_REG_P_VAL + i * IO_OUT_FPP] = (void*)&(pOut->RegPParameter); - IO_PTRS_OUT[IO_OUT_REG_I_VAL + i * IO_OUT_FPP] = (void*)&(pOut->RegIParameter); - IO_PTRS_OUT[IO_OUT_REG_D_VAL + i * IO_OUT_FPP] = (void*)&(pOut->RegDParameter); - IO_PTRS_OUT[IO_OUT_BLOCK_TACH_COUNT + i * IO_OUT_FPP] = (void*)&(pOut->BlockTachoCount); - IO_PTRS_OUT[IO_OUT_ROTATION_COUNT + i * IO_OUT_FPP] = (void*)&(pOut->RotationCount); - IO_PTRS_OUT[IO_OUT_OPTIONS + i * IO_OUT_FPP] = (void*)&(pOut->Options); - IO_PTRS_OUT[IO_OUT_MAX_SPEED + i * IO_OUT_FPP] = (void*)&(pOut->MaxSpeed); - IO_PTRS_OUT[IO_OUT_MAX_ACCELERATION + i * IO_OUT_FPP] = (void*)&(pOut->MaxAcceleration); - } - - //Initialize IO_PTRS_IN - for (i = 0; i < NO_OF_INPUTS; i++) - { - INPUTSTRUCT * pIn = &(pMapInput->Inputs[i]); - IO_PTRS_IN[IO_IN_TYPE + i * IO_IN_FPP] = (void*)&(pIn->SensorType); - IO_PTRS_IN[IO_IN_MODE + i * IO_IN_FPP] = (void*)&(pIn->SensorMode); - IO_PTRS_IN[IO_IN_ADRAW + i * IO_IN_FPP] = (void*)&(pIn->ADRaw); - IO_PTRS_IN[IO_IN_NORMRAW + i * IO_IN_FPP] = (void*)&(pIn->SensorRaw); - IO_PTRS_IN[IO_IN_SCALEDVAL + i * IO_IN_FPP] = (void*)&(pIn->SensorValue); - IO_PTRS_IN[IO_IN_INVALID_DATA + i * IO_IN_FPP] = (void*)&(pIn->InvalidData); - } - - //Clear memory pool and initialize VarsCmd (cCmdDeactivateProgram effectively re-inits VarsCmd) - cCmdInitPool(); - cCmdDeactivateProgram(); - - //Global state variables for BlueTooth communication. - VarsCmd.CommStat = (SWORD)SUCCESS; - VarsCmd.CommStatReset = (SWORD)BTBUSY; - VarsCmd.CommCurrConnection = 1; - - //Global flags for various reset and bookkeeping scenarios - VarsCmd.DirtyComm = FALSE; - VarsCmd.DirtyDisplay = FALSE; - - VarsCmd.VMState = VM_IDLE; - -#if defined (ARM_NXT) - //Make sure Pool is long-aligned - NXT_ASSERT(!((ULONG)(POOL_START) % SIZE_SLONG)); -#endif - - IOMapCmd.ProgStatus = PROG_IDLE; - IOMapCmd.ActivateFlag = FALSE; - IOMapCmd.Awake = TRUE; - - //Default offsets explicitly chosen to cause an error if used with IOMAPREAD/IOMAPWRITE - //Real values will be set when programs run and/or the DS is re-arranged. - IOMapCmd.OffsetDVA = 0xFFFF; - IOMapCmd.OffsetDS = 0xFFFF; - - //Initialize format string and clear out FileName string - strncpy((PSZ)(IOMapCmd.FormatString), VM_FORMAT_STRING, VM_FORMAT_STRING_SIZE); - memset(IOMapCmd.FileName, 0, sizeof(IOMapCmd.FileName)); - - dTimerInit(); - IOMapCmd.Tick = dTimerRead(); - IOMapCmd.SyncTime= 0; - IOMapCmd.SyncTick= 0; - - return; -} - - -void cCmdCtrl(void) -{ - NXT_STATUS Status = NO_ERR; - - switch (VarsCmd.VMState) - { - case VM_RUN_FREE: - case VM_RUN_SINGLE: - { - #if VMProfilingCode - ULONG EnterTime= dTimerReadHiRes(), FinishTime; - CmdCtrlCalls ++; -#endif - ULONG Continue; - -#if VM_BENCHMARK - //IOMapCmd.Tick currently holds the tick from the end of last cCmdCtrl call. - //If we don't come back here before dTimerRead() increments, the m_sched loop has taken *at least* 1 ms. - if (IOMapCmd.Tick != dTimerRead()) - { - VarsCmd.OverTimeCount++; - //Record maximum magnitude of schedule loop overage, in millisecs - if (dTimerRead() - IOMapCmd.Tick > VarsCmd.MaxOverTimeLength) - VarsCmd.MaxOverTimeLength = dTimerRead() - IOMapCmd.Tick; - } - VarsCmd.CmdCtrlCount++; -#endif - //Abort current program if cancel button is pressed - if (IOMapCmd.DeactivateFlag == TRUE || pMapButton->State[BTN1] & PRESSED_EV) - { - IOMapCmd.DeactivateFlag = FALSE; - - //Clear pressed event so it doesn't get double-counted by UI - pMapButton->State[BTN1] &= ~PRESSED_EV; - - //Go to VM_RESET1 state and report abort - VarsCmd.VMState = VM_RESET1; - IOMapCmd.ProgStatus = PROG_ABORT; - break; - } - - //Assert that we have an active program - NXT_ASSERT(VarsCmd.ActiveProgHandle != NOT_A_HANDLE); - - //Handle any resting clumps that are ready to awaken - cCmdCheckRestQ(IOMapCmd.Tick); // not using result, yet - //Execute from at least one clump - do - { - //Execute instructions from a clump up to INSTR_MAX, to end of millisec, - //Finishing/suspending a clump, BREAKOUT_REQ, or any errors will cause a return -#if VMProfilingCode - ULONG ClumpEnterTime= dTimerReadHiRes(); - CLUMP_ID clump= VarsCmd.RunQ.Head; -#endif - Status = cCmdInterpFromClump(); -#if VMProfilingCode - CmdCtrlClumpTime[clump] += dTimerReadHiRes() - ClumpEnterTime; -#endif - - //If RunQ and RestQ are empty, program is done, or wacko - if (!cCmdIsClumpIDSane(VarsCmd.RunQ.Head)) { - Continue = FALSE; - if(!cCmdIsClumpIDSane(VarsCmd.RestQ.Head)) { - VarsCmd.VMState = VM_RESET1; - IOMapCmd.ProgStatus = PROG_OK; - } - } - else if (Status == CLUMP_SUSPEND || Status == CLUMP_DONE) - Continue = TRUE; // queue isn't empty, didn't timeout - //Only rotate RunQ on a "normal" finish, i.e. no error, clump end, or breakout request - else if (Status == ROTATE_QUEUE) { // done and suspend do their own - cCmdRotateQ(); - Continue= TRUE; - } - else if (Status == TIMES_UP) { - cCmdRotateQ(); - Continue = FALSE; - } - else if (IS_ERR(Status)) // mem error is handled in InterpFromClump if possible - { - Continue = FALSE; - VarsCmd.VMState = VM_RESET1; - IOMapCmd.ProgStatus = PROG_ERROR; - } - else if (Status == STOP_REQ) - { - Continue = FALSE; - VarsCmd.VMState = VM_RESET1; - IOMapCmd.ProgStatus = PROG_OK; - } - else if (Status == BREAKOUT_REQ) - { - Continue = FALSE; - } - } while (Continue == TRUE); -#if VMProfilingCode - FinishTime= dTimerReadHiRes(); - if(NotFirstCall) - OverheadTime += EnterTime - LeaveTime; - else - NotFirstCall= 1; - CmdCtrlTime += FinishTime - EnterTime; - LeaveTime= FinishTime; -#endif - // May busy wait to postpone to 1ms schedule - while (IOMapCmd.Tick == dTimerRead()); - } - break; - case VM_IDLE: - { - //If there's a new program to activate... - if (IOMapCmd.ActivateFlag == TRUE) - { - //Clear flag so we only activate once per new file - IOMapCmd.ActivateFlag = FALSE; - - Status = cCmdActivateProgram(IOMapCmd.FileName); - - //If we hit an activation error: - //1. Set PROG_ERROR status - //2. Proceed to VM_RESET1 (some unneeded work, yes, but preserves contract with UI - if (IS_ERR(Status)) - { - IOMapCmd.ProgStatus = PROG_ERROR; - VarsCmd.VMState = VM_RESET1; - } - //Else start running program - else - { - VarsCmd.VMState = VM_RUN_FREE; - IOMapCmd.ProgStatus = PROG_RUNNING; - VarsCmd.StartTick = IOMapCmd.Tick; - if(VarsCmd.VMState == VM_RUN_FREE) - gInstrsToExecute = 20; - else - gInstrsToExecute= 1; - -#if VM_BENCHMARK - //Re-init benchmark - VarsCmd.InstrCount = 0; - VarsCmd.Average = 0; - VarsCmd.OverTimeCount = 0; - VarsCmd.MaxOverTimeLength = 0; - VarsCmd.CmdCtrlCount = 0; - VarsCmd.CompactionCount = 0; - VarsCmd.LastCompactionTick = 0; - VarsCmd.MaxCompactionTime = 0; - memset(VarsCmd.OpcodeBenchmarks, 0, sizeof(VarsCmd.OpcodeBenchmarks)); - memset(VarsCmd.SyscallBenchmarks, 0, sizeof(VarsCmd.SyscallBenchmarks)); -#endif - //Reset devices to a known state before we begin running - cCmdResetDevices(); - - pMapUi->Flags |= (UI_DISABLE_LEFT_RIGHT_ENTER | UI_DISABLE_EXIT); - } - } - while (IOMapCmd.Tick == dTimerRead()); // delay until scheduled time - } - break; - - //Initialize VM internal state data and devices which must respond immediately to program ending - case VM_RESET1: - { - //If we aborted a program, reset devices (specifically, motors) immediately - //Otherwise, wait for UI to put us into PROG_RESET (gives motors a chance to brake before setting to coast) - //!!! This means cCmdResetDevices will get called twice on abort. Should not be a big deal. - if (IOMapCmd.ProgStatus == PROG_ABORT) - cCmdResetDevices(); - - //Reenable UI access to buttons - pMapUi->Flags &= ~(UI_DISABLE_LEFT_RIGHT_ENTER | UI_DISABLE_EXIT); - -#if VM_BENCHMARK - if (IOMapCmd.Tick != VarsCmd.StartTick) - VarsCmd.Average = VarsCmd.InstrCount / (IOMapCmd.Tick - VarsCmd.StartTick); - else - //It appears that we finished in 0 milliseconds. Very unlikely on ARM, so set a flag value. - VarsCmd.Average = 0xFFFFFFFF; - - cCmdWriteBenchmarkFile(); -#endif - - //Re-initialize program state data (contents of memory pool preserved) - //!!! Skip this step in simulator builds so helper access methods still work -#ifndef SIM_NXT - cCmdDeactivateProgram(); -#endif //SIM_NXT - - //If this program has taken over the display, reset it for the UI - cCmdRestoreDefaultScreen(); - - //Stop any currently playing sound and re-init volume according to UI prefs - pMapSound->State = SOUND_STOP; - pMapSound->Volume = pMapUi->Volume; - - //Artificially set CommStatReset to BTBUSY to force at least one SETCMDMODE call (see VM_RESET2 case) - VarsCmd.CommStatReset = (SWORD)BTBUSY; - - VarsCmd.VMState = VM_RESET2; - while (IOMapCmd.Tick == dTimerRead()); // delay until scheduled time - } - break; - - case VM_RESET2: - { - //Reset BlueCore into "command mode" (close any open streams) - //Since SETCMDMODE subject to BTBUSY, we may need to make multiple calls - //Any CommStatReset value other than BTBUSY means our request was accepted - //Assumptions: - //Process should never take longer than UI timeout (see below), but if it does, - // we could be left with the stream open to an NXT peer and block out the PC. - //Also assuming that once SETCMDMODE request is accepted, it never fails. - if (VarsCmd.CommStatReset == (SWORD)BTBUSY && VarsCmd.DirtyComm == TRUE) - pMapComm->pFunc(SETCMDMODE, 0, 0, 0, NULL, (UWORD*)&(VarsCmd.CommStatReset)); - - //If UI is done displaying ending program status, move on. - if (IOMapCmd.ProgStatus == PROG_RESET) - { - //Reset devices whenever a program ends for any reason - cCmdResetDevices(); - - VarsCmd.DirtyComm = FALSE; - - //Go to VM_IDLE state - VarsCmd.VMState = VM_IDLE; - IOMapCmd.ProgStatus = PROG_IDLE; - } - while (IOMapCmd.Tick == dTimerRead()); // delay until scheduled time - } - break; - }//END state machine switch - - //Set tick to new value for next time 'round - IOMapCmd.Tick = dTimerReadNoPoll(); - - return; -} - - -void cCmdExit(void) -{ - dTimerExit(); - - return; -} - - -NXT_STATUS cCmdReadFileHeader(UBYTE* pData, ULONG DataSize, - PROG_FILE_OFFSETS* pFileOffsets) -{ - ULONG i; - UBYTE * pCursor; - UWORD CurrOffset = 0; - UBYTE DepCount; - UWORD DopeVectorOffset; - UWORD FileClumpCount; - UBYTE FileMajor, FileMinor, - CompatibleMinor, CompatibleMajor, - CurrentMajor; - - NXT_ASSERT(pData != NULL); - - if (strncmp((PSZ)pData, "NXTBINARY", VM_FORMAT_STRING_SIZE) == 0) - { - ULONG NativeOffset; - pCursor = (pData + 12); - NativeOffset = (ULONG)(*pCursor); - void (*native)(ULONG, ULONG) = (void (*)())(pData + NativeOffset); - (*native)((ULONG)pData, DataSize); - NXT_BREAK; - return (ERR_VER); - } - //Assign pCursor to point to version word inside file header - pCursor = (pData + VM_FORMAT_STRING_SIZE - 2); - - //Decode version numbers into comparable bytes - FileMajor = *pCursor; - FileMinor = *(pCursor + 1); - CompatibleMajor = (UBYTE)(VM_OLDEST_COMPATIBLE_VERSION >> 8); - CompatibleMinor = (UBYTE)(VM_OLDEST_COMPATIBLE_VERSION); - CurrentMajor = (UBYTE)(FIRMWAREVERSION >> 8); - //CurrentMinor = (UBYTE)(FIRMWAREVERSION); - - //Return ERR_VER if file lacks proper format string or version number - //!!! Only checking major version recommended for future development - if (strncmp((PSZ)pData, VM_FORMAT_STRING, VM_FORMAT_STRING_SIZE) - || FileMajor < CompatibleMajor || FileMinor < CompatibleMinor - || FileMajor > CurrentMajor) - { - NXT_BREAK; - return (ERR_VER); - } - - //Advance CurrOffset past header information - CurrOffset += VM_FORMAT_STRING_SIZE; - - // - //Initialize bookkeeping variables - // - VarsCmd.DataspaceCount = *((UWORD*)(pData + CurrOffset)); - CurrOffset += 2; - - VarsCmd.DataspaceSize = *((UWORD*)(pData + CurrOffset)); - CurrOffset += 2; - - VarsCmd.DSStaticSize = *((UWORD*)(pData + CurrOffset)); - CurrOffset += 2; - - pFileOffsets->DSDefaultsSize = *((UWORD*)(pData + CurrOffset)); - CurrOffset += 2; - - pFileOffsets->DynamicDefaults = *((UWORD*)(pData + CurrOffset)); - CurrOffset += 2; - - pFileOffsets->DynamicDefaultsSize = *((UWORD*)(pData + CurrOffset)); - CurrOffset += 2; - - VarsCmd.MemMgr.Head = *((UWORD*)(pData + CurrOffset)); - CurrOffset += 2; - - VarsCmd.MemMgr.Tail = *((UWORD*)(pData + CurrOffset)); - CurrOffset += 2; - - DopeVectorOffset = *((UWORD*)(pData + CurrOffset)); - CurrOffset += 2; - - //!!! Odd code here to deal with type mismatch between file format and CLUMP_ID typedef. - //Neither is trivial to change, so it's best to just check the data for consistency here. - FileClumpCount = *((UWORD*)(pData + CurrOffset)); - CurrOffset += 2; - - //Must have at least one clump and count can't exceed the NOT_A_CLUMP sentinel - if (FileClumpCount == 0 || FileClumpCount >= NOT_A_CLUMP) - return (ERR_FILE); - else - VarsCmd.AllClumpsCount = (CLUMP_ID)FileClumpCount; - - VarsCmd.CodespaceCount = *((UWORD*)(pData + CurrOffset)); - CurrOffset += 2; - - //Can't have a valid program with no code - if (VarsCmd.CodespaceCount == 0) - return (ERR_FILE); - - // - // Now, calculate offsets for each data segment in the file - // - - CurrOffset += CurrOffset % 2; - pFileOffsets->DSTOC = CurrOffset; - CurrOffset += VarsCmd.DataspaceCount * sizeof(DS_TOC_ENTRY); - - CurrOffset += CurrOffset % 2; - pFileOffsets->DSDefaults = CurrOffset; - CurrOffset += pFileOffsets->DSDefaultsSize; - - //ClumpRecs must be aligned on even boundaries - CurrOffset += CurrOffset % 2; - pFileOffsets->Clumps = CurrOffset; - - //Set cursor to start of clump records - pCursor = pData + CurrOffset; - - //Set CurrOffset to start of dependent lists - CurrOffset += VarsCmd.AllClumpsCount * VM_FILE_CLUMP_REC_SIZE; - - //Read dependent count from each clump record, advancing CurrOffset accordingly - for (i = 0; i < VarsCmd.AllClumpsCount; i++) - { - DepCount = *(pCursor + 1); - CurrOffset += DepCount; - pCursor += VM_FILE_CLUMP_REC_SIZE; - } - - //Codespace must be aligned on even boundary - CurrOffset += CurrOffset % 2; - pFileOffsets->Codespace = CurrOffset; - - //No need to read through codespace, but make sure CurrOffset ended up sane - //If not, something went wrong reading the header information - if (CurrOffset != (DataSize - VarsCmd.CodespaceCount * 2)) - { - NXT_BREAK; - return (ERR_FILE); - } - - // - // Finally, update VarsCmd fields - // - - VarsCmd.RunQ.Head = NOT_A_CLUMP; - VarsCmd.RunQ.Tail = NOT_A_CLUMP; - VarsCmd.RestQ.Head = NOT_A_CLUMP; - VarsCmd.RestQ.Tail = NOT_A_CLUMP; - - //Reset codespace pointer - VarsCmd.pCodespace = (CODE_WORD*)(pData + pFileOffsets->Codespace); - - //...placing clump records first... - VarsCmd.pAllClumps = (CLUMP_REC*)(VarsCmd.Pool + VarsCmd.PoolSize); - VarsCmd.PoolSize += VarsCmd.AllClumpsCount * sizeof(CLUMP_REC); - - //...then DSTOC... - VarsCmd.pDataspaceTOC = (DS_TOC_ENTRY*)(pData + pFileOffsets->DSTOC); - - //...then the dataspace itself - ALIGN_TO_MOD(VarsCmd.PoolSize, POOL_ALIGN); - VarsCmd.pDataspace = (VarsCmd.Pool + VarsCmd.PoolSize); - IOMapCmd.OffsetDS = (UWORD)((ULONG)(VarsCmd.pDataspace) - (ULONG)&(IOMapCmd)); - VarsCmd.PoolSize += VarsCmd.DataspaceSize; - - //init rest of MemMgr - VarsCmd.MemMgr.pDopeVectorArray = (DOPE_VECTOR *)(VarsCmd.pDataspace + DopeVectorOffset); - IOMapCmd.OffsetDVA = (UWORD)((ULONG)(VarsCmd.MemMgr.pDopeVectorArray) - (ULONG)&(IOMapCmd)); - VarsCmd.MemMgr.FreeHead = NOT_A_DS_ID; - - - if (VarsCmd.PoolSize > POOL_MAX_SIZE) - { - NXT_BREAK; - return (ERR_FILE); - } - - return (NO_ERR); -} - - -//!!! Recursive function -NXT_STATUS cCmdInflateDSDefaults(UBYTE* pDSDefaults, UWORD *pDefaultsOffset, DS_ELEMENT_ID DSElementID) -{ - NXT_STATUS Status = NO_ERR; - TYPE_CODE TypeCode; - UWORD i, Count; - UBYTE *pVal; - - NXT_ASSERT(cCmdIsDSElementIDSane(DSElementID)); - - TypeCode = cCmdDSType(DSElementID); - - if (TypeCode > TC_LAST_VALID) - return ERR_INSTR; - else if (TypeCode == TC_CLUSTER) - { - Count = cCmdClusterCount(DSElementID); - //Advance DSElementID to sub-type - DSElementID = INC_ID(DSElementID); - //Loop through sub-types, inflate recursively - for (i = 0; i < Count; i++) - { - Status = cCmdInflateDSDefaults(pDSDefaults, pDefaultsOffset, DSElementID); - if (IS_ERR(Status)) - return Status; - DSElementID = cCmdNextDSElement(DSElementID); - } - } - else - { - if (TypeCode == TC_ARRAY) - { - //Resolve pointer to DVIndex - pVal = VarsCmd.pDataspace + VarsCmd.pDataspaceTOC[DSElementID].DSOffset; - } - else - { - pVal = cCmdResolveDataArg(DSElementID, 0, NULL); - } - - //Check if the element has the "default default" - if (VarsCmd.pDataspaceTOC[DSElementID].Flags & DS_DEFAULT_DEFAULT) - { - //Fill element with the "default default" of zero - memset(pVal, 0, cCmdSizeOf(TypeCode)); - } - else - { - //Get default from stream - memmove(pVal, pDSDefaults + *pDefaultsOffset, cCmdSizeOf(TypeCode)); - *pDefaultsOffset += cCmdSizeOf(TypeCode); - } - } - - //!!! Currently will always return NO_ERR - return Status; -} - -void cCmdRefreshActiveClump(CLUMP_ID CurrID) -{ - CLUMP_REC * clumpRecPtr= &(VarsCmd.pAllClumps[CurrID]); - - if(clumpRecPtr->clumpScalarDispatchHints & scalarBinopDispatchMask) - InterpFuncs[8]= cCmdInterpScalarBinop; - else - InterpFuncs[8]= cCmdInterpBinop; - if(clumpRecPtr->clumpScalarDispatchHints & scalarUnop2DispatchMask) - InterpFuncs[6]= cCmdInterpScalarUnop2; - else - InterpFuncs[6]= cCmdInterpUnop2; -} - -NXT_STATUS cCmdActivateProgram(UBYTE * pFileName) -{ - UWORD i, j; - UBYTE * pCursor; - - NXT_STATUS Status = NO_ERR; - PROG_FILE_OFFSETS FileOffsets; - - LOADER_STATUS LStatus; - ULONG DataSize; - UBYTE * pData; - ULONG pDataHolder; - UWORD DefaultsOffset; - - LStatus = pMapLoader->pFunc(OPENREADLINEAR, pFileName, (UBYTE*)(&pDataHolder), &DataSize); - pData = (UBYTE*)(pDataHolder); - - //If Loader returned error or bad file pointer, bail out - if (LOADER_ERR(LStatus) != SUCCESS || pData == NULL || DataSize == 0) - return (ERR_FILE); - - //Deactivate current program and re-initialize memory pool - cCmdDeactivateProgram(); - cCmdInitPool(); - - //Stash this program's handle since we hold it open while running - VarsCmd.ActiveProgHandle = LOADER_HANDLE(LStatus); - - //Stash this program's name for easy reference later - strncpy((PSZ)(VarsCmd.ActiveProgName), (PSZ)(pFileName), FILENAME_LENGTH + 1); - - //Consume activation record data stream. - //See TargettingVIs/NXT.PackAR.vi for data stream packing details - - //Read header portion of the file, calculating offsets and initializing VarsCmd - Status = cCmdReadFileHeader(pData, DataSize, &FileOffsets); - if (IS_ERR(Status)) - return Status; - - //Do some spot checks to make sure bad file contents didn't leave us with obviously insane VarsCmd contents - //!!! Should add alignment checks on these pointers to avoid data abort exceptions later - if (((UBYTE*)(VarsCmd.pCodespace) < pData) - || ((UBYTE*)(VarsCmd.pCodespace) >= (pData + DataSize)) - || ((UBYTE*)(VarsCmd.pAllClumps) < POOL_START) - || ((UBYTE*)(VarsCmd.pAllClumps) >= POOL_SENTINEL) - || ((UBYTE*)(VarsCmd.pDataspace) < POOL_START) - || ((UBYTE*)(VarsCmd.pDataspace) >= POOL_SENTINEL) - || (VarsCmd.DataspaceSize == 0) ) - { - NXT_BREAK; - return ERR_FILE; - } - - //Initialize CLUMP_RECs as contiguous list in RAM - pCursor = (pData + FileOffsets.Clumps); - for (i = 0; i < VarsCmd.AllClumpsCount; i++) - { - CLUMP_REC *clumpPtr= &VarsCmd.pAllClumps[i]; - clumpPtr->InitFireCount = *(UBYTE*)(pCursor + i * VM_FILE_CLUMP_REC_SIZE); - clumpPtr->DependentCount = *(UBYTE*)(pCursor + (i * VM_FILE_CLUMP_REC_SIZE) + 1); - clumpPtr->CodeStart = *(UWORD*)(pCursor + (i * VM_FILE_CLUMP_REC_SIZE) + 2) + VarsCmd.pCodespace; - - //Initialize remaining CLUMP_REC fields - clumpPtr->PC = clumpPtr->CodeStart; - clumpPtr->Link = NOT_A_CLUMP; - - //Activate any clumps with CurrFireCount of 0 - clumpPtr->CurrFireCount = clumpPtr->InitFireCount; - if (clumpPtr->CurrFireCount == 0) - cCmdEnQClump(&(VarsCmd.RunQ), (CLUMP_ID)i); - } - - //Patch up dependents in separate pass (reuse of pCursor) - pCursor += VarsCmd.AllClumpsCount * VM_FILE_CLUMP_REC_SIZE; - for (i = 0; i < VarsCmd.AllClumpsCount; i++) - { - CLUMP_REC *clumpPtr= &VarsCmd.pAllClumps[i]; - if (clumpPtr->DependentCount > 0) - { - clumpPtr->pDependents = (CLUMP_ID*)(pCursor); - - pCursor += (clumpPtr->DependentCount * sizeof(CLUMP_ID)); - } - else - clumpPtr->pDependents = NULL; - - //Patch up CodeEnd value based on CodeStart of next clump or last overall codeword - if (i < (VarsCmd.AllClumpsCount - 1)) - clumpPtr->CodeEnd = (clumpPtr+1)->CodeStart - 1; - else - clumpPtr->CodeEnd = VarsCmd.CodespaceCount - 1 + VarsCmd.pCodespace; - - //Test for empty/insane clump code definitions - NXT_ASSERT(clumpPtr->CodeStart < clumpPtr->CodeEnd); - } - - // Check if the instructions within a clump are polymorphic and mark which table to dispatch from - for (i = 0; i < VarsCmd.AllClumpsCount; i++) - { // Check type on Boolean, math, ArrInit and ArrIndex, ingore GetSet I/O as these are always scalar - // do we need to check for DataArg encodings to I/O map??? GM - // Get Opcode and size of each instr, if ^^, check Arg types for Array or Cluster - CLUMP_REC *clumpPtr= &VarsCmd.pAllClumps[i]; - CODE_WORD *pInstr = clumpPtr->CodeStart, *lastPC = clumpPtr->CodeEnd; - ULONG InstrSize, opCode, shortOp, isT2Agg, isT3Agg, isScalarBinop= TRUE, isScalarUnop2= TRUE; - TYPE_CODE t1, t2, t3; - ULONG instrWord; - do - { - instrWord= *(UWORD*)pInstr; - opCode= OP_CODE(pInstr); - shortOp= (instrWord>>8) & 0x0F; - InstrSize = INSTR_SIZE(instrWord); - if (InstrSize == VAR_INSTR_SIZE) - InstrSize = ((UWORD*)pInstr)[1]; - if(shortOp <= 7) // no shorts are binOps - { - t2= cCmdDSType(pInstr[2]); - isT2Agg= IS_AGGREGATE_TYPE(t2); - if(InstrSize == 8) { - t3= cCmdDSType(pInstr[3]); - isT3Agg= IS_AGGREGATE_TYPE(t3); - if(isT2Agg || isT3Agg) { - if(opCode == OP_CMP) { - UBYTE isString2, isString3; - isString2= (t2 == TC_ARRAY) && cCmdDSType(INC_ID(pInstr[2])) == TC_UBYTE; - isString3= (t3 == TC_ARRAY) && cCmdDSType(INC_ID(pInstr[3])) == TC_UBYTE; - t1= cCmdDSType(pInstr[1]); - if((!isString2 || !isString3) || t1 == TC_ARRAY) // allow strings to go scalar, don't let through element compares of bytes or Bools - isScalarBinop= FALSE; - } - else if(opCode == OP_BRCMP) - isScalarBinop= FALSE; - } - } - else if(InstrSize == 6 && isT2Agg && (opCode == OP_NOT || opCode == OP_BRTST)) - isScalarUnop2= FALSE; - } - pInstr += InstrSize/2; - } while((isScalarBinop || isScalarUnop2) && pInstr < lastPC); - if(isScalarBinop) - clumpPtr->clumpScalarDispatchHints |= scalarBinopDispatchMask; - else - clumpPtr->clumpScalarDispatchHints &= ~scalarBinopDispatchMask; - - if(isScalarUnop2) - clumpPtr->clumpScalarDispatchHints |= scalarUnop2DispatchMask; - else - clumpPtr->clumpScalarDispatchHints &= ~scalarUnop2DispatchMask; - - } - //Programs with no active clumps constitutes an activation error - if (VarsCmd.RunQ.Head == NOT_A_CLUMP) - return (ERR_FILE); - else - { - // now that we know which clumps are scalar and poly, refresh dispatch table to match head - cCmdRefreshActiveClump(VarsCmd.RunQ.Head); - - } - - //Initialize dataspace with default values from file - //!!! This would be a good place to enforce check against potentially - // unsafe nested types (deeply nested types mean deep recursive calls) - DefaultsOffset = 0; - for (i = 0; i != NOT_A_DS_ID; i = cCmdNextDSElement(i)) - { - - Status = cCmdInflateDSDefaults(pData + FileOffsets.DSDefaults, &DefaultsOffset, i); - if (IS_ERR(Status)) - return Status; - } - - if ((DefaultsOffset != FileOffsets.DynamicDefaults) - || (DefaultsOffset + FileOffsets.DynamicDefaultsSize != FileOffsets.DSDefaultsSize)) - { - NXT_BREAK; - return (ERR_FILE); - } - - //Copy Dynamic defaults from file - memmove(VarsCmd.pDataspace + VarsCmd.DSStaticSize, pData + FileOffsets.DSDefaults + FileOffsets.DynamicDefaults, FileOffsets.DynamicDefaultsSize); - - // fix memmgr links. old files contain unused backPtrs, we now use these to store backLink - DV_INDEX prev= NOT_A_DS_ID; - for (i = VarsCmd.MemMgr.Head; i != NOT_A_DS_ID; i = DV_ARRAY[i].Link) { - DV_ARRAY[i].BackLink= prev; - prev= i; - } - - //Verify the MemMgr ended up where we said it would - if ((UBYTE *)VarsCmd.MemMgr.pDopeVectorArray != VarsCmd.pDataspace + DV_ARRAY[0].Offset) - { - NXT_BREAK; - return (ERR_FILE); - } - - //Initialize message queues - for (i = 0; i < MESSAGE_QUEUE_COUNT; i++) - { - VarsCmd.MessageQueues[i].ReadIndex = 0; - VarsCmd.MessageQueues[i].WriteIndex = 0; - - for (j = 0; j < MESSAGES_PER_QUEUE; j++) - { - VarsCmd.MessageQueues[i].Messages[j] = NOT_A_DS_ID; - } - } - - //Initialize datalog queue - VarsCmd.DatalogBuffer.ReadIndex = 0; - VarsCmd.DatalogBuffer.WriteIndex = 0; - for (j = 0; j < DATALOG_QUEUE_DEPTH; j++) - { - VarsCmd.DatalogBuffer.Datalogs[j] = NOT_A_DS_ID; - } - - // now that we've loaded program, prime memmgr dopevectors based upon number of handles in ds. - ULONG numHandles= DV_ARRAY[0].Count/2; - if(numHandles > 200) - numHandles= 200; - Status = cCmdGrowDopeVectorArray(numHandles); - - if (cCmdVerifyMemMgr() != TRUE) - return (ERR_FILE); - - gUsageSemData= 0; - gRequestSemData= 0; - // preload all calibration coefficients into mem - cCmdLoadCalibrationFiles(); - return (Status); -} - - -void cCmdDeactivateProgram() -{ - UBYTE i, tmp; - - //Wipe away all references into the pool and clear all run-time data - VarsCmd.pCodespace = NULL; - VarsCmd.CodespaceCount = 0; - - VarsCmd.pAllClumps = NULL; - VarsCmd.AllClumpsCount = 0; - - VarsCmd.DataspaceCount = 0; - VarsCmd.pDataspaceTOC = NULL; - VarsCmd.pDataspace = NULL; - VarsCmd.DataspaceSize = 0; - VarsCmd.DSStaticSize = 0; - - VarsCmd.MemMgr.Head = NOT_A_DS_ID; - VarsCmd.MemMgr.Tail = NOT_A_DS_ID; - VarsCmd.MemMgr.FreeHead = NOT_A_DS_ID; - VarsCmd.MemMgr.pDopeVectorArray = NULL; - - VarsCmd.RunQ.Head = NOT_A_CLUMP; - VarsCmd.RunQ.Tail = NOT_A_CLUMP; - - if (VarsCmd.ActiveProgHandle != NOT_A_HANDLE) - { - //Close handle that we've kept open for this program - pMapLoader->pFunc(CLOSE, &(VarsCmd.ActiveProgHandle), NULL, NULL); - VarsCmd.ActiveProgHandle = NOT_A_HANDLE; - - //Clear internal stashed name - memset(VarsCmd.ActiveProgName, 0, FILENAME_LENGTH + 1); - } - - //Close any files we had opened programatically - for (i = 0; i < MAX_HANDLES; i++) - { - //Copy i to tmp, because we pass a pointer to it to pFunc - tmp = i; - //Close file - if (*(VarsCmd.FileHandleTable[i]) != 0) - pMapLoader->pFunc(CROPDATAFILE, &tmp, NULL, NULL); - } - - //Clear FileHandleTable - memset(VarsCmd.FileHandleTable, 0, sizeof(VarsCmd.FileHandleTable)); - - return; -} - - -void cCmdResetDevices(void) -{ - UBYTE i; - - //Clear NXT button counts so 'bumped' will work on first run - for (i = 0; i < NO_OF_BTNS; i++) - { - pMapButton->BtnCnt[i].RelCnt = 0; - //Need to clear short and long counts too, because RelCnt depends on them. No known side effects. - pMapButton->BtnCnt[i].ShortRelCnt = 0; - pMapButton->BtnCnt[i].LongRelCnt = 0; - } - - for (i = 0; i < NO_OF_INPUTS; i++) - { - INPUTSTRUCT * pIn = &(pMapInput->Inputs[i]); - //Clear type and mode to defaults - pIn->SensorType = NO_SENSOR; - pIn->SensorMode = RAWMODE; - - //Reset input values to 0 prior to running (clear things like stale rotation counts) - pIn->ADRaw = 0; - pIn->SensorRaw = 0; - pIn->SensorValue = 0; - - //Assert invalid data flag so future code is aware of these changes - pIn->InvalidData = TRUE; - } - - for (i = 0; i < NO_OF_OUTPUTS; i++) - { - //Coast and reset all motor parameters - OUTPUT * pOut = &(pMapOutPut->Outputs[i]); - pOut->Mode = 0; - pOut->RegMode = REGULATION_MODE_IDLE; - pOut->RunState = MOTOR_RUN_STATE_IDLE; - pOut->Speed = 0; - pOut->TachoLimit = 0; - pOut->SyncTurnParameter = 0; - pOut->Flags = UPDATE_MODE | UPDATE_SPEED | UPDATE_TACHO_LIMIT | UPDATE_RESET_COUNT | UPDATE_RESET_BLOCK_COUNT | UPDATE_RESET_ROTATION_COUNT; - } - - //Lowspeed init, INSERT CODE !!! - for (i = 0; i < NO_OF_LOWSPEED_COM_CHANNEL; i++) - { - pMapLowSpeed->InBuf[i].InPtr = 0; - pMapLowSpeed->InBuf[i].OutPtr = 0; - pMapLowSpeed->InBuf[i].BytesToRx = 0; - pMapLowSpeed->OutBuf[i].InPtr = 0; - pMapLowSpeed->OutBuf[i].OutPtr = 0; - if (pMapLowSpeed->ChannelState[i] != LOWSPEED_IDLE) - { - pMapLowSpeed->ChannelState[i] = LOWSPEED_DONE; - pMapLowSpeed->State |= (0x01<Head == NOT_A_CLUMP) - { - NXT_ASSERT(Queue->Tail == NOT_A_CLUMP); - - Queue->Head = NewClump; - Queue->Tail = NewClump; - if(Queue == &(VarsCmd.RunQ)) - cCmdRefreshActiveClump(NewClump); - } - //Otherwise, tack onto the end - else - { - VarsCmd.pAllClumps[Queue->Tail].Link = NewClump; - Queue->Tail = NewClump; - } - - return; -} - -//Dequeue specified clump -//Normal usage is to dequeue only from the head (i.e. pass Queue.Head as arg) -void cCmdDeQClump(CLUMP_Q * Queue, CLUMP_ID Clump) -{ - CLUMP_ID CurrID, LinkID; - - //Make sure Clump's ID is valid and is already on Queue - NXT_ASSERT(cCmdIsClumpIDSane(Clump)); - NXT_ASSERT(cCmdIsQSane(Queue) == TRUE); - NXT_ASSERT(cCmdIsClumpOnQ(Queue, Clump)); - - CurrID = Queue->Head; - - //If our clump is the head, move up the next and disconnect - if (CurrID == Clump) - { - Queue->Head = VarsCmd.pAllClumps[Clump].Link; - VarsCmd.pAllClumps[Clump].Link = NOT_A_CLUMP; - - //If we just removed the last clump, patch up the queue's tail - if (Queue->Head == NOT_A_CLUMP) - Queue->Tail = NOT_A_CLUMP; - else if(Queue == &(VarsCmd.RunQ)) - cCmdRefreshActiveClump(Queue->Head); - } - //Else, look through rest of list looking for a link to our clump - else - { - do - { - CLUMP_REC *clumpPtr= &VarsCmd.pAllClumps[CurrID]; - LinkID = clumpPtr->Link; - - //If we find a link to our clump, patch up predecessor's link - if (clumpPtr->Link == Clump) - { - clumpPtr->Link = VarsCmd.pAllClumps[Clump].Link; - VarsCmd.pAllClumps[Clump].Link = NOT_A_CLUMP; - - //If we just removed the tail, patch tail - if (Clump == Queue->Tail) - Queue->Tail = CurrID; - } - - CurrID = LinkID; - } while (CurrID != NOT_A_CLUMP); - } - - return; -} - - -//Rotate head to tail and advance head for given Queue -void cCmdRotateQ() -{ - CLUMP_ID CurrID; - CLUMP_REC * pClumpRec; - CLUMP_Q * Queue = &VarsCmd.RunQ; - - //Make sure Queue is sane - NXT_ASSERT(cCmdIsQSane(Queue) == TRUE); - - //If queue has at least two clumps - if (Queue->Head != Queue->Tail) - { - CurrID = Queue->Head; - pClumpRec = &(VarsCmd.pAllClumps[CurrID]); - - //Disconnect head - Queue->Head = pClumpRec->Link; - pClumpRec->Link = NOT_A_CLUMP; - - //Reconnect head as tail - pClumpRec = &(VarsCmd.pAllClumps[Queue->Tail]); - pClumpRec->Link = CurrID; - Queue->Tail = CurrID; - - // reinit clump info - CurrID= Queue->Head; - cCmdRefreshActiveClump(Queue->Head); - - //Make sure we didn't make any really stupid mistakes - NXT_ASSERT(cCmdIsQSane(Queue) == TRUE); - } - - return; -} - - -UBYTE cCmdIsClumpOnQ(CLUMP_Q * Queue, CLUMP_ID Clump) -{ - CLUMP_ID CurrID; - - //Make sure Clump's ID is valid and is already on Queue - NXT_ASSERT(cCmdIsClumpIDSane(Clump)); - NXT_ASSERT(cCmdIsQSane(Queue) == TRUE); - - CurrID = Queue->Head; - - while (CurrID != NOT_A_CLUMP) - { - if (CurrID == Clump) - return TRUE; - - CurrID = VarsCmd.pAllClumps[CurrID].Link; - } - - return FALSE; -} - - -UBYTE cCmdIsQSane(CLUMP_Q * Queue) -{ - CLUMP_ID Head, Tail; - CLUMP_REC * pHead; - - if (Queue == NULL) - { - NXT_BREAK; - return FALSE; - } - - Head = Queue->Head; - Tail = Queue->Tail; - - if (Head == NOT_A_CLUMP && cCmdIsClumpIDSane(Tail)) - return FALSE; - - if (cCmdIsClumpIDSane(Head) && Tail == NOT_A_CLUMP) - return FALSE; - - if (cCmdIsClumpIDSane(Head) && cCmdIsClumpIDSane(Tail)) - { - pHead = &(VarsCmd.pAllClumps[Head]); - - //!!! More comprehensive queue tests could go here - - //Check for mislinked head if there are at least two queue members - if (Head != Tail && pHead->Link == NOT_A_CLUMP) - return FALSE; - } - - return TRUE; -} - -// -// Mutex queuing functions -// - -NXT_STATUS cCmdAcquireMutex(MUTEX_Q * Mutex) -{ - NXT_STATUS Status = NO_ERR; - CLUMP_ID Clump= VarsCmd.RunQ.Head; // save off before queue changes below - - NXT_ASSERT(Mutex != NULL && cCmdIsClumpIDSane(Clump)); - - if (Mutex->Owner == NOT_A_CLUMP) - { - //Mutex is open, so just take it - Mutex->Owner = Clump; - - NXT_ASSERT(Mutex->WaitQ.Head == NOT_A_CLUMP && Mutex->WaitQ.Tail == NOT_A_CLUMP); - } - else - { - //Mutex is reserved by someone else, take self off RunQ and add to WaitQ - cCmdDeQClump(&(VarsCmd.RunQ), Clump); - cCmdEnQClump(&(Mutex->WaitQ), Clump); - Status = CLUMP_SUSPEND; - } - - NXT_ASSERT(cCmdIsQSane(&(Mutex->WaitQ))); - - return (Status); -} - - -NXT_STATUS cCmdReleaseMutex(MUTEX_Q * Mutex) -{ -#if WIN_DEBUG || defined(ARM_DEBUG) - CLUMP_ID Clump= VarsCmd.RunQ.Head; -#endif - NXT_ASSERT(Mutex != NULL); - //!!! don't actually need to pass in Owner clump, but provides nice error checking for now - // Might want to return an error/warning if we see a Release on an free mutex, though... - NXT_ASSERT(Clump != NOT_A_CLUMP && Mutex->Owner == Clump); - - //Always set new Owner to WaitQ's Head, since NOT_A_CLUMP means mutex is free - Mutex->Owner = Mutex->WaitQ.Head; - - if (Mutex->Owner != NOT_A_CLUMP) - { - cCmdDeQClump(&(Mutex->WaitQ), Mutex->Owner); - cCmdEnQClump(&(VarsCmd.RunQ), Mutex->Owner); - } - - NXT_ASSERT(cCmdIsQSane(&(Mutex->WaitQ))); - NXT_ASSERT(cCmdIsQSane(&(VarsCmd.RunQ))); - - return (NO_ERR); -} - -// No instruction to do this yet, but put current clump to sleep until awakeTime occurs -NXT_STATUS cCmdSleepClump(ULONG time) -{ - CLUMP_ID Clump= VarsCmd.RunQ.Head; // save off before queue changes below - CLUMP_REC * pClump = &(VarsCmd.pAllClumps[Clump]); - cCmdDeQClump(&(VarsCmd.RunQ), Clump); - cCmdEnQClump(&(VarsCmd.RestQ), Clump); - pClump->awakenTime= time; - return CLUMP_SUSPEND; -} - -UBYTE cCmdCheckRestQ(ULONG currTime) -{ - UBYTE awakened= FALSE; - CLUMP_ID curr, next; - CLUMP_REC * pClump; - curr= VarsCmd.RestQ.Head; - while(curr != NOT_A_CLUMP) { - pClump= &(VarsCmd.pAllClumps[curr]); - next= pClump->Link; - if(pClump->awakenTime <= currTime) { - pClump->awakenTime= 0; // not necessary, but for debugging identification - cCmdDeQClump(&(VarsCmd.RestQ), curr); - cCmdEnQClump(&(VarsCmd.RunQ), curr); - awakened= TRUE; - } - curr= next; - } - return awakened; -} - -NXT_STATUS cCmdSchedDependents(CLUMP_ID Clump, SWORD Begin, SWORD End) -{ - CLUMP_ID CurrDepClumpID; - SWORD i; - - //Begin and End specify range of CLUMP_IDs in dependent list to schedule - //If either equals -1, both should equal -1, and no dependents will be scheduled - //Else schedule specified subset offset from pDependents - - //Check for valid args - NXT_ASSERT(cCmdIsClumpIDSane(Clump)); - NXT_ASSERT((Begin >= 0 && End >= 0 && End < VarsCmd.pAllClumps[Clump].DependentCount) - || (Begin == -1 && End == -1)); - - //If non-empty range - if (Begin != -1 || End != -1) - { - //update dependents, scheduling if their CurrFireCount reaches 0 - for (i = Begin; i <= End; i++) - { - CurrDepClumpID = VarsCmd.pAllClumps[Clump].pDependents[i]; - - NXT_ASSERT(cCmdIsClumpIDSane(CurrDepClumpID)); - - VarsCmd.pAllClumps[CurrDepClumpID].CurrFireCount--; - - if (VarsCmd.pAllClumps[CurrDepClumpID].CurrFireCount == 0) - cCmdEnQClump(&(VarsCmd.RunQ), CurrDepClumpID); - } - } - - return (NO_ERR); -} - - -NXT_STATUS cCmdSchedDependent(CLUMP_ID Clump, CLUMP_ID TargetClump) -{ - //TargetClump specifies the clump number of the target to schedule explicitly. - - //Check for valid args - NXT_ASSERT(cCmdIsClumpIDSane(Clump)); - NXT_ASSERT(cCmdIsClumpIDSane(TargetClump)); - - CLUMP_REC *clumpPtr= &VarsCmd.pAllClumps[TargetClump]; - clumpPtr->CurrFireCount--; - if (clumpPtr->CurrFireCount == 0) - cCmdEnQClump(&(VarsCmd.RunQ), TargetClump); - - return (NO_ERR); -} - - -UBYTE cCmdIsClumpIDSane(CLUMP_ID Clump) -{ - if (Clump < VarsCmd.AllClumpsCount) - return TRUE; - else - return FALSE; -} - - -// -// Memory pool management functions -// -void cCmdInitPool(void) -{ - ULONG i; - ULONG *poolPtr; - - //VarsCmd.Pool is a UBYTE pointer to ULONG array - //This was done to enforce portable alignment. - VarsCmd.Pool = (UBYTE*)(IOMapCmd.MemoryPool); - - for (i = (POOL_MAX_SIZE / 4), poolPtr= (ULONG*)&(POOL_START)[0]; i>0; i--, poolPtr++) - *poolPtr = 0xDEADBEEF; - - VarsCmd.PoolSize = 0; -} - - -#if VMProfilingCode -ULONG memMgrTime= 0; -#endif -NXT_STATUS cCmdDSArrayAlloc(DS_ELEMENT_ID DSElementID, UWORD Offset, UWORD NewCount) -{ - NXT_STATUS Status = NO_ERR; - UWORD DVIndex; - UWORD OldCount; - UWORD i; -#if VMProfilingCode - ULONG enterTime= dTimerReadHiRes(); -#endif - NXT_ASSERT(cCmdIsDSElementIDSane(DSElementID)); - - //Only arrays are valid here - //!!! Recommended to upgrade NXT_ASSERT to ERR_INSTR return - NXT_ASSERT(cCmdDSType(DSElementID) == TC_ARRAY); - - DVIndex = cCmdGetDVIndex(DSElementID, Offset); - OldCount = DV_ARRAY[DVIndex].Count; - - if(OldCount == NewCount) - goto allocExit; - Status = cCmdDVArrayAlloc(DVIndex, NewCount); - - if (Status < NO_ERR) - goto allocExit; - - if(!IS_AGGREGATE_TYPE(cCmdDSType(INC_ID(DSElementID)))) - goto allocExit; - - if (OldCount > NewCount) - { - //Free dope vectors for sub-arrays. - for (i = NewCount; i < OldCount; i++) - { - Status = cCmdFreeSubArrayDopeVectors(INC_ID(DSElementID), ARRAY_ELEM_OFFSET(DVIndex, i)); - if (IS_ERR(Status)) - goto allocExit; - } - } - else if (OldCount < NewCount) - { - //Alloc dope vectors for sub-arrays. Set up DVIndexes - for (i = OldCount; i < NewCount; i++) - { - Status = cCmdAllocSubArrayDopeVectors(INC_ID(DSElementID), ARRAY_ELEM_OFFSET(DVIndex, i)); - if (IS_ERR(Status)) - goto allocExit; - } - } - - NXT_ASSERT(cCmdVerifyMemMgr()); -allocExit: -#if VMProfilingCode - memMgrTime += dTimerReadHiRes() - enterTime; -#endif - return Status; -} - -NXT_STATUS cCmdDVArrayAlloc(DV_INDEX DVIndex, UWORD NewCount) -{ - NXT_STATUS Status = NO_ERR; - UBYTE *pData; - UWORD ArraySize, InplaceSize; - UWORD NextDVIndex; - UWORD OldCount; - - OldCount = DV_ARRAY[DVIndex].Count; - - if (OldCount == NewCount) - { - //Nothing to alloc. Return. - return Status; - } - else if (OldCount > NewCount) - { - //Already have the space. Shrink inplace. - DV_ARRAY[DVIndex].Count = NewCount; - return Status; - } - else // need to grow array - { - //Calculate new array size - ArraySize = NewCount * DV_ARRAY[DVIndex].ElemSize; - - //Try growing inplace - // If the Offset == NOT_AN_OFFSET then the array has never been allocated and can't grow inplace. - if (DV_ARRAY[DVIndex].Offset != NOT_AN_OFFSET) - { - //Get pointer to next dope vector in dataspace - if (DV_ARRAY[DVIndex].Link != NOT_A_DS_ID) - { - NextDVIndex = DV_ARRAY[DVIndex].Link; - InplaceSize = DV_ARRAY[NextDVIndex].Offset - DV_ARRAY[DVIndex].Offset; - } - else - { - //Last element in dataspace. - NXT_ASSERT(DVIndex == VarsCmd.MemMgr.Tail); - InplaceSize = VarsCmd.DataspaceSize - DV_ARRAY[DVIndex].Offset; - } - - if (ArraySize <= InplaceSize) - { - DV_ARRAY[DVIndex].Count = NewCount; - return Status; - } - } - - //Can't grow inplace, have to allocate new space - - //Make sure we properly align for type - //!!! This could also overflow memory (make PoolSize > POOL_MAX_SIZE) if we're within 3 bytes of the end. - // I don't think it matters because if it does happend, we'll trigger the ERR_MEM below and compact. - // During compaction, we'll reclaim these unused bytes. - //!!! Aligning beginning of ALL arrays to 4 byte address - ALIGN_TO_MOD(VarsCmd.PoolSize, SIZE_ULONG); - ALIGN_TO_MOD(VarsCmd.DataspaceSize, SIZE_ULONG); - - if (VarsCmd.PoolSize + ArraySize >= POOL_MAX_SIZE) - { - //Not enough memory available - return ERR_MEM; - } - - //Get data from end of pool - pData = VarsCmd.Pool + VarsCmd.PoolSize; - //Grow pool and dataspace - VarsCmd.PoolSize += ArraySize; - VarsCmd.DataspaceSize += ArraySize; - - //Move old Array Data to new allocation - if(OldCount) - memmove(pData, VarsCmd.pDataspace + DV_ARRAY[DVIndex].Offset, (UWORD)(DV_ARRAY[DVIndex].ElemSize * OldCount)); - //!!! Clear mem so old mem doesn't contain stale data. Not strictly needed. -#if WIN_DEBUG || defined(ARM_DEBUG) - memset(VarsCmd.pDataspace + DV_ARRAY[DVIndex].Offset, 0xFF, (UWORD)(DV_ARRAY[DVIndex].ElemSize * OldCount)); -#endif - //Update dope vector - DV_ARRAY[DVIndex].Offset = pData - VarsCmd.pDataspace; - DV_ARRAY[DVIndex].Count = NewCount; - - //Move dope vector to end of MemMgr list - Status = cCmdMemMgrMoveToTail(DVIndex); - if (IS_ERR(Status)) - return Status; - - NXT_ASSERT(cCmdVerifyMemMgr()); - } - - return Status; -} - - -//!!! Recursive function -NXT_STATUS cCmdAllocSubArrayDopeVectors(DS_ELEMENT_ID DSElementID, UWORD Offset) -{ - // Walks a single array element to see if it contains arrays - // For any array it finds, a dope vector is allocated and the DVIndex is placed in the dataspace for the parent array. - // This is a non-recursive function. It only walks the immediate array element. - // DSElementID - ID of array sub-entry - // Offset - offset to array element in dataspace - NXT_STATUS Status = NO_ERR; - TYPE_CODE TypeCode; - DV_INDEX DVIndex; - UWORD i; - UWORD DVIndexOffset; //Offset to DVIndex field that points to the DopeVector from pDataspace - UWORD LoopCount = 1; - UWORD ElemSize; - - for (i = 0; i < LoopCount; i++) - { - TypeCode = cCmdDSType((DS_ELEMENT_ID)(DSElementID + i)); - if (TypeCode == TC_CLUSTER) - { - LoopCount += cCmdClusterCount(DSElementID); - } - else if (TypeCode == TC_ARRAY) - { - //!!! ElemSize is a static value, but we don't have anywhere we put it (another TOC sub-entry?) - // It'd be nice to not have to recalculate it. - ElemSize = cCmdCalcArrayElemSize((DS_ELEMENT_ID)(DSElementID + i)); - DVIndexOffset = VarsCmd.pDataspaceTOC[DSElementID + i].DSOffset + Offset; - Status = cCmdAllocDopeVector(&DVIndex, ElemSize); - if (IS_ERR(Status)) - return Status; - - *((UWORD *)(VarsCmd.pDataspace + DVIndexOffset)) = DVIndex; - } - } - - return Status; -} - - -//!!! Recursive function -NXT_STATUS cCmdFreeSubArrayDopeVectors(DS_ELEMENT_ID DSElementID, UWORD Offset) -{ - // Walks a single array element to see if it contains arrays - // Frees all dope vectors associated with the array element. - // Recursively deletes sub-arrays. - // DSElementID - ID of array sub-entry - // Offset - offset to array element in dataspace - NXT_STATUS Status = NO_ERR; - TYPE_CODE TypeCode; - DV_INDEX DVIndex; - UWORD i, Count; - - TypeCode = cCmdDSType(DSElementID); - - if (TypeCode == TC_ARRAY) - { - DVIndex = cCmdGetDVIndex(DSElementID, Offset); - - NXT_ASSERT(DVIndex < DV_ARRAY[0].Count); - - Count = DV_ARRAY[DVIndex].Count; - //Recur on sub-elements - for (i = 0; i < Count; i++) - { - Status = cCmdFreeSubArrayDopeVectors(INC_ID(DSElementID), ARRAY_ELEM_OFFSET(DVIndex, i)); - if (IS_ERR(Status)) - return Status; - } - - //Free Dope Vector - Status = cCmdFreeDopeVector(DVIndex); - } - else if (TypeCode == TC_CLUSTER) - { - Count = cCmdClusterCount(DSElementID); - DSElementID = INC_ID(DSElementID); - //Recur on sub-elements - for (i = 0; i < Count; i++) - { - Status = cCmdFreeSubArrayDopeVectors((DS_ELEMENT_ID)(DSElementID + i), Offset); - if (IS_ERR(Status)) - return Status; - } - } - - return Status; -} - - -NXT_STATUS cCmdAllocDopeVector(DV_INDEX *pIndex, UWORD ElemSize) -{ - NXT_STATUS Status = NO_ERR; - - if (VarsCmd.MemMgr.FreeHead == NOT_A_DS_ID) - { - //No free DVs. Need to grow DopeVector array. - Status = cCmdGrowDopeVectorArray(DV_ARRAY_GROWTH_COUNT); - if (IS_ERR(Status)) - return Status; - } - - if(VarsCmd.MemMgr.FreeHead == NOT_A_DS_ID) - return ERR_MEM; - - //Remove DV from free list - *pIndex = VarsCmd.MemMgr.FreeHead; - VarsCmd.MemMgr.FreeHead = DV_ARRAY[*pIndex].Link; - if(VarsCmd.MemMgr.FreeHead != NOT_A_DS_ID) - DV_ARRAY[VarsCmd.MemMgr.FreeHead].BackLink= NOT_A_DS_ID; - //Add DV to tail of MemMgr list - Status = cCmdMemMgrInsertAtTail(*pIndex); - - //Initialize values - DV_ARRAY[*pIndex].Offset = NOT_AN_OFFSET; - DV_ARRAY[*pIndex].ElemSize = ElemSize; - DV_ARRAY[*pIndex].Count = 0; - - NXT_ASSERT(cCmdVerifyMemMgr()); - - return Status; -} - -// -//cCmdFreeDopeVector() - Open up a spot in the DopeVectorArray for future use -// The DopeVectorArray doesn't shrink when arrays (and their dope vectors) are deleted. -// Instead they're pushed on the free list and the array stays the same size. -// Future allocations check the free list before resorting to cCmdGrowDopeVectorArray() -// -NXT_STATUS cCmdFreeDopeVector(DV_INDEX DVIndex) -{ - NXT_STATUS Status = NO_ERR; - DV_INDEX prev, post; - - //Bounds check - NXT_ASSERT(DVIndex < DV_ARRAY[0].Count); - - //Reset dope vector fields - DV_ARRAY[DVIndex].Count = 0; - DV_ARRAY[DVIndex].ElemSize = 0; - DV_ARRAY[DVIndex].Offset = NOT_AN_OFFSET; - - //Remove from MemMgr list - if (DVIndex == VarsCmd.MemMgr.Head) - { - VarsCmd.MemMgr.Head = DV_ARRAY[DVIndex].Link; - if(VarsCmd.MemMgr.Head != NOT_A_DS_ID) - DV_ARRAY[VarsCmd.MemMgr.Head].BackLink= NOT_A_DS_ID; - } - else - { - // patchup middle or end of list. - prev= DV_ARRAY[DVIndex].BackLink; - post= DV_ARRAY[DVIndex].Link; - NXT_ASSERT(prev != NOT_A_DS_ID); - - DV_ARRAY[prev].Link = post; - if(post != NOT_A_DS_ID) - DV_ARRAY[post].BackLink= prev; - if (DVIndex == VarsCmd.MemMgr.Tail) - VarsCmd.MemMgr.Tail = prev; - //Make sure we found the previous DV, otherwise this DV was not in the the list (already freed?) - } - - //Push onto free list - DV_ARRAY[DVIndex].Link = VarsCmd.MemMgr.FreeHead; - DV_ARRAY[DVIndex].BackLink = NOT_A_DS_ID; - DV_ARRAY[VarsCmd.MemMgr.FreeHead].BackLink= DVIndex; - VarsCmd.MemMgr.FreeHead = DVIndex; - - NXT_ASSERT(cCmdVerifyMemMgr()); - - return Status; -} - -// -//cCmdGrowDopeVectorArray() - expand DopeVectorArray to be able to track more dataspace arrays -// -NXT_STATUS cCmdGrowDopeVectorArray(UWORD NewNodesCount) -{ - NXT_STATUS Status = NO_ERR; - UWORD ArraySize; - UWORD OldCount, NewCount, i; - UBYTE * pData; - - NXT_ASSERT(cCmdVerifyMemMgr()); - - OldCount = DV_ARRAY[0].Count; - NewCount = OldCount + NewNodesCount; - NXT_ASSERT(NewCount > OldCount); - - ArraySize = DV_ARRAY[0].ElemSize * NewCount; - - //!!! Aligning beginning of ALL arrays to 4 byte address - ALIGN_TO_MOD(VarsCmd.PoolSize, SIZE_ULONG); - ALIGN_TO_MOD(VarsCmd.DataspaceSize, SIZE_ULONG); - - if (VarsCmd.PoolSize + ArraySize >= POOL_MAX_SIZE) - { - //Not enough memory available - return ERR_MEM; - } - - //Get data from end of pool - pData = VarsCmd.Pool + VarsCmd.PoolSize; - //Grow pool and dataspace - VarsCmd.PoolSize += ArraySize; - VarsCmd.DataspaceSize += ArraySize; - - //Move DopeVector Array - memmove(pData, (UBYTE *)VarsCmd.MemMgr.pDopeVectorArray, (UWORD)(DV_ARRAY[0].ElemSize * DV_ARRAY[0].Count)); - - //Update MemMgr pointer - VarsCmd.MemMgr.pDopeVectorArray = (DOPE_VECTOR *)pData; - IOMapCmd.OffsetDVA = (UWORD)((ULONG)(VarsCmd.MemMgr.pDopeVectorArray) - (ULONG)&(IOMapCmd)); - - //Update dope vector - DV_ARRAY[0].Offset = pData - VarsCmd.pDataspace; - DV_ARRAY[0].Count = NewCount; - - //Add new DopeVectors to free list - //Push in reverse order so they get popped in order (mostly for ease of debugging) - for (i = NewCount - 1; i >= OldCount; i--) - { - DV_ARRAY[i].Offset = 0xFFFF; - DV_ARRAY[i].ElemSize = 0; - DV_ARRAY[i].Count = 0; - DV_ARRAY[i].BackLink = NOT_A_DS_ID; - if(VarsCmd.MemMgr.FreeHead != NOT_A_DS_ID) - DV_ARRAY[VarsCmd.MemMgr.FreeHead].BackLink = i; - DV_ARRAY[i].Link = VarsCmd.MemMgr.FreeHead; - VarsCmd.MemMgr.FreeHead = i; - } - - //Move dope vector to end of MemMgr list - Status = cCmdMemMgrMoveToTail(0); - - NXT_ASSERT(cCmdVerifyMemMgr()); - - return Status; -} - - -UWORD cCmdCalcArrayElemSize(DS_ELEMENT_ID DSElementID) -{ - TYPE_CODE TypeCode; - UWORD SizeOfType; - UWORD i; - UWORD LoopCount = 1; - UWORD Size = 0; - UWORD Alignment = 0; - - NXT_ASSERT(cCmdDSType(DSElementID) == TC_ARRAY); - - DSElementID = INC_ID(DSElementID); - for (i = 0; i < LoopCount; i++) - { - TypeCode = cCmdDSType((DS_ELEMENT_ID)(DSElementID + i)); - if (TypeCode == TC_CLUSTER) - { - LoopCount += cCmdClusterCount((DS_ELEMENT_ID)(DSElementID + i)); - } - else - { - SizeOfType = cCmdSizeOf(TypeCode); - ALIGN_TO_MOD(Size, SizeOfType); - Size += SizeOfType; - if (SizeOfType > Alignment) - Alignment = SizeOfType; - } - } - ALIGN_TO_MOD(Size, Alignment); - - return Size; -} - - -NXT_STATUS cCmdMemMgrMoveToTail(DV_INDEX DVIndex) -{ - DV_INDEX prev, post; - - //Bounds check - NXT_ASSERT(DVIndex < DV_ARRAY[0].Count); - - //Short circut if its already at the tail - if (DVIndex == VarsCmd.MemMgr.Tail) - return NO_ERR; - - if (DVIndex == VarsCmd.MemMgr.Head) { - VarsCmd.MemMgr.Head = DV_ARRAY[DVIndex].Link; - DV_ARRAY[VarsCmd.MemMgr.Head].BackLink= NOT_A_DS_ID; - } - else - { - // connect to middle or end of list. - prev= DV_ARRAY[DVIndex].BackLink; - post= DV_ARRAY[DVIndex].Link; - NXT_ASSERT(prev != NOT_A_DS_ID); - DV_ARRAY[prev].Link = post; - if(post != NOT_A_DS_ID) - DV_ARRAY[post].BackLink= prev; - } - - DV_ARRAY[DVIndex].Link = NOT_A_DS_ID; - DV_ARRAY[DVIndex].BackLink = VarsCmd.MemMgr.Tail; - if(VarsCmd.MemMgr.Tail != NOT_A_DS_ID) - DV_ARRAY[VarsCmd.MemMgr.Tail].Link = DVIndex; - VarsCmd.MemMgr.Tail = DVIndex; - - NXT_ASSERT(cCmdVerifyMemMgr()); - - return NO_ERR; -} - - -NXT_STATUS cCmdMemMgrInsertAtTail(DV_INDEX DVIndex) -{ - //Bounds check - NXT_ASSERT(DVIndex < DV_ARRAY[0].Count); - - DV_ARRAY[VarsCmd.MemMgr.Tail].Link = DVIndex; - DV_ARRAY[DVIndex].BackLink= VarsCmd.MemMgr.Tail; - DV_ARRAY[DVIndex].Link = NOT_A_DS_ID; - VarsCmd.MemMgr.Tail = DVIndex; - - NXT_ASSERT(cCmdVerifyMemMgr()); - - return NO_ERR; -} - - -UBYTE cCmdVerifyMemMgr() -{ - DV_INDEX i, prev, post; - UWORD CurrOffset = 0; - UWORD PrevOffset = 0; - UWORD DVCount = 0; - - //Make sure the MemMgr list is properly sorted in ascending offset order - for (i = VarsCmd.MemMgr.Head; i != NOT_A_DS_ID; i = DV_ARRAY[i].Link) - { - CurrOffset = DV_ARRAY[i].Offset; - - if (CurrOffset != 0xFFFF) - { - if (PrevOffset > CurrOffset) - return FALSE; - - PrevOffset = CurrOffset; - } - - prev= DV_ARRAY[i].BackLink; - post= DV_ARRAY[i].Link; - if (post == NOT_A_DS_ID && i != VarsCmd.MemMgr.Tail) - return FALSE; - else if(prev == NOT_A_DS_ID && i != VarsCmd.MemMgr.Head) - return FALSE; - else if(prev != NOT_A_DS_ID && DV_ARRAY[prev].Link != i) - return FALSE; - else if(post != NOT_A_DS_ID && DV_ARRAY[post].BackLink != i) - return FALSE; - - DVCount++; - } - - // could check link and backlinks too - for (i = VarsCmd.MemMgr.FreeHead; i != NOT_A_DS_ID; i = DV_ARRAY[i].Link) - { - DVCount++; - } - - //Make sure the # of dope vectors = # used + # free - if (DVCount != DV_ARRAY[0].Count) - return FALSE; - - return TRUE; -} - - -NXT_STATUS cCmdDSCompact(void) -{ - NXT_STATUS Status = NO_ERR; - - DV_INDEX CurrIndex; - UWORD NewOffset; - UWORD CurrOffset; - UWORD Size; - UWORD DeltaDSSize; - UWORD TempOffset, TempSize; - -#if VM_BENCHMARK - ULONG StartTime, TotalTime; - - VarsCmd.CompactionCount++; - VarsCmd.LastCompactionTick = IOMapCmd.Tick - VarsCmd.StartTick; - - StartTime = dTimerRead(); -#endif - - NXT_ASSERT(cCmdVerifyMemMgr()); - - NewOffset = VarsCmd.DSStaticSize; - for (CurrIndex = VarsCmd.MemMgr.Head; CurrIndex != NOT_A_DS_ID; CurrIndex = DV_ARRAY[CurrIndex].Link) - { - //Align NewOffset for array to 4 byte address. - ALIGN_TO_MOD(NewOffset, SIZE_ULONG); - - CurrOffset = DV_ARRAY[CurrIndex].Offset; - if (CurrOffset != NOT_AN_OFFSET) - { - Size = DV_ARRAY[CurrIndex].ElemSize * DV_ARRAY[CurrIndex].Count; - if (CurrOffset != NewOffset) - { - NXT_ASSERT(NewOffset < CurrOffset); - memmove(VarsCmd.pDataspace + NewOffset, VarsCmd.pDataspace + CurrOffset, Size); - - // Clear mem to make stale data references more obvious while debugging. - // Correct for overlapping memory regions (make sure we don't clear what we just moved). - //!!! Clearing step not strictly necessary, so it could be optimized out - if (NewOffset + Size > CurrOffset) - { - TempOffset = NewOffset + Size; - TempSize = Size - (TempOffset - CurrOffset); - } - else - { - TempOffset = CurrOffset; - TempSize = Size; - } - memset(VarsCmd.pDataspace + TempOffset, 0xFF, TempSize); - - //Update pDopeVectorArray if we move the dope vector array - if (CurrIndex == 0) - { - VarsCmd.MemMgr.pDopeVectorArray = (DOPE_VECTOR *)(VarsCmd.pDataspace + NewOffset); - IOMapCmd.OffsetDVA = (UWORD)((ULONG)(VarsCmd.MemMgr.pDopeVectorArray) - (ULONG)&(IOMapCmd)); - } - - //Update offset in DV Array - DV_ARRAY[CurrIndex].Offset = NewOffset; - } - - NewOffset += Size; - } - } - - DeltaDSSize = VarsCmd.DataspaceSize - NewOffset; - - VarsCmd.PoolSize -= DeltaDSSize; - VarsCmd.DataspaceSize -= DeltaDSSize; - - NXT_ASSERT(cCmdVerifyMemMgr()); - -#if VM_BENCHMARK - TotalTime = dTimerRead() - StartTime; - - if (TotalTime > VarsCmd.MaxCompactionTime) - VarsCmd.MaxCompactionTime = TotalTime; -#endif - - return Status; -} - - -// -// Message Queue functions -// - -NXT_STATUS cCmdMessageWrite(UWORD QueueID, UBYTE * pData, UWORD Length) -{ - NXT_STATUS Status = NO_ERR; - - if (pData == NULL) - return ERR_ARG; - - if (QueueID >= MESSAGE_QUEUE_COUNT) - return ERR_INVALID_QUEUE; - - if (VarsCmd.ActiveProgHandle == NOT_A_HANDLE) - return ERR_NO_PROG; - - //Can't accept oversize messages because we treat them as strings (truncation would remove null termination) - if (Length > MAX_MESSAGE_SIZE) - return ERR_INVALID_SIZE; - - if (IS_DV_INDEX_SANE(GET_WRITE_MSG(QueueID))) - { - //A message is already there, the queue is full - NXT_ASSERT(VarsCmd.MessageQueues[QueueID].WriteIndex == VarsCmd.MessageQueues[QueueID].ReadIndex); - - //Bump read index, drop existing message to make room for our new incoming message - VarsCmd.MessageQueues[QueueID].ReadIndex = (VarsCmd.MessageQueues[QueueID].ReadIndex + 1) % MESSAGES_PER_QUEUE; - } - else - { - //Allocate dope vector for message - Status = cCmdAllocDopeVector(&GET_WRITE_MSG(QueueID), 1); - if (IS_ERR(Status)) - return Status; - } - - //Allocate storage for message - Status = cCmdDVArrayAlloc(GET_WRITE_MSG(QueueID), Length); - if (IS_ERR(Status)) - { - //Clear the dope vector for the message, since we're unable to put a message there. - cCmdFreeDopeVector(GET_WRITE_MSG(QueueID)); - SET_WRITE_MSG(QueueID, NOT_A_DS_ID); - return Status; - } - - //Copy message - memmove(cCmdDVPtr(GET_WRITE_MSG(QueueID)), pData, Length); - - //Advance write index - VarsCmd.MessageQueues[QueueID].WriteIndex = (VarsCmd.MessageQueues[QueueID].WriteIndex + 1) % MESSAGES_PER_QUEUE; - - return Status; -} - - -NXT_STATUS cCmdMessageGetSize(UWORD QueueID, UWORD * Size) -{ - DV_INDEX ReadDVIndex; - - if (Size == NULL) - return (ERR_ARG); - - if (VarsCmd.ActiveProgHandle == NOT_A_HANDLE) - { - *Size = 0; - return (ERR_NO_PROG); - } - - if (QueueID >= MESSAGE_QUEUE_COUNT) - { - *Size = 0; - return (ERR_INVALID_QUEUE); - } - - ReadDVIndex = GET_READ_MSG(QueueID); - - if (IS_DV_INDEX_SANE(ReadDVIndex)) - { - *Size = (DV_ARRAY[ReadDVIndex].Count); - return (NO_ERR); - } - else - { - *Size = 0; - return (STAT_MSG_EMPTY_MAILBOX); - } -} - - -NXT_STATUS cCmdMessageRead(UWORD QueueID, UBYTE * pBuffer, UWORD Length, UBYTE Remove) -{ - NXT_STATUS Status = NO_ERR; - DV_INDEX ReadDVIndex; - - if (pBuffer == NULL) - return (ERR_ARG); - - if (VarsCmd.ActiveProgHandle == NOT_A_HANDLE) - return (ERR_NO_PROG); - - if (QueueID >= MESSAGE_QUEUE_COUNT) - return (ERR_INVALID_QUEUE); - - ReadDVIndex = GET_READ_MSG(QueueID); - - if (IS_DV_INDEX_SANE(ReadDVIndex)) - { - //If Buffer doesn't have room for the entire message, - //don't risk incomplete string floating around - if (Length < DV_ARRAY[ReadDVIndex].Count) - return (ERR_INVALID_SIZE); - - //Copy message - memmove(pBuffer, cCmdDVPtr(ReadDVIndex), DV_ARRAY[ReadDVIndex].Count); - - if (Remove) - { - //Free memory used by message - Status = cCmdFreeDopeVector(ReadDVIndex); - if (IS_ERR(Status)) - return Status; - - SET_READ_MSG(QueueID, NOT_A_DS_ID); - - //Advance read index - VarsCmd.MessageQueues[QueueID].ReadIndex = (VarsCmd.MessageQueues[QueueID].ReadIndex + 1) % MESSAGES_PER_QUEUE; - } - } - else - { - //No message to read, message Queue is empty - NXT_ASSERT(VarsCmd.MessageQueues[QueueID].ReadIndex == VarsCmd.MessageQueues[QueueID].WriteIndex); - - return (STAT_MSG_EMPTY_MAILBOX); - } - - return Status; -} - -// -// Datalog Queue function(s) -// - -NXT_STATUS cCmdDatalogWrite(UBYTE * pData, UWORD Length) -{ - NXT_STATUS Status = NO_ERR; - - if (pData == NULL) - return ERR_ARG; - - if (VarsCmd.ActiveProgHandle == NOT_A_HANDLE) - return (ERR_NO_PROG); - - //Can't accept oversize messages because we treat them as strings (truncation would remove null termination) - if (Length > MAX_DATALOG_SIZE) - return ERR_INVALID_SIZE; - - if (IS_DV_INDEX_SANE(GET_WRITE_DTLG())) - { - //A message is already there, the queue is full - NXT_ASSERT(VarsCmd.DatalogBuffer.WriteIndex == VarsCmd.DatalogBuffer.ReadIndex); - Status = STAT_MSG_BUFFERWRAP; - //Bump read index, drop existing message to make room for our newly acquired datalog - VarsCmd.DatalogBuffer.ReadIndex = (VarsCmd.DatalogBuffer.ReadIndex + 1) % DATALOG_QUEUE_DEPTH; - } - else - { - //Allocate dope vector for message - Status = cCmdAllocDopeVector(&GET_WRITE_DTLG(), 1); - if (IS_ERR(Status)) - return Status; - } - - //Allocate storage for message - Status |= cCmdDVArrayAlloc(GET_WRITE_DTLG(), Length); - if (IS_ERR(Status)) - { - //Clear the dope vector for the message, since we're unable to put a message there. - cCmdFreeDopeVector(GET_WRITE_DTLG()); - SET_WRITE_DTLG(NOT_A_DS_ID); - return Status; - } - - //Copy message - memmove(cCmdDVPtr(GET_WRITE_DTLG()), pData, Length); - - //Advance write index - VarsCmd.DatalogBuffer.WriteIndex = (VarsCmd.DatalogBuffer.WriteIndex + 1) % DATALOG_QUEUE_DEPTH; - - return Status; -} - -NXT_STATUS cCmdDatalogGetSize(UWORD * Size) -{ - DV_INDEX ReadDVIndex; - - if (Size == NULL) - return (ERR_ARG); - - if (VarsCmd.ActiveProgHandle == NOT_A_HANDLE) - { - *Size = 0; - return (ERR_NO_PROG); - } - - ReadDVIndex = GET_READ_DTLG(); - - if (IS_DV_INDEX_SANE(ReadDVIndex)) - { - *Size = (DV_ARRAY[ReadDVIndex].Count); - return (NO_ERR); - } - else - { - *Size = 0; - return (STAT_MSG_EMPTY_MAILBOX); - } -} - -NXT_STATUS cCmdDatalogRead(UBYTE * pBuffer, UWORD Length, UBYTE Remove) -{ - NXT_STATUS Status = NO_ERR; - DV_INDEX ReadDVIndex; - - if (pBuffer == NULL) - return (ERR_ARG); - - if (VarsCmd.ActiveProgHandle == NOT_A_HANDLE) - return (ERR_NO_PROG); - - ReadDVIndex = GET_READ_DTLG(); - - if (IS_DV_INDEX_SANE(ReadDVIndex)) - { - //If Buffer doesn't have room for the entire message, - //don't risk incomplete string floating around - if (Length < DV_ARRAY[ReadDVIndex].Count) - return (ERR_INVALID_SIZE); - - //Copy message - memmove(pBuffer, cCmdDVPtr(ReadDVIndex), DV_ARRAY[ReadDVIndex].Count); - - if (Remove) - { - //Free memory used by message - Status = cCmdFreeDopeVector(ReadDVIndex); - if (IS_ERR(Status)) - return Status; - - SET_READ_DTLG(NOT_A_DS_ID); - - //Advance read index - VarsCmd.DatalogBuffer.ReadIndex = (VarsCmd.DatalogBuffer.ReadIndex + 1) % DATALOG_QUEUE_DEPTH; - } - } - else - { - //No message to read, datalog Queue is empty - NXT_ASSERT(VarsCmd.DatalogBuffer.ReadIndex == VarsCmd.DatalogBuffer.WriteIndex); - - return (STAT_MSG_EMPTY_MAILBOX); - } - - return Status; -} - - -// -// Color Sensor Functions -// -NXT_STATUS cCmdColorSensorRead (UBYTE Port, SWORD * SensorValue, UWORD * RawArray, UWORD * NormalizedArray, - SWORD * ScaledArray, UBYTE * InvalidData) -{ - ULONG i; - //Make sure Port is valid for Color Sensor - INPUTSTRUCT * pIn = &(pMapInput->Inputs[Port]); - UBYTE sType = pIn->SensorType; - if (!(sType == COLORFULL || sType == COLORRED || sType == COLORGREEN || - sType == COLORBLUE || sType == COLORNONE)) - { - return (ERR_COMM_CHAN_NOT_READY); //TODO - is this the right error? - } - //Copy Detected Color - *SensorValue = pIn->SensorValue; - - //Copy all raw, normalized and scaled data from I/O Map - for (i=0; iColors[Port]); - RawArray[i] = pColor->ADRaw[i]; - NormalizedArray[i] = pColor->SensorRaw[i]; - ScaledArray[i] = pColor->SensorValue[i]; - } - //Copy the Invalid Data Flag - *InvalidData = pIn->InvalidData; - - return NO_ERR; - -} - - -// -// Dataspace Support functions -// - -UBYTE cCmdIsDSElementIDSane(DS_ELEMENT_ID Index) -{ - if (Index < VarsCmd.DataspaceCount) - return TRUE; - else - return FALSE; -} - -void * cCmdResolveDataArg(DATA_ARG DataArg, UWORD Offset, TYPE_CODE * TypeCode) -{ - void * ret_val = NULL; - - //!!! DATA_ARG masking system only for internal c_cmd use! - // All normal bytecode arguments should go through top if() block. - - NXT_ASSERT(cCmdIsDSElementIDSane(DataArg)); - ret_val = cCmdDSPtr(DataArg, Offset); - if (TypeCode) - *TypeCode = VarsCmd.pDataspaceTOC[DataArg].TypeCode; - - //!!! Caller beware! If DataArg isn't sane, ret_val may be out of range or NULL! - return ret_val; -} - -// normal Resolve handles both, but this is specific to I/O args -void * cCmdResolveIODataArg(DATA_ARG DataArg, ULONG Offset, TYPE_CODE * TypeCode) - { - void * ret_val = NULL; - - ULONG ModuleID; - ULONG FieldID; - //DataArg refers to a field in the IO map - // ModuleID = ((DataArg >> 9) & 0x1F); - ModuleID = ((DataArg & 0x3FFF) >> 9); - FieldID = (DataArg & 0x01FF); - - //!!! Preliminary bounds check -- still could allow invalid combos through - if (ModuleID > MOD_OUTPUT || FieldID >= IO_OUT_FIELD_COUNT) - { - NXT_BREAK; - return NULL; - } - - ret_val = IO_PTRS[ModuleID][FieldID]; - if (TypeCode) - *TypeCode = IO_TYPES[ModuleID][FieldID]; - return ret_val; -} - -void cCmdSetValFlt(void * pVal, TYPE_CODE TypeCode, float NewVal) -{ - - if (pVal) - { - switch (TypeCode) - { - case TC_ULONG: - case TC_SLONG: - { - *(ULONG*)pVal = NewVal; - } - break; - - case TC_UWORD: - case TC_SWORD: - { - *(UWORD*)pVal = (UWORD)NewVal; - } - break; - - case TC_UBYTE: - case TC_SBYTE: - { - *(UBYTE*)pVal = (UBYTE)NewVal; - } - break; - - case TC_FLOAT: - { - *(float*)pVal = (float)NewVal; - } - break; - } - } - - return; -} - -ULONG cCmdGetUByte(void * pVal); -ULONG cCmdGetSByte(void * pVal); -ULONG cCmdGetUWord(void * pVal); -ULONG cCmdGetSWord(void * pVal); -ULONG cCmdGetULong(void * pVal); -ULONG cCmdGetSLong(void * pVal); -ULONG cCmdGetError(void * pVal); -ULONG cCmdGetFloat(void * pVal); - -void cCmdSetByte(void * pVal, ULONG NewVal); -void cCmdSetWord(void * pVal, ULONG NewVal); -void cCmdSetLong(void * pVal, ULONG NewVal); -void cCmdSetError(void * pVal, ULONG NewVal); - - -typedef ULONG (*pGetOperand)(void *); -static pGetOperand GetProcArray[11]= {cCmdGetUByte, cCmdGetUByte, cCmdGetSByte, cCmdGetUWord, cCmdGetSWord, cCmdGetULong, cCmdGetSLong, cCmdGetError, cCmdGetError, cCmdGetError, cCmdGetFloat}; // dup UByte to line up - -typedef void (*pSetOperand)(void *, ULONG); -static pSetOperand SetProcArray[9]= {cCmdSetByte, cCmdSetByte, cCmdSetByte, cCmdSetWord, cCmdSetWord, cCmdSetLong, cCmdSetLong, cCmdSetError, cCmdSetError}; // dup UByte to line up - -void cCmdSetError(void * pVal, ULONG NewVal) { - NXT_BREAK; -} - -void cCmdSetLong(void * pVal, ULONG NewVal) { - *(ULONG*)pVal = NewVal; -} - -void cCmdSetWord(void * pVal, ULONG NewVal) { - *(UWORD*)pVal = (UWORD)NewVal; -} - -void cCmdSetByte(void * pVal, ULONG NewVal) { - *(UBYTE*)pVal = (UBYTE)NewVal; -} - -// only works on simple types, equivalent to resolve and get, but faster -ULONG cCmdGetScalarValFromDataArg(DATA_ARG DataArg, UWORD Offset) -{ - DS_TOC_ENTRY *dsTOCPtr= &VarsCmd.pDataspaceTOC[DataArg]; - return GetProcArray[dsTOCPtr->TypeCode](VarsCmd.pDataspace + dsTOCPtr->DSOffset + Offset); -} - - -ULONG cCmdGetError(void * pVal) { - NXT_BREAK; - return 0; -} - -ULONG cCmdGetULong(void * pVal) { - return (ULONG)(*(ULONG*)pVal); -} - -ULONG cCmdGetSLong(void * pVal) { - return (SLONG)(*(SLONG*)pVal); -} - -ULONG cCmdGetUWord(void * pVal) { - return (UWORD)(*(UWORD*)pVal); -} - -ULONG cCmdGetSWord(void * pVal) { - return (SWORD)(*(SWORD*)pVal); -} - -ULONG cCmdGetUByte(void * pVal) { - return (UBYTE)(*(UBYTE*)pVal); -} - -ULONG cCmdGetSByte(void * pVal) { - return (SBYTE)(*(SBYTE*)pVal); -} - -ULONG cCmdGetFloat(void * pVal) { - float tempVal = *(float*)pVal; - if (tempVal >= 0.0f) { - tempVal += 0.5f; - } - else { - tempVal -= 0.5f; - } - return (ULONG)tempVal; -} - -ULONG cCmdGetVal(void * pVal, TYPE_CODE TypeCode) -{ - if (pVal) - return GetProcArray[TypeCode](pVal); - else - //!!! Default return value places responsibility on caller to use this function wisely - return 0; -} - - -float cCmdGetValFlt(void * pVal, TYPE_CODE TypeCode) -{ - if (pVal) - { - switch (TypeCode) - { - case TC_ULONG: - { - return (ULONG)(*(ULONG*)pVal); - } - - case TC_SLONG: - { - return (SLONG)(*(SLONG*)pVal); - } - - case TC_UWORD: - { - return (UWORD)(*(UWORD*)pVal); - } - - case TC_SWORD: - { - return (SWORD)(*(SWORD*)pVal); - } - - case TC_UBYTE: - { - return (UBYTE)(*(UBYTE*)pVal); - } - - case TC_SBYTE: - { - return (SBYTE)(*(SBYTE*)pVal); - } - - case TC_FLOAT: - { - return (float)(*(float*)pVal); - } - - default: - break; - } - } - - //!!! Default return value places responsibility on caller to use this function wisely - return 0; -} - - - -// Only for scalar types and no offset -void cCmdSetScalarValFromDataArg(DATA_ARG DataArg, ULONG NewVal) -{ - DS_TOC_ENTRY *dsTOCPtr= &VarsCmd.pDataspaceTOC[DataArg]; - SetProcArray[dsTOCPtr->TypeCode](VarsCmd.pDataspace + dsTOCPtr->DSOffset, NewVal); -} - -void cCmdSetVal(void * pVal, TYPE_CODE TypeCode, ULONG NewVal) -{ - if (pVal) - SetProcArray[TypeCode](pVal, NewVal); -} - -void* cCmdDSPtr(DS_ELEMENT_ID DSElementID, UWORD Offset) -{ - void * pDSItem; - DV_INDEX DVIndex; - TYPE_CODE TypeCode; - - NXT_ASSERT(cCmdIsDSElementIDSane(DSElementID)); - - TypeCode = cCmdDSType(DSElementID); - if (TypeCode == TC_ARRAY) - { - //!!! Empty arrays return NULL. - if (cCmdArrayCount(DSElementID, Offset) == 0) - pDSItem = NULL; - else - { - DVIndex = cCmdGetDVIndex(DSElementID, Offset); - pDSItem = (VarsCmd.pDataspace + DV_ARRAY[DVIndex].Offset); - } - } - else if (TypeCode == TC_CLUSTER) - { - NXT_ASSERT(cCmdClusterCount(DSElementID) != 0) - - //Returning pointer to the first element in the cluster - pDSItem = cCmdDSPtr(INC_ID(DSElementID), Offset); - } - else - pDSItem = (VarsCmd.pDataspace + VarsCmd.pDataspaceTOC[DSElementID].DSOffset + Offset); - - NXT_ASSERT((UBYTE*)pDSItem < POOL_SENTINEL); - - return pDSItem; -} - -void* cCmdDVPtr(DV_INDEX DVIndex) -{ - NXT_ASSERT(IS_DV_INDEX_SANE(DVIndex)); - return (VarsCmd.pDataspace + DV_ARRAY[DVIndex].Offset); -} - - -//!!! Recursive function -DS_ELEMENT_ID cCmdNextDSElement(DS_ELEMENT_ID CurrID) -{ - DS_ELEMENT_ID NextID; - TYPE_CODE CurrType; - UWORD ClusterCount, i; - - NXT_ASSERT(cCmdIsDSElementIDSane(CurrID)); - - NextID = CurrID + 1; - - if (!cCmdIsDSElementIDSane(NextID)) - return NOT_A_DS_ID; - - CurrType = cCmdDSType(CurrID); - - if (CurrType == TC_ARRAY) - { - //Arrays contain two elements. Advance past the second one. - NextID = cCmdNextDSElement(NextID); - } - else if (CurrType == TC_CLUSTER) - { - ClusterCount = cCmdClusterCount(CurrID); - for (i = 0; i < ClusterCount; i++) - { - NextID = cCmdNextDSElement(NextID); - } - } - - return NextID; -} - - -//!!! Recursive function -UBYTE cCmdCompareDSType(DS_ELEMENT_ID DSElementID1, DS_ELEMENT_ID DSElementID2) -{ - TYPE_CODE Type1, Type2; - UWORD i, Count1, Count2; - - Type1 = cCmdDSType(DSElementID1); - Type2 = cCmdDSType(DSElementID2); - - if (Type1 != Type2) - return FALSE; - - if (Type1 == TC_CLUSTER) - { - Count1 = cCmdClusterCount(DSElementID1); - Count2 = cCmdClusterCount(DSElementID2); - - if(Count1 != Count2) - return FALSE; - - DSElementID1 = INC_ID(DSElementID1); - DSElementID2 = INC_ID(DSElementID2); - - for (i = 0; i < Count1; i++) - { - if (!cCmdCompareDSType(DSElementID1, DSElementID2)) - return FALSE; - - DSElementID1 = cCmdNextDSElement(DSElementID1); - DSElementID2 = cCmdNextDSElement(DSElementID2); - } - } - else if (Type1 == TC_ARRAY) - { - if (!cCmdCompareDSType(INC_ID(DSElementID1), INC_ID(DSElementID2))) - return FALSE; - } - - return TRUE; -} - - -//!!! Recursive function -UWORD cCmdCalcFlattenedSize(DS_ELEMENT_ID DSElementID, UWORD Offset) -{ - UWORD Size = 0; - TYPE_CODE TypeCode; - DV_INDEX DVIndex; - UWORD i; - UWORD Count; - - TypeCode = cCmdDSType(DSElementID); - - if (TypeCode == TC_ARRAY) - { - DVIndex = cCmdGetDVIndex(DSElementID, Offset); - - DSElementID = INC_ID(DSElementID); - TypeCode = cCmdDSType(DSElementID); - - if (!IS_AGGREGATE_TYPE(TypeCode)) - { - //Short circuit recursive calculation if our array sub-type is a scalar - Size += DV_ARRAY[DVIndex].ElemSize * DV_ARRAY[DVIndex].Count; - } - else - { - //If the sub type is an aggregate type, then it can contain arrays, so we have to recur - for (i = 0; i < DV_ARRAY[DVIndex].Count; i++) - { - Size += cCmdCalcFlattenedSize(DSElementID, ARRAY_ELEM_OFFSET(DVIndex, i)); - } - } - } - else if (TypeCode == TC_CLUSTER) - { - Count = cCmdClusterCount(DSElementID); - - DSElementID = INC_ID(DSElementID); - for (i = 0; i < Count; i++) - { - Size += cCmdCalcFlattenedSize(DSElementID, Offset); - DSElementID = cCmdNextDSElement(DSElementID); - } - } - else //Scalar - { - Size += cCmdSizeOf(TypeCode); - } - return Size; -} - - -//!!! Recursive function -NXT_STATUS cCmdFlattenToByteArray(UBYTE * pByteArray, UWORD * pByteOffset, DS_ELEMENT_ID DSElementID, UWORD Offset) -{ - NXT_STATUS Status = NO_ERR; - TYPE_CODE TypeCode; - DV_INDEX DVIndex; - UWORD i; - UWORD Count; - UBYTE *pVal; - - TypeCode = cCmdDSType(DSElementID); - - if (TypeCode == TC_ARRAY) - { - DVIndex = cCmdGetDVIndex(DSElementID, Offset); - Count = DV_ARRAY[DVIndex].Count; - - DSElementID = INC_ID(DSElementID); - TypeCode = cCmdDSType(DSElementID); - if (!IS_AGGREGATE_TYPE(TypeCode)) - { - //Short circuit recursive calculation if our array sub-type is a scalar - Count = DV_ARRAY[DVIndex].ElemSize * DV_ARRAY[DVIndex].Count; - memmove((pByteArray + *pByteOffset), (VarsCmd.pDataspace + DV_ARRAY[DVIndex].Offset), Count); - *pByteOffset += Count; - } - else - { - //If the sub type is an aggregate type, then it can contain arrays, so we have to recur - for (i = 0; i < Count; i++) - { - cCmdFlattenToByteArray(pByteArray, pByteOffset, DSElementID, ARRAY_ELEM_OFFSET(DVIndex, i)); - } - } - } - else if (TypeCode == TC_CLUSTER) - { - Count = cCmdClusterCount(DSElementID); - - DSElementID = INC_ID(DSElementID); - for (i = 0; i < Count; i++) - { - cCmdFlattenToByteArray(pByteArray, pByteOffset, DSElementID, Offset); - DSElementID = cCmdNextDSElement(DSElementID); - } - } - else //Scalar - { - pVal = cCmdResolveDataArg(DSElementID, Offset, NULL); - Count = cCmdSizeOf(TypeCode); - - memmove((pByteArray + *pByteOffset), pVal, Count); - *pByteOffset += Count; - } - - return Status; -} - -NXT_STATUS cCmdUnflattenFromByteArray(UBYTE * pByteArray, UWORD * pByteOffset, DS_ELEMENT_ID DSElementID, UWORD Offset) -{ - NXT_STATUS Status = NO_ERR; - TYPE_CODE TypeCode; - DV_INDEX DVIndex; - UWORD i; - UWORD Count; - UBYTE *pVal; - - TypeCode = cCmdDSType(DSElementID); - - if (TypeCode == TC_ARRAY) - { - DVIndex = cCmdGetDVIndex(DSElementID, Offset); - Count = DV_ARRAY[DVIndex].Count; - - DSElementID = INC_ID(DSElementID); - TypeCode = cCmdDSType(DSElementID); - if (!IS_AGGREGATE_TYPE(TypeCode)) - { - //Short circuit recursive calculation if our array sub-type is a scalar - Count = DV_ARRAY[DVIndex].ElemSize * DV_ARRAY[DVIndex].Count; - memmove((VarsCmd.pDataspace + DV_ARRAY[DVIndex].Offset), (pByteArray + *pByteOffset), Count); - *pByteOffset += Count; - } - else - { - //If the sub type is an aggregate type, then it can contain arrays, so we have to recur - for (i = 0; i < Count; i++) - { - cCmdUnflattenFromByteArray(pByteArray, pByteOffset, DSElementID, ARRAY_ELEM_OFFSET(DVIndex, i)); - } - } - } - else if (TypeCode == TC_CLUSTER) - { - Count = cCmdClusterCount(DSElementID); - - DSElementID = INC_ID(DSElementID); - for (i = 0; i < Count; i++) - { - cCmdUnflattenFromByteArray(pByteArray, pByteOffset, DSElementID, Offset); - DSElementID = cCmdNextDSElement(DSElementID); - } - } - else //Scalar - { - pVal = cCmdResolveDataArg(DSElementID, Offset, NULL); - Count = cCmdSizeOf(TypeCode); - - memmove(pVal, (pByteArray + *pByteOffset), Count); - *pByteOffset += Count; - } - - return Status; -} - - -UWORD cCmdClusterCount(DS_ELEMENT_ID DSElementID) -{ - UWORD ClusterCount; - - NXT_ASSERT(cCmdIsDSElementIDSane(DSElementID)); - NXT_ASSERT(cCmdDSType(DSElementID) == TC_CLUSTER); - - ClusterCount = VarsCmd.pDataspaceTOC[DSElementID].DSOffset; - - return ClusterCount; -} - - -UWORD cCmdGetDVIndex(DS_ELEMENT_ID DSElementID, UWORD Offset) -{ - UWORD DVIndex; - - NXT_ASSERT(cCmdDSType(DSElementID) == TC_ARRAY); - - DVIndex = *(UWORD *)(VarsCmd.pDataspace + VarsCmd.pDataspaceTOC[DSElementID].DSOffset + Offset); - - //Make sure we're returning a valid DVIndex - NXT_ASSERT(DVIndex != 0 && DVIndex < DV_ARRAY[0].Count); - - return DVIndex; -} - - -UWORD cCmdArrayCount(DS_ELEMENT_ID DSElementID, UWORD Offset) -{ - DV_INDEX DVIndex; - - NXT_ASSERT(cCmdIsDSElementIDSane(DSElementID)); - NXT_ASSERT(cCmdDSType(DSElementID) == TC_ARRAY); - - DVIndex = cCmdGetDVIndex(DSElementID, Offset); - return DV_ARRAY[DVIndex].Count; -} - -TYPE_CODE cCmdArrayType(DS_ELEMENT_ID DSElementID) -{ - TYPE_CODE TypeCode; - - NXT_ASSERT(cCmdIsDSElementIDSane(DSElementID)); - NXT_ASSERT(cCmdIsDSElementIDSane(INC_ID(DSElementID))); - NXT_ASSERT(cCmdDSType(DSElementID) == TC_ARRAY); - - TypeCode = VarsCmd.pDataspaceTOC[DSElementID + 1].TypeCode; - - return TypeCode; -} - - -DS_ELEMENT_ID cCmdGetDataspaceCount(void) -{ - return (VarsCmd.DataspaceCount); -} - - -UBYTE cCmdCompare(UBYTE CompCode, ULONG Val1, ULONG Val2, TYPE_CODE TypeCode1, TYPE_CODE TypeCode2) -{ - SLONG SVal1, SVal2; - if (QUICK_UNSIGNED_TEST(TypeCode1) || QUICK_UNSIGNED_TEST(TypeCode2)) - { - return ((CompCode == OPCC1_LT && Val1 < Val2) - || (CompCode == OPCC1_GT && Val1 > Val2) - || (CompCode == OPCC1_LTEQ && Val1 <= Val2) - || (CompCode == OPCC1_GTEQ && Val1 >= Val2) - || (CompCode == OPCC1_EQ && Val1 == Val2) - || (CompCode == OPCC1_NEQ && Val1 != Val2)); - } - else - { - SVal1 = (SLONG)Val1; - SVal2 = (SLONG)Val2; - return ((CompCode == OPCC1_LT && SVal1 < SVal2) - || (CompCode == OPCC1_GT && SVal1 > SVal2) - || (CompCode == OPCC1_LTEQ && SVal1 <= SVal2) - || (CompCode == OPCC1_GTEQ && SVal1 >= SVal2) - || (CompCode == OPCC1_EQ && SVal1 == SVal2) - || (CompCode == OPCC1_NEQ && SVal1 != SVal2)); - } -} - -UBYTE cCmdCompareFlt(UBYTE CompCode, float Val1, float Val2, TYPE_CODE TypeCode1, TYPE_CODE TypeCode2) -{ - //!!! add threshold to equality comparisons - return ((CompCode == OPCC1_LT && Val1 < Val2) - || (CompCode == OPCC1_GT && Val1 > Val2) - || (CompCode == OPCC1_LTEQ && Val1 <= Val2) - || (CompCode == OPCC1_GTEQ && Val1 >= Val2) - || (CompCode == OPCC1_EQ && Val1 == Val2) - || (CompCode == OPCC1_NEQ && Val1 != Val2)); -} - - -NXT_STATUS cCmdCompareAggregates(UBYTE CompCode, UBYTE *ReturnBool, DATA_ARG Arg2, UWORD Offset2, DATA_ARG Arg3, UWORD Offset3) -{ - NXT_STATUS Status = NO_ERR; - UBYTE Finished; - - Finished = FALSE; - Status = cCmdRecursiveCompareAggregates(CompCode, ReturnBool, &Finished, Arg2, Offset2, Arg3, Offset3); - if (Finished == FALSE) - { - //If Finished has not been set to TRUE, it means that it was unable to find an inequality, thereby ending the comparison. - //Both elements are equal. Assign the proper value to ReturnBool - *ReturnBool = (CompCode == OPCC1_EQ || CompCode == OPCC1_GTEQ || CompCode == OPCC1_LTEQ); - } - - return Status; -} - - -//!!! Recursive function -NXT_STATUS cCmdRecursiveCompareAggregates(UBYTE CompCode, UBYTE *ReturnBool, UBYTE *Finished, DATA_ARG Arg2, UWORD Offset2, DATA_ARG Arg3, UWORD Offset3) -{ - //The value of Finished must be set to FALSE before calling this function. - //We are able to determine the result of the comparison once we find an inequality. - //Once an inequality is found, Finished is set to TRUE and ReturnBool is set based on the CompCode. - //A call to this function will return with Finished still equal to FALSE if both elements are equal in value and count. - //It is the caller of this function's job to set ReturnBool if this function returns with Finished == FALSE. - - NXT_STATUS Status = NO_ERR; - TYPE_CODE TypeCode2, TypeCode3; - DV_INDEX DVIndex2, DVIndex3; - ULONG ArgVal2, ArgVal3; - UWORD Count2, Count3, MinCount; - UWORD i; - - TypeCode2 = cCmdDSType(Arg2); - TypeCode3 = cCmdDSType(Arg3); - - //Make sure the two things we're comparing are the same type - if (IS_AGGREGATE_TYPE(TypeCode2) && (TypeCode2 != TypeCode3)) - { - NXT_BREAK; - return ERR_ARG; - } - - //Simple case, both args are scalars. Solve and return. - if (!IS_AGGREGATE_TYPE(TypeCode2)) - { - ArgVal2 = cCmdGetScalarValFromDataArg(Arg2, Offset2); - ArgVal3 = cCmdGetScalarValFromDataArg(Arg3, Offset3); - - //Once we find an inequality, we can determine the result of the comparison - *Finished = cCmdCompare(OPCC1_NEQ, ArgVal2, ArgVal3, TypeCode2, TypeCode3); - - if (*Finished) - *ReturnBool = cCmdCompare(CompCode, ArgVal2, ArgVal3, TypeCode2, TypeCode3); - - return Status; - } - - // Initialize local variables for each argument - - if (TypeCode2 == TC_ARRAY) - { - Count2 = cCmdArrayCount(Arg2, Offset2); - DVIndex2 = cCmdGetDVIndex(Arg2, Offset2); - Offset2 = DV_ARRAY[DVIndex2].Offset; - - Count3 = cCmdArrayCount(Arg3, Offset3); - DVIndex3 = cCmdGetDVIndex(Arg3, Offset3); - Offset3 = DV_ARRAY[DVIndex3].Offset; - } - else if (TypeCode2 == TC_CLUSTER) - { - Count2 = cCmdClusterCount(Arg2); - Count3 = cCmdClusterCount(Arg3); - } - - //Short circuit evaluation of EQ and NEQ if counts are different - if (Count2 != Count3) - { - if ((CompCode == OPCC1_EQ) || (CompCode == OPCC1_NEQ)) - { - *Finished = TRUE; - *ReturnBool = (CompCode == OPCC1_NEQ); - return Status; - } - } - - MinCount = (Count2 < Count3) ? Count2 : Count3; - - //Advance aggregate args to first sub-element for next call - Arg2 = INC_ID(Arg2); - Arg3 = INC_ID(Arg3); - - // - // Loop through the sub-elements of aggregate arguments. - // Call cCmdRecursiveCompareAggregates recursively with simpler type. - // - - for (i = 0; i < MinCount; i++) - { - Status = cCmdRecursiveCompareAggregates(CompCode, ReturnBool, Finished, Arg2, Offset2, Arg3, Offset3); - if (*Finished || IS_ERR(Status)) - return Status; - - //Advance aggregate args to next sub-element - if (TypeCode2 == TC_ARRAY) - { - Offset2 += DV_ARRAY[DVIndex2].ElemSize; - Offset3 += DV_ARRAY[DVIndex3].ElemSize; - } - else if (TypeCode2 == TC_CLUSTER) - { - Arg2 = cCmdNextDSElement(Arg2); - Arg3 = cCmdNextDSElement(Arg3); - } - } - - //All elements in aggregates type up to MinCount are equal. Count discrepancy determines comparison outcome. - if (Count2 != Count3) - { - *Finished = TRUE; - *ReturnBool = cCmdCompare(CompCode, Count2, Count3, TC_UWORD, TC_UWORD); - } - //Else, no size discrepancy. Elements are equal. Comparison still not resolved, - //so return !Finished and status back up the call chain for further comparison - - return Status; -} - -ULONG gClearProfileInfo= 0, bigExecTime= 0; -#if VMProfilingCode -void UpdateProfileInfo(ULONG shortOp, CODE_WORD *pInstr, ULONG execTime, ULONG InstrSize) -{ - ULONG j; - ULONG opCode; - - if(execTime > 500 && shortOp == 8) - bigExecTime= shortOp; - if(gClearProfileInfo) { - ExecutedInstrs= 0; - CmdCtrlTime= 0; - OverheadTime= 0; - CmdCtrlCalls= 0; - LastAvgCount= 0; - for(j= 0; j < 255; j++) - CmdCtrlClumpTime[j]= 0; - for(j= 0; j < OPCODE_COUNT; j++) { - InstrProfile[j].Avg= 0; - InstrProfile[j].Time= 0; - InstrProfile[j].Count= 0; - InstrProfile[j].Max= 0; - } - for(j= 0; j < SYSCALL_COUNT; j++) { - SysCallProfile[j].Avg= 0; - SysCallProfile[j].Time= 0; - SysCallProfile[j].Count= 0; - SysCallProfile[j].Max= 0; - } - for(j= 0; j < NUM_SHORT_OPCODE_COUNT; j++) { - ShortInstrProfile[j].Avg= 0; - ShortInstrProfile[j].Time= 0; - ShortInstrProfile[j].Count= 0; - ShortInstrProfile[j].Max= 0; - } - for(j= 0; j < NUM_INTERP_FUNCS; j++) { - InterpFuncProfile[j].Avg= 0; - InterpFuncProfile[j].Time= 0; - InterpFuncProfile[j].Count= 0; - InterpFuncProfile[j].Max= 0; - } - gClearProfileInfo= FALSE; - } - ExecutedInstrs ++; - if(shortOp > 7) // shortop bit set - { - ShortInstrProfile[shortOp-8].Time += execTime; - ShortInstrProfile[shortOp-8].Count++; - if(execTime > ShortInstrProfile[shortOp-8].Max) - ShortInstrProfile[shortOp-8].Max= execTime; - } - else - { - opCode = OP_CODE(pInstr); - InstrProfile[opCode].Time += execTime; - InstrProfile[opCode].Count++; - if(execTime > InstrProfile[opCode].Max) - InstrProfile[opCode].Max= execTime; - if(opCode == OP_SYSCALL) - { - SysCallProfile[GetDataArg(pInstr[1])].Time += execTime; - SysCallProfile[GetDataArg(pInstr[1])].Count++; - if(execTime > SysCallProfile[GetDataArg(pInstr[1])].Max) - SysCallProfile[GetDataArg(pInstr[1])].Max= execTime; - } - - InterpFuncProfile[InstrSize].Time += execTime; - InterpFuncProfile[InstrSize].Count++; - if(execTime > InterpFuncProfile[InstrSize].Max) - InterpFuncProfile[InstrSize].Max= execTime; - } - if(ExecutedInstrs - LastAvgCount > 999) // every N instrs, update avgs - { - for(j= 0; j < OPCODE_COUNT; j++) - if(InstrProfile[j].Count) - InstrProfile[j].Avg= InstrProfile[j].Time/InstrProfile[j].Count; - for(j= 0; j < SYSCALL_COUNT; j++) - if(SysCallProfile[j].Count) - SysCallProfile[j].Avg= SysCallProfile[j].Time/SysCallProfile[j].Count; - for(j= 0; j < NUM_SHORT_OPCODE_COUNT; j++) - if(ShortInstrProfile[j].Count) - ShortInstrProfile[j].Avg= ShortInstrProfile[j].Time/ShortInstrProfile[j].Count; - for(j= 0; j < NUM_INTERP_FUNCS; j++) - if(InterpFuncProfile[j].Count) - InterpFuncProfile[j].Avg= InterpFuncProfile[j].Time/InterpFuncProfile[j].Count; - LastAvgCount= ExecutedInstrs; - } -} -#endif - - -// -// Interpreter Functions -// - -NXT_STATUS cCmdInterpFromClump() -{ - CLUMP_ID Clump= VarsCmd.RunQ.Head; - NXT_STATUS Status = NO_ERR; - CLUMP_REC * pClumpRec; - CODE_WORD * pInstr, *lastClumpInstr; - UBYTE InstrSize; - ULONG shortOp, nextMSTick; - SLONG i; -#if VM_BENCHMARK - ULONG InstrTime = dTimerRead(); -#endif - - if (!cCmdIsClumpIDSane(Clump)) // this means all clumps are asleep - return TIMES_UP; - - //Resolve clump record structure and current instruction pointer - pClumpRec = &(VarsCmd.pAllClumps[Clump]); - pInstr = pClumpRec->PC; // abs - lastClumpInstr= pClumpRec->CodeEnd; // abs - - i= gInstrsToExecute; - nextMSTick= dTimerGetNextMSTickCnt(); - do - { -#if VMProfilingCode - ULONG instrStartTime; - instrStartTime= dTimerReadHiRes(); -#endif - - ULONG instrWord= *(UWORD*)pInstr; - shortOp= (instrWord>>8) & 0x0F; - if(shortOp > 7) // shortop bit set - Status= ShortInterpFuncs[shortOp - 8](pInstr); - else - { // we know this is a long instr, dispatch on num params, which correlates to size - InstrSize = INSTR_SIZE(instrWord); // keep in a local for profiling - Status = (*InterpFuncs[InstrSize])(pInstr); - } - -#if VMProfilingCode - UpdateProfileInfo(shortOp, pInstr, dTimerReadHiRes() - instrStartTime, InstrSize); -#endif - -afterCompaction: - if (Status == NO_ERR) - pInstr += gPCDelta; - else if (Status == CLUMP_DONE) // already requeued - { - pClumpRec->PC = pClumpRec->CodeStart; - pClumpRec->CurrFireCount = pClumpRec->InitFireCount; - return Status; - } - else if (Status == CLUMP_SUSPEND || Status == BREAKOUT_REQ || Status == ROTATE_QUEUE) // already requeued - { - pClumpRec->PC = pInstr + gPCDelta; - //Throw error if we ever advance beyond the clump's codespace - if (pInstr > lastClumpInstr) - { - NXT_BREAK; - Status = ERR_INSTR; - } - return Status; - } - else if (Status == ERR_MEM) - { - //Memory is full. Compact dataspace and try the instruction again. - //!!! Could compact DopeVectorArray here - cCmdDSCompact(); - if(shortOp > 7) // shortop bit set - Status= ShortInterpFuncs[shortOp - 8](pInstr); - else - Status = (*InterpFuncs[InstrSize])(pInstr); - if(Status == ERR_MEM) - return Status; - else - goto afterCompaction; - } - else // other errors, breakout, stop - return Status; - - //Throw error if we ever advance beyond the clump's codespace - if (pInstr > lastClumpInstr) - { - NXT_BREAK; - Status = ERR_INSTR; - } - -#if VM_BENCHMARK - //Increment opcode count - VarsCmd.OpcodeBenchmarks[OP_CODE(pInstr)][0]++; - - InstrTime = dTimerRead() - InstrTime; - if (InstrTime > 1) - { - VarsCmd.OpcodeBenchmarks[OP_CODE(pInstr)][1]++; - if (InstrTime > VarsCmd.OpcodeBenchmarks[OP_CODE(pInstr)][2]) - VarsCmd.OpcodeBenchmarks[OP_CODE(pInstr)][2] = InstrTime; - } - VarsCmd.InstrCount++; -#endif - - //Count one more instruction for this pass - if ((SLONG)(nextMSTick - dTimerReadTicks()) <= 0) // HWTimer has passed ms tick limit - Status= TIMES_UP; - else if(--i <= 0) - Status= ROTATE_QUEUE; - } while (!Status); - pClumpRec->PC= pInstr; - return (Status); -} - - -NXT_STATUS cCmdInterpUnop1(CODE_WORD * const pCode) -{ - NXT_STATUS Status = NO_ERR; - UBYTE opCode; - DATA_ARG Arg1; - - NXT_ASSERT(pCode != NULL); - - gPCDelta= 2; - opCode = OP_CODE(pCode); - Arg1 = pCode[1]; - - switch (opCode) - { - case OP_JMP: - { - gPCDelta= (SWORD)Arg1; - Status = NO_ERR; - } - break; - - case OP_ACQUIRE: - { - NXT_ASSERT(cCmdIsDSElementIDSane(Arg1)); - NXT_ASSERT(VarsCmd.pDataspaceTOC[Arg1].TypeCode == TC_MUTEX); - - Status = cCmdAcquireMutex((MUTEX_Q *)cCmdDSScalarPtr(Arg1, 0)); - } - break; - - case OP_RELEASE: - { - NXT_ASSERT(cCmdIsDSElementIDSane(Arg1)); - NXT_ASSERT(VarsCmd.pDataspaceTOC[Arg1].TypeCode == TC_MUTEX); - - Status = cCmdReleaseMutex((MUTEX_Q *)cCmdDSScalarPtr(Arg1, 0)); - } - break; - - case OP_SUBRET: - { - NXT_ASSERT(cCmdIsDSElementIDSane(Arg1)); - - //Take Subroutine off RunQ - //Add Subroutine's caller to RunQ - cCmdDeQClump(&(VarsCmd.RunQ), VarsCmd.RunQ.Head); - cCmdEnQClump(&(VarsCmd.RunQ), *((CLUMP_ID *)cCmdDSScalarPtr(Arg1, 0))); - - Status = CLUMP_DONE; - } - break; - - case OP_FINCLUMPIMMED: - { - CLUMP_ID Clump= VarsCmd.RunQ.Head; // DeQ changes Head, use local val - cCmdDeQClump(&(VarsCmd.RunQ), Clump); //Dequeue finalized clump - cCmdSchedDependent(Clump, (CLUMP_ID)Arg1); // Use immediate form - - Status = CLUMP_DONE; - } - break; - - case OP_GETTICK: - { - cCmdSetScalarValFromDataArg(Arg1, dTimerReadNoPoll()); - } - break; - - case OP_STOP: - { - //Unwired Arg1 means always stop - if (Arg1 == NOT_A_DS_ID) - Status = STOP_REQ; - else if (cCmdGetScalarValFromDataArg(Arg1, 0) > 0) - Status = STOP_REQ; - } - break; - - default: - { - //Fatal error: Unrecognized instruction - NXT_BREAK; - Status = ERR_INSTR; - } - break; - } - - return (Status); -} - -ULONG scalarNots= 0, scalarBrtst= 0, scalarUn2Other= 0, scalarUn2Dispatch= 0, polyUn2Dispatch= 0; -NXT_STATUS cCmdInterpScalarUnop2(CODE_WORD * const pCode) -{ - NXT_STATUS Status; - UBYTE opCode; - - NXT_ASSERT(pCode != NULL); - opCode = OP_CODE(pCode); - DATA_ARG Arg1, Arg2; - - scalarUn2Dispatch ++; - if(opCode == OP_NOT) // t2 && t3 guaranteed scalar - { - gPCDelta= 3; - Arg1 = pCode[1]; - Arg2 = pCode[2]; - ULONG ArgVal1, ArgVal2; - - ArgVal2= cCmdGetScalarValFromDataArg(Arg2, 0); - //!!! OP_NOT is logical, *not* bit-wise. - //This differs from the other logical ops because we don't distinguish booleans from UBYTEs. - ArgVal1= (!ArgVal2); - cCmdSetScalarValFromDataArg(Arg1, ArgVal1); - Status = NO_ERR; - scalarNots ++; - } - else if(opCode == OP_BRTST) - { - ULONG Branch, compare= COMP_CODE(pCode); - ULONG TypeCode; - - Arg1 = pCode[1]; - Arg2 = pCode[2]; - TypeCode = cCmdDSType(Arg2); - - if(Arg2 == NOT_A_DS_ID) - { - Branch= ((compare == OPCC1_EQ) - || (compare == OPCC1_LTEQ) - || (compare == OPCC1_GTEQ)); - } - else - { - if(compare == OPCC1_EQ && TypeCode == TC_UBYTE) // very common for loops - { - UBYTE *pBRVal = (VarsCmd.pDataspace + VarsCmd.pDataspaceTOC[Arg2].DSOffset); - Branch= *pBRVal == 0; - } - else - { - SLONG SVal1 = (SLONG)cCmdGetScalarValFromDataArg(Arg2, 0); - Branch= ((compare == OPCC1_EQ && SVal1 == 0) - || (compare == OPCC1_NEQ && SVal1 != 0) - || (compare == OPCC1_GT && SVal1 > 0) - || (compare == OPCC1_LT && SVal1 < 0) - || (compare == OPCC1_LTEQ && SVal1 <= 0) - || (compare == OPCC1_GTEQ && SVal1 >= 0)); - } - } - if (Branch) - gPCDelta = (SWORD)Arg1; - else - gPCDelta= 3; - Status = NO_ERR; - scalarBrtst ++; - } - else { - Status= cCmdInterpUnop2(pCode); - scalarUn2Other ++; - } - return Status; -} - -NXT_STATUS cCmdInterpUnop2(CODE_WORD * const pCode) -{ - NXT_STATUS Status = NO_ERR; - UBYTE opCode; - DATA_ARG Arg1; - DATA_ARG Arg2; - void *pArg1 = NULL, *pArg2 = NULL; - TYPE_CODE TypeCode1, TypeCode2; - - ULONG i; - UWORD ArgC; - static UBYTE * ArgV[MAX_CALL_ARGS + 1]; - - polyUn2Dispatch ++; - UWORD Count; - UWORD Offset; - SLONG TmpSLong; - ULONG TmpULong; - ULONG ArgVal2; - float FltArgVal2; - char Buffer[30]; - char FormatString[5]; - UBYTE CheckTrailingZeros = 0; - - NXT_ASSERT(pCode != NULL); - - gPCDelta= 3; - opCode = OP_CODE(pCode); - Arg1 = pCode[1]; - Arg2 = pCode[2]; - - if (opCode == OP_NEG || opCode == OP_NOT || opCode == OP_TST || opCode == OP_SQRT || opCode == OP_ABS) - { - return cCmdInterpPolyUnop2(*pCode, Arg1, 0, Arg2, 0); - } - - switch (opCode) - { - case OP_MOV: - { - Status= cCmdMove(Arg1, Arg2); - } - break; - - case OP_SET: - { - //!!! Should throw error if TypeCode1 is non-scalar - // Accepting non-scalar destinations could have unpredictable results! - cCmdSetScalarValFromDataArg(Arg1, Arg2); - } - break; - - case OP_BRTST: - { - //!!!BDUGGAN BRTST w/ Float? - ULONG Branch, compare= COMP_CODE(pCode); - ULONG TypeCode = cCmdDSType(Arg2); - if(compare == OPCC1_EQ && TypeCode == TC_UBYTE) // very common for loops - { - UBYTE *pBRVal = (VarsCmd.pDataspace + VarsCmd.pDataspaceTOC[Arg2].DSOffset); - Branch= *pBRVal == 0; - } - else - { - SLONG SVal1 = (SLONG)cCmdGetScalarValFromDataArg(Arg2, 0); - Branch= ((compare == OPCC1_EQ && SVal1 == 0) - || (compare == OPCC1_NEQ && SVal1 != 0) - || (compare == OPCC1_GT && SVal1 > 0) - || (compare == OPCC1_LT && SVal1 < 0) - || (compare == OPCC1_LTEQ && SVal1 <= 0) - || (compare == OPCC1_GTEQ && SVal1 >= 0)); - } - if (Branch) - - { - gPCDelta = (SWORD)Arg1; - Status = NO_ERR; - } - } - break; - - case OP_FINCLUMP: - { - CLUMP_ID Clump= VarsCmd.RunQ.Head; // DeQ changes Head, use local val - cCmdDeQClump(&(VarsCmd.RunQ), Clump); //Dequeue finalized clump - cCmdSchedDependents(Clump, (SWORD)Arg1, (SWORD)Arg2); - Status = CLUMP_DONE; - } - break; - - case OP_SUBCALL: - { - NXT_ASSERT(cCmdIsClumpIDSane((CLUMP_ID)Arg1)); - NXT_ASSERT(!cCmdIsClumpOnQ(&(VarsCmd.RunQ), (CLUMP_ID)Arg1)); - - NXT_ASSERT(cCmdIsDSElementIDSane(Arg2)); - - *((CLUMP_ID *)(cCmdDSScalarPtr(Arg2, 0))) = VarsCmd.RunQ.Head; - - cCmdDeQClump(&(VarsCmd.RunQ), VarsCmd.RunQ.Head); //Take caller off RunQ - cCmdEnQClump(&(VarsCmd.RunQ), (CLUMP_ID)Arg1); //Add callee to RunQ - - Status = CLUMP_SUSPEND; - } - break; - - case OP_ARRSIZE: - { - cCmdSetScalarValFromDataArg(Arg1, cCmdArrayCount(Arg2, 0)); - } - break; - - case OP_SYSCALL: - { - if (Arg1 >= SYSCALL_COUNT) - { - NXT_BREAK; - Status = ERR_INSTR; - break; - } - - ArgC = cCmdClusterCount(Arg2); - - if (ArgC > MAX_CALL_ARGS) - { - NXT_BREAK; - Status = ERR_INSTR; - break; - } - - if (ArgC > 0) - { - Arg2 = INC_ID(Arg2); - - for (i = 0; i < ArgC; i++) - { - if (cCmdDSType(Arg2) == TC_ARRAY) - { - //Storing pointer to array's DV_INDEX - //!!! This resolve is different than cCmdDSPtr - // since SysCalls may need the DVIndex to re-alloc arrays - ArgV[i] = VarsCmd.pDataspace + VarsCmd.pDataspaceTOC[Arg2].DSOffset; - } - else - { - ArgV[i] = cCmdDSPtr(Arg2, 0); - } - - //If any argument fails to resolve, return a fatal error. - if (ArgV[i] == NULL) - { - Status = ERR_BAD_PTR; - break; - } - - Arg2 = cCmdNextDSElement(Arg2); - } - } - else - { - i = 0; - } - - //ArgV list is null terminated - ArgV[i] = NULL; - - Status = (*SysCallFuncs[Arg1])(ArgV); - } - break; - - case OP_FLATTEN: - { - //Flatten Arg2 to a NULL terminated string - - //Assert that the destination is a string (array of bytes) - NXT_ASSERT(cCmdDSType(Arg1) == TC_ARRAY); - NXT_ASSERT(cCmdDSType(INC_ID(Arg1)) == TC_UBYTE); - - Count = cCmdCalcFlattenedSize(Arg2, 0); - //Add room for NULL terminator - Count++; - Status = cCmdDSArrayAlloc(Arg1, 0, Count); - if (IS_ERR(Status)) - return Status; - - pArg1 = cCmdResolveDataArg(Arg1, 0, NULL); - Offset = 0; - - Status = cCmdFlattenToByteArray(pArg1, &Offset, Arg2, 0); - //Append NULL terminator - *((UBYTE *)pArg1 + Offset) = 0; - Offset++; - NXT_ASSERT(Offset == Count); - } - break; - - case OP_NUMTOSTRING: - { - //Assert that the destination is a string (array of bytes) - NXT_ASSERT(cCmdDSType(Arg1) == TC_ARRAY); - NXT_ASSERT(cCmdDSType(INC_ID(Arg1)) == TC_UBYTE); - - //Make sure we're trying to convert a scalar to a string - TypeCode2= cCmdDSType(Arg2); - NXT_ASSERT(!IS_AGGREGATE_TYPE(TypeCode2)); - - if (TypeCode2 == TC_FLOAT) - { - pArg2 = cCmdResolveDataArg(Arg2, 0, NULL); - FltArgVal2 = cCmdGetValFlt(pArg2, TypeCode2); - // is number too big for display? then format differently and don't bother with trailing zeros - if ((FltArgVal2 > 9999999999999.99f)||(FltArgVal2 < -999999999999.99f)){ // these are the widest %.2f numbers that will fit on display - strcpy (FormatString, "%.6g"); - } - else{ - strcpy (FormatString, "%.2f"); - CheckTrailingZeros = 1; - } - Count = sprintf(Buffer, FormatString, FltArgVal2); - Count++; //add room for null terminator - - if (CheckTrailingZeros){ - // Determine if the trailing digits are zeros. If so, drop them - if (Buffer[Count-2] == 0x30) { // NOTE: 0x30 is ASCII 0 - if (Buffer[Count-3] == 0x30){ - strcpy (FormatString, "%.0f"); // the last two digits = 0, copy as integer - Count = Count - 3; // don't need memory for decimal and 2 ascii characters - } - else { - strcpy (FormatString, "%.1f"); // only the 2nd digit = 0 so drop it, but keep the tenths place - Count = Count - 1; // don't need memory for 2nd ascii character - } - } - } - } - else - { - ArgVal2 = cCmdGetScalarValFromDataArg(Arg2, 0); - //Calculate size of array - if (ArgVal2 == 0) - Count = 1; - else { - Count = 0; - SLONG digits= 0; - ULONG Tmp= 1; - if (TypeCode2 == TC_SLONG || TypeCode2 == TC_SWORD || TypeCode2 == TC_SBYTE) - { - TmpSLong = (SLONG)ArgVal2; - //Add room for negative sign - if (TmpSLong < 0) { - Count++; - TmpULong= -TmpSLong; - } - else - TmpULong= ArgVal2; - } - else - TmpULong= ArgVal2; - - while (Tmp <= TmpULong && digits < 10) { // maxint is ten digits, max - Tmp *= 10; - digits++; - } - Count += digits; - } - //add room for NULL terminator - Count++; - } - - //Allocate array - Status = cCmdDSArrayAlloc(Arg1, 0, Count); - if (IS_ERR(Status)) - return Status; - - pArg1 = cCmdResolveDataArg(Arg1, 0, &TypeCode1); - - //Populate array - if (TypeCode2 == TC_FLOAT) - { - sprintf(pArg1, FormatString, FltArgVal2); - } - else if (TypeCode2 == TC_SLONG || TypeCode2 == TC_SWORD || TypeCode2 == TC_SBYTE) - { - sprintf(pArg1, "%d", (SLONG)ArgVal2); - } - else - { - sprintf(pArg1, "%u", ArgVal2); - } - } - break; - - case OP_STRTOBYTEARR: - { - NXT_ASSERT((cCmdDSType(Arg1) == TC_ARRAY) && (cCmdDSType(INC_ID(Arg1)) == TC_UBYTE)); - NXT_ASSERT((cCmdDSType(Arg2) == TC_ARRAY) && (cCmdDSType(INC_ID(Arg2)) == TC_UBYTE)); - - Count = cCmdArrayCount(Arg2, 0); - - if (Count > 0) - { - Status = cCmdDSArrayAlloc(Arg1, 0, (UWORD)(Count - 1)); - if (IS_ERR(Status)) - return Status; - - pArg1 = cCmdResolveDataArg(Arg1, 0, NULL); - pArg2 = cCmdResolveDataArg(Arg2, 0, NULL); - - memmove(pArg1, pArg2, Count - 1); - } - } - break; - - case OP_BYTEARRTOSTR: - { - NXT_ASSERT((cCmdDSType(Arg1) == TC_ARRAY) && (cCmdDSType(INC_ID(Arg1)) == TC_UBYTE)); - NXT_ASSERT((cCmdDSType(Arg2) == TC_ARRAY) && (cCmdDSType(INC_ID(Arg2)) == TC_UBYTE)); - - Count = cCmdArrayCount(Arg2, 0); - - Status = cCmdDSArrayAlloc(Arg1, 0, (UWORD)(Count + 1)); - if (IS_ERR(Status)) - return Status; - - pArg1 = cCmdResolveDataArg(Arg1, 0, NULL); - pArg2 = cCmdResolveDataArg(Arg2, 0, NULL); - - memmove(pArg1, pArg2, Count); - *((UBYTE *)pArg1 + Count) = '\0'; - } - break; - - case OP_WAIT: - { - ULONG wait= 0; - //Unwired Arg2 defaults to wait 0, which rotates queue - if (Arg2 != NOT_A_DS_ID) - wait= cCmdGetScalarValFromDataArg(Arg2, 0); - if(wait == 0) - Status= ROTATE_QUEUE; - else - Status = cCmdSleepClump(wait + IOMapCmd.Tick); // put to sleep, to wake up wait ms in future - if(Arg1 != NOT_A_DS_ID) - cCmdSetScalarValFromDataArg(Arg1, dTimerReadNoPoll()); - } - break; - - default: - { - //Fatal error: Unrecognized instruction - NXT_BREAK; - Status = ERR_INSTR; - } - break; - } - - return (Status); -} - - -NXT_STATUS cCmdInterpPolyUnop2(CODE_WORD const Code, DATA_ARG Arg1, UWORD Offset1Param, DATA_ARG Arg2, UWORD Offset2Param) -{ - NXT_STATUS Status = NO_ERR; - TYPE_CODE TypeCode1, TypeCode2; - DV_INDEX DVIndex1, DVIndex2; - ULONG ArgVal1, ArgVal2; - float FltArgVal1, FltArgVal2; - UWORD Count1, Count2, Offset1= Offset1Param, Offset2= Offset2Param; - UWORD MinArrayCount; - UWORD i; - //!!! AdvCluster is intended to catch the case where sources are Cluster and an Array of Clusters. - // In practice, the logic it uses is broken, leading to some source cluster elements being ignored. - UBYTE AdvCluster; - - void * pArg1 = NULL, - *pArg2 = NULL; - - TypeCode1 = cCmdDSType(Arg1); - TypeCode2 = cCmdDSType(Arg2); - - //Simple case, scalar. Solve and return. - if (!IS_AGGREGATE_TYPE(TypeCode2)) - { - NXT_ASSERT(!IS_AGGREGATE_TYPE(TypeCode1)); - - pArg1 = cCmdResolveDataArg(Arg1, Offset1, &TypeCode1); - - if (TypeCode1 == TC_FLOAT || TypeCode2 == TC_FLOAT) - { - pArg2 = cCmdResolveDataArg(Arg2, Offset2, &TypeCode2); - FltArgVal2 = cCmdGetValFlt(pArg2, TypeCode2); - FltArgVal1 = cCmdUnop2Flt(Code, FltArgVal2, TypeCode2); - cCmdSetValFlt(pArg1, TypeCode1, FltArgVal1); - } - else - { - ArgVal2= cCmdGetScalarValFromDataArg(Arg2, Offset2); - if(OP_CODE(&Code) == OP_MOV) - ArgVal1= ArgVal2; - else - ArgVal1 = cCmdUnop2(Code, ArgVal2, TypeCode2); - cCmdSetVal(pArg1, TypeCode1, ArgVal1); - } - return Status; - } - - //At least one of the args is an aggregate type - - if(TypeCode1 == TC_ARRAY && TypeCode2 == TC_ARRAY) { - TYPE_CODE tc1, tc2; - tc1= cCmdDSType(INC_ID(Arg1)); - tc2= cCmdDSType(INC_ID(Arg2)); - if(tc1 <= TC_LAST_INT_SCALAR && tc1 == tc2) { - void *pArg1, *pArg2; - ULONG Count = cCmdArrayCount(Arg2, Offset2); - Status = cCmdDSArrayAlloc(Arg1, Offset1, Count); - if (IS_ERR(Status)) - return Status; - pArg1 = cCmdResolveDataArg(Arg1, Offset1, NULL); - pArg2 = cCmdResolveDataArg(Arg2, Offset2, NULL); - memmove(pArg1, pArg2, Count * cCmdSizeOf(tc1)); - return Status; - } - } - - - // - // Initialize Count and ArrayType local variables for each argument - // - - if (TypeCode2 == TC_ARRAY) - { - Count2 = cCmdArrayCount(Arg2, Offset2); - DVIndex2 = cCmdGetDVIndex(Arg2, Offset2); - Offset2 = DV_ARRAY[DVIndex2].Offset; - } - else if (TypeCode2 == TC_CLUSTER) - { - Count2 = cCmdClusterCount(Arg2); - } - - if (TypeCode1 == TC_ARRAY) - { - if (TypeCode2 != TC_ARRAY) - { - //If output is an array, but source is not an array, that's a fatal error! - NXT_BREAK; - return (ERR_ARG); - } - if(Count2 == 0) { // both arrays, input is empty, is output already empty? - Count1= cCmdArrayCount(Arg1, Offset1); - if(Count1 == 0) - return NO_ERR; - } - - MinArrayCount = Count2; - - //Make sure the destination array is the proper size to hold the result - Status = cCmdDSArrayAlloc(Arg1, Offset1, MinArrayCount); - if (IS_ERR(Status)) - return Status; - - if(MinArrayCount == 0) // if we emptied array, nothing else to do. - return NO_ERR; - Count1 = MinArrayCount; - DVIndex1 = cCmdGetDVIndex(Arg1, Offset1); - Offset1 = DV_ARRAY[DVIndex1].Offset; - AdvCluster = FALSE; - } - else if (TypeCode1 == TC_CLUSTER) - { - Count1 = cCmdClusterCount(Arg1); - AdvCluster = TRUE; - } - - //Advance aggregate args to first sub-element for next call - if (IS_AGGREGATE_TYPE(TypeCode1)) - Arg1 = INC_ID(Arg1); - if (IS_AGGREGATE_TYPE(TypeCode2)) - Arg2 = INC_ID(Arg2); - - // - // Loop through the sub-elements of aggregate arguments. - // Call cCmdInterpPolyUnop2 recursively with simpler type. - // - for (i = 0; i < Count1; i++) - { - Status = cCmdInterpPolyUnop2(Code, Arg1, Offset1, Arg2, Offset2); - if (IS_ERR(Status)) - return Status; - - //Advance aggregate args to next sub-element - if (TypeCode1 == TC_ARRAY) - Offset1 += DV_ARRAY[DVIndex1].ElemSize; - else if ((TypeCode1 == TC_CLUSTER) && AdvCluster) - Arg1 = cCmdNextDSElement(Arg1); - - if (TypeCode2 == TC_ARRAY) - Offset2 += DV_ARRAY[DVIndex2].ElemSize; - else if ((TypeCode2 == TC_CLUSTER) && AdvCluster) - Arg2 = cCmdNextDSElement(Arg2); - } - return Status; -} - - -ULONG cCmdUnop2(CODE_WORD const Code, ULONG Operand, TYPE_CODE TypeCode) -{ - UBYTE opCode; - - opCode = OP_CODE((&Code)); - if(opCode == OP_MOV) - return Operand; - else if(opCode == OP_NEG) - return (-((SLONG)Operand)); - else if(opCode == OP_NOT) - //!!! OP_NOT is logical, *not* bit-wise. - //This differs from the other logical ops because we don't distinguish booleans from UBYTEs. - return (!Operand); - else if(opCode == OP_TST) - return cCmdCompare(COMP_CODE((&Code)), Operand, 0, TypeCode, TypeCode); - else if(opCode == OP_ABS) - return abs(Operand); - else - { - //Unrecognized instruction, NXT_BREAK for easy debugging (ERR_INSTR handled in caller) - NXT_BREAK; - return 0; - } -} - -float cCmdUnop2Flt(CODE_WORD const Code, float Operand, TYPE_CODE TypeCode) -{ - UBYTE opCode; - - opCode = OP_CODE((&Code)); - if(opCode == OP_MOV) - return Operand; - else if(opCode == OP_NEG) - return (-(Operand)); - else if(opCode == OP_NOT) - //!!! OP_NOT is logical, *not* bit-wise. - //This differs from the other logical ops because we don't distinguish booleans from UBYTEs. - return (!Operand); - else if(opCode == OP_TST) - return cCmdCompareFlt(COMP_CODE((&Code)), Operand, 0, TypeCode, TypeCode); - else if(opCode == OP_ABS) - return fabsf(Operand); - else if(opCode == OP_SQRT) - return sqrtf(Operand); -#if 0 - else if(opCode == OP_SIN) - return sinf(Operand); - else if(opCode == OP_COS) - return cosf(Operand); - else if(opCode == OP_TAN) - return tanf(Operand); - else if(opCode == OP_ASIN) - return asinf(Operand); - else if(opCode == OP_ACOS) - return acosf(Operand); - else if(opCode == OP_ATAN) - return atanf(Operand); -#endif - else - { - //Unrecognized instruction, NXT_BREAK for easy debugging (ERR_INSTR handled in caller) - NXT_BREAK; - return 0; - } -} - -NXT_STATUS cCmdIOGetSet(ULONG opCode, DATA_ARG Arg1, DATA_ARG Arg2, DATA_ARG Arg3) -{ - ULONG ArgVal1, ArgVal2; - TYPE_CODE TypeCode2; - void *pArg2 = NULL; - switch(opCode) - { - case OP_GETOUT: - { - ArgVal2 = cCmdGetScalarValFromDataArg(Arg2, 0); - Arg2 = (UWORD)(0x200 | (Arg3 + ArgVal2 * IO_OUT_FPP)); - pArg2 = cCmdResolveIODataArg(Arg2, 0, &TypeCode2); - cCmdSetScalarValFromDataArg(Arg1, cCmdGetVal(pArg2, TypeCode2)); - } - break; - //!!! All IO map access commands should screen illegal port values! - // Right now, cCmdResolveIODataArg's implementation allows SETIN/GETIN to access arbitrary RAM! - case OP_SETIN: - { - ArgVal2 = cCmdGetScalarValFromDataArg(Arg2, 0); - Arg2 = (UWORD)(Arg3 + ArgVal2 * IO_IN_FPP); - pArg2 = cCmdResolveIODataArg(Arg2, 0, &TypeCode2); - ArgVal1 = cCmdGetScalarValFromDataArg(Arg1, 0); - cCmdSetVal(pArg2, TypeCode2, ArgVal1); - } - break; - case OP_GETIN: - { - TYPE_CODE TypeCode1; - void * pArg1; - ArgVal2 = cCmdGetScalarValFromDataArg(Arg2, 0); - Arg2 = (UWORD)(Arg3 + ArgVal2 * IO_IN_FPP); - pArg2 = cCmdResolveIODataArg(Arg2, 0, &TypeCode2); - TypeCode1= cCmdDSType(Arg1); - pArg1= cCmdDSScalarPtr(Arg1, 0); - if(TypeCode1 <= TC_SBYTE && TypeCode1 <= TC_SBYTE) // seems really common - *(UBYTE*)pArg1= *(UBYTE*)pArg2; - else - cCmdSetVal(pArg1, TypeCode1, cCmdGetVal(pArg2, TypeCode2)); - } - break; - } - return NO_ERR; -} - -ULONG scalarCmp= 0, scalarFloatCmp= 0, recursiveCmp= 0, PolyScalarCmp= 0, polyPolyCmp= 0, scalarOther= 0, scalarBinopDispatch= 0, polyBinopDispatch= 0; -NXT_STATUS cCmdInterpScalarBinop(CODE_WORD * const pCode) -{ - NXT_STATUS Status; - UBYTE opCode; - UBYTE CmpBool; - - NXT_ASSERT(pCode != NULL); - opCode = OP_CODE(pCode); - DATA_ARG Arg1, Arg2, Arg3; - - scalarBinopDispatch ++; - if(opCode == OP_CMP) // t2 && t3 guaranteed scalar or string - { - gPCDelta= 4; - Arg1 = pCode[1]; - Arg2 = pCode[2]; - Arg3 = pCode[3]; - ULONG ArgVal1, ArgVal2, ArgVal3; - TYPE_CODE TypeCode2, TypeCode3; - DS_TOC_ENTRY *dsTOC2Ptr= &VarsCmd.pDataspaceTOC[Arg2]; - DS_TOC_ENTRY *dsTOC3Ptr= &VarsCmd.pDataspaceTOC[Arg3]; - - TypeCode2 = dsTOC2Ptr->TypeCode; - TypeCode3 = dsTOC3Ptr->TypeCode; - if(TypeCode2 <= TC_LAST_INT_SCALAR && TypeCode3 <= TC_LAST_INT_SCALAR) { - ArgVal2= GetProcArray[TypeCode2](VarsCmd.pDataspace + dsTOC2Ptr->DSOffset); - ArgVal3= GetProcArray[TypeCode3](VarsCmd.pDataspace + dsTOC3Ptr->DSOffset); - ArgVal1= cCmdCompare(COMP_CODE(pCode), ArgVal2, ArgVal3, TypeCode2, TypeCode3); - DS_TOC_ENTRY *dsTOC1Ptr= &VarsCmd.pDataspaceTOC[Arg1]; - SetProcArray[dsTOC1Ptr->TypeCode](VarsCmd.pDataspace + dsTOC1Ptr->DSOffset, ArgVal1); - scalarCmp++; - Status = NO_ERR; - } - else if (TypeCode2 == TC_ARRAY) // two strings - { - // memcmp(); here or in compareagg, could use memcmp to speed up string compares ??? - Status = cCmdCompareAggregates(COMP_CODE(pCode), &CmpBool, Arg2, 0, Arg3, 0); - cCmdSetScalarValFromDataArg(Arg1, CmpBool); - recursiveCmp++; - } - else { // floats - Status = cCmdInterpPolyBinop(*pCode, Arg1, 0, Arg2, 0, Arg3, 0); - scalarFloatCmp++; - } - } - else if(opCode == OP_BRCMP) { // t2 and t3 guaranteed scalar - TYPE_CODE TypeCode2, TypeCode3; - ULONG ArgVal2, ArgVal3; - - Arg1 = pCode[1]; - Arg2 = pCode[2]; - Arg3 = pCode[3]; - TypeCode2= cCmdDSType(Arg2); - TypeCode3= cCmdDSType(Arg3); - ArgVal2= cCmdGetScalarValFromDataArg(Arg2, 0); - ArgVal3= cCmdGetScalarValFromDataArg(Arg3, 0); - CmpBool= cCmdCompare(COMP_CODE(pCode), ArgVal2, ArgVal3, TypeCode2, TypeCode3); - - if (CmpBool) - gPCDelta = (SWORD)Arg1; - else - gPCDelta= 4; - Status= NO_ERR; - } - else if(opCode >= OP_SETIN && opCode <= OP_GETOUT) { - Arg1 = pCode[1]; - Arg2 = pCode[2]; - Arg3 = pCode[3]; - Status= cCmdIOGetSet(opCode, Arg1, Arg2, Arg3); - gPCDelta= 4; - } - else { - scalarOther ++; - Status= cCmdInterpBinop(pCode); - } - return Status; -} - - -NXT_STATUS cCmdInterpBinop(CODE_WORD * const pCode) -{ - NXT_STATUS Status = NO_ERR; - UBYTE opCode; - DATA_ARG Arg1, Arg2, Arg3; - ULONG ArgVal3; - UBYTE CmpBool; - DV_INDEX DVIndex1, DVIndex2; - UWORD i; - - polyBinopDispatch ++; - gPCDelta= 4; - - NXT_ASSERT(pCode != NULL); - opCode = OP_CODE(pCode); - Arg1 = pCode[1]; - Arg2 = pCode[2]; - Arg3 = pCode[3]; - - if (opCode <= OP_XOR) // && ! OP_NEG, can't happen since it is unop - Status= cCmdInterpPolyBinop(opCode, Arg1, 0, Arg2, 0, Arg3, 0); - else if(opCode >= OP_SETIN && opCode <= OP_GETOUT) - Status= cCmdIOGetSet(opCode, Arg1, Arg2, Arg3); - else { - switch (opCode) - { - case OP_CMP: - { - TYPE_CODE TypeCode2= cCmdDSType(Arg2), TypeCode3= cCmdDSType(Arg3); - if(TypeCode2 <= TC_LAST_INT_SCALAR && TypeCode3 <= TC_LAST_INT_SCALAR) { - ULONG ArgVal1, ArgVal2, ArgVal3; - ArgVal2= cCmdGetScalarValFromDataArg(Arg2, 0); - ArgVal3= cCmdGetScalarValFromDataArg(Arg3, 0); - ArgVal1= cCmdCompare(COMP_CODE(pCode), ArgVal2, ArgVal3, TypeCode2, TypeCode3); - cCmdSetScalarValFromDataArg(Arg1, ArgVal1); - PolyScalarCmp++; - } - else if (IS_AGGREGATE_TYPE(TypeCode2) && IS_AGGREGATE_TYPE(TypeCode3) && !IS_AGGREGATE_TYPE(cCmdDSType(Arg1))) - { - //Compare Aggregates - Status = cCmdCompareAggregates(COMP_CODE(pCode), &CmpBool, Arg2, 0, Arg3, 0); - cCmdSetScalarValFromDataArg(Arg1, CmpBool); - recursiveCmp++; - } - else - { - //Compare Elements - Status = cCmdInterpPolyBinop(*pCode, Arg1, 0, Arg2, 0, Arg3, 0); - polyPolyCmp++; - } - } - break; - - case OP_BRCMP: - { - TYPE_CODE TypeCode2= cCmdDSType(Arg2), TypeCode3= cCmdDSType(Arg3); - if(TypeCode2 <= TC_LAST_INT_SCALAR && TypeCode3 <= TC_LAST_INT_SCALAR) { - ULONG ArgVal2, ArgVal3; - ArgVal2= cCmdGetScalarValFromDataArg(Arg2, 0); - ArgVal3= cCmdGetScalarValFromDataArg(Arg3, 0); - CmpBool= cCmdCompare(COMP_CODE(pCode), ArgVal2, ArgVal3, TypeCode2, TypeCode3); - } - else //Compare Aggregates - Status = cCmdCompareAggregates(COMP_CODE(pCode), &CmpBool, Arg2, 0, Arg3, 0); - - if (CmpBool) - gPCDelta = (SWORD)Arg1; - } - break; - - case OP_INDEX: - { - ArgVal3 = (Arg3 != NOT_A_DS_ID) ? cCmdGetScalarValFromDataArg(Arg3, 0) : 0; - - DVIndex2 = cCmdGetDVIndex(Arg2, 0); - if (ArgVal3 >= DV_ARRAY[DVIndex2].Count) - return (ERR_ARG); - - Status = cCmdInterpPolyUnop2(OP_MOV, Arg1, 0, INC_ID(Arg2), ARRAY_ELEM_OFFSET(DVIndex2, ArgVal3)); - } - break; - - case OP_ARRINIT: - { - //Arg1 - Dst, Arg2 - element type/default val, Arg3 - length - - NXT_ASSERT(cCmdDSType(Arg1) == TC_ARRAY); - - ArgVal3 = (Arg3 != NOT_A_DS_ID) ? cCmdGetScalarValFromDataArg(Arg3, 0) : 0; - - Status = cCmdDSArrayAlloc(Arg1, 0, (UWORD)ArgVal3); - if (!IS_ERR(Status)) - { - DVIndex1 = cCmdGetDVIndex(Arg1, 0); - if(cCmdDSType(Arg2) <= TC_LAST_INT_SCALAR) - { - ULONG val= cCmdGetScalarValFromDataArg(Arg2, 0); - TYPE_CODE TypeCode= cCmdDSType(INC_ID(Arg1)); - for (i = 0; i < ArgVal3; i++) // could init ptr and incr by offset GM??? - { - //copy Arg2 into each element of Arg1 - cCmdSetVal(VarsCmd.pDataspace + ARRAY_ELEM_OFFSET(DVIndex1, i), TypeCode, val); - } - } - else - for (i = 0; i < ArgVal3; i++) //copy Arg2 into each element of Arg1 - Status = cCmdInterpPolyUnop2(OP_MOV, INC_ID(Arg1), ARRAY_ELEM_OFFSET(DVIndex1, i), Arg2, 0); - } - } - break; - - default: - { - //Fatal error: Unrecognized instruction - NXT_BREAK; - Status = ERR_INSTR; - } - break; - } - } - return (Status); -} - - -NXT_STATUS cCmdInterpPolyBinop(CODE_WORD const Code, DATA_ARG Arg1, UWORD Offset1, DATA_ARG Arg2, UWORD Offset2, DATA_ARG Arg3, UWORD Offset3) -{ - NXT_STATUS Status = NO_ERR; - TYPE_CODE TypeCode1, TypeCode2, TypeCode3; - DV_INDEX DVIndex1, DVIndex2, DVIndex3; - ULONG ArgVal1, ArgVal2, ArgVal3; - float FltArgVal1, FltArgVal2, FltArgVal3; - UWORD Count1, Count2, Count3; - UWORD MinArrayCount; - UWORD i; - //!!! AdvCluster is intended to catch the case where sources are Cluster and an Array of Clusters. - // In practice, the logic it uses is broken, leading to some source cluster elements being ignored. - UBYTE AdvCluster; - - void * pArg1 = NULL, - *pArg2 = NULL, - *pArg3 = NULL; - - TypeCode1 = cCmdDSType(Arg1); - TypeCode2 = cCmdDSType(Arg2); - TypeCode3 = cCmdDSType(Arg3); - - //Simple case, both args are scalars. Solve and return. - if ((!IS_AGGREGATE_TYPE(TypeCode2)) && (!IS_AGGREGATE_TYPE(TypeCode3))) - { - NXT_ASSERT(!IS_AGGREGATE_TYPE(TypeCode1)); - - pArg1 = cCmdResolveDataArg(Arg1, Offset1, NULL); - - if (TypeCode1 == TC_FLOAT || TypeCode2 == TC_FLOAT || TypeCode3 == TC_FLOAT){ - pArg2 = cCmdResolveDataArg(Arg2, Offset2, NULL); - pArg3 = cCmdResolveDataArg(Arg3, Offset3, NULL); - FltArgVal2 = cCmdGetValFlt(pArg2, TypeCode2); - FltArgVal3 = cCmdGetValFlt(pArg3, TypeCode3); - FltArgVal1 = cCmdBinopFlt(Code, FltArgVal2, FltArgVal3, TypeCode2, TypeCode3); - cCmdSetValFlt(pArg1, TypeCode1, FltArgVal1); - } - else - { - ArgVal2 = cCmdGetScalarValFromDataArg(Arg2, Offset2); - ArgVal3 = cCmdGetScalarValFromDataArg(Arg3, Offset3); - ArgVal1 = cCmdBinop(Code, ArgVal2, ArgVal3, TypeCode2, TypeCode3); - cCmdSetVal(pArg1, TypeCode1, ArgVal1); - } - return Status; - } - - //At least one of the args is an aggregate type - - // - // Initialize Count and ArrayType local variables for each argument - // - - if (TypeCode2 == TC_ARRAY) - { - Count2 = cCmdArrayCount(Arg2, Offset2); - DVIndex2 = cCmdGetDVIndex(Arg2, Offset2); - Offset2 = DV_ARRAY[DVIndex2].Offset; - } - else if (TypeCode2 == TC_CLUSTER) - { - Count2 = cCmdClusterCount(Arg2); - } - - if (TypeCode3 == TC_ARRAY) - { - Count3 = cCmdArrayCount(Arg3, Offset3); - DVIndex3 = cCmdGetDVIndex(Arg3, Offset3); - Offset3 = DV_ARRAY[DVIndex3].Offset; - } - else if (TypeCode3 == TC_CLUSTER) - { - Count3 = cCmdClusterCount(Arg3); - } - - - if (TypeCode1 == TC_ARRAY) - { - //If the destination is an array, make sure it has enough memory to hold the result - if ((TypeCode2 == TC_ARRAY) && (TypeCode3 == TC_ARRAY)) - { - if (Count2 < Count3) - MinArrayCount = Count2; - else - MinArrayCount = Count3; - } - else if (TypeCode2 == TC_ARRAY) - MinArrayCount = Count2; - else if (TypeCode3 == TC_ARRAY) - MinArrayCount = Count3; - else - { - //If output is an array, but no sources are arrays, that's a fatal error! - NXT_BREAK; - return (ERR_ARG); - } - - //Make sure the destination array is the proper size to hold the result - Status = cCmdDSArrayAlloc(Arg1, Offset1, MinArrayCount); - if (IS_ERR(Status)) - return Status; - - Count1 = MinArrayCount; - DVIndex1 = cCmdGetDVIndex(Arg1, Offset1); - Offset1 = DV_ARRAY[DVIndex1].Offset; - AdvCluster = FALSE; - } - else if (TypeCode1 == TC_CLUSTER) - { - Count1 = cCmdClusterCount(Arg1); - AdvCluster = TRUE; - } - - //Advance aggregate args to first sub-element for next call - if (IS_AGGREGATE_TYPE(TypeCode1)) - Arg1 = INC_ID(Arg1); - if (IS_AGGREGATE_TYPE(TypeCode2)) - Arg2 = INC_ID(Arg2); - if (IS_AGGREGATE_TYPE(TypeCode3)) - Arg3 = INC_ID(Arg3); - - // - // Loop through the sub-elements of aggregate arguments. - // Call cCmdInterpPolyBinop recursively with simpler type. - // - - for (i = 0; i < Count1; i++) - { - Status = cCmdInterpPolyBinop(Code, Arg1, Offset1, Arg2, Offset2, Arg3, Offset3); - if (IS_ERR(Status)) - return Status; - - //Advance aggregate args to next sub-element - if (TypeCode1 == TC_ARRAY) - Offset1 += DV_ARRAY[DVIndex1].ElemSize; - else if ((TypeCode1 == TC_CLUSTER) && AdvCluster) - Arg1 = cCmdNextDSElement(Arg1); - - if (TypeCode2 == TC_ARRAY) - Offset2 += DV_ARRAY[DVIndex2].ElemSize; - else if ((TypeCode2 == TC_CLUSTER) && AdvCluster) - Arg2 = cCmdNextDSElement(Arg2); - - if (TypeCode3 == TC_ARRAY) - Offset3 += DV_ARRAY[DVIndex3].ElemSize; - else if ((TypeCode3 == TC_CLUSTER) && AdvCluster) - Arg3 = cCmdNextDSElement(Arg3); - } - - return Status; -} - - -ULONG cCmdBinop(CODE_WORD const Code, ULONG LeftOp, ULONG RightOp, TYPE_CODE LeftType, TYPE_CODE RightType) -{ - UBYTE opCode; - - opCode = OP_CODE((&Code)); - - switch (opCode) - { - case OP_ADD: - { - return LeftOp + RightOp; - } - - case OP_SUB: - { - return LeftOp - RightOp; - } - - case OP_MUL: - { - return LeftOp * RightOp; - } - - case OP_DIV: - { - //Catch divide-by-zero for a portable, well-defined result. - //(x / 0) = 0. Thus Spake LOTHAR!! (It's technical.) - if (RightOp == 0) - return 0; - - if (IS_SIGNED_TYPE(LeftType) && IS_SIGNED_TYPE(RightType)) - return ((SLONG)LeftOp) / ((SLONG)RightOp); - else if (IS_SIGNED_TYPE(LeftType)) - return ((SLONG)LeftOp) / RightOp; - else if (IS_SIGNED_TYPE(RightType)) - return LeftOp / ((SLONG)RightOp); - else - return LeftOp / RightOp; - } - - case OP_MOD: - { - //As with OP_DIV, make sure (x % 0) = x is well-defined - if (RightOp == 0) - return (LeftOp); - - if (IS_SIGNED_TYPE(LeftType) && IS_SIGNED_TYPE(RightType)) - return ((SLONG)LeftOp) % ((SLONG)RightOp); - else if (IS_SIGNED_TYPE(LeftType)) - return ((SLONG)LeftOp) % RightOp; - else if (IS_SIGNED_TYPE(RightType)) - return LeftOp % ((SLONG)RightOp); - else - return LeftOp % RightOp; - } - - case OP_AND: - { - return (LeftOp & RightOp); - } - - case OP_OR: - { - return (LeftOp | RightOp); - } - - case OP_XOR: - { - return ((LeftOp | RightOp) & (~(LeftOp & RightOp))); - } - - case OP_CMP: - { - return cCmdCompare(COMP_CODE((&Code)), LeftOp, RightOp, LeftType, RightType); - } - - default: - { - //Unrecognized instruction, NXT_BREAK for easy debugging (ERR_INSTR handled in caller) - NXT_BREAK; - return 0; - } - } -} - - -float cCmdBinopFlt(CODE_WORD const Code, float LeftOp, float RightOp, TYPE_CODE LeftType, TYPE_CODE RightType) -{ - UBYTE opCode; - - opCode = OP_CODE((&Code)); - - switch (opCode) - { - case OP_ADD: - { - return LeftOp + RightOp; - } - - case OP_SUB: - { - return LeftOp - RightOp; - } - - case OP_MUL: - { - return LeftOp * RightOp; - } - - case OP_DIV: - { - //Catch divide-by-zero for a portable, well-defined result. - //(x / 0) = 0. Thus Spake LOTHAR!! (It's technical.) - if (RightOp == 0) - return 0; - - return LeftOp / RightOp; - } - - case OP_MOD: - { - //As with OP_DIV, make sure (x % 0) = x is well-defined - if (RightOp == 0) - return (LeftOp); - - return (SLONG)LeftOp % (SLONG)RightOp; - } - - case OP_AND: - { - return ((SLONG)LeftOp & (SLONG)RightOp); - } - - case OP_OR: - { - return ((SLONG)LeftOp | (SLONG)RightOp); - } - - case OP_XOR: - { - return (((SLONG)LeftOp | (SLONG)RightOp) & (~((SLONG)LeftOp & (SLONG)RightOp))); - } - - case OP_CMP: - { - return cCmdCompareFlt(COMP_CODE((&Code)), LeftOp, RightOp, LeftType, RightType); - } - - default: - { - //Unrecognized instruction, NXT_BREAK for easy debugging (ERR_INSTR handled in caller) - NXT_BREAK; - return 0; - } - } -} - -NXT_STATUS cCmdInterpNoArg(CODE_WORD * const pCode) -{ - //Fatal error: Unrecognized instruction (no current opcodes have zero instructions) - NXT_BREAK; - return (ERR_INSTR); -} - -NXT_STATUS cCmdInterpShortError(CODE_WORD * const pCode) -{ - //Fatal error: Unrecognized instruction (no current opcodes have zero instructions) - NXT_BREAK; - return (ERR_INSTR); -} - -NXT_STATUS cCmdInterpShortSubCall(CODE_WORD * const pCode) -{ - NXT_STATUS Status; - DATA_ARG Arg1, Arg2; - - gPCDelta= 2; - Arg1 = GetDataArg(SHORT_ARG(pCode) + pCode[1]); - Arg2 = GetDataArg(pCode[1]); - NXT_ASSERT(cCmdIsClumpIDSane((CLUMP_ID)Arg1)); - NXT_ASSERT(!cCmdIsClumpOnQ(&(VarsCmd.RunQ), (CLUMP_ID)Arg1)); - - NXT_ASSERT(cCmdIsDSElementIDSane(Arg2)); - - *((CLUMP_ID *)(cCmdDSScalarPtr(Arg2, 0))) = VarsCmd.RunQ.Head; - - cCmdDeQClump(&(VarsCmd.RunQ), VarsCmd.RunQ.Head); //Take caller off RunQ - cCmdEnQClump(&(VarsCmd.RunQ), (CLUMP_ID)Arg1); //Add callee to RunQ - - Status = CLUMP_SUSPEND; - - return Status; -} - -ULONG moveSameInt= 0, moveDiffInt= 0, moveFloat= 0, moveArrInt= 0, moveOther= 0; -NXT_STATUS cCmdMove(DATA_ARG Arg1, DATA_ARG Arg2) -{ - NXT_STATUS Status; - DS_TOC_ENTRY *TOC1Ptr= &VarsCmd.pDataspaceTOC[Arg1], - *TOC2Ptr= &VarsCmd.pDataspaceTOC[Arg2]; - TYPE_CODE tc1= TOC1Ptr->TypeCode, tc2= TOC2Ptr->TypeCode; - void *pArg1, *pArg2; - - if(tc1 <= TC_LAST_INT_SCALAR && tc2 <= TC_LAST_INT_SCALAR) - { - // if tc1 == tc2, do long, byte, then word assignment - if(tc1 == tc2) - { - moveSameInt++; - pArg1= VarsCmd.pDataspace + TOC1Ptr->DSOffset; - pArg2= VarsCmd.pDataspace + TOC2Ptr->DSOffset; - if(tc1 >= TC_ULONG) - *(ULONG*)pArg1= *(ULONG*)pArg2; - else if(tc1 <= TC_SBYTE) - *(UBYTE*)pArg1= *(UBYTE*)pArg2; - else - *(UWORD*)pArg1= *(UWORD*)pArg2; - Status= NO_ERR; - } - else - { - moveDiffInt++; - ULONG val= cCmdGetScalarValFromDataArg(Arg2, 0); - cCmdSetScalarValFromDataArg(Arg1, val); - Status= NO_ERR; - } - } - else if(tc1 == TC_FLOAT && tc2 == TC_FLOAT) { // may also need to speed up float to int and int to float conversions - moveFloat++; - pArg1= VarsCmd.pDataspace + TOC1Ptr->DSOffset; - pArg2= VarsCmd.pDataspace + TOC2Ptr->DSOffset; - *(float*)pArg1= *(float*)pArg2; - Status= NO_ERR; - } - //!!! Optimized move for arrays of ints. - else if ((tc1 == TC_ARRAY) && (tc2 == TC_ARRAY) - && ((TOC1Ptr+1)->TypeCode <= TC_LAST_INT_SCALAR) - && ((TOC1Ptr+1)->TypeCode == (TOC2Ptr+1)->TypeCode)) - { - ULONG Count; - moveArrInt++; - Count = cCmdArrayCount(Arg2, 0); - Status = cCmdDSArrayAlloc(Arg1, 0, Count); - if (IS_ERR(Status)) - return Status; - - pArg1 = cCmdResolveDataArg(Arg1, 0, NULL); - pArg2 = cCmdResolveDataArg(Arg2, 0, NULL); - - memmove(pArg1, pArg2, Count * cCmdSizeOf((TOC1Ptr+1)->TypeCode)); - } - else { // if ((tc1 == TC_CLUSTER) && (tc2 == TC_CLUSTER)) - moveOther++; - Status = cCmdInterpPolyUnop2(OP_MOV, Arg1, 0, Arg2, 0); - } - return Status; -} - - -NXT_STATUS cCmdInterpShortMove(CODE_WORD * const pCode) -{ - NXT_STATUS Status; - DATA_ARG Arg1, Arg2; - - Arg1 = GetDataArg(SHORT_ARG(pCode) + pCode[1]); - Arg2 = GetDataArg(pCode[1]); - Status= cCmdMove(Arg1, Arg2); - - gPCDelta= 2; - return Status; -} - -NXT_STATUS cCmdInterpShortAcquire(CODE_WORD * const pCode) -{ - NXT_STATUS Status; - DATA_ARG Arg1; - - gPCDelta= 1; - Arg1 = GetDataArg(SHORT_ARG(pCode)); - NXT_ASSERT(cCmdIsDSElementIDSane(Arg1)); - NXT_ASSERT(cCmdDSType(Arg1) == TC_MUTEX); - - Status = cCmdAcquireMutex((MUTEX_Q *)cCmdDSScalarPtr(Arg1, 0)); - - return Status; -} - -NXT_STATUS cCmdInterpShortRelease(CODE_WORD * const pCode) -{ - NXT_STATUS Status; - DATA_ARG Arg1; - - gPCDelta= 1; - Arg1 = GetDataArg(SHORT_ARG(pCode)); - NXT_ASSERT(cCmdIsDSElementIDSane(Arg1)); - NXT_ASSERT(cCmdDSType(Arg1) == TC_MUTEX); - - Status = cCmdReleaseMutex((MUTEX_Q *)cCmdDSScalarPtr(Arg1, 0)); - - return Status; -} - - -//OP_SETOUT gets it's own interpreter function because it is relatively complex -// (called from cCmdInterpOther()) -//This also serves as a convenient breakpoint stop for investigating output module behavior -NXT_STATUS cCmdExecuteSetOut(CODE_WORD * const pCode) -{ - TYPE_CODE TypeCodeField, TypeCodeSrc, TypeCodePortArg; - void *pField = NULL, - *pSrc = NULL, - *pPort = NULL; - DS_ELEMENT_ID PortArg; - UWORD PortCount, InstrSize; - ULONG Port, FieldTableIndex, i, j; - DV_INDEX DVIndex; - - //Arg1 = InstrSize - //Arg2 = port number or list of ports - //Arg3 and beyond = FieldID, src DSID tuples - - //Calculate number of tuples - //!!! Might want to throw ERR_INSTR if instrSize and tuples don't check out - InstrSize = (pCode[1] / 2); - - //Second argument may specify a single port or an array list. - //Figure out which and resolve accordingly. - PortArg = pCode[2]; - TypeCodePortArg = cCmdDSType(PortArg); - - if (TypeCodePortArg == TC_ARRAY) - { - DVIndex = cCmdGetDVIndex(PortArg, 0); - PortCount = cCmdArrayCount(PortArg, 0); - } - else - PortCount = 1; - - //For each port, process all the tuples - for (i = 0; i < PortCount; i++) - { - if (TypeCodePortArg == TC_ARRAY) - { - pPort = (UBYTE*)cCmdResolveDataArg(INC_ID(PortArg), ARRAY_ELEM_OFFSET(DVIndex, i), NULL); - Port = cCmdGetVal(pPort, cCmdDSType(INC_ID(PortArg))); - } - else - { - Port = cCmdGetScalarValFromDataArg(PortArg, 0); - } - - //If user specified a valid port, process the tuples. Else, this port is a no-op - if (Port < NO_OF_OUTPUTS) - { - for (j = 3; j < InstrSize; j += 2) - { - FieldTableIndex = (Port * IO_OUT_FPP) + pCode[j]; - pSrc = cCmdResolveDataArg(pCode[j + 1], 0, &TypeCodeSrc); - - //If FieldTableIndex is valid, go ahead and set the value - if (FieldTableIndex < IO_OUT_FIELD_COUNT) - { - pField = IO_PTRS[MOD_OUTPUT][FieldTableIndex]; - TypeCodeField = IO_TYPES[MOD_OUTPUT][FieldTableIndex]; - cCmdSetVal(pField, TypeCodeField, cCmdGetVal(pSrc, TypeCodeSrc)); - } - //Else, compiler is nutso! Return fatal error. - else - return (ERR_INSTR); - } - } - } - - return (NO_ERR); -} - - -NXT_STATUS cCmdInterpOther(CODE_WORD * const pCode) -{ - NXT_STATUS Status = NO_ERR; - UBYTE opCode; - DATA_ARG Arg1, Arg2, Arg3, Arg4, Arg5; - TYPE_CODE TypeCode1, TypeCode2, TypeCode3, TypeCode5; - ULONG ArgVal2, ArgVal3, ArgVal4, ArgVal5; - UWORD ArrayCount1, ArrayCount2, ArrayCount3, ArrayCount4; - UWORD MinCount; - UWORD i,j; - DV_INDEX DVIndex1, DVIndex2, DVIndex4,TmpDVIndex; - UWORD SrcCount; - DS_ELEMENT_ID TmpDSID; - UWORD DstIndex; - UWORD Size; - UWORD Offset; - - void *pArg1 = NULL; - void *pArg2 = NULL; - void *pArg3 = NULL; - void *pArg5 = NULL; - - NXT_ASSERT(pCode != NULL); - - ULONG sz= INSTR_SIZE(*(UWORD*)pCode); - if (sz == VAR_INSTR_SIZE) - sz = ((UWORD*)pCode)[1]; - gPCDelta= sz/2; // advance words, sz is in bytes - - opCode = OP_CODE(pCode); - - switch (opCode) - { - - case OP_REPLACE: - { - //Arg1 - Dst - //Arg2 - Src - //Arg3 - Index - //Arg4 - New val / array of vals - - Arg1 = pCode[1]; - Arg2 = pCode[2]; - Arg3 = pCode[3]; - Arg4 = pCode[4]; - - NXT_ASSERT(cCmdDSType(Arg1) == TC_ARRAY); - NXT_ASSERT(cCmdDSType(Arg2) == TC_ARRAY); - - //Copy Src to Dst - //!!! Could avoid full data copy if we knew which portion to overwrite - if (Arg1 != Arg2) - { - Status= cCmdMove(Arg1, Arg2); - if (IS_ERR(Status)) - return Status; - } - - DVIndex1 = cCmdGetDVIndex(Arg1, 0); - //Copy new val to Dst - if (Arg3 != NOT_A_DS_ID) - { - pArg3 = cCmdResolveDataArg(Arg3, 0, &TypeCode3); - ArgVal3 = cCmdGetVal(pArg3, TypeCode3); - } - else - { - //Index input unwired - ArgVal3 = 0; - } - - ArrayCount1 = cCmdArrayCount(Arg1, 0); - //Bounds check - //If array index (ArgVal3) is out of range, just pass out the copy of Src (effectively no-op) - if (ArgVal3 >= ArrayCount1) - return (NO_ERR); - - if (cCmdDSType(Arg4) != TC_ARRAY) - { - Status = cCmdInterpPolyUnop2(OP_MOV, INC_ID(Arg1), ARRAY_ELEM_OFFSET(DVIndex1, ArgVal3), Arg4, 0); - if (IS_ERR(Status)) - return Status; - } - else - { - DVIndex4 = cCmdGetDVIndex(Arg4, 0); - - ArrayCount4 = cCmdArrayCount(Arg4, 0); - if (ArrayCount1 - ArgVal3 < ArrayCount4) - MinCount = (UWORD)(ArrayCount1 - ArgVal3); - else - MinCount = ArrayCount4; - - for (i = 0; i < MinCount; i++) - { - Status = cCmdInterpPolyUnop2(OP_MOV, INC_ID(Arg1), ARRAY_ELEM_OFFSET(DVIndex1, ArgVal3 + i), INC_ID(Arg4), ARRAY_ELEM_OFFSET(DVIndex4, i)); - if (IS_ERR(Status)) - return Status; - } - } - } - break; - - case OP_ARRSUBSET: - { - //Arg1 - Dst - //Arg2 - Src - //Arg3 - Index - //Arg4 - Length - - Arg1 = pCode[1]; - Arg2 = pCode[2]; - Arg3 = pCode[3]; - Arg4 = pCode[4]; - - NXT_ASSERT(cCmdDSType(Arg1) == TC_ARRAY); - NXT_ASSERT(cCmdDSType(Arg2) == TC_ARRAY); - - ArrayCount2 = cCmdArrayCount(Arg2, 0); - - if (Arg3 != NOT_A_DS_ID) - ArgVal3 = cCmdGetScalarValFromDataArg(Arg3, 0); - else //Index input unwired - ArgVal3 = 0; - - if (Arg4 != NOT_A_DS_ID) - ArgVal4 = cCmdGetScalarValFromDataArg(Arg4, 0); - else //Length input unwired, set to "rest" - ArgVal4 = (UWORD)(ArrayCount2 - ArgVal3); - - //Bounds check - if (ArgVal3 > ArrayCount2) - { - //Illegal range - return empty subset - Status = cCmdDSArrayAlloc(Arg1, 0, 0); - return Status; - } - - //Set MinCount to "rest" - MinCount = (UWORD)(ArrayCount2 - ArgVal3); - - // Copy "Length" if it is less than "rest" - if (ArgVal4 < (ULONG)MinCount) - MinCount = (UWORD)ArgVal4; - - //Allocate Dst array - Status = cCmdDSArrayAlloc(Arg1, 0, MinCount); - if (IS_ERR(Status)) - return Status; - - DVIndex1 = cCmdGetDVIndex(Arg1, 0); - DVIndex2 = cCmdGetDVIndex(Arg2, 0); - - //Move src subset to dst - for (i = 0; i < MinCount; i++) - { - Status = cCmdInterpPolyUnop2(OP_MOV, INC_ID(Arg1), ARRAY_ELEM_OFFSET(DVIndex1, i), INC_ID(Arg2), ARRAY_ELEM_OFFSET(DVIndex2, ArgVal3 + i)); - if (IS_ERR(Status)) - return Status; - } - } - break; - - case OP_STRSUBSET: - { - //Arg1 - Dst - //Arg2 - Src - //Arg3 - Index - //Arg4 - Length - - Arg1 = pCode[1]; - Arg2 = pCode[2]; - Arg3 = pCode[3]; - Arg4 = pCode[4]; - - NXT_ASSERT(cCmdDSType(Arg1) == TC_ARRAY); - NXT_ASSERT(cCmdDSType(INC_ID(Arg1)) == TC_UBYTE); - NXT_ASSERT(cCmdDSType(Arg2) == TC_ARRAY); - NXT_ASSERT(cCmdDSType(INC_ID(Arg2)) == TC_UBYTE); - - ArrayCount2 = cCmdArrayCount(Arg2, 0); - - //Remove NULL from Count - ArrayCount2--; - - if (Arg3 != NOT_A_DS_ID) - ArgVal3 = cCmdGetScalarValFromDataArg(Arg3, 0); - else //Index input unwired - ArgVal3 = 0; - - if (Arg4 != NOT_A_DS_ID) - ArgVal4 = cCmdGetScalarValFromDataArg(Arg4, 0); - else //Length input unwired, set to "rest" - ArgVal4 = (UWORD)(ArrayCount2 - ArgVal3); - - //Bounds check - if (ArgVal3 > ArrayCount2) - { - //Illegal range - return empty string - Status = cCmdDSArrayAlloc(Arg1, 0, 1); - if (!IS_ERR(Status)) - { - pArg1 = cCmdResolveDataArg(Arg1, 0, NULL); - *((UBYTE *)pArg1) = '\0'; - } - return Status; - } - - //Set MinCount to "rest" - MinCount = (UWORD)(ArrayCount2 - ArgVal3); - - // Copy "Length" if it is less than "rest" - if (ArgVal4 < (ArrayCount2 - ArgVal3)) - MinCount = (UWORD)ArgVal4; - - //Allocate Dst array - Status = cCmdDSArrayAlloc(Arg1, 0, (UWORD)(MinCount + 1)); - if (IS_ERR(Status)) - return Status; - - pArg1 = cCmdResolveDataArg(Arg1, 0, NULL); - pArg2 = cCmdResolveDataArg(Arg2, 0, NULL); - - //Move src subset to dst - memmove((UBYTE *)pArg1, (UBYTE *)pArg2 + ArgVal3, MinCount); - - //Append NULL terminator to Dst - *((UBYTE *)pArg1 + MinCount) = '\0'; - - } - break; - - case OP_SETOUT: - { - Status = cCmdExecuteSetOut(pCode); - } - break; - - case OP_ARRBUILD: - { - // Arg1 - Instruction Size in bytes - // Arg2 - Dst - // Arg3-N - Srcs - - Arg2 = pCode[2]; - - NXT_ASSERT(cCmdDSType(Arg2) == TC_ARRAY); - - //Number of Srcs = total code words - 3 (account for opcode word, size, and Dst) - //!!! Argument access like this is potentially unsafe. - //A function/macro which checks proper encoding would be better - SrcCount = (pCode[1] / 2) - 3; - - //Calculate Dst array count - ArrayCount2 = 0; - for (i = 0; i < SrcCount; i++) - { - TmpDSID = pCode[3 + i]; - NXT_ASSERT(cCmdIsDSElementIDSane(TmpDSID)); - - //If the type descriptors are the same, then the input is an array, not a single element - if (cCmdCompareDSType(Arg2, TmpDSID)) - { - NXT_ASSERT(cCmdDSType(TmpDSID) == TC_ARRAY); - ArrayCount2 += cCmdArrayCount(TmpDSID, 0); - } - else - { - //Assert that the output is an array of this input type - NXT_ASSERT(cCmdCompareDSType(INC_ID(Arg2), TmpDSID)); - ArrayCount2++; - } - } - - //Allocate Dst array - Status = cCmdDSArrayAlloc(Arg2, 0, ArrayCount2); - if (IS_ERR(Status)) - return Status; - - DVIndex2 = cCmdGetDVIndex(Arg2, 0); - - //Move Src(s) to Dst - DstIndex = 0; - for (i = 0; i < SrcCount; i++) - { - TmpDSID = pCode[3 + i]; - - //If the type descriptors are the same, then the input is an array, not a single element - if (cCmdCompareDSType(Arg2, TmpDSID)) - { - NXT_ASSERT(cCmdDSType(TmpDSID) == TC_ARRAY); - TmpDVIndex = cCmdGetDVIndex(TmpDSID, 0); - // if flat, use memmove, otherwise this stuff - if(cCmdDSType(INC_ID(TmpDSID)) <= TC_LAST_INT_SCALAR) - { - memmove(VarsCmd.pDataspace + ARRAY_ELEM_OFFSET(DVIndex2, DstIndex), VarsCmd.pDataspace + DV_ARRAY[TmpDVIndex].Offset, (UWORD)(DV_ARRAY[TmpDVIndex].ElemSize * DV_ARRAY[TmpDVIndex].Count)); - DstIndex += DV_ARRAY[TmpDVIndex].Count; - } - else - for (j = 0; j < DV_ARRAY[TmpDVIndex].Count; j++) - { - Status = cCmdInterpPolyUnop2(OP_MOV, INC_ID(Arg2), ARRAY_ELEM_OFFSET(DVIndex2, DstIndex), INC_ID(TmpDSID), ARRAY_ELEM_OFFSET(TmpDVIndex, j)); - if (IS_ERR(Status)) - return Status; - DstIndex++; - } - } - else - { - //Assert that the output is an array of this input type - NXT_ASSERT(cCmdCompareDSType(INC_ID(Arg2), TmpDSID)); - Status = cCmdInterpPolyUnop2(OP_MOV, INC_ID(Arg2), ARRAY_ELEM_OFFSET(DVIndex2, DstIndex), TmpDSID, 0); - if (IS_ERR(Status)) - return Status; - DstIndex++; - } - } - - NXT_ASSERT(DstIndex == ArrayCount2); - } - break; - - case OP_STRCAT: - { - // Arg1 - Instruction Size in bytes - // Arg2 - Dst - // Arg3-N - Srcs - - Arg2 = pCode[2]; - - //Make sure Dst arg is a string - NXT_ASSERT(cCmdDSType(Arg2) == TC_ARRAY); - NXT_ASSERT(cCmdDSType(INC_ID(Arg2)) == TC_UBYTE); - - //Number of Srcs = total code words - 3 (account for opcode word, size, and Dst) - //!!! Argument access like this is potentially unsafe. - //A function/macro which checks proper encoding would be better - SrcCount = (pCode[1] / 2) - 3; - - //Calculate Dst array count - ArrayCount2 = 0; - for (i = 0; i < SrcCount; i++) - { - TmpDSID = pCode[3 + i]; - NXT_ASSERT(cCmdIsDSElementIDSane(TmpDSID)); - - //Make sure Src arg is a string - //!!! Type checks here should be richer to allow array of strings as input (match LabVIEW behavior) - NXT_ASSERT(cCmdDSType(TmpDSID) == TC_ARRAY); - - if (cCmdDSType(INC_ID(TmpDSID)) != TC_UBYTE) - { - NXT_BREAK; - return ERR_ARG; - } - - ArrayCount3 = cCmdArrayCount(TmpDSID, 0); - NXT_ASSERT(ArrayCount3 > 0); - //Subtract NULL terminator from Src array count - ArrayCount3--; - - //Increase Dst array count by Src array count - ArrayCount2 += ArrayCount3; - } - - //Add room for NULL terminator - ArrayCount2++; - - //Allocate Dst array - Status = cCmdDSArrayAlloc(Arg2, 0, ArrayCount2); - if (IS_ERR(Status)) - return Status; - - //Move Src(s) to Dst - DstIndex = 0; - pArg2 = cCmdResolveDataArg(Arg2, 0, NULL); - for (i = 0; i < SrcCount; i++) - { - TmpDSID = pCode[3 + i]; - - pArg3 = cCmdResolveDataArg(TmpDSID, 0, NULL); - - ArrayCount3 = cCmdArrayCount(TmpDSID, 0); - NXT_ASSERT(ArrayCount3 > 0); - //Subtract NULL terminator from Src array count - ArrayCount3--; - - memmove((UBYTE *)pArg2 + DstIndex, pArg3, ArrayCount3); - DstIndex += ArrayCount3; - } - - //Append NULL terminator to Dst - *((UBYTE *)pArg2 + DstIndex) = '\0'; - DstIndex++; - - NXT_ASSERT(DstIndex == ArrayCount2); - } - break; - - case OP_UNFLATTEN: - { - //Arg1 - Dst - //Arg2 - Err (output) - //Arg3 - Src (byte stream) - //Arg4 - Type - - //The Type arg is a preallocated structure of the exact size you - //want to unflatten into. This allows us to support unflattening arbitrary types. - - //!!! Currently, both outputs must have valid destinations. - // It would be trivial to handle NOT_A_DS_ID to avoid dummy - // allocations when outputs are unused. - - Arg1 = pCode[1]; - Arg2 = pCode[2]; - Arg3 = pCode[3]; - Arg4 = pCode[4]; - - //Move Type template to Dst - //This provides a default value for Dst and makes sure Dst is properly sized - Status= cCmdMove(Arg1, Arg4); - if (IS_ERR(Status)) - return Status; - - //Resolve error data pointer - pArg2 = cCmdResolveDataArg(Arg2, 0, &TypeCode2); - - //Make sure Arg3 is a String - NXT_ASSERT(cCmdDSType(Arg3) == TC_ARRAY); - NXT_ASSERT(cCmdDSType(INC_ID(Arg3)) == TC_UBYTE); - - ArrayCount3 = cCmdArrayCount(Arg3, 0); - //Take NULL terminator out of count - ArrayCount3--; - - Size = cCmdCalcFlattenedSize(Arg4, 0); - - //Check that we have a proper type template to unflatten into - if (ArrayCount3 == Size) - { - pArg3 = cCmdResolveDataArg(Arg3, 0, NULL); - Offset = 0; - Status = cCmdUnflattenFromByteArray(pArg3, &Offset, Arg1, 0); - - //!!! Status ignored from cCmdUnflattenFromByteArray - // If future revisions of this function provide better error checking, - // Err arg should be conditionally set based on the result. - //Unflatten succeeded; set Err arg to FALSE - cCmdSetVal(pArg2, TypeCode2, FALSE); - - NXT_ASSERT(Offset == Size); - } - else - { - //Unflatten failed; set Err arg to TRUE - cCmdSetVal(pArg2, TypeCode2, TRUE); - } - } - break; - - case OP_STRINGTONUM: - { - float ArgValF; - SLONG decimals= 0; - UBYTE cont= TRUE; - // Arg1 - Dst number (output) - // Arg2 - Offset past match (output) - // Arg3 - Src string - // Arg4 - Offset - // Arg5 - Default (type/value) - - //!!! Currently, both outputs must have valid destinations. - // It would be trivial to handle NOT_A_DS_ID to avoid dummy - // allocations when outputs are unused. - - Arg1 = pCode[1]; - Arg2 = pCode[2]; - Arg3 = pCode[3]; - Arg4 = pCode[4]; - Arg5 = pCode[5]; - - pArg1 = cCmdResolveDataArg(Arg1, 0, &TypeCode1); - pArg3 = cCmdResolveDataArg(Arg3, 0, &TypeCode3); - - if (Arg4 != NOT_A_DS_ID) - ArgVal4 = cCmdGetScalarValFromDataArg(Arg4, 0); - else //Offset input unwired - ArgVal4 = 0; - - if (Arg5 != NOT_A_DS_ID) - { - pArg5 = cCmdResolveDataArg(Arg5, 0, &TypeCode5); - ArgVal5 = cCmdGetVal(pArg5, TypeCode5); - } - else //Default input unwired - { - ArgVal5 = 0; - } - - //Read number from string - if (sscanf(((PSZ)pArg3 + ArgVal4), "%f", &ArgValF) == 1) - { - i = (UWORD)ArgVal4; - //Scan until we see the number, consumes negative sign too - while ((((UBYTE *)pArg3)[i] < '0') || (((UBYTE *)pArg3)[i] > '9')) - i++; - - //Scan until we get past the number and no more than one decimal - while (cont) { - if ((((UBYTE *)pArg3)[i] >= '0') && (((UBYTE *)pArg3)[i] <= '9')) - i++; - else if(((UBYTE *)pArg3)[i] == '.' && !decimals) { - i++; - decimals++; - } - else - cont= FALSE; - } - ArgVal2 = i; - } - else - { - //Number wasn't found in string, use defaults - ArgValF = ArgVal5; - ArgVal2 = 0; - } - - //Set outputs - cCmdSetValFlt(pArg1, TypeCode1, ArgValF); - cCmdSetScalarValFromDataArg(Arg2, ArgVal2); - } - break; - - default: - { - //Fatal error: Unrecognized instruction - NXT_BREAK; - Status = ERR_INSTR; - } - break; - } - - return (Status); -} - - -// -//Support functions for lowspeed (I2C devices, i.e. ultrasonic sensor) communications -// - -//Simple lookup table for pMapLowSpeed->ChannelState[Port] values -//This is used to keep VM status code handling consistent -//...and ChannelState gives us too much information, anyway... -static const NXT_STATUS MapLStoVMStat[6] = -{ - NO_ERR, //LOWSPEED_IDLE, - STAT_COMM_PENDING, //LOWSPEED_INIT, - STAT_COMM_PENDING, //LOWSPEED_LOAD_BUFFER, - STAT_COMM_PENDING, //LOWSPEED_COMMUNICATING, - ERR_COMM_BUS_ERR, //LOWSPEED_ERROR, - STAT_COMM_PENDING, //LOWSPEED_DONE (really means c_lowspeed state machine is resetting) -}; - - -//cCmdLSCheckStatus -//Check lowspeed port status, optionally returning bytes available in the buffer for reading -NXT_STATUS cCmdLSCheckStatus(UBYTE Port) -{ - if (Port >= NO_OF_LOWSPEED_COM_CHANNEL) - { - return (ERR_COMM_CHAN_INVALID); - } - - INPUTSTRUCT * pInput = &(pMapInput->Inputs[Port]); - - //If port is not configured properly ahead of time, report that error - //!!! This seems like the right policy, but may restrict otherwise valid read operations... - if (!(pInput->SensorType == LOWSPEED_9V || pInput->SensorType == LOWSPEED) - || !(pInput->InvalidData == FALSE)) - { - return (ERR_COMM_CHAN_NOT_READY); - } - - return (MapLStoVMStat[pMapLowSpeed->ChannelState[Port]]); -} - -//cCmdLSCalcBytesReady -//Calculate true number of bytes available in the inbound LS buffer -UBYTE cCmdLSCalcBytesReady(UBYTE Port) -{ - SLONG Tmp; - - //Expect callers to validate Port, but short circuit here to be safe. - if (Port >= NO_OF_LOWSPEED_COM_CHANNEL) - return 0; - - LSBUF * pInBuf = &(pMapLowSpeed->InBuf[Port]); - - //Normally, bytes available is a simple difference. - Tmp = pInBuf->InPtr - pInBuf->OutPtr; - - //If InPtr is actually behind OutPtr, circular buffer has wrapped. Account for wrappage... - if (Tmp < 0) - Tmp = (pInBuf->InPtr + (SIZE_OF_LSBUF - pInBuf->OutPtr)); - - return (UBYTE)(Tmp); -} - -//cCmdLSWrite -//Write BufLength bytes into specified port's lowspeed buffer and kick off comm process to device -NXT_STATUS cCmdLSWrite(UBYTE Port, UBYTE BufLength, UBYTE *pBuf, UBYTE ResponseLength) -{ - if (Port >= NO_OF_LOWSPEED_COM_CHANNEL) - { - return (ERR_COMM_CHAN_INVALID); - } - - if (BufLength > SIZE_OF_LSBUF || ResponseLength > SIZE_OF_LSBUF) - { - return (ERR_INVALID_SIZE); - } - - INPUTSTRUCT * pInput = &(pMapInput->Inputs[Port]); - UBYTE * pChState = &(pMapLowSpeed->ChannelState[Port]); - LSBUF * pOutBuf = &(pMapLowSpeed->OutBuf[Port]); - - //Only start writing process if port is properly configured and c_lowspeed module is ready - if ((pInput->SensorType == LOWSPEED_9V || pInput->SensorType == LOWSPEED) - && (pInput->InvalidData == FALSE) - && (*pChState == LOWSPEED_IDLE) || (*pChState == LOWSPEED_ERROR)) - { - pOutBuf->InPtr = 0; - pOutBuf->OutPtr = 0; - - memcpy(pOutBuf->Buf, pBuf, BufLength); - pOutBuf->InPtr = (UBYTE)BufLength; - - pMapLowSpeed->InBuf[Port].BytesToRx = ResponseLength; - - *pChState = LOWSPEED_INIT; - pMapLowSpeed->State |= (COM_CHANNEL_ONE_ACTIVE << Port); - - return (NO_ERR); - } - else - { - //!!! Would be more consistent to return STAT_COMM_PENDING if c_lowspeed is busy - return (ERR_COMM_CHAN_NOT_READY); - } -} - - -//cCmdLSRead -//Read BufLength bytes from specified port's lowspeed buffer -NXT_STATUS cCmdLSRead(UBYTE Port, UBYTE BufLength, UBYTE * pBuf) -{ - UBYTE BytesReady, BytesToRead; - - if (Port >= NO_OF_LOWSPEED_COM_CHANNEL) - { - return (ERR_COMM_CHAN_INVALID); - } - - if (BufLength > SIZE_OF_LSBUF) - { - return (ERR_INVALID_SIZE); - } - - BytesReady = cCmdLSCalcBytesReady(Port); - - if (BufLength > BytesReady) - { - return (ERR_COMM_CHAN_NOT_READY); - } - - BytesToRead = BufLength; - - LSBUF * pInBuf = &(pMapLowSpeed->InBuf[Port]); - - //If the bytes we want to read wrap around the end, we must first read the end, then reset back to the beginning - if (pInBuf->OutPtr + BytesToRead >= SIZE_OF_LSBUF) - { - BytesToRead = SIZE_OF_LSBUF - pInBuf->OutPtr; - memcpy(pBuf, pInBuf->Buf + pInBuf->OutPtr, BytesToRead); - pInBuf->OutPtr = 0; - pBuf += BytesToRead; - BytesToRead = BufLength - BytesToRead; - } - - memcpy(pBuf, pInBuf->Buf + pInBuf->OutPtr, BytesToRead); - pInBuf->OutPtr += BytesToRead; - - return (NO_ERR); -} - - -// -//Wrappers for OP_SYSCALL -// - -// -//cCmdWrapFileOpenRead -//ArgV[0]: (Function return) Loader status, U16 return -//ArgV[1]: File Handle, U8 return -//ArgV[2]: Filename, CStr -//ArgV[3]: Length, U32 return -NXT_STATUS cCmdWrapFileOpenRead(UBYTE * ArgV[]) -{ - LOADER_STATUS LStatus; - DV_INDEX DVIndex; - - //Resolve array argument - DVIndex = *(DV_INDEX *)(ArgV[2]); - ArgV[2] = cCmdDVPtr(DVIndex); - - LStatus = pMapLoader->pFunc(OPENREAD, ArgV[2], NULL, (ULONG *)ArgV[3]); - - //Add entry into FileHandleTable - if (LOADER_ERR(LStatus) == SUCCESS) - { - VarsCmd.FileHandleTable[LOADER_HANDLE(LStatus)][0] = 'r'; - strcpy((PSZ)(VarsCmd.FileHandleTable[LOADER_HANDLE(LStatus)] + 1), (PSZ)(ArgV[2])); - } - - //Status code in high byte of LStatus - *((UWORD *)ArgV[0]) = LOADER_ERR(LStatus); - //File handle in low byte of LStatus - *(ArgV[1]) = LOADER_HANDLE(LStatus); - - return NO_ERR; -} - -//cCmdWrapFileOpenWrite -//ArgV[0]: (Function return) Loader status, U16 return -//ArgV[1]: File Handle, U8 return -//ArgV[2]: Filename, CStr -//ArgV[3]: Length, U32 return -NXT_STATUS cCmdWrapFileOpenWrite(UBYTE * ArgV[]) -{ - LOADER_STATUS LStatus; - DV_INDEX DVIndex; - - //Resolve array argument - DVIndex = *(DV_INDEX *)(ArgV[2]); - ArgV[2] = cCmdDVPtr(DVIndex); - - LStatus = pMapLoader->pFunc(OPENWRITEDATA, ArgV[2], NULL, (ULONG *)ArgV[3]); - - //Add entry into FileHandleTable - if (LOADER_ERR(LStatus) == SUCCESS) - { - VarsCmd.FileHandleTable[LOADER_HANDLE(LStatus)][0] = 'w'; - strcpy((PSZ)(VarsCmd.FileHandleTable[LOADER_HANDLE(LStatus)] + 1), (PSZ)(ArgV[2])); - } - - //Status code in high byte of LStatus - *((UWORD *)ArgV[0]) = LOADER_ERR(LStatus); - //File handle in low byte of LStatus - *(ArgV[1]) = LOADER_HANDLE(LStatus); - - return NO_ERR; -} - -//cCmdWrapFileOpenAppend -//ArgV[0]: (Function return) Loader status, U16 return -//ArgV[1]: File Handle, U8 return -//ArgV[2]: Filename, CStr -//ArgV[3]: Length Remaining, U32 return -NXT_STATUS cCmdWrapFileOpenAppend(UBYTE * ArgV[]) -{ - LOADER_STATUS LStatus; - DV_INDEX DVIndex; - - //Resolve array argument - DVIndex = *(DV_INDEX *)(ArgV[2]); - ArgV[2] = cCmdDVPtr(DVIndex); - - LStatus = pMapLoader->pFunc(OPENAPPENDDATA, ArgV[2], NULL, (ULONG *)ArgV[3]); - - //Add entry into FileHandleTable - if (LOADER_ERR(LStatus) == SUCCESS) - { - VarsCmd.FileHandleTable[LOADER_HANDLE(LStatus)][0] = 'w'; - strcpy((PSZ)(VarsCmd.FileHandleTable[LOADER_HANDLE(LStatus)] + 1), (PSZ)(ArgV[2])); - } - - //Status code in high byte of LStatus - *((UWORD *)ArgV[0]) = LOADER_ERR(LStatus); - //File handle in low byte of LStatus - *(ArgV[1]) = LOADER_HANDLE(LStatus); - - return NO_ERR; -} - -//cCmdWrapFileRead -//ArgV[0]: (Function return) Loader status, U16 return -//ArgV[1]: File Handle, U8 in/out -//ArgV[2]: Buffer, CStr out -//ArgV[3]: Length, U32 in/out -NXT_STATUS cCmdWrapFileRead(UBYTE * ArgV[]) -{ - NXT_STATUS Status = NO_ERR; - LOADER_STATUS LStatus; - DV_INDEX DVIndex; - - //Resolve array argument - DVIndex = *(DV_INDEX *)(ArgV[2]); - //Size Buffer to Length - //Add room for null terminator to length - Status = cCmdDVArrayAlloc(DVIndex, (UWORD)(*(ULONG *)ArgV[3] + 1)); - if (IS_ERR(Status)) - return Status; - - ArgV[2] = cCmdDVPtr(DVIndex); - LStatus = pMapLoader->pFunc(READ, ArgV[1], ArgV[2], (ULONG *)ArgV[3]); - - //Tack on NULL terminator - //Note that loader code may have adjusted length (*ArgV[3]) if all requested data was not available - //!!! Better solution would be to resize buffer to new length + 1, - // but then you must also be wary of side effects if resize allocation fails! - *(ArgV[2] + *(ULONG *)ArgV[3]) = '\0'; - - //Status code in high byte of LStatus - *((UWORD *)ArgV[0]) = LOADER_ERR(LStatus); - //File handle in low byte of LStatus - *(ArgV[1]) = LOADER_HANDLE(LStatus); - - return Status; -} - -//cCmdWrapFileWrite -//ArgV[0]: (Function return) Loader status, U16 return -//ArgV[1]: File Handle, U8 in/out -//ArgV[2]: Buffer, CStr -//ArgV[3]: Length, U32 return -NXT_STATUS cCmdWrapFileWrite(UBYTE * ArgV[]) -{ - LOADER_STATUS LStatus; - DV_INDEX DVIndex; - - //Resolve array argument - DVIndex = *(DV_INDEX *)(ArgV[2]); - ArgV[2] = cCmdDVPtr(DVIndex); - - LStatus = pMapLoader->pFunc(WRITE, ArgV[1], ArgV[2], (ULONG *)ArgV[3]); - - //Status code in high byte of LStatus - *((UWORD *)ArgV[0]) = LOADER_ERR(LStatus); - //File handle in low byte of LStatus - *(ArgV[1]) = LOADER_HANDLE(LStatus); - - return NO_ERR; -} - -//cCmdWrapFileClose -//ArgV[0]: (Function return) Loader status, U16 return -//ArgV[1]: File Handle, U8 -NXT_STATUS cCmdWrapFileClose(UBYTE * ArgV[]) -{ - LOADER_STATUS LStatus; - - //!!! This bounds check also exists in dLoaderCloseHandle(), but we provide an explicit error code - if (*(ArgV[1]) >= MAX_HANDLES) - { - *((UWORD *)ArgV[0]) = ILLEGALHANDLE; - return NO_ERR; - } - - LStatus = pMapLoader->pFunc(CLOSE, ArgV[1], NULL, NULL); - - //Clear entry in FileHandleTable - memset(VarsCmd.FileHandleTable[*(ArgV[1])], 0, FILENAME_LENGTH + 2); - - //Status code in high byte of LStatus - *((UWORD *)ArgV[0]) = LOADER_ERR(LStatus); - - return NO_ERR; -} - -//cCmdWrapFileResolveHandle -//ArgV[0]: (Function return) Loader status, U16 return -//ArgV[1]: File Handle, U8 return -//ArgV[2]: Write Handle?, Bool return -//ArgV[3]: Filename, CStr -NXT_STATUS cCmdWrapFileResolveHandle (UBYTE * ArgV[]) -{ - UBYTE i; - DV_INDEX DVIndex; - - //Resolve array argument - DVIndex = *(DV_INDEX *)(ArgV[3]); - ArgV[3] = cCmdDVPtr(DVIndex); - - for (i = 0; i < MAX_HANDLES; i++) - { - if (strcmp((PSZ)(ArgV[3]), (PSZ)(VarsCmd.FileHandleTable[i] + 1)) == 0) - { - *(ArgV[2]) = (VarsCmd.FileHandleTable[i][0] == 'w'); - break; - } - } - - if (i == MAX_HANDLES) - { - i = NOT_A_HANDLE; - *((UWORD *)ArgV[0]) = HANDLEALREADYCLOSED; - } - else - { - *((UWORD *)ArgV[0]) = SUCCESS; - } - - *(ArgV[1]) = i; - - return NO_ERR; -} - - -//cCmdWrapFileRename -//ArgV[0]: (Function return) Loader status, U16 return -//ArgV[1]: Old Filename, CStr -//ArgV[2]: New Filename, CStr -NXT_STATUS cCmdWrapFileRename (UBYTE * ArgV[]) -{ - LOADER_STATUS LStatus; - ULONG Tmp; - DV_INDEX DVIndex; - - //Resolve array arguments - DVIndex = *(DV_INDEX *)(ArgV[1]); - ArgV[1] = cCmdDVPtr(DVIndex); - DVIndex = *(DV_INDEX *)(ArgV[2]); - ArgV[2] = cCmdDVPtr(DVIndex); - - //!!! Tmp placeholder passed into loader code to avoid illegal dereferencing. - LStatus = pMapLoader->pFunc(RENAMEFILE, ArgV[1], ArgV[2], &Tmp); - - //Status code in high byte of LStatus - *((UWORD *)ArgV[0]) = LOADER_ERR(LStatus); - - return NO_ERR; -} - - -//cCmdWrapFileDelete -//ArgV[0]: (Function return) Loader status, U16 return -//ArgV[1]: Filename, CStr -NXT_STATUS cCmdWrapFileDelete (UBYTE * ArgV[]) -{ - LOADER_STATUS LStatus; - DV_INDEX DVIndex; - - //Resolve array arguments - DVIndex = *(DV_INDEX *)(ArgV[1]); - ArgV[1] = cCmdDVPtr(DVIndex); - - LStatus = pMapLoader->pFunc(DELETE, ArgV[1], NULL, NULL); - - //Status code in high byte of LStatus - *((UWORD *)ArgV[0]) = LOADER_ERR(LStatus); - - return NO_ERR; -} - -// -//cCmdWrapSoundPlayFile -//ArgV[0]: (Return value) Status code, SBYTE -//ArgV[1]: Filename, CStr -//ArgV[2]: Loop?, UBYTE (bool) -//ArgV[3]: Volume, UBYTE -// -NXT_STATUS cCmdWrapSoundPlayFile(UBYTE * ArgV[]) -{ - DV_INDEX DVIndex; - - //Resolve array arguments - DVIndex = *(DV_INDEX *)(ArgV[1]); - UBYTE sndVol= *(ArgV[3]); - ArgV[1] = cCmdDVPtr(DVIndex); - - //!!! Should check filename and/or existence and return error before proceeding - strncpy((PSZ)(pMapSound->SoundFilename), (PSZ)(ArgV[1]), FILENAME_LENGTH); - - if (*(ArgV[2]) == TRUE) - pMapSound->Mode = SOUND_LOOP; - else - pMapSound->Mode = SOUND_ONCE; - - if(sndVol > 4) - sndVol= 4; - pMapSound->Volume = sndVol; - //SampleRate of '0' means "let file specify SampleRate" - pMapSound->SampleRate = 0; - pMapSound->Flags |= SOUND_UPDATE; - - *((SBYTE*)(ArgV[0])) = (NO_ERR); - - return (NO_ERR); -} - -// -//cCmdWrapSoundPlayTone -//ArgV[0]: (Return value) Status code, SBYTE -//ArgV[1]: Frequency, UWORD -//ArgV[2]: Duration, UWORD -//ArgV[3]: Loop?, UBYTE (Boolean) -//ArgV[4]: Volume, UBYTE -// -NXT_STATUS cCmdWrapSoundPlayTone(UBYTE * ArgV[]) -{ - UBYTE sndVol= *(ArgV[4]); - pMapSound->Freq = *(UWORD*)(ArgV[1]); - pMapSound->Duration = *(UWORD*)(ArgV[2]); - if(sndVol > 4) - sndVol= 4; - pMapSound->Volume = sndVol; - pMapSound->Flags |= SOUND_UPDATE; - - if (*(ArgV[3]) == TRUE) - pMapSound->Mode = SOUND_TONE | SOUND_LOOP; - else - pMapSound->Mode = SOUND_TONE; - - *((SBYTE*)(ArgV[0])) = (NO_ERR); - - return (NO_ERR); -} - -// -//cCmdWrapSoundGetState -//ArgV[0]: (Return value) sound module state, UBYTE -//ArgV[1]: Flags, UBYTE -// -NXT_STATUS cCmdWrapSoundGetState(UBYTE * ArgV[]) -{ - *(ArgV[0]) = pMapSound->State; - *(ArgV[1]) = pMapSound->Flags; - return (NO_ERR); -} - -// -//cCmdWrapSoundSetState -//ArgV[0]: (Return value) sound module state, UBYTE -//ArgV[1]: State, UBYTE -//ArgV[2]: Flags, UBYTE -// -NXT_STATUS cCmdWrapSoundSetState(UBYTE * ArgV[]) -{ - pMapSound->State = *(ArgV[1]); - //Return same state we just set, mostly for interface consistency - *(ArgV[0]) = pMapSound->State; - - //OR in provided flags (usually 0) - pMapSound->Flags |= *(ArgV[2]); - - return (NO_ERR); -} - -// -//cCmdWrapReadButton -//ArgV[0]: (Function return) Status code, SBYTE -//ArgV[1]: Index (U8) -//ArgV[2]: Pressed (bool) -//ArgV[3]: Count (U8) (count of press-then-release cycles) -//ArgV[4]: ResetCount? (bool in) -// -NXT_STATUS cCmdWrapReadButton(UBYTE * ArgV[]) -{ - UBYTE btnIndex; - - btnIndex = *((UBYTE*)(ArgV[1])); - - if (btnIndex < NO_OF_BTNS) - { - //Set pressed boolean output - if (pMapButton->State[btnIndex] & PRESSED_STATE) - *(ArgV[2]) = TRUE; - else - *(ArgV[2]) = FALSE; - - //Set count output - *(ArgV[3]) = (UBYTE)(pMapButton->BtnCnt[btnIndex].RelCnt); - - //Optionally reset internal count - if (*(ArgV[4]) != 0) - { - pMapButton->BtnCnt[btnIndex].RelCnt = 0; - //Need to clear short and long counts too, because RelCnt depends on them. No known side effects. - pMapButton->BtnCnt[btnIndex].ShortRelCnt = 0; - pMapButton->BtnCnt[btnIndex].LongRelCnt = 0; - } - - // Set status code 'OK' - *((SBYTE*)(ArgV[0])) = NO_ERR; - } - else - { - //Bad button index specified, return error and default outputs - *((SBYTE*)(ArgV[0])) = ERR_INVALID_PORT; - *(ArgV[2]) = FALSE; - *(ArgV[3]) = 0; - } - - return (NO_ERR); -} - -// -//cCmdWrapCommLSWrite -//ArgV[0]: (return) Status code, SBYTE -//ArgV[1]: Port specifier, UBYTE -//ArgV[2]: Buffer to send, UBYTE array, only SIZE_OF_LSBUF bytes will be used -//ArgV[3]: ResponseLength, UBYTE, specifies expected bytes back from slave device -// -NXT_STATUS cCmdWrapCommLSWrite(UBYTE * ArgV[]) -{ - SBYTE * pReturnVal = (SBYTE*)(ArgV[0]); - UBYTE Port = *(ArgV[1]); - UBYTE * pBuf; - UWORD BufLength; - UBYTE ResponseLength = *(ArgV[3]); - DV_INDEX DVIndex; - - //Resolve array arguments - DVIndex = *(DV_INDEX *)(ArgV[2]); - pBuf = cCmdDVPtr(DVIndex); - BufLength = DV_ARRAY[DVIndex].Count; - - *pReturnVal = cCmdLSWrite(Port, (UBYTE)BufLength, pBuf, ResponseLength); - - return (NO_ERR); -} - -// -//cCmdWrapCommLSCheckStatus -//ArgV[0]: (return) Status code, SBYTE -//ArgV[1]: Port specifier, UBYTE -//ArgV[2]: BytesReady, UBYTE -// -NXT_STATUS cCmdWrapCommLSCheckStatus(UBYTE * ArgV[]) -{ - UBYTE Port = *(ArgV[1]); - - *((SBYTE*)(ArgV[0])) = cCmdLSCheckStatus(Port); - *((UBYTE*)(ArgV[2])) = cCmdLSCalcBytesReady(Port); - - return (NO_ERR); -} - -// -//cCmdWrapCommLSRead -//ArgV[0]: (return) Status code, SBYTE -//ArgV[1]: Port specifier, UBYTE -//ArgV[2]: Buffer for data, UBYTE array, max SIZE_OF_LSBUF bytes will be written -//ArgV[3]: BufferLength, UBYTE, specifies size of buffer requested -// -NXT_STATUS cCmdWrapCommLSRead(UBYTE * ArgV[]) -{ - SBYTE * pReturnVal = (SBYTE*)(ArgV[0]); - UBYTE Port = *(ArgV[1]); - UBYTE * pBuf; - UBYTE BufLength = *(ArgV[3]); - UBYTE BytesToRead; - DV_INDEX DVIndex = *(DV_INDEX *)(ArgV[2]); - NXT_STATUS AllocStatus; - - *pReturnVal = cCmdLSCheckStatus(Port); - BytesToRead = cCmdLSCalcBytesReady(Port); - - //If channel is OK and has data ready for us, put the data into outgoing buffer - if (!IS_ERR(*pReturnVal) && BytesToRead > 0) - { - //Limit buffer to available data - if (BufLength > BytesToRead) - BufLength = BytesToRead; - - AllocStatus = cCmdDVArrayAlloc(DVIndex, BufLength); - if (IS_ERR(AllocStatus)) - return (AllocStatus); - - pBuf = cCmdDVPtr(DVIndex); - *pReturnVal = cCmdLSRead(Port, BufLength, pBuf); - } - //Else, the channel has an error and/or there's no data to read; clear the output array - else - { - AllocStatus = cCmdDVArrayAlloc(DVIndex, 0); - if (IS_ERR(AllocStatus)) - return (AllocStatus); - } - - return (NO_ERR); -} - -// -//cCmdWrapRandomNumber -//ArgV[0]: (return) Random number, SWORD -// -NXT_STATUS cCmdWrapRandomNumber(UBYTE * ArgV[]) -{ - static UBYTE count = 0; - SWORD random; - - if (count == 0) - srand(dTimerRead()); - - if (count > 20) - count = 0; - else - count++; - - //!!! IAR's implementation of the rand() library function returns signed values, and we want it that way. - //Some stdlib implementations may return only positive numbers, so be wary if this code is ported. - random = rand(); - - *((SWORD *)ArgV[0]) = random; - - return NO_ERR; -} - -// -//cCmdWrapGetStartTick -//ArgV[0]: (return) Start Tick, ULONG -// -NXT_STATUS cCmdWrapGetStartTick(UBYTE * ArgV[]) -{ - *((ULONG *)ArgV[0]) = VarsCmd.StartTick; - return NO_ERR; -} - -// -//cCmdWrapMessageWrite -//ArgV[0]: (return) Error Code, SBYTE (NXT_STATUS) -//ArgV[1]: QueueID, UBYTE -//ArgV[2]: Message, CStr -// -NXT_STATUS cCmdWrapMessageWrite(UBYTE * ArgV[]) -{ - NXT_STATUS Status = NO_ERR; - DV_INDEX DVIndex; - - //Resolve array arguments - DVIndex = *(DV_INDEX *)(ArgV[2]); - ArgV[2] = cCmdDVPtr(DVIndex); - - Status = cCmdMessageWrite(*(UBYTE *)(ArgV[1]), ArgV[2], DV_ARRAY[DVIndex].Count); - - *(SBYTE *)(ArgV[0]) = Status; - - if (IS_FATAL(Status)) - return Status; - else - return (NO_ERR); -} - - - -// -//cCmdWrapColorSensorRead -//ArgV[0]: (return) Error code, SBYTE -//ArgV[1]: Port, UBYTE -//ArgV[2]: SensorValue, SWORD -//ArgV[3]: RawArray, UWORD[NO_OF_COLORS] -//ArgV[4]: NormalizedArray, UWORD[NO_OF_COLORS] -//ArgV[5]: ScaledArray, SWORD[NO_OF_COLORS] -//ArgV[6]: InvalidData, UBYTE -// -NXT_STATUS cCmdWrapColorSensorRead (UBYTE * ArgV[]) -{ - DV_INDEX DVIndex; - NXT_STATUS Status = NO_ERR; - //Resolve return val arguments - SBYTE * pReturnVal = (SBYTE*)(ArgV[0]); - //Resolve Port argument - UBYTE Port = *(UBYTE*)(ArgV[1]); - //Resolve SensorValue - SWORD SensorValue = *(SWORD*)(ArgV[2]); - //Resolve RawArray as array - DVIndex = *(DV_INDEX*)(ArgV[3]); - NXT_ASSERT(IS_DV_INDEX_SANE(DestDVIndex)); - Status= cCmdDVArrayAlloc(DVIndex, NO_OF_COLORS); - if (IS_ERR(Status)) - return (Status); - ArgV[3] = cCmdDVPtr (DVIndex); - //Resolve NormalizedArray as array - DVIndex = *(DV_INDEX*)(ArgV[4]); - NXT_ASSERT(IS_DV_INDEX_SANE(DestDVIndex)); - Status= cCmdDVArrayAlloc(DVIndex, NO_OF_COLORS); - if (IS_ERR(Status)) - return (Status); - ArgV[4] = cCmdDVPtr (DVIndex); - //Resolve ScaledArray as array - DVIndex = *(DV_INDEX*)(ArgV[5]); - NXT_ASSERT(IS_DV_INDEX_SANE(DestDVIndex)); - Status= cCmdDVArrayAlloc(DVIndex, NO_OF_COLORS); - if (IS_ERR(Status)) - return (Status); - ArgV[5] = cCmdDVPtr (DVIndex); - //Resolve InvalidData - UBYTE InvalidData = *(UBYTE*)(ArgV[6]); - - //call implementation with unwrapped parameters - *pReturnVal = cCmdColorSensorRead (Port, &SensorValue, (UWORD*)ArgV[3], (UWORD*)ArgV[4], (SWORD*)ArgV[5], &InvalidData); - - *(ArgV[2]) = SensorValue; - *(ArgV[6]) = InvalidData; - - if (IS_ERR(*pReturnVal)){ - return (*pReturnVal); - } - return NO_ERR; -} - - -#define UNPACK_STATUS(StatusWord) ((SBYTE)(StatusWord)) - -NXT_STATUS cCmdBTCheckStatus(UBYTE Connection) -{ - //If specified connection is invalid, return error code to the user. - if (Connection >= SIZE_OF_BT_CONNECT_TABLE) - { - return (ERR_INVALID_PORT); - } - - //INPROGRESS means a request is currently pending completion by the comm module - if (VarsCmd.CommStat == INPROGRESS) - { - return (STAT_COMM_PENDING); - } - //Translate BTBUSY to ERR_COMM_CHAN_NOT_READY - //And check if specified connection is indeed configured - else if (VarsCmd.CommStat == (SWORD)BTBUSY - || (pMapComm->BtConnectTable[Connection].Name[0]) == '\0') - { - return (ERR_COMM_CHAN_NOT_READY); - } - else - { - return (UNPACK_STATUS(VarsCmd.CommStat)); - } -} - -//Default packet to send for a remote MESSAGE_READ command. -//3rd byte must be replaced with remote mailbox (QueueID) -//4th byte must be replaced with local mailbox -static UBYTE RemoteMsgReadPacket[5] = {0x00, 0x13, 0xFF, 0xFF, 0x01}; - -// -//cCmdWrapMessageRead -//ArgV[0]: (return) Error Code, SBYTE (NXT_STATUS) -//ArgV[1]: QueueID, UBYTE -//ArgV[2]: Remove, UBYTE -//ArgV[3]: (return) Message, CStr -// -NXT_STATUS cCmdWrapMessageRead(UBYTE * ArgV[]) -{ - NXT_STATUS Status = NO_ERR; - NXT_STATUS AllocStatus = NO_ERR; - UBYTE QueueID = *(UBYTE *)(ArgV[1]); - DV_INDEX DestDVIndex = *(DV_INDEX *)(ArgV[3]); - UWORD MessageSize; - UBYTE i; - - NXT_ASSERT(IS_DV_INDEX_SANE(DestDVIndex)); - - //Check Next Message's size - Status = cCmdMessageGetSize(QueueID, &MessageSize); - - //If there is a valid message in local mailbox, read it - if (!IS_ERR(Status) && MessageSize > 0 ) - { - //!!! Also check for EMPTY_MAILBOX status? - //Size destination string - AllocStatus = cCmdDVArrayAlloc(DestDVIndex, MessageSize); - if (IS_ERR(AllocStatus)) - return AllocStatus; - - //Get Message - //!!! Should more aggressively enforce null termination before blindly copying to dataspace - Status = cCmdMessageRead(QueueID, cCmdDVPtr(DestDVIndex), MessageSize, *(ArgV[2])); - } - else - { - //Clear destination string - AllocStatus = cCmdDVArrayAlloc(DestDVIndex, 1); - if (IS_ERR(AllocStatus)) - return AllocStatus; - - //Successful allocation, make sure first byte is null terminator - *(UBYTE*)(cCmdDVPtr(DestDVIndex)) = '\0'; - } - - //If there were no local messages, see if there are any waiting in our slaves' outboxes - if (Status == STAT_MSG_EMPTY_MAILBOX && QueueID < INCOMING_QUEUE_COUNT) - { - //If there's an old error code hanging around, clear it before proceeding. - //!!! Clearing error here means bytecode status checking loops could get false SUCCESS results? - if (VarsCmd.CommStat < 0) - VarsCmd.CommStat = SUCCESS; - - //Search through possible slaves, looking for valid connection - for (i = 0; i < SIZE_OF_BT_CONNECT_TABLE - 1; i++) - { - //Advance CommCurrConnection and limit to 1, 2, or 3 (only slave connection slots are checked) - VarsCmd.CommCurrConnection++; - if (VarsCmd.CommCurrConnection == SIZE_OF_BT_CONNECT_TABLE) - VarsCmd.CommCurrConnection = 1; - - if (cCmdBTCheckStatus(VarsCmd.CommCurrConnection) == NO_ERR) - break; - } - - //If there is at least one configured slave connection, make a remote read request - if (i < SIZE_OF_BT_CONNECT_TABLE - 1) - { - //Outgoing QueueID on slave device is the local QueueID + INCOMING_QUEUE_COUNT - RemoteMsgReadPacket[2] = QueueID + INCOMING_QUEUE_COUNT; - RemoteMsgReadPacket[3] = QueueID; - - //Request comm module to send assembled packet and not go idle until response comes back (or error) - pMapComm->pFunc(SENDDATA, sizeof(RemoteMsgReadPacket), VarsCmd.CommCurrConnection, TRUE, RemoteMsgReadPacket, (UWORD*)&(VarsCmd.CommStat)); - - //Read status back after SENDDATA call so bytecode gets STAT_COMM_PENDING or error - Status = cCmdBTCheckStatus(VarsCmd.CommCurrConnection); - - //If our request was accepted, set the DirtyComm flag so stream will get cleaned up later - if (Status == STAT_COMM_PENDING) - VarsCmd.DirtyComm = TRUE; - } - } - - *(SBYTE *)(ArgV[0]) = Status; - if (IS_FATAL(Status)) - return Status; - else - return (NO_ERR); -} - - -// -//cCmdWrapCommBTCheckStatus -//ArgV[0]: (return) Status byte, SBYTE -//ArgV[1]: Connection index, 0-3 -// -NXT_STATUS cCmdWrapCommBTCheckStatus(UBYTE * ArgV[]) -{ - *((SBYTE*)(ArgV[0])) = cCmdBTCheckStatus(*(ArgV[1])); - - return (NO_ERR); -} - -// -//cCmdWrapCommBTWrite -//ArgV[0]: (return) Status byte, SBYTE -//ArgV[1]: Connection index, 0-3 -//ArgV[2]: Buffer -// -NXT_STATUS cCmdWrapCommBTWrite(UBYTE * ArgV[]) -{ - SBYTE * pReturnVal = (SBYTE*)(ArgV[0]); - UBYTE Connection = *(ArgV[1]); - UBYTE * pBuf; - UWORD BufLength; - DV_INDEX DVIndex; - - //Resolve array arguments - DVIndex = *(DV_INDEX *)(ArgV[2]); - pBuf = cCmdDVPtr(DVIndex); - - BufLength = DV_ARRAY[DVIndex].Count; - - //If there's an old error code hanging around, clear it before proceeding. - if (VarsCmd.CommStat < 0) - VarsCmd.CommStat = SUCCESS; - - //!!! Only first 256 bytes could possibly make it through! Should return error on longer input? - //!!! Not requesting a wait-for-response because only known use doesn't read responses. - pMapComm->pFunc(SENDDATA, (UBYTE)BufLength, Connection, FALSE, pBuf, (UWORD*)&(VarsCmd.CommStat)); - - //!!! Reasonable to wrap below code in cCmdCommBTCheckStatus? - //INPROGRESS means our request was accepted by His Funkiness of pFunc - if (VarsCmd.CommStat == (SWORD)INPROGRESS) - { - *pReturnVal = STAT_COMM_PENDING; - - //Set DirtyComm flag so stream is reset after program ends - VarsCmd.DirtyComm = TRUE; - } - //Translate BTBUSY to ERR_COMM_CHAN_NOT_READY - else if (VarsCmd.CommStat == (SWORD)BTBUSY) - { - *pReturnVal = ERR_COMM_CHAN_NOT_READY; - } - else - { - *pReturnVal = UNPACK_STATUS(VarsCmd.CommStat); - } - - return (NO_ERR); -} - -// -//cCmdWrapCommBTRead -//ArgV[0]: (return) Status byte, SBYTE -//ArgV[1]: Count to read -//ArgV[2]: Buffer -// -NXT_STATUS cCmdWrapCommBTRead(UBYTE * ArgV[]) -{ - //SBYTE * pReturnVal = (SBYTE*)(ArgV[0]); - //UBYTE * pBuf = (ArgV[2]); - //!!! should provide length and/or connection to read? - - //!!! This syscall is not implemented; return fatal error. - return (ERR_INSTR); -} - -// -//cCmdWrapKeepAlive -//ArgV[0]: (return) Current timer limit in ms, ULONG -// -NXT_STATUS cCmdWrapKeepAlive(UBYTE * ArgV[]) -{ - pMapUi->Flags |= UI_RESET_SLEEP_TIMER; - - //Convert UI's minute-based timeout value to millisecs - //Milliseconds are the "natural" time unit in user-land. - *(ULONG*)(ArgV[0]) = (pMapUi->SleepTimeout * 60 * 1000); - - return (NO_ERR); -} - - - -#define MAX_IOM_BUFFER_SIZE 64 -// -//cCmdWrapIOMapRead -//ArgV[0]: (return) Status byte, SBYTE -//ArgV[1]: Module name, CStr -//ArgV[2]: Offset, UWORD -//ArgV[3]: Count, UWORD -//ArgV[4]: Buffer, UBYTE array -// -NXT_STATUS cCmdWrapIOMapRead(UBYTE * ArgV[]) -{ - UWORD LStatus; - NXT_STATUS Status; - - SBYTE * pReturnVal = (SBYTE*)(ArgV[0]); - UWORD Offset = *(UWORD*)(ArgV[2]); - //Our copy of 'Count' must be a ULONG to match the loader interface - ULONG Count = *(UWORD*)(ArgV[3]); - - DV_INDEX DVIndex; - - //Buffer for return of FINDFIRSTMODULE call, structure defined in protocol doc - //We need it to transfer the ModuleID to the IOMAPREAD call - UBYTE FindBuffer[FILENAME_LENGTH + 10]; - //Buffer to store data and offset in for IOMAPREAD call - //!!! Constant size means only limited reads and writes - UBYTE DataBuffer[MAX_IOM_BUFFER_SIZE + 2]; - - if (Count > MAX_IOM_BUFFER_SIZE) - { - //Request to read too much data at once; clear buffer, return error. - DVIndex = *(DV_INDEX *)(ArgV[4]); - *pReturnVal = cCmdDVArrayAlloc(DVIndex, 0); - if (IS_ERR(*pReturnVal)) - return (*pReturnVal); - - *pReturnVal = ERR_INVALID_SIZE; - return (NO_ERR); - } - - //Resolve module name - DVIndex = *(DV_INDEX *)(ArgV[1]); - ArgV[1] = cCmdDVPtr(DVIndex); - - //Find module by name. Note that wildcards are accepted, but only first match matters. - LStatus = pMapLoader->pFunc(FINDFIRSTMODULE, ArgV[1], FindBuffer, NULL); - - if (LOADER_ERR(LStatus) == SUCCESS) - { - //Module was found, transfer Offset into first two bytes of DataBuffer and attempt to read - *(UWORD*)(DataBuffer) = Offset; - LStatus = pMapLoader->pFunc(IOMAPREAD, &(FindBuffer[FILENAME_LENGTH + 1]), DataBuffer, &Count); - - if (LOADER_ERR(LStatus) == SUCCESS) - { - //No error from IOMAPREAD, so copy the data into VM's dataspace - //Size destination array - DVIndex = *(DV_INDEX *)(ArgV[4]); - Status = cCmdDVArrayAlloc(DVIndex, (UWORD)Count); - if (IS_ERR(Status)) - { - //Alloc failed, so close handle and return - pMapLoader->pFunc(CLOSEMODHANDLE, NULL, NULL, NULL); - return (Status); - } - - //Alloc succeeded, so resolve and copy away - ArgV[4] = cCmdDVPtr(DVIndex); - memcpy(ArgV[4], &(DataBuffer[2]), Count); - } - } - - *pReturnVal = LOADER_ERR_BYTE(LStatus); - - pMapLoader->pFunc(CLOSEMODHANDLE, NULL, NULL, NULL); - return (NO_ERR); -} - -// -//cCmdWrapIOMapWrite -//ArgV[0]: (return) Status byte, SBYTE -//ArgV[1]: Module name, CStr -//ArgV[2]: Offset, UWORD -//ArgV[3]: Buffer, UBYTE array -// -NXT_STATUS cCmdWrapIOMapWrite(UBYTE * ArgV[]) -{ - UWORD LStatus; - - SBYTE * pReturnVal = (SBYTE*)(ArgV[0]); - UWORD Offset = *(UWORD*)(ArgV[2]); - - //Our copy of 'Count' must be a ULONG to match the loader interface - ULONG Count; - DV_INDEX DVIndex; - - //Buffer for return of FINDFIRSTMODULE call, structure defined in protocol doc - //We need it to transfer the ModuleID to the IOMAPREAD call - UBYTE FindBuffer[FILENAME_LENGTH + 10]; - //Buffer to store data and offset in for IOMAPREAD call - //!!! Constant size means only limited reads and writes - UBYTE DataBuffer[MAX_IOM_BUFFER_SIZE + 2]; - - //Resolve module name and buffer - DVIndex = *(DV_INDEX *)(ArgV[1]); - ArgV[1] = cCmdDVPtr(DVIndex); - - DVIndex = *(DV_INDEX *)(ArgV[3]); - ArgV[3] = cCmdDVPtr(DVIndex); - Count = DV_ARRAY[DVIndex].Count; - - if (Count > MAX_IOM_BUFFER_SIZE) - { - //Request to read too much data at once; return error and give up - *pReturnVal = ERR_INVALID_SIZE; - return (NO_ERR); - } - - LStatus = pMapLoader->pFunc(FINDFIRSTMODULE, ArgV[1], FindBuffer, NULL); - - if (LOADER_ERR(LStatus) == SUCCESS) - { - //Module was found, transfer Offset into first two bytes of DataBuffer, copy data into rest of buffer, then write - *(UWORD*)(DataBuffer) = Offset; - memcpy(&(DataBuffer[2]), ArgV[3], Count); - LStatus = pMapLoader->pFunc(IOMAPWRITE, &(FindBuffer[FILENAME_LENGTH + 1]), DataBuffer, &Count); - } - - *pReturnVal = LOADER_ERR_BYTE(LStatus); - - pMapLoader->pFunc(CLOSEMODHANDLE, NULL, NULL, NULL); - return (NO_ERR); -} - -#if VM_BENCHMARK -void cCmdWriteBenchmarkFile() -{ - LOADER_STATUS LStatus; - UBYTE Handle; - ULONG BenchFileSize; - ULONG i, Length; - UBYTE Buffer[256]; - - //Remove old benchmark file, create a new one - strcpy((char *)Buffer, "benchmark.txt"); - pMapLoader->pFunc(DELETE, Buffer, NULL, NULL); - BenchFileSize = 2048; - LStatus = pMapLoader->pFunc(OPENWRITEDATA, Buffer, NULL, &BenchFileSize); - - if (!LOADER_ERR(LStatus)) - { - //Write Benchmark file - Handle = LOADER_HANDLE(LStatus); - - //Header - sprintf((char *)Buffer, "Program Name: %s\r\n", VarsCmd.ActiveProgName); - Length = strlen((char *)Buffer); - LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length); - - sprintf((char *)Buffer, "InstrCount: %d\r\n", VarsCmd.InstrCount); - Length = strlen((char *)Buffer); - LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length); - - sprintf((char *)Buffer, "Time: %d\r\n", IOMapCmd.Tick - VarsCmd.StartTick); - Length = strlen((char *)Buffer); - LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length); - - sprintf((char *)Buffer, "Instr/Tick: %d\r\n", VarsCmd.Average); - Length = strlen((char *)Buffer); - LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length); - - sprintf((char *)Buffer, "CmdCtrl Calls: %d\r\n", VarsCmd.CmdCtrlCount); - Length = strlen((char *)Buffer); - LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length); - - sprintf((char *)Buffer, "OverTime Rounds: %d\r\n", VarsCmd.OverTimeCount); - Length = strlen((char *)Buffer); - LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length); - - sprintf((char *)Buffer, "Max OverTime Length: %d\r\n", VarsCmd.MaxOverTimeLength); - Length = strlen((char *)Buffer); - LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length); - - sprintf((char *)Buffer, "CompactionCount: %d\r\n", VarsCmd.CompactionCount); - Length = strlen((char *)Buffer); - LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length); - - sprintf((char *)Buffer, "LastCompactionTick: %d\r\n", VarsCmd.LastCompactionTick); - Length = strlen((char *)Buffer); - LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length); - - sprintf((char *)Buffer, "MaxCompactionTime: %d\r\n", VarsCmd.MaxCompactionTime); - Length = strlen((char *)Buffer); - LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length); - - //opcode benchmarks - sprintf((char *)Buffer, "Op\tCnt\tOver\tMax\r\n"); - Length = strlen((char *)Buffer); - LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length); - for (i = 0; i < OPCODE_COUNT; i++) - { - sprintf((char *)Buffer, "%x\t%d\t%d\t%d\t%d\r\n", i, VarsCmd.OpcodeBenchmarks[i][0], VarsCmd.OpcodeBenchmarks[i][1], VarsCmd.OpcodeBenchmarks[i][2], VarsCmd.OpcodeBenchmarks[i][3]); - Length = strlen((char *)Buffer); - LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length); - } - //close file - LStatus = pMapLoader->pFunc(CLOSE, &Handle, NULL, NULL); - } -} -#endif - - -///////////////////////////////////////////////////////////// -// Dymanic syscall implementations -//////////////////////////////////////////////////////////// - -// -//cCmdWrapDatalogWrite -//ArgV[0]: (return) Error Code, SBYTE (NXT_STATUS) -//ArgV[1]: Message, CStr -// -NXT_STATUS cCmdWrapDatalogWrite(UBYTE * ArgV[]) -{ - NXT_STATUS Status = NO_ERR; - DV_INDEX DVIndex; - - //Resolve array arguments - DVIndex = *(DV_INDEX *)(ArgV[1]); - ArgV[1] = cCmdDVPtr(DVIndex); - - Status = cCmdDatalogWrite(ArgV[1], DV_ARRAY[DVIndex].Count); - - *(SBYTE *)(ArgV[0]) = Status; - - if (IS_FATAL(Status)) - return Status; - else - return (NO_ERR); -} - -// -//cCmdWrapDatalogGetTimes -//ArgV[0]: SyncTime, U32 -//ArgV[1]: SyncTick, U32 -// -NXT_STATUS cCmdWrapDatalogGetTimes(UBYTE * ArgV[]) -{ - *((ULONG *)ArgV[1]) = IOMapCmd.SyncTime; - *((ULONG *)ArgV[2]) = IOMapCmd.SyncTick; - return (NO_ERR); -} - -// -//cCmdWrapSetSleepTimeout -//ArgV[0]: (return) Status byte, SBYTE -//ArgV[1]: desired timer limit in ms, ULONG -// -NXT_STATUS cCmdWrapSetSleepTimeout(UBYTE * ArgV[]) -{ - ULONG value = *(ULONG*)(ArgV[1]); - if(value==0) - { - pMapUi->SleepTimeout=0; - } - else if(value < 60000) - { - pMapUi->SleepTimeout=1; //integer math would've made this zero - } - else - { - pMapUi->SleepTimeout= value / 60000; - } - return (NO_ERR); -} - -// currently copied from LS, not finished. -// -//cCmdWrapCommHSWrite -//ArgV[0]: (return) Status code, SBYTE -//ArgV[1]: Port specifier, UBYTE -//ArgV[2]: Buffer to send, UBYTE array, only SIZE_OF_LSBUF bytes will be used -//ArgV[3]: ResponseLength, UBYTE, specifies expected bytes back from slave device -// -NXT_STATUS cCmdWrapCommHSWrite(UBYTE * ArgV[]) -{ - SBYTE * pReturnVal = (SBYTE*)(ArgV[0]); - UBYTE Port = *(ArgV[1]); - UBYTE * pBuf; - UWORD BufLength; - UBYTE ResponseLength = *(ArgV[3]); - DV_INDEX DVIndex; - - //Resolve array arguments - DVIndex = *(DV_INDEX *)(ArgV[2]); - pBuf = cCmdDVPtr(DVIndex); - BufLength = DV_ARRAY[DVIndex].Count; - - *pReturnVal = cCmdLSWrite(Port, (UBYTE)BufLength, pBuf, ResponseLength); - - return (NO_ERR); -} - -// -//cCmdWrapCommHSCheckStatus -//ArgV[0]: (return) Status code, SBYTE -//ArgV[1]: Port specifier, UBYTE -//ArgV[2]: BytesReady, UBYTE -// -NXT_STATUS cCmdWrapCommHSCheckStatus(UBYTE * ArgV[]) -{ - UBYTE Port = *(ArgV[1]); - - *((SBYTE*)(ArgV[0])) = cCmdLSCheckStatus(Port); - *((UBYTE*)(ArgV[2])) = cCmdLSCalcBytesReady(Port); - - return (NO_ERR); -} - -// -//cCmdWrapCommHSRead -//ArgV[0]: (return) Status code, SBYTE -//ArgV[1]: Port specifier, UBYTE -//ArgV[2]: Buffer for data, UBYTE array, max SIZE_OF_LSBUF bytes will be written -//ArgV[3]: BufferLength, UBYTE, specifies size of buffer requested -// -NXT_STATUS cCmdWrapCommHSRead(UBYTE * ArgV[]) -{ - SBYTE * pReturnVal = (SBYTE*)(ArgV[0]); - UBYTE Port = *(ArgV[1]); - UBYTE * pBuf; - UBYTE BufLength = *(ArgV[3]); - UBYTE BytesToRead; - DV_INDEX DVIndex = *(DV_INDEX *)(ArgV[2]); - NXT_STATUS AllocStatus; - - *pReturnVal = cCmdLSCheckStatus(Port); - BytesToRead = cCmdLSCalcBytesReady(Port); - - //If channel is OK and has data ready for us, put the data into outgoing buffer - if (!IS_ERR(*pReturnVal) && BytesToRead > 0) - { - //Limit buffer to available data - if (BufLength > BytesToRead) - BufLength = BytesToRead; - - AllocStatus = cCmdDVArrayAlloc(DVIndex, BufLength); - if (IS_ERR(AllocStatus)) - return (AllocStatus); - - pBuf = cCmdDVPtr(DVIndex); - *pReturnVal = cCmdLSRead(Port, BufLength, pBuf); - } - //Else, the channel has an error and/or there's no data to read; clear the output array - else - { - AllocStatus = cCmdDVArrayAlloc(DVIndex, 0); - if (IS_ERR(AllocStatus)) - return (AllocStatus); - } - - return (NO_ERR); -} - -// -//cCmdWrapCommBTOnOff -//ArgV[0]: (return) Status byte, SBYTE -//ArgV[1]: Power State, 0-1 -// -NXT_STATUS cCmdWrapCommBTOnOff(UBYTE * ArgV[]) -{ - UWORD retVal; - NXT_STATUS status; - SBYTE * pReturnVal = (SBYTE*)(ArgV[0]); - - UBYTE powerState = *(ArgV[1]); - if(powerState) - status= pMapComm->pFunc(BTON, 0, 0, 0, NULL, &retVal); - else - status= pMapComm->pFunc(BTOFF, 0, 0, 0, NULL, &retVal); - - *pReturnVal= (status == SUCCESS) ? retVal : status; - return (NO_ERR); -} - -// -//cCmdWrapCommBTConnection -//ArgV[0]: (return) Status byte, SBYTE -//ArgV[1]: Action, UBYTE -//ArgV[2]: name, UBYTE array CStr -//ArgV[3]: connection slot, UBYTE -// -NXT_STATUS cCmdWrapCommBTConnection(UBYTE * ArgV[]) -{ - UWORD retVal; - NXT_STATUS status; - SBYTE * pReturnVal = (SBYTE*)(ArgV[0]); - UBYTE *nmPtr; - - UBYTE action = *(ArgV[1]); - UBYTE connection = *(ArgV[3]); - nmPtr = cCmdDVPtr(*(DV_INDEX *)(ArgV[2])); - - if(action) // Init - status= pMapComm->pFunc(CONNECTBYNAME, 0, connection, 0, nmPtr, &retVal); - else // Close - status= pMapComm->pFunc(DISCONNECT, connection, 0, 0, NULL, &retVal); - - *pReturnVal= (status == SUCCESS) ? retVal : status; - return (NO_ERR); -} - - -// -//cCmdWrapReadSemData -//ArgV[0]: return data, U8 -//ArgV[1]: which (0=used, 1=request), U8 -// -NXT_STATUS cCmdWrapReadSemData(UBYTE * ArgV[]) -{ - if(!(*((UBYTE *)ArgV[1]))) - *((UBYTE *)ArgV[0])= gUsageSemData; - else - *((UBYTE *)ArgV[0])= gRequestSemData; - return (NO_ERR); -} - -// -//cCmdWrapWriteSemData -//ArgV[0]: return data, U8 -//ArgV[1]: which (0=used, 1=request), U8 -//ArgV[2]: newValue, U8 -//ArgV[3]: action (0= OR, 1= AND), U8 -// -NXT_STATUS cCmdWrapWriteSemData(UBYTE * ArgV[]) -{ - UBYTE curVal, newVal, which= (*((UBYTE *)ArgV[1])); - if(!which) - curVal= gUsageSemData; - else - curVal= gRequestSemData; - - newVal= *((UBYTE *)ArgV[2]); - - if(*((UBYTE *)ArgV[3])) - curVal &= ~newVal; - else - curVal |= newVal; - - if(!which) - gUsageSemData= curVal; - else - gRequestSemData= curVal; - *((UBYTE *)ArgV[0])= curVal; - return (NO_ERR); -} - - -// -//cCmdWrapUpdateCalibCacheInfo -//ArgV[0]: return data, U8 -//ArgV[1]: nm, UBYTE array CStr -//ArgV[2]: min, U16 -//ArgV[3]: max , U16 -// -NXT_STATUS cCmdWrapUpdateCalibCacheInfo(UBYTE * ArgV[]) -{ - UBYTE *nm= cCmdDVPtr(*(DV_INDEX *)(ArgV[1])); - SWORD min= (*((SWORD *)ArgV[2])); - SWORD max= (*((SWORD *)ArgV[3])); - - cCmdUpdateCalibrationCache(nm, min, max); - *((UBYTE *)ArgV[0])= SUCCESS; - return (NO_ERR); -} - -// -//cCmdWrapComputeCalibValue -//ArgV[0]: return data, U8 -//ArgV[1]: nm, UBYTE array CStr -//ArgV[2]: raw, U16 ref in out -NXT_STATUS cCmdWrapComputeCalibValue (UBYTE * ArgV[]) -{ - UBYTE *nm= cCmdDVPtr(*(DV_INDEX *)(ArgV[1])); - SWORD raw= (*((SWORD *)ArgV[2])); - - *((UBYTE *)ArgV[0])= cCmdComputeCalibratedValue(nm, &raw); - (*((SWORD *)ArgV[2]))= raw; - return (NO_ERR); -} - -typedef struct { - SWORD min, max; - UBYTE nm[FILENAME_LENGTH + 1]; -} CalibCacheType; - -SBYTE gCalibCacheCnt= 0; -DV_INDEX gCalibCacheArrayDVIdx= NOT_A_DS_ID; -CalibCacheType *gCalibCacheArray= NULL; - -SWORD cCmdGetCalibrationIndex(UBYTE *nm) { - SBYTE i; - for(i= 0; i < gCalibCacheCnt; i++) - if(!strcmp((PSZ)nm, (PSZ)gCalibCacheArray[i].nm)) - break; - return i; -} - -NXT_STATUS cCmdComputeCalibratedValue(UBYTE *nm, SWORD *pRaw) { - SBYTE i= cCmdGetCalibrationIndex(nm); - NXT_STATUS status= ERR_RC_ILLEGAL_VAL; - SLONG raw= *pRaw, range; - if(i < gCalibCacheCnt) { - status= SUCCESS; - raw -= gCalibCacheArray[i].min; - range= (gCalibCacheArray[i].max - gCalibCacheArray[i].min); - } - else - range= 1023; - raw *= 100; - raw /= range; - if(raw < 0) raw= 0; - else if(raw > 100) raw= 100; - *pRaw= raw; - return status; -} - - -NXT_STATUS ResizeCalibCache(ULONG elements) { // alloc dv if needed, grow if needed. dv never freed. on boot, set to NOT_A_DS_ID. use cnt for valid elements. - NXT_STATUS Status = NO_ERR; - - if(gCalibCacheArrayDVIdx == NOT_A_DS_ID) - Status = cCmdAllocDopeVector(&gCalibCacheArrayDVIdx, sizeof(CalibCacheType)); - if(!IS_ERR(Status) && DV_ARRAY[gCalibCacheArrayDVIdx].Count < elements) //Allocate storage for cache element - Status = cCmdDVArrayAlloc(gCalibCacheArrayDVIdx, elements); - if(!IS_ERR(Status)) - gCalibCacheArray= cCmdDVPtr(gCalibCacheArrayDVIdx); - // on error, does old DVIdx still point to array, or should we null out array??? - return Status; -} - -// called to update min/max on existing cache element, and to add new named element -void cCmdUpdateCalibrationCache(UBYTE *nm, SWORD min, SWORD max) { - SWORD i= cCmdGetCalibrationIndex(nm); - NXT_STATUS Status = NO_ERR; - - if(i == gCalibCacheCnt) { // sensor wasn't found, insert into cache - Status= ResizeCalibCache(gCalibCacheCnt+1); - if(!IS_ERR(Status)) { - gCalibCacheCnt++; - strcpy((PSZ)gCalibCacheArray[i].nm, (PSZ)nm); - } - } - if(!IS_ERR(Status)) { - gCalibCacheArray[i].min= min; - gCalibCacheArray[i].max= max; - } -} - -void cCmdLoadCalibrationFiles(void) { - ULONG cnt, DataSize; - UBYTE nm[FILENAME_LENGTH + 1], nmLen; - SWORD Handle, HandleSearch; - gCalibCacheCnt= 0; - gCalibCacheArrayDVIdx= NOT_A_DS_ID; - // file I/O to load all .cal files into cached globals used by scaling syscall - HandleSearch = pMapLoader->pFunc(FINDFIRST, "*.cal", nm, &cnt); // returns total files and nm of first one - while (LOADER_ERR(HandleSearch) == SUCCESS) { // if we have a file, process it by closing and opening - SWORD min= 0, max= 0, tmp; - ULONG length; - pMapLoader->pFunc(CLOSE, LOADER_HANDLE_P(HandleSearch), NULL, NULL); - Handle = pMapLoader->pFunc(OPENREAD, nm, NULL, &DataSize); - if (LOADER_ERR(Handle) == SUCCESS && DataSize == 4) { - // access data, two bytes for min and two for max - length= 2; - pMapLoader->pFunc(READ,LOADER_HANDLE_P(Handle),(UBYTE*)&tmp,&length); - if (length == 2) - min= tmp; - length= 2; - pMapLoader->pFunc(READ,LOADER_HANDLE_P(Handle),(UBYTE*)&tmp,&length); - if (length == 2) - max= tmp; - } - pMapLoader->pFunc(CLOSE, LOADER_HANDLE_P(Handle), NULL, NULL); - // update calibration cache with nm, min, and max - nmLen= strlen((PSZ)nm) - 4; // chop off .cal extension - nm[nmLen]= 0; - cCmdUpdateCalibrationCache(nm, min, max); - - HandleSearch = pMapLoader->pFunc(FINDNEXT, LOADER_HANDLE_P(HandleSearch), nm, &cnt); - } - pMapLoader->pFunc(CLOSE, LOADER_HANDLE_P(HandleSearch), NULL, NULL); -} - -// -//cCmdWrapListFiles -//ArgV[0]: return data, SBYTE -//ArgV[1]: pattern, UBYTE array CStr -//ArgV[2]: list, UBYTE array CStr array ref in out -NXT_STATUS cCmdWrapListFiles (UBYTE * ArgV[]) -{ - ULONG fileSize, matchCount=0, i=0, oldCount; - SWORD HandleSearch; - NXT_STATUS Status = NO_ERR; - DV_INDEX listIdx, *list; - UBYTE *strTemp, *pattern; - UBYTE name[FILENAME_LENGTH + 1]; - - //Resolve array arguments - pattern = cCmdDVPtr(*(DV_INDEX *)(ArgV[1])); - listIdx = *(DV_INDEX *)(ArgV[2]); - - HandleSearch = pMapLoader->pFunc(FINDFIRST, pattern, name, &fileSize); // returns first file matching pattern - - //Count how many files we're going to have - while (LOADER_ERR(HandleSearch) == SUCCESS) - { - matchCount++; - pMapLoader->pFunc(CLOSE, LOADER_HANDLE_P(HandleSearch), NULL, NULL); - HandleSearch = pMapLoader->pFunc(FINDNEXT, LOADER_HANDLE_P(HandleSearch), name, &fileSize); - } - - HandleSearch = pMapLoader->pFunc(FINDFIRST, pattern, name, &fileSize); // returns first file matching pattern - - oldCount = DV_ARRAY[listIdx].Count; // Check to see how many dope vectors are already in the array (if they passed us a non-blank array of strings) - - Status = cCmdDVArrayAlloc(listIdx, matchCount); // Size the top-level array - if(IS_ERR(Status)) - return Status; - - list = (DV_INDEX*)(VarsCmd.pDataspace + DV_ARRAY[listIdx].Offset); // Get a pointer into the dataspace for the array of DV_INDEXes - - while (LOADER_ERR(HandleSearch) == SUCCESS && !IS_ERR(Status)) - { - pMapLoader->pFunc(CLOSE, LOADER_HANDLE_P(HandleSearch), NULL, NULL); // Close the handle that we automatically opened above - // Allocate a new dope vector if one doesn't already exist - if(i >= oldCount) - Status = cCmdAllocDopeVector(&(list[i]), sizeof(char)); - - // Allocate the string buffer for output array[i] - if(!IS_ERR(Status)) - Status = cCmdDVArrayAlloc(list[i], strlen((PSZ)name) + 1); - - if(!IS_ERR(Status)) - { - strTemp = VarsCmd.pDataspace + DV_ARRAY[list[i]].Offset; // Get a pointer into the dataspace for this string - strcpy((PSZ)strTemp, (PSZ)name); - } - i++; - - HandleSearch = pMapLoader->pFunc(FINDNEXT, LOADER_HANDLE_P(HandleSearch), name, &fileSize); - } - - *(SBYTE *)(ArgV[0]) = Status; - - return Status; -} - -#ifdef SIM_NXT -// Accessors for simulator library code -SWORD cCmdGetCodeWord(CLUMP_ID Clump, CODE_INDEX Index) -{ - if (Clump == NOT_A_CLUMP) - { - NXT_ASSERT(Index < VarsCmd.CodespaceCount); - return (VarsCmd.pCodespace[Index]); - } - else - { - NXT_ASSERT(cCmdIsClumpIDSane(Clump)); -#error // CodeStart is now absolute, but not sure how to fix - return (((SWORD)VarsCmd.pCodespace[VarsCmd.pAllClumps[Clump].CodeStart + Index])); - } -} - - -UBYTE * cCmdGetDataspace(UWORD *DataspaceSize) -{ - if (DataspaceSize) - *DataspaceSize = VarsCmd.DataspaceSize; - return (VarsCmd.pDataspace); -} - - -DOPE_VECTOR * cCmdGetDopeVectorPtr() -{ - return VarsCmd.MemMgr.pDopeVectorArray; -} - - -MEM_MGR cCmdGetMemMgr(void) -{ - return VarsCmd.MemMgr; -} - - -ULONG cCmdGetPoolSize() -{ - return VarsCmd.PoolSize; -} -#endif - -#else //!ENABLE_VM -// -//Implementations of standard interface if VM is disabled. -//Place low-level test code here if VM is causing issues. -//Test code must implement cCmdInit(), cCmdCtrl(), and cCmdExit() at a minimum. -//Recommend using a pattern like #include "c_cmd_alternate.c" -// - -//!!! !ENABLE_VM implementations really should provide a placeholder function for this pointer -//IOMapCmd.pRCHandler = &cCmdHandleRemoteCommands; -#include "c_cmd_alternate.c" - -#endif //ENABLE_VM diff --git a/AT91SAM7S256/Source/c_cmd.h b/AT91SAM7S256/Source/c_cmd.h deleted file mode 100644 index c6e5267..0000000 --- a/AT91SAM7S256/Source/c_cmd.h +++ /dev/null @@ -1,885 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date: 10-07-08 13:22 $ -// -// Filename $Workfile:: c_cmd.h $ -// -// Version $Revision: 8 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_cmd. $ -// -// Platform C -// - -// -// File Description: -// This file contains definitions and prototypes for the VM which runs bytecode -// programs compatible with LEGO MINDSTORMS NXT Software 1.0. -// - -#ifndef C_CMD -#define C_CMD - -//!!! MAX_HANDLES also defined in m_sched.h -#ifndef MAX_HANDLES -#define MAX_HANDLES 16 -#endif - -#include "c_cmd_bytecodes.h" -#define SYSCALL_COUNT 48 - -extern const HEADER cCmd; - -// -//Standard interface to other modules -// -void cCmdInit(void* pHeader); -void cCmdCtrl(void); -void cCmdExit(void); - -// -//ARM_NXT vs SIM_NXT -//These definitions are set up to allow compiling this code for use in a simulated (non-ARM7) environment. -//If your toolchain doesn't automatically use the __ICCARM__ or __arm__ token, define it to ensure normal compilation. -// -#if defined (__ICCARM__) || (defined (__GNUC__) && defined (__arm__)) -#define ARM_NXT -#else -#define SIM_NXT -#endif - -// -//ENABLE_VM toggles compilation the main body of VM code. -//Define it as 0 to compile alternate implementation for testing (see bottom of c_cmd.c) -// -#define ENABLE_VM 1 -#undef ARM_DEBUG -// -//VM_BENCHMARK enables extra instrumentation code to measure VM performance. -//When enabled, a file named "benchmark.txt" is produced every time a program completes. -// -#define VM_BENCHMARK (ENABLE_VM && 0) //<-- Toggle to turn on benchmark calculations - -#if VM_BENCHMARK -//Prototype for benchmark recording function -void cCmdWriteBenchmarkFile(); -#endif - -// -//Run-time assert macros -//Use these to test for unexpected conditions -//If expr evaluates as false while running under a debugger, -// a software breakpoint exception is thrown. -//NXT_BREAK is just a shortcut for unconditional break. -// -//Assert definitions behind WIN_DEBUG only make sense when compiling SIM_NXT -// under an x86 Windows debugger. -// -#if defined WIN_DEBUG -//"int 3" is a break exception on x86 -#define NXT_ASSERT(expr) if (expr) {} else { __asm {int 3} } -#define NXT_BREAK NXT_ASSERT(0) -// -//Assert definitions behind ARM_DEBUG aren't quite as handy as WIN_DEBUG, -// but they do record the code line causing the last assert failure. -// -#elif defined(ARM_DEBUG) -#define NXT_ASSERT(expr) if (expr) {}\ - else\ - {\ - VarsCmd.AssertFlag = TRUE;\ - VarsCmd.AssertLine = __LINE__;\ - } -#define NXT_BREAK NXT_ASSERT(0); -#else -//Not debugging, so #defined as nothing -//!!! Note that these definitions means all usages of NXT_ASSERT and NXT_BREAK -// get stripped out of an unmodified ARM7 build. -//Unless ARM_DEBUG is enabled, treat them as documentation of expected values. -#define NXT_ASSERT(expr) -#define NXT_BREAK -#endif - -// -//Status byte used to return requests for further action or errors -//Valid codes #defined in c_cmd.iom -//!!!JLOFTUS Replace with NXT_STATUS? Same for ASSERTS? Others? Risk factors? -// -typedef SBYTE NXT_STATUS; - -#if ENABLE_VM - -//Intial values for clump records are packed into 4 bytes in the file format. -#define VM_FILE_CLUMP_REC_SIZE 4 - -// -// Definitions for dataspace management, IO Map (IOM) access, and bytecode instruction structure -// - -//Type codes for use in the dataspace table-of-contents (DSTOC) -typedef UBYTE TYPE_CODE; - -enum -{ - //VOID type for unused DS elements; never valid to address them from bytecode - TC_VOID, - - //Simple scalar integers, equivalent to matching basic types from stdconst.h - TC_UBYTE, - TC_SBYTE, - TC_UWORD, - TC_SWORD, - TC_ULONG, - TC_SLONG, TC_LAST_INT_SCALAR= TC_SLONG, - - //Aggregate types containing one or more scalar - TC_ARRAY, - TC_CLUSTER, - - //Mutex tracks current holder and any waiting clumps - TC_MUTEX, - TC_FLOAT, TC_LAST_VALID= TC_FLOAT -}; - -//Sizes (in bytes) of each scalar type -#define SIZE_UBYTE 1 -#define SIZE_SBYTE 1 -#define SIZE_UWORD 2 -#define SIZE_SWORD 2 -#define SIZE_ULONG 4 -#define SIZE_SLONG 4 -#define SIZE_FLOAT 4 - -//MUTEX record is a struct containing 3 8-bit CLUMP_IDs, packed into 32-bit word -//See MUTEX_Q typedef -#define SIZE_MUTEX 4 - -//Module IDs for IO map addressing -enum -{ - MOD_INPUT, - MOD_OUTPUT -}; - -//Field IDs for input IOM -enum -{ - IO_IN_TYPE, - IO_IN_MODE, - IO_IN_ADRAW, - IO_IN_NORMRAW, - IO_IN_SCALEDVAL, - IO_IN_INVALID_DATA -}; - -//FPP = Fields Per Port -#define IO_IN_FPP 6 -#define IO_IN_FIELD_COUNT (IO_IN_FPP * NO_OF_INPUTS) - -//Field IDs for input IOM -enum -{ - IO_OUT_FLAGS, - IO_OUT_MODE, - IO_OUT_SPEED, //AKA "Power" - IO_OUT_ACTUAL_SPEED, - IO_OUT_TACH_COUNT, - IO_OUT_TACH_LIMIT, - IO_OUT_RUN_STATE, - IO_OUT_TURN_RATIO, - IO_OUT_REG_MODE, - IO_OUT_OVERLOAD, - IO_OUT_REG_P_VAL, - IO_OUT_REG_I_VAL, - IO_OUT_REG_D_VAL, - IO_OUT_BLOCK_TACH_COUNT, - IO_OUT_ROTATION_COUNT, - IO_OUT_OPTIONS, - IO_OUT_MAX_SPEED, - IO_OUT_MAX_ACCELERATION, -}; - -#define IO_OUT_FPP 18 -#define IO_OUT_FIELD_COUNT (IO_OUT_FPP * NO_OF_OUTPUTS) - -// -//DS_TOC_ENTRY is a record in the dataspace table of contents -//The TypeCode describes the data which is stored at Dataspace[DSOffset] -// -typedef struct -{ - TYPE_CODE TypeCode; - UBYTE Flags; - SWORD DSOffset; -} DS_TOC_ENTRY; - -//DS_TOC_ENTRY Flags -//!!! Yes, there's only one flag defined for an 8-bit field. -//ARM7 alignment rules means those bits would otherwise just be padding, anyway. -#define DS_DEFAULT_DEFAULT 1 //This entry has no default value in file; fill with zero at activation time - -//DS_ELEMENT_ID (AKA "DS item ID") indexes DataspaceTOC -typedef UWORD DS_ELEMENT_ID; - -//Special flag value used for opcode-specific default behavior when real dataspace argument is not provided -#define NOT_A_DS_ID 0xFFFF - -//Macro to bump DS_ELEMENT_IDs +1 with a cast (mostly to quash annoying warnings) -#define INC_ID(X) ((DS_ELEMENT_ID)(X + 1)) - -//DATA_ARG may contain a DS_ELEMENT_ID or encoded IO map address -typedef UWORD DATA_ARG; - -//CODE_WORD is a single indexable element of the codespace -typedef SWORD CODE_WORD; - -//CODE_INDEX indexes codespaces for opcodes and args -//!!! UWORD CODE_INDEX currently limits programs to 128KB code -// Yes, this is "plenty", but noted here to make sure we think about it -// when considering code size changes -typedef UWORD CODE_INDEX; - -//Typedef and define to hold and check for valid file handles -typedef UBYTE FILE_HANDLE; - -#define NOT_A_HANDLE 0xFF - -// -// Dynamic Memory Manager -// - -typedef UWORD DV_INDEX; //Dope Vector Index: Index into the DopeVectorArray - -//DOPE_VECTOR struct: One instance exists in the DopeVectorArray for every array in the dataspace. -typedef struct -{ - UWORD Offset; - UWORD ElemSize; - UWORD Count; - DV_INDEX BackLink; // points to previous DV - DV_INDEX Link; // points to next DV -} DOPE_VECTOR; - -// -//MEM_MGR struct -//Head and Tail keep track of the main linked-list of dope vectors, -// which must be maintained in ascending order according to Offset -//FreeHead is the head DV of the list of allocated but unused DVs -//pDopeVectorArray is initialized at activation-time to point to the master DVA -// -typedef struct -{ - DV_INDEX Head; - DV_INDEX Tail; - DV_INDEX FreeHead; - DOPE_VECTOR * pDopeVectorArray; -} MEM_MGR; - -//Macro to shorten common DVA access code -#define DV_ARRAY VarsCmd.MemMgr.pDopeVectorArray -//# of nodes to alloc when the Dope Vector Array is full -#define DV_ARRAY_GROWTH_COUNT 25 -//Flag value for invalid Offset fields in DVs -#define NOT_AN_OFFSET 0xFFFF -//Check for legal index into DVA -#define IS_DV_INDEX_SANE(X) (((X) > 0) && ((X) < DV_ARRAY[0].Count)) - -// -// Message Queuing -// - -// -//There are 10 incoming and 10 outgoing message queues, each 5 messages deep -//A "message" is defined as a null-terminated string under MAX_MESSAGE_SIZE -// -#define MESSAGES_PER_QUEUE 5 -#define MESSAGE_QUEUE_COUNT 20 -#define INCOMING_QUEUE_COUNT ((MESSAGE_QUEUE_COUNT)/2) -#define NOT_A_QUEUE 0xFF - -// -//MAX_MESSAGE_SIZE including null-terminator -//!!! Capped at 59 unless USB protocol assumptions are changed! -// -#define MAX_MESSAGE_SIZE 59 - -//A MESSAGE is a dynamically sized string, so we use a DV_INDEX to get to its information -typedef DV_INDEX MESSAGE; - -// -//MESSAGE_QUEUE keeps track of last messages read and written (acts as a circular buffer) -// -typedef struct -{ - UWORD ReadIndex; - UWORD WriteIndex; - MESSAGE Messages[MESSAGES_PER_QUEUE]; -} MESSAGE_QUEUE; - -//Handy macros for accessing MESSAGE_QUEUEs -#define GET_WRITE_MSG(QueueID) (VarsCmd.MessageQueues[(QueueID)].Messages[VarsCmd.MessageQueues[(QueueID)].WriteIndex]) -#define GET_READ_MSG(QueueID) (VarsCmd.MessageQueues[(QueueID)].Messages[VarsCmd.MessageQueues[(QueueID)].ReadIndex]) -#define SET_WRITE_MSG(QueueID, DVIndex) (VarsCmd.MessageQueues[(QueueID)].Messages[VarsCmd.MessageQueues[(QueueID)].WriteIndex] = (DVIndex)) -#define SET_READ_MSG(QueueID, DVIndex) (VarsCmd.MessageQueues[(QueueID)].Messages[VarsCmd.MessageQueues[(QueueID)].ReadIndex] = (DVIndex)) - -// -// Datalog Queuing -// -// The datalog queue is loosely modeled around the message queue except that there is only one queue, not an array of them. -// - -// A datalog has one less byte of 'header' info so different max size -#define MAX_DATALOG_SIZE 60 - -// The number of datalog messages to buffer -#define DATALOG_QUEUE_DEPTH 30 - -// A DATALOG_MESSAGE is a dynamically sized string, so we use a DV_INDEX to get to its information -typedef DV_INDEX DATALOG_MESSAGE; - -// -// DATALOG_QUEUE keeps track of last messages read and written (acts as a circular buffer) -typedef struct -{ - UWORD ReadIndex; - UWORD WriteIndex; - DATALOG_MESSAGE Datalogs[DATALOG_QUEUE_DEPTH]; -} DATALOG_QUEUE; - -//Handy macros for accessing the DATALOG_QUEUE -#define GET_WRITE_DTLG() (VarsCmd.DatalogBuffer.Datalogs[VarsCmd.DatalogBuffer.WriteIndex]) -#define GET_READ_DTLG() (VarsCmd.DatalogBuffer.Datalogs[VarsCmd.DatalogBuffer.ReadIndex]) -#define SET_WRITE_DTLG(DVIndex) (VarsCmd.DatalogBuffer.Datalogs[VarsCmd.DatalogBuffer.WriteIndex] = (DVIndex)) -#define SET_READ_DTLG(DVIndex) (VarsCmd.DatalogBuffer.Datalogs[VarsCmd.DatalogBuffer.ReadIndex] = (DVIndex)) - - -// -//Definitions related to dataflow scheduling -// - -//CLUMP_IDs are used to index list at pAllClumps -typedef UBYTE CLUMP_ID; - -// -//The last value in CLUMP_ID's range is reserved as NOT_A_CLUMP -//This is useful as a queue terminator and general placeholder -// -#define NOT_A_CLUMP 0xFF -#define MAX_CLUMPS 255 -#define INSTR_MAX_COUNT 20 - -//CLUMP_Q struct for tracking head and tail of a queue of clumps -typedef struct -{ - CLUMP_ID Head; - CLUMP_ID Tail; -} CLUMP_Q; - -// -//MUTEX_Q is a struct to be stashed in the dataspace to track state of a mutex -//If mutex is free, Owner field is NOT_A_CLUMP and WaitQ is empty. -//The mutex is acquired by stashing a new owner's ID. -//If others attempt to acquire, they will be put on the WaitQ -// -typedef struct -{ - CLUMP_ID Owner; - CLUMP_Q WaitQ; -} MUTEX_Q; - -// -// Clump Record, run-time book-keeping for each clump -// -// CodeStart: Start of this clump's bytecodes, absolute address -// CodeEnd: End of this clump's bytecodes, absolute address -// PC: "program counter" -- current offset into codespace relative to CodeStart -// InitFireCount: Initial count of upstream dependencies -// CurrFireCount: Run-time count of unsatisfied dependencies -// Link: ID of next clump in the queue. NOT_A_CLUMP denotes end or bad link. -// -// clumpScalarDispatchHints: this clump only uses scalar data args, can be interpretted with faster dispatch tables -// -// pDependents: pointer to list of downstream dependents' ClumpIDs -// awakenTime: If a clump is on rest queue for sleep, this is the time at which it will return to runQueue -// DependentCount: Count of downstream dependents -// -typedef struct -{ - CODE_WORD* CodeStart; - CODE_WORD* CodeEnd; - CODE_WORD* PC; - UBYTE InitFireCount; - UBYTE CurrFireCount; //AKA ShortCount - CLUMP_ID Link; - - UBYTE clumpScalarDispatchHints; - - CLUMP_ID* pDependents; - ULONG awakenTime; - UBYTE DependentCount; -} CLUMP_REC; - -// -//Definitions for memory pool management -// - -//First valid pointer into the memory pool -#define POOL_START ((UBYTE*)(VarsCmd.Pool)) - -//Sentinel points one byte *past* the pool -- i.e. first bad pool pointer -#define POOL_SENTINEL ((UBYTE*)(VarsCmd.Pool + VarsCmd.PoolSize)) - -//Alignment mod for Pool and all sub-fields of the Pool -#define POOL_ALIGN SIZE_SLONG - -#define ALIGN_TO_MOD(val,mod) if ((val) % (mod) != 0) { (val) += (mod) - ((val) % (mod)); } else {} - -// -//Internal states of the VM -//VM_IDLE: Just sitting around. Request to run program will lead to ONE of the VM_RUN* states. -//VM_RUN_FREE: Attempt to run as many instructions as possible within our timeslice -//VM_RUN_SINGLE: Run exactly one instruction per timeslice -//VM_RUN_PAUSE: Program still "active", but someone has asked us to pause -//VM_RESET2: Final clean up and return to IDLE -//VM_RESET1: Initialize state variables and some I/O devices -- executed when programs end -// -typedef enum -{ - VM_IDLE, - VM_RUN_FREE, - VM_RUN_SINGLE, - VM_RUN_PAUSE, - VM_RESET1, - VM_RESET2, -} VM_STATE; - -// -// VARSCMD: Private state data for active program and VM system -// -//pCodespace: pointer for flat codespace (stored in flash, includes all clumps) -//CodespaceCount: count of code words -// -//pAllClumps: Pointer to list of CLUMP_RECs -//AllClumpsCount: Count of CLUMP_RECs in list -// -//RunQ: Head and tail of run queue (elements in-place in AllClumps list) -// -//pDataspaceTOC: Pointer to DSTOC entries (stored in flash) -//DataspaceCount: Count of entries in DSTOC -//pDataspace: Base pointer of actual dataspace -//DataspaceSize: Size, in bytes, of dataspace -//DSStaticSize: Size, in bytes, of static portion of the dataspace (used as an offset to the dynamic dataspace) -// -//VMState: Internal state of VM's loader/scheduler (cCmdCtrl()) -// -//MemMgr: Contains data to manage dynamic arrays -// -//PoolSize: Current size of main memory pool, in bytes. -//Pool: Static pool of bytes for stashing all program run-time data -// -//ActiveProgHandle: Handle of the program that is currently running -//ActiveProgName: Stashed name of currently running program, if any -// -//FileHandleTable: Table of file names opened by program while running. -// First byte of each record is 'r' or 'w' (read or write). -// -//MessageQueues: Message buffer tracking data -// -//CommStat, CommStatReset, CommCurrConnection, DirtyComm: Helper data for interfacing to c_comm module -// -//DirtyDisplay: Boolean reminding us to re-initialize the display if program used it -// -//StartTick: MS tick stashed when program started. Used for relative time measurements. -// -//Further notes on the memory pool: -// The main memory pool is used for all clump records, dataspace tracking data, -// and the dataspace itself. In other words, pAllClumps and -// pDataspace must all point to memory within the pool. Watch for NXT_ASSERTs -// to enforce safe indexing into the pool. -// -typedef struct -{ - CODE_WORD* pCodespace; - CLUMP_REC* pAllClumps; - DS_TOC_ENTRY* pDataspaceTOC; - UBYTE* pDataspace; - UBYTE* Pool; - - ULONG PoolSize; - UWORD CodespaceCount; - CLUMP_ID AllClumpsCount; - UWORD DataspaceCount; - UWORD DataspaceSize; - UWORD DSStaticSize; - - VM_STATE VMState; - - MEM_MGR MemMgr; - - CLUMP_Q RunQ; - CLUMP_Q RestQ; - - UBYTE ActiveProgHandle; - UBYTE ActiveProgName[FILENAME_LENGTH + 1]; - - UBYTE FileHandleTable[MAX_HANDLES][FILENAME_LENGTH + 2]; - - MESSAGE_QUEUE MessageQueues[MESSAGE_QUEUE_COUNT]; - - SWORD CommStat; - SWORD CommStatReset; - UBYTE CommCurrConnection; - - UBYTE DirtyComm; - UBYTE DirtyDisplay; - - ULONG StartTick; - - DATALOG_QUEUE DatalogBuffer; - -#if VM_BENCHMARK - ULONG InstrCount; - ULONG Average; - ULONG OverTimeCount; - ULONG MaxOverTimeLength; - ULONG CmdCtrlCount; - ULONG CompactionCount; - ULONG LastCompactionTick; - ULONG MaxCompactionTime; - ULONG OpcodeBenchmarks[OPCODE_COUNT][4]; - ULONG SyscallBenchmarks[SYSCALL_COUNT][4]; - UBYTE Buffer[256]; -#endif - -#if defined ARM_DEBUG - UBYTE AssertFlag; - ULONG AssertLine; -#endif -} VARSCMD; - -// -//Activation -// - -//Activate new program by filename (open file and inflate run-time data) -NXT_STATUS cCmdActivateProgram(UBYTE * pFileName); - -//Deactivate currently active program (re-init run-time data and close file) -void cCmdDeactivateProgram(); - -//Reset various device state variables -void cCmdResetDevices(void); - -//Parse activation record file header information -typedef struct -{ - UWORD DSTOC; - UWORD DSDefaults; - UWORD DSDefaultsSize; - UWORD DynamicDefaults; - UWORD DynamicDefaultsSize; - UWORD Clumps; - UWORD Codespace; -} PROG_FILE_OFFSETS; - -NXT_STATUS cCmdReadFileHeader(UBYTE* pData, ULONG DataSize, - PROG_FILE_OFFSETS* pFileOffsets); - -NXT_STATUS cCmdInflateDSDefaults(UBYTE* pDSDefaults, UWORD *pDefaultsOffset, DS_ELEMENT_ID DSElementID); - - -// -//Clump management -// - -//Clump queuing -void cCmdEnQClump(CLUMP_Q * Queue, CLUMP_ID NewClump); -void cCmdDeQClump(CLUMP_Q * Queue, CLUMP_ID Clump); -void cCmdRotateQ(); -UBYTE cCmdIsClumpOnQ(CLUMP_Q * Queue, CLUMP_ID Clump); -UBYTE cCmdIsQSane(CLUMP_Q * Queue); - -// Rest queue functions -NXT_STATUS cCmdSleepClump(ULONG time); -UBYTE cCmdCheckRestQ(ULONG currTime); - -//Mutex queuing -NXT_STATUS cCmdAcquireMutex(MUTEX_Q * Mutex); -NXT_STATUS cCmdReleaseMutex(MUTEX_Q * Mutex); - -//Conditionally schedule dependents of given clump (Begin and End specify subset of list) -NXT_STATUS cCmdSchedDependents(CLUMP_ID Clump, SWORD Begin, SWORD End); - -//Conditionally schedule TargetClump -NXT_STATUS cCmdSchedDependent(CLUMP_ID Clump, CLUMP_ID TargetClump); - -//Test if ClumpID is sane at run-time (valid for indexing AllClumps) -UBYTE cCmdIsClumpIDSane(CLUMP_ID Clump); - -// -//Code stream management -// - -//Instruction masking macros -- get the interesting bits out of an encoded instruction word -#define COMP_CODE(pInstr) ((UBYTE)((((pInstr)[0]) & 0x0700) >> 8)) -#define INSTR_SIZE(wd) ((wd) >> 12) & 0x0F; - -#define IS_SHORT_OP(pInstr) ((UBYTE)((((pInstr)[0]) & 0x0800) >> 8) == 8) -#define SHORT_OP_CODE(pInstr) COMP_CODE(pInstr) -#define SHORT_ARG(pInstr) ((SBYTE) (((pInstr)[0]) & 0x00FF)) -//ShortOpMap defined in c_cmd_bytecodes.h -#define OP_CODE(pInstr) (UBYTE) (((pInstr)[0]) & 0x00FF) - -// -//Memory pool management -// - -//Initialize entire memory pool with default value -void cCmdInitPool(void); - -//Resize dataspace array specified by DSElementID and Offset. -NXT_STATUS cCmdDSArrayAlloc(DS_ELEMENT_ID DSElementID, UWORD Offset, UWORD NewCount); -//Resize dataspace array specified by DVIndex. In most cases, call higher-level cCmdDSArrayAlloc instead. -NXT_STATUS cCmdDVArrayAlloc(DV_INDEX DVIndex, UWORD NewCount); - -NXT_STATUS cCmdAllocSubArrayDopeVectors(DS_ELEMENT_ID DSElementID, UWORD Offset); -NXT_STATUS cCmdFreeSubArrayDopeVectors(DS_ELEMENT_ID DSElementID, UWORD Offset); -NXT_STATUS cCmdAllocDopeVector(DV_INDEX *pIndex, UWORD ElemSize); -NXT_STATUS cCmdFreeDopeVector(DV_INDEX DVIndex); -NXT_STATUS cCmdGrowDopeVectorArray(UWORD NewCount); - -UWORD cCmdCalcArrayElemSize(DS_ELEMENT_ID DSElementID); - -NXT_STATUS cCmdMemMgrMoveToTail(DV_INDEX DVIndex); -NXT_STATUS cCmdMemMgrInsertAtTail(DV_INDEX DVIndex); - -//Utility function to check sanity of MemMgr data structure. Boolean result. -UBYTE cCmdVerifyMemMgr(); - -NXT_STATUS cCmdDSCompact(void); - -// -// Message Queue management -// - -NXT_STATUS cCmdMessageWrite(UWORD QueueID, UBYTE * pData, UWORD Length); -NXT_STATUS cCmdMessageRead(UWORD QueueID, UBYTE * pData, UWORD Length, UBYTE Remove); -NXT_STATUS cCmdMessageGetSize(UWORD QueueID, UWORD * Size); - -// -// Datalog Queue management -// - -NXT_STATUS cCmdDatalogWrite(UBYTE * pData, UWORD Length); -NXT_STATUS cCmdDatalogRead(UBYTE * pData, UWORD Length, UBYTE Remove); -NXT_STATUS cCmdDatalogGetSize(UWORD * Size); - -// -// Color Sensor -// - -NXT_STATUS cCmdColorSensorRead (UBYTE Port, SWORD* SensorValue, UWORD* RawArray, UWORD* NormalizedArray, - SWORD* ScaledArray, UBYTE* InvalidData); - -// -//Dataspace management -// - -#define IS_AGGREGATE_TYPE(TypeCode) ((TypeCode == TC_ARRAY) || (TypeCode == TC_CLUSTER)) -// use carefully, only where tc will be a scalar int -#define QUICK_UNSIGNED_TEST(TypeCode) ((TypeCode) & 0x1) -#define IS_SIGNED_TYPE(TypeCode) (((TypeCode) == TC_SBYTE) || ((TypeCode) == TC_SWORD) || ((TypeCode) == TC_SLONG)) -//!!!BDUGGAN add TC_FLOAT? - -//Test if DS_ELEMENT_ID is sane at run-time (valid for indexing DS TOC) -UBYTE cCmdIsDSElementIDSane(DS_ELEMENT_ID Index); - -DS_ELEMENT_ID cCmdGetDataspaceCount(void); - -//Pointer accessors to resolve actual data locations in RAM -void* cCmdDSPtr(DS_ELEMENT_ID DSElementID, UWORD Offset); -void* cCmdDVPtr(DV_INDEX DVIndex); - -//Helper to walk the DSTOC to the next entry at the same aggregate nesting level as CurrID -DS_ELEMENT_ID cCmdNextDSElement(DS_ELEMENT_ID CurrID); - -//Recursively compare two complete data type descriptors -UBYTE cCmdCompareDSType(DS_ELEMENT_ID DSElementID1, DS_ELEMENT_ID DSElementID2); - -//Functions for managing data flattened to byte arrays -UWORD cCmdCalcFlattenedSize(DS_ELEMENT_ID DSElementID, UWORD Offset); -NXT_STATUS cCmdFlattenToByteArray(UBYTE * pByteArray, UWORD * pByteOffset, DS_ELEMENT_ID DSElementID, UWORD Offset); -NXT_STATUS cCmdUnflattenFromByteArray(UBYTE * pByteArray, UWORD * pByteOffset, DS_ELEMENT_ID DSElementID, UWORD Offset); - -//Comparison evaluation. Comparison codes defined in c_cmd_bytecodes.h. -//cCmdCompare operates on scalars passed as ULONGs -- type-specific comparisons done inside function. -UBYTE cCmdCompare(UBYTE CompCode, ULONG Val1, ULONG Val2, TYPE_CODE TypeCode1, TYPE_CODE TypeCode2); -UBYTE cCmdCompareFlt(UBYTE CompCode, float Val1, float Val2, TYPE_CODE TypeCode1, TYPE_CODE TypeCode2); -//cCmdCompareAggregates does polymorphic comparisons (with recursive helper function). -NXT_STATUS cCmdCompareAggregates(UBYTE CompCode, UBYTE *ReturnBool, DATA_ARG Arg2, UWORD Offset2, DATA_ARG Arg3, UWORD Offset3); -NXT_STATUS cCmdRecursiveCompareAggregates(UBYTE CompCode, UBYTE *ReturnBool, UBYTE *Finished, DATA_ARG Arg2, UWORD Offset2, DATA_ARG Arg3, UWORD Offset3); - -//Cluster functions -UWORD cCmdClusterCount(DS_ELEMENT_ID DSElementID); - -//Array functions -#define ARRAY_ELEM_OFFSET(DVIndex, Index) ((UWORD)(DV_ARRAY[(DVIndex)].Offset + DV_ARRAY[(DVIndex)].ElemSize * (Index))) -UWORD cCmdGetDVIndex(DS_ELEMENT_ID DSElementID, UWORD Offset); -UWORD cCmdArrayCount(DS_ELEMENT_ID DSElementID, UWORD Offset); -TYPE_CODE cCmdArrayType(DS_ELEMENT_ID DSElementID); - -//!!! DATA_ARG masks are for internal use only! (Bytecode programs should never contain them) -// See cCmdResolveDataArg() calls in the interpreter code for OP_GETOUT, OP_SETIN, and OP_GETIN. -#define DATA_ARG_ADDR_MASK 0x3FFF -#define DATA_ARG_IMM_MASK 0x7FFF - -//General data accessors (DS and IO Map) -void * cCmdResolveDataArg(DATA_ARG DataArg, UWORD Offset, TYPE_CODE * TypeCode); -void * cCmdResolveIODataArg(DATA_ARG DataArg, ULONG Offset, TYPE_CODE * TypeCode); -ULONG cCmdGetVal(void * pVal, TYPE_CODE TypeCode); -void cCmdSetVal(void * pVal, TYPE_CODE TypeCode, ULONG NewVal); - -// Calibration routines -void cCmdLoadCalibrationFiles(void); -NXT_STATUS cCmdComputeCalibratedValue(UBYTE *nm, SWORD *raw); -void cCmdUpdateCalibrationCache(UBYTE *nm, SWORD min, SWORD max); - -// -//Interpreter functions -// - -//Clump-based "master" interpreter -NXT_STATUS cCmdInterpFromClump(); - -//Function pointer typedef for sub-interpreters -typedef NXT_STATUS (*pInterp)(CODE_WORD * const); -typedef NXT_STATUS (*pInterpShort)(CODE_WORD * const); - -//Sub-interpreter dispatch functions -NXT_STATUS cCmdInterpNoArg(CODE_WORD * const pCode); -NXT_STATUS cCmdInterpUnop1(CODE_WORD * const pCode); -NXT_STATUS cCmdInterpUnop2(CODE_WORD * const pCode); -NXT_STATUS cCmdInterpScalarUnop2(CODE_WORD * const pCode); -NXT_STATUS cCmdInterpBinop(CODE_WORD * const pCode); -NXT_STATUS cCmdInterpScalarBinop(CODE_WORD * const pCode); -NXT_STATUS cCmdInterpOther(CODE_WORD * const pCode); - -NXT_STATUS cCmdInterpShortError(CODE_WORD * const pCode); -NXT_STATUS cCmdInterpShortSubCall(CODE_WORD * const pCode); -NXT_STATUS cCmdInterpShortMove(CODE_WORD * const pCode); -NXT_STATUS cCmdInterpShortAcquire(CODE_WORD * const pCode); -NXT_STATUS cCmdInterpShortRelease(CODE_WORD * const pCode); - -NXT_STATUS cCmdMove(DATA_ARG Arg1, DATA_ARG Arg2); - -//Polymorphic interpreter functions -NXT_STATUS cCmdInterpPolyUnop2(CODE_WORD const Code, DATA_ARG Arg1, UWORD Offset1, DATA_ARG Arg2, UWORD Offset2); -ULONG cCmdUnop2(CODE_WORD const Code, ULONG Operand, TYPE_CODE TypeCode); -float cCmdUnop2Flt(CODE_WORD const Code, float Operand, TYPE_CODE TypeCode); - -NXT_STATUS cCmdInterpPolyBinop(CODE_WORD const Code, DATA_ARG Arg1, UWORD Offset1, DATA_ARG Arg2, UWORD Offset2, DATA_ARG Arg3, UWORD Offset3); -ULONG cCmdBinop(CODE_WORD const Code, ULONG LeftOp, ULONG RightOp, TYPE_CODE LeftType, TYPE_CODE RightType); -float cCmdBinopFlt(CODE_WORD const Code, float LeftOp, float RightOp, TYPE_CODE LeftType, TYPE_CODE RightType); -void cCmdSetValFlt(void * pVal, TYPE_CODE TypeCode, float NewVal); -float cCmdGetValFlt(void * pVal, TYPE_CODE TypeCode); -// -//Support functions for lowspeed (I2C devices, i.e. ultrasonic sensor) communications -// - -NXT_STATUS cCmdLSCheckStatus(UBYTE Port); -UBYTE cCmdLSCalcBytesReady(UBYTE Port); -NXT_STATUS cCmdLSWrite(UBYTE Port, UBYTE BufLength, UBYTE *pBuf, UBYTE ResponseLength); -NXT_STATUS cCmdLSRead(UBYTE Port, UBYTE BufLength, UBYTE * pBuf); - -// -//Support for OP_SYSCALL -// - -// -//Each cCmdWrap funtion below implements one system call. -//The OP_SYSCALL interpreter wrangles the argument vector, ArgV, -// then calls the appropriate wrapper function according to the SysCallID. -//Wrapper functions write directly back into the dataspace via ArgV. -// -#define MAX_CALL_ARGS 16 - -typedef NXT_STATUS (*pSysCall)(UBYTE * ArgV[]); - -NXT_STATUS cCmdWrapFileOpenRead(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapFileOpenWrite(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapFileOpenAppend(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapFileRead(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapFileWrite(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapFileClose(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapFileResolveHandle (UBYTE * ArgV[]); -NXT_STATUS cCmdWrapFileRename (UBYTE * ArgV[]); -NXT_STATUS cCmdWrapFileDelete (UBYTE * ArgV[]); -NXT_STATUS cCmdWrapSoundPlayFile(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapSoundPlayTone(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapSoundGetState(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapSoundSetState(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapDrawText(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapDrawPoint(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapDrawLine(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapDrawCircle(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapDrawRect(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapDrawPicture(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapSetScreenMode(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapReadButton(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapCommLSWrite(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapCommLSRead(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapCommLSCheckStatus(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapRandomNumber(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapGetStartTick(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapMessageWrite(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapMessageRead(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapDatalogWrite(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapCommBTCheckStatus(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapCommBTWrite(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapCommBTRead(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapKeepAlive(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapIOMapRead(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapIOMapWrite(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapColorSensorRead (UBYTE * ArgV[]); -NXT_STATUS cCmdWrapDatalogGetTimes(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapSetSleepTimeout(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapListFiles(UBYTE * ArgV[]); - -// Handlers for dynamically added syscalls -NXT_STATUS cCmdWrapCommHSWrite(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapCommHSRead(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapCommHSCheckStatus(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapCommBTOnOff(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapCommBTConnection(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapReadSemData(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapWriteSemData(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapUpdateCalibCacheInfo(UBYTE * ArgV[]); -NXT_STATUS cCmdWrapComputeCalibValue(UBYTE * ArgV[]); - - -//Handler for remote control protocol packets -- called from comm module via IO map function pointer -UWORD cCmdHandleRemoteCommands(UBYTE * pInBuf, UBYTE * pOutBuf, UBYTE * pLen); - -#ifdef SIM_NXT -// -// Helper functions to provide simulator library access to VM internals -// -SWORD cCmdGetCodeWord(CLUMP_ID Clump, CODE_INDEX Index); -UBYTE * cCmdGetDataspace(UWORD *DataspaceSize); -DOPE_VECTOR * cCmdGetDopeVectorPtr(void); -ULONG cCmdGetPoolSize(void); -MEM_MGR cCmdGetMemMgr(void); -#endif - -#else //!ENABLE_VM - -//Placeholder VARSCMD for alternate implementation (see bottom of c_cmd.c for usage notes) -typedef struct -{ - UBYTE Tmp; -} VARSCMD; - -#endif //ENABLE_VM - -#endif //C_CMD diff --git a/AT91SAM7S256/Source/c_cmd.iom b/AT91SAM7S256/Source/c_cmd.iom deleted file mode 100644 index 7c5906c..0000000 --- a/AT91SAM7S256/Source/c_cmd.iom +++ /dev/null @@ -1,202 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date: 3-02-09 9:28 $ -// -// Filename $Workfile:: c_cmd.iom $ -// -// Version $Revision: 5 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_cmd. $ -// -// Platform C -// - -#ifndef CCMD_IOM -#define CCMD_IOM - -#include "modules.h" - -#define pMapCmd ((IOMAPCMD*)(pHeaders[ENTRY_CMD]->pIOMap)) - -// -// Status/error codes for the VM internal code and bytecodes, loosely categorized -// Positive values are used for non-error status codes; commonly used by bytecode handlers -// to affect future execution. -// Negative values are run-time errors, and the first group is considered "fatal" in that -// program execution cannot continue when these errors are encountered. -// - -#define STAT_MSG_EMPTY_MAILBOX 64 //0x40 Specified mailbox contains no new messages -#define STAT_MSG_BUFFERWRAP 16 //0x10 Datalog buffer not being read fast enough -#define STAT_COMM_PENDING 32 //0x20 Pending setup operation in progress - -#define TIMES_UP 6 //0x06 Return to let drivers run -#define ROTATE_QUEUE 5 //0x05 Give a slice to another queue -#define STOP_REQ 4 //0x04 Abort current program -#define BREAKOUT_REQ 3 //0x03 Break multi-instruction interpreter loop; give I/O a chance to run -#define CLUMP_SUSPEND 2 //0x02 Place clump in stasis; execute others until this one returns to RunQ -#define CLUMP_DONE 1 //0x01 Finish and reset this clump; execute others until this one is rescheduled - -#define NO_ERR 0 - -//Fatal errors -#define ERR_ARG -1 //0xFF Bad arguments -#define ERR_INSTR -2 //0xFE Illegal bytecode instruction -#define ERR_FILE -3 //0xFD Mal-formed file contents -#define ERR_VER -4 //0xFC Version mismatch between firmware and compiler -#define ERR_MEM -5 //0xFB Insufficient memory available -#define ERR_BAD_PTR -6 //0xFA Someone passed us a bad pointer! - -//General errors -#define ERR_INVALID_PORT -16 //0xF0 Bad input or output port specified -#define ERR_INVALID_FIELD -17 //0xEF Attempted to access invalid field of a structure -#define ERR_INVALID_QUEUE -18 //0xEE Illegal queue ID specified -#define ERR_INVALID_SIZE -19 //0xED Illegal size specified -#define ERR_NO_PROG -20 //0xEC No active program - -//Communications specific errors -#define ERR_COMM_CHAN_NOT_READY -32 //0xE0 Specified channel/connection not configured or busy -#define ERR_COMM_CHAN_INVALID -33 //0xDF Specified channel/connection is not valid -#define ERR_COMM_BUFFER_FULL -34 //0xDE No room in comm buffer -#define ERR_COMM_BUS_ERR -35 //0xDD Something went wrong on the communications bus - -//Remote control ("direct commands") errors -#define ERR_RC_ILLEGAL_VAL -64 //0xC0 Data contains out-of-range values -#define ERR_RC_BAD_PACKET -65 //0xBF Clearly insane packet -#define ERR_RC_UNKNOWN_CMD -66 //0xBE Unknown command opcode -#define ERR_RC_FAILED -67 //0xBD Request failed (i.e. specified file not found) - -//NB: Error codes -96 through -128 (0xA0 through 0x80) reserved for loader (file system) errors -//This whole range isn't actually used by current loader code, but it's a reasonable range to reserve - -#define IS_ERR(Status) ((Status) < NO_ERR) - -//Errors are considered fatal if they are something we'd consider halting the VM for. -#define IS_FATAL(Status) ((Status) < NO_ERR && (Status) >= ERR_BAD_PTR) - -//Direct command protocol opcodes -//!!! These MUST be mutually exclusive with c_comm's protocol opcodes. -// Since all of c_comm's protocol opcodes are above 0x80, we're safe for now. -enum -{ - RC_START_PROGRAM, - RC_STOP_PROGRAM, - RC_PLAY_SOUND_FILE, - RC_PLAY_TONE, - RC_SET_OUT_STATE, - RC_SET_IN_MODE, - RC_GET_OUT_STATE, - RC_GET_IN_VALS, - RC_RESET_IN_VAL, - RC_MESSAGE_WRITE, - RC_RESET_POSITION, - RC_GET_BATT_LVL, - RC_STOP_SOUND, - RC_KEEP_ALIVE, - RC_LS_GET_STATUS, - RC_LS_WRITE, - RC_LS_READ, - RC_GET_CURR_PROGRAM, - RC_GET_BUTTON_STATE, - RC_MESSAGE_READ, - RC_RESERVED1, - RC_RESERVED2, - RC_RESERVED3, - RC_RESERVED4, - RC_RESERVED5, - RC_DATALOG_READ, - RC_DATALOG_SET_TIMES, - RC_BT_GET_CONTACT_COUNT, - RC_BT_GET_CONTACT_NAME, - RC_BT_GET_CONN_COUNT, - RC_BT_GET_CONN_NAME, - RC_SET_PROPERTY, - RC_GET_PROPERTY, - RC_UPDATE_RESET_COUNT, - - NUM_RC_OPCODES -}; - -// selectors for RC Get and Set properties -enum { -RC_PROP_BTONOFF, -RC_PROP_SOUND_LEVEL, -RC_PROP_SLEEP_TIMEOUT -}; - -// -//Published status of last program to be activated -//This value is published so outside parties (like the UI) can check if a program is running, -//and if not, how the last program ended. Initial value is "PROG_OK". -//PROG_OK: Last program finished normally. -//PROG_RUNNING: Program currently running -//PROG_ERROR: Last program ended because of an error -//PROG_ABORT: Last program ended because of (user) abort -// -typedef enum -{ - PROG_IDLE, - PROG_OK, - PROG_RUNNING, - PROG_ERROR, - PROG_ABORT, - PROG_RESET -} PROGRAM_STATUS; - -//Maximum size of memory pool, in bytes -//!!! Code assumes this value is evenly divisible by 4! -#define POOL_MAX_SIZE 32768 - -//Versioning information -//Format string must exist verbatim in the header of a valid program file. -//Also included in IOMAPCMD for remote identification of the VM -#define VM_FORMAT_STRING "MindstormsNXT" -//Size of format string above, plus version number packed in the last two bytes. -#define VM_FORMAT_STRING_SIZE 16 -//Current firmware version defined in c_loader.iom as FIRMWAREVERSION -//This is the oldest compatible version in the same system -#define VM_OLDEST_COMPATIBLE_VERSION 0x0004 -// -//IO Map for Command Module -// pRCHandler: Function pointer to handler for remote control protocol -// Tick: Latest value from 1 ms system timer - -//!!! Two offset values below are useful for external debugging. They are only valid after a program has started! -// OffsetDS: Offset to the dataspace (inside MemoryPool); relative to first byte of IOMapCmd -// OffsetDVA: Offset to the DopeVectorArray (inside MemoryPool); relative to first byte of IOMapCmd - -// ProgStatus: Published status of last program to be activated -// Awake: Boolean is only true after initialization - -// ActivateFlag: Set this flag to notify cCmdCtrl to activate new file -// DeactivateFlag: Set this flag to notify cCmdCtrl to deactivate current program - -// FileName[]: Fill in this buffer when using ActivateFlag -// MemoryPool[]: Main memory pool for program data. -// (Declared as ULONG for portable alignment; used internally via a byte pointer.) -// -typedef struct -{ - UBYTE FormatString[VM_FORMAT_STRING_SIZE]; - UWORD (*pRCHandler)(UBYTE *, UBYTE *, UBYTE *); - ULONG Tick; - - UWORD OffsetDS; - UWORD OffsetDVA; - - PROGRAM_STATUS ProgStatus; - - UBYTE Awake; - - UBYTE ActivateFlag; - UBYTE DeactivateFlag; - UBYTE FileName[FILENAME_LENGTH + 1]; - - ULONG MemoryPool[POOL_MAX_SIZE / 4]; - - ULONG SyncTime; - ULONG SyncTick; -} IOMAPCMD; - -#endif //CCMD_IOM diff --git a/AT91SAM7S256/Source/c_cmd_bytecodes.h b/AT91SAM7S256/Source/c_cmd_bytecodes.h deleted file mode 100644 index 5cd9dfd..0000000 --- a/AT91SAM7S256/Source/c_cmd_bytecodes.h +++ /dev/null @@ -1,119 +0,0 @@ -#ifndef C_CMD_BYTECODES -#define C_CMD_BYTECODES -// -// opcode definitions -// symbol, bits, arg format -// -#define OPCODE_COUNT 0x38 - -//Family: Math -#define OP_ADD 0x00 // dest, src1, src2 -#define OP_SUB 0x01 // dest, src1, src2 -#define OP_NEG 0x02 // dest, src -#define OP_MUL 0x03 // dest, src1, src2 -#define OP_DIV 0x04 // dest, src1, src2 -#define OP_MOD 0x05 // dest, src1, src2 - -//Family: Logic -#define OP_AND 0x06 // dest, src1, src2 -#define OP_OR 0x07 // dest, src1, src2 -#define OP_XOR 0x08 // dest, src1, src2 -#define OP_NOT 0x09 // dest, src - -//Family: Bit manipulation -#define OP_CMNT 0x0A // dest, src -#define OP_LSL 0x0B // dest, src -#define OP_LSR 0x0C // dest, src -#define OP_ASL 0x0D // dest, src -#define OP_ASR 0x0E // dest, src -#define OP_ROTL 0x0F // dest, src -#define OP_ROTR 0x10 // dest, src - -//Family: Comparison -#define OP_CMP 0x11 // dest, src1, src2 -#define OP_TST 0x12 // dest, src -#define OP_CMPSET 0x13 // dest, src, testsrc, testsrc -#define OP_TSTSET 0x14 // dest, src, testsrc - -//Family: Array ops -#define OP_INDEX 0x15 // dest, src, index -#define OP_REPLACE 0x16 // dest, src, index, val -#define OP_ARRSIZE 0x17 // dest, src -#define OP_ARRBUILD 0x18 // instrsize, dest, src1, src2, … -#define OP_ARRSUBSET 0x19 // dest, src, index, length -#define OP_ARRINIT 0x1A // dest, elem, length - -//Family: Memory ops -#define OP_MOV 0x1B // dest, src -#define OP_SET 0x1C // dest, imm - -//Family: String ops -#define OP_FLATTEN 0x1D // dest, src -#define OP_UNFLATTEN 0x1E // dest, err, src, type -#define OP_NUMTOSTRING 0x1F // dest, src -#define OP_STRINGTONUM 0x20 // dest, offsetpast, src, offset, default -#define OP_STRCAT 0x21 // instrsize, dest, src1, src2, … -#define OP_STRSUBSET 0x22 // dest, src, index, length -#define OP_STRTOBYTEARR 0x23 // dest, src -#define OP_BYTEARRTOSTR 0x24 // dest, src - -//Family: Control flow -#define OP_JMP 0x25 // offset -#define OP_BRCMP 0x26 // offset, src1, src2 -#define OP_BRTST 0x27 // offset, src -#define OP_SYSCALL 0x28 // func, args -#define OP_STOP 0x29 // stop? - -//Family: Clump scheduling -#define OP_FINCLUMP 0x2A // start, end -#define OP_FINCLUMPIMMED 0x2B // clumpID -#define OP_ACQUIRE 0x2C // mutexID -#define OP_RELEASE 0x2D // mutexID -#define OP_SUBCALL 0x2E // subroutine, callerID -#define OP_SUBRET 0x2F // callerID - -//Family: IO ops -#define OP_SETIN 0x30 // src, port, propid -#define OP_SETOUT 0x31 // src, port, propid -#define OP_GETIN 0x32 // dest, port, propid -#define OP_GETOUT 0x33 // dest, port, propid - -//Family: Timing -#define OP_WAIT 0x34 // dest, src -#define OP_GETTICK 0x35 // dest - -//Family: Math NEW -#define OP_SQRT 0x36 // dest, src -#define OP_ABS 0x37 // dest, src - -// condition code definitions -#define OPCC1_LT 0x00 -#define OPCC1_GT 0x01 -#define OPCC1_LTEQ 0x02 -#define OPCC1_GTEQ 0x03 -#define OPCC1_EQ 0x04 -#define OPCC1_NEQ 0x05 - - - -// -// short op definitions -// -#define USE_SHORT_OPS -#define SHORT_OP_MOV 0 -#define SHORT_OP_ACQUIRE 1 -#define SHORT_OP_RELEASE 2 -#define SHORT_OP_SUBCALL 3 - -// -// short op mapping table -// -static UBYTE ShortOpMap[4] = -{ - OP_MOV, - OP_ACQUIRE, - OP_RELEASE, - OP_SUBCALL -}; - -#endif // C_CMD_BYTECODES diff --git a/AT91SAM7S256/Source/c_cmd_drawing.inc b/AT91SAM7S256/Source/c_cmd_drawing.inc deleted file mode 100644 index 0132d44..0000000 --- a/AT91SAM7S256/Source/c_cmd_drawing.inc +++ /dev/null @@ -1,894 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 8/26/05 4:17p $ -// -// Filename $Workfile:: c_cmd.c $ -// -// Version $Revision:: 35 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_cmd_drawing.c $ -// -// Platform C -// - -//absolute value of a -#define ABS(a) (((a)<0) ? -(a) : (a)) - -//take binary sign of a, either -1, or 1 if >= 0 -#define SGN(a) (((a)<0) ? -1 : 1) - -#define DISP_BUFFER_P ((UBYTE*)&(pMapDisplay->Normal)) - -//------------------------------------------------------------------ -// cCmdClearScreenIfNeeded - Clear entire sceen buffer if explicitly requested or implicitly required. -void cCmdClearScreenIfNeeded(ULONG DrawOptions); - -//------------------------------------------------------------------ -// cCmdRestorDefaultScreen - Restore screen to default 'Running' screen -void cCmdRestoreDefaultScreen(void); - -//------------------------------------------------------------------ -// cCmdDrawString - Draw string to display buffer -void cCmdDrawString(UBYTE *pString, ULONG X, ULONG Y); - -// OP codes supported by RIC files -enum { - IMG_DESCRIPTION_ID = 0, // Ignored at this time - IMG_SPRITE_ID = 1, - IMG_VARMAP_ID = 2, - IMG_COPYBITS_ID = 3, - IMG_PIXEL_ID = 4, - IMG_LINE_ID = 5, - IMG_RECTANGLE_ID = 6, - IMG_CIRCLE_ID = 7, - IMG_NUMBOX_ID = 8 -}; - -#define IMG_SYMB_USEARGS(_v) (_v & (SWORD)0xF000) -#define IMG_SYMB_MAP(_v) ((_v & 0x0F00) >> 8) -#define IMG_SYMB_ARG(_v) (_v & 0x000F) - -// DrawingOptions -#define DRAW_OPT_CLEAR_WHOLE_SCREEN (0x0001) -#define DRAW_OPT_CLEAR_EXCEPT_STATUS_SCREEN (0x0002) -#define DRAW_OPT_CLEAR_MODE(_v) ((_v) & 0x0003) - - -// Clear Before Drawing Modes for Draw functions -enum { - DO_NOT_CLEAR = 0, - CLEAR_B4_DRAW = 1 -}; - -// Screen Modes for SetScreenMode function -enum { - RESTORE_NXT_SCREEN = 0 -}; - -#define IMG_COMMON_FIELDS UWORD OpSize; UWORD OpCode; - -#define TRANSLATE_Y(_y) ((DISPLAY_HEIGHT-1) - (_y)) - -typedef struct -{ - SWORD X, Y; -} IMG_PT; - -typedef struct -{ - IMG_PT Pt; - SWORD Width, Height; -} IMG_RECT; - -typedef struct -{ - IMG_COMMON_FIELDS -} IMG_OP_CORE; - -typedef struct -{ - IMG_COMMON_FIELDS - UWORD Options; - UWORD Width; - UWORD Height; -} IMG_OP_DESCRIPTION; - -typedef struct -{ - IMG_COMMON_FIELDS - UWORD DataAddr; //Address sprite handle will be stored in. - UWORD Rows; //Second deminsion of the array below. - UWORD RowBytes; //The actual size of the following array. Must be even. - UBYTE Bytes[2]; //Minimum of two for alignment purposes -} IMG_OP_SPRITE; - -typedef struct -{ - IMG_COMMON_FIELDS - UWORD DataAddr; //Address sprite handle will be stored in. - UWORD MapCount; //The actual size of the following array. Must be even. - struct - { //Minimum of two for alignment purposes - UWORD Domain; - UWORD Range; - } MapElt[1]; -} IMG_OP_VARMAP; - -typedef struct -{ - IMG_COMMON_FIELDS - UWORD CopyOptions; // Copy, CopyNot, Or, BitClear; - UWORD DataAddr; // Address of an already defined sprite - IMG_RECT Src; // Source rectangle - IMG_PT Dst; // Destination left top -} IMG_OP_COPYBITS; - -typedef struct -{ - IMG_COMMON_FIELDS - UWORD CopyOptions; - IMG_PT Pt; - UWORD Value; // typically mapped to an argument -} IMG_OP_PIXEL; - -typedef struct -{ - IMG_COMMON_FIELDS - UWORD CopyOptions; - IMG_PT Pt1; - IMG_PT Pt2; -} IMG_OP_LINE; - -typedef struct -{ - IMG_COMMON_FIELDS - UWORD CopyOptions; - IMG_PT Pt; - SWORD Width, Height; -} IMG_OP_RECT; - -typedef struct -{ - IMG_COMMON_FIELDS - UWORD CopyOptions; - IMG_PT Pt; - UWORD Radius; -} IMG_OP_CIRCLE; - -typedef struct -{ - IMG_COMMON_FIELDS - UWORD CopyOptions; - IMG_PT Pt; - UWORD Value; // typically mapped to an argument -} IMG_OP_NUMBOX; - -typedef union -{ IMG_OP_CORE Core; - IMG_OP_DESCRIPTION Desc; - IMG_OP_SPRITE Sprite; - IMG_OP_VARMAP VarMap; - IMG_OP_COPYBITS CopyBits; - IMG_OP_PIXEL Pixel; - IMG_OP_LINE Line; - IMG_OP_RECT Rect; - IMG_OP_CIRCLE Circle; - IMG_OP_NUMBOX NumBox; -} IMG_OP_UNION; - -// Variables for DrawImage -#define IMG_MAX_DATA 11 -IMG_OP_UNION * gpImgData[IMG_MAX_DATA]; -SLONG * gpPassedImgVars; -SWORD gPassedVarsCount; - -// Private Prototypes -void cCmdDrawLine(SLONG x1, SLONG y1, SLONG x2, SLONG y2); -void cCmdDrawRect(SLONG left, SLONG bottom, SLONG width, SLONG hieght); -void cCmdCopyBitMapBits(SLONG dst_x, SLONG dst_y, - SLONG src_x, SLONG src_y, SLONG src_width, SLONG src_height, - IMG_OP_SPRITE * pSprite); -SLONG cCmdResolveValue(SWORD Value); -void cCmdSetPixel(SLONG X, SLONG Y, ULONG Val); - -//----------------------------------------------------------------- -//cCmdWrapDrawText -//ArgV[0]: (Function return) Status byte, SBYTE -//ArgV[1]: Location (IMG_PT *) -//ArgV[2]: Text (CStr) -//ArgV[3]: Options (ULONG) -// -NXT_STATUS cCmdWrapDrawText(UBYTE * ArgV[]) -{ - IMG_PT * pPt = (IMG_PT*) ArgV[1]; - - ArgV[2] = (UBYTE*)cCmdDVPtr(*(DV_INDEX *)(ArgV[2])); //Resolve array argument - - cCmdClearScreenIfNeeded(*(ULONG*)ArgV[3]); - - // Display the String - cCmdDrawString(ArgV[2], (UBYTE)pPt->X, (UBYTE)(pPt->Y)); - pMapDisplay->UpdateMask |= SCREEN_BIT(SCREEN_BACKGROUND); - - // Set return value - *((SBYTE*)(ArgV[0])) = NO_ERR; - - return NO_ERR; -} - -//----------------------------------------------------------------- -//cCmdWrapDrawPoint -//ArgV[0]: (Function return) Status byte, SBYTE -//ArgV[1]: Location (IMG_PT *) -//ArgV[2]: Options (ULONG) -NXT_STATUS cCmdWrapDrawPoint(UBYTE * ArgV[]) -{ - IMG_PT * pPt = (IMG_PT*) ArgV[1]; - - cCmdClearScreenIfNeeded(*(ULONG*)ArgV[2]); - - // Display the String - cCmdSetPixel(pPt->X, pPt->Y, TRUE); - - pMapDisplay->UpdateMask |= SCREEN_BIT(SCREEN_BACKGROUND); - - // Set return value - *((SBYTE*)(ArgV[0])) = NO_ERR; - - return NO_ERR; -} - -//----------------------------------------------------------------- -//cCmdWrapDrawLine -//ArgV[0]: (Function return) Status byte, SBYTE -//ArgV[1]: Start Location (IMG_PT *) -//ArgV[2]: End Location (IMG_PT *) -//ArgV[3]: Options (ULONG) -NXT_STATUS cCmdWrapDrawLine(UBYTE * ArgV[]) -{ - IMG_PT * pPt1 = (IMG_PT*) ArgV[1]; - IMG_PT * pPt2 = (IMG_PT*) ArgV[2]; - - cCmdClearScreenIfNeeded(*(ULONG*)ArgV[3]); - - cCmdDrawLine(pPt1->X, pPt1->Y, pPt2->X, pPt2->Y); - - pMapDisplay->UpdateMask |= SCREEN_BIT(SCREEN_BACKGROUND); - - // Set return value - *((SBYTE*)(ArgV[0])) = NO_ERR; - - return NO_ERR; -} - -//----------------------------------------------------------------- -//cCmdWrapDrawCircle -//ArgV[0]: (Function return) Status byte, SBYTE -//ArgV[1]: Start Location (IMG_PT *) -//ArgV[2]: Radius (U8) -//ArgV[3]: Options (ULONG) -NXT_STATUS cCmdWrapDrawCircle(UBYTE * ArgV[]) -{ - SLONG x, x1, y1, y, dp, delta; - IMG_PT * pPt = (IMG_PT*) ArgV[1]; - SLONG radius = *(UBYTE*)ArgV[2]; - - cCmdClearScreenIfNeeded(*(ULONG*)ArgV[3]); - - x1 = pPt->X; - y1 = pPt->Y; - x = 0; - y = radius; - dp=2*(1-radius); - while(y >= 0) - { - cCmdSetPixel((x+x1), (y+y1), TRUE); - cCmdSetPixel((-x+x1),(-y+y1), TRUE); - cCmdSetPixel((x+x1), (-y+y1), TRUE); - cCmdSetPixel((-x+x1),(y+y1), TRUE); - if(dp<0) - { - delta = 2*dp + 2*y - 1; - if (delta > 0) - { - x++; - y--; - dp += 2*x - 2*y + 2; - } - else - { - x++; - dp += 2*x + 1; - } - } - else if (dp > 0) - { - delta = 2*dp - 2*x - 1; - if (delta > 0) - { - y--; - dp += 1 - 2*y; - } - else - { - x++; - y--; - dp += 2*x - 2*y + 2; - } - } - else - { - x++; - y--; - dp += 2*x - 2*y +2; - } - } - - pMapDisplay->UpdateMask |= SCREEN_BIT(SCREEN_BACKGROUND); - - // Set return value - *((SBYTE*)(ArgV[0])) = NO_ERR; - - return NO_ERR; -} - -//----------------------------------------------------------------- -//cCmdWrapDrawRect -//ArgV[0]: (Function return) Status byte, SBYTE -//ArgV[1]: TopLeft (IMG_PT *) -//ArgV[2]: BottomRight (IMG_PT *) -//ArgV[3]: Options (ULONG) -NXT_STATUS cCmdWrapDrawRect(UBYTE * ArgV[]) -{ - IMG_PT * pPt1 = (IMG_PT*) ArgV[1]; - IMG_PT * pPt2 = (IMG_PT*) ArgV[2]; // Second point is actually (width, height) - - cCmdClearScreenIfNeeded(*(ULONG*)ArgV[3]); - - cCmdDrawRect(pPt1->X, pPt1->Y, pPt2->X, pPt2->Y); - - pMapDisplay->UpdateMask |= SCREEN_BIT(SCREEN_BACKGROUND); - - // Set return value - *((SBYTE*)(ArgV[0])) = NO_ERR; - - return NO_ERR; -} - -//----------------------------------------------------------------- -IMG_OP_UNION * cCmdGetIMGData(ULONG DataAddr) -{ - if (DataAddr >= IMG_MAX_DATA) - return NULL; - else - return gpImgData[DataAddr]; -} - -//----------------------------------------------------------------- -void cCmdSetIMGData(ULONG DataAddr, IMG_OP_UNION * pSprite) -{ - if ((DataAddr >= 1) && (DataAddr < IMG_MAX_DATA)) - gpImgData[DataAddr] = pSprite; -} - -//----------------------------------------------------------------- -SLONG cCmdResolveValue(SWORD Value) -{ - if (!IMG_SYMB_USEARGS(Value)) - { - return Value; - } - else - { - IMG_OP_VARMAP * pVarMap; - SLONG Arg; - - pVarMap = (IMG_OP_VARMAP *) cCmdGetIMGData((SWORD)IMG_SYMB_MAP(Value)); - Arg = gpPassedImgVars[IMG_SYMB_ARG(Value)]; - - if (!pVarMap) - { - // No map, this implies a 1:1 mapping. - return Arg; - } - else - { - // Scan through the list finding the pair the Arg lies between - // Then linearly interpolate the mapping. - SLONG i, DCur, RCur, DSpread, VSpread, RSpread; - SLONG Count = pVarMap->MapCount; - SLONG DPrev = pVarMap->MapElt[0].Domain; - SLONG RPrev = pVarMap->MapElt[0].Range; - if (Arg <= DPrev) - { - // Too small, map it to the first point - return RPrev; - } - - for (i = 1; i < Count; i++) - { - DCur = pVarMap->MapElt[i].Domain; - RCur = pVarMap->MapElt[i].Range; - if (Arg < DCur) - { - DSpread = DCur - DPrev; - VSpread = Arg - DPrev; - RSpread = RCur - RPrev; - // Found the point and mapped, it return. - return (RPrev+((VSpread*RSpread)/DSpread)); - } - DPrev = DCur; - RPrev = RCur; - } - // If we get this far then it is too large, map it to the last point. - return RCur; - } - } -} - - -//----------------------------------------------------------------- -//cCmdWrapDrawGraphic -//ArgV[0]: (Function return) Status Byte, SBYTE -//ArgV[1]: Left Top (IMG_PT *) -//ArgV[2]: Filename, CStr -//ArgV[3]: Variables, array of I32 -//ArgV[4]: Options (ULONG) -NXT_STATUS cCmdWrapDrawPicture(UBYTE * ArgV[]) -{ - SBYTE * pReturnVal = (SBYTE*)(ArgV[0]); - LOADER_STATUS LStatus; - NXT_STATUS DStatus = NO_ERR; - ULONG DataSize; - SLONG OpSize; - IMG_PT Pt; // Where to draw the picture at (up and to the right) - UBYTE ImageHandle; - IMG_OP_UNION * pImage; - - //Resolve array argument - ArgV[2] = (UBYTE*)cCmdDVPtr(*(DV_INDEX *)(ArgV[2])); - ArgV[3] = (UBYTE*)cCmdDVPtr(*(DV_INDEX *)(ArgV[3])); - - cCmdClearScreenIfNeeded(*(ULONG*)ArgV[4]); - - //Open the file in memory map mode. return if failure. - LStatus = pMapLoader->pFunc(OPENREADLINEAR, ArgV[2], (UBYTE*)(&pImage), &DataSize); - ImageHandle = LOADER_HANDLE(LStatus); - - //If error opening file, give up and write loader status back to user. - if (LOADER_ERR(LStatus) != SUCCESS || pImage == NULL) - { - *pReturnVal = (SBYTE)(LOADER_ERR_BYTE(LStatus)); - return (NO_ERR); - } - //Else, start interpretting the file - else - { - // Read the ArgV params, Clear the data table. - Pt = *(IMG_PT*)ArgV[1]; - //!!! Unsafe assumption that array is non-empty. Should check and avoid using pointer if empty. - gpPassedImgVars = (SLONG*)ArgV[3]; - memset(gpImgData,0,sizeof(gpImgData)); - - // Run through the op codes. - while(!IS_ERR(DStatus)) - { - // Setup to look at an opcode, make sure it looke reasonable. - if (DataSize < sizeof(IMG_OP_CORE)) - { - DStatus = ERR_FILE; - break; // Too small to look at, somethings wrong. - } - OpSize = pImage->Core.OpSize + sizeof(UWORD); - if (OpSize & 0x01) - { - DStatus = ERR_FILE; - break; // Odd sizes not allowed. - } - - switch(pImage->Core.OpCode) - { - case IMG_SPRITE_ID: - { - if (OpSize >= sizeof(IMG_OP_SPRITE)) - cCmdSetIMGData(pImage->Sprite.DataAddr, pImage); - } - break; - - case IMG_VARMAP_ID: - { - if (OpSize >= sizeof(IMG_OP_VARMAP)) - cCmdSetIMGData(pImage->VarMap.DataAddr, pImage); - } - break; - - case IMG_COPYBITS_ID: - { - if (OpSize >= sizeof(IMG_OP_COPYBITS)) - { - IMG_OP_COPYBITS * pCB = &(pImage->CopyBits); - cCmdCopyBitMapBits( - (cCmdResolveValue(pCB->Dst.X) + Pt.X), - (cCmdResolveValue(pCB->Dst.Y) + Pt.Y), - cCmdResolveValue((pCB->Src.Pt.X)), - cCmdResolveValue((pCB->Src.Pt.Y)), - cCmdResolveValue((pCB->Src.Width)), - cCmdResolveValue((pCB->Src.Height)), - (IMG_OP_SPRITE*)cCmdGetIMGData(cCmdResolveValue(pCB->DataAddr))); - } - } - break; - - case IMG_LINE_ID: - { - if (OpSize >= sizeof(IMG_OP_LINE)) - { - IMG_OP_LINE * pL = &(pImage->Line); - cCmdDrawLine( - (cCmdResolveValue(pL->Pt1.X)+Pt.X), - (cCmdResolveValue(pL->Pt1.Y)+Pt.Y), - (cCmdResolveValue(pL->Pt2.X)+Pt.X), - (cCmdResolveValue(pL->Pt2.Y)+Pt.Y) - ); - } - } - break; - - case IMG_RECTANGLE_ID: - { - if (OpSize >= sizeof(IMG_OP_LINE)) - { - IMG_OP_RECT * pL = &(pImage->Rect); - cCmdDrawRect( - (SWORD)(cCmdResolveValue(pL->Pt.X)+Pt.X), - (SWORD)(cCmdResolveValue(pL->Pt.Y)+Pt.Y), - (SWORD)(cCmdResolveValue(pL->Width)), - (SWORD)(cCmdResolveValue(pL->Height)) - ); - } - } - break; - - case IMG_PIXEL_ID: - { - if (OpSize >= sizeof(IMG_OP_PIXEL)) - { - cCmdSetPixel( - (cCmdResolveValue(pImage->Pixel.Pt.X) + Pt.X), - (cCmdResolveValue(pImage->Pixel.Pt.Y) + Pt.Y), - TRUE); - } - } - break; - - case IMG_NUMBOX_ID: - { - if (OpSize >= sizeof(IMG_OP_NUMBOX)) - { - UBYTE NumStr[20]; - IMG_OP_NUMBOX * pNB = &(pImage->NumBox); - sprintf((PSZ)NumStr, "%d", cCmdResolveValue(pNB->Value)); - cCmdDrawString( - NumStr, - (UBYTE) (cCmdResolveValue(pNB->Pt.X) + Pt.X), - (UBYTE) (cCmdResolveValue(pNB->Pt.Y) + Pt.Y)); - } - } - break; - - case IMG_DESCRIPTION_ID: - { - //No-op - } - break; - - default: - { - //Unrecognized opcode, pass an error back to the user. - DStatus = ERR_FILE; - } - break; - } - - DataSize -= OpSize; - pImage = (IMG_OP_UNION*) ((UBYTE*)pImage + OpSize); - } - - pMapDisplay->UpdateMask |= SCREEN_BIT(SCREEN_BACKGROUND); - } - - // Set return value, close file and return - *pReturnVal = DStatus; - pMapLoader->pFunc(CLOSE, &ImageHandle, NULL, NULL); - return (NO_ERR); -} - -//----------------------------------------------------------------- -// cCmdDrawLine - draw a line. All clipping is done by the set pixel function. -void cCmdDrawLine( - SLONG x1, - SLONG y1, - SLONG x2, - SLONG y2) -{ - SLONG d,x,y,ax,ay,sx,sy,dx,dy; - - // Initialize variables - dx = x2-x1; ax = ABS(dx)<<1; sx = SGN(dx); - dy = y2-y1; ay = ABS(dy)<<1; sy = SGN(dy); - x = x1; - y = y1; - if (ax>ay) - { /* x dominant */ - d = ay-(ax>>1); - for (;;) - { - cCmdSetPixel(x, y, TRUE); - if (x==x2) - return; - if (d>=0) - { - y += sy; - d -= ax; - } - x += sx; - d += ay; - } - } - else - { /* y dominant */ - d = ax-(ay>>1); - for (;;) - { - cCmdSetPixel(x, y, TRUE); - if (y==y2) - return; - if (d>=0) - { - x += sx; - d -= ay; - } - y += sy; - d += ax; - } - } -} - - -//----------------------------------------------------------------- -// cCmdDrawRect - draw a rectangle. All clipping is done by the set pixel function. -void cCmdDrawRect( - SLONG left, - SLONG bottom, - SLONG width, - SLONG height) -{ - SLONG right = left + width; - SLONG top = bottom + height; - - // Draw the four line segments - cCmdDrawLine(left, top, right, top); - cCmdDrawLine(right, top, right, bottom); - cCmdDrawLine(right, bottom, left, bottom); - cCmdDrawLine(left, bottom, left, top); -} - - -#ifndef DISPLAY_REALWIDTH - #define DISPLAY_REALWIDTH DISPLAY_WIDTH -#endif -//----------------------------------------------------------------- -//cCmdCopyBitMapBits -void cCmdCopyBitMapBits( - SLONG dst_x, // left pixel on LCD - SLONG dst_y, // bottom pixel on LCD - SLONG src_x, // starting pixel x coordinate from source map - SLONG src_y, // starting pixel y coordinate from source map - SLONG src_width, // width in pixels to the right (negative implies to the left) - SLONG src_height, // height in pixels down (negative implies down) - IMG_OP_SPRITE * pSprite) -{ - SLONG dy; // Location in the destination pixmap , the screen that is - SLONG sx; - SLONG sy; // Location in the source pixmap. - SLONG trim, last_x, last_y, rowbytes; - UBYTE *pSrcByte; - UBYTE *pDstBytes; - UBYTE *pDstByte, *pFirstDstByte; - UBYTE *pLastDstByte; - UBYTE bit_y, not_bit_y; - UBYTE masks[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; - - // Data in the image file is row major 8 pixels per byte.top row first. - // src and dst coordinates treat the bottom left most pixel as (0,0) - - if (!pSprite || pSprite->OpCode!=IMG_SPRITE_ID) - return; - - pDstBytes = DISP_BUFFER_P; - - // Clip the edges. Modify the source and width as well. - if (dst_x < 0) { // bounds check start of x - trim = (0 - dst_x); - dst_x = 0; - src_x += trim; - src_width -= trim; - } - - last_x = dst_x + src_width; - if (last_x > DISPLAY_WIDTH) // bound check end of x - last_x = DISPLAY_WIDTH; - - if (dst_y < 0) { // bound check start of y - trim = (0 - dst_y); - dst_y = 0; - src_y += trim; // fix up source as well since we are clipping the start of the loop - src_height -= trim; - } - - last_y = dst_y + src_height; - if (last_y > DISPLAY_HEIGHT) // bound check end of y - last_y = DISPLAY_HEIGHT; - - // Convert the 0,0 bottom left origin to the top left 0,0 used by the actual - // buffer - last_y = TRANSLATE_Y(last_y); - dst_y = TRANSLATE_Y(dst_y); - - // The last row is the top most scan line in the LCD Buffer - // so limit if the copy would copy into memory before the buffer. - // The first row copied will be the one closest to the bottom of the LCD - // If that is off screen then limit as well and adjust the start point on the start - - // Copy bits top to top moving down. - sy = src_y; - rowbytes = pSprite->RowBytes; - - pSrcByte = pSprite->Bytes + ((pSprite->Rows - 1 - sy) * rowbytes); - pFirstDstByte = pDstBytes + ((dst_y >> 3) * DISPLAY_REALWIDTH) + dst_x; - for (dy = dst_y; dy > last_y; dy--) - { - sx = src_x; - bit_y = masks[7 - (dy & 0x07)]; - not_bit_y = ~ bit_y; - pDstByte = pFirstDstByte; - pLastDstByte = pDstByte + (last_x - dst_x); - for (; pDstByte < pLastDstByte; pDstByte++) - { - if ( *(pSrcByte + (sx >> 3)) & masks[sx & 0x07] ){ - *pDstByte |= bit_y; - } else { - *pDstByte &= not_bit_y; - } - sx ++; - } - pSrcByte -= rowbytes; - sy ++; - if ((dy & 0x07) == 0) // bump back the scan line start point at rollover - pFirstDstByte -= DISPLAY_REALWIDTH; - } - -} - -//----------------------------------------------------------------- -// cCmdSetPixel - Set or clear a pixel based on Val -void cCmdSetPixel(SLONG X, SLONG Y, ULONG Val) -{ - Y = TRANSLATE_Y(Y); - - pMapDisplay->pFunc(DISPLAY_PIXEL, (UBYTE)Val, (UBYTE)X, (UBYTE)Y, 0, 0); -} - - -//----------------------------------------------------------------- -//cCmdWrapSetScreenMode -//ArgV[0]: (Function return) Status code, SBYTE -//ArgV[1]: ScreenMode ULONG -NXT_STATUS cCmdWrapSetScreenMode(UBYTE * ArgV[]) -{ - ULONG ScreenMode = (ULONG)(*ArgV[1]); - if (ScreenMode == RESTORE_NXT_SCREEN) { - cCmdRestoreDefaultScreen(); - } - - // Set return value - *(SBYTE*)(ArgV[0]) = NO_ERR; - return NO_ERR; -} - -//------------------------------------------------------------------ -// cCmdClearScreenIfNeeded - Clear entire sceen buffer if explicitly requested or implicitly required. -void cCmdClearScreenIfNeeded(ULONG DrawOptions) -{ - //If we are the first drawing command, clear the screen and record that we've done so - if (VarsCmd.DirtyDisplay == FALSE) - { - VarsCmd.DirtyDisplay = TRUE; - pMapUi->Flags &= ~UI_ENABLE_STATUS_UPDATE; - - //Override DrawOptions because we have to clear anyway - DrawOptions = DRAW_OPT_CLEAR_WHOLE_SCREEN; - } - - if (DRAW_OPT_CLEAR_MODE(DrawOptions)) - { - pMapDisplay->pFunc(DISPLAY_ERASE_ALL, 0, 0, 0, 0, 0); - - //Clear UpdateMask to kill any pending updates - pMapDisplay->UpdateMask = 0; - } - - return; -} - -//------------------------------------------------------------------ -// cCmdDrawString - Draw string to display buffer -// Properly uses 'Normal' display buffer to avoid conflicts with popup buffer -// Clips text at bottom and right hand edges of the screen buffer -//!!! Function copied and modified from cDisplayString -void cCmdDrawString(UBYTE *pString, ULONG X, ULONG Y) -{ - UBYTE *pSource; - UBYTE *pDestination; - FONT *pFont; - ULONG FontWidth; - ULONG Items; - ULONG Item; - ULONG Line; - - //Get current font information - pFont = pMapDisplay->pFont; - Items = pFont->ItemsX * pFont->ItemsY; - - //Invert Y coordinate to match display buffer - Y = TRANSLATE_Y(Y); - Line = (Y & 0xF8) / 8; - - //If text line is out of bounds, do nothing. - if (Line >= TEXTLINES) - return; - - //Calculate pointer to first byte of drawing destination - pDestination = &(DISP_BUFFER_P[Line * DISPLAY_WIDTH + X]); - - while (*pString) - { - FontWidth = pFont->ItemPixelsX; - //Calculate X coordinate of the right edge of this character. - //If it will extend past the right edge, clip the string. - X += FontWidth; - if (X >= DISPLAY_WIDTH) - break; - - //If Item is defined by the font, display it. Else, ignore it. - Item = *pString - ' '; - if (Item < Items) - { - pSource = (UBYTE*)&(pFont->Data[Item * FontWidth]); - while (FontWidth--) - { - *pDestination = *pSource; - pDestination++; - pSource++; - } - } - pString++; - } -} - -//------------------------------------------------------------------ -// cCmdRestoreDefaultScreen - Restore to Default 'Running' screen -void cCmdRestoreDefaultScreen(void) -{ - //If this program has taken over the display, reset it for the UI - if (VarsCmd.DirtyDisplay == TRUE) - { - VarsCmd.DirtyDisplay = FALSE; - - pMapDisplay->pFunc(DISPLAY_ERASE_ALL, 0, 0, 0, 0, 0); - pMapDisplay->UpdateMask = SCREEN_BIT(SCREEN_BACKGROUND); - - pMapUi->Flags |= UI_ENABLE_STATUS_UPDATE | UI_REDRAW_STATUS; - } -} diff --git a/AT91SAM7S256/Source/c_comm.c b/AT91SAM7S256/Source/c_comm.c deleted file mode 100644 index 176a1ff..0000000 --- a/AT91SAM7S256/Source/c_comm.c +++ /dev/null @@ -1,3714 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date: 8-09-08 14:11 $ -// -// Filename $Workfile:: c_comm.c $ -// -// Version $Revision: 7 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_comm $ -// -// Platform C -// - -#include "stdconst.h" -#include "modules.h" -#include "c_comm.iom" -#include "c_loader.iom" -#include "c_ioctrl.iom" -#include "c_ui.iom" -#include "c_cmd.iom" -#include "c_display.iom" -#include "c_comm.h" -#include "d_usb.h" -#include "d_hispeed.h" -#include "d_bt.h" -#include -#include -#ifdef ARMDEBUG -#include "debug_stub.h" -#endif - -enum -{ - DEVICE_VERIFIED, - DEVICE_UPDATED, - DEVICE_INSERTED -}; - -#define DEFAULTBTADR "\x00\x16\x53\xFF\xFF\xFF" -#define BTSTREAMTOUT 610 - -#define LOOKUPNO 3 - -#define CLEARExtMode {\ - UBYTE Tmp;\ - for(Tmp = 0; Tmp < NO_OF_CHANNELS; Tmp++)\ - {\ - VarsComm.ExtMode[Tmp].Status = FALSE;\ - }\ - } - -#define CHNumber(Bit) (Bit>>1) -#define SETBtStateIdle VarsComm.ActiveUpdate = UPD_IDLE;\ - VarsComm.UpdateState = 0;\ - VarsComm.StreamStateCnt = 0;\ - VarsComm.CmdSwitchCnt = 0;\ - VarsComm.CloseConn0Cnt = 0;\ - VarsComm.DiscAllCnt = 0;\ - VarsComm.ResetBtCnt = 0 - -#define SETBtCmdState VarsComm.BtState = BT_ARM_CMD_MODE;\ - IOMapComm.BtInBuf.InPtr = 0;\ - CLEARExtMode;\ - dBtClearArm7CmdSignal();\ - dBtInitReceive(VarsComm.BtModuleInBuf.Buf, (UBYTE)CMD_MODE); - -#define SETBtDataState IOMapComm.BtInBuf.InPtr = 0;\ - VarsComm.BtState = BT_ARM_DATA_MODE;\ - dBtClearTimeOut(); /* stop cmd timeout because in datamode */\ - dBtSetArm7CmdSignal();\ - dBtInitReceive(VarsComm.BtModuleInBuf.Buf, (UBYTE)STREAM_MODE) - -#define SETBtOff VarsComm.BtState = BT_ARM_OFF;\ - dBtSetBcResetPinLow() - -#define CLEARConnEntry(Index) memset((IOMapComm.BtConnectTable[Index].BdAddr), 0, SIZE_OF_BDADDR);\ - memset(IOMapComm.BtConnectTable[Index].Name, 0, SIZE_OF_BT_NAME);\ - memset((IOMapComm.BtConnectTable[Index].ClassOfDevice), 0, SIZE_OF_CLASS_OF_DEVICE);\ - memset((IOMapComm.BtConnectTable[Index].PinCode), 0, SIZE_OF_BT_PINCODE);\ - IOMapComm.BtConnectTable[Index].HandleNr = BLUETOOTH_HANDLE_UNDEFIEND;\ - IOMapComm.BtConnectTable[Index].StreamStatus = 0;\ - IOMapComm.BtConnectTable[Index].LinkQuality = 0 - -#define FILETXTOUT 30000 - -const UBYTE BootString[] = {"Let's dance: SAMBA"}; -const UBYTE NoName[SIZE_OF_BT_NAME] = {"No Name"}; - -static IOMAPCOMM IOMapComm; -static VARSCOMM VarsComm; -static HEADER **pHeaders; - -const HEADER cComm = -{ - 0x00050001L, - "Comm", - cCommInit, - cCommCtrl, - cCommExit, - (void *)&IOMapComm, - (void *)&VarsComm, - (UWORD)sizeof(IOMapComm), - (UWORD)sizeof(VarsComm), - 0x0000 /* Code size - not used so far */ -}; - -UWORD cCommReceivedBtData(void); -void cCommBtCmdInterpreter(void); -UWORD cCommInterprete(UBYTE *pInBuf, UBYTE *pOutBuf, UBYTE *pLength, UBYTE CmdBit, UWORD MsgLength); -UWORD cCommInterpreteCmd(UBYTE Cmd, UBYTE *pInBuf, UBYTE *pOutBuf, UBYTE *pLength, UBYTE CmdBit, UWORD MsgLength); -void cCommCpyToUpper(UBYTE *pDst, UBYTE *pSrc, UBYTE Length); -void cCommCopyFileName(UBYTE *pDst, UBYTE *pSrc); -void cCommSendHiSpeedData(void); -void cCommReceivedHiSpeedData(void); -UWORD cCommReq(UBYTE Cmd, UBYTE Param1, UBYTE Param2, UBYTE Param3, UBYTE *pName, UWORD *pRetVal); -UBYTE cCommBtValidateCmd(void); - -void cCommClearStreamStatus(void); -void cCommUpdateBt(void); -UWORD cCommCopyBdaddr(UBYTE *pDst, UBYTE *pSrc); -UWORD cCommInsertBtName(UBYTE *pDst, UBYTE *pSrc); -UWORD cCommCheckBdaddr(UBYTE *pAdr, UBYTE *pSrc); -UWORD cCommInsertDevice(UBYTE *pBdaddr, UBYTE *pName, UBYTE *pCod, UBYTE DeviceStatus, UBYTE *pAddInfo); -void cCommsSetCmdMode(UBYTE *pNextState); -void cCommsOpenStream(UBYTE *pNextState); -void cCommsCloseConn0(UBYTE *pNextState); -void cCommsDisconnectAll(UBYTE *pNextState); -void cCommsBtReset(UBYTE *pNextState); -void cCommPinCode(UBYTE *pPinCode); -void cCommClrConnTable(void); -SBYTE cCommSearchBTDevTableForName(UBYTE*); - -void cCommInit(void* pHeader) -{ - UBYTE Tmp; - - pHeaders = pHeader; - IOMapComm.pFunc = &cCommReq; - IOMapComm.pFunc2 = &cCommPinCode; - IOMapComm.UsbState = FALSE; - IOMapComm.UsbOutBuf.OutPtr = 0; - - CLEARExtMode; - - dUsbInit(); - dBtInit(); - - SETBtStateIdle; - VarsComm.BtModuleInBuf.InPtr = 0; - VarsComm.BtWaitTimeCnt = 0; - - /* Force a reset sequence on the BC4 */ - VarsComm.pRetVal = &(VarsComm.RetVal); - VarsComm.ActiveUpdate = UPD_RESET; - - VarsComm.BtState = BT_ARM_CMD_MODE; - IOMapComm.BrickData.BtHwStatus = BT_DISABLE; - - for (Tmp = 0; Tmp < SIZE_OF_BT_DEVICE_TABLE; Tmp++) - { - IOMapComm.BtDeviceTable[Tmp].DeviceStatus = BT_DEVICE_EMPTY; - } - IOMapComm.BtDeviceCnt = 0; - IOMapComm.BrickData.BtStateStatus = 0; - - cCommClrConnTable(); - - dBtInitReceive(VarsComm.BtModuleInBuf.Buf, (UBYTE)CMD_MODE); - dBtStartADConverter(); - - dHiSpeedInit(); - VarsComm.HsState = 0; - - IOMapComm.UsbPollBuf.InPtr = 0; - IOMapComm.UsbPollBuf.OutPtr = 0; - - VarsComm.BtAdrStatus = COLDBOOT; -} - -void cCommCtrl(void) -{ - - if (FALSE == cCommReceivedBtData()) - { - - /* there has been a timeout on the BC4 channel */ - SETBtStateIdle; - *(VarsComm.pRetVal) = BTTIMEOUT; - if (COLDBOOT == VarsComm.BtAdrStatus) - { - - /* there is an BT fatal error - set default bt adr and name*/ - strcpy((char*)IOMapComm.BrickData.Name, (char*)UI_NAME_DEFAULT); - dUsbStoreBtAddress((UBYTE*)DEFAULTBTADR); - pMapUi->Flags |= UI_REDRAW_STATUS; - dBtSetBcResetPinLow(); - VarsComm.BtAdrStatus = BTADRERROR; - } - } - cCommUpdateBt(); - VarsComm.BtBcPinLevel = dBtGetBc4CmdSignal(); - - if (UPD_IDLE == VarsComm.ActiveUpdate) - { - switch (VarsComm.BtState) - { - - /* Bluetooth device can either be in CMD, DATA or OFF state at top level */ - case BT_ARM_OFF: - { - } - break; - case BT_ARM_CMD_MODE: - { - if (VarsComm.BtBcPinLevel) - { - SETBtDataState; - } - } - break; - - case BT_ARM_DATA_MODE: - { - if (!(VarsComm.BtBcPinLevel)) - { - SETBtCmdState; - } - } - break; - } - } - IOMapComm.BtInBuf.Buf[BT_CMD_BYTE] = 0; - - - /* Here comes the the HIGHSPEED_PORT implementation */ - if (IOMapComm.HsFlags & HS_UPDATE) - { - IOMapComm.HsFlags &= ~HS_UPDATE; - switch (IOMapComm.HsState) - { - case HS_INITIALISE: - { - dHiSpeedSetupUart(); - IOMapComm.HsState = HS_INIT_RECEIVER; - IOMapComm.HsFlags |= HS_UPDATE; - } - break; - - case HS_INIT_RECEIVER: - { - dHiSpeedInitReceive(VarsComm.HsModuleInBuf.Buf); - VarsComm.HsState = 0x01; - } - break; - - case HS_SEND_DATA: - { - cCommSendHiSpeedData(); - } - break; - - case HS_DISABLE: - { - VarsComm.HsState = 0x00; - dHiSpeedExit(); - } - break; - } - } - - if (VarsComm.HsState != 0) - { - cCommReceivedHiSpeedData(); - } - - /* Here comes the the USB implementation */ - ULONG Length; - UWORD Status; - - if (0 != IOMapComm.UsbOutBuf.OutPtr) - { - dUsbWrite((const UBYTE *)IOMapComm.UsbOutBuf.Buf, (ULONG)IOMapComm.UsbOutBuf.OutPtr); - IOMapComm.UsbOutBuf.OutPtr = 0; - } - - Length = 0; - - if (TRUE == dUsbCheckConnection()) - { - pMapUi->UsbState = 1; - if (TRUE == dUsbIsConfigured()) - { - Length = dUsbRead(IOMapComm.UsbInBuf.Buf, sizeof(IOMapComm.UsbInBuf.Buf)); - IOMapComm.UsbState = TRUE; - pMapUi->UsbState = 2; - } - } - else - { - pMapUi->UsbState = 0; - dUsbResetConfig(); - if (TRUE == IOMapComm.UsbState) - { - IOMapComm.UsbState = FALSE; - Status = dUsbGetFirstHandle(); - while(0 == LOADER_ERR(Status)) - { - IOMapComm.UsbInBuf.Buf[0] = LOADER_HANDLE(Status); - pMapLoader->pFunc(CLOSE, &(IOMapComm.UsbInBuf.Buf[0]), &(IOMapComm.UsbInBuf.Buf[2]), &Length); - dUsbRemoveHandle(IOMapComm.UsbInBuf.Buf[0]); - Status = dUsbGetNextHandle(); - } - } - } - - if (0 != Length) - { - cCommInterprete(IOMapComm.UsbInBuf.Buf, IOMapComm.UsbOutBuf.Buf, (UBYTE*)&Length, USB_CMD_READY, (UWORD)Length); - if (Length) - { - dUsbWrite((const UBYTE *)IOMapComm.UsbOutBuf.Buf, Length); - } - } - dBtStartADConverter(); -} - -void cCommExit(void) -{ - dUsbExit(); - dHiSpeedExit(); - dBtExit(); -} - - -UBYTE cCommCheckSysFileType(UBYTE *pName) -{ - UBYTE RtnVal; - UBYTE TmpFilename[FILENAME_LENGTH + 1]; - - RtnVal = FALSE; - cCommCpyToUpper(TmpFilename, &pName[1], (UBYTE)(FILENAME_LENGTH + 1)); - if ((0 != strstr((PSZ)(TmpFilename), ".RXE")) || - (0 != strstr((PSZ)(TmpFilename), ".SYS")) || - (0 != strstr((PSZ)(TmpFilename), ".RTM"))) - { - RtnVal = TRUE; - } - return(RtnVal); -} - - -UWORD cCommInterprete(UBYTE *pInBuf, UBYTE *pOutBuf, UBYTE *pLength, UBYTE CmdBit, UWORD MsgLength) -{ - UWORD ReturnStatus; - UBYTE Channel; - - Channel = CHNumber(CmdBit); - if (FALSE == VarsComm.ExtMode[Channel].Status) - { - - switch (((pInBuf[0]) & ~NO_REPLY_BIT)) - { - case SYSTEM_CMD: - { - ReturnStatus = cCommInterpreteCmd(pInBuf[1], &(pInBuf[1]), &(pOutBuf[2]), pLength, CmdBit, MsgLength); - - /* Check if reply is requested */ - if ((pInBuf[0]) & NO_REPLY_BIT) - { - - /* Sender has choosen no reply */ - *pLength = 0; - - /* if extended mode then remember the reply bit */ - VarsComm.ExtMode[Channel].Type |= NO_REPLY_BIT; - } - else - { - - /* Check if receiver wants to reply */ - if (*pLength) - { - (*pLength)+= 2; - pOutBuf[0] = REPLY_CMD; - pOutBuf[1] = pInBuf[1]; - } - } - } - break; - - case DIRECT_CMD: - { - - /* Adjust length to account for cmd type byte */ - (*pLength) -= 1; - - /* If no reply requested, pass NULL output buffer pointer and clear *pLength */ - if ((pInBuf[0]) & NO_REPLY_BIT) - { - pMapCmd->pRCHandler(&(pInBuf[0]), NULL, pLength); - } - else - { - pMapCmd->pRCHandler(&(pInBuf[0]), &(pOutBuf[2]), pLength); - if (*pLength) - { - (*pLength) += 2; - pOutBuf[0] = REPLY_CMD; - pOutBuf[1] = pInBuf[1]; - } - } - } - break; - - case REPLY_CMD: - { - - /* If this is a reply to a direct command opcode, pRCHandler will handle it */ - if (pInBuf[1] < NUM_RC_OPCODES) - pMapCmd->pRCHandler(&(pInBuf[0]), NULL, pLength); - - /* No Reply ever required on REPLY_CMD messages */ - *pLength = 0; - } - break; - -#ifdef ARMDEBUG - case DEBUG_CMD: - { - ReturnStatus = cCommHandleDebug(&(pInBuf[0]), CmdBit, MsgLength); /* Pass everything (incl. message command byte) to function */ - /* Check that Debug Command does not expect reply */ - ReturnStatus = (0 == ((pInBuf[0]) & NO_REPLY_BIT)); - *pLength = 0; - } - break; -#endif - - default: - { - - /* UNSUPPORTED - don't reply on these messages */ - *pLength = 0; - } - break; - } - - } - else - { - switch (VarsComm.ExtMode[Channel].Type & ~NO_REPLY_BIT) - { - case SYSTEM_CMD: - { - ReturnStatus = cCommInterpreteCmd(VarsComm.ExtMode[Channel].Cmd, &(pInBuf[0]), &(pOutBuf[2]), pLength, CmdBit, MsgLength); - if ((VarsComm.ExtMode[Channel].Type) & NO_REPLY_BIT) - { - - /* Sender has choosen no reply */ - *pLength = 0; - } - else - { - - /* Check if receiver wants to reply */ - if (*pLength) - { - (*pLength) += 2; - pOutBuf[0] = REPLY_CMD; - pOutBuf[1] = VarsComm.ExtMode[Channel].Cmd; - } - } - } - break; - case DIRECT_CMD: - { - } - break; - case REPLY_CMD: - { - } - break; - default: - { - } - break; - } - } - - return(ReturnStatus); -} - - -UWORD cCommInterpreteCmd(UBYTE Cmd, UBYTE *pInBuf, UBYTE *pOutBuf, UBYTE *pLength, UBYTE CmdBit, UWORD MsgLength) -{ - ULONG FileLength; - UWORD Status; - UBYTE Channel; - - Channel = CHNumber(CmdBit); - switch(Cmd) - { - case OPENWRITE: - { - FileLength = pInBuf[21]; - FileLength += (ULONG)pInBuf[22] << 8; - FileLength += (ULONG)pInBuf[23] << 16; - FileLength += (ULONG)pInBuf[24] << 24; - - if(TRUE == cCommCheckSysFileType(&pInBuf[1])) - { - Status = pMapLoader->pFunc(OPENWRITELINEAR, &pInBuf[1], NULL, &FileLength); - } - else - { - Status = pMapLoader->pFunc(OPENWRITE, &pInBuf[1], NULL, &FileLength); - } - pOutBuf[0] = LOADER_ERR_BYTE(Status); - pOutBuf[1] = LOADER_HANDLE(Status); - *pLength = 2; - if ((SUCCESS == LOADER_ERR(Status)) && (CmdBit & USB_CMD_READY)) - { - dUsbInsertHandle(LOADER_HANDLE(Status)); - } - } - break; - case WRITE: - { - - if (FALSE == VarsComm.ExtMode[Channel].Status) - { - - FileLength = *pLength - 3; - Status = pMapLoader->pFunc(WRITE, &(pInBuf[1]), &(pInBuf[2]), &FileLength); - pOutBuf[2] = (UBYTE)(FileLength); - pOutBuf[3] = (UBYTE)(FileLength >> 8); - if ((*pLength != MsgLength) && (MsgLength != 0)) - { - - /* This is the beginnig of and extended write command*/ - VarsComm.ExtMode[Channel].Cmd = WRITE; - VarsComm.ExtMode[Channel].Type = SYSTEM_CMD; - VarsComm.ExtMode[Channel].Status = TRUE; - VarsComm.ExtMode[Channel].Handle = LOADER_HANDLE(Status); - *pLength = 0; - } - else - { - - /* Normal write */ - pOutBuf[0] = LOADER_ERR_BYTE(Status); - pOutBuf[1] = LOADER_HANDLE(Status); - *pLength = 4; - } - } - else - { - UWORD TmpLen; - FileLength = *pLength; - Status = pMapLoader->pFunc(WRITE, &(VarsComm.ExtMode[Channel].Handle), &(pInBuf[0]), &FileLength); - TmpLen = pOutBuf[3]; - TmpLen <<= 8; - TmpLen |= pOutBuf[2]; - TmpLen += FileLength; - pOutBuf[2] = (UBYTE)(TmpLen); - pOutBuf[3] = (UBYTE)(TmpLen >> 8); - if (MsgLength) - { - - /* Don't answer before complete message has been received */ - *pLength = 0; - } - else - { - - /* Complete msg has been received */ - VarsComm.ExtMode[Channel].Status = FALSE; - pOutBuf[0] = LOADER_ERR_BYTE(Status); - pOutBuf[1] = LOADER_HANDLE(Status); - *pLength = 4; /* Remember the 2 length bytes */ - - } - } - - } - break; - case OPENWRITEDATA: - { - FileLength = pInBuf[21]; - FileLength += (ULONG)pInBuf[22] << 8; - FileLength += (ULONG)pInBuf[23] << 16; - FileLength += (ULONG)pInBuf[24] << 24; - - if(TRUE == cCommCheckSysFileType(&pInBuf[1])) - { - Status = ILLEGALFILENAME; - } - else - { - Status = pMapLoader->pFunc(OPENWRITEDATA, &pInBuf[1], NULL, &FileLength); - } - pOutBuf[0] = LOADER_ERR_BYTE(Status); - pOutBuf[1] = LOADER_HANDLE(Status); - *pLength = 2; - if ((SUCCESS == LOADER_ERR(Status)) && (CmdBit & USB_CMD_READY)) - { - dUsbInsertHandle(LOADER_HANDLE(Status)); - } - } - break; - case OPENAPPENDDATA: - { - Status = pMapLoader->pFunc(OPENAPPENDDATA, &pInBuf[1], NULL, &FileLength); - pOutBuf[0] = LOADER_ERR_BYTE(Status); - pOutBuf[1] = LOADER_HANDLE(Status); - - pOutBuf[2] = (UBYTE)FileLength; - pOutBuf[3] = (UBYTE)(FileLength >> 8); - pOutBuf[4] = (UBYTE)(FileLength >> 16); - pOutBuf[5] = (UBYTE)(FileLength >> 24); - *pLength = 6; - if ((SUCCESS == LOADER_ERR(Status)) && (CmdBit & USB_CMD_READY)) - { - dUsbInsertHandle(LOADER_HANDLE(Status)); - } - } - break; - case CLOSE: - { - if (CmdBit & USB_CMD_READY) - { - dUsbRemoveHandle(pInBuf[1]); - } - Status = pMapLoader->pFunc(CLOSE, &(pInBuf[1]), NULL, &FileLength); - pOutBuf[0] = LOADER_ERR_BYTE(Status); - pOutBuf[1] = LOADER_HANDLE(Status); - *pLength = 2; - } - break; - case CROPDATAFILE: - { - Status = pMapLoader->pFunc(CROPDATAFILE, &(pInBuf[1]), NULL, &FileLength); - pOutBuf[0] = LOADER_ERR_BYTE(Status); - pOutBuf[1] = LOADER_HANDLE(Status); - *pLength = 2; - } - break; - case OPENREAD: - { - Status = pMapLoader->pFunc(OPENREAD, &pInBuf[1], NULL, &FileLength); - pOutBuf[0] = LOADER_ERR_BYTE(Status); - pOutBuf[1] = LOADER_HANDLE(Status); - pOutBuf[2] = (UBYTE)FileLength; - pOutBuf[3] = (UBYTE)(FileLength >> 8); - pOutBuf[4] = (UBYTE)(FileLength >> 16); - pOutBuf[5] = (UBYTE)(FileLength >> 24); - *pLength = 6; - if ((SUCCESS == LOADER_ERR(Status)) && (CmdBit & USB_CMD_READY)) - { - dUsbInsertHandle(LOADER_HANDLE(Status)); - } - } - break; - case READ: - { - ULONG Length; - - FileLength = pInBuf[3]; - FileLength <<= 8; - FileLength |= pInBuf[2]; - Length = FileLength; - - /* Here test for channel - USB can only handle a 64 byte return (- wrapping )*/ - if (CmdBit & USB_CMD_READY) - { - if (FileLength > (SIZE_OF_USBBUF - 6)) - { - - /* Buffer cannot hold the requested data adjust to buffer size */ - FileLength = (SIZE_OF_USBBUF - 6); - } - *pLength = FileLength + 4; - Status = pMapLoader->pFunc(READ, &pInBuf[1], &pOutBuf[4], &FileLength); - pOutBuf[0] = LOADER_ERR_BYTE(Status); - pOutBuf[1] = LOADER_HANDLE(Status); - pOutBuf[2] = (UBYTE)Length; - pOutBuf[3] = (UBYTE)(Length >> 8); - - if (FileLength < Length) - { - - /* End of file is detcted - add up with zeros to the requested msg length */ - Length -= FileLength; - memset(&(pOutBuf[(FileLength + 4)]),0x00,Length); - } - } - else - { - - /* This is a BT request - BT can handle large packets */ - if (FileLength > (SIZE_OF_BTBUF - 6)) - { - - /* Read length exceeds buffer length check for extended read back */ - if (SUCCESS == cCommReq(EXTREAD, 0x00, 0x00, 0x00, NULL, &(VarsComm.RetVal))) - { - - /* More data requested than buffer can hold .... go into extended mode */ - VarsComm.ExtTx.RemMsgSize = FileLength; - VarsComm.ExtTx.SrcHandle = pInBuf[1]; - VarsComm.ExtTx.Cmd = READ; - *pLength = 0; - } - else - { - - /* We were not able to go into extended mode bt was busy */ - /* for now do not try to reply as it is not possible to */ - /* return the requested bytes */ - *pLength = 0; - } - } - else - { - - *pLength = FileLength + 4; - Status = pMapLoader->pFunc(READ, &pInBuf[1], &pOutBuf[4], &FileLength); - pOutBuf[0] = LOADER_ERR_BYTE(Status); - pOutBuf[1] = LOADER_HANDLE(Status); - pOutBuf[2] = (UBYTE)Length; - pOutBuf[3] = (UBYTE)(Length >> 8); - - if (FileLength < Length) - { - - /* End of file is detcted - add up with zeros to the requested msg length */ - Length -= FileLength; - memset(&(pOutBuf[(FileLength + 4)]),0x00,Length); - } - } - } - } - break; - case DELETE: - { - Status = pMapLoader->pFunc(DELETE, &pInBuf[1], NULL, &FileLength); - pOutBuf[0] = LOADER_ERR_BYTE(Status); - cCommCopyFileName(&pOutBuf[1], &pInBuf[1]); - *pLength = FILENAME_LENGTH + 1 + 1; /*Filemname + 0 terminator + error byte */ - } - break; - case FINDFIRST: - { - Status = pMapLoader->pFunc(FINDFIRST, &(pInBuf[1]), &(pOutBuf[2]), &FileLength); - pOutBuf[0] = LOADER_ERR_BYTE(Status); - pOutBuf[1] = LOADER_HANDLE(Status); - if (LOADER_ERR_BYTE(SUCCESS) == pOutBuf[0]) - { - pOutBuf[22] = (UBYTE)FileLength; - pOutBuf[23] = (UBYTE)(FileLength >> 8); - pOutBuf[24] = (UBYTE)(FileLength >> 16); - pOutBuf[25] = (UBYTE)(FileLength >> 24); - if (CmdBit & USB_CMD_READY) - { - dUsbInsertHandle(pOutBuf[1]); - } - } - else - { - - /* ERROR - Fill with zeros */ - memset(&(pOutBuf[2]),0x00,24); - } - - *pLength = 26; - } - break; - case FINDNEXT: - { - Status = pMapLoader->pFunc(FINDNEXT, &(pInBuf[1]), &(pOutBuf[2]), &FileLength); - pOutBuf[0] = LOADER_ERR_BYTE(Status); - pOutBuf[1] = LOADER_HANDLE(Status); - if (LOADER_ERR_BYTE(SUCCESS) == pOutBuf[0]) - { - pOutBuf[22] = (UBYTE)FileLength; - pOutBuf[23] = (UBYTE)(FileLength >> 8); - pOutBuf[24] = (UBYTE)(FileLength >> 16); - pOutBuf[25] = (UBYTE)(FileLength >> 24); - } - else - { - - /* ERROR - Fill with zeros */ - memset(&(pOutBuf[2]),0x00,24); - } - *pLength = 26; - } - break; - case OPENREADLINEAR: - { - - /* For internal use only */ - } - break; - case VERSIONS: - { - pOutBuf[0] = LOADER_ERR_BYTE(SUCCESS); - pOutBuf[1] = (UBYTE)PROTOCOLVERSION; - pOutBuf[2] = (UBYTE)(PROTOCOLVERSION>>8); - pOutBuf[3] = (UBYTE)FIRMWAREVERSION; - pOutBuf[4] = (UBYTE)(FIRMWAREVERSION>>8); - *pLength = 5; - } - break; - case OPENWRITELINEAR: - { - FileLength = pInBuf[21]; - FileLength += (ULONG)pInBuf[22] << 8; - FileLength += (ULONG)pInBuf[23] << 16; - FileLength += (ULONG)pInBuf[24] << 24; - Status = pMapLoader->pFunc(OPENWRITELINEAR, &pInBuf[1], NULL, &FileLength); - pOutBuf[0] = LOADER_ERR_BYTE(Status); - pOutBuf[1] = LOADER_HANDLE(Status); - *pLength = 2; - if ((SUCCESS == LOADER_ERR(Status)) && (CmdBit & USB_CMD_READY)) - { - dUsbInsertHandle(LOADER_HANDLE(Status)); - } - } - break; - case FINDFIRSTMODULE: - { - Status = pMapLoader->pFunc(FINDFIRSTMODULE, &pInBuf[1], &pOutBuf[2], &FileLength); - pOutBuf[0] = LOADER_ERR_BYTE(Status); - pOutBuf[1] = 0; - - if (LOADER_ERR_BYTE(SUCCESS) != pOutBuf[0]) - { - memset(&pOutBuf[2], 0x00, 30); - } - *pLength = 32; - } - break; - - case FINDNEXTMODULE: - { - Status = pMapLoader->pFunc(FINDNEXTMODULE, pInBuf, &pOutBuf[2], &FileLength); - pOutBuf[0] = LOADER_ERR_BYTE(Status); - pOutBuf[1] = 0; - - if (LOADER_ERR_BYTE(SUCCESS) != pOutBuf[0]) - { - memset(&pOutBuf[2], 0x00, 30); - } - *pLength = 32; - } - break; - - case CLOSEMODHANDLE: - { - Status = pMapLoader->pFunc(CLOSEMODHANDLE, NULL, NULL, NULL); - pOutBuf[0] = LOADER_ERR_BYTE(Status); - pOutBuf[1] = 0; - *pLength = 2; - } - break; - - case IOMAPREAD: - { - ULONG ModuleId; - UWORD Length; - - ModuleId = pInBuf[1]; - ModuleId |= (ULONG)pInBuf[2] << 8; - ModuleId |= (ULONG)pInBuf[3] << 16; - ModuleId |= (ULONG)pInBuf[4] << 24; - - /* Transfer the Module id */ - pOutBuf[1] = pInBuf[1]; - pOutBuf[2] = pInBuf[2]; - pOutBuf[3] = pInBuf[3]; - pOutBuf[4] = pInBuf[4]; - - /* Transfer the offset into the iomap (pOutBuf[6] is intended...)*/ - pOutBuf[5] = pInBuf[5]; - pOutBuf[6] = pInBuf[6]; - - /* Get the read *pLength */ - FileLength = pInBuf[8]; - FileLength <<= 8; - FileLength |= pInBuf[7]; - - if (CmdBit & USB_CMD_READY) - { - - /* test for USB buffer overrun */ - if (FileLength > (SIZE_OF_USBBUF - 9)) - { - FileLength = SIZE_OF_USBBUF - 9; - } - } - else - { - - /* test for BT buffer overrun */ - if (FileLength > (SIZE_OF_BTBUF - 9)) - { - FileLength = SIZE_OF_BTBUF - 9; - } - } - - Length = FileLength; - *pLength = Length + 7; - Status = pMapLoader->pFunc(IOMAPREAD, (UBYTE *)&ModuleId, &pOutBuf[5], &FileLength); - - pOutBuf[0] = LOADER_ERR_BYTE(Status); - pOutBuf[5] = (UBYTE)FileLength; - pOutBuf[6] = (UBYTE)(FileLength >> 8); - - if (Length > FileLength) - { - Length -= FileLength; - memset(&(pOutBuf[FileLength + 7]), 0x00, Length); - } - } - break; - - case IOMAPWRITE: - { - ULONG ModuleId; - - pOutBuf[1] = pInBuf[1]; - pOutBuf[2] = pInBuf[2]; - pOutBuf[3] = pInBuf[3]; - pOutBuf[4] = pInBuf[4]; - - ModuleId = pInBuf[1]; - ModuleId |= (ULONG)pInBuf[2] << 8; - ModuleId |= (ULONG)pInBuf[3] << 16; - ModuleId |= (ULONG)pInBuf[4] << 24; - - FileLength = pInBuf[8]; - FileLength <<= 8; - FileLength |= pInBuf[7]; - - /* Place offset right before data */ - pInBuf[8] = pInBuf[6]; - pInBuf[7] = pInBuf[5]; - - Status = pMapLoader->pFunc(IOMAPWRITE, (UBYTE *)&ModuleId, &pInBuf[7], &FileLength); - - pOutBuf[0] = LOADER_ERR_BYTE(Status); - pOutBuf[5] = (UBYTE)FileLength; - pOutBuf[6] = (UBYTE)(FileLength >> 8); - - *pLength = 7; - } - break; - - case BOOTCMD: - { - - UBYTE Tmp; - - /* The boot command is only allowed by USB - as firmware download can ONLY */ - /* be send by USB */ - pOutBuf[0] = LOADER_ERR_BYTE(UNDEFINEDERROR); - memset(&(pOutBuf[1]), 0, 4); - *pLength = 5; - - if (CmdBit & USB_CMD_READY) - { - - Tmp = 0; - while((Tmp < (sizeof(BootString) - 1)) && (BootString[Tmp] == pInBuf[Tmp+1])) - { - Tmp++; - } - if (Tmp == (sizeof(BootString) - 1)) - { - - /* Yes valid boot sequence */ - pMapDisplay->Flags &= ~DISPLAY_ON; - pMapDisplay->Flags |= DISPLAY_REFRESH; - pMapIoCtrl->PowerOn = BOOT; - pOutBuf[0] = LOADER_ERR_BYTE(SUCCESS); - pOutBuf[1] = 'Y'; - pOutBuf[2] = 'e'; - pOutBuf[3] = 's'; - pOutBuf[4] = '\0'; - } - } - } - break; - - case SETBRICKNAME: - { - - UWORD RtnVal; - - *pLength = 1; - - /* Update the name in the BT device - reply for this command is send */ - /* before command is actually executed */ - if (SUCCESS == cCommReq(SETBTNAME, 0, 0, 0, &pInBuf[1], &RtnVal)) - { - pOutBuf[0] = LOADER_ERR_BYTE(SUCCESS); - cCommInsertBtName(IOMapComm.BrickData.Name, &pInBuf[1]); - pMapUi->Flags |= UI_REDRAW_STATUS; - } - else - { - pOutBuf[0] = LOADER_ERR_BYTE(BTBUSY); - } - } - break; - - case BTGETADR: - { - UBYTE Tmp; - UBYTE *pAdr; - - pAdr = (IOMapComm.BrickData.BdAddr); - for (Tmp = 0; Tmp < 7; Tmp++) - { - pOutBuf[Tmp + 1] = pAdr[Tmp]; - } - pOutBuf[0] = LOADER_ERR_BYTE(SUCCESS); - *pLength = 8; - } - break; - - case DEVICEINFO: - { - - pOutBuf[0] = LOADER_ERR_BYTE(SUCCESS); - - /* Brick name */ - memcpy(&(pOutBuf[1]), IOMapComm.BrickData.Name, 15); - - /* BT address */ - cCommCopyBdaddr(&(pOutBuf[16]), (IOMapComm.BrickData.BdAddr)); - - /* Link quality of the 4 possible connected devices */ - pOutBuf[23] = IOMapComm.BtConnectTable[0].LinkQuality; - pOutBuf[24] = IOMapComm.BtConnectTable[1].LinkQuality; - pOutBuf[25] = IOMapComm.BtConnectTable[2].LinkQuality; - pOutBuf[26] = IOMapComm.BtConnectTable[3].LinkQuality; - - /* Free user flash */ - memcpy(&(pOutBuf[27]), &(pMapLoader->FreeUserFlash), sizeof(pMapLoader->FreeUserFlash)); - - /* Set answer length */ - *pLength = 31; - } - break; - - case DELETEUSERFLASH: - { - Status = pMapLoader->pFunc(DELETEUSERFLASH, NULL, NULL, NULL); - pOutBuf[0] = LOADER_ERR_BYTE(SUCCESS); - *pLength = 1; - } - break; - - case POLLCMDLEN: - { - - pOutBuf[0] = LOADER_ERR_BYTE(SUCCESS); - pOutBuf[1] = pInBuf[1]; /* This is the Buf Number */ - if (0 == pInBuf[1]) - { - - /* USB poll buffer */ - pOutBuf[2] = ((IOMapComm.UsbPollBuf.InPtr - IOMapComm.UsbPollBuf.OutPtr) & (SIZE_OF_USBBUF - 1)); - } - else - { - - /* HI speed poll buffer */ - pOutBuf[2] = ((IOMapComm.HsInBuf.InPtr - IOMapComm.HsInBuf.OutPtr) & (SIZE_OF_HSBUF - 1)); - } - *pLength = 3; - } - break; - - case POLLCMD: - { - UBYTE Tmp; - UBYTE MaxBufData; - - pOutBuf[0] = LOADER_ERR_BYTE(SUCCESS); - pOutBuf[1] = pInBuf[1]; - *pLength = pInBuf[2]; - - if (CmdBit & USB_CMD_READY) - { - MaxBufData = (SIZE_OF_USBDATA - 5); /* Substract wrapping */ - } - else - { - MaxBufData = (SIZE_OF_BTBUF - 7); /* Substract wrapping + length bytes for BT*/ - } - - if (0x00 == pInBuf[1]) - { - - /* Data from USB poll buffer are requested */ - if (*pLength <= MaxBufData) - { - for (Tmp = 0; ((Tmp < (*pLength)) && (IOMapComm.UsbPollBuf.InPtr != IOMapComm.UsbPollBuf.OutPtr)); Tmp++) - { - pOutBuf[3 + Tmp] = IOMapComm.UsbPollBuf.Buf[IOMapComm.UsbPollBuf.OutPtr]; - IOMapComm.UsbPollBuf.OutPtr = ((IOMapComm.UsbPollBuf.OutPtr) + 1) % SIZE_OF_USBBUF; - } - pOutBuf[2] = Tmp; - - /* if end of buffer has been reached fill up with zeros */ - memset(&(pOutBuf[Tmp + 3]), 0x00, (*pLength - Tmp)); - } - else - { - - /* if more data requested than possible to return */ - pOutBuf[0] = LOADER_ERR_BYTE(UNDEFINEDERROR); - pOutBuf[1] = pInBuf[1]; /* This is buffer number */ - pOutBuf[2] = 0; /* no of bytes returned */ - *pLength = 0; - } - } - else - { - - /* Data from hi speed buffer are requested */ - if (*pLength <= MaxBufData) - { - for (Tmp = 0; ((Tmp < (*pLength)) && (IOMapComm.HsInBuf.InPtr != IOMapComm.HsInBuf.OutPtr)); Tmp++) - { - pOutBuf[3 + Tmp] = IOMapComm.HsInBuf.Buf[IOMapComm.HsInBuf.OutPtr]; - IOMapComm.HsInBuf.OutPtr = ((IOMapComm.HsInBuf.OutPtr) + 1) % SIZE_OF_USBBUF; - } - pOutBuf[2] = Tmp; - - /* if end of buffer has been reached fill up with zeros */ - memset(&(pOutBuf[Tmp + 3]), 0x00, (*pLength - Tmp)); - } - else - { - - /* if more data requested than possible to return */ - pOutBuf[0] = LOADER_ERR_BYTE(UNDEFINEDERROR); - pOutBuf[1] = pInBuf[1]; /* This is buffer number */ - pOutBuf[2] = 0; /* no of bytes returned */ - *pLength = 0; - } - } - (*pLength) += 3; /* Add 3 bytes for the status byte, length byte and Buf no */ - } - break; - - case BTFACTORYRESET: - { - UWORD RtnVal; - - if (CmdBit & USB_CMD_READY) - { - if (SUCCESS == cCommReq(FACTORYRESET, 0, 0, 0, NULL, &RtnVal)) - { - - /* Request success */ - pOutBuf[0] = LOADER_ERR_BYTE(SUCCESS); - } - else - { - - /* BT request error */ - pOutBuf[0] = LOADER_ERR_BYTE(UNDEFINEDERROR); - } - } - else - { - - /* Factory reset request cannot be done by bluetooth */ - pOutBuf[0] = LOADER_ERR_BYTE(UNDEFINEDERROR); - } - *pLength = 1; - } - break; - - default: - { - } - break; - } - return(Status); -} - - -UWORD cCommReceivedBtData(void) -{ - UWORD NumberOfBytes; - UWORD BytesToGo; - UWORD RtnVal; - - RtnVal = dBtReceivedData(&NumberOfBytes, &BytesToGo); - if (TRUE == RtnVal) - { - - /* Everything is fine go on */ - if (NumberOfBytes != 0) - { - - /* Copy the bytes into the IOMapBuffer */ - memcpy((IOMapComm.BtInBuf.Buf), (VarsComm.BtModuleInBuf.Buf), NumberOfBytes); - - if (VarsComm.BtState == BT_ARM_CMD_MODE) - { - - /* Call the BC4 command interpreter */ - cCommBtCmdInterpreter(); - IOMapComm.BtInBuf.InPtr = 0; - } - else - { - - /* ActiveUpdate has to be idle because BC4 can send stream data even if CMD */ - /* mode has been requested - dont try to interprete the data */ - /* VarsComm.CmdSwitchCnt != 0 if a transition to Cmd mode is in process */ - if ((VarsComm.BtState == BT_ARM_DATA_MODE) && (0 == VarsComm.CmdSwitchCnt)) - { - - /* Move the inptr ahead */ - IOMapComm.BtInBuf.InPtr = NumberOfBytes; - - /* using the outbuf inptr in order to get the number of bytes in the return answer at the right place*/ - IOMapComm.BtOutBuf.InPtr = NumberOfBytes; - - /* call the data stream interpreter */ - cCommInterprete(IOMapComm.BtInBuf.Buf, IOMapComm.BtOutBuf.Buf, &(IOMapComm.BtOutBuf.InPtr), (UBYTE) BT_CMD_READY, BytesToGo); - - /* if there is a reply to be send then send it */ - if (IOMapComm.BtOutBuf.InPtr) - { - dBtSendMsg(IOMapComm.BtOutBuf.Buf, IOMapComm.BtOutBuf.InPtr, IOMapComm.BtOutBuf.InPtr); - IOMapComm.BtOutBuf.InPtr = 0; - } - } - } - } - } - return(RtnVal); -} - -void cCommBtCmdInterpreter(void) -{ - - /* this function handles all bluecode commands that can be */ - /* initiated from the outside, meaning from other devices */ - if(cCommBtValidateCmd()) - { - switch (IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) - { - case MSG_REQUEST_PIN_CODE: - { - - /* Pass the pin request on to cCommReq it'l handle it */ - cCommReq(PINREQ, 0x00, 0x00, 0x00, NULL, &(VarsComm.RetVal)); - } - break; - - case MSG_REQUEST_CONNECTION: - { - - /* Connect request from the outside */ - cCommReq(CONNECTREQ, 0x00, 0x00, 0x00, NULL, &(VarsComm.RetVal)); - } - break; - - case MSG_LIST_RESULT: - { - switch (IOMapComm.BtInBuf.Buf[2]) - { - case LR_SUCCESS: - { - } - break; - case LR_ENTRY_REMOVED: - { - } - break; -/* - case LR_COULD_NOT_SAVE: - case LR_STORE_IS_FULL: - case LR_UNKOWN_ADDR: -*/ - default: - { - pMapUi->Error = (UBYTE)IOMapComm.BtInBuf.Buf[2]; - pMapUi->BluetoothState |= BT_ERROR_ATTENTION; - } - break; - } - } - break; - - case MSG_CLOSE_CONNECTION_RESULT: - { - UBYTE ConnNo; - - for (ConnNo = 0; ConnNo < SIZE_OF_BT_CONNECT_TABLE; ConnNo++) - { - if (IOMapComm.BtConnectTable[ConnNo].HandleNr == IOMapComm.BtInBuf.Buf[3]) - { - IOMapComm.BrickData.BtStateStatus &= ~(BT_CONNECTION_0_ENABLE<BluetoothState &= ~BT_STATE_CONNECTED; - } - pMapUi->Flags |= UI_REDRAW_STATUS; - } - break; - - case MSG_PORT_OPEN_RESULT: - { - if (IOMapComm.BtInBuf.Buf[2] == 1) - { - IOMapComm.BtConnectTable[0].HandleNr = IOMapComm.BtInBuf.Buf[3]; - IOMapComm.BrickData.BtStateStatus |= BT_BRICK_PORT_OPEN; - } - else - { - - /* There was an error setting up the OpenPort command in BC4 */ - IOMapComm.BtConnectTable[0].HandleNr = BLUETOOTH_HANDLE_UNDEFIEND; - IOMapComm.BrickData.BtStateStatus &= ~BT_BRICK_PORT_OPEN; - } - } - break; - - case MSG_CLOSE_PORT_RESULT: - { - if (IOMapComm.BtInBuf.Buf[2] == 1) - { - IOMapComm.BtConnectTable[0].HandleNr = BLUETOOTH_HANDLE_UNDEFIEND; - IOMapComm.BrickData.BtStateStatus &= ~BT_BRICK_PORT_OPEN; - } - } - break; - - case MSG_PIN_CODE_ACK: - { - pMapUi->BluetoothState &= ~BT_PIN_REQUEST; - } - break; - - case MSG_DISCOVERABLE_ACK: - { - if (VarsComm.BtCmdData.ParamOne == 1) - { - IOMapComm.BrickData.BtStateStatus |= BT_BRICK_VISIBILITY; - pMapUi->BluetoothState |= BT_STATE_VISIBLE; - } - else - { - IOMapComm.BrickData.BtStateStatus &= ~BT_BRICK_VISIBILITY; - pMapUi->BluetoothState &= ~BT_STATE_VISIBLE; - } - } - break; - case MSG_RESET_INDICATION: - { - if ((UPD_RESET != VarsComm.ActiveUpdate) && - (UPD_BRICKNAME != VarsComm.ActiveUpdate) && - (UPD_FACTORYRESET != VarsComm.ActiveUpdate)) - { - - /* Not intended reset indication - restart the bluecore */ - if (VarsComm.ActiveUpdate != UPD_IDLE) - { - - /* Something was ongoing send error message */ - *(VarsComm.pRetVal) = (UWORD)ERR_COMM_BUS_ERR; - *(VarsComm.pRetVal) |= 0x8000; - } - - SETBtStateIdle; - VarsComm.pRetVal = &(VarsComm.RetVal); - VarsComm.ActiveUpdate = UPD_RESET; - } - } - break; - } - } - else - { - /* Receive a message with wrong checkSum ! */ - } -} - -void cCommCpyToUpper(UBYTE *pDst, UBYTE *pSrc, UBYTE Length) -{ - UBYTE Tmp; - - for(Tmp = 0; Tmp < Length; Tmp++) - { - pDst[Tmp] =(UBYTE)toupper((UWORD)pSrc[Tmp]); - } - - /* The requried length has been copied - now fill with zeros */ - for(Tmp = Length; Tmp < (FILENAME_LENGTH + 1); Tmp++) - { - pDst[Tmp] = '\0'; - } -} - -void cCommCopyFileName(UBYTE *pDst, UBYTE *pSrc) -{ - UBYTE Tmp; - - for(Tmp = 0; Tmp < (FILENAME_LENGTH + 1); Tmp++, pDst++) - { - if ('\0' != *pSrc) - { - *pDst = *pSrc; - pSrc++; - } - else - { - *pDst = '\0'; - } - } -} - -void cCommSendHiSpeedData(void) -{ - VarsComm.HsModuleOutBuf.OutPtr = 0; - for (VarsComm.HsModuleOutBuf.InPtr = 0; VarsComm.HsModuleOutBuf.InPtr < IOMapComm.HsOutBuf.InPtr; VarsComm.HsModuleOutBuf.InPtr++) - { - VarsComm.HsModuleOutBuf.Buf[VarsComm.HsModuleOutBuf.InPtr] = IOMapComm.HsOutBuf.Buf[IOMapComm.HsOutBuf.OutPtr]; - IOMapComm.HsOutBuf.OutPtr++; - } - dHiSpeedSendData(VarsComm.HsModuleOutBuf.Buf, (VarsComm.HsModuleOutBuf.InPtr - VarsComm.HsModuleOutBuf.OutPtr)); -} - -void cCommReceivedHiSpeedData(void) -{ - UWORD NumberOfBytes; - UWORD Tmp; - - dHiSpeedReceivedData(&NumberOfBytes); - - if (NumberOfBytes != 0) - { - for (Tmp = 0; Tmp < NumberOfBytes; Tmp++) - { - IOMapComm.HsInBuf.Buf[IOMapComm.HsInBuf.InPtr] = VarsComm.HsModuleInBuf.Buf[Tmp]; - IOMapComm.HsInBuf.InPtr++; - if (IOMapComm.HsInBuf.InPtr > (SIZE_OF_HSBUF - 1)) - { - IOMapComm.HsInBuf.InPtr = 0; - } - VarsComm.HsModuleInBuf.Buf[Tmp] = 0; - } - - /* Now new data is available from the HIGH SPEED port ! */ - } -} - -UBYTE cCommBtValidateCmd(void) -{ - UWORD CheckSumTmp = 0; - UBYTE Tmp, CheckSumHigh, CheckSumLow; - - for (Tmp = 0; Tmp < (IOMapComm.BtInBuf.Buf[0] - 1);Tmp++) - { - CheckSumTmp += IOMapComm.BtInBuf.Buf[Tmp]; - } - CheckSumTmp = (UWORD) (1 + (0xFFFF - CheckSumTmp)); - CheckSumHigh = (UBYTE)((CheckSumTmp & 0xFF00)>>8); - CheckSumLow = (UBYTE)(CheckSumTmp & 0x00FF); - - if ((CheckSumHigh == IOMapComm.BtInBuf.Buf[IOMapComm.BtInBuf.Buf[0] - 1]) && (CheckSumLow == IOMapComm.BtInBuf.Buf[IOMapComm.BtInBuf.Buf[0]])) - { - return(TRUE); - } - else - { - return(FALSE); - } -} - -void cCommClearStreamStatus(void) -{ - IOMapComm.BtConnectTable[0].StreamStatus = 0; - IOMapComm.BtConnectTable[1].StreamStatus = 0; - IOMapComm.BtConnectTable[2].StreamStatus = 0; - IOMapComm.BtConnectTable[3].StreamStatus = 0; -} - -void cCommUpdateBt(void) -{ - UBYTE Tmp, Tmp2, Handle; - - Tmp = 0; - Tmp2 = 0; - - switch(VarsComm.ActiveUpdate) - { - case UPD_RESET: - { - - switch(VarsComm.UpdateState) - { - case 0: - { - /* Setup Reset sequence */ - pMapUi->BluetoothState = BT_STATE_OFF; - VarsComm.UpdateState = 1; - } - break; - - case 1: - { - cCommsBtReset(&(VarsComm.UpdateState)); - } - break; - - case 2: - { - (VarsComm.UpdateState)++; - dBtSendBtCmd((UBYTE)MSG_GET_LOCAL_ADDR, 0, 0, NULL, NULL, NULL, NULL); - } - break; - - case 3: - { - if (MSG_GET_LOCAL_ADDR_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) - { - cCommCopyBdaddr((IOMapComm.BrickData.BdAddr), &(IOMapComm.BtInBuf.Buf[BT_CMD_BYTE + 1])); - dUsbStoreBtAddress( &(IOMapComm.BtInBuf.Buf[BT_CMD_BYTE + 1])); - dBtSendBtCmd((UBYTE)MSG_GET_FRIENDLY_NAME, 0, 0, NULL, NULL, NULL, NULL); - VarsComm.BtAdrStatus = INITIALIZED; - (VarsComm.UpdateState)++; - } - } - break; - - case 4: - { - if (MSG_GET_FRIENDLY_NAME_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) - { - memcpy(IOMapComm.BrickData.Name, &(IOMapComm.BtInBuf.Buf[BT_CMD_BYTE + 1]), SIZE_OF_BRICK_NAME); - pMapUi->Flags |= UI_REDRAW_STATUS; - IOMapComm.BtDeviceCnt = 0; - IOMapComm.BtDeviceNameCnt = 0; - dBtSendBtCmd((UBYTE)MSG_DUMP_LIST, 0, 0, NULL, NULL, NULL, NULL); - (VarsComm.UpdateState)++; - } - } - break; - - case 5: - { - if (MSG_LIST_ITEM == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) - { - cCommCopyBdaddr((IOMapComm.BtDeviceTable[IOMapComm.BtDeviceCnt].BdAddr), &(IOMapComm.BtInBuf.Buf[2])); - cCommInsertBtName(IOMapComm.BtDeviceTable[IOMapComm.BtDeviceCnt].Name, &(IOMapComm.BtInBuf.Buf[9])); - IOMapComm.BtDeviceTable[IOMapComm.BtDeviceCnt].DeviceStatus = BT_DEVICE_KNOWN; - - memcpy(IOMapComm.BtDeviceTable[IOMapComm.BtDeviceCnt].ClassOfDevice, &(IOMapComm.BtInBuf.Buf[9+SIZE_OF_BT_NAME]), sizeof(IOMapComm.BtDeviceTable[IOMapComm.BtDeviceCnt].ClassOfDevice)); - - IOMapComm.BtDeviceCnt++; - IOMapComm.BtDeviceNameCnt++; - } - - if (MSG_LIST_DUMP_STOPPED == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) - { - dBtSendBtCmd((UBYTE)MSG_GET_VERSION, 0, 0, NULL, NULL, NULL, NULL); - (VarsComm.UpdateState)++; - } - IOMapComm.BtInBuf.Buf[BT_CMD_BYTE] = 0; - } - break; - - case 6: - { - if (MSG_GET_VERSION_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) - { - - IOMapComm.BrickData.BluecoreVersion[0] = IOMapComm.BtInBuf.Buf[3]; - IOMapComm.BrickData.BluecoreVersion[1] = IOMapComm.BtInBuf.Buf[2]; - - /* BtHwStatus indicates cold boot or user interaction */ - if (BT_DISABLE == IOMapComm.BrickData.BtHwStatus) - { - - /* This is from brick turning on */ - dBtSendBtCmd((UBYTE)MSG_GET_BRICK_STATUSBYTE, 0, 0, NULL, NULL, NULL, NULL); - } - else - { - - /* this is user interaction setting the brick on */ - dBtSendBtCmd((UBYTE)MSG_SET_BRICK_STATUSBYTE, BT_ENABLE, 0, NULL, NULL, NULL, NULL); - } - (VarsComm.UpdateState)++; - pMapUi->Flags |= UI_REDRAW_STATUS; - } - } - break; - - case 7: - { - if (MSG_GET_BRICK_STATUSBYTE_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) - { - IOMapComm.BrickData.TimeOutValue = IOMapComm.BtInBuf.Buf[BT_CMD_BYTE + 2]; - - /* Check for brick to be on or off */ - if (BT_ENABLE == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE + 1]) - { - pMapUi->BluetoothState &= ~BT_STATE_OFF; - IOMapComm.BrickData.BtHwStatus = BT_ENABLE; - dBtSendBtCmd((UBYTE)MSG_GET_DISCOVERABLE, 0, 0, NULL, NULL, NULL, NULL); - (VarsComm.UpdateState)++; - } - else - { - SETBtOff; - IOMapComm.BrickData.BtHwStatus = BT_ENABLE; - SETBtStateIdle; - *(VarsComm.pRetVal) = SUCCESS; - } - } - if (MSG_SET_BRICK_STATUSBYTE_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) - { - - /* brick to be on*/ - pMapUi->BluetoothState &= ~BT_STATE_OFF; - IOMapComm.BrickData.BtHwStatus = BT_ENABLE; - dBtSendBtCmd((UBYTE)MSG_GET_DISCOVERABLE, 0, 0, NULL, NULL, NULL, NULL); - (VarsComm.UpdateState)++; - } - } - break; - - case 8: - { - if (MSG_GET_DISCOVERABLE_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) - { - if (IOMapComm.BtInBuf.Buf[2] & 0x01) - { - IOMapComm.BrickData.BtStateStatus |= BT_BRICK_VISIBILITY; - pMapUi->BluetoothState |= BT_STATE_VISIBLE; - } - else - { - IOMapComm.BrickData.BtStateStatus &= ~BT_BRICK_VISIBILITY; - pMapUi->BluetoothState &= ~BT_STATE_VISIBLE; - } - dBtSendBtCmd((UBYTE)MSG_OPEN_PORT, 0, 0, NULL, NULL, NULL, NULL); - (VarsComm.UpdateState)++; - } - } - break; - - case 9: - { - - if (MSG_PORT_OPEN_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) - { - if (IOMapComm.BtInBuf.Buf[BT_CMD_BYTE + 1] & 0x01) - { - IOMapComm.BrickData.BtStateStatus |= BT_BRICK_PORT_OPEN; - } - else - { - IOMapComm.BrickData.BtStateStatus &= ~BT_BRICK_PORT_OPEN; - } - - SETBtStateIdle; - *(VarsComm.pRetVal) = SUCCESS; - } - } - break; - } - } - break; - - case UPD_FACTORYRESET: - { - switch(VarsComm.UpdateState) - { - - case 0: - { - if (BT_STATE_OFF & (pMapUi->BluetoothState)) - { - - /* Bluetooth is off - now start it up */ - (VarsComm.UpdateState)++; - } - else - { - - /* BT is already on - continue */ - (VarsComm.UpdateState) += 2; - } - } - break; - case 1: - { - cCommsBtReset(&(VarsComm.UpdateState)); - } - break; - case 2: - { - cCommsSetCmdMode(&(VarsComm.UpdateState)); - } - break; - case 3: - { - cCommsDisconnectAll(&(VarsComm.UpdateState)); - } - break; - case 4: - { - - /* Now bc4 is in cmd mode now factory can be sent */ - /* Just leave the BC4 in cmd mode */ - dBtSendBtCmd((UBYTE)MSG_SET_FACTORY_SETTINGS, 0, 0, NULL, NULL, NULL, NULL); - (VarsComm.UpdateState)++; - } - break; - case 5: - { - if (MSG_SET_FACTORY_SETTINGS_ACK == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) - { - SETBtStateIdle; - IOMapComm.BrickData.BtHwStatus = BT_DISABLE; /* Boot BT like cold boot*/ - VarsComm.ActiveUpdate = UPD_RESET; - } - } - break; - } - } - break; - - case UPD_BRICKNAME: - { - switch(VarsComm.UpdateState) - { - case 0: - { - - if (BT_STATE_OFF & (pMapUi->BluetoothState)) - { - - /* Bluetooth is off - now start it up */ - (VarsComm.UpdateState)++; - } - else - { - VarsComm.UpdateState = 2; - } - } - break; - - case 1: - { - cCommsBtReset(&(VarsComm.UpdateState)); - } - break; - - case 2: - { - VarsComm.BtUpdateDataConnectNr = 0; - if (BT_ARM_DATA_MODE == VarsComm.BtState) - { - for (Tmp = 0; Tmp < SIZE_OF_BT_CONNECT_TABLE; Tmp++) - { - if (IOMapComm.BtConnectTable[Tmp].StreamStatus) - { - VarsComm.BtUpdateDataConnectNr = Tmp | 0x80; - } - } - (VarsComm.UpdateState)++; - } - else - { - (VarsComm.UpdateState) += 2; - } - } - break; - - case 3: - { - cCommsSetCmdMode(&(VarsComm.UpdateState)); - } - break; - - case 4: - { - - /* Brick name has been updated prior to this */ - dBtSendBtCmd((UBYTE)MSG_SET_FRIENDLY_NAME, 0, 0, NULL, IOMapComm.BrickData.Name, NULL, NULL); - (VarsComm.UpdateState)++; - } - break; - - case 5: - { - if (MSG_SET_FRIENDLY_NAME_ACK == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) - { - - /* Set name has been executed */ - if (VarsComm.BtUpdateDataConnectNr & 0x80) - { - dBtSendBtCmd((UBYTE)MSG_OPEN_STREAM, IOMapComm.BtConnectTable[(VarsComm.BtUpdateDataConnectNr & ~0x80)].HandleNr, - 0, NULL, NULL, NULL, NULL); - (VarsComm.UpdateState)++; - } - else - { - if (BT_STATE_OFF & (pMapUi->BluetoothState)) - { - SETBtOff; - } - SETBtStateIdle; - *(VarsComm.pRetVal) = SUCCESS; - } - pMapUi->Flags |= UI_REDRAW_STATUS; - } - } - break; - case 6: - { - if (VarsComm.BtBcPinLevel) - { - IOMapComm.BtConnectTable[(VarsComm.BtUpdateDataConnectNr & ~0x80)].StreamStatus = 1; - *(VarsComm.pRetVal) = SUCCESS; - SETBtDataState; - SETBtStateIdle; - } - } - break; - } - } - break; - - case UPD_REQCMDMODE: - { - switch(VarsComm.UpdateState) - { - case 0: - { - cCommsSetCmdMode(&(VarsComm.UpdateState)); - } - break; - case 1: - { - *(VarsComm.pRetVal) = SUCCESS; - SETBtStateIdle; - } - break; - } - } - break; - - case UPD_OPENSTREAM: - { - switch(VarsComm.UpdateState) - { - case 0: - { - cCommsOpenStream(&(VarsComm.UpdateState)); - } - break; - - case 1: - { - *(VarsComm.pRetVal) = SUCCESS; - SETBtStateIdle; - } - break; - } - } - break; - - case UPD_SENDFILE: - { - switch (VarsComm.UpdateState) - { - case 0: - { - cCommsOpenStream(&(VarsComm.UpdateState)); - } - break; - - case 1: - { - - /* Here we wait for the open stream to succeed*/ - if (IOMapComm.BtConnectTable[VarsComm.ExtTx.SlotNo].StreamStatus) - { - - /* Stream has been opened send the openwrite command */ - VarsComm.BtModuleOutBuf.Buf[0] = SYSTEM_CMD; - VarsComm.BtModuleOutBuf.Buf[1] = OPENWRITE; - memcpy((UBYTE*)&(VarsComm.BtModuleOutBuf.Buf[2]),(UBYTE*)VarsComm.ExtTx.FileName, FILENAME_LENGTH + 1); - memcpy((UBYTE*)&(VarsComm.BtModuleOutBuf.Buf[22]),(UBYTE*)&(VarsComm.ExtTx.RemFileSize), sizeof(VarsComm.ExtTx.RemFileSize)); - dBtSendMsg(VarsComm.BtModuleOutBuf.Buf, 26, 26); - - VarsComm.ExtTx.Timer = 0; - VarsComm.UpdateState = 2; - - } - else - { - if (VarsComm.ExtTx.Timer >= FILETXTOUT) - { - *(VarsComm.pRetVal) = FILETX_STREAMERROR; - VarsComm.UpdateState = 8; - } - else - { - (VarsComm.ExtTx.Timer)++; - } - } - } - break; - - case 2: - { - - if (4 == IOMapComm.BtInBuf.InPtr) - { - - /* Data has been received - examine the answer */ - if ((REPLY_CMD == IOMapComm.BtInBuf.Buf[0]) && (OPENWRITE == IOMapComm.BtInBuf.Buf[1])) - { - - /* OpenWrite answer */ - if (LOADER_ERR_BYTE(SUCCESS) == IOMapComm.BtInBuf.Buf[2]) - { - - /* save the handle from the other brick */ - VarsComm.ExtTx.DstHandle = IOMapComm.BtInBuf.Buf[3]; - VarsComm.UpdateState = 3; - IOMapComm.BtInBuf.InPtr = 0; - } - else - { - - /* Open write failiure - terminate file transfer */ - *(VarsComm.pRetVal) = IOMapComm.BtInBuf.Buf[2]; - VarsComm.UpdateState = 8; - } - } - } - - if (VarsComm.ExtTx.Timer >= FILETXTOUT) - { - *(VarsComm.pRetVal) = FILETX_TIMEOUT; - VarsComm.UpdateState = 8; - } - else - { - (VarsComm.ExtTx.Timer)++; - } - } - break; - - case 3: /*SENDWRITE:*/ - { - ULONG Length; - UWORD MsgSize; - - VarsComm.ExtTx.Timer = 0; - - if (VarsComm.ExtTx.RemFileSize > (MAX_BT_MSG_SIZE - 5)) - { - - /* need to use the maximum size available - approx 64K */ - VarsComm.ExtTx.RemMsgSize = (MAX_BT_MSG_SIZE - 5); - } - else - { - - /* Message can hold the remaining message */ - VarsComm.ExtTx.RemMsgSize = VarsComm.ExtTx.RemFileSize; - } - - if (VarsComm.ExtTx.RemMsgSize > (SIZE_OF_BTBUF - 5)) - { - Length = SIZE_OF_BTBUF - 5; - VarsComm.UpdateState = 4; - } - else - { - Length = VarsComm.ExtTx.RemMsgSize; - VarsComm.UpdateState = 5; - } - - Handle = (UBYTE)(VarsComm.ExtTx.SrcHandle); - pMapLoader->pFunc(READ, &Handle, &(VarsComm.BtModuleOutBuf.Buf[3]), &Length); - MsgSize = VarsComm.ExtTx.RemMsgSize + 3; - VarsComm.BtModuleOutBuf.Buf[0] = SYSTEM_CMD; - VarsComm.BtModuleOutBuf.Buf[1] = WRITE; - VarsComm.BtModuleOutBuf.Buf[2] = VarsComm.ExtTx.DstHandle; - dBtSendMsg(VarsComm.BtModuleOutBuf.Buf, Length + 3, MsgSize); - - VarsComm.ExtTx.RemMsgSize -= Length; - VarsComm.ExtTx.RemFileSize -= Length; - } - break; - - case 4: /* CONTINOUSWRITE:*/ - { - ULONG Length; - UWORD Status; - - if(dBtCheckForTxBuf()) - { - - /* do only send more data if buffer is empty */ - VarsComm.ExtTx.Timer = 0; - if (VarsComm.ExtTx.RemMsgSize >= SIZE_OF_BTBUF) - { - Length = SIZE_OF_BTBUF; - } - else - { - Length = VarsComm.ExtTx.RemMsgSize; - } - - VarsComm.ExtTx.RemMsgSize -= Length; - VarsComm.ExtTx.RemFileSize -= Length; - Handle = (UBYTE)(VarsComm.ExtTx.SrcHandle); - Status = pMapLoader->pFunc(READ, &Handle, &(VarsComm.BtModuleOutBuf.Buf[0]), &Length); - if (Status >= 0x8000) - { - Length = 0; - } - dBtSend(VarsComm.BtModuleOutBuf.Buf, Length); - if (!(VarsComm.ExtTx.RemMsgSize)) - { - - /* at this point due to large write command acknowledge is expected */ - VarsComm.UpdateState = 5; - VarsComm.ExtTx.Timer = 0; - IOMapComm.BtInBuf.InPtr = 0; - } - } - } - break; - - case 5: /* WRITEACK: */ - { - if (6 == IOMapComm.BtInBuf.InPtr) - { - if ((WRITE == IOMapComm.BtInBuf.Buf[1]) && - (REPLY_CMD == IOMapComm.BtInBuf.Buf[0]) && - (VarsComm.ExtTx.DstHandle == IOMapComm.BtInBuf.Buf[3])) - { - - /* Ok the the return reply is for me - was it ok? */ - if (LOADER_ERR_BYTE(SUCCESS) == IOMapComm.BtInBuf.Buf[2]) - { - - /* Ok send next write*/ - if (VarsComm.ExtTx.RemFileSize) - { - VarsComm.UpdateState = 3; - } - else - { - VarsComm.UpdateState = 6; - } - IOMapComm.BtInBuf.InPtr = 0; - } - } - } - - if (VarsComm.ExtTx.Timer >= FILETXTOUT) - { - *(VarsComm.pRetVal) = FILETX_TIMEOUT; - VarsComm.UpdateState = 8; - } - else - { - (VarsComm.ExtTx.Timer)++; - } - } - break; - - case 6: /*TERMINATESEND: */ - { - - /* Stream still open close the receiver handle */ - VarsComm.BtModuleOutBuf.Buf[0] = SYSTEM_CMD; - VarsComm.BtModuleOutBuf.Buf[1] = CLOSE; - VarsComm.BtModuleOutBuf.Buf[2] = VarsComm.ExtTx.DstHandle; - dBtSendMsg(VarsComm.BtModuleOutBuf.Buf, 3, 3); - - VarsComm.ExtTx.Timer = 0; - VarsComm.UpdateState = 7; - } - break; - case 7: /* TERMINATEACK:*/ - { - - if (4 == IOMapComm.BtInBuf.InPtr) - { - - if ((CLOSE == IOMapComm.BtInBuf.Buf[1]) && - (REPLY_CMD == IOMapComm.BtInBuf.Buf[0]) && - (VarsComm.ExtTx.DstHandle == IOMapComm.BtInBuf.Buf[3])) - { - if (LOADER_ERR_BYTE(SUCCESS) == IOMapComm.BtInBuf.Buf[2]) - { - *(VarsComm.pRetVal) = SUCCESS; - VarsComm.UpdateState = 8; - } - else - { - *(VarsComm.pRetVal) = FILETX_CLOSEERROR; - VarsComm.UpdateState = 8; - } - IOMapComm.BtInBuf.InPtr = 0; - } - } - - if (VarsComm.ExtTx.Timer >= FILETXTOUT) - { - *(VarsComm.pRetVal) = FILETX_TIMEOUT; - VarsComm.UpdateState = 8; - } - else - { - (VarsComm.ExtTx.Timer)++; - } - } - break; - case 8: - { - UBYTE Handle; - Handle = (UBYTE)(VarsComm.ExtTx.SrcHandle); - pMapLoader->pFunc(CLOSE, &Handle, NULL, NULL); - (VarsComm.UpdateState)++; - } - break; - case 9: - { - cCommsSetCmdMode(&(VarsComm.UpdateState)); - } - break; - case 10: - { - SETBtStateIdle; - } - break; - } - } - break; - - case UPD_EXTREAD: - { - switch (VarsComm.UpdateState) - { - case 0: - { - ULONG MsgLength; - UWORD Status; - - MsgLength = (SIZE_OF_BTBUF - 8); - Handle =(UBYTE)(VarsComm.ExtTx.SrcHandle); - Status = pMapLoader->pFunc(READ, &Handle, &(VarsComm.BtModuleOutBuf.Buf[6]), &MsgLength); - VarsComm.BtModuleOutBuf.Buf[0] = (UBYTE) (REPLY_CMD); - VarsComm.BtModuleOutBuf.Buf[1] = (UBYTE) (VarsComm.ExtTx.Cmd); - VarsComm.BtModuleOutBuf.Buf[2] = LOADER_ERR_BYTE(Status); - VarsComm.BtModuleOutBuf.Buf[3] = LOADER_HANDLE(Status); - VarsComm.BtModuleOutBuf.Buf[4] = (UBYTE)VarsComm.ExtTx.RemMsgSize; - VarsComm.BtModuleOutBuf.Buf[5] = (UBYTE)(VarsComm.ExtTx.RemMsgSize >> 8); - dBtSendMsg(VarsComm.BtModuleOutBuf.Buf, (UBYTE)(SIZE_OF_BTBUF - 2), (VarsComm.ExtTx.RemMsgSize + 6)); - - VarsComm.ExtTx.RemMsgSize -= (SIZE_OF_BTBUF - 8); - VarsComm.UpdateState = 1; - } - break; - - case 1: - { - - ULONG Length; - - if(dBtCheckForTxBuf()) - { - if (VarsComm.ExtTx.RemMsgSize > (SIZE_OF_BTBUF)) - { - - /* Send max number of bytes */ - VarsComm.ExtTx.RemMsgSize -= SIZE_OF_BTBUF; - Length = SIZE_OF_BTBUF; - } - else - { - - /* Buffer can hold the last part of the requested data */ - Length = VarsComm.ExtTx.RemMsgSize; - VarsComm.ExtTx.RemMsgSize = 0; - *(VarsComm.pRetVal) = SUCCESS; - SETBtStateIdle; - } - Handle =(UBYTE)(VarsComm.ExtTx.SrcHandle); - pMapLoader->pFunc(READ, &Handle, (VarsComm.BtModuleOutBuf.Buf), &Length); - dBtSend(VarsComm.BtModuleOutBuf.Buf, Length); - } - } - break; - } - } - break; - - case UPD_SEARCH: - { - switch (VarsComm.UpdateState) - { - case 0: - { - cCommsSetCmdMode(&(VarsComm.UpdateState)); - } - break; - case 1: - { - cCommsCloseConn0(&(VarsComm.UpdateState)); - } - break; - case 2: - { - - /* Now ready for the actual search */ - for (Tmp = 0; Tmp < SIZE_OF_BT_DEVICE_TABLE; Tmp++) - { - if ((IOMapComm.BtDeviceTable[Tmp].DeviceStatus) & BT_DEVICE_KNOWN) - { - (IOMapComm.BtDeviceTable[Tmp].DeviceStatus) = (BT_DEVICE_AWAY | BT_DEVICE_KNOWN); - } - else - { - IOMapComm.BtDeviceTable[Tmp].DeviceStatus = BT_DEVICE_EMPTY; - } - } - dBtSendBtCmd((UBYTE)MSG_BEGIN_INQUIRY, (UBYTE)BT_DEFAULT_INQUIRY_MAX, - BT_DEFAULT_INQUIRY_TIMEOUT_LO, NULL, NULL, NULL, NULL); - (VarsComm.UpdateState)++; - } - break; - case 3: - { - - /* this is the stop search flag */ - /* - meaning that the search should be stopped */ - if (1 == VarsComm.BtCmdData.ParamOne) - { - dBtSendBtCmd((UBYTE)MSG_CANCEL_INQUIRY, 0, 0, NULL, NULL, NULL, NULL); - (VarsComm.UpdateState) = 7; - } - else - { - - - /* when inquiry is running there is 2 alloable return answers */ - /* either inquiry result or inquiry stopped */ - if (MSG_INQUIRY_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) - { - - dBtResetTimeOut(); /* reset the cmd timeout */ - Tmp = cCommInsertDevice(&(IOMapComm.BtInBuf.Buf[2]), &(IOMapComm.BtInBuf.Buf[9]), - &(IOMapComm.BtInBuf.Buf[25]), (UBYTE) BT_DEVICE_UNKNOWN, &Tmp2); - if (SIZE_OF_BT_DEVICE_TABLE > Tmp) - { - - /* Remember to check for already existing entry ....*/ - if (DEVICE_VERIFIED != Tmp2) - { - (IOMapComm.BtDeviceTable[Tmp].DeviceStatus) &= ~BT_DEVICE_AWAY; - IOMapComm.BtDeviceCnt++; - } - } - else - { - - /* We will send a stop inquiry cmd as the table is full! */ - dBtSendBtCmd((UBYTE)MSG_CANCEL_INQUIRY, 0, 0, NULL, NULL, NULL, NULL); - } - } - - if (MSG_INQUIRY_STOPPED == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) - { - VarsComm.BtDeviceIndex = 0; /* Start looking for found devices at index 0 */ - VarsComm.LookUpCnt = 0; /* how many times should we try to ask for the name */ - (VarsComm.UpdateState)++; - } - } - IOMapComm.BtInBuf.Buf[BT_CMD_BYTE] = 0; - } - break; - - case 4: - { - - /* this is the stop search flag */ - /* - meaning that the search should be stopped */ - if (1 == VarsComm.BtCmdData.ParamOne) - { - (VarsComm.UpdateState) = 8; - } - else - { - - /* Needs to run through the hole list as found devices can be placed anywhere */ - /* in the table */ - for (Tmp = (VarsComm.BtDeviceIndex); Tmp < SIZE_OF_BT_DEVICE_TABLE; Tmp++) - { - if ((BT_DEVICE_UNKNOWN == IOMapComm.BtDeviceTable[Tmp].DeviceStatus) || - (BT_DEVICE_KNOWN == IOMapComm.BtDeviceTable[Tmp].DeviceStatus)) - { - VarsComm.BtDeviceIndex = (Tmp + 1); - (VarsComm.UpdateState)++; - dBtSendBtCmd((UBYTE)MSG_LOOKUP_NAME, 0, 0, (IOMapComm.BtDeviceTable[Tmp].BdAddr), - NULL, NULL, NULL); - break; - } - } - if (SIZE_OF_BT_DEVICE_TABLE == Tmp) - { - (VarsComm.LookUpCnt)++; - if (((VarsComm.LookUpCnt) < LOOKUPNO) && ((IOMapComm.BtDeviceNameCnt) != (IOMapComm.BtDeviceCnt))) - { - VarsComm.BtDeviceIndex = 0; - } - else - { - - // all done - SETBtStateIdle; - *(VarsComm.pRetVal) = SUCCESS; - } - } - } - } - break; - - case 5: - { - - if (MSG_LOOKUP_NAME_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) - { - Tmp2 = FALSE; /* Tmp2 used to indicate name change */ - (IOMapComm.BtDeviceNameCnt)++; - - /* Try look the most obvious place in the device table */ - Tmp = VarsComm.BtDeviceIndex - 1; - if (TRUE != cCommCheckBdaddr((IOMapComm.BtDeviceTable[Tmp].BdAddr), &(IOMapComm.BtInBuf.Buf[2]))) - { - - /* there was no match - now look the complete table */ - for (Tmp = 0; Tmp < SIZE_OF_BT_DEVICE_TABLE; Tmp++) - { - if (TRUE == cCommCheckBdaddr((IOMapComm.BtDeviceTable[Tmp].BdAddr), &(IOMapComm.BtInBuf.Buf[2]))) - { - break; - } - } - } - - if (Tmp < SIZE_OF_BT_DEVICE_TABLE) - { - - /* Valid index with matching device adress found */ - if (0 == IOMapComm.BtInBuf.Buf[9]) - { - - if (0 == IOMapComm.BtDeviceTable[Tmp].Name[0]) - { - - /* No valid name recvd and no valid name in table -> insert "No Name" */ - cCommInsertBtName(IOMapComm.BtDeviceTable[Tmp].Name, (UBYTE*)NoName); - } - } - else - { - - /* Valid Name - check it against the one allready stored in the device table */ - /* if it differs then update */ - if (0 != strcmp((char const*)IOMapComm.BtDeviceTable[Tmp].Name, (char const*)&(IOMapComm.BtInBuf.Buf[9]))) - { - cCommInsertBtName(IOMapComm.BtDeviceTable[Tmp].Name, &(IOMapComm.BtInBuf.Buf[9])); - Tmp2 = TRUE; - } - } - if ((BT_DEVICE_KNOWN == (IOMapComm.BtDeviceTable[Tmp].DeviceStatus)) && (TRUE == Tmp2)) - { - dBtSendBtCmd((UBYTE)MSG_ADD_DEVICE, 0, 0, (IOMapComm.BtDeviceTable[Tmp].BdAddr), - (IOMapComm.BtDeviceTable[Tmp].Name), (IOMapComm.BtDeviceTable[Tmp].ClassOfDevice), NULL); - (VarsComm.UpdateState)++; - } - else - { - (VarsComm.UpdateState)--; - } - } - - /* Update devicestatus (name found) so it doesn't look up the name anymore */ - IOMapComm.BtDeviceTable[Tmp].DeviceStatus |= BT_DEVICE_NAME; - } - - if (MSG_LOOKUP_NAME_FAILURE == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) - { - - if ((LOOKUPNO - 1) == VarsComm.LookUpCnt) - { - - /* This is the last time we ask this device -> we will not get a valid name */ - /* Try look the most obvious place in the device table */ - Tmp = VarsComm.BtDeviceIndex - 1; - if (TRUE != cCommCheckBdaddr((IOMapComm.BtDeviceTable[Tmp].BdAddr), &(IOMapComm.BtInBuf.Buf[2]))) - { - for (Tmp = 0; Tmp < SIZE_OF_BT_DEVICE_TABLE; Tmp++) - { - if (TRUE == cCommCheckBdaddr((IOMapComm.BtDeviceTable[Tmp].BdAddr), &(IOMapComm.BtInBuf.Buf[2]))) - { - break; - } - } - if ((Tmp < SIZE_OF_BT_DEVICE_TABLE) && (BT_DEVICE_UNKNOWN == (IOMapComm.BtDeviceTable[Tmp].DeviceStatus))) - { - cCommInsertBtName(IOMapComm.BtDeviceTable[Tmp].Name, (UBYTE*) NoName); - } - } - (IOMapComm.BtDeviceNameCnt)++; - } - (VarsComm.UpdateState)--; - } - IOMapComm.BtInBuf.Buf[BT_CMD_BYTE] = 0; - } - break; - - case 6: - { - - /* Waiting for reply on add device command - List result */ - if (MSG_LIST_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) - { - if (LR_SUCCESS == IOMapComm.BtInBuf.Buf[2]) - { - - /* Return and go through the list*/ - (VarsComm.UpdateState) -= 2; - } - else - { - pMapUi->Error = (UBYTE)IOMapComm.BtInBuf.Buf[2]; - pMapUi->BluetoothState |= BT_ERROR_ATTENTION; - } - } - } - break; - case 7: - { - - /* here because search has been stopped by user during inquiry */ - if (MSG_INQUIRY_STOPPED == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) - { - - /* table should be cleared as no names hes been inquired */ - for (Tmp = 0; Tmp < SIZE_OF_BT_DEVICE_TABLE; Tmp++) - { - if ((IOMapComm.BtDeviceTable[Tmp].DeviceStatus) & BT_DEVICE_KNOWN) - { - (IOMapComm.BtDeviceTable[Tmp].DeviceStatus) = BT_DEVICE_KNOWN; - } - else - { - (IOMapComm.BtDeviceTable[Tmp].DeviceStatus) = BT_DEVICE_EMPTY; - } - IOMapComm.BtDeviceCnt = 0; - IOMapComm.BtDeviceNameCnt = 0; - } - SETBtStateIdle; - *(VarsComm.pRetVal) = SUCCESS; - } - } - break; - case 8: - { - for (Tmp = (VarsComm.BtDeviceIndex); Tmp < SIZE_OF_BT_DEVICE_TABLE; Tmp++) - { - if (BT_DEVICE_UNKNOWN == IOMapComm.BtDeviceTable[Tmp].DeviceStatus) - { - IOMapComm.BtDeviceTable[Tmp].DeviceStatus = BT_DEVICE_EMPTY; - } - } - SETBtStateIdle; - *(VarsComm.pRetVal) = SUCCESS; - } - break; - } - } - break; - - case UPD_CONNECTREQ: - { - switch (VarsComm.UpdateState) - { - - case 0: - { - dBtSendBtCmd((UBYTE)MSG_ACCEPT_CONNECTION, 1, 0, NULL, NULL, NULL, NULL); - cCommCopyBdaddr((IOMapComm.BtConnectTable[0].BdAddr), &(IOMapComm.BtInBuf.Buf[BT_CMD_BYTE + 1])); - (VarsComm.UpdateState)++; - } - break; - - case 1: - { - if (MSG_CONNECT_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) - { - - /* Check for successfull connection */ - if (1 == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE + 1]) - { - - /* Save the handle number and look up the name of the master */ - IOMapComm.BtConnectTable[0].HandleNr = IOMapComm.BtInBuf.Buf[BT_CMD_BYTE + 2]; - pMapUi->BluetoothState |= BT_STATE_CONNECTED; - dBtSendBtCmd((UBYTE)MSG_LOOKUP_NAME, 0, 0, (IOMapComm.BtConnectTable[0].BdAddr), NULL, NULL, NULL); - (VarsComm.UpdateState)++; - } - else - { - - /* Unsuccessful connection */ - SETBtStateIdle; - *(VarsComm.pRetVal) = BTCONNECTFAIL; - } - } - } - break; - - case 2: - { - - /* a close connection can happen during connection sequence - if this */ - /* occurs for connection 0 then abort the rest of the sequence - OxFF */ - /* is unused handle */ - if ((MSG_CLOSE_CONNECTION_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) && - (0xFF == IOMapComm.BtConnectTable[0].HandleNr)) - { - SETBtStateIdle; - *(VarsComm.pRetVal) = BTCONNECTFAIL; - } - else - { - - if (MSG_LOOKUP_NAME_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) - { - Tmp = cCommInsertDevice(&(IOMapComm.BtInBuf.Buf[2]), &(IOMapComm.BtInBuf.Buf[9]), - &(IOMapComm.BtInBuf.Buf[25]), (UBYTE) BT_DEVICE_KNOWN, &Tmp2); - - if (SIZE_OF_BT_DEVICE_TABLE > Tmp) - { - - /* entry has been added or is allready existing in the devicetable */ - cCommInsertBtName(IOMapComm.BtConnectTable[0].Name, &(IOMapComm.BtInBuf.Buf[9])); - cCommCopyBdaddr((IOMapComm.BtConnectTable[0].BdAddr), &(IOMapComm.BtInBuf.Buf[2])); - memcpy(IOMapComm.BtConnectTable[0].ClassOfDevice, - IOMapComm.BtDeviceTable[Tmp].ClassOfDevice, SIZE_OF_CLASS_OF_DEVICE); - dBtSendBtCmd((UBYTE)MSG_ADD_DEVICE, 0, 0, (IOMapComm.BtDeviceTable[Tmp].BdAddr), - (IOMapComm.BtDeviceTable[Tmp].Name), (IOMapComm.BtDeviceTable[Tmp].ClassOfDevice), NULL); - (VarsComm.UpdateState)++; - } - else - { - - /* no room in the devicetable -> reject the request. Param2 is index in connect table */ - dBtSendBtCmd((UBYTE)MSG_CLOSE_CONNECTION, IOMapComm.BtConnectTable[0].HandleNr, - 0, NULL, NULL, NULL, NULL); - SETBtStateIdle; - *(VarsComm.pRetVal) = BTCONNECTFAIL; - } - } - - if (MSG_LOOKUP_NAME_FAILURE == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) - { - - /* not able to get the name - disconnect*/ - dBtSendBtCmd((UBYTE)MSG_CLOSE_CONNECTION, IOMapComm.BtConnectTable[0].HandleNr, - 0, NULL, NULL, NULL, NULL); - *(VarsComm.pRetVal) = BTCONNECTFAIL; - SETBtStateIdle; - } - } - } - break; - - case 3: - { - if (MSG_LIST_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) - { - if (LR_SUCCESS == IOMapComm.BtInBuf.Buf[2]) - { - - /* All success - open stream (Data mode) */ - dBtSendBtCmd((UBYTE)MSG_OPEN_STREAM, IOMapComm.BtConnectTable[0].HandleNr, 0, NULL, NULL, NULL, NULL); - (VarsComm.UpdateState)++; - } - else - { - - /* no room in the BC4 -> reject the request */ - dBtSendBtCmd((UBYTE)MSG_CLOSE_CONNECTION, IOMapComm.BtConnectTable[0].HandleNr, - 0, NULL, NULL, NULL, NULL); - *(VarsComm.pRetVal) = BTCONNECTFAIL; - SETBtStateIdle; - } - } - } - break; - - case 4: - { - if (VarsComm.BtBcPinLevel) - { - IOMapComm.BtConnectTable[0].StreamStatus = 1; - *(VarsComm.pRetVal) = SUCCESS; - SETBtDataState; - SETBtStateIdle; - } - } - break; - } - } - break; - - case UPD_CONNECT: - { - switch (VarsComm.UpdateState) - { - case 0: - { - cCommsSetCmdMode(&(VarsComm.UpdateState)); - } - break; - case 1: - { - cCommsCloseConn0(&(VarsComm.UpdateState)); - } - break; - case 2: - { - dBtSendBtCmd((UBYTE)MSG_CONNECT, 0, 0, - IOMapComm.BtDeviceTable[VarsComm.BtCmdData.ParamOne].BdAddr, NULL, NULL, NULL); - (VarsComm.UpdateState)++; - } - break; - - case 3: - { - if (MSG_CONNECT_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) - { - if (IOMapComm.BtInBuf.Buf[2] == 1) - { - - IOMapComm.BtConnectTable[VarsComm.BtCmdData.ParamTwo].HandleNr = IOMapComm.BtInBuf.Buf[3]; - pMapUi->BluetoothState |= BT_STATE_CONNECTED; - - //Now we need to copy the data to the connectiontable - memcpy((IOMapComm.BtConnectTable[VarsComm.BtCmdData.ParamTwo].BdAddr), (IOMapComm.BtDeviceTable[VarsComm.BtCmdData.ParamOne].BdAddr), SIZE_OF_BDADDR); - cCommInsertBtName(IOMapComm.BtConnectTable[VarsComm.BtCmdData.ParamTwo].Name, IOMapComm.BtDeviceTable[VarsComm.BtCmdData.ParamOne].Name); - memcpy((IOMapComm.BtConnectTable[VarsComm.BtCmdData.ParamTwo].ClassOfDevice), - (IOMapComm.BtDeviceTable[VarsComm.BtCmdData.ParamOne].ClassOfDevice), SIZE_OF_CLASS_OF_DEVICE); - IOMapComm.BtDeviceTable[VarsComm.BtCmdData.ParamOne].DeviceStatus = BT_DEVICE_KNOWN; - - if (VarsComm.BtCmdData.ParamTwo == 1) - { - IOMapComm.BrickData.BtStateStatus |= BT_CONNECTION_1_ENABLE; - } - else - { - if (VarsComm.BtCmdData.ParamTwo == 2) - { - IOMapComm.BrickData.BtStateStatus |= BT_CONNECTION_2_ENABLE; - } - else - { - if (VarsComm.BtCmdData.ParamTwo == 3) - { - IOMapComm.BrickData.BtStateStatus |= BT_CONNECTION_3_ENABLE; - } - } - } - dBtSendBtCmd((UBYTE)MSG_ADD_DEVICE, 0, 0, (IOMapComm.BtConnectTable[VarsComm.BtCmdData.ParamTwo].BdAddr), - (IOMapComm.BtConnectTable[VarsComm.BtCmdData.ParamTwo].Name), - (IOMapComm.BtDeviceTable[VarsComm.BtCmdData.ParamOne].ClassOfDevice), NULL); - (VarsComm.UpdateState)+=3; /* skip the pin code part */ - } - else - { - - /* Connect request denied */ - *(VarsComm.pRetVal) = BTCONNECTFAIL; - SETBtStateIdle; - } - } - if (MSG_REQUEST_PIN_CODE == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) - { - *(VarsComm.pRetVal) = REQPIN; - VarsComm.pValidPinCode = NULL; - (VarsComm.UpdateState)++; - } - } - break; - - case 4: - { - if (NULL != VarsComm.pValidPinCode) - { - - memcpy((IOMapComm.BtConnectTable[VarsComm.BtCmdData.ParamTwo].PinCode), - VarsComm.pValidPinCode, SIZE_OF_BT_PINCODE); - - dBtSendBtCmd((UBYTE)MSG_PIN_CODE, 0, 0, IOMapComm.BtDeviceTable[VarsComm.BtCmdData.ParamOne].BdAddr, - NULL, NULL, (VarsComm.pValidPinCode)); - (VarsComm.UpdateState)++; - } - if (MSG_CONNECT_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) - { - - /* if no pin code has been accepted then timeout indicated */ - /* by connect failiure - it can only be failiure here */ - *(VarsComm.pRetVal) = BTCONNECTFAIL; - SETBtStateIdle; - } - } - break; - - case 5: - { - - if (MSG_CONNECT_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) - { - - /* Connect failiure can happen at any time */ - *(VarsComm.pRetVal) = BTCONNECTFAIL; - SETBtStateIdle; - } - if (MSG_PIN_CODE_ACK == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) - { - - /* return back and wait for connect ack */ - (VarsComm.UpdateState) = 3; - } - } - break; - case 6: - { - if (MSG_LIST_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) - { - *(VarsComm.pRetVal) = SUCCESS; - SETBtStateIdle; - } - } - break; - } - } - break; - - case UPD_DISCONNECT: - { - switch (VarsComm.UpdateState) - { - case 0: - { - cCommsSetCmdMode(&(VarsComm.UpdateState)); - } - break; - - case 1: - { - if (BLUETOOTH_HANDLE_UNDEFIEND != IOMapComm.BtConnectTable[VarsComm.BtCmdData.ParamOne].HandleNr) - { - VarsComm.BtCmdData.ParamOne = IOMapComm.BtConnectTable[VarsComm.BtCmdData.ParamOne].HandleNr; - dBtSendBtCmd((UBYTE)MSG_CLOSE_CONNECTION, VarsComm.BtCmdData.ParamOne, 0, NULL, NULL, NULL, NULL); - (VarsComm.UpdateState)++; - } - else - { - *(VarsComm.pRetVal) = SUCCESS; - SETBtStateIdle; - } - } - break; - - case 2: - { - - /* look for right message and right handle */ - if ((MSG_CLOSE_CONNECTION_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) && - (VarsComm.BtCmdData.ParamOne == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE + 2])) - { - *(VarsComm.pRetVal) = SUCCESS; - SETBtStateIdle; - } - } - break; - } - } - break; - case UPD_DISCONNECTALL: - { - switch (VarsComm.UpdateState) - { - case 0: - { - cCommsSetCmdMode(&(VarsComm.UpdateState)); - } - break; - case 1: - { - cCommsDisconnectAll(&(VarsComm.UpdateState)); - } - break; - case 2: - { - *(VarsComm.pRetVal) = SUCCESS; - SETBtStateIdle; - } - break; - } - } - break; - case UPD_REMOVEDEVICE: - { - switch (VarsComm.UpdateState) - { - case 0: - { - cCommsSetCmdMode(&(VarsComm.UpdateState)); - } - break; - case 1: - { - cCommsCloseConn0(&(VarsComm.UpdateState)); - } - break; - case 2: - { - dBtSendBtCmd((UBYTE)MSG_REMOVE_DEVICE, 0, 0, - IOMapComm.BtDeviceTable[VarsComm.BtCmdData.ParamOne].BdAddr, NULL, NULL, NULL); - IOMapComm.BtDeviceTable[VarsComm.BtCmdData.ParamOne].DeviceStatus = BT_DEVICE_EMPTY; - (VarsComm.UpdateState)++; - } - break; - case 3: - { - if (MSG_LIST_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) - { - *(VarsComm.pRetVal) = SUCCESS; - SETBtStateIdle; - } - } - break; - } - } - break; - - case UPD_PINREQ: - { - - /* This is pincode request from the outside - always conn 0*/ - switch (VarsComm.UpdateState) - { - case 0: - { - if (NULL != VarsComm.pValidPinCode) - { - memcpy((IOMapComm.BtConnectTable[0].PinCode), - VarsComm.pValidPinCode, SIZE_OF_BT_PINCODE); - dBtSendBtCmd((UBYTE)MSG_PIN_CODE, 0, 0, (IOMapComm.BtConnectTable[0].BdAddr), - NULL, NULL, (VarsComm.pValidPinCode)); - (VarsComm.UpdateState)++; - } - } - break; - case 1: - { - if (MSG_PIN_CODE_ACK == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) - { - SETBtStateIdle; - } - } - break; - } - } - break; - - case UPD_VISIBILITY: - { - switch (VarsComm.UpdateState) - { - case 0: - { - cCommsSetCmdMode(&(VarsComm.UpdateState)); - } - break; - case 1: - { - cCommsCloseConn0(&(VarsComm.UpdateState)); - } - break; - case 2: - { - dBtSendBtCmd((UBYTE)MSG_SET_DISCOVERABLE, VarsComm.BtCmdData.ParamOne, 0, NULL, NULL, NULL, NULL); - (VarsComm.UpdateState)++; - } - break; - case 3: - { - if (MSG_DISCOVERABLE_ACK == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) - { - if (VarsComm.BtCmdData.ParamOne == 1) - { - IOMapComm.BrickData.BtStateStatus |= BT_BRICK_VISIBILITY; - pMapUi->BluetoothState |= BT_STATE_VISIBLE; - } - else - { - IOMapComm.BrickData.BtStateStatus &= ~BT_BRICK_VISIBILITY; - pMapUi->BluetoothState &= ~BT_STATE_VISIBLE; - } - *(VarsComm.pRetVal) = SUCCESS; - SETBtStateIdle; - } - } - break; - } - } - break; - - case UPD_OFF: - { - switch (VarsComm.UpdateState) - { - case 0: - { - cCommsSetCmdMode(&(VarsComm.UpdateState)); - } - break; - case 1: - { - cCommsDisconnectAll(&(VarsComm.UpdateState)); - } - break; - case 2: - { - dBtSendBtCmd((UBYTE)MSG_SET_BRICK_STATUSBYTE, BT_DISABLE, 0, NULL, NULL, NULL, NULL); - (VarsComm.UpdateState)++; - } - break; - case 3: - { - if (MSG_SET_BRICK_STATUSBYTE_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) - { - if (IOMapComm.BtInBuf.Buf[2] == LR_SUCCESS) - { - SETBtOff; - pMapUi->BluetoothState = BT_STATE_OFF; - pMapUi->Flags |= UI_REDRAW_STATUS; - } - *(VarsComm.pRetVal) = SUCCESS; - SETBtStateIdle; - } - } - break; - } - } - break; - case UPD_SENDDATA: - { - switch (VarsComm.UpdateState) - { - case 0: - { - if (1 == IOMapComm.BtConnectTable[VarsComm.BtCmdData.ParamTwo].StreamStatus) - { - - /* Stream is allready open for the requested channel */ - (VarsComm.UpdateState) += 2; - } - else - { - - /* Stream not open - try open it*/ - (VarsComm.UpdateState)++; - } - } - break; - case 1: - { - cCommsOpenStream(&(VarsComm.UpdateState)); - } - break; - case 2: - { - - /* Stream is now opened now send the data */ - IOMapComm.BtInBuf.Buf[0] = 0; - dBtSendMsg((VarsComm.BtModuleOutBuf.Buf), VarsComm.BtCmdData.ParamOne, (UWORD)(VarsComm.BtCmdData.ParamOne)); - (VarsComm.UpdateState)++; - } - break; - case 3: - { - if(dBtCheckForTxBuf()) - { - if (VarsComm.BtCmdData.ParamThree) - { - VarsComm.ExtTx.Timer = 0; - (VarsComm.UpdateState)++; - } - else - { - *(VarsComm.pRetVal) = SUCCESS; - SETBtStateIdle; - } - } - } - break; - case 4: - { - if (0x02 == IOMapComm.BtInBuf.Buf[0]) - { - - /* a reply has been received now release the send sequence */ - *(VarsComm.pRetVal) = SUCCESS; - SETBtStateIdle; - } - else - { - if (++VarsComm.ExtTx.Timer > BTSTREAMTOUT) - { - *(VarsComm.pRetVal) = BTTIMEOUT; - SETBtStateIdle; - } - } - } - break; - } - } - break; - default: - { - - /* This is idle */ - VarsComm.UpdateState = 0; - } - break; - } -} - -UWORD cCommCopyBdaddr(UBYTE *pDst, UBYTE *pSrc) -{ - memcpy(pDst, pSrc, SIZE_OF_BDADDR); - return((UWORD) SIZE_OF_BDADDR); -} - -UWORD cCommCheckBdaddr(UBYTE *pAdr, UBYTE *pSrc) -{ - UWORD RetVal; - - RetVal = FALSE; - if (0 == memcmp((UBYTE*)pAdr, pSrc, SIZE_OF_BDADDR)) - { - RetVal = TRUE; - } - return(RetVal); -} - -UWORD cCommInsertBtName(UBYTE *pDst, UBYTE *pSrc) -{ - UBYTE Cnt; - - Cnt = 0; - - /* Complete brick name */ - while ((pSrc[Cnt]) && (Cnt < (SIZE_OF_BT_NAME - 1))) - { - pDst[Cnt] = pSrc[Cnt]; - Cnt++; - } - - /* Fill remaining up with zeros */ - while (Cnt < SIZE_OF_BT_NAME) - { - pDst[Cnt] = 0; - Cnt++; - } - - return((UWORD)SIZE_OF_BT_NAME); -} - - -UWORD cCommInsertDevice(UBYTE *pBdaddr, UBYTE *pName, UBYTE *pCod, UBYTE DeviceStatus, UBYTE *pAddInfo) -{ - UWORD Tmp; - UWORD RtnVal; - - RtnVal = FALSE; - *pAddInfo = DEVICE_VERIFIED; - for (Tmp = 0; Tmp < SIZE_OF_BT_DEVICE_TABLE; Tmp++) - { - if ((TRUE == cCommCheckBdaddr((IOMapComm.BtDeviceTable[Tmp].BdAddr), pBdaddr)) && - (IOMapComm.BtDeviceTable[Tmp].DeviceStatus != BT_DEVICE_EMPTY)) - { - - if ((IOMapComm.BtDeviceTable[Tmp].DeviceStatus) & BT_DEVICE_AWAY) - { - *pAddInfo = DEVICE_UPDATED; - (IOMapComm.BtDeviceTable[Tmp].DeviceStatus) &= ~BT_DEVICE_AWAY; - } - - if (BT_DEVICE_UNKNOWN == IOMapComm.BtDeviceTable[Tmp].DeviceStatus) - { - - /* Former unknown adresses can be upgraded - downgrading is not possible */ - IOMapComm.BtDeviceTable[Tmp].DeviceStatus = DeviceStatus; - } - if (pCod != NULL) - { - - /* Class of device can also upgraded - never downgraded to 0 */ - memcpy(&(IOMapComm.BtDeviceTable[Tmp].ClassOfDevice), pCod, SIZE_OF_CLASS_OF_DEVICE); - } - if ((*pName) != 0) - { - - /* Only upgrade name if name is received */ - cCommInsertBtName(IOMapComm.BtDeviceTable[Tmp].Name, pName); - } - RtnVal = TRUE; - - /* Break out - entry can only be found once */ - break; - } - } - - if (FALSE == RtnVal) - { - for (Tmp = 0; Tmp < SIZE_OF_BT_DEVICE_TABLE; Tmp++) - { - if (IOMapComm.BtDeviceTable[Tmp].DeviceStatus == BT_DEVICE_EMPTY) - { - *pAddInfo = DEVICE_INSERTED; - IOMapComm.BtDeviceTable[Tmp].DeviceStatus = DeviceStatus; - cCommCopyBdaddr((IOMapComm.BtDeviceTable[Tmp].BdAddr), pBdaddr); - cCommInsertBtName(IOMapComm.BtDeviceTable[Tmp].Name, pName); - if (NULL != pCod) - { - memcpy((IOMapComm.BtDeviceTable[Tmp].ClassOfDevice), pCod, SIZE_OF_CLASS_OF_DEVICE); - } - else - { - memset((IOMapComm.BtDeviceTable[Tmp].ClassOfDevice), 0, SIZE_OF_CLASS_OF_DEVICE); - } - RtnVal = TRUE; - break; - } - } - } - - /* Function returns SIZE_OF_BT_DEVICE_TABLE if device is not in the list */ - return(Tmp); -} - -void cCommsSetCmdMode(UBYTE *pNextState) -{ - switch(VarsComm.CmdSwitchCnt) - { - case 0: - { - if (BT_ARM_CMD_MODE != VarsComm.BtState) - { - cCommClearStreamStatus(); - VarsComm.BtCmdModeWaitCnt = 0; - VarsComm.CmdSwitchCnt++; - } - else - { - - /* allready in CMD mode - Exit */ - VarsComm.CmdSwitchCnt = 0; - (*pNextState)++; - } - } - break; - - case 1: - { - - /* stream status has been cleared now wait until buffers has been emptied */ - if (TRUE == dBtTxEnd()) - { - - /* Wait 100 ms after last byte has been sent to BC4 - else BC4 can crash */ - if (++(VarsComm.BtCmdModeWaitCnt) > 100) - { - dBtClearArm7CmdSignal(); - VarsComm.CmdSwitchCnt++; - } - } - } - break; - - case 2: - { - if (VarsComm.BtBcPinLevel == 0) - { - - /* Bluecore has entered cmd mode */ - SETBtCmdState; - VarsComm.CmdSwitchCnt = 0; - (*pNextState)++; - } - } - break; - - default: - { - VarsComm.CmdSwitchCnt = 0; - } - break; - } -} - -void cCommsOpenStream(UBYTE *pNextState) -{ - switch(VarsComm.StreamStateCnt) - { - case 0: - { - - if (SIZE_OF_BT_CONNECT_TABLE > VarsComm.BtCmdData.ParamTwo) - { - - /* first check if there is a connection on the requested channel */ - if ('\0' != IOMapComm.BtConnectTable[VarsComm.BtCmdData.ParamTwo].Name[0]) - { - - if (1 == IOMapComm.BtConnectTable[VarsComm.BtCmdData.ParamTwo].StreamStatus) - { - - /* Stream is allready open - continue */ - (*pNextState)++; - } - else - { - - /* There is a connection on requested channel proceed */ - VarsComm.StreamStateCnt = 1; - } - } - else - { - - /* Error - no connecteion on requested channel - exit */ - *(VarsComm.pRetVal) = (UWORD)ERR_COMM_CHAN_NOT_READY; - *(VarsComm.pRetVal) |= 0x8000; - SETBtStateIdle; - } - } - else - { - - /* Error - Illegal channel no - exit */ - *(VarsComm.pRetVal) = (UWORD)ERR_COMM_CHAN_INVALID; - *(VarsComm.pRetVal) |= 0x8000; - SETBtStateIdle; - } - } - break; - - case 1: - { - cCommsSetCmdMode(&(VarsComm.StreamStateCnt)); - } - break; - - case 2: - { - cCommsCloseConn0(&(VarsComm.StreamStateCnt)); - } - break; - - case 3: - { - - /* Open stream on the specified channel */ - VarsComm.StreamStateCnt = 4; - dBtSendBtCmd((UBYTE)MSG_OPEN_STREAM, IOMapComm.BtConnectTable[VarsComm.BtCmdData.ParamTwo].HandleNr, - 0, NULL, NULL, NULL, NULL); - } - break; - - case 4: - { - if (VarsComm.BtBcPinLevel) - { - SETBtDataState; - IOMapComm.BtConnectTable[VarsComm.BtCmdData.ParamTwo].StreamStatus = 1; - VarsComm.StreamStateCnt = 0; - (*pNextState)++; - } - } - break; - - default: - { - VarsComm.StreamStateCnt = 0; - } - break; - } -} - -void cCommsCloseConn0(UBYTE *pNextState) -{ - switch(VarsComm.CloseConn0Cnt) - { - case 0: - { - if ('\0' != IOMapComm.BtConnectTable[0].Name[0]) - { - - /* now disconnect channel 0 */ - VarsComm.CloseConn0Cnt = 1; - dBtSendBtCmd((UBYTE)MSG_CLOSE_CONNECTION, IOMapComm.BtConnectTable[0].HandleNr, 0, NULL, NULL, NULL, NULL); - } - else - { - (*pNextState)++; - } - } - break; - case 1: - { - if (MSG_CLOSE_CONNECTION_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) - { - VarsComm.CloseConn0Cnt = 0; - (*pNextState)++; - } - } - break; - default: - { - VarsComm.CloseConn0Cnt = 0; - } - break; - } -} - -void cCommsDisconnectAll(UBYTE *pNextState) -{ - switch(VarsComm.DiscAllCnt) - { - case 0: - { - VarsComm.BtCmdData.ParamOne = 0; - (VarsComm.DiscAllCnt)++; - } - break; - case 1: - { - while (('\0' == IOMapComm.BtConnectTable[VarsComm.BtCmdData.ParamOne].Name[0]) && - (VarsComm.BtCmdData.ParamOne < 4)) - { - VarsComm.BtCmdData.ParamOne++; - } - if (VarsComm.BtCmdData.ParamOne < 4) - { - - /* now disconnect selected channel */ - dBtSendBtCmd((UBYTE)MSG_CLOSE_CONNECTION, IOMapComm.BtConnectTable[VarsComm.BtCmdData.ParamOne].HandleNr, - 0, NULL, NULL, NULL, NULL); - VarsComm.BtCmdData.ParamOne++; - (VarsComm.DiscAllCnt)++; - } - else - { - - /* no more connections - move on */ - (VarsComm.DiscAllCnt) = 0; - (*pNextState)++; - } - } - break; - case 2: - { - if (MSG_CLOSE_CONNECTION_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) - { - - /* Go back and check for more connections to close */ - (VarsComm.DiscAllCnt)--; - } - } - break; - } -} - -void cCommsBtReset(UBYTE *pNextState) -{ - switch(VarsComm.ResetBtCnt) - { - case 0: - { - - /* Setup Reset sequence */ - VarsComm.BtResetTimeCnt = 0; - VarsComm.ResetBtCnt = 1; - dBtSetBcResetPinLow(); - } - break; - case 1: - { - - /* Reset should be held low for a certain time "BLUECORE_RESET_TIME" */ - VarsComm.BtResetTimeCnt++; - if (VarsComm.BtResetTimeCnt > BLUECORE_RESET_TIME) - { - dBtSetBcResetPinHigh(); - VarsComm.BtWaitTimeCnt = 0; - VarsComm.ResetBtCnt = 2; - } - } - break; - case 2: - { - - /* Wait after reset is released either wait a minimum time or wait for the reset indication telegram */ - VarsComm.BtWaitTimeCnt++; - if ((VarsComm.BtWaitTimeCnt > BLUECORE_WAIT_BEFORE_INIT) || (MSG_RESET_INDICATION == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE])) - { - memset(&(IOMapComm.BtDeviceTable), 0, sizeof(IOMapComm.BtDeviceTable)); - cCommClrConnTable(); - VarsComm.ResetBtCnt = 3; - } - } - break; - - case 3: - { - SETBtCmdState; - VarsComm.ResetBtCnt = 0; - (*pNextState)++; - } - break; - } -} - - -UWORD cCommReq(UBYTE Cmd, UBYTE Param1, UBYTE Param2, UBYTE Param3, UBYTE *pName, UWORD *pRetVal) -{ - ULONG Length; - UWORD ReturnVal; - SBYTE foundIndex= 0; - - ReturnVal = BTBUSY; - *pRetVal = BTBUSY; - if ((UPD_IDLE == (VarsComm.ActiveUpdate)) || ((UPD_SEARCH == (VarsComm.ActiveUpdate)) && (STOPSEARCH == Cmd))) - { - - ReturnVal = SUCCESS; - *pRetVal = INPROGRESS; - VarsComm.pRetVal = pRetVal; - switch(Cmd) - { - case SENDFILE: - { - ReturnVal = SUCCESS; - - /* No file is currently beeing send - Now open the file */ - VarsComm.ExtTx.SrcHandle = pMapLoader->pFunc(OPENREAD, pName, NULL, &Length); - VarsComm.ExtTx.RemFileSize = Length; - VarsComm.ExtTx.SlotNo = Param1; - VarsComm.BtCmdData.ParamTwo = Param1; /* This is used to open the correct stream */ - - if (0x8000 > VarsComm.ExtTx.SrcHandle) - { - - /* Source file is ok - go ahead */ - VarsComm.ActiveUpdate = UPD_SENDFILE; - VarsComm.ExtTx.Timer = 0; - VarsComm.ExtTx.Cmd = WRITE; - cCommCopyFileName(VarsComm.ExtTx.FileName, pName); - } - else - { - - /* Error in opening source file for read - file do not exist */ - ReturnVal = FILETX_SRCMISSING; - } - } - break; - case CONNECTBYNAME: // redo Param1, then fall through existing CONNECT code - foundIndex= cCommSearchBTDevTableForName(pName); - if(foundIndex != -1) - Param1= foundIndex; - case CONNECT: - { - - if (BLUETOOTH_HANDLE_UNDEFIEND == IOMapComm.BtConnectTable[Param2].HandleNr && foundIndex != -1) - { - - /* Connection not occupied */ - VarsComm.ActiveUpdate = UPD_CONNECT; - VarsComm.BtCmdData.ParamOne = Param1; - VarsComm.BtCmdData.ParamTwo = Param2; - } - else - { - - /* Connection occupied */ - ReturnVal = BTCONNECTFAIL; - *pRetVal = BTCONNECTFAIL; - } - } - break; - - case DISCONNECT: - { - VarsComm.ActiveUpdate = UPD_DISCONNECT; - VarsComm.BtCmdData.ParamOne = Param1; - } - break; - - case DISCONNECTALL: - { - VarsComm.ActiveUpdate = UPD_DISCONNECTALL; - } - break; - - case SEARCH: - { - VarsComm.ActiveUpdate = UPD_SEARCH; - IOMapComm.BtDeviceNameCnt = 0; - IOMapComm.BtDeviceCnt = 0; - VarsComm.BtCmdData.ParamOne = 0; - } - break; - case STOPSEARCH: - { - if (UPD_SEARCH == (VarsComm.ActiveUpdate)) - { - VarsComm.BtCmdData.ParamOne = 1; - } - else - { - *pRetVal = SUCCESS; - } - } - break; - case REMOVEDEVICE: - { - VarsComm.ActiveUpdate = UPD_REMOVEDEVICE; - VarsComm.BtCmdData.ParamOne = Param1; - } - break; - case VISIBILITY: - { - VarsComm.ActiveUpdate = UPD_VISIBILITY; - VarsComm.BtCmdData.ParamOne = Param1; - } - break; - case SETCMDMODE: - { - VarsComm.ActiveUpdate = UPD_REQCMDMODE; - } - break; - case FACTORYRESET: - { - VarsComm.ActiveUpdate = UPD_FACTORYRESET; - } - break; - case BTON: - { - if (BT_STATE_OFF & (pMapUi->BluetoothState)) - { - VarsComm.ActiveUpdate = UPD_RESET; - } - else - { - - /* Device is already on*/ - *pRetVal = SUCCESS; - } - } - break; - case BTOFF: - { - VarsComm.ActiveUpdate = UPD_OFF; - } - break; - case SENDDATA: - { - - /* Param2 indicates the port that the data should be */ - /* be sent on - param1 indicates the number of data */ - /* to be sent. pName is the pointer to the data */ - if (Param1 <= sizeof(VarsComm.BtModuleOutBuf.Buf)) - { - if ('\0' != IOMapComm.BtConnectTable[Param2].Name[0]) - { - VarsComm.BtCmdData.ParamOne = Param1; - VarsComm.BtCmdData.ParamTwo = Param2; - VarsComm.BtCmdData.ParamThree = Param3; - memcpy((VarsComm.BtModuleOutBuf.Buf), pName, Param1); - VarsComm.ActiveUpdate = UPD_SENDDATA; - } - else - { - ReturnVal = (UWORD)ERR_COMM_CHAN_NOT_READY; - ReturnVal |= 0x8000; - } - } - else - { - ReturnVal = (UWORD)ERR_COMM_BUFFER_FULL; - ReturnVal |= 0x8000; - } - } - break; - case OPENSTREAM: - { - VarsComm.BtCmdData.ParamTwo = Param2; - VarsComm.ActiveUpdate = UPD_OPENSTREAM; - } - break; - case SETBTNAME: - { - VarsComm.ActiveUpdate = UPD_BRICKNAME; - } - break; - case EXTREAD: - { - VarsComm.ActiveUpdate = UPD_EXTREAD; - } - break; - case PINREQ: - { - - /* This is an incomming pinrequest for connection on connection 0 because */ - /* ActiveUpdate is idle (if it was incomming it is not idle) */ - cCommCopyBdaddr((IOMapComm.BtConnectTable[0].BdAddr), &(IOMapComm.BtInBuf.Buf[2])); - pMapUi->BluetoothState |= (BT_CONNECT_REQUEST | BT_PIN_REQUEST); - VarsComm.pValidPinCode = NULL; - VarsComm.ActiveUpdate = UPD_PINREQ; - } - break; - case CONNECTREQ: - { - VarsComm.ActiveUpdate = UPD_CONNECTREQ; - } - break; - } - } - return(ReturnVal); -} - -void cCommPinCode(UBYTE *pPinCode) -{ - VarsComm.pValidPinCode = pPinCode; - if (REQPIN == (*(VarsComm.pRetVal))) - { - *(VarsComm.pRetVal) = INPROGRESS; - } -} - -void cCommClrConnTable(void) -{ - UBYTE Tmp; - - for (Tmp = 0; Tmp < SIZE_OF_BT_CONNECT_TABLE; Tmp++) - { - CLEARConnEntry(Tmp); - } - IOMapComm.BrickData.BtStateStatus &= ~(BT_CONNECTION_0_ENABLE | BT_CONNECTION_1_ENABLE | BT_CONNECTION_2_ENABLE | BT_CONNECTION_3_ENABLE); - pMapUi->BluetoothState &= ~BT_STATE_CONNECTED; - pMapUi->Flags |= UI_REDRAW_STATUS; -} - - /* search the BT table */ -SBYTE cCommSearchBTDevTableForName(UBYTE *name) { - UBYTE Tmp; - for (Tmp = 0; Tmp < SIZE_OF_BT_DEVICE_TABLE; Tmp++) - { - if (0 == strcmp((char*)(IOMapComm.BtDeviceTable[Tmp].Name), (char*)name)) - return Tmp; - } - return -1; -} diff --git a/AT91SAM7S256/Source/c_comm.h b/AT91SAM7S256/Source/c_comm.h deleted file mode 100644 index 06137b2..0000000 --- a/AT91SAM7S256/Source/c_comm.h +++ /dev/null @@ -1,154 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: c_comm.h $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_comm $ -// -// Platform C -// - -#ifndef C_COMM -#define C_COMM - - -#define BLUECORE_RESET_TIME 100 // Time in mS -#define BLUECORE_WAIT_BEFORE_INIT 5000 // Time in mS -#define BLUETOOTH_HANDLE_UNDEFIEND 0xFF - -/* Constants related to BtAdrStatus*/ -enum -{ - COLDBOOT, - INITIALIZED, - BTADRERROR -}; - - -enum -{ - USB_CH, - BT_CH, - HISPEED_CH, - NO_OF_CHANNELS -}; - - -/* enum reffering to BT update */ -enum -{ - UPD_BRICKNAME, - UPD_FACTORYRESET, - UPD_OPENSTREAM, - UPD_REQCMDMODE, - UPD_CONNECT, - UPD_CONNECTREQ, - UPD_PINREQ, - UPD_DISCONNECT, - UPD_DISCONNECTALL, - UPD_REMOVEDEVICE, - UPD_SEARCH, - UPD_RESET, - UPD_EXTREAD, - UPD_SENDFILE, - UPD_OFF, - UPD_VISIBILITY, - UPD_SENDDATA, - UPD_IDLE -}; - -/* Constants reffering to Protocol */ -enum -{ - DIRECT_CMD = 0x00, - SYSTEM_CMD = 0x01, - REPLY_CMD = 0x02, -#ifdef ARMDEBUG - DEBUG_CMD = 0x0d, -#endif - NO_REPLY_BIT = 0x80 -}; - -typedef struct -{ - ULONG RemFileSize; - UWORD RemMsgSize; - UWORD SrcHandle; - UWORD DstHandle; - UWORD Timer; - UBYTE FileName[FILENAME_LENGTH + 1]; - UBYTE Cmd; - UBYTE SlotNo; -}EXTTX; - -typedef struct -{ - UBYTE Buf[256]; - UWORD InPtr; - UWORD OutPtr; -}BTDATA; - -typedef struct -{ - UBYTE Buf[256]; - UWORD InPtr; - UWORD OutPtr; -}HSDATA; - -typedef struct -{ - UBYTE Status; - UBYTE Type; - UBYTE Handle; - UBYTE Cmd; -}EXTMODE; - -typedef struct -{ - UBYTE ParamOne; - UBYTE ParamTwo; - UBYTE ParamThree; -}BTCMD; - -typedef struct -{ - UBYTE BtUpdateDataConnectNr; - UBYTE BtBcPinLevel; - UBYTE BtResetTimeCnt; - UWORD BtWaitTimeCnt; - BTDATA BtModuleInBuf; - BTDATA BtModuleOutBuf; - BTCMD BtCmdData; - UBYTE HsState; - HSDATA HsModuleInBuf; - HSDATA HsModuleOutBuf; - EXTTX ExtTx; - EXTMODE ExtMode[NO_OF_CHANNELS]; - UBYTE ActiveUpdate; - UBYTE UpdateState; - UBYTE BtDeviceIndex; - UBYTE CmdSwitchCnt; - UBYTE StreamStateCnt; - UBYTE CloseConn0Cnt; - UBYTE DiscAllCnt; - UBYTE ResetBtCnt; - UBYTE BtState; - UWORD *pRetVal; - UWORD RetVal; - UBYTE *pValidPinCode; - UBYTE LookUpCnt; - UBYTE BtAdrStatus; - UBYTE BtCmdModeWaitCnt; -}VARSCOMM; - -void cCommInit(void* pHeader); -void cCommCtrl(void); -void cCommExit(void); - -extern const HEADER cComm; - -#endif diff --git a/AT91SAM7S256/Source/c_comm.iom b/AT91SAM7S256/Source/c_comm.iom deleted file mode 100644 index 2dfe994..0000000 --- a/AT91SAM7S256/Source/c_comm.iom +++ /dev/null @@ -1,223 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 9-06-08 14:57 $ -// -// Filename $Workfile:: c_comm.iom $ -// -// Version $Revision:: 2 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_comm $ -// -// Platform C -// - -#ifndef CCOMM_IOM -#define CCOMM_IOM - -#define pMapComm ((IOMAPCOMM*)(pHeaders[ENTRY_COMM]->pIOMap)) - -#define SIZE_OF_USBBUF 64 -#define USB_PROTOCOL_OVERHEAD 1 + 1 /* Command type byte + Command */ -#define SIZE_OF_USBDATA (SIZE_OF_USBBUF - USB_PROTOCOL_OVERHEAD) -#define SIZE_OF_HSBUF 128 -#define SIZE_OF_BTBUF 128 - -#define BT_CMD_BYTE 1 -#define SIZE_OF_BT_DEVICE_TABLE 30 -#define SIZE_OF_BT_CONNECT_TABLE 4 /* Index 0 is alway incomming connections */ -#define MAX_BT_MSG_SIZE 60000L - -#define BT_DEFAULT_INQUIRY_MAX 0 /* Unlimited no */ -#define BT_DEFAULT_INQUIRY_TIMEOUT_LO 15 /* 15 x 1,28 Sec = 19,2 Sec */ - - -// Constants reffering to BtState -enum -{ - BT_ARM_OFF, - BT_ARM_CMD_MODE, - BT_ARM_DATA_MODE, -}; - -//Constant reffering to BtStateStatus -#define BT_BRICK_VISIBILITY 0x01 -#define BT_BRICK_PORT_OPEN 0x02 -#define BT_CONNECTION_0_ENABLE 0x10 -#define BT_CONNECTION_1_ENABLE 0x20 -#define BT_CONNECTION_2_ENABLE 0x40 -#define BT_CONNECTION_3_ENABLE 0x80 - -//Constant reffering to BtHwStatus -#define BT_ENABLE 0x00 -#define BT_DISABLE 0x01 - -// Constants reffering to HsFlags -enum -{ - HS_UPDATE = 1 -}; - -// Constants reffering to HsState -enum -{ - HS_INITIALISE = 1, - HS_INIT_RECEIVER, - HS_SEND_DATA, - HS_DISABLE -}; - -//Constants refering to DeviceStatus within DeviceTable -enum -{ - BT_DEVICE_EMPTY = 0x00, - BT_DEVICE_UNKNOWN = 0x01, - BT_DEVICE_KNOWN = 0x02, - BT_DEVICE_NAME = 0x40, - BT_DEVICE_AWAY = 0x80 -}; - -/* Interface between command other modules */ -enum -{ - SENDFILE, - SEARCH, - STOPSEARCH, - CONNECT, - DISCONNECT, - DISCONNECTALL, - REMOVEDEVICE, - VISIBILITY, - SETCMDMODE, - OPENSTREAM, - SENDDATA, - FACTORYRESET, - BTON, - BTOFF, - SETBTNAME, - EXTREAD, - PINREQ, - CONNECTREQ, - CONNECTBYNAME -}; - - -enum -{ - LR_SUCCESS = 0x50, - LR_COULD_NOT_SAVE, - LR_STORE_IS_FULL, - LR_ENTRY_REMOVED, - LR_UNKOWN_ADDR -}; - -enum -{ - USB_CMD_READY = 0x01, - BT_CMD_READY = 0x02, - HS_CMD_READY = 0x04 -}; - -typedef struct -{ - UBYTE Buf[SIZE_OF_USBBUF]; - UBYTE InPtr; - UBYTE OutPtr; - UBYTE Spare1; - UBYTE Spare2; -}USBBUF; - -typedef struct -{ - UBYTE Buf[SIZE_OF_HSBUF]; - UBYTE InPtr; - UBYTE OutPtr; - UBYTE Spare1; - UBYTE Spare2; -}HSBUF; - -typedef struct -{ - UBYTE Buf[SIZE_OF_BTBUF]; - UBYTE InPtr; - UBYTE OutPtr; - UBYTE Spare1; - UBYTE Spare2; -}BTBUF; - -typedef struct -{ - UBYTE Name[SIZE_OF_BT_NAME]; - UBYTE ClassOfDevice[SIZE_OF_CLASS_OF_DEVICE]; - UBYTE BdAddr[SIZE_OF_BDADDR]; - UBYTE DeviceStatus; - UBYTE Spare1; - UBYTE Spare2; - UBYTE Spare3; -}BDDEVICETABLE; - -typedef struct -{ - UBYTE Name[SIZE_OF_BT_NAME]; - UBYTE ClassOfDevice[SIZE_OF_CLASS_OF_DEVICE]; - UBYTE PinCode[16]; - UBYTE BdAddr[SIZE_OF_BDADDR]; - UBYTE HandleNr; - UBYTE StreamStatus; - UBYTE LinkQuality; - UBYTE Spare; -}BDCONNECTTABLE; - -typedef struct -{ - UBYTE Name[SIZE_OF_BT_NAME]; - UBYTE BluecoreVersion[2]; - UBYTE BdAddr[SIZE_OF_BDADDR]; - UBYTE BtStateStatus; - UBYTE BtHwStatus; - UBYTE TimeOutValue; - UBYTE Spare1; - UBYTE Spare2; - UBYTE Spare3; -}BRICKDATA; - -typedef struct -{ - UWORD (*pFunc)(UBYTE, UBYTE, UBYTE, UBYTE, UBYTE*, UWORD*); - void (*pFunc2)(UBYTE*); - - // BT related entries - BDDEVICETABLE BtDeviceTable[SIZE_OF_BT_DEVICE_TABLE]; - BDCONNECTTABLE BtConnectTable[SIZE_OF_BT_CONNECT_TABLE]; - - //General brick data - BRICKDATA BrickData; - - BTBUF BtInBuf; - BTBUF BtOutBuf; - - // HI Speed related entries - HSBUF HsInBuf; - HSBUF HsOutBuf; - - // USB related entries - USBBUF UsbInBuf; - USBBUF UsbOutBuf; - USBBUF UsbPollBuf; - - UBYTE BtDeviceCnt; - UBYTE BtDeviceNameCnt; - - UBYTE HsFlags; - UBYTE HsSpeed; - UBYTE HsState; - - UBYTE UsbState; - -}IOMAPCOMM; - - -#endif - - - diff --git a/AT91SAM7S256/Source/c_display.c b/AT91SAM7S256/Source/c_display.c deleted file mode 100644 index 6b15495..0000000 --- a/AT91SAM7S256/Source/c_display.c +++ /dev/null @@ -1,849 +0,0 @@ -// -// Programmer -// -// Date init 14.12.2004 -// -// Reviser $Author: Dkflebun $ -// -// Revision date $Date: 9-06-08 13:35 $ -// -// Filename $Workfile:: c_display.c $ -// -// Version $Revision: 2 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_disp $ -// -// Platform C -// - -#include -#include "stdconst.h" -#include "modules.h" -#include "c_display.iom" -#include "c_display.h" -#include "d_display.h" - - -static IOMAPDISPLAY IOMapDisplay; -static VARSDISPLAY VarsDisplay; - -const HEADER cDisplay = -{ - 0x000A0001L, - "Display", - cDisplayInit, - cDisplayCtrl, - cDisplayExit, - (void *)&IOMapDisplay, - (void *)&VarsDisplay, - (UWORD)sizeof(IOMapDisplay), - (UWORD)sizeof(VarsDisplay), - 0x0000 //Code size - not used so far -}; - - -const SCREEN_CORDINATE SCREEN_CORDINATES[SCREENS] = -{ - { 0, 0,DISPLAY_WIDTH,DISPLAY_HEIGHT }, // Background - { 0, 8,DISPLAY_WIDTH,DISPLAY_HEIGHT - 8 }, // Large - { 0, 8,DISPLAY_WIDTH,24 } // Small -}; - -const SCREEN_CORDINATE SELECT_FRAME_CORDINATES = -{ - 38,41,24,24 -}; - - -const SCREEN_CORDINATE MENUICON_CORDINATES[MENUICONS] = -{ - { DISPLAY_MENUICONS_X_OFFS,DISPLAY_MENUICONS_Y,24,24 }, // Left - { DISPLAY_MENUICONS_X_OFFS + DISPLAY_MENUICONS_X_DIFF,DISPLAY_MENUICONS_Y,24,24 }, // Center - { DISPLAY_MENUICONS_X_OFFS + DISPLAY_MENUICONS_X_DIFF * 2,DISPLAY_MENUICONS_Y,24,24 },// Right -}; - -const SCREEN_CORDINATE STATUSICON_CORDINATES[STATUSICONS] = -{ - { 0, 0,12, 8 }, // Bluetooth - { 12, 0,12, 8 }, // Usb - { 76, 0,12, 8 }, // Vm - { 88, 0,12, 8 } // Battery -}; - - -const SCREEN_CORDINATE STEPICON_CORDINATES[STEPICONS] = -{ - { 11,16,11,16 }, // Step 1 - { 28,16,11,16 }, // Step 2 - { 45,16,11,16 }, // Step 3 - { 62,16,11,16 }, // Step 4 - { 79,16,11,16 } // Step 5 -}; - - -void cDisplaySetPixel(UBYTE X,UBYTE Y) -{ - if ((X < DISPLAY_WIDTH) && (Y < DISPLAY_HEIGHT)) - { - IOMapDisplay.Display[(Y / 8) * DISPLAY_WIDTH + X] |= (1 << (Y % 8)); - } -} - - -void cDisplayClrPixel(UBYTE X,UBYTE Y) -{ - if ((X < DISPLAY_WIDTH) && (Y < DISPLAY_HEIGHT)) - { - IOMapDisplay.Display[(Y / 8) * DISPLAY_WIDTH + X] &= ~(1 << (Y % 8)); - } -} - - -void cDisplayChar(FONT *pFont,UBYTE On,UBYTE X,UBYTE Y,UBYTE Char) -{ - UBYTE *pSource; - UBYTE FontWidth; - UBYTE FontHeight; - UBYTE Items; - UBYTE Item; - UBYTE TmpY; - - - Items = pFont->ItemsX * pFont->ItemsY; - Item = Char - ' '; - if (Item < Items) - { - FontWidth = pFont->ItemPixelsX; - pSource = (UBYTE*)&pFont->Data[Item * FontWidth]; - while (FontWidth--) - { - TmpY = 0; - FontHeight = pFont->ItemPixelsY; - while (FontHeight--) - { - if (On == TRUE) - { - if (((*pSource) & (1 << TmpY))) - { - cDisplaySetPixel(X,Y + TmpY); - } - else - { - cDisplayClrPixel(X,Y + TmpY); - } - } - else - { - if (((*pSource) & (1 << TmpY))) - { - cDisplayClrPixel(X,Y + TmpY); - } - else - { - cDisplaySetPixel(X,Y + TmpY); - } - } - TmpY++; - } - X++; - pSource++; - } - } -} - - -void cDisplayString(FONT *pFont,UBYTE X,UBYTE Y,UBYTE *pString) -{ - UBYTE *pSource; - UBYTE *pDestination; - UBYTE FontWidth; - UBYTE Line; - UBYTE Items; - UBYTE Item; - - - Line = (Y & 0xF8) / 8; - Items = pFont->ItemsX * pFont->ItemsY; - pDestination = (UBYTE*)&IOMapDisplay.Display[Line * DISPLAY_WIDTH + X]; - - while (*pString) - { - Item = *pString - ' '; - if (Item < Items) - { - FontWidth = pFont->ItemPixelsX; - pSource = (UBYTE*)&pFont->Data[Item * FontWidth]; - while (FontWidth--) - { - *pDestination = *pSource; - pDestination++; - pSource++; - } - } - pString++; - } -} - - -void cDisplayUpdateScreen(SCREEN_CORDINATE *pCord,BMPMAP *pBitmap) -{ - UBYTE *pSource; - UBYTE *pDestination; - UBYTE Line; - UBYTE Lines; - - if (pBitmap) - { - if ((((pBitmap->StartY + pCord->StartY) & 0x07) == 0) && ((pBitmap->PixelsY & 0x07) == 0)) - { - pSource = pBitmap->Data; - Line = (pBitmap->StartY + pCord->StartY) / 8; - Lines = Line + pBitmap->PixelsY / 8; - while (Line < Lines) - { - pDestination = &IOMapDisplay.Display[Line * DISPLAY_WIDTH + pBitmap->StartX + pCord->StartX]; - memcpy(pDestination,pSource,(size_t)pBitmap->PixelsX); - pSource += pBitmap->PixelsX; - Line++; - } - } - } -} - - -void cDisplayCenterString(FONT *pFont,UBYTE *pString,UBYTE Line) -{ - UWORD Chars; - UBYTE Column; - - if (pString) - { - Chars = 0; - while (pString[Chars]) - { - Chars++; - } - Column = (DISPLAY_WIDTH - Chars * pFont->ItemPixelsX) / 2; - cDisplayString(pFont,Column,Line * 8,pString); - } -} - - -void cDisplayUpdateMenuIcon(UBYTE *pIcon,SCREEN_CORDINATE *pCord) -{ - UBYTE *pDestination; - UBYTE Line; - UBYTE Column; - UBYTE Lines; - UBYTE Columns; - - if (((pCord->StartY & 0x07) == 0) && ((pCord->PixelsY & 0x07) == 0)) - { - Line = pCord->StartY / 8; - Lines = Line + pCord->PixelsY / 8; - Columns = pCord->StartX + pCord->PixelsX; - if (pIcon != NULL) - { - while (Line < Lines) - { - Column = pCord->StartX; - pDestination = &IOMapDisplay.Display[Line * DISPLAY_WIDTH + Column]; - - while (Column < Columns) - { - *pDestination |= *pIcon; - pIcon++; - pDestination++; - Column++; - } - Line++; - } - } - else - { - while (Line < Lines) - { - pDestination = &IOMapDisplay.Display[Line * DISPLAY_WIDTH + pCord->StartX]; - memset(pDestination,0,(size_t)pCord->PixelsX); - Line++; - } - } - } -} - - -void cDisplayUpdateIcon(ICON *pIcons,UBYTE Index,SCREEN_CORDINATE *pCord) -{ - UBYTE *pSource; - UBYTE *pDestination; - UBYTE Line; - UBYTE Lines; - - if (pIcons) - { - if ((Index > 0) && (Index <= (pIcons->ItemsX * pIcons->ItemsY))) - { - Index--; - if (((pCord->StartY & 0x07) == 0) && ((pCord->PixelsY & 0x07) == 0)) - { - Line = pCord->StartY / 8; - Lines = Line + pCord->PixelsY / 8; - pSource = &pIcons->Data[((Index / pIcons->ItemsX) * pIcons->ItemsX * pIcons->ItemPixelsX * pIcons->ItemPixelsY / 8) + ((Index % pIcons->ItemsX) * pIcons->ItemPixelsX)]; - while (Line < Lines) - { - pDestination = &IOMapDisplay.Display[Line * DISPLAY_WIDTH + pCord->StartX]; - memcpy(pDestination,pSource,(size_t)pCord->PixelsX); - pSource += (pIcons->ItemPixelsX * pIcons->ItemsX); - Line++; - } - } - } - else - { - if (((pCord->StartY & 0x07) == 0) && ((pCord->PixelsY & 0x07) == 0)) - { - Line = pCord->StartY / 8; - Lines = Line + pCord->PixelsY / 8; - while (Line < Lines) - { - pDestination = &IOMapDisplay.Display[Line * DISPLAY_WIDTH + pCord->StartX]; - memset(pDestination,0,(size_t)pCord->PixelsX); - Line++; - } - } - } - } -} - - -void cDisplayLineX(UBYTE X1,UBYTE X2,UBYTE Y) -{ - UBYTE X; - UBYTE M; - - M = 1 << (Y % 8); - Y >>= 3; - for (X = X1;X < X2;X++) - { - IOMapDisplay.Display[Y * DISPLAY_WIDTH + X] |= M; - } -} - -void cDisplayLineY(UBYTE X,UBYTE Y1,UBYTE Y2) -{ - UBYTE Y; - - for (Y = Y1;Y < Y2;Y++) - { - IOMapDisplay.Display[(Y / 8) * DISPLAY_WIDTH + X] |= (1 << (Y % 8)); - } -} - -void cDisplayFrame(SCREEN_CORDINATE *pCord) -{ - cDisplayLineX(pCord->StartX,pCord->StartX + pCord->PixelsX - 1,pCord->StartY); - cDisplayLineY(pCord->StartX,pCord->StartY,pCord->StartY + pCord->PixelsY - 1); - cDisplayLineY(pCord->StartX + pCord->PixelsX - 1,pCord->StartY,pCord->StartY + pCord->PixelsY - 1); -} - - -void cDisplayEraseLine(UBYTE Line) -{ - memset(&IOMapDisplay.Display[Line * DISPLAY_WIDTH], 0x00, DISPLAY_WIDTH); -} - - -void cDisplayErase(void) -{ - memset(&IOMapDisplay.Display[0], 0x00, DISPLAY_WIDTH*DISPLAY_HEIGHT/8); -} - - -void cDisplayEraseScreen(SCREEN_CORDINATE *pCord) -{ - UBYTE *pDestination; - UBYTE Line; - UBYTE Lines; - - if (((pCord->StartY & 0x07) == 0) && ((pCord->PixelsY & 0x07) == 0)) - { - Line = pCord->StartY / 8; - Lines = Line + pCord->PixelsY / 8; - - while (Line < Lines) - { - pDestination = &IOMapDisplay.Display[Line * DISPLAY_WIDTH + pCord->StartX]; - memset(pDestination,0,(size_t)pCord->PixelsX); - Line++; - } - } -} - - -void cDisplayDraw(UBYTE Cmd,UBYTE On,UBYTE X1,UBYTE Y1,UBYTE X2,UBYTE Y2) -{ - switch (Cmd) - { - case DISPLAY_ERASE_ALL : - { - cDisplayErase(); - } - break; - - case DISPLAY_PIXEL : - { - if (On == TRUE) - { - cDisplaySetPixel(X1,Y1); - } - else - { - cDisplayClrPixel(X1,Y1); - } - } - break; - - case DISPLAY_HORISONTAL_LINE : - { - if (On == TRUE) - { - if (X1 > X2) - { - cDisplayLineX(X2,X1,Y1); - } - else - { - cDisplayLineX(X1,X2,Y1); - } - } - } - break; - - case DISPLAY_VERTICAL_LINE : - { - if (On == TRUE) - { - if (Y1 > Y2) - { - cDisplayLineY(X1,Y2,Y1); - } - else - { - cDisplayLineY(X1,Y1,Y2); - } - } - } - break; - - case DISPLAY_CHAR : - { - cDisplayChar(IOMapDisplay.pFont,On,X1,Y1,X2); - } - break; - - } -} - - -void cDisplayInit(void* pHeader) -{ - dDisplayInit(); - IOMapDisplay.Display = (UBYTE*)IOMapDisplay.Normal; - IOMapDisplay.pFunc = &cDisplayDraw; - IOMapDisplay.EraseMask = 0; - IOMapDisplay.UpdateMask = 0; - IOMapDisplay.TextLinesCenterFlags = 0; - IOMapDisplay.Flags = DISPLAY_REFRESH | DISPLAY_ON; - VarsDisplay.ErasePointer = 0; - VarsDisplay.UpdatePointer = 0; -} - - -void cDisplayCtrl(void) -{ - ULONG TmpMask; - UBYTE Tmp; - SCREEN_CORDINATE Cordinate; - - if (!(IOMapDisplay.Flags & DISPLAY_POPUP)) - { - if (IOMapDisplay.Display == (UBYTE*)IOMapDisplay.Popup) - { - IOMapDisplay.Display = VarsDisplay.DisplaySave; - } - } - else - { - if (IOMapDisplay.Display != (UBYTE*)IOMapDisplay.Popup) - { - VarsDisplay.DisplaySave = IOMapDisplay.Display; - IOMapDisplay.Display = (UBYTE*)IOMapDisplay.Popup; - } - } - - if (IOMapDisplay.EraseMask) - { - - VarsDisplay.ErasePointer = 31; - while ((VarsDisplay.ErasePointer) && (!(IOMapDisplay.EraseMask & (0x00000001 << VarsDisplay.ErasePointer)))) - { - VarsDisplay.ErasePointer--; - } - - TmpMask = IOMapDisplay.EraseMask & (1 << VarsDisplay.ErasePointer); - if ((TmpMask & TEXTLINE_BITS)) - { - Tmp = 0; - while (!(TmpMask & TEXTLINE_BIT(Tmp))) - { - Tmp++; - } - if (Tmp < TEXTLINES) - { - cDisplayEraseLine(Tmp); - } - } - else - { - if ((TmpMask & MENUICON_BITS)) - { - Tmp = 0; - while (!(TmpMask & MENUICON_BIT(Tmp))) - { - Tmp++; - } - if (Tmp < MENUICONS) - { - cDisplayEraseScreen((SCREEN_CORDINATE*)&MENUICON_CORDINATES[Tmp]); - } - } - else - { - if ((TmpMask & STATUSICON_BITS)) - { - Tmp = 0; - while (!(TmpMask & STATUSICON_BIT(Tmp))) - { - Tmp++; - } - if (Tmp < STATUSICONS) - { - cDisplayEraseScreen((SCREEN_CORDINATE*)&STATUSICON_CORDINATES[Tmp]); - } - } - else - { - if ((TmpMask & SCREEN_BITS)) - { - Tmp = 0; - while (!(TmpMask & SCREEN_BIT(Tmp))) - { - Tmp++; - } - if (Tmp < SCREENS) - { - cDisplayEraseScreen((SCREEN_CORDINATE*)&SCREEN_CORDINATES[Tmp]); - } - if ((TmpMask & SCREEN_BIT(SCREEN_LARGE))) - { - if ((IOMapDisplay.UpdateMask & SPECIAL_BIT(TOPLINE))) - { - cDisplayLineX(0,DISPLAY_WIDTH - 1,9); - IOMapDisplay.UpdateMask &= ~SPECIAL_BIT(TOPLINE); - } - } - } - else - { - if ((TmpMask & BITMAP_BITS)) - { - Tmp = 0; - while (!(TmpMask & BITMAP_BIT(Tmp))) - { - Tmp++; - } - if (Tmp < BITMAPS) - { - Cordinate.StartX = VarsDisplay.pOldBitmaps[Tmp]->StartX; - Cordinate.StartY = VarsDisplay.pOldBitmaps[Tmp]->StartY; - Cordinate.PixelsX = VarsDisplay.pOldBitmaps[Tmp]->PixelsX; - Cordinate.PixelsY = VarsDisplay.pOldBitmaps[Tmp]->PixelsY; - cDisplayEraseScreen(&Cordinate); - } - } - else - { - if ((TmpMask & SPECIAL_BITS)) - { - Tmp = 0; - while (!(TmpMask & SPECIAL_BIT(Tmp))) - { - Tmp++; - } - switch (Tmp) - { - case FRAME_SELECT : - { - } - break; - - case MENUTEXT : - { - cDisplayEraseLine(TEXTLINE_5); - } - break; - - case STATUSTEXT : - { - cDisplayEraseLine(TEXTLINE_1); - } - break; - - case STEPLINE : - { - } - break; - - case TOPLINE : - { - } - break; - - } - } - else - { - if ((TmpMask & STEPICON_BITS)) - { - Tmp = 0; - while (!(TmpMask & STEPICON_BIT(Tmp))) - { - Tmp++; - } - if (Tmp < STEPICONS) - { - cDisplayEraseScreen((SCREEN_CORDINATE*)&STEPICON_CORDINATES[Tmp]); - } - } - } - } - } - } - } - } - IOMapDisplay.EraseMask &= ~TmpMask; - - if (++VarsDisplay.ErasePointer >= 32) - { - VarsDisplay.ErasePointer = 0; - } - VarsDisplay.UpdatePointer = 0; - } - else - { - if (IOMapDisplay.UpdateMask) - { - - VarsDisplay.UpdatePointer = 31; - while ((VarsDisplay.UpdatePointer) && (!(IOMapDisplay.UpdateMask & (0x00000001 << VarsDisplay.UpdatePointer)))) - { - VarsDisplay.UpdatePointer--; - } - TmpMask = IOMapDisplay.UpdateMask & (0x00000001 << VarsDisplay.UpdatePointer); - - if ((TmpMask & TEXTLINE_BITS)) - { - Tmp = 0; - while (!(TmpMask & TEXTLINE_BIT(Tmp))) - { - Tmp++; - } - if (Tmp < TEXTLINES) - { - if ((IOMapDisplay.TextLinesCenterFlags & (UBYTE)TmpMask)) - { - cDisplayCenterString(IOMapDisplay.pFont,IOMapDisplay.pTextLines[Tmp],TEXTLINE_1 + Tmp); - } - else - { - cDisplayString(IOMapDisplay.pFont,0,Tmp * 8,IOMapDisplay.pTextLines[Tmp]); - } - } - } - else - { - if ((TmpMask & MENUICON_BITS)) - { - Tmp = 0; - while (!(TmpMask & MENUICON_BIT(Tmp))) - { - Tmp++; - } - if (Tmp < MENUICONS) - { - cDisplayUpdateMenuIcon(IOMapDisplay.pMenuIcons[Tmp],(SCREEN_CORDINATE*)&MENUICON_CORDINATES[Tmp]); - } - } - else - { - if ((TmpMask & STATUSICON_BITS)) - { - Tmp = 0; - while (!(TmpMask & STATUSICON_BIT(Tmp))) - { - Tmp++; - } - if (Tmp < STATUSICONS) - { - cDisplayUpdateIcon(IOMapDisplay.pStatusIcons,IOMapDisplay.StatusIcons[Tmp],(SCREEN_CORDINATE*)&STATUSICON_CORDINATES[Tmp]); - } - } - else - { - if ((TmpMask & SCREEN_BITS)) - { - Tmp = 0; - while (!(TmpMask & SCREEN_BIT(Tmp))) - { - Tmp++; - } - if (Tmp < SCREENS) - { - cDisplayUpdateScreen((SCREEN_CORDINATE*)&SCREEN_CORDINATES[Tmp],IOMapDisplay.pScreens[Tmp]); - } - } - else - { - if ((TmpMask & BITMAP_BITS)) - { - Tmp = 0; - while (!(TmpMask & BITMAP_BIT(Tmp))) - { - Tmp++; - } - if (Tmp < BITMAPS) - { - VarsDisplay.pOldBitmaps[Tmp] = IOMapDisplay.pBitmaps[Tmp]; - cDisplayUpdateScreen((SCREEN_CORDINATE*)&SCREEN_CORDINATES[SCREEN_BACKGROUND],IOMapDisplay.pBitmaps[Tmp]); - } - } - else - { - if ((TmpMask & SPECIAL_BITS)) - { - Tmp = 0; - while (!(TmpMask & SPECIAL_BIT(Tmp))) - { - Tmp++; - } - switch (Tmp) - { - case FRAME_SELECT : - { - cDisplayFrame((SCREEN_CORDINATE*)&SELECT_FRAME_CORDINATES); - } - break; - - case MENUTEXT : - { - cDisplayCenterString(IOMapDisplay.pFont,IOMapDisplay.pMenuText,TEXTLINE_5); - } - break; - - case STATUSTEXT : - { - cDisplayCenterString(IOMapDisplay.pFont,IOMapDisplay.pStatusText,TEXTLINE_1); - } - break; - - case STEPLINE : - { - cDisplayLineX(22,28,20); - cDisplayLineX(39,45,20); - cDisplayLineX(56,62,20); - cDisplayLineX(73,79,20); - } - break; - - case TOPLINE : - { - cDisplayLineX(0,DISPLAY_WIDTH - 1,9); - } - break; - - } - } - else - { - if ((TmpMask & STEPICON_BITS)) - { - Tmp = 0; - while (!(TmpMask & STEPICON_BIT(Tmp))) - { - Tmp++; - } - if (Tmp < STEPICONS) - { - cDisplayUpdateIcon(IOMapDisplay.pStepIcons,IOMapDisplay.StepIcons[Tmp],(SCREEN_CORDINATE*)&STEPICON_CORDINATES[Tmp]); - } - } - } - } - } - } - } - } - IOMapDisplay.TextLinesCenterFlags &= (UBYTE)(~TmpMask); - IOMapDisplay.UpdateMask &= ~TmpMask; - if (++VarsDisplay.UpdatePointer >= 32) - { - VarsDisplay.UpdatePointer = 0; - } - } - VarsDisplay.ErasePointer = 0; - } - if (!(IOMapDisplay.Flags & DISPLAY_POPUP)) - { - if (!(IOMapDisplay.Flags & DISPLAY_REFRESH_DISABLED)) - { - if ((IOMapDisplay.Flags & DISPLAY_ON)) - { - dDisplayOn(TRUE); - } - else - { - dDisplayOn(FALSE); - } - if (!(dDisplayUpdate(DISPLAY_HEIGHT,DISPLAY_WIDTH,(UBYTE*)IOMapDisplay.Normal))) - { - IOMapDisplay.Flags &= ~DISPLAY_BUSY; - if (!(IOMapDisplay.Flags & DISPLAY_REFRESH)) - { - IOMapDisplay.Flags |= DISPLAY_REFRESH_DISABLED; - } - } - else - { - IOMapDisplay.Flags |= DISPLAY_BUSY; - } - } - else - { - if ((IOMapDisplay.Flags & DISPLAY_REFRESH)) - { - IOMapDisplay.Flags &= ~DISPLAY_REFRESH_DISABLED; - } - } - } - else - { - dDisplayUpdate(DISPLAY_HEIGHT,DISPLAY_WIDTH,(UBYTE*)IOMapDisplay.Popup); - } -} - - -void cDisplayExit(void) -{ - dDisplayExit(); -} - diff --git a/AT91SAM7S256/Source/c_display.h b/AT91SAM7S256/Source/c_display.h deleted file mode 100644 index 56b6744..0000000 --- a/AT91SAM7S256/Source/c_display.h +++ /dev/null @@ -1,43 +0,0 @@ -// -// Programmer -// -// Date init 14.12.2004 -// -// Reviser $Author:: Dkandlun $ -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: c_display.h $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_disp $ -// -// Platform C -// - -#ifndef C_DISPLAY -#define C_DISPLAY - -#ifndef INCLUDE_OS - -typedef struct -{ - UBYTE *DisplaySave; - BMPMAP *pOldBitmaps[BITMAPS]; - UBYTE ErasePointer; - UBYTE UpdatePointer; -}VARSDISPLAY; - -#endif - - -void cDisplayInit(void* pHeader); -void cDisplayCtrl(void); -void cDisplayExit(void); - - -extern const HEADER cDisplay; - - -#endif diff --git a/AT91SAM7S256/Source/c_display.iom b/AT91SAM7S256/Source/c_display.iom deleted file mode 100644 index 2e1ab74..0000000 --- a/AT91SAM7S256/Source/c_display.iom +++ /dev/null @@ -1,177 +0,0 @@ -// -// Programmer -// -// Date init 14.12.2004 -// -// Reviser $Author:: Dkandlun $ -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: c_display.iom $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_disp $ -// -// Platform C -// - -#ifndef CDISPLAY_IOM -#define CDISPLAY_IOM - -#define pMapDisplay ((IOMAPDISPLAY*)(pHeaders[ENTRY_DISPLAY]->pIOMap)) - -// Constants related to simple draw entry (x = dont care) -enum -{ - DISPLAY_ERASE_ALL = 0x00, // W - erase entire screen (CMD,x,x,x,x,x) - DISPLAY_PIXEL = 0x01, // W - set pixel (on/off) (CMD,TRUE/FALSE,X,Y,x,x) - DISPLAY_HORISONTAL_LINE = 0x02, // W - draw horisontal line (CMD,TRUE,X1,Y1,X2,x) - DISPLAY_VERTICAL_LINE = 0x03, // W - draw vertical line (CMD,TRUE,X1,Y1,x,Y2) - DISPLAY_CHAR = 0x04 // W - draw char (actual font) (CMD,TRUE,X1,Y1,Char,x) -}; - -// Constants related to Flags -enum -{ - DISPLAY_ON = 0x01, // W - Display on - DISPLAY_REFRESH = 0x02, // W - Enable refresh - DISPLAY_POPUP = 0x08, // W - Use popup display memory - DISPLAY_REFRESH_DISABLED = 0x40, // R - Refresh disabled - DISPLAY_BUSY = 0x80 // R - Refresh in progress -}; - - -#define DISPLAY_HEIGHT 64 // Y pixels -#define DISPLAY_WIDTH 100 // X pixels - -#define DISPLAY_MENUICONS_Y 40 -#define DISPLAY_MENUICONS_X_OFFS 7 -#define DISPLAY_MENUICONS_X_DIFF 31 - -#define DISPLAY_IDLE ((pMapDisplay->EraseMask == 0) && (pMapDisplay->UpdateMask == 0)) - -enum TEXTLINE_NO // Used in macro "TEXTLINE_BIT" -{ - TEXTLINE_1, // Upper most line - TEXTLINE_2, // - TEXTLINE_3, // - TEXTLINE_4, // - TEXTLINE_5, // - TEXTLINE_6, // - TEXTLINE_7, // - TEXTLINE_8, // Buttom line - TEXTLINES -}; - -enum MENUICON_NO // Used in macro "MENUICON_BIT" -{ - MENUICON_LEFT, // Left icon - MENUICON_CENTER, // Center icon - MENUICON_RIGHT, // Right icon - MENUICONS -}; - -enum SPECIAL_NO // Used in macro "SPECIAL_BIT" -{ - FRAME_SELECT, // Center icon select frame - STATUSTEXT, // Status text (BT name) - MENUTEXT, // Center icon text - STEPLINE, // Step collection lines - TOPLINE, // Top status underline - SPECIALS -}; - -enum STATUSICON_NO // Used in macro "STATUSICON_BIT" -{ - STATUSICON_BLUETOOTH, // BlueTooth status icon collection - STATUSICON_USB, // USB status icon collection - STATUSICON_VM, // VM status icon collection - STATUSICON_BATTERY, // Battery status icon collection - STATUSICONS -}; - -enum SCREEN_NO // Used in macro "SCREEN_BIT" -{ - SCREEN_BACKGROUND, // Entire screen - SCREEN_LARGE, // Entire screen except status line - SCREEN_SMALL, // Screen between menu icons and status line - SCREENS -}; - -enum BITMAP_NO // Used in macro "BITMAP_BIT" -{ - BITMAP_1, // Bitmap 1 - BITMAP_2, // Bitmap 2 - BITMAP_3, // Bitmap 3 - BITMAP_4, // Bitmap 4 - BITMAPS -}; - -enum STEP_NO // Used in macro "STEPICON_BIT" -{ - STEPICON_1, // Left most step icon - STEPICON_2, // - STEPICON_3, // - STEPICON_4, // - STEPICON_5, // Right most step icon - STEPICONS -}; - -#define SCREEN_BITS ((ULONG)0xE0000000) // Executed as 1. -#define STEPICON_BITS ((ULONG)0x1F000000) // Executed as 2. -#define BITMAP_BITS ((ULONG)0x00F00000) // Executed as 3. -#define MENUICON_BITS ((ULONG)0x000E0000) // Executed as 4. -#define STATUSICON_BITS ((ULONG)0x0001E000) // Executed as 5. -#define SPECIAL_BITS ((ULONG)0x00001F00) // Executed as 6. -#define TEXTLINE_BITS ((ULONG)0x000000FF) // Executed as 7. - -#define SCREEN_BIT(No) ((ULONG)0x20000000 << (No)) -#define STEPICON_BIT(No) ((ULONG)0x01000000 << (No)) -#define BITMAP_BIT(No) ((ULONG)0x00100000 << (No)) -#define MENUICON_BIT(No) ((ULONG)0x00020000 << (No)) -#define STATUSICON_BIT(No) ((ULONG)0x00002000 << (No)) -#define SPECIAL_BIT(No) ((ULONG)0x00000100 << (No)) -#define TEXTLINE_BIT(No) ((ULONG)0x00000001 << (No)) - - -typedef struct -{ - void (*pFunc)(UBYTE,UBYTE,UBYTE,UBYTE,UBYTE,UBYTE); // Simple draw entry - - ULONG EraseMask; // Section erase mask (executed first) - ULONG UpdateMask; // Section update mask (executed next) - - FONT *pFont; // Pointer to font file - UBYTE *pTextLines[TEXTLINES]; // Pointer to text strings - - UBYTE *pStatusText; // Pointer to status text string - ICON *pStatusIcons; // Pointer to status icon collection file - - BMPMAP *pScreens[SCREENS]; // Pointer to screen bitmap file - BMPMAP *pBitmaps[BITMAPS]; // Pointer to free bitmap files - - UBYTE *pMenuText; // Pointer to menu icon text (NULL == none) - UBYTE *pMenuIcons[MENUICONS]; // Pointer to menu icon images (NULL == none) - - ICON *pStepIcons; // Pointer to step icon collection file - - UBYTE *Display; // Display content copied to physical display every 17 mS - - UBYTE StatusIcons[STATUSICONS]; // Index in status icon collection file (index = 0 -> none) - - UBYTE StepIcons[STEPICONS]; // Index in step icon collection file (index = 0 -> none) - - UBYTE Flags; // Update flags enumerated above - - UBYTE TextLinesCenterFlags; // Mask to center TextLines - - UBYTE Normal[DISPLAY_HEIGHT / 8][DISPLAY_WIDTH]; // Raw display memory for normal screen - UBYTE Popup[DISPLAY_HEIGHT / 8][DISPLAY_WIDTH]; // Raw display memory for popup screen -} -IOMAPDISPLAY; - -#endif - - - diff --git a/AT91SAM7S256/Source/c_input.c b/AT91SAM7S256/Source/c_input.c deleted file mode 100644 index 2cb9be1..0000000 --- a/AT91SAM7S256/Source/c_input.c +++ /dev/null @@ -1,1335 +0,0 @@ - -// -// Date init 14.12.2004 -// -// Revision date $Date:: 3/21/09 10:31a $ -// -// Filename $Workfile:: c_input.c $ -// -// Version $Revision:: 39 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_inpu $ -// -// Platform C -// - -#include "stdconst.h" -#include "modules.h" -#include "c_input.h" -#include "d_input.h" -#include "c_output.iom" -#include "c_loader.iom" -#include - - -#define INVALID_RELOAD_NORMAL 20 -#define INVALID_RELOAD_SOUND 300 -#define INVALID_RELOAD_COLOR 400 - -#define ROT_SLOW_SPEED 30 -#define ROT_OV_SAMPLING 7 - -#define VCC_SENSOR 5000L -#define VCC_SENSOR_DIODE 4300L -#define AD_MAX 1023L - -#define REFLECTIONSENSORMIN (1906L/(VCC_SENSOR/AD_MAX)) -#define REFLECTIONSENSORMAX ((AD_MAX * 4398L)/VCC_SENSOR) -#define REFLECTIONSENSORPCTDYN (UBYTE)(((REFLECTIONSENSORMAX - REFLECTIONSENSORMIN) * 100L)/AD_MAX) - -#define NEWLIGHTSENSORMIN (800L/(VCC_SENSOR/AD_MAX)) -#define NEWLIGHTSENSORMAX ((AD_MAX * 4400L)/VCC_SENSOR) -#define NEWLIGHTSENSORPCTDYN (UBYTE)(((NEWLIGHTSENSORMAX - NEWLIGHTSENSORMIN) * 100L)/AD_MAX) - -#define NEWSOUNDSENSORMIN (650L/(VCC_SENSOR/AD_MAX)) -#define NEWSOUNDSENSORMAX ((AD_MAX * 4980L)/VCC_SENSOR) -#define NEWSOUNDSENSORPCTDYN (UBYTE)(((NEWSOUNDSENSORMAX - NEWSOUNDSENSORMIN) * 100L)/AD_MAX) - -/* Remember this is ARM AD converter - 3,3 VDC as max voltage */ -/* When in color mode background value is substracted => min = 0!!! */ -#define COLORSENSORBGMIN (214/(3300/AD_MAX)) -#define COLORSENSORMIN (1L/(3300/AD_MAX)) /* 1 inserted else div 0 (1L/(120/AD_MAX)) */ -#define COLORSENSORMAX ((AD_MAX * 3300L)/3300) -#define COLORSENSORPCTDYN (UBYTE)(((COLORSENSORMAX - COLORSENSORMIN) * 100L)/AD_MAX) -#define COLORSENSORBGPCTDYN (UBYTE)(((COLORSENSORMAX - COLORSENSORBGMIN) * 100L)/AD_MAX) - -enum -{ - POWER = 0x00, - NO_POWER = 0x01, - ACTIVE = 0x02, - ALWAYS_ACTIVE = 0x04, - DIGI_0_HIGH = 0x08, - DIGI_1_HIGH = 0x10, - DIGI_0_IN = 0x20, - DIGI_1_IN = 0x40, - CUSTOM_SETUP = 0x80 -}; - -static IOMAPINPUT IOMapInput; -static VARSINPUT VarsInput; - -const HEADER cInput = -{ - 0x00030001L, - "Input", - cInputInit, - cInputCtrl, - cInputExit, - (void *)&IOMapInput, - (void *)&VarsInput, - (UWORD)sizeof(IOMapInput), - (UWORD)sizeof(VarsInput), - 0x0000 //Code size - not used so far -}; - -void cInputCalcFullScale(UWORD *pRawVal, UWORD ZeroPointOffset, UBYTE PctFullScale, UBYTE InvState); -void cInputCalcSensorValue(UWORD NewSensorRaw, UWORD *pOldSensorRaw, SWORD *pSensorValue, - UBYTE *pBoolean, UBYTE *pDebounce, UBYTE *pSampleCnt, - UBYTE *LastAngle, UBYTE *pEdgeCnt, UBYTE Slope, - UBYTE Mode); -void cInputSetupType(UBYTE Port, UBYTE *pType, UBYTE OldType); -void cInputSetupCustomSensor(UBYTE Port); -void cInputCalcSensorValues(UBYTE No); -UBYTE cInputInitColorSensor(UBYTE Port, UBYTE *pInitStatus); -void cInputCalibrateColor(COLORSTRUCT *pC, UWORD *pNewVals); -SWORD cInputTempConv(UWORD InputVal); - -void cInputInit(void* pHeader) -{ - UBYTE Tmp; - - memset(IOMapInput.Colors, 0, sizeof(IOMapInput.Colors)); - memset(VarsInput.VarsColor, 0, sizeof(VarsInput.VarsColor)); - - /* Init IO map */ - for (Tmp = 0; Tmp < NO_OF_INPUTS; Tmp++) - { - IOMapInput.Inputs[Tmp].SensorType = NO_SENSOR; - IOMapInput.Inputs[Tmp].SensorMode = RAWMODE; - IOMapInput.Inputs[Tmp].SensorRaw = 0; - IOMapInput.Inputs[Tmp].SensorValue = 0; - IOMapInput.Inputs[Tmp].SensorBoolean = 0; - IOMapInput.Inputs[Tmp].InvalidData = INVALID_DATA; - IOMapInput.Inputs[Tmp].DigiPinsDir = 0; - IOMapInput.Inputs[Tmp].DigiPinsOut = 0; - IOMapInput.Inputs[Tmp].CustomActiveStatus = CUSTOMINACTIVE; - IOMapInput.Inputs[Tmp].CustomZeroOffset = 0; - IOMapInput.Inputs[Tmp].CustomPctFullScale = 0; - dInputRead0(Tmp, &(IOMapInput.Inputs[Tmp].DigiPinsIn)); - dInputRead1(Tmp, &(IOMapInput.Inputs[Tmp].DigiPinsIn)); - - VarsInput.EdgeCnt[Tmp] = 0; - VarsInput.InputDebounce[Tmp] = 0; - VarsInput.LastAngle[Tmp] = 0; - VarsInput.SampleCnt[Tmp] = 0; - VarsInput.InvalidTimer[Tmp] = INVALID_RELOAD_NORMAL; - VarsInput.OldSensorType[Tmp] = NO_SENSOR; - } - - VarsInput.ColorStatus = 0; - VarsInput.ColorCnt = 0; - - dInputInit(); -} - -void cInputCtrl(void) -{ - UBYTE Tmp; - - - if (VarsInput.ColorStatus) - { - switch(VarsInput.ColorCnt) - { - case 0: - { - VarsInput.ColorCnt = 1; - dInputSetColorClkInput(); - - } - break; - case 1: - { - VarsInput.ColorCnt = 2; - } - break; - case 2: - { - VarsInput.ColorCnt = 0; - dInputGetAllColors(IOMapInput.Colors, VarsInput.ColorStatus); - } - break; - default: - { - VarsInput.ColorCnt = 0; - } - break; - } - } - - for (Tmp = 0; Tmp < NO_OF_INPUTS; Tmp++) - { - UBYTE sType = IOMapInput.Inputs[Tmp].SensorType; - UBYTE *pType = &IOMapInput.Inputs[Tmp].SensorType; - UBYTE oldType = VarsInput.OldSensorType[Tmp]; - - if (sType != oldType) - { - - /* Clear all variables for this sensor */ - VarsInput.EdgeCnt[Tmp] = 0; - VarsInput.InputDebounce[Tmp] = 0; - VarsInput.LastAngle[Tmp] = 0; - VarsInput.SampleCnt[Tmp] = 0; - VarsInput.ColorStatus &= ~(0x01< 928) - InputVal = 928; - InputVal = cInputTempConv(InputVal - 290); - InputVal = InputVal + 200; - InputVal = (UWORD)(((SLONG)InputVal * (SLONG)1023)/(SLONG)900); - } - else if (sType == LIGHT_ACTIVE || sType == LIGHT_INACTIVE) - { - cInputCalcFullScale(&InputVal, NEWLIGHTSENSORMIN, NEWLIGHTSENSORPCTDYN, TRUE); - } - else if (sType == SOUND_DB || sType == SOUND_DBA) - { - cInputCalcFullScale(&InputVal, NEWSOUNDSENSORMIN, NEWSOUNDSENSORPCTDYN, TRUE); - } - else if (sType == CUSTOM) - { - cInputCalcFullScale(&InputVal, IOMapInput.Inputs[No].CustomZeroOffset, IOMapInput.Inputs[No].CustomPctFullScale, FALSE); - } - cInputCalcSensorValue( InputVal, - &(IOMapInput.Inputs[No].SensorRaw), - &(IOMapInput.Inputs[No].SensorValue), - &(IOMapInput.Inputs[No].SensorBoolean), - &(VarsInput.InputDebounce[No]), - &(VarsInput.SampleCnt[No]), - &(VarsInput.LastAngle[No]), - &(VarsInput.EdgeCnt[No]), - ((IOMapInput.Inputs[No].SensorMode) & SLOPEMASK), - ((IOMapInput.Inputs[No].SensorMode) & MODEMASK)); - } - break; - - /* Tripple case intended */ - case LOWSPEED: - case LOWSPEED_9V: - case HIGHSPEED: - { - } - break; - - /* Four cases intended */ - case COLORRED: - case COLORGREEN: - case COLORBLUE: - case COLORNONE: - { - - UWORD InputVal; - switch (IOMapInput.Colors[No].CalibrationState) - { - case SENSOROFF: - { - - /* Make sure that sensor data are invalid while unplugged*/ - VarsInput.InvalidTimer[No] = INVALID_RELOAD_COLOR; - IOMapInput.Inputs[No].InvalidData = INVALID_DATA; - - /* Check if sensor has been attached */ - if (dInputCheckColorStatus(No)) - { - - /* Sensor has been attached now get cal data */ - VarsInput.VarsColor[No].ColorInitState = 0; - (IOMapInput.Colors[No].CalibrationState) = SENSORCAL; - } - } - break; - case SENSORCAL: - { - - UBYTE Status; - if (FALSE == cInputInitColorSensor(No, &Status)) - { - - /* Color sensor has been removed during calibration */ - (IOMapInput.Colors[No].CalibrationState) = SENSOROFF; - } - - if (TRUE == Status) - { - - /* Use clock to detect errors */ - dInputSetDirInDigi0(No); - (IOMapInput.Colors[No].CalibrationState) = 0; - } - } - break; - default: - { - if (dInputGetColor(No, &(IOMapInput.Inputs[No].ADRaw))) - { - InputVal = IOMapInput.Inputs[No].ADRaw; - cInputCalcFullScale(&InputVal, COLORSENSORBGMIN, COLORSENSORBGPCTDYN, FALSE); - cInputCalcSensorValue(InputVal, - &(IOMapInput.Inputs[No].SensorRaw), - &(IOMapInput.Inputs[No].SensorValue), - &(IOMapInput.Inputs[No].SensorBoolean), - &(VarsInput.InputDebounce[No]), - &(VarsInput.SampleCnt[No]), - &(VarsInput.LastAngle[No]), - &(VarsInput.EdgeCnt[No]), - ((IOMapInput.Inputs[No].SensorMode) & SLOPEMASK), - ((IOMapInput.Inputs[No].SensorMode) & MODEMASK)); - } - else - { - IOMapInput.Colors[No].CalibrationState = SENSOROFF; - } - } - break; - } - } - break; - case COLORFULL: - { - switch (IOMapInput.Colors[No].CalibrationState) - { - case SENSOROFF: - { - - /* Make sure that sensor data are invalid while unplugged */ - VarsInput.InvalidTimer[No] = INVALID_RELOAD_COLOR; - IOMapInput.Inputs[No].InvalidData = INVALID_DATA; - - /* Check if sensor has been attached */ - if (dInputCheckColorStatus(No)) - { - - /* Sensor has been attached now get cal data */ - VarsInput.VarsColor[No].ColorInitState = 0; - (IOMapInput.Colors[No].CalibrationState) = SENSORCAL; - } - } - break; - case SENSORCAL: - { - UBYTE Status; - - if (FALSE == cInputInitColorSensor(No, &Status)) - { - - /* Color sensor has been removed during calibration */ - (IOMapInput.Colors[No].CalibrationState) = SENSOROFF; - VarsInput.ColorStatus &= ~(0x01<SensorRaw[RED]) > (pC->SensorRaw[BLUE] )) && - ((pC->SensorRaw[RED]) > (pC->SensorRaw[GREEN]))) - { - - /* If all 3 colors are less than 65 OR (Less that 110 and bg less than 40)*/ - if (((pC->SensorRaw[RED]) < 65) || - (((pC->SensorRaw[BLANK]) < 40) && ((pC->SensorRaw[RED]) < 110))) - { - IOMapInput.Inputs[No].SensorValue = BLACKCOLOR; - } - else - { - if (((((pC->SensorRaw[BLUE]) >> 2) + ((pC->SensorRaw[BLUE]) >> 3) + (pC->SensorRaw[BLUE])) < (pC->SensorRaw[GREEN])) && - ((((pC->SensorRaw[GREEN]) << 1)) > (pC->SensorRaw[RED]))) - { - IOMapInput.Inputs[No].SensorValue = YELLOWCOLOR; - } - else - { - - if ((((pC->SensorRaw[GREEN]) << 1) - ((pC->SensorRaw[GREEN]) >> 2)) < (pC->SensorRaw[RED])) - { - - IOMapInput.Inputs[No].SensorValue = REDCOLOR; - } - else - { - - if ((((pC->SensorRaw[BLUE]) < 70) || - ((pC->SensorRaw[GREEN]) < 70)) || - (((pC->SensorRaw[BLANK]) < 140) && ((pC->SensorRaw[RED]) < 140))) - { - IOMapInput.Inputs[No].SensorValue = BLACKCOLOR; - } - else - { - IOMapInput.Inputs[No].SensorValue = WHITECOLOR; - } - } - } - } - } - else - { - - /* Red is not the dominant color */ - if ((pC->SensorRaw[GREEN]) > (pC->SensorRaw[BLUE])) - { - - /* Green is the dominant color */ - /* If all 3 colors are less than 40 OR (Less that 70 and bg less than 20)*/ - if (((pC->SensorRaw[GREEN]) < 40) || - (((pC->SensorRaw[BLANK]) < 30) && ((pC->SensorRaw[GREEN]) < 70))) - { - IOMapInput.Inputs[No].SensorValue = BLACKCOLOR; - } - else - { - if ((((pC->SensorRaw[BLUE]) << 1)) < (pC->SensorRaw[RED])) - { - IOMapInput.Inputs[No].SensorValue = YELLOWCOLOR; - } - else - { - if ((((pC->SensorRaw[RED]) + ((pC->SensorRaw[RED])>>2)) < (pC->SensorRaw[GREEN])) || - (((pC->SensorRaw[BLUE]) + ((pC->SensorRaw[BLUE])>>2)) < (pC->SensorRaw[GREEN]))) - { - IOMapInput.Inputs[No].SensorValue = GREENCOLOR; - } - else - { - if ((((pC->SensorRaw[RED]) < 70) || - ((pC->SensorRaw[BLUE]) < 70)) || - (((pC->SensorRaw[BLANK]) < 140) && ((pC->SensorRaw[GREEN]) < 140))) - { - IOMapInput.Inputs[No].SensorValue = BLACKCOLOR; - } - else - { - IOMapInput.Inputs[No].SensorValue = WHITECOLOR; - } - } - } - } - } - else - { - - /* Blue is the most dominant color */ - /* Colors can be blue, white or black */ - /* If all 3 colors are less than 48 OR (Less that 85 and bg less than 25)*/ - if (((pC->SensorRaw[BLUE]) < 48) || - (((pC->SensorRaw[BLANK]) < 25) && ((pC->SensorRaw[BLUE]) < 85))) - { - IOMapInput.Inputs[No].SensorValue = BLACKCOLOR; - } - else - { - if ((((((pC->SensorRaw[RED]) * 48) >> 5) < (pC->SensorRaw[BLUE])) && - ((((pC->SensorRaw[GREEN]) * 48) >> 5) < (pC->SensorRaw[BLUE]))) - || - (((((pC->SensorRaw[RED]) * 58) >> 5) < (pC->SensorRaw[BLUE])) || - ((((pC->SensorRaw[GREEN]) * 58) >> 5) < (pC->SensorRaw[BLUE])))) - { - IOMapInput.Inputs[No].SensorValue = BLUECOLOR; - } - else - { - - /* Color is white or Black */ - if ((((pC->SensorRaw[RED]) < 60) || - ((pC->SensorRaw[GREEN]) < 60)) || - (((pC->SensorRaw[BLANK]) < 110) && ((pC->SensorRaw[BLUE]) < 120))) - { - IOMapInput.Inputs[No].SensorValue = BLACKCOLOR; - } - else - { - if ((((pC->SensorRaw[RED]) + ((pC->SensorRaw[RED]) >> 3)) < (pC->SensorRaw[BLUE])) || - (((pC->SensorRaw[GREEN]) + ((pC->SensorRaw[GREEN]) >> 3)) < (pC->SensorRaw[BLUE]))) - { - IOMapInput.Inputs[No].SensorValue = BLUECOLOR; - } - else - { - IOMapInput.Inputs[No].SensorValue = WHITECOLOR; - } - } - } - } - } - } - } - else - { - IOMapInput.Colors[No].CalibrationState = SENSOROFF; - VarsInput.ColorStatus &= ~(0x01< THRESHOLD_FALSE) - { - PresentBoolean = FALSE; - } - else - { - if (NewSensorRaw < THRESHOLD_TRUE) - { - PresentBoolean = TRUE; - } - } - } - else - { - - /* This is dynamic measure method */ - if (NewSensorRaw > (ACTUAL_AD_RES - Slope)) - { - PresentBoolean = FALSE; - } - else - { - if (NewSensorRaw < Slope) - { - PresentBoolean = TRUE; - } - else - { - Delta = *pOldSensorRaw - NewSensorRaw; - if (Delta < 0) - { - if (-Delta > Slope) - { - PresentBoolean = FALSE; - } - } - else - { - if (Delta > Slope) - { - PresentBoolean = TRUE; - } - } - } - } - } - *pOldSensorRaw = NewSensorRaw; - - switch(Mode) - { - - case RAWMODE: - { - *pSensorValue = NewSensorRaw; - } - break; - - case BOOLEANMODE: - { - *pSensorValue = PresentBoolean; - } - break; - - case TRANSITIONCNTMODE: - { - if ((*pDebounce) > 0) - { - (*pDebounce)--; - } - else - { - if (*pBoolean != PresentBoolean) - { - (*pDebounce) = DEBOUNCERELOAD; - (*pSensorValue)++; - } - } - } - break; - - case PERIODCOUNTERMODE: - { - if ((*pDebounce) > 0) - { - (*pDebounce)--; - } - else - { - if (*pBoolean != PresentBoolean) - { - (*pDebounce) = DEBOUNCERELOAD; - *pBoolean = PresentBoolean; - if (++(*pEdgeCnt) > 1) - { - if (PresentBoolean == 0) - { - (*pEdgeCnt) = 0; - (*pSensorValue)++; - } - } - } - } - } - break; - - case PCTFULLSCALEMODE: - { - - /* Output is 0-100 pct */ - *pSensorValue = ((NewSensorRaw) * 100)/SENSOR_RESOLUTION; - } - break; - - case FAHRENHEITMODE: - { - - /* Fahrenheit mode goes from -40 to 158 degrees */ - *pSensorValue = (((ULONG)(NewSensorRaw) * 900L)/SENSOR_RESOLUTION) - 200; - *pSensorValue = ((180L * (ULONG)(*pSensorValue))/100L) + 320; - } - break; - - case CELSIUSMODE: - { - - /* Celsius mode goes from -20 to 70 degrees */ - *pSensorValue = (((ULONG)(NewSensorRaw * 900L)/SENSOR_RESOLUTION) - 200); - } - break; - - case ANGLESTEPSMODE: - { - *pBoolean = PresentBoolean; - - if (NewSensorRaw < ANGLELIMITA) - { - Sample = 0; - } - else - { - if (NewSensorRaw < ANGLELIMITB) - { - Sample = 1; - } - else - { - if (NewSensorRaw < ANGLELIMITC) - { - Sample = 2; - } - else - { - Sample = 3; - } - } - } - - switch (*LastAngle) - { - case 0 : - { - if (Sample == 1) - { - if ((*pSampleCnt) >= ROT_SLOW_SPEED ) - { - - if (++(*pSampleCnt) >= (ROT_SLOW_SPEED + ROT_OV_SAMPLING)) - { - (*pSensorValue)++; - (*LastAngle) = Sample; - } - } - else - { - (*pSensorValue)++; - (*LastAngle) = Sample; - } - } - if (Sample == 2) - { - (*pSensorValue)--; - (*LastAngle) = Sample; - } - if (Sample == 0) - { - if ((*pSampleCnt) < ROT_SLOW_SPEED) - { - (*pSampleCnt)++; - } - } - } - break; - case 1 : - { - if (Sample == 3) - { - (*pSensorValue)++; - (*LastAngle) = Sample; - } - if (Sample == 0) - { - (*pSensorValue)--; - (*LastAngle) = Sample; - } - (*pSampleCnt) = 0; - } - break; - case 2 : - { - if (Sample == 0) - { - (*pSensorValue)++; - (*LastAngle) = Sample; - } - if (Sample == 3) - { - (*pSensorValue)--; - (*LastAngle) = Sample; - } - (*pSampleCnt) = 0; - } - break; - case 3 : - { - if (Sample == 2) - { - if ((*pSampleCnt) >= ROT_SLOW_SPEED) - { - - if (++(*pSampleCnt) >= (ROT_SLOW_SPEED + ROT_OV_SAMPLING)) - { - (*pSensorValue)++; - (*LastAngle) = Sample; - } - } - else - { - (*pSensorValue)++; - (*LastAngle) = Sample; - } - } - if (Sample == 1) - { - (*pSensorValue)--; - (*LastAngle) = Sample; - } - if (Sample == 3) - { - if ((*pSampleCnt) < ROT_SLOW_SPEED) - { - (*pSampleCnt)++; - } - } - } - break; - } - } - } - - *pBoolean = PresentBoolean; -} - -void cInputCalcFullScale(UWORD *pRawVal, UWORD ZeroPointOffset, UBYTE PctFullScale, UBYTE InvStatus) -{ - if (*pRawVal >= ZeroPointOffset) - { - *pRawVal -= ZeroPointOffset; - } - else - { - *pRawVal = 0; - } - - *pRawVal = (*pRawVal * 100)/PctFullScale; - if (*pRawVal > SENSOR_RESOLUTION) - { - *pRawVal = SENSOR_RESOLUTION; - } - if (TRUE == InvStatus) - { - *pRawVal = SENSOR_RESOLUTION - *pRawVal; - } -} - - -void cInputSetupType(UBYTE Port, UBYTE *pType, UBYTE OldType) -{ - - VarsInput.InvalidTimer[Port] = INVALID_RELOAD_NORMAL; - - /* If old type is color sensor in color lamp mode then turn off leds */ - switch (OldType) - { - case COLORRED: - case COLORGREEN: - case COLORBLUE: - case COLORFULL: - case COLOREXIT: - { - if (NO_SENSOR == *pType) - { - VarsInput.InvalidTimer[Port] = INVALID_RELOAD_COLOR; - *pType = COLOREXIT; - } - } - break; - } - switch(*pType) - { - case NO_SENSOR: - case SWITCH: - case TEMPERATURE: - { - dInputSetInactive(Port); - dInputSetDirInDigi0(Port); - dInputSetDirInDigi1(Port); - } - break; - - case REFLECTION: - case ANGLE: - { - dInputSetActive(Port); - dInputClearDigi0(Port); - dInputClearDigi1(Port); - } - break; - - case LIGHT_ACTIVE: - { - dInputSetInactive(Port); - dInputSetDigi0(Port); - dInputClearDigi1(Port); - } - break; - - case LIGHT_INACTIVE: - { - dInputSetInactive(Port); - dInputClearDigi0(Port); - dInputClearDigi1(Port); - } - break; - - case SOUND_DB: - { - VarsInput.InvalidTimer[Port] = INVALID_RELOAD_SOUND; - dInputSetInactive(Port); - dInputSetDigi0(Port); - dInputClearDigi1(Port); - } - break; - - case SOUND_DBA: - { - VarsInput.InvalidTimer[Port] = INVALID_RELOAD_SOUND; - dInputSetInactive(Port); - dInputClearDigi0(Port); - dInputSetDigi1(Port); - } - break; - - case CUSTOM: - { - cInputSetupCustomSensor(Port); - } - break; - - case LOWSPEED: - { - dInputSetInactive(Port); - dInputSetDigi0(Port); - dInputSetDigi1(Port); - } - break; - - case LOWSPEED_9V: - { - dInputSet9v(Port); - dInputSetDigi0(Port); - dInputSetDigi1(Port); - } - break; - - case HIGHSPEED: - { - dInputSetInactive(Port); - dInputSetDirInDigi0(Port); - dInputSetDirInDigi1(Port); - } - break; - - case COLORFULL: - case COLORRED: - case COLORGREEN: - case COLORBLUE: - case COLORNONE: - { - VarsInput.InvalidTimer[Port] = INVALID_RELOAD_COLOR; - dInputSetInactive(Port); - dInputSetDigi0(Port); - dInputSetDirInDigi1(Port); - IOMapInput.Colors[Port].CalibrationState = SENSORCAL; - VarsInput.VarsColor[Port].ColorInitState = 0; - } - break; - - default: - { - } - break; - } -} - -void cInputSetupCustomSensor(UBYTE Port) -{ - if ((IOMapInput.Inputs[Port].DigiPinsDir) & 0x01) - { - if ((IOMapInput.Inputs[Port].DigiPinsOut) & 0x01) - { - dInputSetDigi0(Port); - } - else - { - dInputClearDigi0(Port); - } - } - if ((IOMapInput.Inputs[Port].DigiPinsDir) & 0x02) - { - if ((IOMapInput.Inputs[Port].DigiPinsOut) & 0x02) - { - dInputSetDigi1(Port); - } - else - { - dInputClearDigi1(Port); - } - } - else - { - dInputSetDirInDigi1(Port); - } - - if (CUSTOMACTIVE == (IOMapInput.Inputs[Port].CustomActiveStatus)) - { - dInputSetActive(Port); - } - else - { - if (CUSTOM9V == (IOMapInput.Inputs[Port].CustomActiveStatus)) - { - dInputSet9v(Port); - } - else - { - dInputSetInactive(Port); - } - } -} - - -SWORD cInputTempConv(UWORD InputVal) -{ - static const long long TempCoeff[] = { -5425ll, 9261399ll, -6686663252ll, - 2573629857807ll, -822478326197838ll, 195856762719738784ll }; - const unsigned int TempCoeffShift = 48; - /* Replace the original table with polynomial. */ - int i; - long long Input = InputVal; - long long Output = TempCoeff[0]; - for (i = 1; i < sizeof TempCoeff / sizeof TempCoeff[0]; i++) - Output = Output * Input + TempCoeff[i]; - /* Round. */ - return Output + (1ll << TempCoeffShift - 1) >> TempCoeffShift; -} - - -UBYTE cInputInitColorSensor(UBYTE Port, UBYTE *pInitStatus) -{ - - *pInitStatus = FALSE; - switch(VarsInput.VarsColor[Port].ColorInitState) - { - case 0: - { - dInputSetDigi0(Port); - dInputSetDigi1(Port); - VarsInput.VarsColor[Port].ColorInitState++; - } - break; - case 1: - { - dInputClearDigi0(Port); - VarsInput.VarsColor[Port].ColorInitState++; - } - break; - - case 2: - { - dInputSetDigi0(Port); - VarsInput.VarsColor[Port].ColorInitState++; - } - break; - case 3: - { - - dInputClearDigi0(Port); - - /* Clear clock for 100mS - use pit timer*/ - dInputClearColor100msTimer(Port); - VarsInput.VarsColor[Port].ColorInitState++; - } - break; - case 4: - { - - /* Wait 100mS */ - if (dInputChkColor100msTimer(Port)) - { - VarsInput.VarsColor[Port].ColorInitState += 1; - } - } - break; - case 5: - { - UBYTE TmpType; - - if (COLOREXIT == IOMapInput.Inputs[Port].SensorType) - { - TmpType = COLORNONE; - } - else - { - TmpType = IOMapInput.Inputs[Port].SensorType; - } - dInputColorTx(Port, TmpType); - - /* Be ready to receive data from sensor */ - dInputSetDirInDigi1(Port); - VarsInput.VarsColor[Port].ReadCnt = 0; - VarsInput.VarsColor[Port].ColorInitState++; - } - break; - case 6: - { - UBYTE Data; - UBYTE DataCnt; - UBYTE *pData; - - DataCnt = (VarsInput.VarsColor[Port].ReadCnt); - pData = (UBYTE*)(IOMapInput.Colors[Port].Calibration); - - /* Read first byte of cal data */ - dInputReadCal(Port, &Data); - - pData[DataCnt] = Data; - - /* If all bytes has been read - then continue to next step */ - if (++(VarsInput.VarsColor[Port].ReadCnt) >= ((sizeof(IOMapInput.Colors[Port].Calibration) + sizeof(IOMapInput.Colors[Port].CalLimits)))) - { - VarsInput.VarsColor[Port].ColorInitState++; - } - } - break; - case 7: - { - - /* Check CRC then continue or restart if false */ - UWORD Crc, CrcCheck; - UBYTE Cnt; - UBYTE Data; - UBYTE *pData; - - dInputReadCal(Port, &Data); - Crc = (UWORD)(Data) << 8; - dInputReadCal(Port, &Data); - Crc += (UWORD)Data; - CrcCheck = 0x5AA5; - pData = (UBYTE*)(IOMapInput.Colors[Port].Calibration); - for (Cnt = 0; Cnt < (sizeof(IOMapInput.Colors[Port].Calibration) + sizeof(IOMapInput.Colors[Port].CalLimits)); Cnt++) - { - UWORD i,j; - UBYTE c; - c = pData[Cnt]; - for(i = 0; i != 8; c >>= 1, i++) - { - j = (c^CrcCheck) & 1; - CrcCheck >>= 1; - - if(j) - { - CrcCheck ^= 0xA001; - } - } - - } - if ((CrcCheck != Crc)) - { - - /* incorrect!!! try again */ - VarsInput.VarsColor[Port].ColorInitState = 0; - VarsInput.InvalidTimer[Port] = INVALID_RELOAD_COLOR; - } - else - { - - /* Correct crc sum -> calculate the calibration values then exit */ - VarsInput.VarsColor[Port].ColorInitState = 0; - - /* Sensor is almost ready - needs a little time to make first measurements */ - VarsInput.InvalidTimer[Port] = 10; - *pInitStatus = TRUE; - } - } - break; - default: - { - VarsInput.VarsColor[Port].ColorInitState = 0; - } - break; - } - return(dInputCheckColorStatus(Port)); -} - - -void cInputCalibrateColor(COLORSTRUCT *pC, UWORD *pNewVals) -{ - UBYTE CalRange; - - if ((pC->ADRaw[BLANK]) < pC->CalLimits[1]) - { - CalRange = 2; - } - else - { - if ((pC->ADRaw[BLANK]) < pC->CalLimits[0]) - { - CalRange = 1; - } - else - { - CalRange = 0; - } - } - - pNewVals[RED] = 0; - if ((pC->ADRaw[RED]) > (pC->ADRaw[BLANK])) - { - pNewVals[RED] = (UWORD)(((ULONG)((pC->ADRaw[RED]) - (pC->ADRaw[BLANK])) * (pC->Calibration[CalRange][RED])) >> 16); - } - - pNewVals[GREEN] = 0; - if ((pC->ADRaw[GREEN]) > (pC->ADRaw[BLANK])) - { - pNewVals[GREEN] = (UWORD)(((ULONG)((pC->ADRaw[GREEN]) - (pC->ADRaw[BLANK])) * (pC->Calibration[CalRange][GREEN])) >> 16); - } - - pNewVals[BLUE] = 0; - if ((pC->ADRaw[BLUE]) > (pC->ADRaw[BLANK])) - { - pNewVals[BLUE] = (UWORD)(((ULONG)((pC->ADRaw[BLUE]) -(pC->ADRaw[BLANK])) * (pC->Calibration[CalRange][BLUE])) >> 16); - } - - pNewVals[BLANK] = (pC->ADRaw[BLANK]); - cInputCalcFullScale(&(pNewVals[BLANK]), COLORSENSORBGMIN, COLORSENSORBGPCTDYN, FALSE); - (pNewVals[BLANK]) = (UWORD)(((ULONG)(pNewVals[BLANK]) * (pC->Calibration[CalRange][BLANK])) >> 16); -} - - -void cInputExit(void) -{ - dInputExit(); -} - diff --git a/AT91SAM7S256/Source/c_input.h b/AT91SAM7S256/Source/c_input.h deleted file mode 100644 index 4e508f3..0000000 --- a/AT91SAM7S256/Source/c_input.h +++ /dev/null @@ -1,67 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 14-01-09 10:33 $ -// -// Filename $Workfile:: c_input.h $ -// -// Version $Revision:: 7 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_inpu $ -// -// Platform C -// - -#ifndef C_INPUT -#define C_INPUT - -#ifdef INCLUDE_OS -extern const HEADER cInput; -#endif - -#include "c_input.iom" - -#define ACTUAL_AD_RES 1023L -#define SENSOR_RESOLUTION 1023L -#define DEBOUNCERELOAD 100 -#define THRESHOLD_FALSE (UWORD)(ACTUAL_AD_RES * 45L / 100L) -#define THRESHOLD_TRUE (UWORD)(ACTUAL_AD_RES * 55L / 100L) - -#define ANGLELIMITA (UWORD)(ACTUAL_AD_RES * 4400L / 10000L) -#define ANGLELIMITB (UWORD)(ACTUAL_AD_RES * 6600L / 10000L) -#define ANGLELIMITC (UWORD)(ACTUAL_AD_RES * 8900L / 10000L) - -#define FWDDIR 1 -#define RWDDIR 2 -#define MAXSAMPLECNT 5 - -typedef struct -{ - UBYTE ColorInputDebounce [NO_OF_COLORS]; - UBYTE ColorEdgeCnt [NO_OF_COLORS]; - UBYTE ColorLastAngle [NO_OF_COLORS]; - UBYTE ColorSampleCnt [NO_OF_COLORS]; - UBYTE ColorInitState; - UBYTE ReadCnt; -} VARSCOLOR; - - -typedef struct -{ - UWORD InvalidTimer [NO_OF_INPUTS]; - UBYTE InputDebounce [NO_OF_INPUTS]; - UBYTE EdgeCnt [NO_OF_INPUTS]; - UBYTE LastAngle [NO_OF_INPUTS]; - UBYTE OldSensorType [NO_OF_INPUTS]; - UBYTE SampleCnt [NO_OF_INPUTS]; - VARSCOLOR VarsColor [NO_OF_INPUTS]; - UBYTE ColorCnt; - UBYTE ColorStatus; -}VARSINPUT; - -void cInputInit(void* pHeader); -void cInputCtrl(void); -void cInputExit(void); - - -#endif diff --git a/AT91SAM7S256/Source/c_input.iom b/AT91SAM7S256/Source/c_input.iom deleted file mode 100644 index dee1309..0000000 --- a/AT91SAM7S256/Source/c_input.iom +++ /dev/null @@ -1,175 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 24-09-08 15:23 $ -// -// Filename $Workfile:: c_input.iom $ -// -// Version $Revision:: 16 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_inpu $ -// -// Platform C -// - -#ifndef CINPUT_IOM -#define CINPUT_IOM - -#define NO_OF_INPUTS 4 -#define pMapInput ((IOMAPINPUT*)(pHeaders[ENTRY_INPUT]->pIOMap)) - - -/* Constants related to sensor type */ -enum -{ - NO_SENSOR = 0, - SWITCH = 1, - TEMPERATURE = 2, - REFLECTION = 3, - ANGLE = 4, - LIGHT_ACTIVE = 5, - LIGHT_INACTIVE = 6, - SOUND_DB = 7, - SOUND_DBA = 8, - CUSTOM = 9, - LOWSPEED = 10, - LOWSPEED_9V = 11, - HIGHSPEED = 12, - COLORFULL = 13, - COLORRED = 14, - COLORGREEN = 15, - COLORBLUE = 16, - COLORNONE = 17, - COLOREXIT = 18, /* For internal use when going from color or Lamp to no_sensor*/ - NO_OF_SENSOR_TYPES = 18 -}; - -/* Constants related to sensor mode */ -enum -{ - RAWMODE = 0x00, - BOOLEANMODE = 0x20, - TRANSITIONCNTMODE = 0x40, - PERIODCOUNTERMODE = 0x60, - PCTFULLSCALEMODE = 0x80, - CELSIUSMODE = 0xA0, - FAHRENHEITMODE = 0xC0, - ANGLESTEPSMODE = 0xE0, - SLOPEMASK = 0x1F, - MODEMASK = 0xE0 -}; - -/* Constants related to Digital I/O */ -enum -{ - DIGI0 = 1, - DIGI1 = 2 -}; - -enum -{ - CUSTOMINACTIVE = 0x00, - CUSTOM9V = 0x01, - CUSTOMACTIVE = 0x02 -}; - -enum -{ - INVALID_DATA = 0x01 -}; - -/* Constants related to Colorstruct */ -enum -{ - RED, - GREEN, - BLUE, - BLANK, - NO_OF_COLORS -}; - - -/* Constants related to color sensor value using */ -/* Color sensor as color detector */ -enum -{ - BLACKCOLOR = 1, - BLUECOLOR = 2, - GREENCOLOR = 3, - YELLOWCOLOR = 4, - REDCOLOR = 5, - WHITECOLOR = 6 -}; - - -/* Constants related to Color CalibrationState */ -/* When STARTCAL is TRUE then calibration is */ -/* in progress */ -enum -{ - SENSORCAL = 0x01, - SENSOROFF = 0x02, - RUNNINGCAL = 0x20, - STARTCAL = 0x40, - RESETCAL = 0x80, -}; - -enum -{ - CAL_POINT_0, - CAL_POINT_1, - CAL_POINT_2, - NO_OF_POINTS -}; - - -typedef struct -{ - UWORD CustomZeroOffset; /* Set the offset of the custom sensor */ - UWORD ADRaw; - UWORD SensorRaw; - SWORD SensorValue; - - UBYTE SensorType; - UBYTE SensorMode; - UBYTE SensorBoolean; - - UBYTE DigiPinsDir; /* Direction of the Digital pins 1 is output 0 is input */ - UBYTE DigiPinsIn; /* Contains the status of the digital pins */ - UBYTE DigiPinsOut; /* Sets the output level of the digital pins */ - UBYTE CustomPctFullScale; /* Sets the Pct full scale of the custom sensor */ - UBYTE CustomActiveStatus; /* Sets the active or inactive state of the custom sensor */ - - UBYTE InvalidData; /* Indicates wether data is invalid (1) or valid (0) */ - - UBYTE Spare1; - UBYTE Spare2; - UBYTE Spare3; - -}INPUTSTRUCT; - -typedef struct -{ - - ULONG Calibration[NO_OF_POINTS][NO_OF_COLORS]; - UWORD CalLimits[NO_OF_POINTS - 1]; - UWORD ADRaw[NO_OF_COLORS]; - UWORD SensorRaw[NO_OF_COLORS]; - SWORD SensorValue[NO_OF_COLORS]; - UBYTE Boolean[NO_OF_COLORS]; - UBYTE CalibrationState; - UBYTE Free1; - UBYTE Free2; - UBYTE Free3; -}COLORSTRUCT; - -typedef struct -{ - INPUTSTRUCT Inputs[NO_OF_INPUTS]; - COLORSTRUCT Colors[NO_OF_INPUTS]; -}IOMAPINPUT; - -#endif - - - diff --git a/AT91SAM7S256/Source/c_ioctrl.c b/AT91SAM7S256/Source/c_ioctrl.c deleted file mode 100644 index daab322..0000000 --- a/AT91SAM7S256/Source/c_ioctrl.c +++ /dev/null @@ -1,78 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: c_ioctrl.c $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_ioct $ -// -// Platform C -// - - -#include "stdconst.h" -#include "modules.h" -#include "c_ioctrl.iom" -#include "c_ioctrl.h" -#include "d_ioctrl.h" - -static IOMAPIOCTRL IOMapIOCtrl; -static VARSIOCTRL VarsIOCtrl; - -const HEADER cIOCtrl = -{ - 0x00060001L, - "IOCtrl", - cIOCtrlInit, - cIOCtrlCtrl, - cIOCtrlExit, - (void *)&IOMapIOCtrl, - (void *)&VarsIOCtrl, - (UWORD)sizeof(IOMapIOCtrl), - (UWORD)sizeof(VarsIOCtrl), - 0x0000 //Code size - not used so far -}; - - -void cIOCtrlInit(void* pHeader) -{ - dIOCtrlSetPower(0); - dIOCtrlInit(); -} - - -void cIOCtrlCtrl(void) -{ - switch(IOMapIOCtrl.PowerOn) - { - case POWERDOWN: - { - dIOCtrlSetPower((POWERDOWN>>8)); - } - break; - case BOOT: - { - dIOCtrlSetPower((UBYTE)(BOOT>>8)); - dIOCtrlSetPwm((UBYTE)BOOT); - } - break; - default: - { - /* No need to change the default value */ - /* if value is boot or reset it should come */ - /* back from reset - setting the value to 0 */ - } - break; - } - dIOCtrlTransfer(); -} - - -void cIOCtrlExit(void) -{ - dIOCtrlExit(); -} - diff --git a/AT91SAM7S256/Source/c_ioctrl.h b/AT91SAM7S256/Source/c_ioctrl.h deleted file mode 100644 index 5ad4c8f..0000000 --- a/AT91SAM7S256/Source/c_ioctrl.h +++ /dev/null @@ -1,28 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: c_ioctrl.h $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_ioct $ -// -// Platform C -// - -#ifndef C_IOCTRL -#define C_IOCTRL - -typedef struct -{ - UBYTE Tmp; -}VARSIOCTRL; - -void cIOCtrlInit(void* pHeader); -void cIOCtrlCtrl(void); -void cIOCtrlExit(void); - -extern const HEADER cIOCtrl; -#endif diff --git a/AT91SAM7S256/Source/c_ioctrl.iom b/AT91SAM7S256/Source/c_ioctrl.iom deleted file mode 100644 index 9742d04..0000000 --- a/AT91SAM7S256/Source/c_ioctrl.iom +++ /dev/null @@ -1,35 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: c_ioctrl.iom $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_ioct $ -// -// Platform C -// - -#ifndef CIOCTRL_IOM -#define CIOCTRL_IOM - -#define pMapIoCtrl ((IOMAPIOCTRL*)(pHeaders[ENTRY_IOCTRL]->pIOMap)) - -enum -{ - POWERDOWN = 0x5A00, - BOOT = 0xA55A -}; - -typedef struct -{ - UWORD PowerOn; -}IOMAPIOCTRL; - - -#endif - - - diff --git a/AT91SAM7S256/Source/c_loader.c b/AT91SAM7S256/Source/c_loader.c deleted file mode 100644 index 995c920..0000000 --- a/AT91SAM7S256/Source/c_loader.c +++ /dev/null @@ -1,464 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 12-03-08 15:28 $ -// -// Filename $Workfile:: c_loader.c $ -// -// Version $Revision:: 5 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_load $ -// -// Platform C -// - -#include "stdconst.h" -#include "modules.h" -#include "c_loader.iom" -#include "c_ioctrl.iom" -#include "d_loader.h" -#include "c_loader.h" - -static IOMAPLOADER IOMapLoader; -static VARSLOADER VarsLoader; -static HEADER **pHeaders; - -const HEADER cLoader = -{ - 0x00090001L, - "Loader", - cLoaderInit, - cLoaderCtrl, - cLoaderExit, - (void *)&IOMapLoader, - (void *)&VarsLoader, - (UWORD)sizeof(IOMapLoader), - (UWORD)sizeof(VarsLoader), - 0x0000 //Code size - not used so far -}; - -UWORD cLoaderFileRq(UBYTE Cmd, UBYTE *pFileName, UBYTE *pBuffer, ULONG *pLength); -UWORD cLoaderGetIoMapInfo(ULONG ModuleId, UBYTE *pIoMap, UWORD *pIoMapSize); -UWORD cLoaderFindModule(UBYTE *pBuffer); -void cLoaderGetModuleName(UBYTE *pDst, UBYTE *pModule); - -void cLoaderInit(void* pHeader) -{ - - IOMapLoader.pFunc = &cLoaderFileRq; - VarsLoader.IoMapHandle = FALSE; - pHeaders = pHeader; - dLoaderInit(); - IOMapLoader.FreeUserFlash = dLoaderReturnFreeUserFlash(); -} - -void cLoaderCtrl(void) -{ -} - - - -UWORD cLoaderFileRq(UBYTE Cmd, UBYTE *pFileName, UBYTE *pBuffer, ULONG *pLength) -{ - UWORD ReturnState; - - ReturnState = SUCCESS; - - switch(Cmd) - { - case OPENREAD: - { - ReturnState = dLoaderOpenRead(pFileName, pLength); - if (0x8000 <= ReturnState) - { - dLoaderCloseHandle(ReturnState); - } - } - break; - case OPENREADLINEAR: - { - ReturnState = dLoaderGetFilePtr(pFileName, pBuffer, pLength); - if (0x8000 <= ReturnState) - { - dLoaderCloseHandle(ReturnState); - } - - } - break; - case OPENWRITE: - { - - /* This is to create a new file */ - ReturnState = dLoaderCreateFileHeader(*pLength, pFileName, (UBYTE) NONLINEAR, SYSTEMFILE); - if (0x8000 <= ReturnState) - { - dLoaderCloseHandle(ReturnState); - } - else - { - IOMapLoader.FreeUserFlash = dLoaderReturnFreeUserFlash(); - } - } - break; - case OPENWRITELINEAR: - { - ReturnState = dLoaderCreateFileHeader(*pLength, pFileName, (UBYTE) LINEAR, SYSTEMFILE); - if (0x8000 <= ReturnState) - { - dLoaderCloseHandle(ReturnState); - } - else - { - IOMapLoader.FreeUserFlash = dLoaderReturnFreeUserFlash(); - } - } - break; - case OPENWRITEDATA: - { - - ReturnState = dLoaderCreateFileHeader(*pLength, pFileName, (UBYTE) NONLINEAR, DATAFILE); - if (0x8000 <= ReturnState) - { - dLoaderCloseHandle(ReturnState); - } - else - { - IOMapLoader.FreeUserFlash = dLoaderReturnFreeUserFlash(); - } - } - break; - case OPENAPPENDDATA: - { - ReturnState = dLoaderOpenAppend(pFileName, pLength); - if (LOADER_ERR(ReturnState) != SUCCESS) - { - dLoaderCloseHandle(ReturnState); - } - } - break; - case CLOSE: - { - ReturnState = dLoaderCloseHandle(*pFileName); - } - break; - case CROPDATAFILE: - { - ReturnState = dLoaderCropDatafile(*pFileName); - IOMapLoader.FreeUserFlash = dLoaderReturnFreeUserFlash(); - } - break; - case READ: - { - ReturnState = dLoaderRead(*pFileName, pBuffer, pLength); - } - break; - case WRITE: - { - ReturnState = dLoaderWriteData(*pFileName, pBuffer, (UWORD*)pLength); - } - break; - case FINDFIRST: - { - ULONG DataLength; - - ReturnState = dLoaderFind(pFileName, pBuffer, pLength, &DataLength, (UBYTE) SEARCHING); - if (0x8000 <= ReturnState) - { - dLoaderCloseHandle(ReturnState); - } - } - break; - case FINDNEXT: - { - UWORD Handle; - ULONG DataLength; - - Handle = *pFileName; - ReturnState = dLoaderFindNext(Handle, pBuffer, pLength, &DataLength); - } - break; - case DELETE: - { - ReturnState = dLoaderDelete(pFileName); - IOMapLoader.FreeUserFlash = dLoaderReturnFreeUserFlash(); - - } - break; - case DELETEUSERFLASH: - { - dLoaderDeleteAllFiles(); - IOMapLoader.FreeUserFlash = dLoaderReturnFreeUserFlash(); - - } - break; - - case FINDFIRSTMODULE: - { - if (FALSE == VarsLoader.IoMapHandle) - { - VarsLoader.IoMapHandle = TRUE; - VarsLoader.ModSearchIndex = 0; - dLoaderInsertSearchStr(VarsLoader.ModSearchStr, pFileName, &(VarsLoader.ModSearchType)); - ReturnState = cLoaderFindModule(pBuffer); - } - else - { - ReturnState = NOMOREHANDLES; - } - } - break; - - case FINDNEXTMODULE: - { - ReturnState = cLoaderFindModule(pBuffer); - } - break; - - case CLOSEMODHANDLE: - { - VarsLoader.IoMapHandle = FALSE; - ReturnState = SUCCESS; - } - break; - - case IOMAPREAD: - { - - UBYTE *pIoMap; - ULONG Ptr; - UWORD IoMapSize; - UBYTE Tmp; - - pIoMap = NULL; - ReturnState = cLoaderGetIoMapInfo((*(ULONG*)(pFileName)),(UBYTE*)(&pIoMap), &IoMapSize); - - /* Did we have a valid module ID ?*/ - if (SUCCESS == LOADER_ERR(ReturnState)) - { - - /* This is the offset */ - Ptr = pBuffer[0]; - Ptr |= (UWORD)pBuffer[1] << 8; - - /* is the offset within the limits of the iomap size? */ - if ((Ptr + *pLength) <= IoMapSize) - { - - /* Add the offset to the pointer */ - pIoMap += Ptr; - - for (Tmp = 0; Tmp < *pLength; Tmp++) - { - pBuffer[Tmp + 2] = *pIoMap; - pIoMap++; - } - } - else - { - - /* Error - not within the bounderies */ - ReturnState = OUTOFBOUNDERY; - *pLength = 0; - } - } - else - { - - /* Error - not a valid module id */ - *pLength = 0; - } - } - break; - - case IOMAPWRITE: - { - UBYTE *pIoMap; - ULONG Ptr; - UWORD IoMapSize; - UWORD Tmp; - - - pIoMap = NULL; - ReturnState = cLoaderGetIoMapInfo(*((ULONG*)pFileName), (UBYTE*)&pIoMap, &IoMapSize); - - if (LOADER_ERR(ReturnState) == SUCCESS) - { - - /* This is the offset */ - Ptr = *pBuffer; - pBuffer++; - Tmp = *pBuffer; - Ptr |= Tmp << 8; - pBuffer++; - - if ((Ptr + *pLength) <= IoMapSize) - { - - pIoMap += Ptr; - for (Tmp = 0; Tmp < *pLength; Tmp++) - { - *pIoMap = pBuffer[Tmp]; - pIoMap++; - } - } - else - { - - /* Error - not within the bounderies */ - ReturnState = OUTOFBOUNDERY; - *pLength = 0; - } - } - else - { - - /* Error - not a valid module id */ - *pLength = 0; - } - } - break; - - case RENAMEFILE: - { - UBYTE FoundName[FILENAME_LENGTH + 1]; - - /* Check for file exists*/ - ReturnState = dLoaderFind(pBuffer, FoundName, pLength, pLength, (UBYTE) SEARCHING); - dLoaderCloseHandle(LOADER_HANDLE(ReturnState)); - if (FILENOTFOUND == LOADER_ERR(ReturnState)) - { - ReturnState = dLoaderFind(pFileName, FoundName, pLength, pLength, (UBYTE) SEARCHING); - if (ReturnState < 0x8000) - { - ReturnState = dLoaderCheckFiles((UBYTE) ReturnState); - if (ReturnState < 0x8000) - { - dLoaderRenameFile((UBYTE) ReturnState, pBuffer); - } - } - dLoaderCloseHandle(LOADER_HANDLE(ReturnState)); - } - else - { - if (SUCCESS == LOADER_ERR(ReturnState)) - { - ReturnState |= FILEEXISTS; - } - } - } - break; - - default: - { - } - break; - } - return (ReturnState); -} - -UWORD cLoaderGetIoMapInfo(ULONG ModuleId, UBYTE *pIoMap, UWORD *pIoMapSize) -{ - UBYTE Tmp; - UBYTE Exit; - UWORD RtnVal; - - RtnVal = SUCCESS; - Tmp = 0; - Exit = FALSE; - while((Tmp < 32) && (Exit == FALSE)) - { - if ((*(pHeaders[Tmp])).ModuleID == ModuleId) - { - Exit = TRUE; - } - else - { - Tmp++; - } - } - - /* Did we have a valid module ID ?*/ - if (TRUE == Exit) - { - /* Get the pointer of the module io map */ - *((ULONG *)pIoMap) = (ULONG)((*(pHeaders[Tmp])).pIOMap); - *pIoMapSize = (*(pHeaders[Tmp])).IOMapSize; - } - else - { - RtnVal = MODULENOTFOUND; - } - - /* To avoid a warning - this is optimized away */ - *pIoMap = *pIoMap; - return(RtnVal); -} - -UWORD cLoaderFindModule(UBYTE *pBuffer) -{ - UBYTE Tmp; - UWORD RtnVal; - UBYTE ModuleName[FILENAME_SIZE]; - - RtnVal = MODULENOTFOUND; - - for (Tmp = VarsLoader.ModSearchIndex; Tmp < 32; Tmp++) - { - if (pHeaders[Tmp] != 0) - { - - cLoaderGetModuleName(ModuleName, ((*(pHeaders[Tmp])).ModuleName)); - if (SUCCESS == dLoaderCheckName(ModuleName, VarsLoader.ModSearchStr, VarsLoader.ModSearchType)) - { - - dLoaderCopyFileName(pBuffer, ModuleName); - - pBuffer[FILENAME_SIZE] = (UBYTE) ((*(pHeaders[Tmp])).ModuleID); - pBuffer[FILENAME_SIZE + 1] = (UBYTE)(((*(pHeaders[Tmp])).ModuleID) >> 8); - pBuffer[FILENAME_SIZE + 2] = (UBYTE)(((*(pHeaders[Tmp])).ModuleID) >> 16); - pBuffer[FILENAME_SIZE + 3] = (UBYTE)(((*(pHeaders[Tmp])).ModuleID) >> 24); - - pBuffer[FILENAME_SIZE + 4] = (UBYTE)(((*(pHeaders[Tmp])).ModuleSize)); - pBuffer[FILENAME_SIZE + 5] = (UBYTE)(((*(pHeaders[Tmp])).ModuleSize) >> 8); - pBuffer[FILENAME_SIZE + 6] = (UBYTE)(((*(pHeaders[Tmp])).ModuleSize) >> 16); - pBuffer[FILENAME_SIZE + 7] = (UBYTE)(((*(pHeaders[Tmp])).ModuleSize) >> 24); - - pBuffer[FILENAME_SIZE + 8] = (UBYTE) ((*(pHeaders[Tmp])).IOMapSize); - pBuffer[FILENAME_SIZE + 9] = (UBYTE)(((*(pHeaders[Tmp])).IOMapSize) >> 8); - - RtnVal = SUCCESS; - (VarsLoader.ModSearchIndex) = Tmp + 1; - Tmp = 32; - } - } - } - return(RtnVal); -} - -void cLoaderGetModuleName(UBYTE *pDst, UBYTE *pModule) -{ - UBYTE Tmp; - - for(Tmp = 0; Tmp < FILENAME_SIZE; Tmp++) - { - if (0 != pModule[Tmp]) - { - pDst[Tmp] = pModule[Tmp]; - } - else - { - pDst[Tmp++] = '.'; - pDst[Tmp++] = 'm'; - pDst[Tmp++] = 'o'; - pDst[Tmp++] = 'd'; - pDst[Tmp] = '\0'; - Tmp = FILENAME_SIZE; - } - } -} - -void cLoaderExit(void) -{ -} - - diff --git a/AT91SAM7S256/Source/c_loader.h b/AT91SAM7S256/Source/c_loader.h deleted file mode 100644 index 03f8062..0000000 --- a/AT91SAM7S256/Source/c_loader.h +++ /dev/null @@ -1,44 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: c_loader.h $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_load $ -// -// Platform C -// - -#ifndef C_LOADER -#define C_LOADER - -enum -{ - LOADER_BUSY, - TOO_MANY_FILES, - NO_MORE_FLASH, - LOADER_SUCCESS -}; - -typedef struct -{ - UBYTE ModSearchStr[FILENAME_LENGTH + 1]; - UBYTE ModSearchIndex; - UBYTE ModSearchType; - UBYTE UsbStatus; - UBYTE IoMapHandle; -}VARSLOADER; - -void cLoaderInit(void* pHeader); -void cLoaderCtrl(void); -void cLoaderExit(void); - -extern const HEADER cLoader; - -#endif - - - diff --git a/AT91SAM7S256/Source/c_loader.iom b/AT91SAM7S256/Source/c_loader.iom deleted file mode 100644 index 80c8c4e..0000000 --- a/AT91SAM7S256/Source/c_loader.iom +++ /dev/null @@ -1,85 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 24-06-09 8:53 $ -// -// Filename $Workfile:: c_loader.iom $ -// -// Version $Revision:: 15 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_load $ -// -// Platform C -// - -#ifndef CLOADER_IOM -#define CLOADER_IOM - -#define pMapLoader ((IOMAPLOADER*)(pHeaders[ENTRY_LOADER]->pIOMap)) - -//Version numbers are two bytes, MAJOR.MINOR (big-endian) -//For example, version 1.5 would be 0x0105 -//If these switch to little-endian, be sure to update -//definition and usages of VM_OLDEST_COMPATIBLE_VERSION, too! -#define FIRMWAREVERSION 0x011D // x.y -#define FIRMWAREPATCH 2 // .z, the third number -#define PROTOCOLVERSION 0x017C //1.124 - -enum -{ - OPENREAD = 0x80, - OPENWRITE = 0x81, - READ = 0x82, - WRITE = 0x83, - CLOSE = 0x84, - DELETE = 0x85, - FINDFIRST = 0x86, - FINDNEXT = 0x87, - VERSIONS = 0x88, - OPENWRITELINEAR = 0x89, - OPENREADLINEAR = 0x8A, - OPENWRITEDATA = 0x8B, - OPENAPPENDDATA = 0x8C, - CROPDATAFILE = 0x8D, /* New cmd for datalogging */ - FINDFIRSTMODULE = 0x90, - FINDNEXTMODULE = 0x91, - CLOSEMODHANDLE = 0x92, - IOMAPREAD = 0x94, - IOMAPWRITE = 0x95, - BOOTCMD = 0x97, /* external command only */ - SETBRICKNAME = 0x98, - BTGETADR = 0x9A, - DEVICEINFO = 0x9B, - DELETEUSERFLASH = 0xA0, - POLLCMDLEN = 0xA1, - POLLCMD = 0xA2, - RENAMEFILE = 0xA3, - BTFACTORYRESET = 0xA4 - -}; - -typedef UWORD LOADER_STATUS; - -//Mask out handle byte of Loader status word for error code checks -#define LOADER_ERR(StatusWord) ((StatusWord & 0xFF00)) - -//Byte value of error half of Loader status word -#define LOADER_ERR_BYTE(StatusWord) ((UBYTE)((StatusWord & 0xFF00) >> 8)) - -//Value of handle inside Loader status word -#define LOADER_HANDLE(StatusWord) ((UBYTE)(StatusWord)) - -//Pointer to lower byte of Loader status word -#define LOADER_HANDLE_P(StatusWord) ((UBYTE*)(&StatusWord)) - -typedef struct -{ - UWORD (*pFunc)(UBYTE, UBYTE *, UBYTE *, ULONG *); - ULONG FreeUserFlash; -}IOMAPLOADER; - - -#endif - - - diff --git a/AT91SAM7S256/Source/c_lowspeed.c b/AT91SAM7S256/Source/c_lowspeed.c deleted file mode 100644 index 26851db..0000000 --- a/AT91SAM7S256/Source/c_lowspeed.c +++ /dev/null @@ -1,236 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: c_lowspeed.c $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_lows $ -// -// Platform C -// - -#include "stdconst.h" -#include "modules.h" -#include "c_lowspeed.iom" -#include "c_input.iom" -#include "c_lowspeed.h" -#include "d_lowspeed.h" - -static IOMAPLOWSPEED IOMapLowSpeed; -static VARSLOWSPEED VarsLowSpeed; -static HEADER **pHeaders; - -const UBYTE LOWSPEED_CH_NUMBER[4] = {0x01, 0x02, 0x04, 0x08}; - -const HEADER cLowSpeed = -{ - 0x000B0001L, - "Low Speed", - cLowSpeedInit, - cLowSpeedCtrl, - cLowSpeedExit, - (void *)&IOMapLowSpeed, - (void *)&VarsLowSpeed, - (UWORD)sizeof(IOMapLowSpeed), - (UWORD)sizeof(VarsLowSpeed), - 0x0000 //Code size - not used so far -}; - -void cLowSpeedInit(void* pHeader) -{ - pHeaders = pHeader; - - dLowSpeedInit(); - IOMapLowSpeed.State = COM_CHANNEL_NONE_ACTIVE; - VarsLowSpeed.TimerState = TIMER_STOPPED; -} - -void cLowSpeedCtrl(void) -{ - UBYTE Temp; - UBYTE ChannelNumber = 0; - - if (IOMapLowSpeed.State != 0) - { - for (ChannelNumber = 0; ChannelNumber < NO_OF_LOWSPEED_COM_CHANNEL; ChannelNumber++) - { - //Lowspeed com is activated - switch (IOMapLowSpeed.ChannelState[ChannelNumber]) - { - case LOWSPEED_IDLE: - { - } - break; - - case LOWSPEED_INIT: - { - if ((pMapInput->Inputs[ChannelNumber].SensorType == LOWSPEED) || (pMapInput->Inputs[ChannelNumber].SensorType == LOWSPEED_9V)) - { - if (VarsLowSpeed.TimerState == TIMER_STOPPED) - { - dLowSpeedStartTimer(); - VarsLowSpeed.TimerState = TIMER_RUNNING; - } - IOMapLowSpeed.ChannelState[ChannelNumber] = LOWSPEED_LOAD_BUFFER; - IOMapLowSpeed.ErrorType[ChannelNumber] = LOWSPEED_NO_ERROR; - VarsLowSpeed.ErrorCount[ChannelNumber] = 0; - dLowSpeedInitPins(ChannelNumber); - } - else - { - IOMapLowSpeed.ChannelState[ChannelNumber] = LOWSPEED_ERROR; - IOMapLowSpeed.ErrorType[ChannelNumber] = LOWSPEED_CH_NOT_READY; - } - } - break; - - case LOWSPEED_LOAD_BUFFER: - { - if ((pMapInput->Inputs[ChannelNumber].SensorType == LOWSPEED) || (pMapInput->Inputs[ChannelNumber].SensorType == LOWSPEED_9V)) - { - VarsLowSpeed.OutputBuf[ChannelNumber].OutPtr = 0; - for (VarsLowSpeed.OutputBuf[ChannelNumber].InPtr = 0; VarsLowSpeed.OutputBuf[ChannelNumber].InPtr < IOMapLowSpeed.OutBuf[ChannelNumber].InPtr; VarsLowSpeed.OutputBuf[ChannelNumber].InPtr++) - { - VarsLowSpeed.OutputBuf[ChannelNumber].Buf[VarsLowSpeed.OutputBuf[ChannelNumber].InPtr] = IOMapLowSpeed.OutBuf[ChannelNumber].Buf[IOMapLowSpeed.OutBuf[ChannelNumber].OutPtr]; - IOMapLowSpeed.OutBuf[ChannelNumber].OutPtr++; - } - if (dLowSpeedSendData(ChannelNumber, &VarsLowSpeed.OutputBuf[ChannelNumber].Buf[0], (VarsLowSpeed.OutputBuf[ChannelNumber].InPtr - VarsLowSpeed.OutputBuf[ChannelNumber].OutPtr))) - { - if (IOMapLowSpeed.InBuf[ChannelNumber].BytesToRx != 0) - { - dLowSpeedReceiveData(ChannelNumber, &VarsLowSpeed.InputBuf[ChannelNumber].Buf[0], IOMapLowSpeed.InBuf[ChannelNumber].BytesToRx); - VarsLowSpeed.RxTimeCnt[ChannelNumber] = 0; - } - IOMapLowSpeed.ChannelState[ChannelNumber] = LOWSPEED_COMMUNICATING; - IOMapLowSpeed.Mode[ChannelNumber] = LOWSPEED_TRANSMITTING; - } - else - { - IOMapLowSpeed.ChannelState[ChannelNumber] = LOWSPEED_ERROR; - IOMapLowSpeed.ErrorType[ChannelNumber] = LOWSPEED_CH_NOT_READY; - } - } - else - { - IOMapLowSpeed.ChannelState[ChannelNumber] = LOWSPEED_ERROR; - IOMapLowSpeed.ErrorType[ChannelNumber] = LOWSPEED_CH_NOT_READY; - } - } - break; - - case LOWSPEED_COMMUNICATING: - { - if ((pMapInput->Inputs[ChannelNumber].SensorType == LOWSPEED) || (pMapInput->Inputs[ChannelNumber].SensorType == LOWSPEED_9V)) - { - if (IOMapLowSpeed.Mode[ChannelNumber] == LOWSPEED_TRANSMITTING) - { - Temp = dLowSpeedComTxStatus(ChannelNumber); // Returns 0x00 if not done, 0x01 if success, 0xFF if error - - if (Temp == LOWSPEED_COMMUNICATION_SUCCESS) - { - if (IOMapLowSpeed.InBuf[ChannelNumber].BytesToRx != 0) - { - IOMapLowSpeed.Mode[ChannelNumber] = LOWSPEED_RECEIVING; - } - else - { - IOMapLowSpeed.Mode[ChannelNumber] = LOWSPEED_DATA_RECEIVED; - IOMapLowSpeed.ChannelState[ChannelNumber] = LOWSPEED_DONE; - } - } - if (Temp == LOWSPEED_COMMUNICATION_ERROR) - { - //ERROR in Communication, No ACK received from SLAVE, retry send data 3 times! - VarsLowSpeed.ErrorCount[ChannelNumber]++; - if (VarsLowSpeed.ErrorCount[ChannelNumber] > MAX_RETRY_TX_COUNT) - { - IOMapLowSpeed.ChannelState[ChannelNumber] = LOWSPEED_ERROR; - IOMapLowSpeed.ErrorType[ChannelNumber] = LOWSPEED_TX_ERROR; - } - else - { - IOMapLowSpeed.ChannelState[ChannelNumber] = LOWSPEED_LOAD_BUFFER; - } - } - } - if (IOMapLowSpeed.Mode[ChannelNumber] == LOWSPEED_RECEIVING) - { - VarsLowSpeed.RxTimeCnt[ChannelNumber]++; - if (VarsLowSpeed.RxTimeCnt[ChannelNumber] > LOWSPEED_RX_TIMEOUT) - { - IOMapLowSpeed.ChannelState[ChannelNumber] = LOWSPEED_ERROR; - IOMapLowSpeed.ErrorType[ChannelNumber] = LOWSPEED_RX_ERROR; - } - Temp = dLowSpeedComRxStatus(ChannelNumber); - if (Temp == LOWSPEED_COMMUNICATION_SUCCESS) - { - for (VarsLowSpeed.InputBuf[ChannelNumber].OutPtr = 0; VarsLowSpeed.InputBuf[ChannelNumber].OutPtr < IOMapLowSpeed.InBuf[ChannelNumber].BytesToRx; VarsLowSpeed.InputBuf[ChannelNumber].OutPtr++) - { - IOMapLowSpeed.InBuf[ChannelNumber].Buf[IOMapLowSpeed.InBuf[ChannelNumber].InPtr] = VarsLowSpeed.InputBuf[ChannelNumber].Buf[VarsLowSpeed.InputBuf[ChannelNumber].OutPtr]; - IOMapLowSpeed.InBuf[ChannelNumber].InPtr++; - if (IOMapLowSpeed.InBuf[ChannelNumber].InPtr >= SIZE_OF_LSBUF) - { - IOMapLowSpeed.InBuf[ChannelNumber].InPtr = 0; - } - VarsLowSpeed.InputBuf[ChannelNumber].Buf[VarsLowSpeed.InputBuf[ChannelNumber].OutPtr] = 0; - } - IOMapLowSpeed.Mode[ChannelNumber] = LOWSPEED_DATA_RECEIVED; - IOMapLowSpeed.ChannelState[ChannelNumber] = LOWSPEED_DONE; - } - if (Temp == LOWSPEED_COMMUNICATION_ERROR) - { - //There was and error in receiving data from the device - for (VarsLowSpeed.InputBuf[ChannelNumber].OutPtr = 0; VarsLowSpeed.InputBuf[ChannelNumber].OutPtr < IOMapLowSpeed.InBuf[ChannelNumber].BytesToRx; VarsLowSpeed.InputBuf[ChannelNumber].OutPtr++) - { - VarsLowSpeed.InputBuf[ChannelNumber].Buf[VarsLowSpeed.InputBuf[ChannelNumber].OutPtr] = 0; - } - IOMapLowSpeed.ChannelState[ChannelNumber] = LOWSPEED_ERROR; - IOMapLowSpeed.ErrorType[ChannelNumber] = LOWSPEED_RX_ERROR; - } - } - } - else - { - IOMapLowSpeed.ChannelState[ChannelNumber] = LOWSPEED_ERROR; - IOMapLowSpeed.ErrorType[ChannelNumber] = LOWSPEED_CH_NOT_READY; - } - } - break; - - case LOWSPEED_ERROR: - { - IOMapLowSpeed.State = IOMapLowSpeed.State & ~LOWSPEED_CH_NUMBER[ChannelNumber]; - if (IOMapLowSpeed.State == 0) - { - dLowSpeedStopTimer(); - VarsLowSpeed.TimerState = TIMER_STOPPED; - } - } - break; - - case LOWSPEED_DONE: - { - IOMapLowSpeed.State = IOMapLowSpeed.State & ~LOWSPEED_CH_NUMBER[ChannelNumber]; - IOMapLowSpeed.ChannelState[ChannelNumber] = LOWSPEED_IDLE; - if (IOMapLowSpeed.State == 0) - { - dLowSpeedStopTimer(); - VarsLowSpeed.TimerState = TIMER_STOPPED; - } - } - break; - - default: - break; - } - } - } -} - -void cLowSpeedExit(void) -{ - dLowSpeedExit(); -} diff --git a/AT91SAM7S256/Source/c_lowspeed.h b/AT91SAM7S256/Source/c_lowspeed.h deleted file mode 100644 index 1595158..0000000 --- a/AT91SAM7S256/Source/c_lowspeed.h +++ /dev/null @@ -1,61 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: c_lowspeed.h $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_lows $ -// -// Platform C -// - -#ifndef C_LOWSPEED -#define C_LOWSPEED - -#define LOWSPEED_RX_TIMEOUT 100 -#define LOWSPEED_COMMUNICATION_SUCCESS 0x01 -#define LOWSPEED_COMMUNICATION_ERROR 0xFF -#define SIZE_OF_LSBUFDATA 16 -#define NO_OF_LOWSPEED_COM_CH 4 - -enum -{ - LOWSPEED_CHANNEL1, - LOWSPEED_CHANNEL2, - LOWSPEED_CHANNEL3, - LOWSPEED_CHANNEL4 -}; - -enum -{ - TIMER_STOPPED, - TIMER_RUNNING -}; - -typedef struct -{ - UBYTE Buf[SIZE_OF_LSBUFDATA]; - UBYTE InPtr; - UBYTE OutPtr; -}LSDATA; - -typedef struct -{ - LSDATA OutputBuf[NO_OF_LOWSPEED_COM_CH]; - LSDATA InputBuf[NO_OF_LOWSPEED_COM_CH]; - UBYTE RxTimeCnt[NO_OF_LOWSPEED_COM_CH]; - UBYTE ErrorCount[NO_OF_LOWSPEED_COM_CH]; - UBYTE Tmp; - UBYTE TimerState; -}VARSLOWSPEED; - -void cLowSpeedInit(void* pHeader); -void cLowSpeedCtrl(void); -void cLowSpeedExit(void); - -extern const HEADER cLowSpeed; - -#endif diff --git a/AT91SAM7S256/Source/c_lowspeed.iom b/AT91SAM7S256/Source/c_lowspeed.iom deleted file mode 100644 index 290ed35..0000000 --- a/AT91SAM7S256/Source/c_lowspeed.iom +++ /dev/null @@ -1,95 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: c_lowspeed.iom $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_lows $ -// -// Platform C -// - -#ifndef CLOWSPEED_IOM -#define CLOWSPEED_IOM - -#define pMapLowSpeed ((IOMAPLOWSPEED*)(pHeaders[ENTRY_LOWSPEED]->pIOMap)) - -#define MAX_RETRY_TX_COUNT 3 -#define NO_OF_LOWSPEED_COM_CHANNEL 4 -#define NO_OF_LSBUF NO_OF_LOWSPEED_COM_CHANNEL -#define SIZE_OF_LSBUF 16 - -//Constants referring to LowSpeedDeviceType -enum -{ - ULTRA_SONIC = 2, - CUSTOM_LS_DEVICE -}; - -// Constants reffering to State -enum -{ - COM_CHANNEL_NONE_ACTIVE = 0x00, - COM_CHANNEL_ONE_ACTIVE = 0x01, - COM_CHANNEL_TWO_ACTIVE = 0x02, - COM_CHANNEL_THREE_ACTIVE = 0x04, - COM_CHANNEL_FOUR_ACTIVE = 0x08 -}; - -// Constants reffering to ChannelState -enum -{ - LOWSPEED_IDLE, - LOWSPEED_INIT, - LOWSPEED_LOAD_BUFFER, - LOWSPEED_COMMUNICATING, - LOWSPEED_ERROR, - LOWSPEED_DONE -}; - -// Constants reffering to Mode -enum -{ - LOWSPEED_TRANSMITTING = 1, - LOWSPEED_RECEIVING, - LOWSPEED_DATA_RECEIVED -}; - -// Constants reffering to ErrorType -enum -{ - LOWSPEED_NO_ERROR = 0, - LOWSPEED_CH_NOT_READY, - LOWSPEED_TX_ERROR, - LOWSPEED_RX_ERROR -}; - - -typedef struct -{ - UBYTE Buf[SIZE_OF_LSBUF]; - UBYTE InPtr; - UBYTE OutPtr; - UBYTE BytesToRx; -}LSBUF; - -typedef struct -{ - LSBUF InBuf[NO_OF_LSBUF]; - LSBUF OutBuf[NO_OF_LSBUF]; - UBYTE Mode[NO_OF_LSBUF]; - UBYTE ChannelState[NO_OF_LSBUF]; - UBYTE ErrorType[NO_OF_LSBUF]; - UBYTE State; - UBYTE Speed; - UBYTE Spare1; -}IOMAPLOWSPEED; - - -#endif - - - diff --git a/AT91SAM7S256/Source/c_output.c b/AT91SAM7S256/Source/c_output.c deleted file mode 100644 index e0645e0..0000000 --- a/AT91SAM7S256/Source/c_output.c +++ /dev/null @@ -1,180 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: c_output.c $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_outp $ -// -// Platform C -// - -#include -#include "stdbool.h" -#include "stdconst.h" -#include "modules.h" -#include "c_output.iom" -#include "c_output.h" -#include "d_output.h" -#include "c_display.iom" - -static IOMAPOUTPUT IOMapOutput; -static VARSOUTPUT VarsOutput; - -const HEADER cOutput = -{ - 0x00020001L, - "Output", - cOutputInit, - cOutputCtrl, - cOutputExit, - (void *)&IOMapOutput, - (void *)&VarsOutput, - (UWORD)sizeof(IOMapOutput), - (UWORD)sizeof(VarsOutput), - 0x0000 //Code size - not used so far -}; - - -void cOutputInit(void* pHeader) -{ - UBYTE Tmp; - - for(Tmp = 0; Tmp < NO_OF_OUTPUTS; Tmp++) - { - OUTPUT * pOut = &(IOMapOutput.Outputs[Tmp]); - pOut->Mode = 0x00; - pOut->Speed = 0x00; - pOut->ActualSpeed = 0x00; - pOut->TachoCnt = 0x00; - pOut->RunState = 0x00; - pOut->TachoLimit = 0x00; - pOut->RegPParameter = DEFAULT_P_GAIN_FACTOR; - pOut->RegIParameter = DEFAULT_I_GAIN_FACTOR; - pOut->RegDParameter = DEFAULT_D_GAIN_FACTOR; - pOut->Options = 0x00; - pOut->MaxSpeed = DEFAULT_MAX_SPEED; - pOut->MaxAcceleration = DEFAULT_MAX_ACCELERATION; - } - IOMapOutput.RegulationTime = REGULATION_TIME; - IOMapOutput.RegulationOptions = 0; - VarsOutput.TimeCnt = 0; - dOutputInit(); -} - -void cOutputCtrl(void) -{ - UBYTE Tmp; - - for(Tmp = 0; Tmp < NO_OF_OUTPUTS; Tmp++) - { - OUTPUT * pOut = &(IOMapOutput.Outputs[Tmp]); - if (pOut->Flags != 0) - { - if (pOut->Flags & UPDATE_RESET_ROTATION_COUNT) - { - pOut->Flags &= ~UPDATE_RESET_ROTATION_COUNT; - dOutputResetRotationCaptureCount(Tmp); - } - if (pOut->Flags & UPDATE_RESET_COUNT) - { - pOut->Flags &= ~UPDATE_RESET_COUNT; - dOutputResetTachoLimit(Tmp); - } - if (pOut->Flags & UPDATE_RESET_BLOCK_COUNT) - { - pOut->Flags &= ~UPDATE_RESET_BLOCK_COUNT; - dOutputResetBlockTachoLimit(Tmp); - } - if (pOut->Flags & UPDATE_SPEED) - { - pOut->Flags &= ~UPDATE_SPEED; - if (pOut->Mode & MOTORON) - { - dOutputSetSpeed(Tmp, pOut->RunState, pOut->Speed, pOut->SyncTurnParameter); - } - } - if (pOut->Flags & UPDATE_MODE) - { - pOut->Flags &= ~UPDATE_MODE; - if (pOut->Mode & BRAKE) - { - // Motor is Braked - dOutputSetMode(Tmp, BRAKE); - } - else - { - // Motor is floated - dOutputSetMode(Tmp, 0x00); - } - if (pOut->Mode & MOTORON) - { - if (pOut->Mode & REGULATED) - { - dOutputEnableRegulation(Tmp, pOut->RegMode); - } - else - { - dOutputDisableRegulation(Tmp); - } - } - else - { - dOutputSetSpeed(Tmp, 0x00, 0x00, 0x00); - dOutputDisableRegulation(Tmp); - } - } - if (pOut->Flags & UPDATE_TACHO_LIMIT) - { - pOut->Flags &= ~UPDATE_TACHO_LIMIT; - dOutputSetTachoLimit(Tmp, pOut->TachoLimit); - } - if (pOut->Flags & UPDATE_PID_VALUES) - { - pOut->Flags &= ~UPDATE_PID_VALUES; - dOutputSetPIDParameters(Tmp, pOut->RegPParameter, pOut->RegIParameter, pOut->RegDParameter); - dOutputSetMax(Tmp, pOut->MaxSpeed, pOut->MaxAcceleration); - } - } - } - dOutputSetRegulationTime(IOMapOutput.RegulationTime); - dOutputSetRegulationOptions(IOMapOutput.RegulationOptions); - dOutputCtrl(); - cOutputUpdateIomap(); -} - -void cOutputUpdateIomap(void) -{ - UBYTE TempCurrentMotorSpeed[NO_OF_OUTPUTS]; - UBYTE TempRunState[NO_OF_OUTPUTS]; - UBYTE TempMotorOverloaded[NO_OF_OUTPUTS]; - SLONG TempTachoCount[NO_OF_OUTPUTS]; - SLONG TempBlockTachoCount[NO_OF_OUTPUTS]; - SLONG TempRotationCount[NO_OF_OUTPUTS]; - - UBYTE Tmp; - - dOutputGetMotorParameters(TempCurrentMotorSpeed, TempTachoCount, TempBlockTachoCount, TempRunState, TempMotorOverloaded,TempRotationCount); - - for(Tmp = 0; Tmp < NO_OF_OUTPUTS; Tmp++) - { - OUTPUT * pOut = &(IOMapOutput.Outputs[Tmp]); - pOut->ActualSpeed = TempCurrentMotorSpeed[Tmp]; - pOut->TachoCnt = TempTachoCount[Tmp]; - pOut->BlockTachoCount = TempBlockTachoCount[Tmp]; - pOut->RotationCount = TempRotationCount[Tmp]; - pOut->Overloaded = TempMotorOverloaded[Tmp]; - if (!(pOut->Flags & PENDING_UPDATES)) - { - pOut->RunState = TempRunState[Tmp]; - } - } -} - -void cOutputExit(void) -{ - dOutputExit(); -} diff --git a/AT91SAM7S256/Source/c_output.h b/AT91SAM7S256/Source/c_output.h deleted file mode 100644 index 14faa2c..0000000 --- a/AT91SAM7S256/Source/c_output.h +++ /dev/null @@ -1,31 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: c_output.h $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_outp $ -// -// Platform C -// - -#ifndef C_OUTPUT -#define C_OUTPUT - -typedef struct -{ - UBYTE TimeCnt; - UBYTE Tmp; -}VARSOUTPUT; - -void cOutputInit(void* pHeader); -void cOutputCtrl(void); -void cOutputExit(void); -void cOutputUpdateIomap(void); - -extern const HEADER cOutput; - -#endif diff --git a/AT91SAM7S256/Source/c_output.iom b/AT91SAM7S256/Source/c_output.iom deleted file mode 100644 index 276bcba..0000000 --- a/AT91SAM7S256/Source/c_output.iom +++ /dev/null @@ -1,94 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: c_output.iom $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_outp $ -// -// Platform C -// - -#ifndef COUTPUT_IOM -#define COUTPUT_IOM - -#define NO_OF_OUTPUTS 3 -#define pMapOutPut ((IOMAPOUTPUT*)(pHeaders[ENTRY_OUTPUT]->pIOMap)) - -// Constants reffering to mode -enum -{ - MOTORON = 0x01, - BRAKE = 0x02, - REGULATED = 0x04, - REG_METHOD = 0xF0 /* Regulation methods - to be designed! */ -}; - -// Constants related to Flags -enum -{ - UPDATE_MODE = 0x01, - UPDATE_SPEED = 0x02, - UPDATE_TACHO_LIMIT = 0x04, - UPDATE_RESET_COUNT = 0x08, - UPDATE_PID_VALUES = 0x10, - UPDATE_RESET_BLOCK_COUNT = 0x20, - UPDATE_RESET_ROTATION_COUNT = 0x40, - PENDING_UPDATES = 0x80 -}; - -// Constant related to RunState -#define MOTOR_RUN_STATE_IDLE 0x00 -#define MOTOR_RUN_STATE_RAMPUP 0x10 -#define MOTOR_RUN_STATE_RUNNING 0x20 -#define MOTOR_RUN_STATE_RAMPDOWN 0x40 - -// Constant related to RegMode -enum -{ - REGULATION_MODE_IDLE = 0, - REGULATION_MODE_MOTOR_SPEED = 1, - REGULATION_MODE_MOTOR_SYNC = 2, - REGULATION_MODE_MOTOR_POS = 4, -}; - -typedef struct -{ - SLONG TachoCnt; /* R - Holds current number of counts, since last reset, updated every 1 mS */ - SLONG BlockTachoCount; /* R - Holds current number of counts for the current output block */ - SLONG RotationCount; /* R - Holds current number of counts for the rotation counter to the output */ - ULONG TachoLimit; /* RW - Holds number of counts to travel, 0 => Run forever */ - SWORD MotorRPM; /* !! Is not updated, will be removed later !! */ - UBYTE Flags; /* RW - Holds flags for which data should be updated */ - UBYTE Mode; /* RW - Holds motor mode: Run, Break, regulated, ... */ - SBYTE Speed; /* RW - Holds the wanted speed */ - SBYTE ActualSpeed; /* R - Holds the current motor speed */ - UBYTE RegPParameter; /* RW - Holds the P-constant use din the regulation, Is set to a default value at init => Setting this value is optional for the user */ - UBYTE RegIParameter; /* RW - Holds the I-constant use din the regulation, Is set to a default value at init => Setting this value is optional for the user */ - UBYTE RegDParameter; /* RW - Holds the D-constant use din the regulation, Is set to a default value at init => Setting this value is optional for the user */ - UBYTE RunState; /* RW - Holds the current RunState in the output module */ - UBYTE RegMode; /* RW - Tells which regulation mode should be used */ - UBYTE Overloaded; /* R - True if the motor has been overloaded within speed control regulation */ - SBYTE SyncTurnParameter; /* RW - Holds the turning parameter need within MoveBlock */ - UBYTE Options; - SBYTE MaxSpeed; /* RW - Maximum speed for absolute regulation, or 0 for no limit */ - SBYTE MaxAcceleration; /* RW - Maximum acceleration for absolute regulation, or 0 for no limit */ -}OUTPUT; - - -typedef struct -{ - OUTPUT Outputs[NO_OF_OUTPUTS]; - UBYTE RegulationTime; /* RW - Interval between regulation computations */ - UBYTE RegulationOptions; /* RW - Options for regulation, see REGOPTION_* */ -}IOMAPOUTPUT; - - - -#endif - - - diff --git a/AT91SAM7S256/Source/c_sound.c b/AT91SAM7S256/Source/c_sound.c deleted file mode 100644 index 9d0a81d..0000000 --- a/AT91SAM7S256/Source/c_sound.c +++ /dev/null @@ -1,309 +0,0 @@ -// -// Programmer -// -// Date init 14.12.2004 -// -// Reviser $Author:: Dkandlun $ -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: c_sound.c $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_soun $ -// -// Platform C -// - -#include -#include -#include "stdconst.h" -#include "modules.h" -#include "c_sound.iom" -#include "c_loader.iom" -#include "c_sound.h" -#include "d_sound.h" - -static IOMAPSOUND IOMapSound; -static VARSSOUND VarsSound; -static HEADER **pHeaders; - -const HEADER cSound = -{ - 0x00080001L, - "Sound", - cSoundInit, - cSoundCtrl, - cSoundExit, - (void *)&IOMapSound, - (void *)&VarsSound, - (UWORD)sizeof(IOMapSound), - (UWORD)sizeof(VarsSound), - 0x0000 //Code size - not used so far -}; - - -UWORD cSoundFile(UBYTE Cmd,UBYTE *pFile,UBYTE *pData,ULONG *pLng) -{ - return (pMapLoader->pFunc(Cmd,pFile,pData,pLng)); -} - - -void cSoundInit(void* pHeader) -{ - pHeaders = pHeader; - IOMapSound.Flags &= ~SOUND_UPDATE; - IOMapSound.Flags &= ~SOUND_RUNNING; - IOMapSound.State = SOUND_IDLE; - IOMapSound.Mode = SOUND_ONCE; - IOMapSound.Volume = SOUNDVOLUMESTEPS; - IOMapSound.SampleRate = 0; - IOMapSound.SoundFilename[0] = 0; - VarsSound.BufferIn = 0; - VarsSound.BufferOut = 0; - dSoundInit(); -} - -void cSoundCtrl(void) -{ - static UWORD FileFormat; - static UBYTE SoundFilename[FILENAME_LENGTH + 1]; - UWORD Handle; - ULONG Length; - UBYTE Header[FILEHEADER_LENGTH]; - UBYTE In,Out,Tmp; - - In = VarsSound.BufferIn; - Out = VarsSound.BufferOut; - - if ((IOMapSound.Flags & SOUND_UPDATE)) - { -// Check if valid update - if (!(SOUND_TONE & IOMapSound.Mode)) - { - Handle = pMapLoader->pFunc(FINDFIRST,IOMapSound.SoundFilename,SoundFilename,&Length); - if (!(Handle & 0x8000)) - { - pMapLoader->pFunc(CLOSE,(UBYTE*)&Handle,NULL,NULL); - } - else - { - IOMapSound.Flags &= ~SOUND_UPDATE; - } - } - if ((IOMapSound.Flags & SOUND_UPDATE)) - { -// Check for open file - if (!(VarsSound.File & 0x8000)) - { - cSoundFile(CLOSE,(UBYTE*)&VarsSound.File,NULL,NULL); - VarsSound.File = 0x8000; - } - - IOMapSound.Flags &= ~SOUND_UPDATE; - - if ((SOUND_TONE & IOMapSound.Mode)) - { - dSoundFreq(IOMapSound.Freq,IOMapSound.Duration,IOMapSound.Volume); - IOMapSound.State = SOUND_FREQ; - } - else - { - if (IOMapSound.Flags & SOUND_RUNNING) - { - dSoundStop(); - IOMapSound.Flags &= ~SOUND_RUNNING; - } - VarsSound.File = pMapLoader->pFunc(OPENREAD,SoundFilename,NULL,&Length); - if (!(VarsSound.File & 0x8000)) - { - Length = FILEHEADER_LENGTH; - pMapLoader->pFunc(READ,(UBYTE*)&VarsSound.File,Header,&Length); - if (Length == FILEHEADER_LENGTH) - { - FileFormat = ((UWORD)Header[0] << 8) + (UWORD)Header[1]; - - if (FILEFORMAT_SOUND == (FileFormat & 0xFF00)) - { - if (IOMapSound.SampleRate) - { - VarsSound.SampleRate = IOMapSound.SampleRate; - IOMapSound.SampleRate = 0; - } - else - { - VarsSound.SampleRate = ((UWORD)Header[4] << 8) + (UWORD)Header[5]; - } - dSoundVolume(IOMapSound.Volume); - Length = SOUNDBUFFERSIZE; - pMapLoader->pFunc(READ,(UBYTE*)&VarsSound.File,VarsSound.Buffer[In],&Length); - VarsSound.Length[In] = (UWORD)Length; - In++; - if (In >= SOUNDBUFFERS) - { - In = 0; - } - IOMapSound.State = SOUND_BUSY; - } - else - { - if (FILEFORMAT_MELODY == FileFormat) - { - Length = SOUNDBUFFERSIZE; - pMapLoader->pFunc(READ,(UBYTE*)&VarsSound.File,VarsSound.Buffer[In],&Length); - VarsSound.Length[In] = (UWORD)Length; - In++; - if (In >= SOUNDBUFFERS) - { - In = 0; - } - IOMapSound.State = SOUND_BUSY; - } - else - { - pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsSound.File,NULL,NULL); - } - } - } - } - } - } - } - - switch (IOMapSound.State) - { - case SOUND_BUSY : - { - IOMapSound.Flags |= SOUND_RUNNING; - if (In != Out) - { - if ((FILEFORMAT_SOUND == FileFormat) || (FILEFORMAT_SOUND_COMPRESSED == FileFormat)) - { - if (dSoundStart(VarsSound.Buffer[Out],VarsSound.Length[Out],VarsSound.SampleRate,(UBYTE)(FileFormat & 0x00FF)) == TRUE) - { - Out++; - if (Out >= SOUNDBUFFERS) - { - Out = 0; - } - } - } - else - { - if (dSoundTone(VarsSound.Buffer[Out],VarsSound.Length[Out],IOMapSound.Volume) == TRUE) - { - Out++; - if (Out >= SOUNDBUFFERS) - { - Out = 0; - } - } - } - } - - Tmp = In; - Tmp++; - if (Tmp >= SOUNDBUFFERS) - { - Tmp = 0; - } - - if (Tmp != Out) - { - Tmp++; - if (Tmp >= SOUNDBUFFERS) - { - Tmp = 0; - } - if (Tmp != Out) - { - Length = SOUNDBUFFERSIZE; - Handle = cSoundFile(READ,(UBYTE*)&VarsSound.File,VarsSound.Buffer[In],&Length); - if ((Handle & 0x8000)) - { - Length = 0L; - } - VarsSound.Length[In] = (UWORD)Length; - if (VarsSound.Length[In] == 0) - { - if (SOUND_LOOP == IOMapSound.Mode) - { - if (!(IOMapSound.Flags & SOUND_UPDATE)) - { - cSoundFile(CLOSE,(UBYTE*)&VarsSound.File,NULL,NULL); - VarsSound.File = cSoundFile(OPENREAD,SoundFilename,NULL,&Length); - Length = FILEHEADER_LENGTH; - cSoundFile(READ,(UBYTE*)&VarsSound.File,Header,&Length); - Length = SOUNDBUFFERSIZE; - cSoundFile(READ,(UBYTE*)&VarsSound.File,VarsSound.Buffer[In],&Length); - VarsSound.Length[In] = (UWORD)Length; - } - } - } - if (VarsSound.Length[In] != 0) - { - In++; - if (In >= SOUNDBUFFERS) - { - In = 0; - } - } - if (VarsSound.Length[Out] == 0) - { - if (!(VarsSound.File & 0x8000)) - { - pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsSound.File,NULL,NULL); - VarsSound.File = 0x8000; - } - IOMapSound.Flags &= ~SOUND_RUNNING; - IOMapSound.State = SOUND_IDLE; - } - } - } - } - break; - - case SOUND_FREQ : - { - IOMapSound.Flags |= SOUND_RUNNING; - if (dSoundReady() == TRUE) - { - if (SOUND_LOOP & IOMapSound.Mode) - { - dSoundFreq(IOMapSound.Freq,IOMapSound.Duration,IOMapSound.Volume); - } - else - { - IOMapSound.Flags &= ~SOUND_RUNNING; - IOMapSound.State = SOUND_IDLE; - } - } - } - break; - - case SOUND_STOP : - { - dSoundStop(); - if (!(VarsSound.File & 0x8000)) - { - pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsSound.File,NULL,NULL); - VarsSound.File = 0x8000; - } - IOMapSound.Flags &= ~SOUND_RUNNING; - IOMapSound.State = SOUND_IDLE; - Out = In; - } - break; - - } - - VarsSound.BufferIn = In; - VarsSound.BufferOut = Out; -} - - -void cSoundExit(void) -{ - dSoundExit(); -} diff --git a/AT91SAM7S256/Source/c_sound.h b/AT91SAM7S256/Source/c_sound.h deleted file mode 100644 index ebdbb9a..0000000 --- a/AT91SAM7S256/Source/c_sound.h +++ /dev/null @@ -1,44 +0,0 @@ -// -// Programmer -// -// Date init 14.12.2004 -// -// Reviser $Author:: Dkandlun $ -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: c_sound.h $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_soun $ -// -// Platform C -// - - -#ifndef C_SOUND -#define C_SOUND - -#define SOUNDBUFFERSIZE 64 // Flash Sector size ? -#define SOUNDBUFFERS 3 // Min 3 - max 255 - - -typedef struct -{ - UWORD Length[SOUNDBUFFERS]; - UWORD File; - UWORD SampleRate; - UBYTE Buffer[SOUNDBUFFERS][SOUNDBUFFERSIZE]; - UBYTE BufferIn; - UBYTE BufferOut; - UBYTE BufferTmp; -}VARSSOUND; - -void cSoundInit(void* pHeaders); -void cSoundCtrl(void); -void cSoundExit(void); - -extern const HEADER cSound; - -#endif diff --git a/AT91SAM7S256/Source/c_sound.iom b/AT91SAM7S256/Source/c_sound.iom deleted file mode 100644 index ec12076..0000000 --- a/AT91SAM7S256/Source/c_sound.iom +++ /dev/null @@ -1,109 +0,0 @@ -// -// Programmer -// -// Date init 14.12.2004 -// -// Reviser $Author:: Dkandlun $ -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: c_sound.iom $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_soun $ -// -// Platform C -// - -#ifndef CSOUND_IOM -#define CSOUND_IOM - -#define pMapSound ((IOMAPSOUND*)(pHeaders[ENTRY_SOUND]->pIOMap)) - - -/* HOW TO - -Start a sound file strcpy((char*)pMapSound->SoundFilename,"xxxxxxx.rso"); - pMapSound->Volume = IOMapUi.Volume; - pMapSound->Mode = SOUND_ONCE; - pMapSound->Flags |= SOUND_UPDATE; - - -Start and loop a sound file strcpy((char*)pMapSound->SoundFilename,"xxxxxxx.rso"); - pMapSound->Volume = IOMapUi.Volume; - pMapSound->Mode = SOUND_LOOP; - pMapSound->Flags |= SOUND_UPDATE; - - -Start a tone pMapSound->Freq = 440; - pMapSound->Duration = 1000; - pMapSound->Volume = IOMapUi.Volume; - pMapSound->Mode = SOUND_TONE; - pMapSound->Flags |= SOUND_UPDATE; - - -Start and loop a tone pMapSound->Freq = 440; - pMapSound->Duration = 1000; - pMapSound->Volume = IOMapUi.Volume; - pMapSound->Mode = SOUND_TONE | SOUND_LOOP; - pMapSound->Flags |= SOUND_UPDATE; - - - -Test for sound finished if (!(pMapSound->Flags & (SOUND_RUNNING | SOUND_UPDATE))) - { - // FINISHED - } - - -Abort sound or tone pMapSound->State = SOUND_STOP; - - -**** Start always abort running sound or tone **** - - - -*/ - -// Constants related to Flags -enum -{ - SOUND_UPDATE = 0x01, // W - Make changes take effect - SOUND_RUNNING = 0x02 // R - Processing tone or file -}; - -// Constants related to State -enum -{ - SOUND_IDLE = 0x00, // R - Idle, ready for start sound (SOUND_UPDATE) - SOUND_BUSY = 0x02, // R - Processing file of sound/melody data - SOUND_FREQ = 0x03, // R - Processing play tone request - SOUND_STOP = 0x04 // W - Stop sound imedately and close hardware -}; - -// Constants related to Mode -enum -{ - SOUND_ONCE = 0x00, // W - Only play file once - SOUND_LOOP = 0x01, // W - Play file until writing "SOUND_STOP" into "State" or new "update" - SOUND_TONE = 0x02 // W - Play tone specified in Freq for Duration ms -}; - -typedef struct -{ - UWORD Freq; // RW - Tone frequency [Hz] - UWORD Duration; // RW - Tone duration [mS] - UWORD SampleRate; // RW - Sound file sample rate [2000..16000] - UBYTE SoundFilename[FILENAME_LENGTH + 1]; // RW - Sound/melody filename - UBYTE Flags; // RW - Play flag - descripted above - UBYTE State; // RW - Play state - descriped above - UBYTE Mode; // RW - Play mode - descriped above - UBYTE Volume; // RW - Sound/melody volume [0..4] 0 = off -}IOMAPSOUND; - - -#endif - - - diff --git a/AT91SAM7S256/Source/c_ui.c b/AT91SAM7S256/Source/c_ui.c deleted file mode 100644 index 7e39d6f..0000000 --- a/AT91SAM7S256/Source/c_ui.c +++ /dev/null @@ -1,1944 +0,0 @@ -// -// Programmer -// -// Date init 14.12.2004 -// -// Reviser $Author:: Dkandlun $ -// -// Revision date $Date:: 10-06-08 9:26 $ -// -// Filename $Workfile:: c_ui.c $ -// -// Version $Revision:: 7 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_ui.c $ -// -// Platform C -// - -#include "stdio.h" -#include "string.h" -#include "ctype.h" -#include "stdconst.h" -#include "modules.h" -#include "c_ui.iom" -#include "c_ui.h" -#include "m_sched.h" -#include "c_display.iom" -#include "c_loader.iom" -#include "c_button.iom" -#include "c_sound.iom" -#include "c_input.iom" -#include "c_output.iom" -#include "c_ioctrl.iom" -#include "c_cmd.iom" -#include "c_comm.iom" -#include "c_lowspeed.iom" - -static IOMAPUI IOMapUi; -static VARSUI VarsUi; -static HEADER **pHeaders; - -const HEADER cUi = -{ - 0x000C0001L, - "Ui", - cUiInit, - cUiCtrl, - cUiExit, - (void *)&IOMapUi, - (void *)&VarsUi, - (UWORD)sizeof(IOMapUi), - (UWORD)sizeof(VarsUi), - 0x0000 // Code size - not used so far -}; - - -// ****** GENERAL GRAPHIC RESOURCES ****************************************** - -#include "Display.txt" // Bitmap for frame used in view and datalog -#include "LowBattery.txt" // Bitmap showed when low battery occures -#include "Font.txt" // Font used for all text -#include "Step.txt" // Bitmap used in On Brick Programming -#include "Cursor.txt" // Bitmap for cursor -#include "Running.txt" // Icon collection used for "running" symbol -#include "Port.txt" // Font used for naming sensor ports in datalog/bluetooth -#include "Ok.txt" // Bitmap for OK buttom in get user string -#include "Wait.txt" // Bitmap for feedback -#include "Fail.txt" // Bitmap for feedback -#include "Info.txt" // Bitmap for feedback -#include "Icons.txt" // Icon collection used for menues - -// ****** INTRO ANIMATION RESOURCES ****************************************** - -#include "RCXintro_1.txt" // Bitmap for picture 1 in the intro animation -#include "RCXintro_2.txt" // Bitmap for picture 2 in the intro animation -#include "RCXintro_3.txt" // Bitmap for picture 3 in the intro animation -#include "RCXintro_4.txt" // Bitmap for picture 4 in the intro animation -#include "RCXintro_5.txt" // Bitmap for picture 5 in the intro animation -#include "RCXintro_6.txt" // Bitmap for picture 6 in the intro animation -#include "RCXintro_7.txt" // Bitmap for picture 7 in the intro animation -#include "RCXintro_8.txt" // Bitmap for picture 8 in the intro animation -#include "RCXintro_9.txt" // Bitmap for picture 9 in the intro animation -#include "RCXintro_10.txt" // Bitmap for picture 10 in the intro animation -#include "RCXintro_11.txt" // Bitmap for picture 11 in the intro animation -#include "RCXintro_12.txt" // Bitmap for picture 12 in the intro animation -#include "RCXintro_13.txt" // Bitmap for picture 13 in the intro animation -#include "RCXintro_14.txt" // Bitmap for picture 14 in the intro animation -#include "RCXintro_15.txt" // Bitmap for picture 15 in the intro animation -#include "RCXintro_16.txt" // Bitmap for picture 16 in the intro animation - -const BMPMAP *Intro[NO_OF_INTROBITMAPS] = // Picture sequence for the intro animation -{ - (BMPMAP*) POINTER_TO_DATA (RCXintro_1), - (BMPMAP*) POINTER_TO_DATA (RCXintro_2), - (BMPMAP*) POINTER_TO_DATA (RCXintro_3), - (BMPMAP*) POINTER_TO_DATA (RCXintro_4), - (BMPMAP*) POINTER_TO_DATA (RCXintro_5), - (BMPMAP*) POINTER_TO_DATA (RCXintro_6), - (BMPMAP*) POINTER_TO_DATA (RCXintro_7), - (BMPMAP*) POINTER_TO_DATA (RCXintro_8), - (BMPMAP*) POINTER_TO_DATA (RCXintro_9), - (BMPMAP*) POINTER_TO_DATA (RCXintro_10), - (BMPMAP*) POINTER_TO_DATA (RCXintro_11), - (BMPMAP*) POINTER_TO_DATA (RCXintro_12), - (BMPMAP*) POINTER_TO_DATA (RCXintro_13), - (BMPMAP*) POINTER_TO_DATA (RCXintro_14), - (BMPMAP*) POINTER_TO_DATA (RCXintro_15), - (BMPMAP*) POINTER_TO_DATA (RCXintro_16) -}; - -// ****** STATUS LINE GRAPHIC RESOURCES ************************************** - -#include "Status.txt" // Status icon collection file - -enum STATUS_NO // Index in status icon collection file -{ - STATUS_NO_NOT_USED, - STATUS_NO_RUNNING_0, - STATUS_NO_RUNNING_1, - STATUS_NO_RUNNING_2, - STATUS_NO_RUNNING_3, - STATUS_NO_RUNNING_4, - STATUS_NO_RUNNING_5, - STATUS_NO_RUNNING_6, - STATUS_NO_RUNNING_7, - STATUS_NO_RUNNING_8, - STATUS_NO_RUNNING_9, - STATUS_NO_RUNNING_10, - STATUS_NO_RUNNING_11, - STATUS_NO_BATTERY_0, - STATUS_NO_BATTERY_1, - STATUS_NO_BATTERY_2, - STATUS_NO_BATTERY_3, - STATUS_NO_BATTERY_4, - STATUS_NO_BATTERY_5, - STATUS_NO_RECHARGEABLE_0, - STATUS_NO_RECHARGEABLE_1, - STATUS_NO_RECHARGEABLE_2, - STATUS_NO_RECHARGEABLE_3, - STATUS_NO_RECHARGEABLE_4, - STATUS_NO_RECHARGEABLE_5, - STATUS_NO_BLUETOOTH_0, - STATUS_NO_BLUETOOTH_1, - STATUS_NO_BLUETOOTH_2, - STATUS_NO_BLUETOOTH_3, - STATUS_NO_BLUETOOTH_4, - STATUS_NO_BLUETOOTH_5, - STATUS_NO_USB_0, - STATUS_NO_USB_1, - STATUS_NO_USB_2, - STATUS_NO_USB_3, - STATUS_NO_USB_4, - STATUS_NO_USB_5 -}; - -// ****** BT DEVICE GRAPHIC RESOURCES **************************************** - -#include "Devices.txt" // Icon collection used for Blue tooth devices - -// ****** BT CONNECTIONS GRAPHIC RESOURCES *********************************** - -#include "Connections.txt" // Icon collection used for Blue tooth connections - -// ****** FREE TEXT GRAPHIC RESOURCES **************************************** - -#include "Ui.txt" // Text strings that is'nt defined in menu files - -enum // String index in text string file -{ - TXT_GENERAL_EMPTY, - // BlueTooth connect - TXT_FB_BT_CONNECTING_WAIT, // "Connecting" - TXT_FB_BT_CONNECT_BUSY_FAIL, // "Line is busy" - TXT_FB_BT_CONNECTING_FAIL, // "Failed!" - - // BlueTooth send file - TXT_FB_BT_SENDING_NO_CONN_FAIL, // "Connection?" - TXT_FB_BT_SENDING_WAIT, // "Sending file" - TXT_FB_BT_SENDING_FAIL, // "Failed!" - - // BlueTooth on/off - TXT_FB_BT_TURNING_ON_WAIT, // "Turning on" - TXT_FB_BT_TURNING_ON_FAIL, // "Failed!" - TXT_FB_BT_TURNING_OFF_WAIT, // "Turning off" - TXT_FB_BT_TURNING_OFF_FAIL, // "Failed!" - - // BlueTooth seach - TXT_FB_BT_SEARCHING_WAIT, // "Searching" - TXT_FB_BT_SEARCH_ABORTED_INFO, // "Aborted!" - TXT_FB_BT_SEARCHING_FAIL, // "Failed!" - - // BlueTooth device list - TXT_FB_BT_REMOVE_FAIL, // "Failed!" - - // BlueTooth connection list - TXT_FB_BT_DISCONNECT_FAIL, // "Failed!" - - // On Brick Programming - TXT_FB_OBP_MEMORY_FULL_FAIL, // "Memory full!" - TXT_FB_OBP_FILE_SAVED_INFO, // "File saved" - TXT_FB_OBP_FILE_EXIST_FAIL, // "File exist" - TXT_FB_OBP_OVERWRITE_FAIL, // "overwrite!" - - // Datalogging - TXT_FB_DL_FILE_SAVED_INFO, // "File saved" - TXT_FB_DL_FILE_EXIST_FAIL, // "File exist" - TXT_FB_DL_OVERWRITE_FAIL, // "overwrite!" - - // File delete - TXT_FB_FD_FILE_DELETED_INFO, // "File deleted" - - // Files delete - TXT_FB_FD_FILES_INFO, // "Files" - TXT_FB_FD_DELETED_INFO, // "deleted" - - // File run - TXT_FILERUN_RUNNING, // "Running" - TXT_FILERUN_ABORTED, // "Aborted!" - TXT_FILERUN_ENDED, // "Ended" - TXT_FILERUN_FILE_ERROR, // "File error!" - - // Files delete - TXT_FILESDELETE_DELETING_ALL, // "Deleting all" - TXT_FILESDELETE_S_FILES, // "%s files!" - - // Datalogging - TXT_DATALOGGING_PRESS_EXIT_TO, // "Press exit to" - TXT_DATALOGGING_STOP_DATALOGGING, // "stop datalogging" - TXT_DATALOGGING_PORT_OCCUPIED, // "Port occupied!" - TXT_DATALOGGING_RATE, // "H:MM:SS:00 - TXT_DATALOGGING_TIME, // "HH:MM:SS" - - // File types - TXT_FILETYPE_SOUND, // "Sound" - TXT_FILETYPE_LMS, // "Software" - TXT_FILETYPE_NXT, // "NXT" - TXT_FILETYPE_TRY_ME, // "Try me" - TXT_FILETYPE_DATA, // "Datalog" - - // Get user string - TXT_GETUSERSTRING_PIN, // "Pin:" - TXT_GETUSERSTRING_FILENAME, // "Filename:" - - // On Brick Programming - TXT_ONBRICKPROGRAMMING_PLEASE_USE_PORT, // "Please use port:" - TXT_ONBRICKPROGRAMMING_1_TOUCH_SENSOR, // "1 - Touch sensor" - TXT_ONBRICKPROGRAMMING_2_SOUND_SENSOR, // "2 - Sound sensor" - TXT_ONBRICKPROGRAMMING_3_LIGHT_SENSOR, // "3 - Light sensor" - TXT_ONBRICKPROGRAMMING_4_ULTRA_SONIC, // "4 - Ultra sonic" - TXT_ONBRICKPROGRAMMING_BC_LR_MOTORS, // "B/C - L/R motors" - - // View - TXT_VIEW_SELECT, // "Select" - - // BlueTooth device list - TXT_BTDEVICELIST_SELECT, // "Select" - - // BlueTooth connection list - TXT_BTCONNECTLIST_SELECT, // "Select" - - // Bluetooth list errors - TXT_FB_BT_ERROR_LR_COULD_NOT_SAVE_1, // BT save data error! - TXT_FB_BT_ERROR_LR_COULD_NOT_SAVE_2, // - TXT_FB_BT_ERROR_LR_STORE_IS_FULL_1, // BT store is full error! - TXT_FB_BT_ERROR_LR_STORE_IS_FULL_2, // - TXT_FB_BT_ERROR_LR_UNKOWN_ADDR_1, // BT unknown addr. error! - TXT_FB_BT_ERROR_LR_UNKOWN_ADDR_2, // - - // Datalog errors - TXT_FB_DL_ERROR_MEMORY_FULL_1, // Memory is full! - TXT_FB_DL_ERROR_MEMORY_FULL_2, // - - // Power of time - TXT_POWEROFFTIME_NEVER // "Never" - -}; - -// ****** FILE TYPE GRAPHIC RESOURCES **************************************** - -#define ALLFILES 0x1A // Icon collection offset - -enum // File type id's -{ - FILETYPE_ALL, // 0 = All - FILETYPE_SOUND, // 1 = Sound - FILETYPE_LMS, // 2 = LMS - FILETYPE_NXT, // 3 = NXT - FILETYPE_TRYME, // 4 = Try me - FILETYPE_DATALOG, // 5 = Datalog - FILETYPES -}; - -const UBYTE TXT_FILE_EXT[FILETYPES][4] = -{ - "*", // 0 = All - TXT_SOUND_EXT, // 1 = Sound - TXT_LMS_EXT, // 2 = LMS - TXT_NXT_EXT, // 3 = NXT - TXT_TRYME_EXT, // 4 = Try me - TXT_DATA_EXT // 5 = Datalog -}; - -const UBYTE TXT_FILETYPE[FILETYPES] = -{ - 0, // NA - TXT_FILETYPE_SOUND, // 1 = Sound - TXT_FILETYPE_LMS, // 2 = LMS - TXT_FILETYPE_NXT, // 3 = NXT - TXT_FILETYPE_TRY_ME,// 4 = Try me - TXT_FILETYPE_DATA // 5 = Datalog -}; - -// ****** POWER OFF DEFINITIONS ********************************************** - -#define POWER_OFF_TIME_STEPS 6 -#define POWER_OFF_TIME_DEFAULT 3 - -const UBYTE PowerOffTimeSteps[POWER_OFF_TIME_STEPS] = { 0,2,5,10,30,60 }; // [min] - -// ****** BATTERY DEFINITIONS ************************************************ - -#define BATTERYLIMITS 4 // [Cnt] -#define BATTERYLIMITHYST 100 // [mV] -#define RECHARGEABLELIMITHYST 50 // [mV] - -const UWORD BatteryLimits[BATTERYLIMITS] = -{ - 6100,6500,7000,7500 // [mV] -}; - -const UWORD RechargeableLimits[BATTERYLIMITS] = -{ - 7100,7200,7300,7500 // [mV] -}; - -//******* UI MENU FILE HANDLER ************************************************************************* - -#include "Mainmenu.rms" -#include "Submenu01.rms" -#include "Submenu02.rms" -#include "Submenu03.rms" -#include "Submenu04.rms" -#include "Submenu05.rms" -#include "Submenu06.rms" -#include "Submenu07.rms" - -const UBYTE *MenuPointers[] = -{ - (UBYTE*)MAINMENU, - (UBYTE*)SUBMENU01, - (UBYTE*)SUBMENU02, - (UBYTE*)SUBMENU03, - (UBYTE*)SUBMENU04, - (UBYTE*)SUBMENU05, - (UBYTE*)SUBMENU06, - (UBYTE*)SUBMENU07 -}; - - -UBYTE* cUiGetMenuPointer(UBYTE FileNo) -{ - return ((UBYTE*)MenuPointers[FileNo]); -} - - -//****************************************************************************************************** - -UBYTE* cUiGetString(UBYTE No) // Get string in text string file -{ - UBYTE *Result = NULL; - TXT *pUi; - UWORD Tmp; - - pUi = (TXT*)Ui; - if (No) - { - if (No <= pUi->ItemsY) - { - Tmp = No - 1; - Tmp *= pUi->ItemCharsX; - Result = &(pUi->Data[Tmp]); - } - } - - return (Result); -} - - -UBYTE cUiReadButtons(void) // Read buttons -{ - UBYTE Result = BUTTON_NONE; - - if (!(IOMapUi.Flags & UI_DISABLE_LEFT_RIGHT_ENTER)) - { - if ((pMapButton->State[BTN3] & PRESSED_STATE)) - { - Result = BUTTON_LEFT; - } - if ((pMapButton->State[BTN2] & PRESSED_STATE)) - { - Result = BUTTON_RIGHT; - } - if ((pMapButton->State[BTN4] & PRESSED_STATE)) - { - Result = BUTTON_ENTER; - } - } - if (!(IOMapUi.Flags & UI_DISABLE_EXIT)) - { - if ((pMapButton->State[BTN1] & PRESSED_STATE)) - { - Result = BUTTON_EXIT; - } - } - if (Result == BUTTON_NONE) - { - // All buttons released - VarsUi.ButtonOld = BUTTON_NONE; - VarsUi.ButtonTime = BUTTON_DELAY_TIME; - } - else - { - // Some button pressed - if (VarsUi.ButtonOld == BUTTON_NONE) - { - // Just pressed - VarsUi.ButtonOld = Result; - VarsUi.ButtonTimer = 0; - } - else - { - // Still pressed - Result = BUTTON_NONE; - - if (VarsUi.ButtonTimer >= VarsUi.ButtonTime) - { - VarsUi.ButtonTimer = 0; - VarsUi.ButtonTime = BUTTON_REPEAT_TIME; - if ((VarsUi.ButtonOld == BUTTON_LEFT) || (VarsUi.ButtonOld == BUTTON_RIGHT)) - { - // If arrow repeat - Result = VarsUi.ButtonOld; - } - } - } - } - if (VarsUi.ButtonOld == BUTTON_NONE) - { - // If no key - check interface - Result = IOMapUi.Button; - IOMapUi.Button = BUTTON_NONE; - } - if (Result != BUTTON_NONE) - { - // If key - play key sound file - sprintf((char*)pMapSound->SoundFilename,"%s.%s",(char*)UI_KEYCLICK_SOUND,(char*)TXT_FILE_EXT[FILETYPE_SOUND]); - pMapSound->Volume = IOMapUi.Volume; - pMapSound->Mode = SOUND_ONCE; - pMapSound->Flags |= SOUND_UPDATE; - - // Reset power down timer - IOMapUi.Flags |= UI_RESET_SLEEP_TIMER; - } - - return (Result); -} - - -void cUiListLeft(UBYTE Limit,UBYTE *Center) -{ - UBYTE Tmp; - - Tmp = *Center; - if (Tmp > 1) - { - Tmp--; - } - else - { - if (Limit > 2) - { - Tmp = Limit; - } - } - *Center = Tmp; -} - - -void cUiListRight(UBYTE Limit,UBYTE *Center) -{ - UBYTE Tmp; - - Tmp = *Center; - if (Tmp < Limit) - { - Tmp++; - } - else - { - if (Limit > 2) - { - Tmp = 1; - } - } - *Center = Tmp; -} - - -void cUiListCalc(UBYTE Limit,UBYTE *Center,UBYTE *Left,UBYTE *Right) -{ - switch (Limit) - { - case 1 : - { - *Left = 0; - *Right = 0; - } - break; - - case 2 : - { - if ((*Center) == 1) - { - *Left = 0; - *Right = 2; - } - else - { - *Left = 1; - *Right = 0; - } - } - break; - - default : - { - *Left = *Center - 1; - if ((*Left) < 1) - { - *Left = Limit; - } - *Right = *Center + 1; - if ((*Right) > Limit) - { - *Right = 1; - } - } - break; - - } -} - - -UBYTE cUiMenuSearchSensorIcon(UBYTE Sensor) -{ - UBYTE Result = 0; - MENUITEM *MenuItem; - UBYTE Index; - - for (Index = 0;(Index < IOMapUi.pMenu->Items) && (Result == NULL);Index++) - { - MenuItem = &IOMapUi.pMenu->Data[Index]; - if (MenuItem->FunctionParameter == Sensor) - { - Result = MenuItem->IconImageNo; - } - } - - return (Result); -} - - -ULONG cUiMenuGetId(MENUITEM *pMenuItem) -{ - ULONG MenuId; - - MenuId = (ULONG)pMenuItem->ItemId01; - MenuId |= (ULONG)pMenuItem->ItemId23 << 8; - MenuId |= (ULONG)pMenuItem->ItemId45 << 16; - MenuId |= (ULONG)pMenuItem->ItemId67 << 24; - - return (MenuId); -} - - -ULONG cUiMenuGetSpecialMask(MENUITEM *pMenuItem) -{ - ULONG Mask; - - Mask = 0; - if (pMenuItem != NULL) - { - Mask = (ULONG)pMenuItem->SpecialMask0; - Mask |= (ULONG)pMenuItem->SpecialMask1 << 8; - Mask |= (ULONG)pMenuItem->SpecialMask2 << 16; - Mask |= (ULONG)pMenuItem->SpecialMask3 << 24; - } - - return (Mask); -} - - -UBYTE* cUiMenuGetIconImage(UBYTE No) -{ - UBYTE *Image; - - Image = NULL; - if (No < (Icons->ItemsX * Icons->ItemsY)) - { - Image = (UBYTE*)&Icons->Data[No * Icons->ItemPixelsX * (Icons->ItemPixelsY / 8)]; - } - - return (Image); -} - - -ULONG cUiMenuMotherId(ULONG Id,UBYTE Level) -{ - ULONG MotherIdMask; - - MotherIdMask = 0xFFFFFFFFL >> ((8 - Level) * 4); - MotherIdMask |= 0xFFFFFFFFL << ((Level + 1) * 4); - - return (Id & MotherIdMask); -} - - -UBYTE cUiMenuIdValid(MENUFILE *pMenuFile,ULONG Id) -{ - ULONG SpecialMask; - ULONG MotherId; - UBYTE Level; - UBYTE Result; - - Result = FALSE; - Level = pMenuFile->MenuLevel; - - if (Level) - { - SpecialMask = pMenuFile->MenuLevels[Level - 1].SpecialFlags; - MotherId = pMenuFile->MenuLevels[Level - 1].Id; - if ((SpecialMask & MENU_SKIP_THIS_MOTHER_ID)) - { - MotherId &= ~(0x0000000F << ((Level - 1) * 4)); - SpecialMask >>= 28; - MotherId |= (SpecialMask << ((Level - 1) * 4)); - } - if (MotherId == cUiMenuMotherId(Id,Level)) - { - Id >>= (Level * 4); - if ((Id & 0x0000000F) && (!(Id & 0xFFFFFFF0))) - { - Result = TRUE; - } - } - } - else - { - if ((Id & 0x0000000F) && (!(Id & 0xFFFFFFF0))) - { - Result = TRUE; - } - } - - return (Result); -} - - -UBYTE cUiMenuGetNoOfMenus(MENU *pMenu,MENUFILE *pMenuFile) -{ - ULONG MenuId; - UBYTE NoOfMenus; - UBYTE Index; - - NoOfMenus = 0; - for (Index = 0;Index < pMenu->Items;Index++) - { - MenuId = cUiMenuGetId(&pMenu->Data[Index]); - - if (cUiMenuIdValid(pMenuFile,MenuId) == TRUE) - { - if ((cUiMenuGetSpecialMask(&pMenu->Data[Index]) & MENU_ONLY_BT_ON)) - { - // BT module must be on - if (!(IOMapUi.BluetoothState & BT_STATE_OFF)) - { - // Yes - NoOfMenus++; - } - } - else - { - if ((cUiMenuGetSpecialMask(&pMenu->Data[Index]) & MENU_ONLY_DATALOG_ENABLED)) - { - // Datalog menu must be enabled - if (VarsUi.NVData.DatalogEnabled) - { - // Yes - NoOfMenus++; - } - } - else - { - // No restrictions - NoOfMenus++; - } - } - } - } - - return (NoOfMenus); -} - - -UBYTE cUiGetMenuItemIndex(MENU *pMenu,MENUFILE *pMenuFile,UBYTE No) -{ - ULONG MenuId; - UBYTE NoOfMenus; - UBYTE Index; - UBYTE TmpIndex = 0; - - NoOfMenus = 0; - for (Index = 0;(Index < pMenu->Items) && (No != NoOfMenus);Index++) - { - MenuId = cUiMenuGetId(&pMenu->Data[Index]); - - if (cUiMenuIdValid(pMenuFile,MenuId) == TRUE) - { - if ((cUiMenuGetSpecialMask(&pMenu->Data[Index]) & MENU_ONLY_BT_ON)) - { - // BT module must be on - if (!(IOMapUi.BluetoothState & BT_STATE_OFF)) - { - // Yes - TmpIndex = Index; - NoOfMenus++; - } - } - else - { - if ((cUiMenuGetSpecialMask(&pMenu->Data[Index]) & MENU_ONLY_DATALOG_ENABLED)) - { - // Datalog menu must be enabled - if (VarsUi.NVData.DatalogEnabled) - { - // Yes - TmpIndex = Index; - NoOfMenus++; - } - } - else - { - // No restrictions - TmpIndex = Index; - NoOfMenus++; - } - } - } - } - if (No != NoOfMenus) - { - Index = TmpIndex + 1; - } - - return (Index); -} - - - -UBYTE cUiMenuGetNo(MENU *pMenu,ULONG Id,UBYTE Level) -{ - ULONG MenuId; - ULONG MotherId; - UBYTE Index; - UBYTE No; - UBYTE NoOfItems; - - No = 0; - NoOfItems = 0; - - MotherId = cUiMenuMotherId(Id,Level); - - for (Index = 0;(Index < pMenu->Items) && (No == 0);Index++) - { - MenuId = cUiMenuGetId(&pMenu->Data[Index]); - - // Scanning all id's until No is found - if (!(MenuId >> ((Level + 1) * 4))) - { - // MenuId is above or on actual level - if (((MenuId >> (Level * 4)) & 0x0000000F)) - { - // MenuId is on actual level - if (MotherId == cUiMenuMotherId(MenuId,Level)) - { - // Same mother id - NoOfItems++; - if (MenuId == Id) - { - No = NoOfItems; - } - } - } - } - } - - return (No); -} - -void cUiUpdateStatus(void) -{ - UWORD Tmp; - UWORD Hyst; - UWORD *pTmp; - UBYTE Pointer; - - if (++VarsUi.UpdateCounter >= RUN_STATUS_CHANGE_TIME) - { - VarsUi.UpdateCounter = 0; - - // Update running status icon pointer - if (++VarsUi.Running >= 12) - { - VarsUi.Running = 0; - } - - // Get battery voltage limits - if ((IoFromAvr.Battery & 0x8000)) - { - IOMapUi.Rechargeable = 1; - pTmp = (UWORD*)RechargeableLimits; - Hyst = RECHARGEABLELIMITHYST; - } - else - { - IOMapUi.Rechargeable = 0; - pTmp = (UWORD*)BatteryLimits; - Hyst = BATTERYLIMITHYST; - } - - // Calculate battery voltage - Tmp = IoFromAvr.Battery & 0x03FF; - Tmp = (UWORD)((float)Tmp * BATTERY_COUNT_TO_MV); - - IOMapUi.BatteryVoltage = Tmp; - - // Find new battery state - Pointer = 0; - while ((Tmp > pTmp[Pointer]) && (Pointer < BATTERYLIMITS)) - { - Pointer++; - } - - // Change battery state - if (Pointer != IOMapUi.BatteryState) - { - if (Pointer > IOMapUi.BatteryState) - { - if (Tmp > (pTmp[IOMapUi.BatteryState] + Hyst)) - { - IOMapUi.BatteryState = Pointer; - } - } - else - { - IOMapUi.BatteryState = Pointer; - } - } - - // Control toggle and bitmap - if (IOMapUi.BatteryState) - { - VarsUi.BatteryToggle = 0; - VarsUi.LowBatt = 0; - } - else - { - if (VarsUi.LowBatt < 255) - { - VarsUi.LowBatt++; - } - - if (VarsUi.BatteryToggle) - { - VarsUi.BatteryToggle = 0; - } - else - { - VarsUi.BatteryToggle = 1; - } - } - - // Ensure frequently status updates - IOMapUi.Flags |= UI_UPDATE; - } - - if ((IOMapUi.Flags & UI_ENABLE_STATUS_UPDATE)) - { - if ((IOMapUi.Flags & UI_UPDATE) || (IOMapUi.Flags & UI_REDRAW_STATUS)) - { - VarsUi.ErrorTimer = 0; - pMapDisplay->pStatusText = (UBYTE*)VarsUi.StatusText; - - // Status line update nessesary - if (IOMapUi.BatteryState < Status->ItemsX) - { - // Update battery status icons - if (IoFromAvr.Battery & 0x8000) - { - VarsUi.NewStatusIcons[STATUSICON_BATTERY] = STATUS_NO_RECHARGEABLE_0 + IOMapUi.BatteryState + VarsUi.BatteryToggle; - } - else - { - VarsUi.NewStatusIcons[STATUSICON_BATTERY] = STATUS_NO_BATTERY_0 + IOMapUi.BatteryState + VarsUi.BatteryToggle; - } - } - - // Update bluetooth status icons - if ((IOMapUi.BluetoothState & (BT_STATE_VISIBLE | BT_STATE_CONNECTED | BT_STATE_OFF)) < Status->ItemsX) - { - VarsUi.NewStatusIcons[STATUSICON_BLUETOOTH] = STATUS_NO_BLUETOOTH_0 + (IOMapUi.BluetoothState & (BT_STATE_VISIBLE | BT_STATE_CONNECTED | BT_STATE_OFF)); - } - - // Update usb status icons - if (IOMapUi.UsbState < 6) - { - VarsUi.NewStatusIcons[STATUSICON_USB] = STATUS_NO_USB_0 + IOMapUi.UsbState; - } - - // Update running status icons - if (IOMapUi.RunState == FALSE) - { - VarsUi.Running = 0; - } - VarsUi.NewStatusIcons[STATUSICON_VM] = STATUS_NO_RUNNING_0 + VarsUi.Running; - - // Update only changed status icons - for (Pointer = 0;Pointer < STATUSICONS;Pointer++) - { - if ((pMapDisplay->StatusIcons[Pointer] != VarsUi.NewStatusIcons[Pointer])) - { - pMapDisplay->StatusIcons[Pointer] = VarsUi.NewStatusIcons[Pointer]; - pMapDisplay->UpdateMask |= STATUSICON_BIT(Pointer); - } - } - - if ((IOMapUi.Flags & UI_REDRAW_STATUS)) - { - // Entire status line needs to be redrawed - if (pMapComm->BrickData.Name[0]) - { - for (Pointer = 0;Pointer < STATUSTEXT_SIZE;Pointer++) - { - VarsUi.StatusText[Pointer] = pMapComm->BrickData.Name[Pointer]; - } - VarsUi.StatusText[Pointer] = 0; - } - pMapDisplay->EraseMask |= SPECIAL_BIT(STATUSTEXT); - pMapDisplay->UpdateMask |= SPECIAL_BIT(STATUSTEXT); - pMapDisplay->UpdateMask |= (SPECIAL_BIT(TOPLINE) | STATUSICON_BITS); - } - - // Clear update flag - IOMapUi.Flags &= ~UI_REDRAW_STATUS; - IOMapUi.Flags &= ~UI_UPDATE; - } - } - else - { - pMapDisplay->UpdateMask &= ~(STATUSICON_BITS | SPECIAL_BIT(TOPLINE) | SPECIAL_BIT(STATUSTEXT)); - } -} - - - - -void cUiMenuCallFunction(UBYTE Function,UBYTE Parameter) -{ - if (Function) - { - VarsUi.Function = Function; - VarsUi.Parameter = Parameter; - } -} - - -void cUiMenuNextFile(void) -{ - MENU *pTmpMenu; - - pTmpMenu = (MENU*)cUiGetMenuPointer(VarsUi.pMenuLevel->NextFileNo); - if (pTmpMenu != NULL) - { - if (VarsUi.MenuFileLevel < (MENUFILELEVELS - 1)) - { - VarsUi.MenuFileLevel++; - VarsUi.MenuFiles[VarsUi.MenuFileLevel].FileId = VarsUi.pMenuLevel->NextFileNo; - VarsUi.MenuFiles[VarsUi.MenuFileLevel].MenuLevel = 0; - VarsUi.MenuFiles[VarsUi.MenuFileLevel].MenuLevels[VarsUi.MenuFiles[VarsUi.MenuFileLevel].MenuLevel].ItemIndex = VarsUi.pMenuLevel->NextMenuNo; - IOMapUi.pMenu = pTmpMenu; - } - } -} - - -void cUiMenuPrevFile(void) -{ - if (VarsUi.MenuFileLevel) - { - VarsUi.MenuFileLevel--; - IOMapUi.pMenu = (MENU*)cUiGetMenuPointer(VarsUi.MenuFiles[VarsUi.MenuFileLevel].FileId); - } -} - - -void cUiMenuNext(void) -{ - if (VarsUi.pMenuFile->MenuLevel < (MENULEVELS - 1)) - { - VarsUi.pMenuFile->MenuLevel++; - VarsUi.pMenuFile->MenuLevels[VarsUi.pMenuFile->MenuLevel].ItemIndex = VarsUi.pMenuLevel->NextMenuNo; - } -} - - -void cUiMenuPrev(void) -{ - if (VarsUi.pMenuFile->MenuLevel) - { - VarsUi.pMenuFile->MenuLevel--; - } -} - - -void cUiMenuEnter(void) -{ - // Call function with parameter (if pressent) - if (!(VarsUi.pMenuLevel->SpecialFlags & MENU_INIT_CALLS)) - { - cUiMenuCallFunction(VarsUi.pMenuLevel->FunctionNo,VarsUi.pMenuLevel->Parameter); - } - - if (VarsUi.EnterOnlyCalls != TRUE) - { - if ((VarsUi.pMenuLevel->SpecialFlags & MENU_ENTER_LEAVES_MENUFILE)) - { - cUiMenuPrevFile(); - } - else - { - // Load new menu file (if pressent) - if (VarsUi.pMenuLevel->NextFileNo) - { - cUiMenuNextFile(); - } - else - { - // Activate next menu level (if pressent) - if (VarsUi.pMenuLevel->NextMenuNo) - { - cUiMenuNext(); - } - } - } - IOMapUi.State = NEXT_MENU; - } - else - { - VarsUi.EnterOnlyCalls = FALSE; - IOMapUi.State = DRAW_MENU; - } -} - - -void cUiMenuExit(void) -{ - - if ((VarsUi.pMenuLevel->SpecialFlags & MENU_EXIT_CALLS)) - { - // Call function with parameter (if pressent) - if (!(VarsUi.pMenuLevel->SpecialFlags & MENU_INIT_CALLS)) - { - cUiMenuCallFunction(VarsUi.pMenuLevel->FunctionNo,VarsUi.pMenuLevel->Parameter); - } - } - - // Call function with 0xFF (if ordered) - if ((VarsUi.pMenuLevel->SpecialFlags & MENU_EXIT_CALLS_WITH_FF)) - { - cUiMenuCallFunction(VarsUi.pMenuLevel->FunctionNo,MENU_EXIT); - } - - if (VarsUi.ExitOnlyCalls != TRUE) - { - if ((VarsUi.pMenuFile->MenuLevel) && (!(VarsUi.pMenuLevel->SpecialFlags & MENU_EXIT_LEAVES_MENUFILE))) - { - if (!(VarsUi.pMenuLevel->SpecialFlags & MENU_EXIT_LOAD_MENU)) - { - cUiMenuPrev(); - if ((VarsUi.pMenuLevel->SpecialFlags & MENU_BACK_TWICE)) - { - if (VarsUi.pMenuFile->MenuLevel) - { - cUiMenuPrev(); - } - VarsUi.SecondTime = FALSE; - } - if ((VarsUi.pMenuLevel->SpecialFlags & MENU_BACK_THREE_TIMES)) - { - if (VarsUi.pMenuFile->MenuLevel) - { - cUiMenuPrev(); - } - if (VarsUi.pMenuFile->MenuLevel) - { - cUiMenuPrev(); - } - VarsUi.SecondTime = FALSE; - } - } - else - { - VarsUi.EnterOnlyCalls = FALSE; - VarsUi.ExitOnlyCalls = FALSE; - if (VarsUi.pMenuLevel->NextFileNo) - { - cUiMenuNextFile(); - } - else - { - // Activate next menu level (if pressent) - if (VarsUi.pMenuLevel->NextMenuNo) - { - cUiMenuNext(); - } - } - } - if ((VarsUi.pMenuLevel->SpecialFlags & MENU_EXIT_LOAD_POINTER)) - { - VarsUi.pMenuFile->MenuLevels[VarsUi.pMenuFile->MenuLevel].ItemIndex = (UBYTE)((VarsUi.pMenuLevel->SpecialFlags) >> 24) & 0x0F; - } - } - else - { - if (!(VarsUi.pMenuLevel->SpecialFlags & MENU_EXIT_LOAD_MENU)) - { - cUiMenuPrevFile(); - } - else - { - VarsUi.EnterOnlyCalls = FALSE; - VarsUi.ExitOnlyCalls = FALSE; - if (VarsUi.pMenuLevel->NextFileNo) - { - cUiMenuNextFile(); - } - else - { - // Activate next menu level (if pressent) - if (VarsUi.pMenuLevel->NextMenuNo) - { - cUiMenuNext(); - } - } - } - } - IOMapUi.State = NEXT_MENU; - } - else - { - VarsUi.ExitOnlyCalls = FALSE; - IOMapUi.State = DRAW_MENU; - } -} - - -void cUiLoadLevel(UBYTE FileLevel,UBYTE MenuLevel,UBYTE MenuIndex) -{ - UBYTE Tmp; - - VarsUi.MenuFileLevel = FileLevel; - VarsUi.MenuFiles[FileLevel].MenuLevel = MenuLevel; - VarsUi.MenuFiles[FileLevel].MenuLevels[MenuLevel].ItemIndex = MenuIndex; - IOMapUi.pMenu = (MENU*)cUiGetMenuPointer(VarsUi.MenuFiles[VarsUi.MenuFileLevel].FileId); - - VarsUi.pMenuFile = &VarsUi.MenuFiles[VarsUi.MenuFileLevel]; - VarsUi.pMenuLevel = &VarsUi.pMenuFile->MenuLevels[VarsUi.pMenuFile->MenuLevel]; - - // Count no of menues on current level - VarsUi.pMenuLevel->Items = cUiMenuGetNoOfMenus(IOMapUi.pMenu,VarsUi.pMenuFile); - - if (VarsUi.pMenuLevel->Items) - { - // if items > 0 -> prepare allways center icon - Tmp = cUiGetMenuItemIndex(IOMapUi.pMenu,VarsUi.pMenuFile,VarsUi.pMenuLevel->ItemIndex); - - if (VarsUi.pMenuItem != &IOMapUi.pMenu->Data[Tmp - 1]) - { - VarsUi.pMenuItem = &IOMapUi.pMenu->Data[Tmp - 1]; - VarsUi.SecondTime = FALSE; - } - - // Save center menu item parameters - VarsUi.pMenuLevel->Id = cUiMenuGetId(VarsUi.pMenuItem); - VarsUi.pMenuLevel->IconImageNo = VarsUi.pMenuItem->IconImageNo; - VarsUi.pMenuLevel->IconText = VarsUi.pMenuItem->IconText; - VarsUi.pMenuLevel->SpecialFlags = cUiMenuGetSpecialMask(VarsUi.pMenuItem); - VarsUi.pMenuLevel->FunctionNo = VarsUi.pMenuItem->FunctionIndex; - VarsUi.pMenuLevel->Parameter = VarsUi.pMenuItem->FunctionParameter; - VarsUi.pMenuLevel->NextFileNo = VarsUi.pMenuItem->FileLoadNo; - VarsUi.pMenuLevel->NextMenuNo = VarsUi.pMenuItem->NextMenu; - } -} - -#include "Functions.inl" - - -void cUiInit(void* pHeader) -{ - pHeaders = pHeader; - VarsUi.Initialized = FALSE; - IOMapUi.BluetoothState = BT_STATE_OFF; - IOMapUi.UsbState = 0; - IOMapUi.State = INIT_DISPLAY; -} - - -void cUiCtrl(void) -{ - UBYTE Tmp; - -// Testcode for low battery voltage -/* - if ((pMapInput->Inputs[0].InvalidData != INVALID_DATA) && (pMapInput->Inputs[0].ADRaw < 500)) - { - if (VarsUi.LowBatt < 255) - { - VarsUi.LowBatt++; - } - } - else - { - VarsUi.LowBatt = 0; - } -*/ -// - -// Testcode for BT connect request -/* - if ((pMapInput->Inputs[0].InvalidData != INVALID_DATA) && (pMapInput->Inputs[0].ADRaw < 500)) - { - IOMapUi.BluetoothState |= BT_CONNECT_REQUEST | BT_PIN_REQUEST; - } -*/ -// - -// Testcode for BT error attention -/* - if ((pMapInput->Inputs[0].InvalidData != INVALID_DATA) && (pMapInput->Inputs[0].ADRaw < 500)) - { - IOMapUi.Error = LR_UNKOWN_ADDR; - IOMapUi.BluetoothState |= BT_ERROR_ATTENTION; - } -*/ -// - -// Testcode for execute program -/* - if ((pMapInput->Inputs[0].InvalidData != INVALID_DATA) && (pMapInput->Inputs[0].ADRaw < 500)) - { - if ((!(IOMapUi.Flags & UI_EXECUTE_LMS_FILE)) && (IOMapUi.State > INIT_MENU)) - { - strcpy((char*)IOMapUi.LMSfilename,"Untitled-1.rxe"); - IOMapUi.Flags |= UI_EXECUTE_LMS_FILE; - } - } -*/ -// - -// Testcode for force off -/* - if ((pMapInput->Inputs[0].InvalidData != INVALID_DATA) && (pMapInput->Inputs[0].ADRaw < 500) && (VarsUi.Initialized == TRUE)) - { - IOMapUi.ForceOff = TRUE; - } -*/ -// - - - VarsUi.CRPasskey++; - VarsUi.ButtonTimer++; - VarsUi.OBPTimer++; - switch (IOMapUi.State) - { - case INIT_DISPLAY : // Load font and icons - { -// pMapLoader->pFunc(DELETEUSERFLASH,NULL,NULL,NULL); - - VarsUi.Initialized = FALSE; - - IOMapUi.Flags = UI_BUSY; - IOMapUi.RunState = 1; - IOMapUi.BatteryState = 0; - IOMapUi.Error = 0; - IOMapUi.ForceOff = FALSE; - VarsUi.LowBatt = 0; - VarsUi.LowBattHasOccured = 0; - - pMapDisplay->pFont = (FONT*)Font; - pMapDisplay->pStatusIcons = (ICON*)Status; - pMapDisplay->pStatusText = (UBYTE*)VarsUi.StatusText; - pMapDisplay->pStepIcons = (ICON*)Step; - - VarsUi.State = 0; - VarsUi.Pointer = 0; - VarsUi.Timer = CONFIG_INTRO ? -INTRO_START_TIME : 0; - - VarsUi.FNOFState = 0; - VarsUi.FBState = 0; - - VarsUi.UpdateCounter = 0; - VarsUi.Running = 0; - VarsUi.BatteryToggle = 0; - - VarsUi.GUSState = 0; - - IOMapUi.pMenu = (MENU*)cUiGetMenuPointer(0); - IOMapUi.State = CONFIG_INTRO ? INIT_INTRO : INIT_WAIT; - - pMapDisplay->EraseMask = SCREEN_BIT(SCREEN_BACKGROUND); - pMapDisplay->pBitmaps[BITMAP_1] = CONFIG_INTRO ? (BMPMAP*)Intro[VarsUi.Pointer] : RCXintro_16; - pMapDisplay->UpdateMask = BITMAP_BIT(BITMAP_1); - pMapDisplay->Flags |= DISPLAY_ON; - - cUiNVRead(); - IOMapUi.Volume = VarsUi.NVData.VolumeStep; - IOMapUi.SleepTimeout = PowerOffTimeSteps[VarsUi.NVData.PowerdownCode]; - } - break; - -#if CONFIG_INTRO - case INIT_LOW_BATTERY : - { - if (++VarsUi.Timer >= (INTRO_LOWBATT_TIME)) - { - VarsUi.LowBattHasOccured = 2; - pMapDisplay->EraseMask = SCREEN_BIT(SCREEN_BACKGROUND); - pMapDisplay->pBitmaps[BITMAP_1] = (BMPMAP*)Intro[VarsUi.Pointer]; - pMapDisplay->UpdateMask = BITMAP_BIT(BITMAP_1); - IOMapUi.Flags &= ~UI_ENABLE_STATUS_UPDATE; - VarsUi.State = 0; - VarsUi.Pointer = 0; - VarsUi.Timer = -INTRO_START_TIME; - IOMapUi.State = INIT_INTRO; - } - } - break; - - case INIT_INTRO : - { - if (VarsUi.LowBattHasOccured == 1) - { - IOMapUi.Flags |= UI_ENABLE_STATUS_UPDATE; - IOMapUi.Flags |= UI_UPDATE; - IOMapUi.Flags |= UI_REDRAW_STATUS; - VarsUi.Timer = 0; - IOMapUi.State = INIT_LOW_BATTERY; - } - else - { - if (VarsUi.LowBattHasOccured == 0) - { - if (VarsUi.LowBatt) - { - pMapDisplay->pBitmaps[BITMAP_1] = (BMPMAP*)LowBattery; - pMapDisplay->UpdateMask = BITMAP_BIT(BITMAP_1); - VarsUi.LowBattHasOccured = 1; - } - } - if (++VarsUi.Timer >= (INTRO_SHIFT_TIME)) - { - switch (VarsUi.State) - { - case 0 : - { - pMapDisplay->Flags &= ~DISPLAY_REFRESH; - VarsUi.State++; - } - break; - - case 1 : - { - if ((pMapDisplay->Flags & DISPLAY_REFRESH_DISABLED)) - { - if (VarsUi.Pointer < NO_OF_INTROBITMAPS) - { - pMapDisplay->EraseMask |= BITMAP_BIT(BITMAP_1); - pMapDisplay->pBitmaps[BITMAP_1] = (BMPMAP*)Intro[VarsUi.Pointer]; - pMapDisplay->UpdateMask = BITMAP_BIT(BITMAP_1); - if (VarsUi.Pointer == 11) - { - sprintf((char*)pMapSound->SoundFilename,"%s.%s",(char*)UI_STARTUP_SOUND,(char*)TXT_FILE_EXT[FILETYPE_SOUND]); - pMapSound->Volume = IOMapUi.Volume; - pMapSound->Mode = SOUND_ONCE; - pMapSound->Flags |= SOUND_UPDATE; - } - VarsUi.Pointer++; - } - else - { - pMapDisplay->Flags |= DISPLAY_REFRESH; - IOMapUi.State = INIT_WAIT; - } - VarsUi.State++; - } - } - break; - - default : - { - if (!(pMapDisplay->UpdateMask & BITMAP_BIT(BITMAP_1))) - { - pMapDisplay->Flags |= DISPLAY_REFRESH; - VarsUi.Timer = 0; - VarsUi.State = 0; - } - } - break; - - } - } - } - } - break; -#endif /* CONFIG_INTRO */ - - case INIT_WAIT : - { - if (++VarsUi.Timer >= INTRO_STOP_TIME) - { - pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_BACKGROUND); - IOMapUi.State = INIT_MENU; - } - } - break; - - case INIT_MENU : - { - // Restart menu system - VarsUi.Function = 0; - VarsUi.MenuFileLevel = 0; - - cUiLoadLevel(0,0,1); - cUiLoadLevel(0,1,1); - - VarsUi.EnterOnlyCalls = FALSE; - VarsUi.ExitOnlyCalls = FALSE; - - IOMapUi.State = NEXT_MENU; - } - break; - - case NEXT_MENU : // prepare icons - { - // Init various variables - VarsUi.State = 0; - - // Init icon pointers - pMapDisplay->pMenuIcons[MENUICON_LEFT] = NULL; - pMapDisplay->pMenuIcons[MENUICON_CENTER] = NULL; - pMapDisplay->pMenuIcons[MENUICON_RIGHT] = NULL; - - cUiLoadLevel(VarsUi.MenuFileLevel,VarsUi.MenuFiles[VarsUi.MenuFileLevel].MenuLevel,VarsUi.MenuFiles[VarsUi.MenuFileLevel].MenuLevels[VarsUi.MenuFiles[VarsUi.MenuFileLevel].MenuLevel].ItemIndex); - - // Find menu icons - if (VarsUi.pMenuLevel->Items) - { - // Prepare center icon - pMapDisplay->pMenuIcons[MENUICON_CENTER] = cUiMenuGetIconImage(VarsUi.pMenuLevel->IconImageNo); - pMapDisplay->pMenuText = VarsUi.pMenuLevel->IconText; - - if (VarsUi.pMenuLevel->Items == 2) - { - // if 2 menues -> prepare left or right icon - if (VarsUi.pMenuLevel->ItemIndex == 1) - { - Tmp = cUiGetMenuItemIndex(IOMapUi.pMenu,VarsUi.pMenuFile,2); - if (Tmp) - { - Tmp--; - pMapDisplay->pMenuIcons[MENUICON_RIGHT] = cUiMenuGetIconImage(IOMapUi.pMenu->Data[Tmp].IconImageNo); - } - } - else - { - Tmp = cUiGetMenuItemIndex(IOMapUi.pMenu,VarsUi.pMenuFile,1); - if (Tmp) - { - Tmp--; - pMapDisplay->pMenuIcons[MENUICON_LEFT] = cUiMenuGetIconImage(IOMapUi.pMenu->Data[Tmp].IconImageNo); - } - } - } - - if (VarsUi.pMenuLevel->Items > 2) - { - // if more menues -> prepare left and right icon - if (VarsUi.pMenuLevel->ItemIndex > 1) - { - Tmp = VarsUi.pMenuLevel->ItemIndex -1; - } - else - { - Tmp = VarsUi.pMenuLevel->Items; - } - Tmp = cUiGetMenuItemIndex(IOMapUi.pMenu,VarsUi.pMenuFile,Tmp); - if (Tmp) - { - Tmp--; - pMapDisplay->pMenuIcons[MENUICON_LEFT] = cUiMenuGetIconImage(IOMapUi.pMenu->Data[Tmp].IconImageNo); - - } - if (VarsUi.pMenuLevel->ItemIndex < VarsUi.pMenuLevel->Items) - { - Tmp = VarsUi.pMenuLevel->ItemIndex + 1; - } - else - { - Tmp = 1; - } - Tmp = cUiGetMenuItemIndex(IOMapUi.pMenu,VarsUi.pMenuFile,Tmp); - if (Tmp) - { - Tmp--; - pMapDisplay->pMenuIcons[MENUICON_RIGHT] = cUiMenuGetIconImage(IOMapUi.pMenu->Data[Tmp].IconImageNo); - } - } - } - if ((VarsUi.pMenuLevel->SpecialFlags & MENU_ENTER_ONLY_CALLS)) - { - VarsUi.EnterOnlyCalls = TRUE; - } - if ((VarsUi.pMenuLevel->SpecialFlags & MENU_EXIT_ONLY_CALLS)) - { - VarsUi.ExitOnlyCalls = TRUE; - } - - IOMapUi.State = DRAW_MENU; - } - break; - - case DRAW_MENU : // If no function active -> erase screen, draw statusline and menu icons - { - if (VarsUi.Function) - { - // Function active - if (VarsUi.Function < FUNC_NO_MAX) - { - if (Functions[VarsUi.Function](VarsUi.Parameter) == 0) - { - VarsUi.Function = 0; - } - } - else - { - VarsUi.Function = 0; - } - } - else - { - // function inactive - erase screen - if (!(VarsUi.pMenuLevel->SpecialFlags & MENU_LEAVE_BACKGROUND)) - { - pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_LARGE); - - // Draw only icons, frame and icon text - pMapDisplay->UpdateMask = (MENUICON_BITS | SPECIAL_BIT(FRAME_SELECT) | SPECIAL_BIT(MENUTEXT)); - pMapDisplay->TextLinesCenterFlags = 0; - } - else - { - pMapDisplay->EraseMask |= (SPECIAL_BIT(MENUTEXT) | MENUICON_BITS); - - // Draw icons, frame and icon text - pMapDisplay->UpdateMask |= (MENUICON_BITS | SPECIAL_BIT(FRAME_SELECT) | SPECIAL_BIT(MENUTEXT)); - } - - // Draw status - IOMapUi.Flags |= (UI_ENABLE_STATUS_UPDATE | UI_UPDATE | UI_REDRAW_STATUS); - - if ((VarsUi.pMenuLevel->SpecialFlags & MENU_INIT_CALLS_WITH_0) && (VarsUi.SecondTime == FALSE)) - { - VarsUi.SecondTime = TRUE; - cUiMenuCallFunction(VarsUi.pMenuLevel->FunctionNo,MENU_INIT); - } - else - { - if ((VarsUi.pMenuLevel->SpecialFlags & MENU_INIT_CALLS_WITH_1) && (VarsUi.SecondTime == FALSE)) - { - VarsUi.SecondTime = TRUE; - cUiMenuCallFunction(VarsUi.pMenuLevel->FunctionNo,MENU_INIT_ALTERNATIVE); - } - else - { - if ((VarsUi.pMenuLevel->SpecialFlags & MENU_INIT_CALLS) && (VarsUi.SecondTime == FALSE)) - { - VarsUi.SecondTime = TRUE; - cUiMenuCallFunction(VarsUi.pMenuLevel->FunctionNo,VarsUi.pMenuLevel->Parameter); - } - else - { - if ((VarsUi.pMenuLevel->SpecialFlags & MENU_AUTO_PRESS_ENTER)) - { - IOMapUi.State = ENTER_PRESSED; - } - else - { - IOMapUi.State = TEST_BUTTONS; - } - } - } - } - } - } - break; - - case TEST_BUTTONS : // Test buttons to execute new functions and new menus - { - if (VarsUi.Initialized == FALSE) - { - VarsUi.Initialized = TRUE; - IOMapUi.Flags &= ~UI_BUSY; - } - - switch (cUiReadButtons()) - { - case BUTTON_LEFT : - { - IOMapUi.State = LEFT_PRESSED; - } - break; - - case BUTTON_RIGHT : - { - IOMapUi.State = RIGHT_PRESSED; - } - break; - - case BUTTON_ENTER : - { - IOMapUi.State = ENTER_PRESSED; - } - break; - - case BUTTON_EXIT : - { - if (!(VarsUi.pMenuLevel->SpecialFlags & MENU_EXIT_DISABLE)) - { - IOMapUi.State = EXIT_PRESSED; - } - } - break; - - } - - } - break; - - case LEFT_PRESSED : - { - if ((VarsUi.pMenuLevel->SpecialFlags & MENU_LEFT_RIGHT_AS_CALL)) - { - cUiMenuCallFunction(VarsUi.pMenuLevel->FunctionNo,MENU_LEFT); - } - else - { - VarsUi.SecondTime = FALSE; - VarsUi.EnterOnlyCalls = FALSE; - VarsUi.ExitOnlyCalls = FALSE; - - if (VarsUi.pMenuLevel->ItemIndex > 1) - { - VarsUi.pMenuLevel->ItemIndex--; - } - else - { - if (VarsUi.pMenuLevel->Items > 2) - { - VarsUi.pMenuLevel->ItemIndex = VarsUi.pMenuLevel->Items; - } - } - } - IOMapUi.State = NEXT_MENU; - } - break; - - case RIGHT_PRESSED : - { - if ((VarsUi.pMenuLevel->SpecialFlags & MENU_LEFT_RIGHT_AS_CALL)) - { - cUiMenuCallFunction(VarsUi.pMenuLevel->FunctionNo,MENU_RIGHT); - } - else - { - VarsUi.SecondTime = FALSE; - VarsUi.EnterOnlyCalls = FALSE; - VarsUi.ExitOnlyCalls = FALSE; - - if (VarsUi.pMenuLevel->ItemIndex < VarsUi.pMenuLevel->Items) - { - VarsUi.pMenuLevel->ItemIndex++; - } - else - { - if (VarsUi.pMenuLevel->Items > 2) - { - VarsUi.pMenuLevel->ItemIndex = 1; - } - } - } - IOMapUi.State = NEXT_MENU; - } - break; - - case ENTER_PRESSED : - { - if ((VarsUi.pMenuLevel->SpecialFlags & MENU_ENTER_ACT_AS_EXIT)) - { - cUiMenuExit(); - } - else - { - cUiMenuEnter(); - } - } - break; - - case EXIT_PRESSED : - { - if ((VarsUi.pMenuLevel->SpecialFlags & MENU_EXIT_ACT_AS_ENTER)) - { - cUiMenuEnter(); - } - else - { - cUiMenuExit(); - } - } - break; - - case CONNECT_REQUEST : - { - if (cUiBTConnectRequest(MENU_INIT) == 0) - { - IOMapUi.BluetoothState &= ~BT_CONNECT_REQUEST; - cUiLoadLevel(0,1,1); - IOMapUi.State = NEXT_MENU; - IOMapUi.Flags &= ~UI_BUSY; - } - } - break; - - case EXECUTE_FILE : - { - cUiLoadLevel(0,1,1); - cUiMenuEnter(); - cUiLoadLevel(VarsUi.MenuFileLevel,VarsUi.MenuFiles[VarsUi.MenuFileLevel].MenuLevel,VarsUi.MenuFiles[VarsUi.MenuFileLevel].MenuLevels[VarsUi.MenuFiles[VarsUi.MenuFileLevel].MenuLevel].ItemIndex); - cUiMenuEnter(); - cUiLoadLevel(VarsUi.MenuFileLevel,VarsUi.MenuFiles[VarsUi.MenuFileLevel].MenuLevel,VarsUi.MenuFiles[VarsUi.MenuFileLevel].MenuLevels[VarsUi.MenuFiles[VarsUi.MenuFileLevel].MenuLevel].ItemIndex); - cUiMenuEnter(); - cUiLoadLevel(VarsUi.MenuFileLevel,VarsUi.MenuFiles[VarsUi.MenuFileLevel].MenuLevel,VarsUi.MenuFiles[VarsUi.MenuFileLevel].MenuLevels[VarsUi.MenuFiles[VarsUi.MenuFileLevel].MenuLevel].ItemIndex); - - VarsUi.Function = 0; - VarsUi.State = 0; - VarsUi.Pointer = 0; - VarsUi.FNOFState = 0; - VarsUi.FBState = 0; - VarsUi.GUSState = 0; - - strcpy((char*)VarsUi.SelectedFilename,(char*)IOMapUi.LMSfilename); - IOMapUi.State = EXECUTING_FILE; - VarsUi.FileType = FILETYPE_LMS; - cUiFileRun(MENU_INIT); - } - break; - - case EXECUTING_FILE : - { - if (cUiFileRun(MENU_RUN) == 0) - { - IOMapUi.Flags &= ~UI_EXECUTE_LMS_FILE; - IOMapUi.State = NEXT_MENU; - } - } - break; - - case LOW_BATTERY : - { - if (DISPLAY_IDLE) - { - if (cUiReadButtons() != BUTTON_NONE) - { - pMapDisplay->Flags &= ~DISPLAY_POPUP; - pMapDisplay->pBitmaps[BITMAP_1] = (BMPMAP*)VarsUi.LowBattSavedBitmap; - IOMapUi.State = VarsUi.LowBattSavedState; - IOMapUi.Flags &= ~UI_BUSY; - } - } - } - break; - - case BT_ERROR : - { - switch (IOMapUi.Error) - { - case LR_COULD_NOT_SAVE : - { - Tmp = TXT_FB_BT_ERROR_LR_COULD_NOT_SAVE_1; - } - break; - - case LR_STORE_IS_FULL : - { - Tmp = TXT_FB_BT_ERROR_LR_STORE_IS_FULL_1; - } - break; - - default : - { - Tmp = TXT_FB_BT_ERROR_LR_UNKOWN_ADDR_1; - } - break; - - } - - if (!cUiFeedback((BMPMAP*)Fail,Tmp,Tmp + 1,DISPLAY_SHOW_ERROR_TIME)) - { - IOMapUi.BluetoothState &= ~BT_ERROR_ATTENTION; - cUiLoadLevel(0,1,1); - IOMapUi.State = NEXT_MENU; - IOMapUi.Flags &= ~UI_BUSY; - } - } - break; - - } - - // Check for low battery voltage - if (VarsUi.LowBatt >= LOW_BATT_THRESHOLD) - { - if (!VarsUi.LowBattHasOccured) - { - if (DISPLAY_IDLE) - { - if (!(IOMapUi.Flags & UI_BUSY)) - { - pMapDisplay->Flags |= DISPLAY_POPUP; - VarsUi.LowBattHasOccured = 1; - VarsUi.LowBattSavedState = IOMapUi.State; - VarsUi.LowBattSavedBitmap = (UBYTE*)pMapDisplay->pBitmaps[BITMAP_1]; - pMapDisplay->pBitmaps[BITMAP_1] = (BMPMAP*)LowBattery; - pMapDisplay->UpdateMask = BITMAP_BIT(BITMAP_1); - IOMapUi.Flags |= UI_REDRAW_STATUS; - IOMapUi.Flags |= UI_BUSY; - IOMapUi.State = LOW_BATTERY; - } - } - } - } - - // Check for incomming BT connection requests - if ((IOMapUi.BluetoothState & BT_CONNECT_REQUEST) && (!(IOMapUi.Flags & UI_BUSY))) - { - IOMapUi.Flags |= UI_BUSY; - IOMapUi.State = CONNECT_REQUEST; - } - - // Check for BT errors - if ((IOMapUi.BluetoothState & BT_ERROR_ATTENTION) && (!(IOMapUi.Flags & UI_BUSY))) - { - IOMapUi.Flags |= UI_BUSY; - IOMapUi.State = BT_ERROR; - } - - // Check for incomming execute program - if ((IOMapUi.Flags & UI_EXECUTE_LMS_FILE) && (!(IOMapUi.Flags & UI_BUSY))) - { - // Reset power down timer - IOMapUi.Flags |= UI_RESET_SLEEP_TIMER; - - // Set state and busy - IOMapUi.Flags |= UI_BUSY; - IOMapUi.State = EXECUTE_FILE; - } - - // Check for power timeout - if ((IOMapUi.Flags & UI_RESET_SLEEP_TIMER)) - { - IOMapUi.Flags &= ~UI_RESET_SLEEP_TIMER; - IOMapUi.SleepTimer = 0; - VarsUi.SleepTimer = 0; - } - if (IOMapUi.SleepTimeout) - { - if (++VarsUi.SleepTimer >= 60000) - { - VarsUi.SleepTimer = 0; - if (++IOMapUi.SleepTimer >= IOMapUi.SleepTimeout) - { - IOMapUi.ForceOff = TRUE; - } - } - } - else - { - IOMapUi.Flags |= UI_RESET_SLEEP_TIMER; - } - - // Check for "long prees on exit" power off - if ((pMapButton->State[BTN1] & LONG_PRESSED_EV) && (pMapCmd->ProgStatus != PROG_RUNNING) && (VarsUi.Initialized == TRUE) && (VarsUi.State == 0)) - { - IOMapUi.ForceOff = TRUE; - } - - // Check for "force" off - if (IOMapUi.ForceOff != FALSE) - { - IOMapUi.ForceOff = FALSE; - VarsUi.Function = FUNC_NO_OFF; - VarsUi.Parameter = MENU_INIT; - VarsUi.State = 0; - IOMapUi.State = DRAW_MENU; - } - - // Update status line - cUiUpdateStatus(); -} - - -void cUiExit(void) -{ - VarsUi.Initialized = FALSE; - IOMapUi.State = INIT_DISPLAY; -} diff --git a/AT91SAM7S256/Source/c_ui.h b/AT91SAM7S256/Source/c_ui.h deleted file mode 100644 index e0f8f4a..0000000 --- a/AT91SAM7S256/Source/c_ui.h +++ /dev/null @@ -1,387 +0,0 @@ -// -// Programmer -// -// Date init 14.12.2004 -// -// Reviser $Author:: Dktochpe $ -// -// Revision date $Date:: 10/21/08 12:08p $ -// -// Filename $Workfile:: c_ui.h $ -// -// Version $Revision:: 10 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_ui.h $ -// -// Platform C -// - -#ifndef C_UI -#define C_UI - -#define DATALOGENABLED 1 // 1 == Datalog enable - -#define NO_OF_FEEDBACK_CHARS 12 // Chars left when bitmap also showed -#define SIZE_OF_CURSOR 16 // Bitmap size of cursor (header + 8x8 pixels) -#define SIZE_OF_PORTBITMAP 11 // Bitmap size of port no (header + 3x8 pixels) -#define NO_OF_STATUSICONS 4 // Status icons - -#define NO_OF_INTROBITMAPS 16 // Intro bitmaps -#define INTRO_START_TIME 1000 // Intro startup time [mS] -#define INTRO_SHIFT_TIME 100 // Intro inter bitmap time [mS] -#define INTRO_STOP_TIME 1000 // Intro stop time [mS] -#define INTRO_LOWBATT_TIME 2000 // Low battery show time at power up [mS] - -#define MAX_VOLUME 4 // Max volume in UI [cnt] - -#define CHECKBYTE 0x78 // Used to validate NVData - -#define BATTERY_COUNT_TO_MV 13.848f // Battery count to mV factor [mV/cnt] -#define LOW_BATT_THRESHOLD 6 // Low batt conunts before warning - -#define BUTTON_DELAY_TIME 800 // Delay before first repeat [mS] -#define BUTTON_REPEAT_TIME 200 // Repeat time [mS] - -#define RUN_BITMAP_CHANGE_TIME 125 // Running bimap update time [mS] -#define RUN_STATUS_CHANGE_TIME 167 // Running status update time [mS] - -#define DISPLAY_SHOW_ERROR_TIME 2500 // Error string show time [mS] -#define DISPLAY_SHOW_TIME 1500 // Min. response display time [mS] -#define DISPLAY_VIEW_UPDATE 200 // Display update time [mS] -#define MIN_DISPLAY_UPDATE_TIME 50 // OBP min graphics update time [mS] -#define MIN_SENSOR_READ_TIME 100 // Time between sensor reads [mS] - -#define ARM_WAIT_FOR_POWER_OFF 250 // Time for off command to execute [mS] - -#define DISPLAY_SHOW_FILENAME_TIME 3000 // Datalog show saves as time [mS] -#define DATALOG_DEFAULT_SAMPLE_TIME 100L // Default time between samples [mS] - -// Menu special flags - -#define MENU_SKIP_THIS_MOTHER_ID 0x00000001L // Used to seek next common menu (i0000000) - // Free -#define MENU_ENTER_ACT_AS_EXIT 0x00000004L // Enter button acts as exit button -#define MENU_BACK_TWICE 0x00000008L // Exit twice on exit button -#define MENU_EXIT_ACT_AS_ENTER 0x00000010L // Exit button acts as enter button -#define MENU_LEAVE_BACKGROUND 0x00000020L // Don't erase background at next menu -#define MENU_EXIT_CALLS_WITH_FF 0x00000040L // Exit button calls function with MENU_EXIT -#define MENU_EXIT_LEAVES_MENUFILE 0x00000080L // Exit leaves menu file -#define MENU_INIT_CALLS_WITH_0 0x00000100L // Menu init calls with MENU_INIT -#define MENU_LEFT_RIGHT_AS_CALL 0x00000200L // Left calls with MENU_LEFT and right with MENU_RIGHT -#define MENU_ENTER_ONLY_CALLS 0x00000400L // Enter calls only it does not change menues -#define MENU_EXIT_ONLY_CALLS 0x00000800L // Exit calls only it does not change menues -#define MENU_AUTO_PRESS_ENTER 0x00001000L // Enter button is pressed automaticly -#define MENU_ENTER_LEAVES_MENUFILE 0x00002000L // Enter leaves menufile -#define MENU_INIT_CALLS 0x00004000L // Init calls instead of enter -#define MENU_ACCEPT_INCOMMING_REQUEST 0x00008000L // Accept incomming BT connection request -#define MENU_BACK_THREE_TIMES 0x00010000L // Exit three times on exit button -#define MENU_EXIT_DISABLE 0x00020000L // Disable exit button -#define MENU_EXIT_LOAD_POINTER 0x00040000L // Load item index on exit (0i000000) -#define MENU_EXIT_CALLS 0x00080000L // Exit calls as enter -#define MENU_INIT_CALLS_WITH_1 0x00100000L // Menu init calls with MENU_INIT -#define MENU_EXIT_LOAD_MENU 0x00200000L // Exit loads next menu -#define MENU_ONLY_BT_ON 0x00400000L // Only valid when bluecore is on -#define MENU_ONLY_DATALOG_ENABLED 0x00800000L // Only valid when datalog is enabled - -// Menu function call parameter - -#define MENU_SENSOR_EMPTY 0x01 // Empty -#define MENU_SENSOR_SOUND_DB 0x02 // Sound sensor dB -#define MENU_SENSOR_SOUND_DBA 0x03 // Sound sensor dBA -#define MENU_SENSOR_LIGHT 0x04 // Light sensor with flood light -#define MENU_SENSOR_LIGHT_AMB 0x05 // Light sensor without flood light -#define MENU_SENSOR_TOUCH 0x06 // Touch sensor -#define MENU_SENSOR_MOTOR_DEG 0x07 // Motor sensor degrees -#define MENU_SENSOR_MOTOR_ROT 0x08 // Motor sensor rotations -#define MENU_SENSOR_ULTRASONIC_IN 0x09 // Ultrasonic sensor inch -#define MENU_SENSOR_ULTRASONIC_CM 0x0A // Ultrasonic sensor cm -#define MENU_SENSOR_IIC_TEMP_C 0x0B // IIC temp sensor celcius -#define MENU_SENSOR_IIC_TEMP_F 0x0C // IIC temp sensor fahrenheit -#define MENU_SENSOR_COLOR 0x0D // Color sensor -#define MENU_SENSOR_INVALID 0x0E // Invalid - -#define MENU_PORT_EMPTY 0x11 // Port empty -#define MENU_PORT_1 0x12 // Port 1 -#define MENU_PORT_2 0x13 // Port 2 -#define MENU_PORT_3 0x14 // Port 3 -#define MENU_PORT_4 0x15 // Port 4 -#define MENU_PORT_A 0x16 // Port A -#define MENU_PORT_B 0x17 // Port B -#define MENU_PORT_C 0x18 // Port C -#define MENU_PORT_INVALID 0x19 // Invalid - -#define MENU_ACTION_EMPTY 0x21 // Empty -#define MENU_ACTION_FORWARD_1 0x22 // Forward until -#define MENU_ACTION_FORWARD_2 0x23 // Forward 5 -#define MENU_ACTION_BACK_LEFT_2 0x24 // Back left 2 -#define MENU_ACTION_TURN_LEFT_1 0x25 // Turn left until -#define MENU_ACTION_TURN_LEFT_2 0x26 // Turn left 2 -#define MENU_ACTION_BACK_RIGHT_1 0x27 // Back right until -#define MENU_ACTION_TURN_RIGHT_1 0x28 // Turn right until -#define MENU_ACTION_TURN_RIGHT_2 0x29 // Turn right 2 -#define MENU_ACTION_BACK_LEFT_1 0x2A // Back left until -#define MENU_ACTION_TONE_1 0x2B // Tone 1 -#define MENU_ACTION_TONE_2 0x2C // Tone 2 -#define MENU_ACTION_BACKWARD_1 0x2D // Backward until -#define MENU_ACTION_BACKWARD_2 0x2E // Backward 5 -#define MENU_ACTION_BACK_RIGHT_2 0x2F // Back right 2 -#define MENU_ACTION_INVALID 0x30 // Invalid - -#define MENU_WAIT_EMPTY 0x41 // Empty -#define MENU_WAIT_LIGHT 0x42 // Light -#define MENU_WAIT_SEEK_OBJ 0x43 // Seek obj. -#define MENU_WAIT_SOUND 0x44 // Sound -#define MENU_WAIT_TOUCH 0x45 // Touch -#define MENU_WAIT_1 0x46 // Wait 2 -#define MENU_WAIT_2 0x47 // Wait 5 -#define MENU_WAIT_3 0x48 // Wait 10 -#define MENU_WAIT_DARK 0x49 // Dark -#define MENU_WAIT_INVALID 0x4A // Invalid - -#define MENU_INIT 0x00 // Init -#define MENU_INIT_ALTERNATIVE 0x01 // Init alternative -#define MENU_DRAW 0xE9 // Draw -#define MENU_OFF 0xEA // Off -#define MENU_ON 0xEB // On -#define MENU_OPEN_STREAM 0xEC // Open stream -#define MENU_OVERWRITE 0xED // Overwrite file -#define MENU_CALCULATE 0xEE // Calculate -#define MENU_ENTER 0xEF // Enter -#define MENU_DISCONNECT 0xF0 // Disconnect BT -#define MENU_DELETE 0xF1 // Delete -#define MENU_SELECT 0xF2 // Select -#define MENU_RUN_SILENT 0xF3 // Run without graphics -#define MENU_TOGGLE 0xF4 // Toggle -#define MENU_CONNECT 0xF5 // Connect BT -#define MENU_UPDATE 0xF6 // Update -#define MENU_TEXT 0xF7 // Text -#define MENU_RUN 0xF8 // Run -#define MENU_SEND 0xF9 // Send -#define MENU_SAVE 0xFA // Save -#define MENU_STOP 0xFB // Stop -#define MENU_LOOP 0xFC // Loop -#define MENU_LEFT 0xFD // Left -#define MENU_RIGHT 0xFE // Right -#define MENU_EXIT 0xFF // Exit - -#define DATALOGPORTS (MENU_PORT_INVALID - MENU_PORT_EMPTY - 1) -#define MAX_DATALOGS 9999 // Highest datalog file number -#define DATALOGBUFFERSIZE 25 // Largest number of characters buffered before flash write - -#define MENULEVELS 10 // Max no of levels in one file (8 + 2 virtual) -#define MENUFILELEVELS 3 // Max deept in menu file pool - -typedef struct // VarsUi.MenuFiles[VarsUi.MenuFileLevel].MenuLevels[VarsUi.MenuLevel]. -{ - ULONG Id; // Menu item id - UBYTE *IconText; // Menu item icon text pointer - ULONG SpecialFlags; // Menu item special behaivor - UBYTE IconImageNo; // Menu item icon image no - UBYTE FunctionNo; // Menu item function call no (0 = none) - UBYTE Parameter; // Menu item function call parameter - UBYTE NextFileNo; // Menu item next menu file no (0 = none) - UBYTE NextMenuNo; // Menu item next menu no (0 = none) - - UBYTE ItemIndex; // Menu item index on level - UBYTE Items; // Menu items on level -} -MENULEVEL; - -typedef struct -{ - MENULEVEL MenuLevels[MENULEVELS]; // See above - UBYTE FileId; // VarsUi.MenuFiles[VarsUi.MenuFileLevel].FileId - UBYTE MenuLevel; // VarsUi.MenuFiles[VarsUi.MenuFileLevel].MenuLevel -} -MENUFILE; - -typedef struct -{ - UBYTE CheckByte; // Check byte (CHECKBYTE) - UBYTE DatalogEnabled; // Datalog enabled flag (0 = no) - UBYTE VolumeStep; // Volume step (0 - MAX_VOLUME) - UBYTE PowerdownCode; // Power down code - UWORD DatalogNumber; // Datalog file number (0 - MAX_DATALOGS) -} -NVDATA; - -typedef struct -{ - UBYTE StatusText[STATUSTEXT_SIZE + 1]; // RCX name - UBYTE Initialized; // Ui init done - UWORD SleepTimer; // Sleep timer - - // Menu system - MENUFILE MenuFiles[MENUFILELEVELS]; // Menu file array - MENUFILE *pMenuFile; // Actual menu file pointer - MENULEVEL *pMenuLevel; // Actual menu item on level, pointer - MENUITEM *pMenuItem; // Actual menu item in menu flash file - UBYTE MenuFileLevel; // Actual menu file level - UBYTE Function; // Running function (0 = none) - UBYTE Parameter; // Parameter for running function - UBYTE SecondTime; // Second time flag - UBYTE EnterOnlyCalls; // Enter button only calls - UBYTE ExitOnlyCalls; // Exit button only calls - UWORD ButtonTimer; // Button repeat timer - UWORD ButtonTime; // Button repeat time - UBYTE ButtonOld; // Button old state - - // Update status - UWORD UpdateCounter; // Update counter - UBYTE Running; // Running pointer - UBYTE BatteryToggle; // Battery flash toggle flag - UBYTE NewStatusIcons[NO_OF_STATUSICONS]; // New status icons (used to detect changes) - - // Low battery voltage - UBYTE *LowBattSavedBitmap; // Low battery overwritten bitmap placeholder - UBYTE LowBatt; // Low battery volatge flag - UBYTE LowBattHasOccured; // Low battery voltage has occured - UBYTE LowBattSavedState; // Low battery current state placeholder - - // General used variables - UBYTE *MenuIconTextSave; // Menu icon text save - - UBYTE *pTmp; // General UBYTE pointer - ULONG TmpLength; // General filelength (used in filelist) - SWORD TmpHandle; // General filehandle (used in filelist) - - SWORD Timer; // General tmp purpose timer - SWORD ReadoutTimer; // General read out timer - UBYTE Tmp; // General UBYTE - UBYTE FileType; // General file type - UBYTE State; // General tmp purpose state - UBYTE Pointer; // General tmp purpose pointer - UBYTE Counter; // General tmp purpose counter - UBYTE Cursor; // General cursor - UBYTE SelectedSensor; // General used for selected sensor - UBYTE SelectedPort; // General used for selected port - UBYTE SensorReset; - UBYTE SensorState; // Sensor state (reset, ask, read) - SWORD SensorTimer; // Timer used to time sensor states - UBYTE NextState; - - UBYTE SelectedFilename[FILENAME_LENGTH + 1]; // Selected file name - UBYTE FilenameBuffer[FILENAME_LENGTH + 1]; // General filename buffer - UBYTE SearchFilenameBuffer[FILENAME_LENGTH + 1];// General filename buffer - UBYTE DisplayBuffer[DISPLAYLINE_LENGTH + 1]; // General purpose display buffer - - UBYTE PortBitmapLeft[SIZE_OF_PORTBITMAP]; // Port no bitmap for left icon - UBYTE PortBitmapCenter[SIZE_OF_PORTBITMAP]; // Port no bitmap for center icon - UBYTE PortBitmapRight[SIZE_OF_PORTBITMAP]; // Port no bitmap for right icon - - // Find no of files and find name for file no - ULONG FNOFLength; // Length - SWORD FNOFHandle; // Handle - UBYTE FNOFState; // State - UBYTE FNOFSearchBuffer[FILENAME_LENGTH + 1]; // Search buffer - UBYTE FNOFNameBuffer[FILENAME_LENGTH + 1]; // File name buffer - UBYTE FNOFFileNo; // File no - - // File list - UBYTE FileCenter; // File center - UBYTE FileLeft; // File left - UBYTE FileRight; // File right - UBYTE NoOfFiles; // No of files - - // On brick programming menu - UBYTE ProgramSteps[ON_BRICK_PROGRAMSTEPS]; // On brick programming steps - UBYTE ProgramStepPointer; // On brick programming step pointer - UBYTE CursorTmp[SIZE_OF_CURSOR]; // On brick programming cursor - UBYTE FileHeader[FILEHEADER_LENGTH]; // File header for programs - UBYTE *FeedBackText; // Program end text - UWORD OBPTimer; // Graphic update timer - - // BT search menu - UBYTE NoOfDevices; // BT search no of devices found - UBYTE NoOfNames; // BT search no of names found - UBYTE SelectedDevice; // BT selected device - UBYTE SelectedSlot; // BT selected slot - - // BT device list menu - UBYTE DevicesKnown; // BT device known flag - UBYTE Devices; // BT devices - UBYTE DeviceLeft; // BT device left - UBYTE DeviceCenter; // BT device center - UBYTE DeviceRight; // BT device right - UBYTE DeviceType; // BT device type - - // BT connect Menu - UBYTE Slots; // BT connect no of slots - UBYTE SlotLeft; // BT connect - UBYTE SlotCenter; // BT connect - UBYTE SlotRight; // BT connect - - // Get user string - UBYTE GUSTmp; // Seperat tmp for "Get user string" - UBYTE GUSState; // Seperat state for "Get user string" - UBYTE GUSNoname; // No user entry - UBYTE UserString[DISPLAYLINE_LENGTH + 1]; // User string - UBYTE DisplayText[DISPLAYLINE_LENGTH + 1]; // Display buffer - SBYTE FigurePointer; // Figure cursor - UBYTE GUSCursor; // User string cursor - - // Connect request - ULONG CRPasskey; // Passkey to fake wrong pin code - UBYTE CRState; // Seperate state for "Connect request" - UBYTE CRTmp; // Seperate tmp for "Connect request" - - // Run files - UBYTE *RunIconSave; // Menu center icon save - UWORD RunTimer; // Bitmap change timer - UBYTE RunBitmapPointer; // Bitmap pointer - - // Delete files - UBYTE SelectedType; // Type of selected files for delete - - // View - SLONG ViewSampleValue; // Latch for sensor values - UBYTE ViewSampleValid; // Latch for sensor valid - - // Datalog - ULONG DatalogOldTick; - ULONG DatalogRTC; // Real time in mS - ULONG DatalogTimer; // Logging main timer - ULONG DatalogSampleTime; // Logging sample time - ULONG DatalogSampleTimer; // Logging sample timer - SLONG DatalogSampleValue[DATALOGPORTS]; // Latch for sensor values - UBYTE DatalogSampleValid[DATALOGPORTS]; // Latch for sensor valid - UWORD DatalogError; // Error code - UBYTE DatalogPort[DATALOGPORTS]; // Logging sensor - UBYTE Update; // Update icons flag - - // NV storage - ULONG NVTmpLength; // Non volatile filelength - SWORD NVTmpHandle; // Non volatile filehandle - UBYTE NVFilename[FILENAME_LENGTH + 1]; // Non volatile file name - NVDATA NVData; // Non volatile data - - // Feedback - UBYTE *FBText; // Seperate text pointer for feedback - UWORD FBTimer; // Seperate timer for feedback - UBYTE FBState; // Seperate state for feedback - UBYTE FBPointer; // Seperate pointer for feedback - - // BT command - UBYTE BTIndex; // List index - UBYTE BTTmpIndex; // Tmp list index - UBYTE BTCommand; // Last lached BT command - UBYTE BTPar1; // Last lached BT command parameter 1 - UBYTE BTPar2; // Last lached BT command parameter 2 - UWORD BTResult; // Last lached BT command result - - // Error display - UBYTE ErrorTimer; // Error show timer - UBYTE ErrorFunction; // Error latched function - UBYTE ErrorParameter; // Error latched parameter - UBYTE ErrorState; // Error latched state - UBYTE ErrorString[DISPLAYLINE_LENGTH + 1]; // Error string -}VARSUI; - - -void cUiInit(void* pHeader); // Init controller -void cUiCtrl(void); // Run controller -void cUiExit(void); // Exit controller - -extern const HEADER cUi; - -#endif diff --git a/AT91SAM7S256/Source/c_ui.iom b/AT91SAM7S256/Source/c_ui.iom deleted file mode 100644 index 770b682..0000000 --- a/AT91SAM7S256/Source/c_ui.iom +++ /dev/null @@ -1,127 +0,0 @@ -// -// Programmer -// -// Date init 14.12.2004 -// -// Reviser $Author:: Dkandlun $ -// -// Revision date $Date:: 10-06-08 9:26 $ -// -// Filename $Workfile:: c_ui.iom $ -// -// Version $Revision:: 4 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_ui.i $ -// -// Platform C -// - -#ifndef CUI_IOM -#define CUI_IOM - -#define pMapUi ((IOMAPUI*)(pHeaders[ENTRY_UI]->pIOMap)) - -enum -{ - DEVICETYPE_UNKNOWN, - DEVICETYPE_NXT, - DEVICETYPE_PHONE, - DEVICETYPE_PC -}; - -// Various filenames without extension -#define UI_NONVOLATILE "NVConfig" // Ui non volatile config filename -#define UI_PROGRAM_DEFAULT "Untitled" // On brick programming default filename -#define UI_PROGRAM_TEMP "Program" // On brick programming tmp filename -#define UI_PROGRAM_READER "RPGReader" // On brick programming script reader filename -#define UI_DATALOG_FILENAME "OBD_" // On brick datalog filename -#define UI_DATALOG_DEFAULT "Untitled" // On brick datalog default name -#define UI_DATALOG_TEMP "Tmp" // On brick datalog tmp filename -#define UI_STARTUP_SOUND "! Startup" // Sound file activated when the menu system starts up -#define UI_KEYCLICK_SOUND "! Click" // Sound file activated when key pressed in the menu system -#define UI_ATTENTION_SOUND "! Attention" // Sound file activated when incomming BT requests attention - -// Various text strings -#define UI_NAME_DEFAULT "NXT" // Default blue tooth name -#define UI_PINCODE_DEFAULT "1234" // Default blue tooth pin code -#define UI_PINCODE_NONE_OUT "????" // Fake pin code to deney outgoing request -#define UI_PINCODE_NONE_IN "????" // Fake pin code to deney incomming request - -// Constants related to Flags -enum -{ - UI_UPDATE = 0x01, // W - Make changes take effect - UI_DISABLE_LEFT_RIGHT_ENTER = 0x02, // RW - Disable left, right and enter button - UI_DISABLE_EXIT = 0x04, // RW - Disable exit button - UI_REDRAW_STATUS = 0x08, // W - Redraw entire status line - UI_RESET_SLEEP_TIMER = 0x10, // W - Reset sleep timeout timer - UI_EXECUTE_LMS_FILE = 0x20, // W - Execute LMS file in "LMSfilename" (Try It) - UI_BUSY = 0x40, // R - UI busy running or datalogging (popup disabled) - UI_ENABLE_STATUS_UPDATE = 0x80 // W - Enable status line to be updated -}; - -// Constants related to State -enum -{ - INIT_DISPLAY, // RW - Init display and load font, menu etc. - INIT_LOW_BATTERY, // R - Low battery voltage at power on - INIT_INTRO, // R - Display intro - INIT_WAIT, // RW - Wait for initialization end - INIT_MENU, // RW - Init menu system - NEXT_MENU, // RW - Next menu icons ready for drawing - DRAW_MENU, // RW - Execute function and draw menu icons - TEST_BUTTONS, // RW - Wait for buttons to be pressed - LEFT_PRESSED, // RW - Load selected function and next menu id - RIGHT_PRESSED, // RW - Load selected function and next menu id - ENTER_PRESSED, // RW - Load selected function and next menu id - EXIT_PRESSED, // RW - Load selected function and next menu id - CONNECT_REQUEST, // RW - Request for connection accept - EXECUTE_FILE, // RW - Execute file in "LMSfilename" - EXECUTING_FILE, // R - Executing file in "LMSfilename" - LOW_BATTERY, // R - Low battery at runtime - BT_ERROR // R - BT error -}; - -// Constants related to Button -enum -{ - BUTTON_NONE, // R - Button inserted are executed - BUTTON_LEFT, // W - Insert left arrow button - BUTTON_ENTER, // W - Insert enter button - BUTTON_RIGHT, // W - Insert right arrow button - BUTTON_EXIT // W - Insert exit button -}; - -// Constants related to BlueToothState -enum -{ - BT_STATE_VISIBLE = 0x01, // RW - BT visible - BT_STATE_CONNECTED = 0x02, // RW - BT connected to something - BT_STATE_OFF = 0x04, // RW - BT power off - BT_ERROR_ATTENTION = 0x08, // W - BT error attention - BT_CONNECT_REQUEST = 0x40, // RW - BT get connect accept in progress - BT_PIN_REQUEST = 0x80 // RW - BT get pin code -}; - -typedef struct -{ - MENU *pMenu; // W - Pointer to menu file - UWORD BatteryVoltage; // R - Battery voltage in millivolts - UBYTE LMSfilename[FILENAME_LENGTH + 1]; // W - LMS filename to execute (Try It) - UBYTE Flags; // RW - Update command flags (flags enumerated above) - UBYTE State; // RW - UI state (states enumerated above) - UBYTE Button; // RW - Insert button (buttons enumerated above) - UBYTE RunState; // W - VM Run state (0 = stopped, 1 = running) - UBYTE BatteryState; // W - Battery state (0..4 capacity) - UBYTE BluetoothState; // W - Bluetooth state (0=on, 1=visible, 2=conn, 3=conn.visible, 4=off, 5=dfu) - UBYTE UsbState; // W - Usb state (0=disconnected, 1=connected, 2=working) - UBYTE SleepTimeout; // RW - Sleep timeout time (min) - UBYTE SleepTimer; // RW - Sleep timer (min) - UBYTE Rechargeable; // R - Rechargeable battery (0 = no, 1 = yes) - UBYTE Volume; // RW - Volume used in UI (0 - 4) - UBYTE Error; // W - Error code - UBYTE OBPPointer; // W - Actual OBP step (0 - 4) - UBYTE ForceOff; // W - Force off (> 0 = off) -}IOMAPUI; - -#endif diff --git a/AT91SAM7S256/Source/config.h b/AT91SAM7S256/Source/config.h deleted file mode 100644 index d396771..0000000 --- a/AT91SAM7S256/Source/config.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef CONFIG_H -#define CONFIG_H -/* - * This file defines compilation options. - */ - -/* Include intro code and images. */ -#define CONFIG_INTRO 1 - -#endif /* CONFIG_H */ diff --git a/AT91SAM7S256/Source/d_bt.c b/AT91SAM7S256/Source/d_bt.c deleted file mode 100644 index 6e3e47d..0000000 --- a/AT91SAM7S256/Source/d_bt.c +++ /dev/null @@ -1,452 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 24-04-08 14:33 $ -// -// Filename $Workfile:: d_bt.c $ -// -// Version $Revision:: 3 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_bt.c $ -// -// Platform C -// - - -#include "stdconst.h" -#include "modules.h" -#include "m_sched.h" -#include "d_bt.h" -#include "d_bt.r" -#include - -enum -{ - BT_FAST_TIMEOUT = 500, - BT_CMD_TIMEOUT_2S = 2000, - BT_TIMEOUT_30S = 30000 -}; - -#define SETTimeout(TOut) CmdTOut = 0;\ - CmdTOutLimit = TOut -#define RESETTimeout CmdTOut = 0 - -static UWORD CmdTOut; -static UWORD CmdTOutLimit; - -void dBtInit(void) -{ - SETTimeout(0); - BTInit; - BTInitPIOPins; -} - -void dBtSetBcResetPinLow(void) -{ - BTSetResetLow; /* Set Reset pin to Bluecore chip low */ -} - -void dBtSetBcResetPinHigh(void) -{ - BTSetResetHigh; /* Set Reset pin to Bluecore chip high */ -} - -void dBtStartADConverter(void) -{ - BTStartADConverter; -} - -void dBtInitReceive(UBYTE *InputBuffer, UBYTE Mode) -{ - BTInitReceiver(InputBuffer, Mode); -} - -void dBtSetArm7CmdSignal(void) -{ - BT_SetArm7CmdPin; -} - -void dBtClearArm7CmdSignal(void) -{ - BT_ClearArm7CmdPin; -} - -UBYTE dBtGetBc4CmdSignal(void) -{ - UWORD ADValue; - - BTReadADCValue(ADValue); - - if (ADValue > 0x200) - { - ADValue = 1; - } - else - { - ADValue = 0; - } - return(ADValue); -} - - -UWORD dBtTxEnd(void) -{ - UWORD TxEnd; - - REQTxEnd(TxEnd); - - return(TxEnd); - -} - -UWORD dBtCheckForTxBuf(void) -{ - UWORD AvailBytes; - - AVAILOutBuf(AvailBytes); - - return(AvailBytes); -} - -void dBtSendMsg(UBYTE *OutputBuffer, UBYTE BytesToSend, UWORD MsgSize) -{ - - /* Used for sending a complete message that can be placed in the buffer - */ - /* or to send the first part of a message that cannot be placed in the buffer */ - /* once (bigger than the buffer) */ - BTSendMsg(OutputBuffer,BytesToSend, MsgSize); -} - -void dBtSend(UBYTE *OutputBuffer, UBYTE BytesToSend) -{ - - /* Used for continous stream of data to be send */ - BTSend(OutputBuffer, BytesToSend); -} - -UWORD dBtReceivedData(UWORD *pLength, UWORD *pBytesToGo) -{ - UWORD RtnVal; - - RtnVal = TRUE; - BTReceivedData(pLength, pBytesToGo); - if (*pLength) - { - SETTimeout(0); - } - else - { - if (CmdTOut < CmdTOutLimit) - { - CmdTOut++; - if (CmdTOut >= CmdTOutLimit) - { - SETTimeout(0); - RtnVal = FALSE; - } - } - } - return(RtnVal); -} - -void dBtResetTimeOut(void) -{ - RESETTimeout; -} - -void dBtClearTimeOut(void) -{ - SETTimeout(0); -} - -void dBtSendBtCmd(UBYTE Cmd, UBYTE Param1, UBYTE Param2, UBYTE *pBdAddr, UBYTE *pName, UBYTE *pCod, UBYTE *pPin) -{ - UBYTE Tmp; - UBYTE SendData; - UWORD CheckSumTmp; - UBYTE BtOutBuf[128]; - UBYTE BtOutCnt; - - SendData = 0; - BtOutCnt = 0; - switch (Cmd) - { - case MSG_BEGIN_INQUIRY: - { - BtOutBuf[BtOutCnt++] = MSG_BEGIN_INQUIRY; - BtOutBuf[BtOutCnt++] = Param1; - BtOutBuf[BtOutCnt++] = 0x00; - BtOutBuf[BtOutCnt++] = Param2; - BtOutBuf[BtOutCnt++] = 0x00; - BtOutBuf[BtOutCnt++] = 0x00; - BtOutBuf[BtOutCnt++] = 0x00; - BtOutBuf[BtOutCnt++] = 0x00; - - SendData = 1; - SETTimeout(BT_TIMEOUT_30S); - } - break; - - case MSG_CANCEL_INQUIRY: - { - BtOutBuf[BtOutCnt++] = MSG_CANCEL_INQUIRY; - - SendData = 1; - SETTimeout(BT_FAST_TIMEOUT); - } - break; - - case MSG_CONNECT: - { - BtOutBuf[BtOutCnt++] = MSG_CONNECT; - memcpy(&(BtOutBuf[BtOutCnt]), pBdAddr, SIZE_OF_BDADDR); - BtOutCnt += SIZE_OF_BDADDR; - - SendData = 1; - SETTimeout(BT_TIMEOUT_30S); - } - break; - - case MSG_OPEN_PORT: - { - BtOutBuf[BtOutCnt++] = MSG_OPEN_PORT; - - SendData = 1; - SETTimeout(BT_FAST_TIMEOUT); - } - break; - - case MSG_LOOKUP_NAME: - { - BtOutBuf[BtOutCnt++] = MSG_LOOKUP_NAME; - memcpy(&(BtOutBuf[BtOutCnt]), pBdAddr, SIZE_OF_BDADDR); - BtOutCnt += SIZE_OF_BDADDR; - - SendData = 1; - SETTimeout(BT_TIMEOUT_30S); - } - break; - - case MSG_ADD_DEVICE: - { - BtOutBuf[BtOutCnt++] = MSG_ADD_DEVICE; - memcpy(&(BtOutBuf[BtOutCnt]), pBdAddr, SIZE_OF_BDADDR); - BtOutCnt += SIZE_OF_BDADDR; - memcpy(&(BtOutBuf[BtOutCnt]), pName, SIZE_OF_BT_NAME); - BtOutCnt += SIZE_OF_BT_NAME; - memcpy(&(BtOutBuf[BtOutCnt]), pCod, SIZE_OF_CLASS_OF_DEVICE); - BtOutCnt += SIZE_OF_CLASS_OF_DEVICE; - - SendData = 1; - SETTimeout(BT_TIMEOUT_30S); - } - break; - - case MSG_REMOVE_DEVICE: - { - BtOutBuf[BtOutCnt++] = MSG_REMOVE_DEVICE; - memcpy(&(BtOutBuf[BtOutCnt]), pBdAddr, SIZE_OF_BDADDR); - BtOutCnt += SIZE_OF_BDADDR; - - SendData = 1; - SETTimeout(BT_FAST_TIMEOUT); - } - break; - - case MSG_DUMP_LIST: - { - BtOutBuf[BtOutCnt++] = MSG_DUMP_LIST; - - SendData = 1; - SETTimeout(BT_TIMEOUT_30S); - } - break; - - case MSG_CLOSE_CONNECTION: - { - BtOutBuf[BtOutCnt++] = MSG_CLOSE_CONNECTION; - BtOutBuf[BtOutCnt++] = Param1; - - SendData = 1; - SETTimeout(BT_TIMEOUT_30S); - } - break; - - case MSG_ACCEPT_CONNECTION: - { - BtOutBuf[BtOutCnt++] = MSG_ACCEPT_CONNECTION; - BtOutBuf[BtOutCnt++] = Param1; - - SendData = 1; - SETTimeout(BT_TIMEOUT_30S); - } - break; - - case MSG_PIN_CODE: - { - BtOutBuf[BtOutCnt++] = MSG_PIN_CODE; - memcpy(&(BtOutBuf[BtOutCnt]), pBdAddr, SIZE_OF_BDADDR); - BtOutCnt += SIZE_OF_BDADDR; - memcpy(&(BtOutBuf[BtOutCnt]), pPin, SIZE_OF_BT_PINCODE); - BtOutCnt += SIZE_OF_BT_PINCODE; - - SendData = 1; - SETTimeout(BT_TIMEOUT_30S); - } - break; - - case MSG_OPEN_STREAM: - { - BtOutBuf[BtOutCnt++] = MSG_OPEN_STREAM; - BtOutBuf[BtOutCnt++] = Param1; - - SendData = 1; - SETTimeout(BT_TIMEOUT_30S); - } - break; - - case MSG_START_HEART: - { - BtOutBuf[BtOutCnt++] = MSG_START_HEART; - - SendData = 1; - SETTimeout(BT_FAST_TIMEOUT); - } - break; - - case MSG_SET_DISCOVERABLE: - { - BtOutBuf[BtOutCnt++] = MSG_SET_DISCOVERABLE; - BtOutBuf[BtOutCnt++] = Param1; - - SendData = 1; - SETTimeout(BT_FAST_TIMEOUT); - } - break; - - case MSG_CLOSE_PORT: - { - BtOutBuf[BtOutCnt++] = MSG_CLOSE_PORT; - BtOutBuf[BtOutCnt++] = 0x03; - - SendData = 1; - SETTimeout(BT_FAST_TIMEOUT); - } - break; - - case MSG_SET_FRIENDLY_NAME: - { - BtOutBuf[BtOutCnt++] = MSG_SET_FRIENDLY_NAME; - memcpy(&(BtOutBuf[BtOutCnt]), pName, SIZE_OF_BT_NAME); - BtOutCnt += SIZE_OF_BT_NAME; - - SendData = 1; - SETTimeout(BT_FAST_TIMEOUT); - } - break; - - case MSG_GET_LINK_QUALITY: - { - BtOutBuf[BtOutCnt++] = MSG_GET_LINK_QUALITY; - BtOutBuf[BtOutCnt++] = Param1; - - SendData = 1; - SETTimeout(BT_FAST_TIMEOUT); - } - break; - - case MSG_SET_FACTORY_SETTINGS: - { - BtOutBuf[BtOutCnt++] = MSG_SET_FACTORY_SETTINGS; - - SendData = 1; - SETTimeout(BT_FAST_TIMEOUT); - } - break; - - case MSG_GET_LOCAL_ADDR: - { - BtOutBuf[BtOutCnt++] = MSG_GET_LOCAL_ADDR; - - SendData = 1; - SETTimeout(BT_FAST_TIMEOUT); - } - break; - - case MSG_GET_FRIENDLY_NAME: - { - BtOutBuf[BtOutCnt++] = MSG_GET_FRIENDLY_NAME; - - SendData = 1; - SETTimeout(BT_FAST_TIMEOUT); - } - break; - - case MSG_GET_DISCOVERABLE: - { - BtOutBuf[BtOutCnt++] = MSG_GET_DISCOVERABLE; - - SendData = 1; - SETTimeout(BT_FAST_TIMEOUT); - } - break; - - case MSG_GET_PORT_OPEN: - { - BtOutBuf[BtOutCnt++] = MSG_GET_PORT_OPEN; - - SendData = 1; - SETTimeout(BT_FAST_TIMEOUT); - } - break; - - case MSG_GET_VERSION: - { - BtOutBuf[BtOutCnt++] = MSG_GET_VERSION; - - SendData = 1; - SETTimeout(BT_FAST_TIMEOUT); - } - break; - - case MSG_GET_BRICK_STATUSBYTE: - { - BtOutBuf[BtOutCnt++] = MSG_GET_BRICK_STATUSBYTE; - - SendData = 1; - SETTimeout(BT_FAST_TIMEOUT); - } - break; - - case MSG_SET_BRICK_STATUSBYTE: - { - BtOutBuf[BtOutCnt++] = MSG_SET_BRICK_STATUSBYTE; - BtOutBuf[BtOutCnt++] = Param1; - BtOutBuf[BtOutCnt++] = Param2; - - SendData = 1; - SETTimeout(BT_FAST_TIMEOUT); - } - break; - } - - if (SendData == 1) - { - CheckSumTmp = 0; - for(Tmp = 0; Tmp < BtOutCnt; Tmp++) - { - CheckSumTmp += BtOutBuf[Tmp]; - } - CheckSumTmp = (UWORD) (1 + (0xFFFF - CheckSumTmp)); - BtOutBuf[BtOutCnt++] = (UBYTE)((CheckSumTmp & 0xFF00)>>8); - BtOutBuf[BtOutCnt++] = (UBYTE)(CheckSumTmp & 0x00FF); - BTSendMsg(BtOutBuf, BtOutCnt, (UWORD)BtOutCnt); - } -} - - - -void dBtExit(void) -{ - BTExit; -} diff --git a/AT91SAM7S256/Source/d_bt.h b/AT91SAM7S256/Source/d_bt.h deleted file mode 100644 index baf3ab6..0000000 --- a/AT91SAM7S256/Source/d_bt.h +++ /dev/null @@ -1,39 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: d_bt.h $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_bt.h $ -// -// Platform C -// - -#ifndef D_BT -#define D_BT - -#define STREAM_MODE 1 -#define CMD_MODE 2 - -void dBtInit(void); -void dBtExit(void); -void dBtStartADConverter(void); -void dBtSetArm7CmdSignal(void); -void dBtClearArm7CmdSignal(void); -void dBtInitReceive(UBYTE *InputBuffer, UBYTE Mode); -void dBtSetBcResetPinLow(void); -void dBtSetBcResetPinHigh(void); -void dBtSendBtCmd(UBYTE Cmd, UBYTE Param1, UBYTE Param2, UBYTE *pBdAddr, UBYTE *pName, UBYTE *pCod, UBYTE *pPin); -void dBtSendMsg(UBYTE *pData, UBYTE Length, UWORD MsgSize); -void dBtSend(UBYTE *pData, UBYTE Length); -void dBtResetTimeOut(void); -void dBtClearTimeOut(void); -UBYTE dBtGetBc4CmdSignal(void); -UWORD dBtTxEnd(void); -UWORD dBtReceivedData(UWORD *pLength, UWORD *pBytesToGo); -UWORD dBtCheckForTxBuf(void); - -#endif diff --git a/AT91SAM7S256/Source/d_bt.r b/AT91SAM7S256/Source/d_bt.r deleted file mode 100644 index 8c9558f..0000000 --- a/AT91SAM7S256/Source/d_bt.r +++ /dev/null @@ -1,347 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 24-04-08 14:33 $ -// -// Filename $Workfile:: d_bt.r $ -// -// Version $Revision:: 3 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_bt.r $ -// -// Platform C -// - -#ifdef SAM7S256 - -#if defined (PROTOTYPE_PCB_3) || (PROTOTYPE_PCB_4) - -#define BT_RX_PIN AT91C_PIO_PA21 -#define BT_TX_PIN AT91C_PIO_PA22 -#define BT_SCK_PIN AT91C_PIO_PA23 -#define BT_RTS_PIN AT91C_PIO_PA24 -#define BT_CTS_PIN AT91C_PIO_PA25 - -#define BT_CS_PIN AT91C_PIO_PA31 -#define BT_RST_PIN AT91C_PIO_PA11 - -#define BT_ARM7_CMD_PIN AT91C_PIO_PA27 - -#else - -#endif - -#define BAUD_RATE 460800L - -#define SIZE_OF_INBUF 128 -#define NO_OF_INBUFFERS 2 -#define NO_OF_DMA_OUTBUFFERS 2 -#define SIZE_OF_OUTBUF 256 - -#define PER_ID7_UART_1 0x80 -#define UART1_INQ 0x80 -#define EXT_LEN_MSG_BIT 0x80 - -static UBYTE InBuf[NO_OF_INBUFFERS][SIZE_OF_INBUF]; -static ULONG InBufPtrs[NO_OF_INBUFFERS]; -static UBYTE InBufInPtr; -static UBYTE LengthSize; - -static UBYTE OutDma[NO_OF_DMA_OUTBUFFERS][SIZE_OF_OUTBUF]; -static UBYTE DmaBufPtr; -static UBYTE *pBuffer; - -static UBYTE MsgIn; -static UBYTE InBufOutCnt; -static UWORD FullRxLength; -static UWORD RemainingLength; - - -#define ENABLEDebugOutput {\ - *AT91C_PIOA_PER = 0x20000000; /* Enable PIO on PA029 */\ - *AT91C_PIOA_OER = 0x20000000; /* PA029 set to Output */\ - } - -#define SETDebugOutputHigh *AT91C_PIOA_SODR = 0x20000000 - -#define SETDebugOutputLow *AT91C_PIOA_CODR = 0x20000000 - -#define BTInit {\ - UBYTE Tmp;\ - LengthSize = 1;\ - InBufInPtr = 0;\ - for(Tmp = 0; Tmp < NO_OF_INBUFFERS; Tmp++)\ - {\ - InBufPtrs[Tmp] = (ULONG)&(InBuf[Tmp][0]);\ - }\ - *AT91C_PMC_PCER = PER_ID7_UART_1; /* Enable PMC clock for UART 1 */\ - *AT91C_PIOA_PDR = BT_RX_PIN | BT_TX_PIN | BT_SCK_PIN | BT_RTS_PIN | BT_CTS_PIN; /* Disable Per. A on PA21, PA22, PA23, PA24 & PA25 */\ - *AT91C_PIOA_ASR = BT_RX_PIN | BT_TX_PIN | BT_SCK_PIN | BT_RTS_PIN | BT_CTS_PIN; /* Enable Per. A on PA21, PA22, PA23, PA24 & PA25 */\ - *AT91C_US1_CR = AT91C_US_RSTSTA; /* Resets pins on UART1 */\ - *AT91C_US1_CR = AT91C_US_STTTO; /* Start timeout functionality after 1 byte */\ - *AT91C_US1_RTOR = 10000; /* Approxitely 20 mS,x times bit time with 115200 bit pr s */\ - *AT91C_US1_IDR = AT91C_US_TIMEOUT; /* Disable interrupt on timeout */\ - *AT91C_AIC_IDCR = UART1_INQ; /* Disable UART1 interrupt */\ - *AT91C_AIC_ICCR = UART1_INQ; /* Clear interrupt register */\ - *AT91C_US1_MR = AT91C_US_USMODE_HWHSH; /* Set UART with HW handshake */\ - *AT91C_US1_MR &= ~AT91C_US_SYNC; /* Set UART in asynchronous mode */\ - *AT91C_US1_MR |= AT91C_US_CLKS_CLOCK; /* Clock setup MCK*/\ - *AT91C_US1_MR |= AT91C_US_CHRL_8_BITS; /* UART using 8-bit */\ - *AT91C_US1_MR |= AT91C_US_PAR_NONE; /* UART using none parity bit */\ - *AT91C_US1_MR |= AT91C_US_NBSTOP_1_BIT; /* UART using 1 stop bit */\ - *AT91C_US1_MR |= AT91C_US_OVER; /* UART is using 8-bit sampling */\ - *AT91C_US1_BRGR = ((OSC/8/BAUD_RATE) | (((OSC/8) - ((OSC/8/BAUD_RATE) * BAUD_RATE)) / ((BAUD_RATE + 4)/8)) << 16);\ - *AT91C_US1_PTCR = (AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS); /* Disable of TX & RX with DMA */\ - *AT91C_US1_RCR = 0; /* Receive Counter Register */\ - *AT91C_US1_TCR = 0; /* Transmit Counter Register */\ - *AT91C_US1_RNPR = 0;\ - *AT91C_US1_TNPR = 0;\ - Tmp = *AT91C_US1_RHR;\ - Tmp = *AT91C_US1_CSR;\ - *AT91C_US1_RPR = (unsigned int)&(InBuf[InBufInPtr][0]); /* Initialise receiver buffer using DMA */\ - *AT91C_US1_RCR = SIZE_OF_INBUF;\ - *AT91C_US1_RNPR = (unsigned int)&(InBuf[(InBufInPtr + 1)%NO_OF_INBUFFERS][0]);\ - *AT91C_US1_RNCR = SIZE_OF_INBUF;\ - MsgIn = 0;\ - InBufOutCnt = 0;\ - FullRxLength = 0;\ - RemainingLength = 0;\ - *AT91C_US1_CR = AT91C_US_RXEN | AT91C_US_TXEN; /* Enable Tx & Rx on UART 1*/\ - *AT91C_US1_PTCR = (AT91C_PDC_RXTEN | AT91C_PDC_TXTEN); /* Enable of TX & RX with DMA */\ - } - - -#define BTInitPIOPins {\ - *AT91C_PIOA_PER = BT_CS_PIN | BT_RST_PIN; /* Enable PIO on PA11 & PA31 */\ - *AT91C_PIOA_OER = BT_CS_PIN | BT_RST_PIN; /* PA11 & PA31 set to output */\ - *AT91C_PIOA_SODR = BT_CS_PIN | BT_RST_PIN; /* PA31 & PA11 set output high */\ - *AT91C_PIOA_PPUDR = BT_ARM7_CMD_PIN; /* Disable PULL-UP resistor on PA27 */\ - *AT91C_PIOA_PER = BT_ARM7_CMD_PIN; /* Enable PIO on PA27 */\ - *AT91C_PIOA_CODR = BT_ARM7_CMD_PIN; /* PA27 set output low */\ - *AT91C_PIOA_OER = BT_ARM7_CMD_PIN; /* PA27 set to output */\ - } - -#define BTStartADConverter {\ - *AT91C_ADC_CHER = AT91C_ADC_CH6 | AT91C_ADC_CH4; \ - ADStart; \ - while(!((*AT91C_ADC_SR) & AT91C_ADC_CH6)); \ - *AT91C_ADC_CHDR = AT91C_ADC_CH6 | AT91C_ADC_CH4; \ - } - -#define BTReadADCValue(ADValue) ADValue = *AT91C_ADC_CDR6; - -#define BTSetResetHigh {\ - *AT91C_PIOA_SODR = BT_RST_PIN; /* PA11 set output high */\ - } - -#define BTSetResetLow {\ - *AT91C_PIOA_CODR = BT_RST_PIN; /* PA11 set output low */\ - } - -#define BTInitReceiver(InputBuffer, Mode)\ - {\ - pBuffer = InputBuffer;\ - MsgIn = 0;\ - FullRxLength = 0;\ - if (STREAM_MODE == Mode)\ - {\ - LengthSize = 2;\ - }\ - else\ - {\ - LengthSize = 1;\ - }\ - } - -#define BT_SetArm7CmdPin *AT91C_PIOA_SODR = BT_ARM7_CMD_PIN - -#define BT_ClearArm7CmdPin *AT91C_PIOA_CODR = BT_ARM7_CMD_PIN - -#define BT_GetBc4CmdPin *AT91C_PIOA_PDSR & BT_BC4_CMD_PIN - -#define REQTxEnd(TxEnd) TxEnd = FALSE;\ - if ((!(*AT91C_US1_TNCR)) && (!(*AT91C_US1_TCR)))\ - {\ - TxEnd = TRUE;\ - } - -#define AVAILOutBuf(Avail) if (!(*AT91C_US1_TNCR))\ - {\ - Avail = SIZE_OF_OUTBUF;\ - }\ - else\ - {\ - Avail = 0;\ - } - - -#define BTSend(OutputBuffer, BytesToSend)\ - {\ - UWORD Avail;\ - AVAILOutBuf(Avail);\ - if (BytesToSend < (Avail - 1))\ - {\ - memcpy(&(OutDma[DmaBufPtr][0]), OutputBuffer, BytesToSend);\ - *AT91C_US1_TNPR = (unsigned int)&(OutDma[DmaBufPtr][0]);\ - *AT91C_US1_TNCR = BytesToSend;\ - DmaBufPtr = (DmaBufPtr + 1) % NO_OF_DMA_OUTBUFFERS;\ - }\ - } - - -#define BTSendMsg(OutputBuffer, BytesToSend, MsgSize)\ - {\ - UWORD Avail;\ - AVAILOutBuf(Avail);\ - if (BytesToSend < (Avail - 1))\ - {\ - if (2 == LengthSize)\ - {\ - OutDma[DmaBufPtr][0] = (UBYTE)MsgSize;\ - OutDma[DmaBufPtr][1] = (UBYTE)(MsgSize>>8);\ - }\ - else\ - {\ - OutDma[DmaBufPtr][0] = (UBYTE)MsgSize;\ - }\ - memcpy(&(OutDma[DmaBufPtr][LengthSize]), OutputBuffer, BytesToSend);\ - *AT91C_US1_TNPR = (unsigned int)&(OutDma[DmaBufPtr][0]);\ - *AT91C_US1_TNCR = BytesToSend + LengthSize;\ - DmaBufPtr = (DmaBufPtr + 1) % NO_OF_DMA_OUTBUFFERS;\ - }\ - } - - -#define BTReceivedData(pByteCnt, pToGo)\ - {\ - UWORD InCnt, Cnt;\ - *pByteCnt = 0;\ - *pToGo = 0;\ - InCnt = (SIZE_OF_INBUF - *AT91C_US1_RCR);\ - if (*AT91C_US1_RNCR == 0)\ - {\ - InCnt = SIZE_OF_INBUF;\ - }\ - InCnt -= InBufOutCnt; /* Remove already read bytes */\ - if (InCnt)\ - {\ - if (0 == FullRxLength) /* FullRxLength still to be calculated */\ - {\ - while((MsgIn < LengthSize) && (InCnt > 0))\ - {\ - pBuffer[MsgIn] = InBuf[InBufInPtr][InBufOutCnt];\ - MsgIn++;\ - InBufOutCnt++;\ - InCnt--;\ - }\ - if (LengthSize == MsgIn)\ - {\ - if (2 == LengthSize)\ - {\ - FullRxLength = pBuffer[1];\ - FullRxLength <<= 8;\ - FullRxLength |= pBuffer[0];\ - /* Remove Length when in strean mode */\ - MsgIn = 0;\ - }\ - else\ - {\ - FullRxLength = pBuffer[0];\ - }\ - RemainingLength = FullRxLength;\ - }\ - else\ - {\ - /* Length still not received */\ - FullRxLength = 0;\ - }\ - }\ - if (FullRxLength)\ - {\ - /* Incomming msg in progress */\ - /* room for bytes? */\ - if (InCnt >= RemainingLength)\ - {\ - /* Remaining msg bytes are in the buffer */\ - /* Can remaining byte be stored in buffer? */\ - if ((MsgIn + RemainingLength) <= SIZE_OF_INBUF)\ - {\ - /* All bytes can be stored */\ - for (Cnt = 0; Cnt < RemainingLength; Cnt++)\ - {\ - pBuffer[MsgIn] = InBuf[InBufInPtr][InBufOutCnt];\ - MsgIn++;\ - InBufOutCnt++;\ - }\ - *pByteCnt = MsgIn;\ - *pToGo = 0;\ - FullRxLength = 0;\ - RemainingLength = 0;\ - MsgIn = 0;\ - }\ - else\ - {\ - for (Cnt = 0; MsgIn < SIZE_OF_INBUF; Cnt++)\ - {\ - pBuffer[MsgIn] = InBuf[InBufInPtr][InBufOutCnt];\ - MsgIn++;\ - InBufOutCnt++;\ - }\ - *pByteCnt = SIZE_OF_INBUF;\ - RemainingLength -= Cnt;\ - *pToGo = RemainingLength;\ - MsgIn = 0;\ - }\ - }\ - else\ - {\ - if ((InCnt + MsgIn) < SIZE_OF_INBUF)\ - {\ - /* Received bytes do not fill up the buffer */\ - for (Cnt = 0; Cnt < InCnt; Cnt++)\ - {\ - pBuffer[MsgIn] = InBuf[InBufInPtr][InBufOutCnt];\ - MsgIn++;\ - InBufOutCnt++;\ - }\ - RemainingLength -= InCnt;\ - }\ - else\ - {\ - /* Received bytes fill up the buffer */\ - for (Cnt = 0; MsgIn < SIZE_OF_INBUF; Cnt++)\ - {\ - pBuffer[MsgIn] = InBuf[InBufInPtr][InBufOutCnt];\ - MsgIn++;\ - InBufOutCnt++;\ - }\ - *pByteCnt = SIZE_OF_INBUF;\ - RemainingLength -= Cnt; /* Only substract no removed */\ - *pToGo = RemainingLength;\ - MsgIn = 0;\ - }\ - }\ - }\ - }\ - if ((*AT91C_US1_RNCR == 0) && (SIZE_OF_INBUF == InBufOutCnt))\ - {\ - InBufOutCnt = 0;\ - *AT91C_US1_RNPR = (unsigned int)InBufPtrs[InBufInPtr];\ - *AT91C_US1_RNCR = SIZE_OF_INBUF;\ - InBufInPtr = (InBufInPtr + 1) % NO_OF_INBUFFERS;\ - }\ - } - -#define BTExit {\ - *AT91C_PMC_PCDR = PER_ID7_UART_1; /* Disable PMC clock for UART 1*/\ - *AT91C_US1_IDR = AT91C_US_TIMEOUT; /* Disable interrupt on timeout */\ - *AT91C_AIC_IDCR = UART1_INQ; /* Disable PIO interrupt */\ - *AT91C_AIC_ICCR = UART1_INQ; /* Clear interrupt register */\ - } - - -#endif - -#ifdef PCWIN - -#endif diff --git a/AT91SAM7S256/Source/d_button.c b/AT91SAM7S256/Source/d_button.c deleted file mode 100644 index 2691e8c..0000000 --- a/AT91SAM7S256/Source/d_button.c +++ /dev/null @@ -1,36 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: d_button.c $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_butt $ -// -// Platform C -// - -#include "stdconst.h" -#include "m_sched.h" -#include "d_button.h" -#include "d_button.r" - -static UBYTE TimeTick; - -void dButtonInit(UBYTE Prescaler) -{ - TimeTick = Prescaler; - BUTTONInit; -} - -void dButtonRead(UBYTE *pButton) -{ - BUTTONRead(pButton); -} - -void dButtonExit(void) -{ - BUTTONExit; -} diff --git a/AT91SAM7S256/Source/d_button.h b/AT91SAM7S256/Source/d_button.h deleted file mode 100644 index 10dacac..0000000 --- a/AT91SAM7S256/Source/d_button.h +++ /dev/null @@ -1,24 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: d_button.h $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_butt $ -// -// Platform C -// - -#ifndef D_BUTTON -#define D_BUTTON - -void dButtonInit(UBYTE Prescaler); -void dButtonExit(void); - -void dButtonRead(UBYTE *pButton); - - -#endif diff --git a/AT91SAM7S256/Source/d_button.r b/AT91SAM7S256/Source/d_button.r deleted file mode 100644 index c478394..0000000 --- a/AT91SAM7S256/Source/d_button.r +++ /dev/null @@ -1,189 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: d_button.r $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_butt $ -// -// Platform C -// - -#ifdef SAM7S256 - -static UBYTE PrellCnt[NOS_OF_AVR_BTNS]; -static UWORD OldVal; -static UBYTE OldState; -static UBYTE RisingTime; - -#define PRELL_TIME (60/TimeTick) -#define RISING_THRESHOLD (10/TimeTick) - -#define BUTTONInit {\ - UBYTE Tmp;\ - for (Tmp = 0; Tmp < NOS_OF_AVR_BTNS; Tmp++)\ - {\ - PrellCnt[Tmp] = 0;\ - }\ - IoFromAvr.Buttons = 0;\ - OldVal = 0;\ - OldState = 0;\ - RisingTime = 0;\ - } - -#if defined (PROTOTYPE_PCB_3) || (PROTOTYPE_PCB_4) - -/* Buttons read here are free of prell or jitter */ -/* And because it's an AD value returned from the AVR */ -/* then a peak detector is needed */ -#define BUTTONRead(pB) {\ - UBYTE Tmp, BtnPtr;\ - UWORD TmpBtn;\ - *pB = OldState;\ - BtnPtr = 0x01;\ - if (OldVal < IoFromAvr.Buttons)\ - {\ - OldVal = IoFromAvr.Buttons;\ - RisingTime = 0;\ - }\ - else\ - {\ - if (OldVal > (IoFromAvr.Buttons + 20))\ - {\ - OldVal = IoFromAvr.Buttons;\ - RisingTime = 0;\ - }\ - else\ - {\ - if (RisingTime > RISING_THRESHOLD)\ - {\ - TmpBtn = IoFromAvr.Buttons;\ - if (0x40 > TmpBtn)\ - {\ - TmpBtn = 0x00;\ - }\ - else if (0x100 > TmpBtn)\ - {\ - TmpBtn = 0x04;\ - }\ - else if (0x1FF > TmpBtn)\ - {\ - TmpBtn = 0x02;\ - }\ - else if (0x5FF > TmpBtn)\ - {\ - TmpBtn = 0x01;\ - }\ - else\ - {\ - TmpBtn = 0x08;\ - }\ - for (Tmp = 0; Tmp < NOS_OF_AVR_BTNS; Tmp++)\ - {\ - if ((TmpBtn) & BtnPtr)\ - {\ - *pB |= BtnPtr;\ - PrellCnt[Tmp] = PRELL_TIME;\ - }\ - else\ - {\ - /* btn not pressed */\ - if (0 != PrellCnt[Tmp])\ - {\ - PrellCnt[Tmp]--;\ - }\ - else\ - {\ - *pB &= ~BtnPtr;\ - }\ - }\ - BtnPtr <<= 1;\ - }\ - OldState = *pB;\ - }\ - else\ - {\ - RisingTime++;\ - }\ - }\ - }\ - } - -#else - -// Buttons read here are free of prell or jitter -#define BUTTONRead(pB) {\ - UBYTE Tmp, BtnPtr;\ - UWORD TmpBtn;\ - *pB = OldState;\ - BtnPtr = 0x01;\ - if ((OldVal) < IoFromAvr.Buttons)\ - {\ - OldVal = IoFromAvr.Buttons;\ - }\ - else\ - {\ - if ((OldVal) > IoFromAvr.Buttons)\ - {\ - OldVal = IoFromAvr.Buttons;\ - }\ - else\ - {\ - TmpBtn = IoFromAvr.Buttons;\ - if (100 > TmpBtn)\ - {\ - TmpBtn = 0x00;\ - }\ - else if (170 > TmpBtn)\ - {\ - TmpBtn = 0x01;\ - }\ - else if (255 > TmpBtn)\ - {\ - TmpBtn = 0x02;\ - }\ - else if (1000 > TmpBtn)\ - {\ - TmpBtn = 0x04;\ - }\ - else if (1024 > TmpBtn)\ - {\ - TmpBtn = 0x08;\ - }\ - for (Tmp = 0; Tmp < NOS_OF_AVR_BTNS; Tmp++)\ - {\ - if ((TmpBtn) & BtnPtr)\ - {\ - *pB |= BtnPtr;\ - PrellCnt[Tmp] = PRELL_TIME;\ - }\ - else\ - {\ - /* btn not pressed */\ - if (0 != PrellCnt[Tmp])\ - {\ - PrellCnt[Tmp]--;\ - }\ - else\ - {\ - *pB &= ~BtnPtr;\ - }\ - }\ - BtnPtr <<= 1;\ - }\ - OldState = *pB;\ - }\ - }\ - } -#endif - -#define BUTTONExit - -#endif - -#ifdef PCWIN - -#endif diff --git a/AT91SAM7S256/Source/d_display.c b/AT91SAM7S256/Source/d_display.c deleted file mode 100644 index 99f16c6..0000000 --- a/AT91SAM7S256/Source/d_display.c +++ /dev/null @@ -1,53 +0,0 @@ -// -// Programmer -// -// Date init 14.12.2004 -// -// Reviser $Author:: Dkandlun $ -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: d_display.c $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_disp $ -// -// Platform C -// - -#include "stdconst.h" -#include "m_sched.h" -#include "d_display.h" -#include "d_display.r" - - -void dDisplayInit(void) -{ - DISPLAYInit; -} - - -void dDisplayOn(UBYTE On) -{ - if (On) - { - DISPLAYOn; - } - else - { - DISPLAYOff; - } -} - - -UBYTE dDisplayUpdate(UWORD Height,UWORD Width,UBYTE *pImage) -{ - return (DISPLAYUpdate(Height,Width,pImage)); -} - - -void dDisplayExit(void) -{ - DISPLAYExit; -} diff --git a/AT91SAM7S256/Source/d_display.h b/AT91SAM7S256/Source/d_display.h deleted file mode 100644 index a894685..0000000 --- a/AT91SAM7S256/Source/d_display.h +++ /dev/null @@ -1,39 +0,0 @@ -// -// Programmer -// -// Date init 14.12.2004 -// -// Reviser $Author:: Dkandlun $ -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: d_display.h $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_disp $ -// -// Platform C -// - -#ifndef D_DISPLAY -#define D_DISPLAY - -void dDisplayInit(void); -void dDisplayOn(UBYTE On); -UBYTE dDisplayUpdate(UWORD Height,UWORD Width,UBYTE *pImage); -void dDisplayExit(void); - - - -typedef struct -{ - UBYTE StartX; - UBYTE StartY; - UBYTE PixelsX; - UBYTE PixelsY; -} -SCREEN_CORDINATE; - - -#endif diff --git a/AT91SAM7S256/Source/d_display.r b/AT91SAM7S256/Source/d_display.r deleted file mode 100644 index e38bb45..0000000 --- a/AT91SAM7S256/Source/d_display.r +++ /dev/null @@ -1,374 +0,0 @@ -// -// Programmer -// -// Date init 14.12.2004 -// -// Reviser $Author:: Dkandlun $ -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: d_display.r $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_disp $ -// -// Platform C -// - -#ifdef SAM7S256 - -// Display 128 x 64 -// 1/65 duty, 1/9 bias -// VLCD 12.0V - -// SPI interface -// -// PCB LCD ARM PIO -// ------ ----- ---- ----- -// CS_DIS -CS1 PA10 NPCS2 (PB) -// DIS_A0 A0 PA12 PA12 -// DIS_SCL SCL PA14 SPCK (PA) -// DIS_SDA SI PA13 MOSI (PA) - - -// CPOL = 0, NCPHA=0, - -#define BT_RESET_OUT AT91C_PIO_PA11 -#define BT_RESET_IN AT91C_PIO_PA29 -#define BT_MOSI_OUT AT91C_PIO_PA13 -#define BT_MOSI_IN AT91C_PIO_PA20 -#define BT_CLK_OUT AT91C_PIO_PA14 -#define BT_CLK_IN AT91C_PIO_PA28 -#define BT_CE_OUT AT91C_PIO_PA31 -#define BT_CE_IN AT91C_PIO_PA19 -#define BT_REA_OUT AT91C_PIO_PA7 -#define BT_MISO_OUT AT91C_PIO_PA6 -#define BT_MISO_IN AT91C_PIO_PA12 - -#pragma optimize=s 9 - -__ramfunc void SpiBtIo(void) -{ - register ULONG Port; - - *AT91C_AIC_IDCR = 0xFFFFFFFF; /* Disable all interrupts */ - - *AT91C_PIOA_PER = BT_RESET_OUT; /* Enable pin RESET out */ - *AT91C_PIOA_OER = BT_RESET_OUT; /* Set output */ - *AT91C_PIOA_SODR = BT_RESET_OUT; /* Set high */ - - *AT91C_PIOA_PER = BT_MOSI_OUT; /* Enable pin MOSI out */ - *AT91C_PIOA_OER = BT_MOSI_OUT; /* Set output */ - - *AT91C_PIOA_PER = BT_CLK_OUT; /* Enable pin CLK out */ - *AT91C_PIOA_OER = BT_CLK_OUT; /* Set output */ - - *AT91C_PIOA_PER = BT_CE_OUT; /* Enable pin CE out */ - *AT91C_PIOA_OER = BT_CE_OUT; /* Set output */ - - *AT91C_PIOA_PER = BT_REA_OUT; /* Enable pin REA out */ - *AT91C_PIOA_OER = BT_REA_OUT; /* Set output */ - *AT91C_PIOA_SODR = BT_REA_OUT; /* Set high */ - - *AT91C_PIOA_PER = BT_MISO_OUT; /* Enable pin MISO out */ - *AT91C_PIOA_OER = BT_MISO_OUT; /* Set output */ - - *AT91C_PIOA_PER = BT_RESET_IN; /* Enable pin RESET in */ - *AT91C_PIOA_ODR = BT_RESET_IN; /* Set input */ - *AT91C_PIOA_IFDR = BT_RESET_IN; /* Disable filter */ - *AT91C_PIOA_IDR = BT_RESET_IN; /* Disable interrupt */ - *AT91C_PIOA_MDDR = BT_RESET_IN; /* Disable multidriver */ - *AT91C_PIOA_PPUDR = BT_RESET_IN; /* Disable pullup */ - - *AT91C_PIOA_PER = BT_MOSI_IN; /* Enable pin MOSI in */ - *AT91C_PIOA_ODR = BT_MOSI_IN; /* Set input */ - *AT91C_PIOA_IFDR = BT_MOSI_IN; /* Disable filter */ - *AT91C_PIOA_IDR = BT_MOSI_IN; /* Disable interrupt */ - *AT91C_PIOA_MDDR = BT_MOSI_IN; /* Disable multidriver */ - *AT91C_PIOA_PPUDR = BT_MOSI_IN; /* Disable pullup */ - - *AT91C_PIOA_PER = BT_CLK_IN; /* Enable pin CLK in */ - *AT91C_PIOA_ODR = BT_CLK_IN; /* Set input */ - *AT91C_PIOA_IFDR = BT_CLK_IN; /* Disable filter */ - *AT91C_PIOA_IDR = BT_CLK_IN; /* Disable interrupt */ - *AT91C_PIOA_MDDR = BT_CLK_IN; /* Disable multidriver */ - *AT91C_PIOA_PPUDR = BT_CLK_IN; /* Disable pullup */ - - *AT91C_PIOA_PER = BT_CE_IN; /* Enable pin CE in */ - *AT91C_PIOA_ODR = BT_CE_IN; /* Set input */ - *AT91C_PIOA_IFDR = BT_CE_IN; /* Disable filter */ - *AT91C_PIOA_IDR = BT_CE_IN; /* Disable interrupt */ - *AT91C_PIOA_MDDR = BT_CE_IN; /* Disable multidriver */ - *AT91C_PIOA_PPUDR = BT_CE_IN; /* Disable pullup */ - - *AT91C_PIOA_PER = BT_MISO_IN; /* Enable pin MISO in */ - *AT91C_PIOA_ODR = BT_MISO_IN; /* Set input */ - *AT91C_PIOA_IFDR = BT_MISO_IN; /* Disable filter */ - *AT91C_PIOA_IDR = BT_MISO_IN; /* Disable interrupt */ - *AT91C_PIOA_MDDR = BT_MISO_IN; /* Disable multidriver */ - *AT91C_PIOA_PPUDR = BT_MISO_IN; /* Disable pullup */ - - while (1) - { - Port = *AT91C_PIOA_PDSR; - if ((Port & BT_MISO_IN)) - { - *AT91C_PIOA_SODR = BT_MISO_OUT; - } - else - { - *AT91C_PIOA_CODR = BT_MISO_OUT; - } - if ((Port & BT_MOSI_IN)) - { - *AT91C_PIOA_SODR = BT_MOSI_OUT; - } - else - { - *AT91C_PIOA_CODR = BT_MOSI_OUT; - } - if ((Port & BT_CLK_IN)) - { - *AT91C_PIOA_SODR = BT_CLK_OUT; - } - else - { - *AT91C_PIOA_CODR = BT_CLK_OUT; - } - if ((Port & BT_CE_IN)) - { - *AT91C_PIOA_SODR = BT_CE_OUT; - } - else - { - *AT91C_PIOA_CODR = BT_CE_OUT; - } - } - -} - - -void BtIo(void) -{ - SpiBtIo(); -} - - - -#define SPI_BITRATE 2000000 - -#define SPIA0High {\ - *AT91C_PIOA_SODR = AT91C_PIO_PA12;\ - } - - -#define SPIA0Low {\ - *AT91C_PIOA_CODR = AT91C_PIO_PA12;\ - } - - -#define SPIInit {\ - *AT91C_PMC_PCER = (1L << AT91C_ID_SPI); /* Enable MCK clock */\ - *AT91C_PIOA_PER = AT91C_PIO_PA12; /* Enable A0 on PA12 */\ - *AT91C_PIOA_OER = AT91C_PIO_PA12;\ - *AT91C_PIOA_CODR = AT91C_PIO_PA12;\ - *AT91C_PIOA_PDR = AT91C_PA14_SPCK; /* Enable SPCK on PA14 */\ - *AT91C_PIOA_ASR = AT91C_PA14_SPCK;\ - *AT91C_PIOA_ODR = AT91C_PA14_SPCK;\ - *AT91C_PIOA_OWER = AT91C_PA14_SPCK;\ - *AT91C_PIOA_MDDR = AT91C_PA14_SPCK;\ - *AT91C_PIOA_PPUDR = AT91C_PA14_SPCK;\ - *AT91C_PIOA_IFDR = AT91C_PA14_SPCK;\ - *AT91C_PIOA_CODR = AT91C_PA14_SPCK;\ - *AT91C_PIOA_IDR = AT91C_PA14_SPCK;\ - *AT91C_PIOA_PDR = AT91C_PA13_MOSI; /* Enable mosi on PA13 */\ - *AT91C_PIOA_ASR = AT91C_PA13_MOSI;\ - *AT91C_PIOA_ODR = AT91C_PA13_MOSI;\ - *AT91C_PIOA_OWER = AT91C_PA13_MOSI;\ - *AT91C_PIOA_MDDR = AT91C_PA13_MOSI;\ - *AT91C_PIOA_PPUDR = AT91C_PA13_MOSI;\ - *AT91C_PIOA_IFDR = AT91C_PA13_MOSI;\ - *AT91C_PIOA_CODR = AT91C_PA13_MOSI;\ - *AT91C_PIOA_IDR = AT91C_PA13_MOSI;\ - *AT91C_PIOA_PDR = AT91C_PA10_NPCS2; /* Enable npcs0 on PA11 */\ - *AT91C_PIOA_BSR = AT91C_PA10_NPCS2;\ - *AT91C_PIOA_ODR = AT91C_PA10_NPCS2;\ - *AT91C_PIOA_OWER = AT91C_PA10_NPCS2;\ - *AT91C_PIOA_MDDR = AT91C_PA10_NPCS2;\ - *AT91C_PIOA_PPUDR = AT91C_PA10_NPCS2;\ - *AT91C_PIOA_IFDR = AT91C_PA10_NPCS2;\ - *AT91C_PIOA_CODR = AT91C_PA10_NPCS2;\ - *AT91C_PIOA_IDR = AT91C_PA10_NPCS2;\ - *AT91C_SPI_CR = AT91C_SPI_SWRST; /* Soft reset */\ - *AT91C_SPI_CR = AT91C_SPI_SPIEN; /* Enable spi */\ - *AT91C_SPI_MR = AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | (0xB << 16);\ - AT91C_SPI_CSR[2] = ((OSC / SPI_BITRATE) << 8) | AT91C_SPI_CPOL;\ - } - - -#define SPIWrite(pString,Length) {\ - *AT91C_SPI_TPR = (unsigned int)pString;\ - *AT91C_SPI_TCR = (unsigned int)Length;\ - *AT91C_SPI_PTCR = AT91C_PDC_TXTEN;\ - } - - - -#define CMD 0 -#define DAT 1 -#define DISP_LINES 8 - -#if defined (PROTOTYPE_PCB_3) || (PROTOTYPE_PCB_4) - -#define ACTUAL_WIDTH 100 - -UBYTE DisplayInitString[] = -{ - 0xEB, // LCD bias setting = 1/9 0xEB - 0x2F, // Power control = internal 0x2F - 0xA4, // All points not on 0xA4 - 0xA6, // Not inverse 0xA6 - 0x40, // Start line = 0 0x40 - 0x81, // Electronic volume 0x81 - 0x5A, // -"- 0x5F - 0xC4, // LCD mapping 0xC4 - 0x27, // Set temp comp. 0x27- - 0x29, // Panel loading 0x28 0-1 - 0xA0, // Framerate 0xA0- - 0x88, // CA++ 0x88- - 0x23, // Multiplex 1:65 0x23 - 0xAF // Display on 0xAF -}; - -#else - -#define ACTUAL_WIDTH 128 - -UBYTE DisplayInitString[] = -{ - 0xA2, // LCD bias setting = 1/9 - 0x2F, // Power control = internal - 0xA4, // All points not on - 0xA6, // Not inverse - 0x40, // Start line = 0 - 0x81, // Electronic volume - 0x3F, // -"- - 0xA0, // LCD mapping - 0x27, // Resistor ratio - 0xC8, // Common output state selection - 0xF8, // Booster ratio - 0x00, // -"- - 0xE3, // nop - 0xAF // Display on -}; - -#endif - -UBYTE DisplayLineString[DISP_LINES][3] = -{ - { 0xB0,0x10,0x00 }, - { 0xB1,0x10,0x00 }, - { 0xB2,0x10,0x00 }, - { 0xB3,0x10,0x00 }, - { 0xB4,0x10,0x00 }, - { 0xB5,0x10,0x00 }, - { 0xB6,0x10,0x00 }, - { 0xB7,0x10,0x00 } -}; - -UBYTE DisplayWrite(UBYTE Type,UBYTE *pData,UWORD Length) -{ - UBYTE Result = FALSE; - - if ((*AT91C_SPI_SR & AT91C_SPI_TXEMPTY)) - { - if (Type) - { - SPIA0High; - } - else - { - SPIA0Low; - } - SPIWrite(pData,Length); - Result = TRUE; - } - - return (Result); -} - -UBYTE DisplayUpdate(UWORD Height,UWORD Width,UBYTE *pImage) -{ - static UWORD State = 0; - static UWORD Line; - - if (State == 0) - { - if (DisplayWrite(CMD,(UBYTE*)DisplayInitString,sizeof(DisplayInitString)) == TRUE) - { - Line = 0; - State++; - } - } - else - { - if ((State & 1)) - { - if (DisplayWrite(CMD,(UBYTE*)DisplayLineString[Line],3) == TRUE) - { - State++; - } - } - else - { - if (DisplayWrite(DAT,(UBYTE*)&pImage[Line * Width],ACTUAL_WIDTH) == TRUE) - { - State++; - if (++Line >= (Height / 8)) - { - State = 0; - } - } - } - } - - return (State); -} - - -#if defined (PROTOTYPE_PCB_3) - -#define DISPLAYInit {\ - TSTInit;\ - TSTOn;\ - SPIInit;\ - } - -#else - -#define DISPLAYInit {\ - SPIInit;\ - } - -#endif - -#define DISPLAYOn {\ - DisplayInitString[6] = 0x5A;\ - DisplayInitString[13] = 0xAF;\ - } - -#define DISPLAYOff {\ - DisplayInitString[6] = 0x00;\ - DisplayInitString[13] = 0xAE;\ - } - -#define DISPLAYUpdate(H,W,I) DisplayUpdate(H,W,I) - -#define DISPLAYExit - -#endif - -#ifdef PCWIN - -#endif diff --git a/AT91SAM7S256/Source/d_hispeed.c b/AT91SAM7S256/Source/d_hispeed.c deleted file mode 100644 index 01f2d07..0000000 --- a/AT91SAM7S256/Source/d_hispeed.c +++ /dev/null @@ -1,48 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: d_hispeed.c $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_hisp $ -// -// Platform C -// - -#include "stdconst.h" -#include "m_sched.h" -#include "d_hispeed.h" -#include "d_hispeed.r" - -void dHiSpeedInit(void) -{ - HIGHSPEEDInit; -} - -void dHiSpeedSendData(UBYTE *OutputBuffer, UBYTE BytesToSend) -{ - HIGHSPEEDSendDmaData(OutputBuffer,BytesToSend); -} - -void dHiSpeedSetupUart(void) -{ - HIGHSPEEDSetupUart; -} - -void dHiSpeedInitReceive(UBYTE *InputBuffer) -{ - HIGHSPEEDInitReceiver(InputBuffer); -} - -void dHiSpeedReceivedData(UWORD *ByteCnt) -{ - HIGHSPEEDReceivedData(ByteCnt); -} - -void dHiSpeedExit(void) -{ - HIGHSPEEDExit; -} diff --git a/AT91SAM7S256/Source/d_hispeed.h b/AT91SAM7S256/Source/d_hispeed.h deleted file mode 100644 index 669a5d1..0000000 --- a/AT91SAM7S256/Source/d_hispeed.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: d_hispeed.h $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_hisp $ -// -// Platform C -// - -#ifndef D_HISPEED -#define D_HISPEED - -void dHiSpeedInit(void); -void dHiSpeedSendData(UBYTE *OutputBuffer, UBYTE BytesToSend); -void dHiSpeedSetupUart(void); -void dHiSpeedInitReceive(UBYTE *InputBuffer); -void dHiSpeedReceivedData(UWORD *ByteCnt); -void dHiSpeedExit(void); - -#endif diff --git a/AT91SAM7S256/Source/d_hispeed.r b/AT91SAM7S256/Source/d_hispeed.r deleted file mode 100644 index 52d5e14..0000000 --- a/AT91SAM7S256/Source/d_hispeed.r +++ /dev/null @@ -1,190 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: d_hispeed.r $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_hisp $ -// -// Platform C -// - -#ifdef SAM7S256 - -#if defined (PROTOTYPE_PCB_3) || (PROTOTYPE_PCB_4) - -#define HIGHSPEED_RX_PIN AT91C_PIO_PA5 -#define HIGHSPEED_TX_PIN AT91C_PIO_PA6 -#define HIGHSPEED_RTS_PIN AT91C_PIO_PA7 - -#else - - -#endif - -#define PER_ID6_UART_0 0x40 -#define UART0_INQ 0x40 -#define BAUD_RATE 921600L - -#define SIZE_OF_INBUF 128 -#define NO_OF_INBUFFERS 2 -#define SIZE_OF_OUTBUF 128 -#define NO_OF_DMA_OUTBUFFERS 1 - -static UBYTE InBuf[NO_OF_INBUFFERS][SIZE_OF_INBUF]; -static ULONG InBufPtrs[NO_OF_INBUFFERS]; -static UBYTE InBufInPtr; - -static UBYTE OutDma[NO_OF_DMA_OUTBUFFERS][SIZE_OF_OUTBUF]; -static UBYTE DmaBufPtr; -static UBYTE *pBuffer; - -static UBYTE MsgIn; -static UBYTE InBufOutCnt; - -#define HIGHSPEEDInit {\ - *AT91C_PIOA_PER = HIGHSPEED_TX_PIN | HIGHSPEED_RTS_PIN | HIGHSPEED_RX_PIN; /* Enable PIO on PA07, PA06 & PA05 */\ - *AT91C_PIOA_PPUDR = HIGHSPEED_RX_PIN | HIGHSPEED_TX_PIN | HIGHSPEED_RTS_PIN; /* Disable Pull-up resistor */\ - *AT91C_PIOA_OER = HIGHSPEED_TX_PIN | HIGHSPEED_RTS_PIN | HIGHSPEED_RX_PIN; /* PA07 & PA06 set to Output */\ - *AT91C_PIOA_CODR = HIGHSPEED_TX_PIN | HIGHSPEED_RTS_PIN | HIGHSPEED_RX_PIN; /* Set output low */\ - } - - -#define HIGHSPEEDSetupUart {\ - UBYTE Tmp;\ - InBufInPtr = 0;\ - for(Tmp = 0; Tmp < NO_OF_INBUFFERS; Tmp++)\ - {\ - InBufPtrs[Tmp] = (ULONG)&(InBuf[Tmp][0]);\ - }\ - *AT91C_PMC_PCER = PER_ID6_UART_0; /* Enable PMC clock for UART 0 */\ - *AT91C_PIOA_PPUDR = HIGHSPEED_RX_PIN | HIGHSPEED_TX_PIN | HIGHSPEED_RTS_PIN; /* Disable Pull-up resistor */\ - *AT91C_PIOA_PDR = HIGHSPEED_TX_PIN | HIGHSPEED_RTS_PIN | HIGHSPEED_RX_PIN; /* Disable Per. A on PA5, PA6 & PA7 */\ - *AT91C_PIOA_ASR = HIGHSPEED_TX_PIN | HIGHSPEED_RTS_PIN | HIGHSPEED_RX_PIN;; /* Enable Per. A on PA5, PA6 & PA7 */\ - *AT91C_US0_CR = AT91C_US_RSTSTA; /* Resets pins on UART0 */\ - *AT91C_US0_CR = AT91C_US_STTTO; /* Start timeout functionality after 1 byte */\ - *AT91C_US0_RTOR = 2400; /* Approxitely 20 mS,x times bit time with 115200 bit pr s */\ - *AT91C_US0_IDR = AT91C_US_TIMEOUT; /* Disable interrupt on timeout */\ - *AT91C_AIC_IDCR = UART0_INQ; /* Disable UART0 interrupt */\ - *AT91C_AIC_ICCR = UART0_INQ; /* Clear interrupt register */\ - *AT91C_US0_MR = AT91C_US_USMODE_RS485; /* Set UART to RUN RS485 Mode*/\ - *AT91C_US0_MR &= ~AT91C_US_SYNC; /* Set UART in asynchronous mode */\ - *AT91C_US0_MR |= AT91C_US_CLKS_CLOCK; /* Clock setup MCK*/\ - *AT91C_US0_MR |= AT91C_US_CHRL_8_BITS; /* UART using 8-bit */\ - *AT91C_US0_MR |= AT91C_US_PAR_NONE; /* UART using none parity bit */\ - *AT91C_US0_MR |= AT91C_US_NBSTOP_1_BIT; /* UART using 1 stop bit */\ - *AT91C_US0_MR |= AT91C_US_OVER; /* UART is using 8-bit sampling */\ - *AT91C_US0_BRGR = ((OSC/8/BAUD_RATE) | (((OSC/8) - ((OSC/8/BAUD_RATE) * BAUD_RATE)) / ((BAUD_RATE + 4)/8)) << 16);\ - *AT91C_US0_PTCR = (AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS); /* Disable of TX & RX with DMA */\ - *AT91C_US0_RCR = 0; /* Receive Counter Register */\ - *AT91C_US0_TCR = 0; /* Transmit Counter Register */\ - *AT91C_US0_RNPR = 0;\ - *AT91C_US0_TNPR = 0;\ - Tmp = *AT91C_US0_RHR;\ - Tmp = *AT91C_US0_CSR;\ - *AT91C_US0_RPR = (unsigned int)&(InBuf[InBufInPtr][0]); /* Initialise receiver buffer using DMA */\ - *AT91C_US0_RCR = SIZE_OF_INBUF;\ - *AT91C_US0_RNPR = (unsigned int)&(InBuf[(InBufInPtr + 1)%NO_OF_INBUFFERS][0]);\ - *AT91C_US0_RNCR = SIZE_OF_INBUF;\ - MsgIn = 0;\ - InBufOutCnt = 0;\ - *AT91C_US0_CR = AT91C_US_RXEN | AT91C_US_TXEN; /* Enable Tx & Rx on UART 0*/\ - *AT91C_US0_PTCR = (AT91C_PDC_RXTEN | AT91C_PDC_TXTEN); /* Enable of TX & RX with DMA */\ - } - -#define HIGHSPEEDInitReceiver(InputBuffer)\ - {\ - UBYTE Tmp;\ - pBuffer = InputBuffer;\ - *AT91C_US0_PTCR = (AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS); /* Disable of TX & RX with DMA */\ - *AT91C_US0_RCR = 0; /* Receive Counter Register */\ - *AT91C_US0_TCR = 0; /* Transmit Counter Register */\ - *AT91C_US0_RNPR = 0;\ - *AT91C_US0_TNPR = 0;\ - Tmp = *AT91C_US0_RHR;\ - Tmp = *AT91C_US0_CSR;\ - Tmp = Tmp;\ - *AT91C_US0_RPR = (unsigned int)&(InBuf[InBufInPtr][0]); /* Initialise receiver buffer using DMA */\ - *AT91C_US0_RCR = SIZE_OF_INBUF;\ - *AT91C_US0_RNPR = (unsigned int)&(InBuf[(InBufInPtr + 1)%NO_OF_INBUFFERS][0]);\ - *AT91C_US0_RNCR = SIZE_OF_INBUF;\ - MsgIn = 0;\ - InBufOutCnt = 0;\ - *AT91C_US0_CR = AT91C_US_RXEN | AT91C_US_TXEN; /* Enable Tx & Rx on UART 0*/\ - *AT91C_US0_PTCR = (AT91C_PDC_RXTEN | AT91C_PDC_TXTEN); /* Enable of TX & RX with DMA */\ - } - - -#define HIGHSPEEDReceivedData(pByteCnt)\ - {\ - UWORD InCnt;\ - *pByteCnt = 0;\ - InCnt = (SIZE_OF_INBUF - *AT91C_US0_RCR);\ - if (*AT91C_US0_RNCR == 0)\ - {\ - InCnt = SIZE_OF_INBUF;\ - }\ - InCnt -= InBufOutCnt; /* Remove already read bytes */\ - if(InCnt)\ - {\ - while(InCnt > 0)\ - {\ - pBuffer[MsgIn] = InBuf[InBufInPtr][InBufOutCnt];\ - MsgIn++;\ - InBufOutCnt++;\ - InCnt--;\ - }\ - *pByteCnt = MsgIn;\ - MsgIn = 0;\ - }\ - if ((*AT91C_US0_RNCR == 0) && (SIZE_OF_INBUF == InBufOutCnt))\ - {\ - InBufOutCnt = 0;\ - *AT91C_US0_RNPR = (unsigned int)InBufPtrs[InBufInPtr];\ - *AT91C_US0_RNCR = SIZE_OF_INBUF;\ - InBufInPtr = (InBufInPtr + 1) % NO_OF_INBUFFERS;\ - }\ - } - -#define AVAILOutBuf(Avail) if (!(*AT91C_US0_TNCR))\ - {\ - Avail = SIZE_OF_OUTBUF;\ - }\ - else\ - {\ - Avail = 0;\ - } - -#define HIGHSPEEDSendDmaData(OutputBuffer, BytesToSend)\ - {\ - UWORD Avail, Cnt;\ - AVAILOutBuf(Avail);\ - if (BytesToSend < (Avail - 1))\ - {\ - for (Cnt = 0; Cnt < BytesToSend; Cnt++)\ - {\ - OutDma[DmaBufPtr][Cnt] = OutputBuffer[Cnt];\ - }\ - *AT91C_US0_TNPR = (unsigned int)&(OutDma[DmaBufPtr][0]);\ - *AT91C_US0_TNCR = BytesToSend;\ - DmaBufPtr = (DmaBufPtr + 1) % NO_OF_DMA_OUTBUFFERS;\ - }\ - } - -#define HIGHSPEEDExit {\ - *AT91C_PMC_PCDR = PER_ID6_UART_0; /* Disable PMC clock for UART 0*/\ - *AT91C_PIOA_PER = HIGHSPEED_TX_PIN | HIGHSPEED_RTS_PIN | HIGHSPEED_RX_PIN; /* Enable PIO on PA07, PA06 & PA05 */\ - *AT91C_PIOA_PPUDR = HIGHSPEED_RX_PIN | HIGHSPEED_TX_PIN | HIGHSPEED_RTS_PIN; /* Disable Pull-up resistor */\ - *AT91C_PIOA_OER = HIGHSPEED_TX_PIN | HIGHSPEED_RTS_PIN | HIGHSPEED_RX_PIN; /* PA07 & PA06 set to Output */\ - *AT91C_PIOA_CODR = HIGHSPEED_TX_PIN | HIGHSPEED_RTS_PIN | HIGHSPEED_RX_PIN; /* Set output low */\ - } - - -#endif - -#ifdef PCWIN - -#endif diff --git a/AT91SAM7S256/Source/d_input.c b/AT91SAM7S256/Source/d_input.c deleted file mode 100644 index 771eb3e..0000000 --- a/AT91SAM7S256/Source/d_input.c +++ /dev/null @@ -1,152 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 14-01-09 10:34 $ -// -// Filename $Workfile:: d_input.c $ -// -// Version $Revision:: 12 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_inpu $ -// -// Platform C -// - -#include "stdconst.h" -#include "m_sched.h" -#include "c_input.h" -#include "d_input.h" -#include "d_input.r" - - -void dInputInit(void) -{ - INPUTInit; -} - -void dInputSetColorClkInput(void) -{ - COLORClkInput; -} - -void dInputGetAllColors(COLORSTRUCT *pRaw, UBYTE Status) -{ - UPDATEAllColors(pRaw, Status); -} - -void dInputGetRawAd(UWORD *pValues, UBYTE No) -{ - INPUTGetVal(pValues, No); -} - -void dInputSetDirOutDigi0(UBYTE Port) -{ - INPUTSetOutDigi0(Port); -} - -void dInputSetDirOutDigi1(UBYTE Port) -{ - INPUTSetOutDigi1(Port); -} - -void dInputSetDirInDigi0(UBYTE Port) -{ - INPUTSetInDigi0(Port); -} - -void dInputSetDirInDigi1(UBYTE Port) -{ - INPUTSetInDigi1(Port); -} - -void dInputClearDigi0(UBYTE Port) -{ - INPUTClearDigi0(Port); - INPUTSetOutDigi0(Port); -} - -void dInputClearDigi1(UBYTE Port) -{ - INPUTClearDigi1(Port); - INPUTSetOutDigi1(Port); -} - -void dInputSetDigi0(UBYTE Port) -{ - INPUTSetDigi0(Port); - INPUTSetOutDigi0(Port); -} - -void dInputSetDigi1(UBYTE Port) -{ - INPUTSetDigi1(Port); - INPUTSetOutDigi1(Port); -} - -void dInputRead0(UBYTE Port, UBYTE *pData) -{ - INPUTReadDigi0(Port, pData); -} - -void dInputRead1(UBYTE Port, UBYTE * pData) -{ - INPUTReadDigi1(Port, pData); -} - -void dInputSetActive(UBYTE Port) -{ - INPUTSetActive(Port); -} - -void dInputSet9v(UBYTE Port) -{ - INPUTSet9v(Port); -} - -void dInputSetInactive(UBYTE Port) -{ - INPUTSetInactive(Port); -} - -UBYTE dInputGetColor(UBYTE No, UWORD *pCol) -{ - UBYTE Status; - UPDATELed(No, pCol, Status); - return(Status); -} - -void dInputColorTx(UBYTE Port, UBYTE Data) -{ - COLORTx(Port, Data); -} - -void dInputReadCal(UBYTE Port, UBYTE *pData) -{ - CALDataRead(Port, pData); -} - -UBYTE dInputCheckColorStatus(UBYTE Port) -{ - UBYTE Status; - - CHECKColorState(Port,Status); - return(Status); -} - -void dInputClearColor100msTimer(UBYTE No) -{ - CLEARColor100msTimer(No); -} - -UBYTE dInputChkColor100msTimer(UBYTE No) -{ - UBYTE State; - COLOR100msStatus(No, State); - return(State); -} - -void dInputExit(void) -{ - INPUTExit; -} - diff --git a/AT91SAM7S256/Source/d_input.h b/AT91SAM7S256/Source/d_input.h deleted file mode 100644 index d365dd1..0000000 --- a/AT91SAM7S256/Source/d_input.h +++ /dev/null @@ -1,48 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 14-01-09 10:33 $ -// -// Filename $Workfile:: d_input.h $ -// -// Version $Revision:: 12 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_inpu $ -// -// Platform C -// - -#ifndef D_INPUT -#define D_INPUT - -void dInputInit(void); -void dInputExit(void); - -void dInputGetRawAd(UWORD *pValues, UBYTE No); -void dInputSetActive(UBYTE Port); -void dInputSet9v(UBYTE Port); -void dInputSetInactive(UBYTE Port); - -void dInputSetDirOutDigi0(UBYTE Port); -void dInputSetDirOutDigi1(UBYTE Port); -void dInputSetDirInDigi0(UBYTE Port); -void dInputSetDirInDigi1(UBYTE Port); -void dInputClearDigi0(UBYTE Port); -void dInputClearDigi1(UBYTE Port); -void dInputSetDigi0(UBYTE Port); -void dInputSetDigi1(UBYTE Port); -void dInputRead0(UBYTE Port, UBYTE *pData); -void dInputRead1(UBYTE Port, UBYTE *pData); - -UBYTE dInputGetColor(UBYTE No, UWORD *pCol); - -void dInputColorTx(UBYTE Port, UBYTE Data); -void dInputReadCal(UBYTE Port, UBYTE *pData); -UBYTE dInputCheckColorStatus(UBYTE Port); -void dInputGetAllColors(COLORSTRUCT *pRaw, UBYTE Status); -void dInputSetColorClkInput(void); -void dInputClearColor100msTimer(UBYTE No); -UBYTE dInputChkColor100msTimer(UBYTE No); - - -#endif diff --git a/AT91SAM7S256/Source/d_input.r b/AT91SAM7S256/Source/d_input.r deleted file mode 100644 index 3dc567e..0000000 --- a/AT91SAM7S256/Source/d_input.r +++ /dev/null @@ -1,312 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 14-01-09 10:33 $ -// -// Filename $Workfile:: d_input.r $ -// -// Version $Revision:: 24 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_inpu $ -// -// Platform C -// - - -#ifdef SAM7S256 - -void rInputWait2uS(void); -void rInputWait20uS(void); -void rInputWait30uS(void); -void rInputSingleADC(UBYTE Port, UWORD *Val); - -const ULONG Digi0Alloc[] = {AT91C_PIO_PA23, AT91C_PIO_PA28, AT91C_PIO_PA29, AT91C_PIO_PA30}; -const ULONG Digi1Alloc[] = {AT91C_PIO_PA18, AT91C_PIO_PA19, AT91C_PIO_PA20, AT91C_PIO_PA2}; -const ULONG ADPinDef[NO_OF_INPUTS] = {AT91C_ADC_CH1, AT91C_ADC_CH2, AT91C_ADC_CH3, AT91C_ADC_CH7}; -unsigned int volatile* ADValRegs[NO_OF_INPUTS] = {AT91C_ADC_CDR1, AT91C_ADC_CDR2, AT91C_ADC_CDR3, AT91C_ADC_CDR7}; - -static UBYTE ColorReset[NO_OF_INPUTS]; -static ULONG ColorClkDef; -static ULONG ColorTimer[NO_OF_INPUTS]; - -#define TIME2US ((OSC/16)/500000L) -#define TIME20US ((OSC/16)/50000L) -#define TIME30US ((OSC/16)/33333L) -#define TIME100MS ((OSC/16)/10L) - -#define MAX_AD_VALUE 0x3FF - -#define INPUTInit {\ - UBYTE Tmp; \ - for (Tmp = 0; Tmp < NOS_OF_AVR_INPUTS; Tmp++)\ - { \ - IoFromAvr.AdValue[Tmp] = MAX_AD_VALUE; \ - } \ - IoToAvr.InputPower = 0; \ - for (Tmp = 0; Tmp < NO_OF_INPUTS; Tmp++) \ - { \ - *AT91C_PIOA_PPUDR = Digi0Alloc[Tmp]; \ - *AT91C_PIOA_PPUDR = Digi1Alloc[Tmp]; \ - INPUTSetInDigi0(Tmp); \ - INPUTSetInDigi1(Tmp); \ - ColorReset[Tmp] = FALSE; \ - } \ - ColorClkDef = 0; \ - } - -#define INPUTGetVal(pValues, No) *pValues = (UWORD)IoFromAvr.AdValue[No]; \ - *pValues &= 0x03FF - -#define INPUTSetActive(Input) IoToAvr.InputPower |= (0x01 << Input); \ - IoToAvr.InputPower &= ~(0x10 << Input) -#define INPUTSet9v(Input) IoToAvr.InputPower |= (0x10 << Input); \ - IoToAvr.InputPower &= ~(0x01 << Input) -#define INPUTSetInactive(Input) IoToAvr.InputPower &= ~(0x11 << Input) - -#define INPUTSetOutDigi0(Input) *AT91C_PIOA_PER = Digi0Alloc[Input]; \ - *AT91C_PIOA_OER = Digi0Alloc[Input] - -#define INPUTSetOutDigi1(Input) *AT91C_PIOA_PER = Digi1Alloc[Input]; \ - *AT91C_PIOA_OER = Digi1Alloc[Input] - -#define INPUTSetInDigi0(Input) *AT91C_PIOA_PER = Digi0Alloc[Input]; \ - *AT91C_PIOA_ODR = Digi0Alloc[Input] - -#define INPUTSetInDigi1(Input) *AT91C_PIOA_PER = Digi1Alloc[Input]; \ - *AT91C_PIOA_ODR = Digi1Alloc[Input] - -#define INPUTSetDigi0(Input) *AT91C_PIOA_SODR = Digi0Alloc[Input] - -#define INPUTSetDigi1(Input) *AT91C_PIOA_SODR = Digi1Alloc[Input] - -#define INPUTClearDigi0(Input) *AT91C_PIOA_CODR = Digi0Alloc[Input] - -#define INPUTClearDigi1(Input) *AT91C_PIOA_CODR = Digi1Alloc[Input] - -#define INPUTReadDigi0(Input, Data) if ((*AT91C_PIOA_PDSR) & Digi0Alloc[Input]) \ - { \ - *Data |= 0x00000001; \ - } \ - else \ - { \ - *Data &= ~0x00000001; \ - } -#define INPUTReadDigi1(Input, Data) if ((*AT91C_PIOA_PDSR) & Digi1Alloc[Input]) \ - { \ - *Data |= 0x00000002; \ - } \ - else \ - { \ - *Data &= ~0x00000002; \ - } - -#define INPUTClkHigh(Port) INPUTSetDigi0(Port); \ - INPUTSetOutDigi0(Port); \ - rInputWait2uS() - -#define INPUTClkLow(Port) INPUTClearDigi0(Port); \ - INPUTSetOutDigi0(Port); \ - rInputWait2uS() - -#define COLORClkInput *AT91C_PIOA_ODR = ColorClkDef - -#define UPDATEAllColors(Vals, Status){\ - ULONG ADDef; \ - ADDef = 0; \ - ColorClkDef = 0; \ - if (0x01 & Status) \ - { \ - ADDef |= ADPinDef[0]; \ - ColorClkDef |= Digi0Alloc[0]; \ - if ((*AT91C_PIOA_PDSR) & Digi0Alloc[0]) \ - { \ - ColorReset[0] = TRUE; \ - } \ - } \ - if (0x02 & Status) \ - { \ - ADDef |= ADPinDef[1]; \ - ColorClkDef |= Digi0Alloc[1]; \ - if ((*AT91C_PIOA_PDSR) & Digi0Alloc[1]) \ - { \ - ColorReset[1] = TRUE; \ - } \ - } \ - if (0x04 & Status) \ - { \ - ADDef |= ADPinDef[2]; \ - ColorClkDef |= Digi0Alloc[2]; \ - if ((*AT91C_PIOA_PDSR) & Digi0Alloc[2]) \ - { \ - ColorReset[2] = TRUE; \ - } \ - } \ - if (0x08 & Status) \ - { \ - ADDef |= ADPinDef[3]; \ - ColorClkDef |= Digi0Alloc[3]; \ - if ((*AT91C_PIOA_PDSR) & Digi0Alloc[3]) \ - { \ - ColorReset[3] = TRUE; \ - } \ - } \ - *AT91C_PIOA_OER = ColorClkDef; \ - *AT91C_ADC_CHER = ADDef; \ - GetAdVals(Vals, BLANK, Status); \ - *AT91C_PIOA_SODR = ColorClkDef; \ - rInputWait20uS(); \ - GetAdVals(Vals, RED, Status); \ - *AT91C_PIOA_CODR = ColorClkDef; \ - rInputWait20uS(); \ - GetAdVals(Vals, GREEN, Status); \ - *AT91C_PIOA_SODR = ColorClkDef; \ - rInputWait20uS(); \ - GetAdVals(Vals, BLUE, Status); \ - *AT91C_PIOA_CODR = ColorClkDef; \ - *AT91C_ADC_CHDR = ADDef; \ - } - -#define UPDATELed(Port, Col, Status) { \ - rInputSingleADC(Port, Col); \ - if ((*AT91C_PIOA_PDSR) & Digi0Alloc[Port]) \ - { \ - ColorReset[Port] = TRUE; \ - } \ - CHECKColorState(Port, Status); \ - } - -#define SETClkHi(Port) INPUTClkHigh(Port) \ - -#define COLORTx(Port, Data) { \ - UBYTE BitCnt; \ - BitCnt = 0; \ - while(BitCnt++ < 8) \ - { \ - INPUTClkHigh(Port); \ - if (Data & 0x01) \ - { \ - INPUTSetDigi1(Port); \ - } \ - else \ - { \ - INPUTClearDigi1(Port); \ - } \ - rInputWait30uS(); \ - Data >>= 1; \ - INPUTClkLow(Port); \ - rInputWait30uS(); \ - } \ - } - -#define CALDataRead(Port, pData) {\ - UBYTE BitCnt; \ - UBYTE Data; \ - BitCnt = 0; \ - INPUTClkHigh(Port); \ - rInputWait2uS(); \ - while(BitCnt++ < 8) \ - { \ - INPUTClkHigh(Port); \ - rInputWait2uS(); \ - rInputWait2uS(); \ - INPUTClkLow(Port); \ - Data >>= 1; \ - if ((*AT91C_PIOA_PDSR) & Digi1Alloc[Port])\ - { \ - Data |= 0x80; \ - } \ - rInputWait2uS(); \ - } \ - *pData = Data; \ - } - -#define CHECKColorState(Port, Status) {\ - Status = TRUE; \ - if ((IoFromAvr.AdValue[Port] > 50) || (TRUE == ColorReset[Port])) \ - { \ - Status = FALSE; \ - ColorReset[Port] = FALSE; \ - } \ - } - - -#define INPUTExit { \ - UBYTE Tmp; \ - *AT91C_ADC_CHDR = (AT91C_ADC_CH1 | AT91C_ADC_CH2 | AT91C_ADC_CH3 | AT91C_ADC_CH7);\ - for (Tmp = 0; Tmp < NO_OF_INPUTS; Tmp++) \ - { \ - INPUTSetInDigi0(Tmp); \ - INPUTSetInDigi1(Tmp); \ - } \ - } - -#define CLEARColor100msTimer(No) ColorTimer[No] = (*AT91C_PITC_PIIR);\ - -#define COLOR100msStatus(No,V) V = FALSE;\ - if (((*AT91C_PITC_PIIR) - ColorTimer[No]) > TIME100MS)\ - {\ - V = TRUE;\ - } - - - -void rInputSingleADC(UBYTE Port, UWORD *Val) -{ - *Val = *AT91C_ADC_LCDR; - *AT91C_ADC_CHER = ADPinDef[Port]; - ADStart; - while(!((*AT91C_ADC_SR) & AT91C_ADC_DRDY)); - *Val = *AT91C_ADC_LCDR; - *AT91C_ADC_CHDR = ADPinDef[Port]; -} - -void GetAdVals(COLORSTRUCT *pColStruct, UBYTE Color, UBYTE Status) -{ - UBYTE ChCnt; - ADStart; - for(ChCnt = 0; ChCnt < NO_OF_INPUTS; ChCnt++) - { - if (Status & (0x01 << ChCnt)) - { - while(!((*AT91C_ADC_SR) & ADPinDef[ChCnt])); - pColStruct[ChCnt].ADRaw[Color] = *ADValRegs[ChCnt]; - } - } - ADStart; - for(ChCnt = 0; ChCnt < NO_OF_INPUTS; ChCnt++) - { - if (Status & (0x01 << ChCnt)) - { - while(!((*AT91C_ADC_SR) & ADPinDef[ChCnt])); - pColStruct[ChCnt].ADRaw[Color] += *ADValRegs[ChCnt]; - pColStruct[ChCnt].ADRaw[Color] = (pColStruct[ChCnt].ADRaw[Color])>>1; - } - } -} - -void rInputWait2uS(void) -{ - ULONG PitTmr; - PitTmr = (*AT91C_PITC_PIIR); - while (((*AT91C_PITC_PIIR) - PitTmr) < TIME2US); -} - -void rInputWait20uS(void) -{ - ULONG PitTmr; - PitTmr = (*AT91C_PITC_PIIR); - while (((*AT91C_PITC_PIIR) - PitTmr) < TIME20US); -} - -void rInputWait30uS(void) -{ - ULONG PitTmr; - PitTmr = (*AT91C_PITC_PIIR); - while (((*AT91C_PITC_PIIR) - PitTmr) < TIME30US); -} - -#endif - -#ifdef PCWIN - -#endif diff --git a/AT91SAM7S256/Source/d_ioctrl.c b/AT91SAM7S256/Source/d_ioctrl.c deleted file mode 100644 index 2506172..0000000 --- a/AT91SAM7S256/Source/d_ioctrl.c +++ /dev/null @@ -1,47 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 5-12-07 15:23 $ -// -// Filename $Workfile:: d_ioctrl.c $ -// -// Version $Revision:: 2 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_ioct $ -// -// Platform C -// - - -#include -#include "stdconst.h" -#include "m_sched.h" -#include "d_ioctrl.h" -#include "d_ioctrl.r" - - -void dIOCtrlInit(void) -{ - IOCTRLInit; -} - -void dIOCtrlSetPower(UBYTE Power) -{ - INSERTPower(Power); -} - -void dIOCtrlSetPwm(UBYTE Pwm) -{ - INSERTPwm(Pwm); -} - -void dIOCtrlTransfer(void) -{ - I2CTransfer; -} - -void dIOCtrlExit(void) -{ - IOCTRLExit; -} - diff --git a/AT91SAM7S256/Source/d_ioctrl.h b/AT91SAM7S256/Source/d_ioctrl.h deleted file mode 100644 index 4b7ae4f..0000000 --- a/AT91SAM7S256/Source/d_ioctrl.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: d_ioctrl.h $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_ioct $ -// -// Platform C -// - -#ifndef D_AVRCOMM -#define D_AVRCOMM - -void dIOCtrlInit(void); -void dIOCtrlExit(void); - -void dIOCtrlSetPower(UBYTE Power); -void dIOCtrlSetPwm(UBYTE Pwm); -void dIOCtrlTransfer(void); - -#endif diff --git a/AT91SAM7S256/Source/d_ioctrl.r b/AT91SAM7S256/Source/d_ioctrl.r deleted file mode 100644 index 1071276..0000000 --- a/AT91SAM7S256/Source/d_ioctrl.r +++ /dev/null @@ -1,237 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 7-12-07 14:09 $ -// -// Filename $Workfile:: d_ioctrl.r $ -// -// Version $Revision:: 4 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_ioct $ -// -// Platform C -// - - -#ifdef SAM7S256 - -extern void I2cHandler(void); - -enum -{ - I2C_IDLE = 1, - I2C_ERROR = 2, - I2C_TX = 3, - I2C_RX = 4 -}; - -#define NO_TO_TX BYTES_TO_TX + 1 -#define NO_TO_RX BYTES_TO_RX + 1 -#define TIMEOUT (((OSC/16)/1000)*30) /* 100 ms timeout on I2C*/ -#define I2CCLK 400000L -#define TIME400KHZ (((OSC/16L)/(I2CCLK * 2)) + 1) -#define CLDIV (((OSC/I2CCLK)/2)-3) -#define DEVICE_ADR 0x01 - - -static UBYTE *pIrq; -static UBYTE volatile Cnt; -static UBYTE I2cStatus; -static UBYTE I2cLastStatus; -static UBYTE I2cInBuffer[NO_TO_RX]; -static UBYTE I2cOutBuffer[COPYRIGHTSTRINGLENGTH + 1]; -static UBYTE RxSum; -static ULONG I2CTimerValue; - - -#define DISABLEI2cIrqs *AT91C_TWI_IDR = 0x000001C7 -#define ISSUEStopCond *AT91C_TWI_CR = AT91C_TWI_STOP -#define INSERTPower(Power) IoToAvr.Power = Power -#define INSERTPwm(Pwm) IoToAvr.PwmFreq = Pwm -#define SETTime I2CTimerValue = ((*AT91C_PITC_PIIR) & AT91C_PITC_CPIV) - - -#define DISABLETwi *AT91C_PIOA_PPUDR = (AT91C_PA4_TWCK | AT91C_PA3_TWD);/* no pull up */\ - *AT91C_PIOA_MDER = (AT91C_PA4_TWCK | AT91C_PA3_TWD);/* SCL + SDA is open drain*/\ - *AT91C_PIOA_SODR = (AT91C_PA4_TWCK | AT91C_PA3_TWD);/* SCL + SDA is high */\ - *AT91C_PIOA_OER = (AT91C_PA4_TWCK | AT91C_PA3_TWD);/* SCL + SDA is output */\ - *AT91C_PIOA_PER = (AT91C_PA4_TWCK | AT91C_PA3_TWD);/* Disable peripheal */\ - - -#define STARTIrqTx I2cStatus = I2C_TX;\ - I2cLastStatus = I2C_TX;\ - pIrq = I2cOutBuffer;\ - *AT91C_TWI_CR = AT91C_TWI_MSEN;\ - *AT91C_TWI_MMR = (AT91C_TWI_IADRSZ_NO | (DEVICE_ADR << 16)); /* no int. adr, write dir */\ - *AT91C_TWI_IER = 0x00000104; /* Enable TX related irq */\ - *AT91C_TWI_THR = *pIrq - - -#define WAITClk {\ - ULONG PitTmr;\ - PitTmr = (*AT91C_PITC_PIIR & AT91C_PITC_CPIV) + TIME400KHZ;\ - if (PitTmr >= (*AT91C_PITC_PIMR & AT91C_PITC_CPIV))\ - {\ - PitTmr -= (*AT91C_PITC_PIMR & AT91C_PITC_CPIV);\ - }\ - while ((*AT91C_PITC_PIIR & AT91C_PITC_CPIV) < PitTmr);\ - } - - -#define RESETI2c {\ - UBYTE Tmp;\ - DISABLETwi;\ - Tmp = 0;\ - /* Clock minimum 9 times and both SCK and SDA should be high */\ - while((!(*AT91C_PIOA_PDSR & AT91C_PA3_TWD)) || (Tmp <= 9))\ - {\ - if ((*AT91C_PIOA_PDSR) & AT91C_PA4_TWCK) /* Clk strectching? */\ - {\ - *AT91C_PIOA_CODR = AT91C_PA4_TWCK; /* SCL is low */\ - WAITClk;\ - *AT91C_PIOA_SODR = AT91C_PA4_TWCK; /* SCL is high */\ - WAITClk;\ - Tmp++;\ - }\ - }\ - *AT91C_TWI_CR = AT91C_TWI_MSDIS;\ - *AT91C_TWI_CR = AT91C_TWI_SWRST;\ - *AT91C_PIOA_ASR = (AT91C_PA4_TWCK | AT91C_PA3_TWD); /* Sel. per. A */\ - *AT91C_PIOA_PDR = (AT91C_PA4_TWCK | AT91C_PA3_TWD); /* Sel. per on pins*/\ - } - - -#define IOCTRLInit *AT91C_AIC_IDCR = (1L< -#include - -#define FILEVERSION (0x0000010DL) - -#define MAX_FILES ((FILETABLE_SIZE) - 1) /* Last file entry is used for file version*/ -#define FILEVERSIONINDEX ((FILETABLE_SIZE) - 1) /* Last file entry is used for file version*/ -#define MAX_WRITE_BUFFERS 4 -#define FLASHOFFSET (0x100000L) - -#define IS_LOADER_ERR(LStatus) (((LStatus) & 0xFF00) != SUCCESS) -#define SECTORINDEXUSERFLASH ((STARTOFUSERFLASH & ~FLASHOFFSET)/256/32) -#define SECTORPOINTERUSERFLASH (((STARTOFUSERFLASH & ~FLASHOFFSET) - ((SECTORINDEXUSERFLASH * 32) * 256))/256) - -typedef struct -{ - const UBYTE *pFlash; - const UWORD *pSectorNo; - ULONG ReadLength; - ULONG DataLength; - ULONG FileDlPtr; - UBYTE SearchStr[FILENAME_SIZE]; - UWORD FileIndex; - UWORD CheckSum; - UBYTE SearchType; - UBYTE Status; - UBYTE FileType; - UBYTE WriteBufNo; -}HANDLE; - -typedef struct -{ - ULONG Buf[SECTORSIZE/4]; - UBYTE BufIndex; - UBYTE Status; -}WRITEBUF; - -static HANDLE HandleTable[MAX_HANDLES]; -static WRITEBUF WriteBuffer[MAX_WRITE_BUFFERS]; -static ULONG SectorTable[NOOFSECTORS>>5]; -static FILEHEADER Header; -static ULONG FreeUserFlash; -static UWORD FreeSectors; - -void dLoaderUpdateSectorTable(void); -UWORD dLoaderGetFreeHandle(void); -const UBYTE * dLoaderGetNextSectorPtr(UBYTE Handle); -ULONG dLoaderReturnFreeFlash(void); -UWORD dLoaderAllocateHeader(UWORD Handle, ULONG *FileStartAdr, FILEHEADER *pHeader, UWORD HeaderByteSize, UWORD CompleteFileSectorSize); -UWORD dLoaderFlashFileHeader(UWORD Handle, ULONG FileStartAdr, FILEHEADER *pHeader, UWORD HeaderByteSize); -UWORD dLoaderFindFirstSector(UBYTE Type, UWORD SectorCount, UWORD *pSector); -UWORD dLoaderAllocateWriteBuffer(UWORD Handle); -UWORD dLoaderSetFilePointer(UWORD Handle, ULONG BytePtr, const UBYTE **pData); -UWORD dLoaderGetSectorNumber(ULONG Adr); -void dLoaderCheckVersion(void); -UWORD dLoaderCheckHandle(UWORD Handle, UBYTE Operation); -ULONG dLoaderCalcFreeFileSpace(UWORD NosOfFreeSectors); -UWORD dLoaderCheckDownload(UBYTE *pName); -UWORD dLoaderAvailFileNo(void); - - -void dLoaderInit(void) -{ - UWORD Tmp; - - LOADERInit; - - /* Clear handle table */ - for (Tmp = 0; Tmp < MAX_HANDLES; Tmp++) - { - HandleTable[Tmp].Status = FREE; - HandleTable[Tmp].WriteBufNo = FREEBUFNO; - } - - /* Clear write buffers */ - for (Tmp = 0; Tmp < MAX_WRITE_BUFFERS; Tmp++) - { - WriteBuffer[Tmp].Status = FREE; - } - - dLoaderCheckVersion(); - dLoaderUpdateSectorTable(); -} - - -UWORD dLoaderAvailFileNo(void) -{ - UBYTE Tmp, Tmp2; - UWORD ReturnVal; - - ReturnVal = NOMOREFILES; - Tmp2 = 0; - for(Tmp = 0; Tmp < MAX_HANDLES; Tmp++) - { - - /* Check for files allready downloading except datafiles as the have entered their */ - /* filepointer in the filepointer table at begin of download */ - if ((DOWNLOADING == HandleTable[Tmp].Status) && (DATAFILE != HandleTable[Tmp].FileType)) - { - Tmp2++; - } - } - if ((0xFFFFFFFF == FILEPTRTABLE[(MAX_FILES - 1) - Tmp2]) || (0 == FILEPTRTABLE[(MAX_FILES - 1) - Tmp2])) - { - ReturnVal = SUCCESS; - } - return(ReturnVal); -} - - -void dLoaderWriteFilePtrTable(ULONG *RamFilePtrTable) -{ - UWORD TmpTableSize; - - /* FILETABLE_SIZE is in LONG */ - TmpTableSize = (FILETABLE_SIZE * 4); - while(TmpTableSize) - { - TmpTableSize -= SECTORSIZE; - dLoaderWritePage((ULONG)FILEPTRTABLE + TmpTableSize, SECTORSIZE, RamFilePtrTable + (TmpTableSize/4)); - } -} - - -UWORD dLoaderInsertPtrTable(const UBYTE *pAdr, UWORD Handle) -{ - UWORD TmpCnt; - UWORD Status; - ULONG PtrTable[FILETABLE_SIZE]; - - /* It is possible to add the file as checking for number of files */ - /* is done when initiating the file download */ - memset(PtrTable, 0, sizeof(PtrTable)); - TmpCnt = MAX_FILES - 1; - while(TmpCnt) - { - - /* TmpCnt-- first because you want to copy from index 0 */ - TmpCnt--; - PtrTable[TmpCnt + 1] = FILEPTRTABLE[TmpCnt]; - } - - /* Copy the new file in position 0 */ - PtrTable[0] = (ULONG)pAdr; - - /* Add the File version to the top of the file list */ - PtrTable[FILEVERSIONINDEX] = FILEPTRTABLE[FILEVERSIONINDEX]; - - /* Write the file pointer table to flash */ - dLoaderWriteFilePtrTable(PtrTable); - - /* FileIndex in HandleTable should be incremented by one - new file index is 0 */ - for (TmpCnt = 0; TmpCnt < MAX_HANDLES; TmpCnt++) - { - if (HandleTable[TmpCnt].Status != FREE) - { - (HandleTable[TmpCnt].FileIndex)++; - } - } - HandleTable[Handle].FileIndex = 0; - Status = SUCCESS | Handle; - - return(Status); -} - - -UWORD dLoaderDeleteFilePtr(UWORD Handle) -{ - UWORD ErrorCode; - UWORD LongCnt; - ULONG PtrTable[FILETABLE_SIZE]; - - ErrorCode = SUCCESS; - if (0xFFFFFFFF != FILEPTRTABLE[HandleTable[Handle].FileIndex]) - { - ErrorCode = dLoaderCheckFiles(Handle); - if (0x8000 > ErrorCode) - { - for (LongCnt = 0; LongCnt < (HandleTable[Handle].FileIndex); LongCnt++) - { - PtrTable[LongCnt] = FILEPTRTABLE[LongCnt]; - } - - /* Skip the file that has to be deleted "LongCnt + 1" */ - for ( ; LongCnt < (MAX_FILES - 1); LongCnt++) - { - PtrTable[LongCnt] = FILEPTRTABLE[LongCnt+1]; - } - - /* The top file entry is now free */ - PtrTable[MAX_FILES - 1] = 0xFFFFFFFF; - - /* Insert the file version */ - PtrTable[MAX_FILES] = FILEPTRTABLE[MAX_FILES]; - - /* Write the file pointer table back into flash */ - dLoaderWriteFilePtrTable(PtrTable); - dLoaderUpdateSectorTable(); - - /* Update the HandleTable[].FileIndex */ - for (LongCnt = 0; LongCnt < MAX_HANDLES; LongCnt++) - { - - /* FileIndex must not be decremented for to the file to be deleted (when Handle = LongCnt)*/ - if ((HandleTable[Handle].FileIndex < HandleTable[LongCnt].FileIndex) && (FREE != HandleTable[LongCnt].Status)) - { - (HandleTable[LongCnt].FileIndex)--; - } - } - } - } - else - { - ErrorCode = FILENOTFOUND; - } - return(ErrorCode | Handle); -} - - -void dLoaderDeleteAllFiles(void) -{ - ULONG Tmp; - ULONG PtrTable[FILETABLE_SIZE]; - - /* Close all handles - all files is to be wiped out */ - for (Tmp = 0; Tmp < MAX_HANDLES; Tmp++) - { - dLoaderCloseHandle(Tmp); - } - - for (Tmp = ((STARTOFUSERFLASH-FLASHOFFSET)/SECTORSIZE); Tmp < (SIZEOFFLASH/SECTORSIZE); Tmp++) - { - dLoaderErasePage(Tmp<>5] |= (0x1 << (SectorNo & 0x001F)); - Tmp += (SECTORSIZE >> 2); - } - - for (Tmp = 0; Tmp < MAX_FILES; Tmp++) - { - if ((0xFFFFFFFF != FILEPTRTABLE[Tmp]) && (0x00000000 != FILEPTRTABLE[Tmp])) - { - pFile = (const FILEHEADER *) FILEPTRTABLE[Tmp]; - - /* This is necessary if the start address is at the first address in an sector */ - SectorNo = dLoaderGetSectorNumber((ULONG)pFile->FileStartAdr); - SectorTable[SectorNo>>5] |= (0x1 << (SectorNo & 0x001F)); - - /* This is necessary as the first sector (where the fileheader is) is not */ - /* included in the sector table */ - SectorNo = dLoaderGetSectorNumber((ULONG)FILEPTRTABLE[Tmp]); - SectorTable[SectorNo>>5] |= (0x1 << (SectorNo & 0x001F)); - - /* First Sector with data has been allocated add this as the initial */ - /* file size */ - FileSize = SECTORSIZE - ((pFile->FileStartAdr) & (SECTORSIZE-1)) ; - pSectorTable = pFile->FileSectorTable; - while((FileSize < (pFile->FileSize)) && (NOOFSECTORS > (*pSectorTable))) - { - SectorTable[(*pSectorTable)>>5] |= (0x1 << ((*pSectorTable) & 0x1F)); - if (0 == ((ULONG)(pSectorTable + 1) & (SECTORSIZE-1))) - { - pSectorTable = (UWORD*)(((ULONG)(*pSectorTable) << SECTORSIZESHIFT) | FLASHOFFSET); - } - else - { - *pSectorTable++; - FileSize += SECTORSIZE; - } - } - } - } - FreeUserFlash = dLoaderReturnFreeFlash(); -} - - -UWORD dLoaderCreateFileHeader(ULONG FileSize, UBYTE *pName, UBYTE LinearState, UBYTE FileType) -{ - UWORD HeaderByteSize; - ULONG FileStartAdr; - ULONG CompleteFileByteSize; - UWORD Handle; - UBYTE Name[FILENAME_SIZE]; - ULONG FileLength; - ULONG DataLength; - UWORD ErrorCode; - UWORD CompleteSectorNo; - UWORD Tmp; - - memset(&(Header.FileName), 0, sizeof(Header.FileName)); - memset(&(Header.FileSectorTable), 0xFF, sizeof(Header.FileSectorTable)); - - ErrorCode = dLoaderFind(pName, Name, &FileLength, &DataLength, (UBYTE)BUSY); - Handle = ErrorCode & 0x00FF; - if (SUCCESS == (ErrorCode & 0xFF00)) - { - ErrorCode |= FILEEXISTS; - } - if (FILENOTFOUND == (ErrorCode & 0xFF00)) - { - - /* Here check for the download buffers for a matching download */ - /* in progress */ - ErrorCode &= 0x00FF; - ErrorCode = dLoaderCheckDownload(pName); - - if (0x8000 > ErrorCode) - { - - /* Check for file overflow */ - ErrorCode = dLoaderAvailFileNo(); - if (0x8000 > ErrorCode) - { - - ErrorCode = dLoaderAllocateWriteBuffer(Handle); - if (0x8000 > ErrorCode) - { - - dLoaderCopyFileName((Header.FileName), pName); - HandleTable[Handle].pSectorNo = 0; - HandleTable[Handle].DataLength = FileSize; /* used for end of file detection */ - Header.FileSize = FileSize; /* used to program into flash */ - if (DATAFILE == FileType) - { - Header.DataSize = 0; - } - else - { - Header.DataSize = FileSize; - } - HandleTable[Handle].FileType = FileType | LinearState; /* if it is a datafile it can be stopped */ - Header.FileType = FileType | LinearState; /* FileType included for future appending */ - - /* File body size calculation*/ - CompleteFileByteSize = FileSize; - - /* Add the the fixed header to the fixed size */ - CompleteFileByteSize += HEADERFIXEDSIZE; - - /* Find the number of sectors used by the fixed file size */ - CompleteSectorNo = (CompleteFileByteSize - 1) >> SECTORSIZESHIFT; - - /* Add the size taken by the sectortable */ - CompleteFileByteSize += (CompleteSectorNo << 1); - - /* Recalc the number of sectors - to see wether the sectortable has caused */ - /* the sectornumber to encrease */ - Tmp = ((CompleteFileByteSize - 1) >> SECTORSIZESHIFT); - - /* Substract from the original sectors used - Tmp holds the encreased number*/ - Tmp -= CompleteSectorNo; - if (Tmp) - { - /* The sectortable takes up more than one sector */ - CompleteFileByteSize += Tmp << 1; - CompleteSectorNo += Tmp; - } - - HeaderByteSize = CompleteFileByteSize - FileSize; - - if (HeaderByteSize & 0x0003) - { - /* Header size is not a multiplum of 4 - now make it a mul 4 */ - HeaderByteSize += (0x0004 - (HeaderByteSize & 0x0003)); - } - - if (FileSize <= FreeUserFlash) - { - - /* Allocate file header */ - Tmp = (((CompleteFileByteSize - 1) >> SECTORSIZESHIFT) + 1); - Handle = dLoaderAllocateHeader(Handle, &FileStartAdr, &Header, HeaderByteSize, Tmp); - if (Handle < 0x8000) - { - dLoaderFlashFileHeader(Handle, FileStartAdr, &Header, HeaderByteSize); - - /* If this is a datafile then add the filepointer to the filepointer table */ - /* now as the datafile do not need to have a special size to be valid */ - if (DATAFILE & HandleTable[Handle].FileType) - { - ErrorCode = dLoaderInsertPtrTable((const UBYTE *)HandleTable[Handle].FileDlPtr, Handle); - } - FreeSectors -= Tmp; - FreeUserFlash = dLoaderCalcFreeFileSpace(FreeSectors); - HandleTable[Handle].Status = DOWNLOADING; - } - } - else - { - ErrorCode = NOSPACE; - } - } - } - } - } - - return(ErrorCode | Handle); -} - - -UWORD dLoaderWriteData(UWORD Handle, UBYTE *pBuf, UWORD *pLen) -{ - UWORD Tmp; - UBYTE *pSectorBuf; - - Handle = dLoaderCheckHandle(Handle, DOWNLOADING); - if (0x8000 > Handle) - { - - if (*pLen > HandleTable[Handle].DataLength) - { - - /* Write request exceeds filesize - only flash up to filesize*/ - *pLen = HandleTable[Handle].DataLength; - WriteBuffer[HandleTable[Handle].WriteBufNo].Status = DLERROR; /* save error untill close handle */ - } - - pSectorBuf = (UBYTE *)WriteBuffer[HandleTable[Handle].WriteBufNo].Buf; - for(Tmp = 0; Tmp < *pLen; Tmp++) - { - pSectorBuf[WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex] = pBuf[Tmp]; - if ((WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex) >= (SECTORSIZE-1)) - { - dLoaderWritePage(((ULONG)HandleTable[Handle].pFlash & ~(SECTORSIZE - 1)), SECTORSIZE, WriteBuffer[HandleTable[Handle].WriteBufNo].Buf); - WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex = 0; - HandleTable[Handle].pFlash = dLoaderGetNextSectorPtr(Handle); - memset(WriteBuffer[HandleTable[Handle].WriteBufNo].Buf, 0xFF, sizeof(WriteBuffer[0].Buf)); - } - else - { - (WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex)++; - } - } - HandleTable[Handle].DataLength -= *pLen; - - /* Check for correct end of file */ - if (0 == HandleTable[Handle].DataLength) - { - if ((WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex) != 0) - { - - /* write the last data into the file */ - dLoaderWritePage(((ULONG)HandleTable[Handle].pFlash & ~(SECTORSIZE - 1)), WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex, WriteBuffer[HandleTable[Handle].WriteBufNo].Buf); - WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex = 0; - } - } - } - else - { - *pLen = 0; - } - - if (DLERROR == WriteBuffer[HandleTable[Handle].WriteBufNo].Status) - { - - /* DLERROR set due to over flow a file - EOFEXSPECTED should be set */ - /* for repeated overflow requests */ - Handle |= EOFEXSPECTED; - } - return(Handle); -} - - -UWORD dLoaderGetFreeHandle(void) -{ - UBYTE Tmp; - UWORD Handle; - - Handle = NOMOREHANDLES; - for(Tmp = 0; Tmp < MAX_HANDLES; Tmp++) - { - if (FREE == HandleTable[Tmp].Status) - { - HandleTable[Tmp].Status = BUSY; - Handle = 0; /* Clear NOMOREHANDLES */ - Handle = Tmp; - Tmp = MAX_HANDLES; - } - } - return(Handle); -} - -const UBYTE * dLoaderGetNextSectorPtr(UBYTE Handle) -{ - const UBYTE *pAdr; - - /* Check for the last entry in a sector - if so, */ - /* then this is the sector number on the next sector table */ - if (!((ULONG)(HandleTable[Handle].pSectorNo + 1) & (SECTORSIZE-1))) - { - HandleTable[Handle].pSectorNo = (const UWORD *)(((ULONG)(*(HandleTable[Handle].pSectorNo)) << SECTORSIZESHIFT) | FLASHOFFSET); - } - - /* If pointing at an illegal adr then set it to NULL */ - if (SIZEOFFLASH < (ULONG)((ULONG)(HandleTable[Handle].pSectorNo) & ~FLASHOFFSET)) - { - pAdr = NULL; - } - else - { - pAdr = (const UBYTE *)(((ULONG)(*(HandleTable[Handle].pSectorNo)) << SECTORSIZESHIFT) | FLASHOFFSET); - } - - (HandleTable[Handle].pSectorNo)++; - return(pAdr); -} - -UWORD dLoaderCloseHandle(UWORD Handle) -{ - UWORD RtnStatus; - FILEHEADER *TmpFileHeader; - - RtnStatus = Handle; - - /* if it is a normal handle or handle closed due to an error then error must be different */ - /* from the no more handles available error (else you would delete a used handle) */ - if (((0x8000 > Handle) || (NOMOREHANDLES != (Handle & 0xFF00))) && ((UBYTE)Handle < MAX_HANDLES)) - { - Handle &= 0x00FF; - if (FREE == HandleTable[Handle].Status) - { - RtnStatus |= HANDLEALREADYCLOSED; - } - else - { - - /* Handle was NOT free - now close it */ - if (DOWNLOADING == HandleTable[Handle].Status) - { - if (DATAFILE & HandleTable[Handle].FileType) - { - - /* This is a Datafile that should be closed and this is a legal action */ - /* 1. Write the data from the writebuffer into flash */ - /* 2. Update the Datalength in the file header */ - /* This takes minimum 8 mS (2 page writes into flash) */ - - if (WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex) - { - - /* There are databytes in the writebuffer write them into flash */ - dLoaderWritePage(((ULONG)HandleTable[Handle].pFlash & ~(SECTORSIZE - 1)), WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex, WriteBuffer[HandleTable[Handle].WriteBufNo].Buf); - } - - /* Now the databuffer is free now use if for a buffer for the fileheader*/ - memcpy(WriteBuffer[HandleTable[Handle].WriteBufNo].Buf, (void const*)HandleTable[Handle].FileDlPtr, SECTORSIZE); - TmpFileHeader = (FILEHEADER *) WriteBuffer[HandleTable[Handle].WriteBufNo].Buf; - TmpFileHeader->DataSize = TmpFileHeader->FileSize - HandleTable[Handle].DataLength; - dLoaderWritePage(((ULONG)HandleTable[Handle].FileDlPtr & ~(SECTORSIZE - 1)), SECTORSIZE, WriteBuffer[HandleTable[Handle].WriteBufNo].Buf); - } - else - { - - /* This is a system file being closed now update the file pointer table if no error and complete file written */ - if ((DLERROR != WriteBuffer[HandleTable[Handle].WriteBufNo].Status) && (0 == HandleTable[Handle].DataLength)) - { - - /* no error durig download - add the file pointer to the file pointer table */ - Handle = dLoaderInsertPtrTable((const UBYTE *) HandleTable[Handle].FileDlPtr, Handle); - } - else - { - - /* an error has occured during download - now clean up the mess... */ - dLoaderUpdateSectorTable(); - } - } - } - if (HandleTable[Handle].WriteBufNo != FREEBUFNO) - { - WriteBuffer[HandleTable[Handle].WriteBufNo].Status = FREE; - HandleTable[Handle].WriteBufNo = FREEBUFNO; - } - HandleTable[Handle].Status = FREE; - } - } - return(RtnStatus); -} - - -UWORD dLoaderOpenRead(UBYTE *pFileName, ULONG *pLength) -{ - UWORD Handle; - UBYTE Name[16]; - const FILEHEADER *TmpHeader; - ULONG FileLength; - ULONG DataLength; - - Handle = dLoaderFind(pFileName, Name, &FileLength, &DataLength, (UBYTE)BUSY); - if (0x8000 > Handle) - { - if (FileLength) - { - TmpHeader = (FILEHEADER const *)(FILEPTRTABLE[HandleTable[Handle].FileIndex]); - HandleTable[Handle].pFlash = (const UBYTE *)TmpHeader->FileStartAdr; - HandleTable[Handle].pSectorNo = TmpHeader->FileSectorTable; - HandleTable[Handle].DataLength = TmpHeader->DataSize; - HandleTable[Handle].ReadLength = 0; - *pLength = TmpHeader->DataSize; - } - else - { - Handle = FILENOTFOUND; - } - } - return(Handle); -} - -UWORD dLoaderRead(UBYTE Handle, UBYTE *pBuffer, ULONG *pLength) -{ - UWORD ByteCnt, Status; - - Status = dLoaderCheckHandle(Handle, BUSY); - if (0x8000 > Status) - { - Status = Handle; - ByteCnt = 0; - while (ByteCnt < *pLength) - { - if (HandleTable[Handle].DataLength <= HandleTable[Handle].ReadLength) - { - *pLength = ByteCnt; - Status |= ENDOFFILE; - } - else - { - *pBuffer = *(HandleTable[Handle].pFlash); - pBuffer++; - ByteCnt++; - HandleTable[Handle].pFlash++; - HandleTable[Handle].ReadLength++; - if (!((ULONG)(HandleTable[Handle].pFlash) & (SECTORSIZE-1))) - { - HandleTable[Handle].pFlash = dLoaderGetNextSectorPtr(Handle); - } - } - } - } - return(Status); -} - -UWORD dLoaderDelete(UBYTE *pFile) -{ - UWORD LStatus; - ULONG FileLength; - ULONG DataLength; - UBYTE Name[FILENAME_LENGTH + 1]; - - LStatus = dLoaderFind(pFile, Name, &FileLength, &DataLength, (UBYTE)BUSY); - - if (!IS_LOADER_ERR(LStatus)) - { - LStatus = dLoaderDeleteFilePtr((UBYTE)LStatus); - } - - dLoaderCloseHandle(LStatus); - - return(LStatus); -} - -UWORD dLoaderFind(UBYTE *pFind, UBYTE *pFound, ULONG *pFileLength, ULONG *pDataLength, UBYTE Session) -{ - UWORD Handle; - - Handle = dLoaderGetFreeHandle(); - if (Handle < 0x8000) - { - if (FILENAME_LENGTH < strlen((const char*)pFind)) - { - Handle |= ILLEGALFILENAME; - } - else - { - HandleTable[Handle].FileIndex = 0xFFFF; - HandleTable[Handle].Status = Session; - dLoaderInsertSearchStr((HandleTable[Handle].SearchStr), pFind, &(HandleTable[Handle].SearchType)); - Handle = dLoaderFindNext(Handle, pFound, pFileLength, pDataLength); - } - } - - return(Handle); -} - -UWORD dLoaderFindNext(UWORD Handle, UBYTE *pFound, ULONG *pFileLength, ULONG *pDataLength) -{ - UBYTE Tmp; - UWORD ReturnVal; - FILEHEADER *pHeader; - - *pFileLength = 0; - ReturnVal = Handle | FILENOTFOUND; - - - for (Tmp = ((HandleTable[Handle].FileIndex) + 1); Tmp < MAX_FILES; Tmp++) - { - if (0xFFFFFFFF != FILEPTRTABLE[Tmp]) - { - if (SUCCESS == dLoaderCheckName((UBYTE*)FILEPTRTABLE[Tmp], HandleTable[Handle].SearchStr, HandleTable[Handle].SearchType)) - { - HandleTable[Handle].FileIndex = Tmp; - Tmp = MAX_FILES; - ReturnVal = Handle; - } - } - } - if (0x8000 > ReturnVal) - { - pHeader = (FILEHEADER *)FILEPTRTABLE[HandleTable[Handle].FileIndex]; - if (NULL != pFileLength) - { - *pFileLength = pHeader->FileSize; - } - if (NULL != pDataLength) - { - *pDataLength = pHeader->DataSize; - } - if (NULL != pFound) - { - dLoaderCopyFileName(pFound, (UBYTE *)pHeader->FileName); - } - } - return(ReturnVal); -} - - -ULONG dLoaderReturnFreeFlash(void) -{ - ULONG SectorCnt, IndexPtr; - UWORD Sectors; - - - Sectors = 0; - IndexPtr = (ULONG)0x01 << SECTORPOINTERUSERFLASH; /* Offset in first index can be different from 0 */ - for(SectorCnt = SECTORINDEXUSERFLASH; SectorCnt <= ((NOOFSECTORS>>5)-1); SectorCnt++) - { - for( ; IndexPtr > 0; IndexPtr<<=1) - { - if (!(SectorTable[SectorCnt] & IndexPtr)) - { - Sectors++; - } - } - IndexPtr = 0x00000001; - } - - FreeSectors = Sectors; - return(dLoaderCalcFreeFileSpace(Sectors)); -} - -ULONG dLoaderCalcFreeFileSpace(UWORD NosOfFreeSectors) -{ - UWORD SectorCnt; - ULONG Space; - ULONG HeaderSpace; - - /* Calculate only if any sectors available */ - if (NosOfFreeSectors) - { - - Space = (ULONG)NosOfFreeSectors << SECTORSIZESHIFT; - - /* (FreeSectors - 1) is beacuse the the first sector of a file do not */ - /* require an entry in the sector table - it is pointed to by the filepointer */ - /* in the file pointer table*/ - SectorCnt = NosOfFreeSectors - 1; - - /* If more that one sector is used for the header the first filebody sector do not */ - /* require an entry in the sectortable - it is pointed to by the file startpointer */ - /* in the file header */ - if ((((SectorCnt<<1) + HEADERFIXEDSIZE) & (SECTORSIZE - 1)) < 4) - { - SectorCnt--; - } - - HeaderSpace = (HEADERFIXEDSIZE + (SectorCnt << 1)); - if (HeaderSpace & 0x0003) - { - /* Header size is not a multiplum of 4 - now make it a mul 4 */ - HeaderSpace += (0x0004 - (HeaderSpace & 0x0003)); - } - Space -= HeaderSpace; - } - return(Space); -} - - -UWORD dLoaderGetFilePtr(UBYTE *pFileName, UBYTE *pPtrToFile, ULONG *pFileLength) -{ - UWORD RtnVal; - UBYTE FoundFile[16]; - FILEHEADER *File; - ULONG DataLength; - - - RtnVal = dLoaderFind(pFileName, FoundFile, pFileLength, &DataLength, (UBYTE)BUSY); - if (0x8000 > RtnVal) - { - - File = (FILEHEADER*) FILEPTRTABLE[HandleTable[RtnVal].FileIndex]; - if (LINEAR & File->FileType) - { - *((ULONG*)pPtrToFile) = File->FileStartAdr; - } - else - { - RtnVal |= NOTLINEARFILE; - } - } - return(RtnVal); -} - -UWORD dLoaderAllocateHeader(UWORD Handle, ULONG *FileStartAdr, FILEHEADER *pHeader, UWORD HeaderByteSize, UWORD CompleteFileSectorSize) -{ - UWORD Tmp; - UWORD SectorTableIndex; - ULONG SectorIndex; - UWORD HeaderSectorSize; - UBYTE EvenHeader; - UWORD FileBodySectorSize; - UWORD ErrorCode; - - HeaderSectorSize = ((HeaderByteSize - 1) >> SECTORSIZESHIFT) + 1; - FileBodySectorSize = (((pHeader->FileSize - (SECTORSIZE - (HeaderByteSize & (SECTORSIZE - 1)))) - 1) >> SECTORSIZESHIFT) + 1; - - /* First allocate the file file header - this means the file name, */ - /* the file start adress, and the sector table */ - - /* SectorTableIndex indicates in the last word of a sector in which */ - /* sector the sectortable continues */ - SectorTableIndex = ((SECTORSIZE - HEADERFIXEDSIZE)>>1) - 1; - - /* Find first free sector - here there is a differende between linear or not*/ - ErrorCode = dLoaderFindFirstSector(pHeader->FileType, CompleteFileSectorSize, &Tmp); - - if (SUCCESS == ErrorCode) - { - *FileStartAdr = (ULONG)((ULONG)Tmp << SECTORSIZESHIFT) | FLASHOFFSET; - HandleTable[Handle].FileDlPtr = *FileStartAdr; - - SectorIndex = (Tmp >> 5); - Tmp &= 0x1F; - - SectorTable[SectorIndex]|= (0x01<FileStartAdr = (ULONG)(*FileStartAdr) + HeaderByteSize; - - /* if there is a sectortable it always starts right after the fixed header (Name + start + size)*/ - HandleTable[Handle].pSectorNo = (const UWORD *)(*FileStartAdr + HEADERFIXEDSIZE); - - /* First header has been allocated by find first function */ - HeaderSectorSize--; - UWORD TmpHSS = HeaderSectorSize; - - /* Next part is only executed when more than one sector is used */ - if (HeaderSectorSize) - { - UBYTE ExitCode = FALSE; - - while ((FALSE == ExitCode) && (SectorIndex < (NOOFSECTORS/32))) - { - for(; ((Tmp < 32) && (ExitCode == FALSE)); Tmp++) - { - if (!(SectorTable[SectorIndex] & (0x01<FileSectorTable[SectorTableIndex] = (SectorIndex << 5) + Tmp; - SectorTableIndex += (SECTORSIZE/2); - HeaderSectorSize--; - if (0 == HeaderSectorSize) - { - pHeader->FileStartAdr = (((SectorIndex << 5) + Tmp) << SECTORSIZESHIFT) + (HeaderByteSize - (TmpHSS<= (SECTORSIZE - 2)) || (0 == (HeaderByteSize & (SECTORSIZE - 1)))) - { - - /* The header uses exact one or several sectors */ - /* meaning that the next sector do not go into */ - /* the sectortable as it is pointed to by the */ - /* FileStart pointer */ - EvenHeader = TRUE; - } - - /* Now allocated the file body */ - SectorTableIndex = 0; - while ((FileBodySectorSize > 0) && (SectorIndex < (NOOFSECTORS/32))) - { - for(; Tmp < 32; Tmp++) - { - if (!(SectorTable[SectorIndex] & (0x01<FileStartAdr = (((SectorIndex << 5) + Tmp) << SECTORSIZESHIFT) | FLASHOFFSET; - EvenHeader = FALSE; - } - else - { - - /* Sector is free you can have this one */ - SectorTable[SectorIndex] |= (0x01<>1)-1) == SectorTableIndex) || (((SectorTableIndex - ((SECTORSIZE - HEADERFIXEDSIZE)>>1)) & 0x7F) == 127)) - { - SectorTableIndex++; - } - pHeader->FileSectorTable[SectorTableIndex] = (SectorIndex << 5) + Tmp; - SectorTableIndex++; - FileBodySectorSize--; - if (0 == FileBodySectorSize) - { - Tmp = 32; - SectorIndex = (NOOFSECTORS/32); - } - } - } - } - SectorIndex++; - Tmp = 0; - } - } - else - { - Handle |= ErrorCode; - } - return(Handle); -} - - -UWORD dLoaderFindFirstSector(UBYTE Type, UWORD SectorCount, UWORD *pSector) -{ - UWORD CompleteSectorSize; - UWORD SectorIndex; - UBYTE Tmp; - UWORD SectorCnt; - UWORD ErrorCode; - - - ErrorCode = SUCCESS; - - SectorIndex = SECTORINDEXUSERFLASH; - Tmp = SECTORPOINTERUSERFLASH; - - - - if (LINEAR & Type) - { - CompleteSectorSize = SectorCount; - ErrorCode = NOLINEARSPACE; - - /* find linear adress space */ - SectorCnt = CompleteSectorSize; - - while ((SectorCnt > 0) && (SectorIndex < (NOOFSECTORS>>5))) - { - if ((SectorTable[SectorIndex]) & ((ULONG)0x01<>5); - ErrorCode = SUCCESS; - } - } - - if (0x1F == Tmp) - { - SectorIndex++; - } - Tmp = (Tmp + 1) & 0x1F; - } - } - else - { - ErrorCode = UNDEFINEDERROR; - while(SectorIndex < (NOOFSECTORS>>5)) - { - if (!((SectorTable[SectorIndex]) & ((ULONG)0x01<>5); - ErrorCode = SUCCESS; - } - if (0x1F == Tmp) - { - SectorIndex++; - } - Tmp = (Tmp + 1) & 0x1F; - } - } - return(ErrorCode); -} - - -UWORD dLoaderFlashFileHeader(UWORD Handle, ULONG FileStartAdr, FILEHEADER *pHeader, UWORD HeaderByteSize) -{ - ULONG *pBufPtr; - ULONG FlashPtr; - UWORD HeaderSectorSize; - - pBufPtr = (ULONG*)pHeader; - FlashPtr = FileStartAdr; - HeaderSectorSize = (HeaderByteSize - 1) >> SECTORSIZESHIFT; - - dLoaderWritePage(FlashPtr, SECTORSIZE, pBufPtr); - - while(HeaderSectorSize) - { - pBufPtr += (SECTORSIZE>>2); - FlashPtr = (((*(pBufPtr - 1) & 0xFFFF0000) >> 16) << SECTORSIZESHIFT) | FLASHOFFSET; - dLoaderWritePage(FlashPtr, SECTORSIZE, pBufPtr); - HeaderSectorSize--; - } - - /* Prepare for actual data download */ - memcpy(WriteBuffer[HandleTable[Handle].WriteBufNo].Buf, pBufPtr, SECTORSIZE); - WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex = (UWORD)(pHeader->FileStartAdr) & (SECTORSIZE-1); - HandleTable[Handle].pFlash = (UBYTE *)pHeader->FileStartAdr; - - return(Handle); -} - - -UWORD dLoaderGetSectorNumber(ULONG Adr) -{ - UWORD SectorNo; - - SectorNo = (Adr & ~FLASHOFFSET)>>SECTORSIZESHIFT; - - return(SectorNo); -} - - -UWORD dLoaderAllocateWriteBuffer(UWORD Handle) -{ - UBYTE Tmp; - UWORD ErrorCode; - - ErrorCode = NOWRITEBUFFERS; - for (Tmp = 0; Tmp < MAX_WRITE_BUFFERS; Tmp++) - { - if (FREE == WriteBuffer[Tmp].Status) - { - WriteBuffer[Tmp].Status = BUSY; - memset(WriteBuffer[Tmp].Buf, 0xFF, sizeof(WriteBuffer[Tmp].Buf)); - WriteBuffer[Tmp].BufIndex = 0; - HandleTable[Handle].WriteBufNo = Tmp; - ErrorCode = SUCCESS; - Tmp = MAX_WRITE_BUFFERS; - } - } - Handle |= ErrorCode; - return(Handle); -} - -UWORD dLoaderCheckFiles(UBYTE Handle) -{ - UBYTE Tmp; - UBYTE Index; - UWORD ErrorCode; - - ErrorCode = SUCCESS; - Index = HandleTable[Handle].FileIndex; - for (Tmp = 0; Tmp < MAX_HANDLES; Tmp++) - { - if (((BUSY == HandleTable[Tmp].Status) || (DOWNLOADING == HandleTable[Tmp].Status)) && (Index == HandleTable[Tmp].FileIndex) && (Tmp != Handle)) - { - ErrorCode = FILEISBUSY; - } - } - return(Handle | ErrorCode); -} - - -void dLoaderCopyFileName(UBYTE *pDst, UBYTE *pSrc) -{ - UBYTE Tmp; - - for(Tmp = 0; Tmp < FILENAME_SIZE; Tmp++, pDst++) - { - if ('\0' != *pSrc) - { - *pDst = *pSrc; - pSrc++; - } - else - { - *pDst = '\0'; - } - } -} - - -void dLoaderCheckVersion(void) -{ - if (FILEPTRTABLE[FILEVERSIONINDEX] != FILEVERSION) - { - dLoaderDeleteAllFiles(); - } -} - - -UWORD dLoaderOpenAppend(UBYTE *pFileName, ULONG *pAvailSize) -{ - UWORD Handle; - ULONG FileSize, DataSize; - UBYTE Name[FILENAME_SIZE]; - FILEHEADER *pHeader; - - *pAvailSize = 0; - - Handle = dLoaderFind(pFileName, Name, &FileSize, &DataSize, (UBYTE)BUSY); - if (0x8000 > Handle) - { - - /* Check for an append in progress for this file */ - if (0x8000 > dLoaderCheckDownload(pFileName)) - { - - /* File has bee found - check for then correct filetype (Datafile) */ - pHeader = (FILEHEADER *)FILEPTRTABLE[HandleTable[Handle].FileIndex]; - if (DATAFILE & pHeader->FileType) - { - if (FileSize > DataSize) - { - /* Append is possible */ - Handle = dLoaderAllocateWriteBuffer(Handle); - if (Handle < 0x8000) - { - dLoaderSetFilePointer(Handle, DataSize, &(HandleTable[Handle].pFlash)); - WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex = (ULONG)(HandleTable[Handle].pFlash) & (SECTORSIZE - 1); - memcpy(WriteBuffer[HandleTable[Handle].WriteBufNo].Buf, (const UBYTE *)((ULONG)(HandleTable[Handle].pFlash) & ~(SECTORSIZE - 1)), WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex ); - HandleTable[Handle].FileDlPtr = FILEPTRTABLE[HandleTable[Handle].FileIndex]; - HandleTable[Handle].Status = (UBYTE)DOWNLOADING; - *pAvailSize = FileSize - DataSize; - HandleTable[Handle].DataLength = *pAvailSize; - HandleTable[Handle].FileType = pHeader->FileType; - } - } - else - { - Handle |= FILEISFULL; - } - } - else - { - Handle |= APPENDNOTPOSSIBLE; - } - } - else - { - Handle |= FILEISBUSY; - } - } - - return(Handle); -} - - -UWORD dLoaderSetFilePointer(UWORD Handle, ULONG BytePtr, const UBYTE **pData) -{ - ULONG AdrOffset; - const UBYTE *Adr; - UWORD SectorNo; - UWORD Tmp; - FILEHEADER *pHeader; - - - pData = pData; - pHeader = (FILEHEADER*)FILEPTRTABLE[HandleTable[Handle].FileIndex]; - HandleTable[Handle].pSectorNo = pHeader->FileSectorTable; - - /* Get the sector offset */ - AdrOffset = SECTORSIZE - ((pHeader->FileStartAdr) & (SECTORSIZE - 1)); - - if (BytePtr > AdrOffset) - { - BytePtr = BytePtr - AdrOffset; - SectorNo = ((BytePtr >> SECTORSIZESHIFT) + 1); - - for (Tmp = 0; Tmp < SectorNo; Tmp++) - { - Adr = dLoaderGetNextSectorPtr(Handle); - if (BytePtr > SECTORSIZE) - { - BytePtr -= SECTORSIZE; - } - } - *pData = (const UBYTE *)((ULONG)Adr + BytePtr); - } - else - { - - /* Pointer reside in the first sector of the file body */ - *pData = (const UBYTE *)((ULONG)(pHeader->FileStartAdr) + BytePtr); - } - return(Handle); -} - -void dLoaderCpyToLower(UBYTE *pDst, UBYTE *pSrc, UBYTE Length) -{ - UBYTE Tmp; - - for(Tmp = 0; Tmp < Length; Tmp++) - { - pDst[Tmp] =(UBYTE)toupper((UWORD)pSrc[Tmp]); - } - - /* The requried length has been copied - now fill with zeros */ - for(Tmp = Length; Tmp < FILENAME_SIZE; Tmp++) - { - pDst[Tmp] = '\0'; - } -} - -UWORD dLoaderCheckName(UBYTE *pName, UBYTE *pSearchStr, UBYTE SearchType) -{ - UBYTE TmpName[FILENAME_SIZE]; - UWORD RtnVal; - - RtnVal = UNDEFINEDERROR; - - dLoaderCpyToLower(TmpName, pName, (UBYTE)FILENAME_SIZE); - - RtnVal = SUCCESS; - switch (SearchType) - { - case FULLNAME: - { - if (0 != strcmp((const char*)TmpName, (const char *)pSearchStr)) - { - RtnVal = UNDEFINEDERROR; - } - } - break; - case NAME: - { - if (0 != memcmp(TmpName, pSearchStr, strlen((const char *)pSearchStr))) - { - RtnVal = UNDEFINEDERROR; - } - } - break; - case EXTENTION: - { - if (0 == strstr((const char *)TmpName, (const char*)pSearchStr)) - { - RtnVal = UNDEFINEDERROR; - } - } - break; - case WILDCARD: - { - RtnVal = SUCCESS; - } - break; - default: - { - } - break; - } - return(RtnVal); -} - -void dLoaderInsertSearchStr(UBYTE *pDst, UBYTE *pSrc, UBYTE *pSearchType) -{ - UBYTE Tmp; - - *pSearchType = WILDCARD; - if (0 != strstr((char const *)pSrc, "*.*")) - { - - /* find all */ - strcpy ((PSZ)pDst, (PSZ)pSrc); - *pSearchType = WILDCARD; - } - else - { - - /* Using other wild cards? */ - Tmp = strlen((char const *)pSrc); - if (0 != strstr((PSZ)(pSrc), ".*")) - { - - /* Extention wildcard */ - dLoaderCpyToLower(pDst, pSrc, (Tmp-1)); - *pSearchType = NAME; - } - else - { - if (0 != strstr((PSZ)(pSrc), "*.")) - { - - /* Filename wildcard */ - dLoaderCpyToLower(pDst, &pSrc[1], (UBYTE)4); - *pSearchType = EXTENTION; - } - else - { - - /* no wildcards used */ - dLoaderCpyToLower(pDst, pSrc, Tmp); - *pSearchType = FULLNAME; - } - } - } -} - -UWORD dLoaderCheckHandle(UWORD Handle, UBYTE Operation) -{ - - if (MAX_HANDLES > Handle) - { - if (Operation != HandleTable[(UBYTE)Handle].Status) - { - Handle |= ILLEGALHANDLE; - } - } - else - { - Handle |= ILLEGALHANDLE; - } - return(Handle); -} - -ULONG dLoaderReturnFreeUserFlash(void) -{ - return(FreeUserFlash); -} - -UWORD dLoaderRenameFile(UBYTE Handle, UBYTE *pNewName) -{ - ULONG SectorBuf[SECTORSIZE/4]; - ULONG *pFile; - UBYTE Tmp; - FILEHEADER *pHeader; - - pFile = (ULONG *)FILEPTRTABLE[HandleTable[Handle].FileIndex]; - for (Tmp = 0; Tmp < (SECTORSIZE/4); Tmp++) - { - SectorBuf[Tmp] = pFile[Tmp]; - } - - pHeader = (FILEHEADER *) SectorBuf; - - dLoaderCopyFileName((pHeader->FileName), pNewName); - dLoaderWritePage((ULONG)pFile, SECTORSIZE, SectorBuf); - return(SUCCESS); -} - - -UWORD dLoaderCheckDownload(UBYTE *pName) -{ - UBYTE Tmp; - UWORD ErrorCode; - - ErrorCode = SUCCESS; - for(Tmp = 0; Tmp < MAX_HANDLES; Tmp ++) - { - if (DOWNLOADING == HandleTable[Tmp].Status) - { - if (SUCCESS == dLoaderCheckName(pName, HandleTable[Tmp].SearchStr, FULLNAME)) - { - Tmp = MAX_HANDLES; - ErrorCode = FILEEXISTS; - } - } - } - return(ErrorCode); -} - - - - -UWORD dLoaderCropDatafile(UBYTE Handle) -{ - UWORD ReturnVal; - ULONG SectorBuffer[SECTORSIZE]; - UBYTE FileIndex; - - /* Save the fileindex for use after the handle has been closed */ - FileIndex = HandleTable[Handle].FileIndex; - - ReturnVal = dLoaderCloseHandle(Handle); - if (0x8000 > ReturnVal) - { - - /* Successful close handle now try to crop the file if filesize and datasize differs */ - /* and File exists */ - if (((FILEPTRTABLE[FileIndex]) != 0x00000000) && ((FILEPTRTABLE[FileIndex]) != 0xFFFFFFFF)) - { - if (((FILEHEADER const *)(FILEPTRTABLE[FileIndex]))->FileSize != ((FILEHEADER const *)(FILEPTRTABLE[FileIndex]))->DataSize) - { - memcpy(SectorBuffer, (void const*)(FILEPTRTABLE[FileIndex]), SECTORSIZE); - ((FILEHEADER*)SectorBuffer)->FileSize = ((FILEHEADER const *)(FILEPTRTABLE[FileIndex]))->DataSize; - dLoaderWritePage((ULONG)(FILEPTRTABLE[HandleTable[Handle].FileIndex]), SECTORSIZE, SectorBuffer); - - /* Update sectortable and available flash size */ - dLoaderUpdateSectorTable(); - } - } - } - return(ReturnVal); -} - -void dLoaderExit(void) -{ -} diff --git a/AT91SAM7S256/Source/d_loader.h b/AT91SAM7S256/Source/d_loader.h deleted file mode 100644 index 902c7f7..0000000 --- a/AT91SAM7S256/Source/d_loader.h +++ /dev/null @@ -1,109 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 24-06-09 12:15 $ -// -// Filename $Workfile:: d_loader.h $ -// -// Version $Revision:: 18 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_load $ -// -// Platform C -// - -#ifndef D_LOADER -#define D_LOADER - -#define FILETABLE_SIZE ((2 * SECTORSIZE)/4) -#define STARTOFFILETABLE (0x140000L - (FILETABLE_SIZE*4)) -#define FILEPTRTABLE ((const ULONG*)(0x140000L - (FILETABLE_SIZE*4))) -#ifndef STARTOFUSERFLASH_FROM_LINKER -#define STARTOFUSERFLASH (0x122100L) -#define SIZEOFUSERFLASH_MAX SIZEOFUSERFLASH -#else -extern char __STARTOFUSERFLASH_FROM_LINKER; -#define STARTOFUSERFLASH ((ULONG) &__STARTOFUSERFLASH_FROM_LINKER) -#define SIZEOFUSERFLASH_MAX ((ULONG) (128 * 1024)) -#endif -#define SIZEOFUSERFLASH ((ULONG)STARTOFFILETABLE - STARTOFUSERFLASH) - -#define SIZEOFFLASH 262144L -#define SECTORSIZE 256L -#define SECTORSIZESHIFT 8 -#define NOOFSECTORS (SIZEOFFLASH/SECTORSIZE) -#define HEADERFIXEDSIZE (FILENAME_SIZE + 4 + 4 + 4 + 2 + 2) -#define FILENAME_SIZE (FILENAME_LENGTH + 1) - -#define FULLNAME 1 -#define NAME 2 -#define EXTENTION 3 -#define WILDCARD 4 - -/* Enum related to HandleTable Status */ -enum -{ - FREE, - BUSY, - DOWNLOADING, - SEARCHING, - DLERROR -}; - -/* Enum related to HandleTable WriteBufNo */ -enum -{ - FREEBUFNO = 0xFF -}; - - -/* Constants related to filetype */ -enum -{ - SYSTEMFILE = 0x01, - DATAFILE = 0x02, - LINEAR = 0x04, - NONLINEAR = 0x08 -}; - -typedef struct -{ - UBYTE FileName[FILENAME_SIZE]; - ULONG FileStartAdr; - ULONG FileSize; - ULONG DataSize; - UWORD CheckSum; - UWORD FileType; - UWORD FileSectorTable[(SIZEOFUSERFLASH_MAX/SECTORSIZE)]; -}FILEHEADER; - -void dLoaderInit(void); -__ramfunc UWORD dLoaderWritePage(ULONG Flash_Address, UWORD Size, ULONG *pBuf); -UWORD dLoaderInsertPtrTable(const UBYTE *pAdr, UWORD Handle); -UWORD dLoaderCreateFileHeader(ULONG FileSize, UBYTE *pName, UBYTE LinearState, UBYTE FileType); -UWORD dLoaderWriteData(UWORD Handle, UBYTE *pBuf, UWORD *pLen); -UWORD dLoaderCloseHandle(UWORD Handle); -UWORD dLoaderOpenRead(UBYTE *pFileName, ULONG *pLength); -UWORD dLoaderRead(UBYTE Handle, UBYTE *pBuf, ULONG *pLength); -UWORD dLoaderDelete(UBYTE *pFile); -UWORD dLoaderFind(UBYTE *pFind, UBYTE *pFound, ULONG *pFileLength, ULONG *pDataLength, UBYTE Session); -UWORD dLoaderFindNext(UWORD Handle, UBYTE *pFound, ULONG *pFileLength, ULONG *pDataLength); -UWORD dLoaderDeleteFilePtr(UWORD Handle); -void dLoaderDeleteAllFiles(void); -UWORD dLoaderGetFilePtr(UBYTE *pFileName, UBYTE *pPtrToFile, ULONG *pFileLength); -void dLoaderCopyFileName(UBYTE *pDst, UBYTE *pSrc); -UWORD dLoaderOpenAppend(UBYTE *pFileName, ULONG *pAvailSize); -void dLoaderCpyToLower(UBYTE *pDst, UBYTE *pSrc, UBYTE Length); -UWORD dLoaderCheckName(UBYTE *pName, UBYTE *pSearchStr, UBYTE SearchType); -void dLoaderInsertSearchStr(UBYTE *pDst, UBYTE *pSrc, UBYTE *pSearchType); -ULONG dLoaderReturnFreeUserFlash(void); -UWORD dLoaderRenameFile(UBYTE Handle, UBYTE *pNewName); -UWORD dLoaderCheckFiles(UBYTE Handle); - -UWORD dLoaderCropDatafile(UBYTE Handle); - - - -void dLoaderExit(void); - -#endif diff --git a/AT91SAM7S256/Source/d_loader.r b/AT91SAM7S256/Source/d_loader.r deleted file mode 100644 index 3fb2556..0000000 --- a/AT91SAM7S256/Source/d_loader.r +++ /dev/null @@ -1,117 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: d_loader.r $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_load $ -// -// Platform C -// - -#ifdef SAM7S256 - -#define AT91C_MC_CORRECT_KEY 0x5A000000L - -static ULONG SectorImage[SECTORSIZE>>2]; - -#define LOADERInit - - -__ramfunc UWORD AT91F_Flash_Ready (void) -{ - UWORD status; - status = 0; - - //* Wait the end of command - while ((status & AT91C_MC_FRDY) != AT91C_MC_FRDY ) - { - status = AT91C_BASE_MC->MC_FSR; - } - return status; -} - -__ramfunc UWORD dLoaderWritePage(ULONG Flash_Address, UWORD Size, ULONG *pBuf) -{ - //* set the Flash controller base address - AT91PS_MC ptMC = AT91C_BASE_MC; - unsigned int i, page, status; - unsigned int * Flash; - - //* init flash pointer - Flash = (unsigned int *) (Flash_Address | (unsigned int)AT91C_IFLASH); - - //* Get the Flash page number - page = ((Flash_Address & ~(unsigned int)AT91C_IFLASH) >> SECTORSIZESHIFT); - - //* copy the new value - if (Size & 0x0003) - { - Size = Size + (0x0004 - (Size & 0x0003)); - } - for (i=0; (i < SECTORSIZE) & (Size > 0) ;i++, Flash++,pBuf++,Size-=4 ) - { - //* copy the flash to the write buffer ensuring code generation - *Flash=*pBuf; - } - - //* Write the write page command - ptMC->MC_FCR = AT91C_MC_CORRECT_KEY | AT91C_MC_FCMD_START_PROG | (AT91C_MC_PAGEN & (page <<8)); - - //* Wait the end of command - status = AT91F_Flash_Ready(); - - //* Check the result - if ( (status & ( AT91C_MC_PROGE | AT91C_MC_LOCKE ))!=0) - { - return FALSE; - } - return TRUE; - -} - -__ramfunc UWORD dLoaderErasePage(ULONG Flash_Address) -{ - //* set the Flash controller base address - AT91PS_MC ptMC = AT91C_BASE_MC; - unsigned int i, page, status, Size; - unsigned int * Flash; - - Size = SECTORSIZE; - - //* init flash pointer - Flash = (unsigned int *) (Flash_Address | (unsigned int)AT91C_IFLASH); - - //* Get the Flash page number - page = ((Flash_Address & ~(unsigned int)AT91C_IFLASH) >> SECTORSIZESHIFT); - - //* copy the new value - for (i=0; (i < SECTORSIZE) & (Size > 0) ;i++, Flash++,Size-=4 ) - { - //* copy the flash to the write buffer ensuring code generation - *Flash=0xFFFFFFFF; - } - - //* Write the write page command - ptMC->MC_FCR = AT91C_MC_CORRECT_KEY | AT91C_MC_FCMD_START_PROG | (AT91C_MC_PAGEN & (page <<8)); - - //* Wait the end of command - status = AT91F_Flash_Ready(); - - //* Check the result - if ( (status & ( AT91C_MC_PROGE | AT91C_MC_LOCKE ))!=0) - { - return FALSE; - } - return TRUE; - -} - - - - - -#endif diff --git a/AT91SAM7S256/Source/d_lowspeed.c b/AT91SAM7S256/Source/d_lowspeed.c deleted file mode 100644 index 91c1341..0000000 --- a/AT91SAM7S256/Source/d_lowspeed.c +++ /dev/null @@ -1,77 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: d_lowspeed.c $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_lows $ -// -// Platform C -// - -#include "stdconst.h" -#include "m_sched.h" -#include "d_lowspeed.h" -#include "d_lowspeed.r" - - -void dLowSpeedInit(void) -{ - LOWSpeedTxInit; - LOWSpeedTimerInit; - //ENABLEDebugOutput; -} - -void dLowSpeedStartTimer(void) -{ - ENABLEPWMTimerForLowCom; -} - -void dLowSpeedStopTimer(void) -{ - DISABLEPWMTimerForLowCom; -} - -void dLowSpeedInitPins(UBYTE ChannelNumber) -{ - ENABLETxPins(ChannelNumber); -} - -UBYTE dLowSpeedSendData(UBYTE ChannelNumber, UBYTE *DataOutBuffer, UBYTE NumberOfTxByte) -{ - UBYTE Status; - - TxData(ChannelNumber, Status, DataOutBuffer, NumberOfTxByte); - return(Status); -} - -void dLowSpeedReceiveData(UBYTE ChannelNumber, UBYTE *DataInBuffer, UBYTE ByteToRx) -{ - RxData(ChannelNumber, DataInBuffer, ByteToRx); -} - -UBYTE dLowSpeedComTxStatus(UBYTE ChannelNumber) -{ - UBYTE Status; - - STATUSTxCom(ChannelNumber, Status) - - return(Status); -} - -UBYTE dLowSpeedComRxStatus(UBYTE ChannelNumber) -{ - UBYTE Status; - - STATUSRxCom(ChannelNumber, Status) - - return(Status); -} - -void dLowSpeedExit(void) -{ - LOWSpeedExit; -} diff --git a/AT91SAM7S256/Source/d_lowspeed.h b/AT91SAM7S256/Source/d_lowspeed.h deleted file mode 100644 index 6ec62fd..0000000 --- a/AT91SAM7S256/Source/d_lowspeed.h +++ /dev/null @@ -1,28 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: d_lowspeed.h $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_lows $ -// -// Platform C -// - -#ifndef D_LOWSPEED -#define D_LOWSPEED - -void dLowSpeedInit(void); -void dLowSpeedStartTimer(void); -void dLowSpeedStopTimer(void); -void dLowSpeedInitPins(UBYTE ChannelNumber); -UBYTE dLowSpeedSendData(UBYTE ChannelNumber, UBYTE *DataOutBuffer, UBYTE NumberOfTxByte); -void dLowSpeedReceiveData(UBYTE ChannelNumber, UBYTE *DataInBuffer, UBYTE ByteToRx); -UBYTE dLowSpeedComTxStatus(UBYTE ChannelNumber); -UBYTE dLowSpeedComRxStatus(UBYTE ChannelNumber); -void dLowSpeedExit(void); - -#endif diff --git a/AT91SAM7S256/Source/d_lowspeed.r b/AT91SAM7S256/Source/d_lowspeed.r deleted file mode 100644 index 279c10e..0000000 --- a/AT91SAM7S256/Source/d_lowspeed.r +++ /dev/null @@ -1,612 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 19-02-09 18:51 $ -// -// Filename $Workfile:: d_lowspeed.r $ -// -// Version $Revision:: 4 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_lows $ -// -// Platform C -// - -#ifdef SAM7S256 - -#if defined (PROTOTYPE_PCB_3) || (PROTOTYPE_PCB_4) - -#define CHANNEL_ONE_CLK AT91C_PIO_PA23 /* PA23 is Clk */ -#define CHANNEL_ONE_DATA AT91C_PIO_PA18 /* PA18 is Data */ - -#define CHANNEL_TWO_CLK AT91C_PIO_PA28 /* PA28 is Clk */ -#define CHANNEL_TWO_DATA AT91C_PIO_PA19 /* PA19 is Data */ - -#define CHANNEL_THREE_CLK AT91C_PIO_PA29 /* PA29 is Clk */ -#define CHANNEL_THREE_DATA AT91C_PIO_PA20 /* PA20 is Data */ - -#define CHANNEL_FOUR_CLK AT91C_PIO_PA30 /* PA30 is Clk */ -#define CHANNEL_FOUR_DATA AT91C_PIO_PA2 /* PA2 is Data */ - -#else - -#define CHANNEL_ONE_CLK AT91C_PIO_PA28 /* PA28 is Clk */ -#define CHANNEL_ONE_DATA AT91C_PIO_PA20 /* PA20 is Data */ - -#endif - -typedef struct -{ - UWORD MaskBit; - UBYTE ChannelState; - UBYTE TxState; - UBYTE RxState; - UBYTE ReStartState; - UBYTE TxByteCnt; - UBYTE RxByteCnt; - UBYTE *pComOutBuffer; - UBYTE *pComInBuffer; - UBYTE AckStatus; - UBYTE RxBitCnt; - UBYTE ReStartBit; - UBYTE ComDeviceAddress; - UBYTE RxWaitCnt; - UBYTE ClkStatus; -}LOWSPEEDPARAMETERS; - -static LOWSPEEDPARAMETERS LowSpeedData[4]; - -__ramdata -ULONG DATA_PINS[4] = {CHANNEL_ONE_DATA, CHANNEL_TWO_DATA, CHANNEL_THREE_DATA, CHANNEL_FOUR_DATA}; -__ramdata -ULONG CLK_PINS[4] = {CHANNEL_ONE_CLK, CHANNEL_TWO_CLK, CHANNEL_THREE_CLK, CHANNEL_FOUR_CLK}; - -#define LOWSPEED_CHANNEL1 0 -#define LOWSPEED_CHANNEL2 1 -#define LOWSPEED_CHANNEL3 2 -#define LOWSPEED_CHANNEL4 3 -#define NO_OF_LOWSPEED_COM_CHANNEL 4 - -#define MASK_BIT_8 0x80 - -#define PIO_INQ 0x04 - -//Used for variable ChannelState -#define LOWSPEED_IDLE 0x00 -#define LOWSPEED_TX_STOP_BIT 0x01 -#define LOWSPEED_TRANSMITTING 0x02 -#define LOWSPEED_RECEIVING 0x04 -#define LOWSPEED_TEST_WAIT_STATE 0x08 -#define LOWSPEED_RESTART_CONDITION 0x10 -#define LOWSPEED_WAIT_BEFORE_RX 0x20 - -//Used for variable TxState -#define TX_IDLE 0x00 -#define TX_DATA_MORE_DATA 0x01 -#define TX_DATA_CLK_HIGH 0x02 -#define TX_EVALUATE_ACK_CLK_HIGH 0x03 -#define TX_DATA_READ_ACK_CLK_LOW 0x04 -#define TX_DATA_CLK_LOW 0x05 -#define TX_ACK_EVALUATED_CLK_LOW 0x06 - -//Used for variable RxState -#define RX_IDLE 0x00 -#define RX_START_BIT_CLK_HIGH 0x01 -#define RX_DATA_CLK_HIGH 0x02 -#define RX_ACK_TX_CLK_HIGH 0x03 -#define RX_DATA_CLK_LOW 0x04 -#define RX_DONE_OR_NOT_CLK_LOW 0x05 - -//Used for variable ReStart -#define RESTART_STATE_IDLE 0x00 -#define RESTART_STATE_ONE 0x01 -#define RESTART_STATE_TWO 0x02 -#define RESTART_STATE_THREE 0x03 -#define RESTART_STATE_FOUR 0x04 -#define RESTART_STATE_FIVE 0x05 -#define RESTART_STATE_SIX 0x06 -#define RESTART_STATE_SEVEN 0x07 - -#define LOWSpeedTxInit {\ - LowSpeedData[LOWSPEED_CHANNEL1].ChannelState = 0;\ - LowSpeedData[LOWSPEED_CHANNEL2].ChannelState = 0;\ - LowSpeedData[LOWSPEED_CHANNEL3].ChannelState = 0;\ - LowSpeedData[LOWSPEED_CHANNEL4].ChannelState = 0;\ - } - -#define LOWSpeedTimerInit {\ - *AT91C_PMC_PCER = 0x400; /* Enable clock for PWM, PID10*/\ - *AT91C_PWMC_MR = 0x01; /* CLKA is output from prescaler */\ - *AT91C_PWMC_MR |= 0x600; /* Prescaler MCK divided with 64 */\ - *AT91C_PWMC_CH0_CMR = 0x06; /* Channel 0 uses MCK divided by 64 */\ - *AT91C_PWMC_CH0_CMR &= 0xFFFFFEFF; /* Left alignment on periode */\ - *AT91C_PWMC_CH0_CPRDR = 0x20; /* Set to 39 => 52uSecondes interrupt */\ - *AT91C_PWMC_IDR = AT91C_PWMC_CHID0; /* Disable interrupt for PWM output channel 0 */\ - *AT91C_AIC_IDCR = 0x400; /* Disable AIC intterupt on ID10 PWM */\ - AT91C_AIC_SVR[10] = (unsigned int)LowSpeedPwmIrqHandler;\ - AT91C_AIC_SMR[10] = 0x01; /* Enable trigger on level */\ - *AT91C_AIC_ICCR = 0x400; /* Clear interrupt register PID10*/\ - *AT91C_PWMC_IER = AT91C_PWMC_CHID0; /* Enable interrupt for PWM output channel 0 */\ - *AT91C_AIC_IECR = 0x400; /* Enable interrupt from PWM */\ - } - -#define LOWSpeedExit - -#define ENABLEDebugOutput {\ - *AT91C_PIOA_PER = AT91C_PIO_PA29; /* Enable PIO on PA029 */\ - *AT91C_PIOA_OER = AT91C_PIO_PA29; /* PA029 set to Output */\ - *AT91C_PIOA_CODR = 0x20000000;\ - } - -#define SETDebugOutputHigh *AT91C_PIOA_SODR = 0x20000000 - -#define SETDebugOutputLow *AT91C_PIOA_CODR = 0x20000000 - - -#define SETClkLow(ChannelNr) {\ - *AT91C_PIOA_CODR = CLK_PINS[ChannelNr];\ - LowSpeedData[ChannelNr].ClkStatus = 0;\ -} - -#define SETClkHigh(ChannelNr) {\ - *AT91C_PIOA_SODR = CLK_PINS[ChannelNr];\ - LowSpeedData[ChannelNr].ClkStatus = 1;\ -} - -#define SETDataLow(ChannelNr) {\ - *AT91C_PIOA_CODR = DATA_PINS[ChannelNr];\ -} - -#define SETDataHigh(ChannelNr) {\ - *AT91C_PIOA_SODR = DATA_PINS[ChannelNr];\ -} - -#define SETDataToInput(ChannelNr) {\ - *AT91C_PIOA_ODR = DATA_PINS[ChannelNr];\ -} - - -#define SETDataToOutput(ChannelNr) {\ - *AT91C_PIOA_OER = DATA_PINS[ChannelNr];\ -} - -#define GetClkPinLevel(ChannelNr) (*AT91C_PIOA_PDSR & CLK_PINS[ChannelNr]) -#define GetDataPinLevel(ChannelNr) (*AT91C_PIOA_PDSR & DATA_PINS[ChannelNr]) - -#define ENABLEPWMTimerForLowCom {\ - *AT91C_PWMC_ENA = AT91C_PWMC_CHID0; /* Enable PWM output channel 0 */\ - } - -#define DISABLEPWMTimerForLowCom {\ - *AT91C_PWMC_DIS = AT91C_PWMC_CHID0; /* Disable PWM output channel 0 */\ - } - -#define OLD_DISABLEPWMTimerForLowCom {\ - *AT91C_PWMC_DIS = AT91C_PWMC_CHID0; /* Disable PWM output channel 0 */\ - *AT91C_PWMC_IDR = AT91C_PWMC_CHID0; /* Disable interrupt from PWM output channel 0 */\ - *AT91C_AIC_IDCR = 0x400; /* Disable Irq from PID10 */\ - *AT91C_AIC_ICCR = 0x400; /* Clear interrupt register PID10*/\ - *AT91C_PMC_PCDR = 0x400; /* Disable clock for PWM, PID10*/\ - } - -__ramfunc void LowSpeedPwmIrqHandler(void) -{ - ULONG TestVar; - ULONG PinStatus; - UBYTE ChannelNr; - - TestVar = *AT91C_PWMC_ISR; - TestVar = TestVar; - PinStatus = *AT91C_PIOA_PDSR; - - for (ChannelNr = 0; ChannelNr < NO_OF_LOWSPEED_COM_CHANNEL; ChannelNr++) - { - if (((LowSpeedData[ChannelNr].ClkStatus == 1) && (PinStatus & CLK_PINS[ChannelNr])) || (((LowSpeedData[ChannelNr].ClkStatus == 0) && (!(PinStatus & CLK_PINS[ChannelNr]))))) - { - switch(LowSpeedData[ChannelNr].ChannelState) - { - case LOWSPEED_IDLE: - { - } - break; - - case LOWSPEED_TX_STOP_BIT: - { - SETDataHigh(ChannelNr); - LowSpeedData[ChannelNr].ChannelState = LOWSPEED_IDLE; //Now we have send a STOP sequence, disable this channel - } - break; - - case LOWSPEED_TRANSMITTING: - { - switch(LowSpeedData[ChannelNr].TxState) - { - case TX_DATA_MORE_DATA: - { - PinStatus |= CLK_PINS[ChannelNr]; - LowSpeedData[ChannelNr].TxState = TX_DATA_CLK_HIGH; - } - break; - - case TX_DATA_CLK_HIGH: - { - SETClkLow(ChannelNr); - if (LowSpeedData[ChannelNr].MaskBit == 0) //Is Byte Done, then we need a ack from receiver - { - SETDataToInput(ChannelNr); //Set datapin to input - LowSpeedData[ChannelNr].TxState = TX_DATA_READ_ACK_CLK_LOW; - } - else - { - if (*LowSpeedData[ChannelNr].pComOutBuffer & LowSpeedData[ChannelNr].MaskBit) //Setup data pin in relation to the data - { - SETDataHigh(ChannelNr); //Set data output high - } - else - { - SETDataLow(ChannelNr); //Set data output low - } - LowSpeedData[ChannelNr].TxState = TX_DATA_CLK_LOW; - } - } - break; - - case TX_EVALUATE_ACK_CLK_HIGH: - { - SETClkLow(ChannelNr); - if (LowSpeedData[ChannelNr].AckStatus == 1) - { - LowSpeedData[ChannelNr].TxByteCnt--; - if (LowSpeedData[ChannelNr].TxByteCnt > 0) //Here initialise to send next byte - { - LowSpeedData[ChannelNr].MaskBit = MASK_BIT_8; - LowSpeedData[ChannelNr].pComOutBuffer++; - } - LowSpeedData[ChannelNr].TxState = TX_ACK_EVALUATED_CLK_LOW; //Received ack, now make a stop sequence or send next byte - } - else - { //Data communication error ! - LowSpeedData[ChannelNr].TxByteCnt = 0; - SETClkHigh(ChannelNr); - LowSpeedData[ChannelNr].ChannelState = LOWSPEED_TX_STOP_BIT; //Received ack, now make a stop sequence or send next byte. - } - } - break; - - case TX_DATA_READ_ACK_CLK_LOW: - { - if (!(PinStatus & DATA_PINS[ChannelNr])) - { - LowSpeedData[ChannelNr].AckStatus = 1; //Read ack signal from receiver - } - SETDataToOutput(ChannelNr); - SETDataLow(ChannelNr); - LowSpeedData[ChannelNr].TxState = TX_EVALUATE_ACK_CLK_HIGH; - SETClkHigh(ChannelNr); - } - break; - - case TX_DATA_CLK_LOW: - { - LowSpeedData[ChannelNr].MaskBit = LowSpeedData[ChannelNr].MaskBit >> 1; //Get ready for the next bit which should be clk out next time - SETClkHigh(ChannelNr); //Clk goes high = The reciever reads the data - LowSpeedData[ChannelNr].TxState = TX_DATA_CLK_HIGH; - } - break; - - case TX_ACK_EVALUATED_CLK_LOW: - { - if (LowSpeedData[ChannelNr].MaskBit != 0) - { - LowSpeedData[ChannelNr].TxState = TX_DATA_MORE_DATA; - } - else - { - if (LowSpeedData[ChannelNr].ReStartBit != 0) - { - LowSpeedData[ChannelNr].ChannelState = LOWSPEED_RESTART_CONDITION; - LowSpeedData[ChannelNr].ReStartState = RESTART_STATE_ONE; - SETDataLow(ChannelNr); - SETClkHigh(ChannelNr); //Clk goes high = The reciever reads the data - } - else - { - if (LowSpeedData[ChannelNr].RxByteCnt != 0) - { - LowSpeedData[ChannelNr].ChannelState = LOWSPEED_WAIT_BEFORE_RX; - } - else - { - LowSpeedData[ChannelNr].ChannelState = LOWSPEED_TX_STOP_BIT; - SETClkHigh(ChannelNr); //Clk goes high = The reciever reads the data - } - } - LowSpeedData[ChannelNr].TxState = TX_IDLE; - } - } - break; - } - } - break; - - case LOWSPEED_RESTART_CONDITION: - { - switch(LowSpeedData[ChannelNr].ReStartState) - { - case RESTART_STATE_ONE: - { - LowSpeedData[ChannelNr].ReStartState = RESTART_STATE_TWO; - } - break; - - case RESTART_STATE_TWO: - { - SETDataHigh(ChannelNr); - LowSpeedData[ChannelNr].ReStartState = RESTART_STATE_THREE; - } - break; - - case RESTART_STATE_THREE: - { - SETClkLow(ChannelNr); - LowSpeedData[ChannelNr].ReStartState = RESTART_STATE_FOUR; - } - break; - - case RESTART_STATE_FOUR: - { - SETClkHigh(ChannelNr); - LowSpeedData[ChannelNr].ReStartState = RESTART_STATE_FIVE; - } - break; - - case RESTART_STATE_FIVE: - { - SETDataLow(ChannelNr); - LowSpeedData[ChannelNr].ReStartState = RESTART_STATE_SIX; - } - break; - - case RESTART_STATE_SIX: - { - LowSpeedData[ChannelNr].ReStartState = RESTART_STATE_SEVEN; - } - break; - - case RESTART_STATE_SEVEN: - { - SETClkLow(ChannelNr); - LowSpeedData[ChannelNr].ReStartState = RESTART_STATE_IDLE; - LowSpeedData[ChannelNr].ReStartBit = 0; - LowSpeedData[ChannelNr].pComOutBuffer = &LowSpeedData[ChannelNr].ComDeviceAddress; - *LowSpeedData[ChannelNr].pComOutBuffer += 0x01; - LowSpeedData[ChannelNr].ChannelState = LOWSPEED_TRANSMITTING; - LowSpeedData[ChannelNr].MaskBit = MASK_BIT_8; - LowSpeedData[ChannelNr].TxByteCnt = 0x01; - LowSpeedData[ChannelNr].TxState = TX_DATA_CLK_HIGH; - LowSpeedData[ChannelNr].AckStatus = 0; - } - break; - } - } - break; - - case LOWSPEED_WAIT_BEFORE_RX: - { - LowSpeedData[ChannelNr].RxWaitCnt++; - if (LowSpeedData[ChannelNr].RxWaitCnt > 5) - { - LowSpeedData[ChannelNr].ChannelState = LOWSPEED_RECEIVING; - SETDataToInput(ChannelNr); - } - } - break; - - case LOWSPEED_RECEIVING: - { - switch(LowSpeedData[ChannelNr].RxState) - { - case RX_START_BIT_CLK_HIGH: - { - SETClkLow(ChannelNr); - LowSpeedData[ChannelNr].RxState = RX_DATA_CLK_LOW; - } - break; - - case RX_DATA_CLK_HIGH: - { - LowSpeedData[ChannelNr].RxBitCnt++; - if(PinStatus & DATA_PINS[ChannelNr]) - { - *LowSpeedData[ChannelNr].pComInBuffer |= 0x01; - } - SETClkLow(ChannelNr); - if (LowSpeedData[ChannelNr].RxBitCnt < 8) - { - *LowSpeedData[ChannelNr].pComInBuffer = *LowSpeedData[ChannelNr].pComInBuffer << 1; - } - else - { - if (LowSpeedData[ChannelNr].RxByteCnt > 1) - { - SETDataToOutput(ChannelNr); - SETDataLow(ChannelNr); - } - } - LowSpeedData[ChannelNr].RxState = RX_DATA_CLK_LOW; - } - break; - - case RX_ACK_TX_CLK_HIGH: - { - SETClkLow(ChannelNr); - SETDataToInput(ChannelNr); - LowSpeedData[ChannelNr].pComInBuffer++; - LowSpeedData[ChannelNr].RxByteCnt--; - LowSpeedData[ChannelNr].RxBitCnt = 0; - LowSpeedData[ChannelNr].RxState = RX_DONE_OR_NOT_CLK_LOW; - } - break; - - case RX_DATA_CLK_LOW: - { - SETClkHigh(ChannelNr); - if (LowSpeedData[ChannelNr].RxBitCnt == 8) - { - LowSpeedData[ChannelNr].RxState = RX_ACK_TX_CLK_HIGH; - } - else - { - LowSpeedData[ChannelNr].RxState = RX_DATA_CLK_HIGH; - } - } - break; - - case RX_DONE_OR_NOT_CLK_LOW: - { - if (LowSpeedData[ChannelNr].RxByteCnt == 0) - { - LowSpeedData[ChannelNr].ChannelState = LOWSPEED_IDLE; - LowSpeedData[ChannelNr].RxState = RX_IDLE; - SETClkHigh(ChannelNr); - } - else - { - LowSpeedData[ChannelNr].RxState = RX_START_BIT_CLK_HIGH; - } - } - break; - } - } - break; - - default: - break; - } - } - else - { - - if (LOWSPEED_IDLE != LowSpeedData[ChannelNr].ChannelState) - { - //Data communication error ! - LowSpeedData[ChannelNr].TxByteCnt = 0; - SETClkHigh(ChannelNr); - LowSpeedData[ChannelNr].ChannelState = LOWSPEED_TX_STOP_BIT; - } - } - } -} - -#define ENABLETxPins(ChannelNumber) {\ - ULONG Tmp = CLK_PINS[ChannelNumber] | DATA_PINS[ChannelNumber];\ - *AT91C_PIOA_PER = Tmp; /* Enable PIO */\ - *AT91C_PIOA_PPUDR = Tmp; /* Disable Pull-up resistor */\ - *AT91C_PIOA_ODR = Tmp; /* PIO set to Input */\ -} - -#define TxData(ChannelNumber, Status, DataOutBuffer, NumberOfByte) {\ - if ((GetDataPinLevel(ChannelNumber) && GetClkPinLevel(ChannelNumber)) && (LowSpeedData[ChannelNumber].ChannelState == LOWSPEED_IDLE))\ - {\ - ULONG Tmp = CLK_PINS[ChannelNumber] | DATA_PINS[ChannelNumber];\ - *AT91C_PIOA_PER = Tmp; /* Enable PIO */\ - *AT91C_PIOA_OER = Tmp; /* POI set to Output */\ - *AT91C_PIOA_PPUDR = Tmp; /* Disable Pull-up resistor */\ - SETClkHigh(ChannelNumber);\ - SETDataLow(ChannelNumber);\ - LowSpeedData[ChannelNumber].ClkStatus = 1;\ - LowSpeedData[ChannelNumber].pComOutBuffer = DataOutBuffer;\ - LowSpeedData[ChannelNumber].ComDeviceAddress = *LowSpeedData[ChannelNumber].pComOutBuffer;\ - LowSpeedData[ChannelNumber].MaskBit = MASK_BIT_8;\ - LowSpeedData[ChannelNumber].TxByteCnt = NumberOfByte;\ - LowSpeedData[ChannelNumber].TxState = TX_DATA_CLK_HIGH;\ - LowSpeedData[ChannelNumber].AckStatus = 0;\ - LowSpeedData[ChannelNumber].ChannelState = LOWSPEED_TRANSMITTING;\ - Status = 1;\ - }\ - else\ - {\ - Status = 0;\ - }\ -} - -#define RxData(ChannelNumber, DataInBuffer, RxBytes) {\ - LowSpeedData[ChannelNumber].pComInBuffer = DataInBuffer;\ - LowSpeedData[ChannelNumber].RxBitCnt = 0;\ - LowSpeedData[ChannelNumber].RxByteCnt = RxBytes;\ - LowSpeedData[ChannelNumber].RxState = RX_DATA_CLK_LOW;\ - LowSpeedData[ChannelNumber].ReStartBit = 1;\ - LowSpeedData[ChannelNumber].RxWaitCnt = 0;\ - } - - -#define STATUSTxCom(ChannelNumber, Status) {\ - if (LowSpeedData[ChannelNumber].ChannelState != 0)\ - {\ - if ((LowSpeedData[ChannelNumber].TxByteCnt == 0) && (LowSpeedData[ChannelNumber].ChannelState != LOWSPEED_RESTART_CONDITION))\ - {\ - if (LowSpeedData[ChannelNumber].MaskBit == 0)\ - {\ - if (LowSpeedData[ChannelNumber].AckStatus == 1)\ - {\ - Status = 0x01; /* TX SUCCESS */\ - }\ - else\ - {\ - Status = 0xFF; /* TX ERROR */\ - }\ - }\ - else\ - {\ - Status = 0;\ - }\ - }\ - else\ - {\ - Status = 0;\ - }\ - }\ - else\ - {\ - if (LowSpeedData[ChannelNumber].RxByteCnt == 0)\ - {\ - if (LowSpeedData[ChannelNumber].AckStatus == 1)\ - {\ - Status = 0x01; /* TX SUCCESS */\ - }\ - else\ - {\ - Status = 0xFF; /* TX ERROR */\ - }\ - }\ - else\ - {\ - Status = 0xFF; /* TX ERROR */\ - }\ - }\ - } - -#define STATUSRxCom(ChannelNumber, Status) {\ - if (LowSpeedData[ChannelNumber].ChannelState == LOWSPEED_IDLE)\ - {\ - if (LowSpeedData[ChannelNumber].RxByteCnt == 0)\ - {\ - Status = 0x01; /* RX SUCCESS */\ - }\ - else\ - {\ - Status = 0xFF; /* RX ERROR */\ - }\ - }\ - else\ - {\ - Status = 0;\ - }\ - } - - -#endif - -#ifdef PCWIN - -#endif diff --git a/AT91SAM7S256/Source/d_output.c b/AT91SAM7S256/Source/d_output.c deleted file mode 100644 index 326f6f8..0000000 --- a/AT91SAM7S256/Source/d_output.c +++ /dev/null @@ -1,1415 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 3-02-09 14:46 $ -// -// Filename $Workfile:: d_output.c $ -// -// Version $Revision:: 2 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_outp $ -// -// Platform C -// - -#include "stdconst.h" -#include "m_sched.h" -#include "d_output.h" -#include "d_output.r" - -#include - -#define MAXIMUM_SPEED_FW 100 -#define MAXIMUM_SPEED_RW -100 - -#define INPUT_SCALE_FACTOR 100 -#define SPEED_TIME 100 - -#define MAX_COUNT_TO_RUN 10000000 - -#define REG_MAX_VALUE 100 - -#define RAMP_TIME_INTERVAL 25 // Measured in 1 mS => 25 mS interval - -#define RAMPDOWN_STATE_RAMPDOWN 0 -#define RAMPDOWN_STATE_CONTINIUE 1 - -#define COAST_MOTOR_MODE 0 - -void dOutputRampDownSynch(UBYTE MotorNr); -SLONG dOutputBound(SLONG In, SLONG Limit); -SLONG dOutputPIDRegulation(UBYTE MotorNr, SLONG PositionError); -SLONG dOutputFractionalChange(SLONG Value, SWORD *FracError); -void dOutputSpeedFilter(UBYTE MotorNr, SLONG PositionDiff); - -#define ABS(a) (((a) < 0) ? -(a) : (a)) -#define MIN(a, b) ((a) < (b) ? (a) : (b)) - -typedef struct -{ - SBYTE MotorSetSpeed; // Motor setpoint in speed - SBYTE MotorTargetSpeed; // Speed order for the movement - SBYTE MotorActualSpeed; // Actual speed for motor (Calculated within the PID regulation) - SBYTE TurnParameter; // Tell the turning parameter used - UBYTE RegPParameter; // Current P parameter used within the regulation - UBYTE RegIParameter; // Current I parameter used within the regulation - UBYTE RegDParameter; // Current D parameter used within the regulation - UBYTE RegulationTimeCount; // Time counter used to evaluate when the regulation should run again (100 mS) - UBYTE MotorRunState; // Hold current motor state (Ramp-up, Running, Ramp-Down, Idle) - UBYTE RegulationMode; // Hold current regulation mode (Position control, Synchronization mode) - UBYTE MotorOverloaded; // Set if the motor speed in regulation is calculated to be above maximum - UBYTE MotorRunForever; // Tell that the motor is set to run forever - UWORD MotorRampDownCount; // Counter to tell if the ramp-down can reach it gaol and therefor need some additional help - SWORD MotorRampDownIncrement; // Tell the number of count between each speed adjustment during Ramp-Down - UWORD MotorRampUpCount; // Used to speedup Ramp-Up if position regulation is not enabled - SWORD MotorRampUpIncrement; // Tell the number of count between each speed adjustment during Ramp-up - SWORD AccError; // Accumulated Error, used within the integrator of the PID regulation - SWORD OldPositionError; // Used within position regulation - SWORD PositionFracError; // Fractionnal position error of last position update - SLONG DeltaCaptureCount; // Counts within last regulation time-periode - SLONG CurrentCaptureCount; // Total counts since motor counts has been reset - SLONG MotorTachoCountToRun; // Holds number of counts to run. 0 = Run forever - SLONG MotorBlockTachoCount; // Hold CaptureCount for current movement - SLONG MotorRampTachoCountOld; // Used to hold old position during Ramp-Up - SLONG MotorRampTachoCountStart; // Used to hold position when Ramp-up started - SLONG RotationCaptureCount; // Counter for additional rotation counter - SLONG MotorTachoCountTarget; // For absolute regulation, position on which regulation is done - SWORD SpeedFracError; // Fractionnal speed error of last speed update - SBYTE MotorMaxSpeed; // For absolute regulation, maximum motor speed - SBYTE MotorMaxAcceleration; // For absolute regulation, maximum motor acceleration -}MOTORDATA; - -typedef struct -{ - SLONG SyncTachoDif; - SLONG SyncTurnParameter; - SWORD SyncOldError; - SWORD SyncAccError; -}SYNCMOTORDATA; - -static MOTORDATA MotorData[3]; -static SYNCMOTORDATA SyncData; -static UBYTE RegulationTime; -static UBYTE RegulationOptions; - -void dOutputInit(void) -{ - UBYTE Temp; - - OUTPUTInit; - ENABLECaptureMotorA; - ENABLECaptureMotorB; - ENABLECaptureMotorC; - - for (Temp = 0; Temp < 3; Temp++) - { - MOTORDATA * pMD = &(MotorData[Temp]); - pMD->MotorSetSpeed = 0; - pMD->MotorTargetSpeed = 0; - pMD->MotorActualSpeed = 0; - pMD->MotorRampUpCount = 0; - pMD->MotorRampDownCount = 0; - pMD->MotorRunState = 0; - pMD->MotorTachoCountToRun = 0; - pMD->MotorRunForever = 1; - pMD->AccError = 0; - pMD->PositionFracError = 0; - pMD->RegulationTimeCount = 0; - pMD->RegPParameter = DEFAULT_P_GAIN_FACTOR; - pMD->RegIParameter = DEFAULT_I_GAIN_FACTOR; - pMD->RegDParameter = DEFAULT_D_GAIN_FACTOR; - pMD->MotorMaxSpeed = DEFAULT_MAX_SPEED; - pMD->MotorMaxAcceleration = DEFAULT_MAX_ACCELERATION; - pMD->RegulationMode = 0; - pMD->MotorOverloaded = 0; - INSERTMode(Temp, COAST_MOTOR_MODE); - INSERTSpeed(Temp, pMD->MotorSetSpeed); - } -} - -/* This function is called every 1 mS and will go through all the motors and there dependencies */ -/* Actual motor speed is only passed (updated) to the AVR controller form this function */ -/* DeltacaptureCount used to count number of Tachocount within last 100 mS. Used with position control regulation */ -/* CurrentCaptureCount used to tell total current position. Used to tell when movement has been obtained */ -/* MotorBlockTachoCount tell current position within current movement. Reset when a new block is started from the VM */ -/* RotationCaptureCount is additional counter for the rotationsensor. Uses it own value so it does conflict with other CaptureCount */ -void dOutputCtrl(void) -{ - UBYTE MotorNr; - SLONG NewTachoCount[3]; - - TACHOCaptureReadResetAll(NewTachoCount[MOTOR_A], NewTachoCount[MOTOR_B], NewTachoCount[MOTOR_C]); - - for (MotorNr = 0; MotorNr < 3; MotorNr++) - { - MOTORDATA * pMD = &(MotorData[MotorNr]); - pMD->DeltaCaptureCount += NewTachoCount[MotorNr]; - pMD->CurrentCaptureCount += NewTachoCount[MotorNr]; - pMD->MotorBlockTachoCount += NewTachoCount[MotorNr]; - pMD->RotationCaptureCount += NewTachoCount[MotorNr]; - pMD->RegulationTimeCount++; - - if (pMD->MotorRunState == MOTOR_RUN_STATE_RAMPUP) - { - dOutputRampUpFunction(MotorNr); - } - if (pMD->MotorRunState == MOTOR_RUN_STATE_RAMPDOWN) - { - dOutputRampDownFunction(MotorNr); - } - if (pMD->MotorRunState == MOTOR_RUN_STATE_RUNNING) - { - dOutputTachoLimitControl(MotorNr); - } - if (pMD->MotorRunState == MOTOR_RUN_STATE_IDLE) - { - dOutputMotorIdleControl(MotorNr); - } - if (pMD->MotorRunState == MOTOR_RUN_STATE_HOLD) - { - pMD->MotorSetSpeed = 0; - pMD->MotorActualSpeed = 0; - pMD->MotorTargetSpeed = 0; - pMD->PositionFracError = 0; - pMD->RegulationTimeCount = 0; - pMD->DeltaCaptureCount = 0; - pMD->MotorRunState = MOTOR_RUN_STATE_RUNNING; - - } - if (pMD->RegulationTimeCount > RegulationTime) - { - pMD->RegulationTimeCount = 0; - dOutputRegulateMotor(MotorNr); - pMD->DeltaCaptureCount = 0; - } - } - INSERTSpeed(MOTOR_A, MotorData[MOTOR_A].MotorActualSpeed); - INSERTSpeed(MOTOR_B, MotorData[MOTOR_B].MotorActualSpeed); - INSERTSpeed(MOTOR_C, MotorData[MOTOR_C].MotorActualSpeed); -} - -void dOutputExit(void) -{ - OUTPUTExit; -} - -/* Called eveyr 1 mS */ -/* Data mapping for controller (IO-Map is updated with these values) */ -void dOutputGetMotorParameters(UBYTE *CurrentMotorSpeed, SLONG *TachoCount, SLONG *BlockTachoCount, UBYTE *RunState, UBYTE *MotorOverloaded, SLONG *RotationCount) -{ - UBYTE Tmp; - - for (Tmp = 0; Tmp < 3; Tmp++) - { - MOTORDATA * pMD = &(MotorData[Tmp]); - CurrentMotorSpeed[Tmp] = pMD->MotorActualSpeed; - TachoCount[Tmp] = pMD->CurrentCaptureCount; - BlockTachoCount[Tmp] = pMD->MotorBlockTachoCount; - RotationCount[Tmp] = pMD->RotationCaptureCount; - RunState[Tmp] = pMD->MotorRunState; - MotorOverloaded[Tmp] = pMD->MotorOverloaded; - } -} - -void dOutputSetMode(UBYTE MotorNr, UBYTE Mode) //Set motor mode (break, Float) -{ - INSERTMode(MotorNr, Mode); -} - -/* Update the regulation state for the motor */ -/* Need to reset regulation parameter depending on current status of the motor */ -/* AccError & OldPositionError used for position regulation and Sync Parameter are used for synchronization regulation */ -void dOutputEnableRegulation(UBYTE MotorNr, UBYTE RegulationMode) -{ - MOTORDATA * pMD = &(MotorData[MotorNr]); - pMD->RegulationMode = RegulationMode; - - if ((pMD->RegulationMode & REGSTATE_REGULATED) && (pMD->MotorSetSpeed == 0) && (pMD->MotorRunState != MOTOR_RUN_STATE_RAMPDOWN)) - { - pMD->AccError = 0; - pMD->OldPositionError = 0; - pMD->PositionFracError = 0; - } - - if (pMD->RegulationMode & REGSTATE_SYNCHRONE) - { - if (((pMD->MotorActualSpeed == 0) || (pMD->TurnParameter != 0) || (pMD->TurnParameter == 0)) && (pMD->MotorRunState != MOTOR_RUN_STATE_RAMPDOWN)) - { - SyncData.SyncTachoDif = 0; - - SyncData.SyncAccError = 0; - SyncData.SyncOldError = 0; - SyncData.SyncTurnParameter = 0; - } - } -} - -/* Disable current regulation if enabled */ -void dOutputDisableRegulation(UBYTE MotorNr) -{ - MotorData[MotorNr].RegulationMode = REGSTATE_IDLE; -} - -/* Calling this function with reset count which tell current position and which is used to tell if the wanted position is obtained */ -/* Calling this function will reset current movement of the motor if it is running */ -void dOutputResetTachoLimit(UBYTE MotorNr) -{ - MOTORDATA * pMD = &(MotorData[MotorNr]); - pMD->CurrentCaptureCount = 0; - pMD->MotorTachoCountToRun = 0; - pMD->MotorTachoCountTarget = 0; - - if (pMD->RegulationMode & REGSTATE_SYNCHRONE) - { - dOutputResetSyncMotors(MotorNr); - } - - if (pMD->MotorRunForever == 1) - { - pMD->MotorRunForever = 0; // To ensure that we get the same functionality for all combination on motor durations - } -} - -/* MotorBlockTachoCount tells current position in current movement. */ -/* Used within the synchronization to compare current motor position. Reset on every new movement from the VM */ -void dOutputResetBlockTachoLimit(UBYTE MotorNr) -{ - MotorData[MotorNr].MotorBlockTachoCount = 0; -} - -/* Additional counter add to help the VM application keep track of number of rotation for the rotation sensor */ -/* This values can be reset independtly from the other tacho count values used with regulation and position control */ -void dOutputResetRotationCaptureCount(UBYTE MotorNr) -{ - MotorData[MotorNr].RotationCaptureCount = 0; -} - -/* Can be used to set new PID values */ -void dOutputSetPIDParameters(UBYTE MotorNr, UBYTE NewRegPParameter, UBYTE NewRegIParameter, UBYTE NewRegDParameter) -{ - MOTORDATA * pMD = &(MotorData[MotorNr]); - pMD->RegPParameter = NewRegPParameter; - pMD->RegIParameter = NewRegIParameter; - pMD->RegDParameter = NewRegDParameter; -} - -/* Set maximum speed and acceleration */ -void dOutputSetMax(UBYTE MotorNr, SBYTE NewMaxSpeed, SBYTE NewMaxAcceleration) -{ - MOTORDATA * pMD = &(MotorData[MotorNr]); - pMD->MotorMaxSpeed = NewMaxSpeed; - pMD->MotorMaxAcceleration = NewMaxAcceleration; -} - -/* Set new regulation time */ -void dOutputSetRegulationTime(UBYTE NewRegulationTime) -{ - RegulationTime = NewRegulationTime; -} - -/* Set new regulation options */ -void dOutputSetRegulationOptions(UBYTE NewRegulationOptions) -{ - RegulationOptions = NewRegulationOptions; -} - -/* Called to set TachoCountToRun which is used for position control for the model */ -/* Must be called before motor start */ -/* TachoCountToRun is calculated as a signed value */ -void dOutputSetTachoLimit(UBYTE MotorNr, ULONG BlockTachoCntToTravel) -{ - MOTORDATA * pMD = &(MotorData[MotorNr]); - if (pMD->RegulationMode & REGSTATE_POSITION) - { - pMD->MotorRunForever = 0; - pMD->MotorTachoCountToRun = BlockTachoCntToTravel; - } - else if (BlockTachoCntToTravel == 0) - { - pMD->MotorRunForever = 1; - } - else - { - pMD->MotorRunForever = 0; - - if (pMD->MotorSetSpeed == 0) - { - if (pMD->MotorTargetSpeed > 0) - { - pMD->MotorTachoCountToRun += BlockTachoCntToTravel; - } - else - { - pMD->MotorTachoCountToRun -= BlockTachoCntToTravel; - } - } - else - { - if (pMD->MotorSetSpeed > 0) - { - pMD->MotorTachoCountToRun += BlockTachoCntToTravel; - } - else - { - pMD->MotorTachoCountToRun -= BlockTachoCntToTravel; - } - } - } -} - -/* This function is used for setting up the motor mode and motor speed */ -void dOutputSetSpeed (UBYTE MotorNr, UBYTE NewMotorRunState, SBYTE Speed, SBYTE NewTurnParameter) -{ - MOTORDATA * pMD = &(MotorData[MotorNr]); - if ((pMD->MotorSetSpeed != Speed) || (pMD->MotorRunState != NewMotorRunState) || - (NewMotorRunState == MOTOR_RUN_STATE_IDLE) || (pMD->TurnParameter != NewTurnParameter)) - { - if (pMD->MotorTargetSpeed == 0) - { - pMD->AccError = 0; - pMD->OldPositionError = 0; - pMD->PositionFracError = 0; - pMD->RegulationTimeCount = 0; - pMD->DeltaCaptureCount = 0; - TACHOCountReset(MotorNr); - } - switch (NewMotorRunState) - { - case MOTOR_RUN_STATE_IDLE: - { - //pMD->MotorSetSpeed = 0; - //pMD->MotorTargetSpeed = 0; - //pMD->TurnParameter = 0; - pMD->RegulationMode = REGSTATE_IDLE; - } - break; - - case MOTOR_RUN_STATE_RAMPUP: - { - if (pMD->MotorSetSpeed == 0) - { - pMD->MotorSetSpeed = Speed; - pMD->TurnParameter = NewTurnParameter; - pMD->MotorRampUpIncrement = 0; - pMD->MotorRampTachoCountStart = pMD->CurrentCaptureCount; - pMD->MotorRampUpCount = 0; - } - else - { - if (Speed > 0) - { - if (pMD->MotorSetSpeed >= Speed) - { - NewMotorRunState = MOTOR_RUN_STATE_RUNNING; - } - else - { - pMD->MotorSetSpeed = Speed; - pMD->TurnParameter = NewTurnParameter; - pMD->MotorRampUpIncrement = 0; - pMD->MotorRampTachoCountStart = pMD->CurrentCaptureCount; - pMD->MotorRampUpCount = 0; - } - } - else - { - if (pMD->MotorSetSpeed <= Speed) - { - NewMotorRunState = MOTOR_RUN_STATE_RUNNING; - } - else - { - pMD->MotorSetSpeed = Speed; - pMD->TurnParameter = NewTurnParameter; - pMD->MotorRampUpIncrement = 0; - pMD->MotorRampTachoCountStart = pMD->CurrentCaptureCount; - pMD->MotorRampUpCount = 0; - } - } - } - } - break; - - case MOTOR_RUN_STATE_RUNNING: - { - pMD->MotorSetSpeed = Speed; - pMD->MotorTargetSpeed = Speed; - pMD->TurnParameter = NewTurnParameter; - - if (pMD->MotorSetSpeed == 0) - { - NewMotorRunState = MOTOR_RUN_STATE_HOLD; - } - } - break; - - case MOTOR_RUN_STATE_RAMPDOWN: - { - if (pMD->MotorTargetSpeed >= 0) - { - if (pMD->MotorSetSpeed <= Speed) - { - NewMotorRunState = MOTOR_RUN_STATE_RUNNING; - } - else - { - pMD->MotorSetSpeed = Speed; - pMD->TurnParameter = NewTurnParameter; - pMD->MotorRampDownIncrement = 0; - pMD->MotorRampTachoCountStart = pMD->CurrentCaptureCount; - pMD->MotorRampDownCount = 0; - } - } - else - { - if (pMD->MotorSetSpeed >= Speed) - { - NewMotorRunState = MOTOR_RUN_STATE_RUNNING; - } - else - { - pMD->MotorSetSpeed = Speed; - pMD->TurnParameter = NewTurnParameter; - pMD->MotorRampDownIncrement = 0; - pMD->MotorRampTachoCountStart = pMD->CurrentCaptureCount; - pMD->MotorRampDownCount = 0; - } - } - } - break; - } - pMD->MotorRunState = NewMotorRunState; - pMD->MotorOverloaded = 0; - } -} - -/* Function used for controlling the Ramp-up periode */ -/* Ramp-up is done with 1 increment in speed every X number of TachoCount, where X depend on duration of the periode and the wanted speed */ -void dOutputRampUpFunction(UBYTE MotorNr) -{ - MOTORDATA * pMD = &(MotorData[MotorNr]); - if (pMD->MotorTargetSpeed == 0) - { - if (pMD->MotorSetSpeed > 0) - { - pMD->MotorTargetSpeed = MIN_MOVEMENT_POWER; - } - else - { - pMD->MotorTargetSpeed = -MIN_MOVEMENT_POWER; - } - } - else - { - if (pMD->MotorRampUpIncrement == 0) - { - SWORD delta = (SWORD)((pMD->MotorTachoCountToRun - pMD->MotorRampTachoCountStart) / (pMD->MotorSetSpeed - pMD->MotorTargetSpeed)); - if (pMD->MotorSetSpeed > 0) - { - pMD->MotorRampUpIncrement = delta; - } - else - { - pMD->MotorRampUpIncrement = -delta; - } - pMD->MotorRampTachoCountOld = pMD->CurrentCaptureCount; - } - if (pMD->MotorSetSpeed > 0) - { - if (pMD->CurrentCaptureCount > (pMD->MotorRampTachoCountOld + pMD->MotorRampUpIncrement)) - { - pMD->MotorTargetSpeed += 1; - pMD->MotorRampTachoCountOld = pMD->CurrentCaptureCount; - pMD->MotorRampUpCount = 0; - } - else - { - if (!(pMD->RegulationMode & REGSTATE_REGULATED)) - { - pMD->MotorRampUpCount++; - if (pMD->MotorRampUpCount > 100) - { - pMD->MotorRampUpCount = 0; - pMD->MotorTargetSpeed++; - } - } - } - } - else - { - if (pMD->CurrentCaptureCount < (pMD->MotorRampTachoCountOld + pMD->MotorRampUpIncrement)) - { - pMD->MotorTargetSpeed -= 1; - pMD->MotorRampTachoCountOld = pMD->CurrentCaptureCount; - pMD->MotorRampUpCount = 0; - } - else - { - if (!(pMD->RegulationMode & REGSTATE_REGULATED)) - { - pMD->MotorRampUpCount++; - if (pMD->MotorRampUpCount > 100) - { - pMD->MotorRampUpCount = 0; - pMD->MotorTargetSpeed--; - } - } - } - } - } - if (pMD->MotorSetSpeed > 0) - { - if ((pMD->CurrentCaptureCount - pMD->MotorRampTachoCountStart) >= (pMD->MotorTachoCountToRun - pMD->MotorRampTachoCountStart)) - { - pMD->MotorTargetSpeed = pMD->MotorSetSpeed; - pMD->MotorRunState = MOTOR_RUN_STATE_IDLE; - } - } - else - { - if ((pMD->CurrentCaptureCount + pMD->MotorRampTachoCountStart) <= (pMD->MotorTachoCountToRun + pMD->MotorRampTachoCountStart)) - { - pMD->MotorTargetSpeed = pMD->MotorSetSpeed; - pMD->MotorRunState = MOTOR_RUN_STATE_IDLE; - } - } - if (pMD->MotorSetSpeed > 0) - { - if (pMD->MotorTargetSpeed > pMD->MotorSetSpeed) - { - pMD->MotorTargetSpeed = pMD->MotorSetSpeed; - } - } - else - { - if (pMD->MotorTargetSpeed < pMD->MotorSetSpeed) - { - pMD->MotorTargetSpeed = pMD->MotorSetSpeed; - } - } - if (pMD->RegulationMode == REGSTATE_IDLE) - { - pMD->MotorActualSpeed = pMD->MotorTargetSpeed; - } -} - -/* Function used for controlling the Ramp-down periode */ -/* Ramp-down is done with 1 decrement in speed every X number of TachoCount, where X depend on duration of the periode and the wanted speed */ -void dOutputRampDownFunction(UBYTE MotorNr) -{ - MOTORDATA * pMD = &(MotorData[MotorNr]); - if (pMD->MotorRampDownIncrement == 0) - { - if (pMD->MotorTargetSpeed > 0) - { - if ((pMD->MotorTargetSpeed > MIN_MOVEMENT_POWER) && (pMD->MotorSetSpeed == 0)) - { - pMD->MotorRampDownIncrement = ((pMD->MotorTachoCountToRun - pMD->CurrentCaptureCount) / ((pMD->MotorTargetSpeed - pMD->MotorSetSpeed) - MIN_MOVEMENT_POWER)); - } - else - { - pMD->MotorRampDownIncrement = ((pMD->MotorTachoCountToRun - pMD->CurrentCaptureCount) / (pMD->MotorTargetSpeed - pMD->MotorSetSpeed)); - } - } - else - { - if ((pMD->MotorTargetSpeed < -MIN_MOVEMENT_POWER) && (pMD->MotorSetSpeed == 0)) - { - pMD->MotorRampDownIncrement = (-((pMD->MotorTachoCountToRun - pMD->CurrentCaptureCount) / ((pMD->MotorTargetSpeed - pMD->MotorSetSpeed) + MIN_MOVEMENT_POWER))); - } - else - { - pMD->MotorRampDownIncrement = (-((pMD->MotorTachoCountToRun - pMD->CurrentCaptureCount) / (pMD->MotorTargetSpeed - pMD->MotorSetSpeed))); - } - } - pMD->MotorRampTachoCountOld = pMD->CurrentCaptureCount; - } - if (pMD->MotorTargetSpeed > 0) - { - if (pMD->CurrentCaptureCount > (pMD->MotorRampTachoCountOld + (SLONG)pMD->MotorRampDownIncrement)) - { - pMD->MotorTargetSpeed--; - if (pMD->MotorTargetSpeed < MIN_MOVEMENT_POWER) - { - pMD->MotorTargetSpeed = MIN_MOVEMENT_POWER; - } - pMD->MotorRampTachoCountOld = pMD->CurrentCaptureCount; - pMD->MotorRampDownCount = 0; - dOutputRampDownSynch(MotorNr); - } - else - { - if (!(pMD->RegulationMode & REGSTATE_REGULATED)) - { - pMD->MotorRampDownCount++; - if (pMD->MotorRampDownCount > (UWORD)(30 * pMD->MotorRampDownIncrement)) - { - pMD->MotorRampDownCount = (UWORD)(20 * pMD->MotorRampDownIncrement); - pMD->MotorTargetSpeed++; - } - } - } - } - else - { - if (pMD->CurrentCaptureCount < (pMD->MotorRampTachoCountOld + (SLONG)pMD->MotorRampDownIncrement)) - { - pMD->MotorTargetSpeed++; - if (pMD->MotorTargetSpeed > -MIN_MOVEMENT_POWER) - { - pMD->MotorTargetSpeed = -MIN_MOVEMENT_POWER; - } - pMD->MotorRampTachoCountOld = pMD->CurrentCaptureCount; - pMD->MotorRampDownCount = 0; - dOutputRampDownSynch(MotorNr); - } - else - { - if (!(pMD->RegulationMode & REGSTATE_REGULATED)) - { - pMD->MotorRampDownCount++; - if (pMD->MotorRampDownCount > (UWORD)(30 * (-pMD->MotorRampDownIncrement))) - { - pMD->MotorRampDownCount = (UWORD)(20 * (-pMD->MotorRampDownIncrement)); - pMD->MotorTargetSpeed--; - } - } - } - } - if ((pMD->RegulationMode & REGSTATE_SYNCHRONE) && (pMD->TurnParameter != 0)) - { - dOutputSyncTachoLimitControl(MotorNr); - if (pMD->MotorRunState == MOTOR_RUN_STATE_IDLE) - { - dOutputMotorReachedTachoLimit(MotorNr); - } - } - else - { - if (pMD->MotorTargetSpeed > 0) - { - if (pMD->CurrentCaptureCount >= pMD->MotorTachoCountToRun) - { - dOutputMotorReachedTachoLimit(MotorNr); - } - } - else - { - if (pMD->CurrentCaptureCount <= pMD->MotorTachoCountToRun) - { - dOutputMotorReachedTachoLimit(MotorNr); - } - } - } - if (pMD->RegulationMode == REGSTATE_IDLE) - { - pMD->MotorActualSpeed = pMD->MotorTargetSpeed; - } -} - -/* Function used to tell whether the wanted position is obtained */ -void dOutputTachoLimitControl(UBYTE MotorNr) -{ - MOTORDATA * pMD = &(MotorData[MotorNr]); - if (pMD->RegulationMode & REGSTATE_POSITION) - { - /* No limit when doing absolute position regulation. */ - return; - } - if (pMD->MotorRunForever == 0) - { - if (pMD->RegulationMode & REGSTATE_SYNCHRONE) - { - dOutputSyncTachoLimitControl(MotorNr); - } - else - { - if (pMD->MotorSetSpeed > 0) - { - if ((pMD->CurrentCaptureCount >= pMD->MotorTachoCountToRun)) - { - pMD->MotorRunState = MOTOR_RUN_STATE_IDLE; - pMD->RegulationMode = REGSTATE_IDLE; - } - } - else - { - if (pMD->MotorSetSpeed < 0) - { - if (pMD->CurrentCaptureCount <= pMD->MotorTachoCountToRun) - { - pMD->MotorRunState = MOTOR_RUN_STATE_IDLE; - pMD->RegulationMode = REGSTATE_IDLE; - } - } - } - } - } - else - { - if (pMD->CurrentCaptureCount > MAX_COUNT_TO_RUN) - { - pMD->CurrentCaptureCount = 0; - } - if (pMD->MotorTargetSpeed != 0) - { - pMD->MotorTachoCountToRun = pMD->CurrentCaptureCount; - } - } - if (pMD->RegulationMode == REGSTATE_IDLE) - { - pMD->MotorActualSpeed = pMD->MotorTargetSpeed; - } -} - -/* Function used to decrease speed slowly when the motor is set to idle */ -void dOutputMotorIdleControl(UBYTE MotorNr) -{ - INSERTMode(MotorNr, COAST_MOTOR_MODE); - - MOTORDATA * pMD = &(MotorData[MotorNr]); - - if (pMD->MotorActualSpeed != 0) - { - if (pMD->MotorActualSpeed > 0) - { - pMD->MotorActualSpeed--; - } - else - { - pMD->MotorActualSpeed++; - } - } - - if (pMD->MotorTargetSpeed != 0) - { - if (pMD->MotorTargetSpeed > 0) - { - pMD->MotorTargetSpeed--; - } - else - { - pMD->MotorTargetSpeed++; - } - } - - if (pMD->MotorSetSpeed != 0) - { - if (pMD->MotorSetSpeed > 0) - { - pMD->MotorSetSpeed--; - } - else - { - pMD->MotorSetSpeed++; - } - } -} - -/* Check if Value is between [-Limit:Limit], and change it if it is not the case. */ -SLONG dOutputBound(SLONG Value, SLONG Limit) -{ - if (Value > Limit) - return Limit; - else if (Value < -Limit) - return -Limit; - else - return Value; -} - -/* Function called to evaluate which regulation princip that need to run and which MotorNr to use (I.E.: Which motors are synched together)*/ -void dOutputRegulateMotor(UBYTE MotorNr) -{ - UBYTE SyncMotorOne; - UBYTE SyncMotorTwo; - - MOTORDATA * pMD = &(MotorData[MotorNr]); - if (pMD->RegulationMode & REGSTATE_POSITION) - { - dOutputAbsolutePositionRegulation(MotorNr); - } - else if (pMD->RegulationMode & REGSTATE_REGULATED) - { - dOutputCalculateMotorPosition(MotorNr); - } - else - { - if (pMD->RegulationMode & REGSTATE_SYNCHRONE) - { - dOutputMotorSyncStatus(MotorNr, &SyncMotorOne, &SyncMotorTwo); - - if ((SyncMotorOne != 0xFF) &&(SyncMotorTwo != 0xFF)) - { - dOutputSyncMotorPosition(SyncMotorOne, SyncMotorTwo); - } - } - } -} - -/* Compute PID regulation result for a given error. */ -SLONG dOutputPIDRegulation(UBYTE MotorNr, SLONG PositionError) -{ - SLONG PValue, DValue, IValue, TotalRegValue; - - MOTORDATA *pMD = &MotorData[MotorNr]; - - PositionError = dOutputBound (PositionError, 32000); - - PValue = PositionError * (pMD->RegPParameter/REG_CONST_DIV); - - DValue = (PositionError - pMD->OldPositionError) * (pMD->RegDParameter/REG_CONST_DIV); - pMD->OldPositionError = PositionError; - - pMD->AccError = (pMD->AccError * 3 + PositionError) / 4; - pMD->AccError = dOutputBound (pMD->AccError, 800); - - IValue = pMD->AccError * (pMD->RegIParameter/REG_CONST_DIV); - - if (!(RegulationOptions & REGOPTION_NO_SATURATION)) - { - PValue = dOutputBound (PValue, REG_MAX_VALUE); - IValue = dOutputBound (IValue, REG_MAX_VALUE); - } - - TotalRegValue = (PValue + IValue + DValue) / 2; - - if (TotalRegValue > MAXIMUM_SPEED_FW) - { - TotalRegValue = MAXIMUM_SPEED_FW; - pMD->MotorOverloaded = 1; - } - else if (TotalRegValue < MAXIMUM_SPEED_RW) - { - TotalRegValue = MAXIMUM_SPEED_RW; - pMD->MotorOverloaded = 1; - } - - return TotalRegValue; -} - -/* Compute integer change for this regulation step, according to value and - * previous fractional error. - * Used for values which are expressed as "per SPEED_TIME" to translate them - * in "per RegulationTime".*/ -SLONG dOutputFractionalChange(SLONG Value, SWORD *FracError) -{ - SLONG IntegerChange; - - /* Apply fractional change in case RegulationTime is different from - * SPEED_TIME. In this case, fractional part is accumulated until it reach - * one half (with "one" being SPEED_TIME). This is use the same principle - * as the Bresenham algorithm. */ - IntegerChange = Value * RegulationTime / SPEED_TIME; - *FracError += Value * RegulationTime % SPEED_TIME; - if (*FracError > SPEED_TIME / 2) - { - *FracError -= SPEED_TIME; - IntegerChange++; - } - else if (*FracError < -SPEED_TIME / 2) - { - *FracError += SPEED_TIME; - IntegerChange--; - } - - return IntegerChange; -} - -/* Filter speed according to motor maximum speed and acceleration. */ -void dOutputSpeedFilter(UBYTE MotorNr, SLONG PositionDiff) -{ - /* Inputs: - * - PositionDiff: difference between current position and position to reach. - * - MotorMaxAcceleration: maximum speed change per regulation period (or 0 for unlimited). - * - MotorMaxSpeed: maximum motor speed (can not be zero, or do not call this function). - * Output: - * - MotorTargetSpeed: speed to regulate on motor. - */ - MOTORDATA *pMD = &MotorData[MotorNr]; - SLONG IdealSpeed; - SLONG PositionDiffAbs = ABS (PositionDiff); - /* Should be able to brake on time. */ - if (pMD->MotorMaxAcceleration - && PositionDiffAbs < MAXIMUM_SPEED_FW * MAXIMUM_SPEED_FW / 2) - { - IdealSpeed = sqrtf (2 * PositionDiffAbs * pMD->MotorMaxAcceleration); - IdealSpeed = dOutputBound (IdealSpeed, pMD->MotorMaxSpeed); - } - else - { - /* Do not go past consign. */ - IdealSpeed = MIN (PositionDiffAbs, pMD->MotorMaxSpeed); - } - /* Apply sign. */ - if (PositionDiff < 0) - { - IdealSpeed = -IdealSpeed; - } - /* Check max acceleration. */ - SLONG SpeedDiff = IdealSpeed - pMD->MotorTargetSpeed; - if (pMD->MotorMaxAcceleration) - { - SLONG MaxSpeedChange = dOutputFractionalChange (pMD->MotorMaxAcceleration, &pMD->SpeedFracError); - SpeedDiff = dOutputBound (SpeedDiff, MaxSpeedChange); - } - pMD->MotorTargetSpeed += SpeedDiff; -} - -/* Absolute position regulation. */ -void dOutputAbsolutePositionRegulation(UBYTE MotorNr) -{ - /* Inputs: - * - CurrentCaptureCount: current motor position. - * - MotorTachoCountToRun: wanted position, filtered with speed and acceleration. - * - * Outputs: - * - MotorActualSpeed: power to be applied to motor. - * - MotorOverloaded: set if MotorActualSpeed reached maximum. - */ - SLONG PositionChange; - SLONG PositionError; - SLONG TotalRegValue; - - MOTORDATA *pMD = &MotorData[MotorNr]; - - /* Position update. */ - if (pMD->MotorMaxSpeed) - { - dOutputSpeedFilter (MotorNr, pMD->MotorTachoCountToRun - pMD->MotorTachoCountTarget); - PositionChange = dOutputFractionalChange (pMD->MotorTargetSpeed * MAX_CAPTURE_COUNT / INPUT_SCALE_FACTOR, &pMD->PositionFracError); - pMD->MotorTachoCountTarget += PositionChange; - } - else - { - pMD->MotorTachoCountTarget = pMD->MotorTachoCountToRun; - } - - /* Regulation. */ - PositionError = pMD->MotorTachoCountTarget - pMD->CurrentCaptureCount; - TotalRegValue = dOutputPIDRegulation (MotorNr, PositionError); - - pMD->MotorActualSpeed = TotalRegValue; -} - -/* Regulation function used when Position regulation is enabled */ -/* The regulation form only control one motor at a time */ -void dOutputCalculateMotorPosition(UBYTE MotorNr) -{ - SLONG PositionError; - SLONG TotalRegValue; - SLONG PositionChange; - - MOTORDATA * pMD = &(MotorData[MotorNr]); - - PositionChange = dOutputFractionalChange (pMD->MotorTargetSpeed * MAX_CAPTURE_COUNT / INPUT_SCALE_FACTOR, &pMD->PositionFracError); - - PositionError = (pMD->OldPositionError - pMD->DeltaCaptureCount) + PositionChange; - - TotalRegValue = dOutputPIDRegulation (MotorNr, PositionError); - - pMD->MotorActualSpeed = (SBYTE)TotalRegValue; -} - -/* Regulation function used when syncrhonization regulation is enabled */ -/* The regulation form controls two motors at a time */ -void dOutputSyncMotorPosition(UBYTE MotorOne, UBYTE MotorTwo) -{ - SLONG TempTurnParameter; - SLONG PValue; - SLONG IValue; - SLONG DValue; - SLONG CorrectionValue; - SLONG MotorSpeed; - - MOTORDATA * pOne = &(MotorData[MotorOne]); - MOTORDATA * pTwo = &(MotorData[MotorTwo]); - SyncData.SyncTachoDif = (SLONG)((pOne->MotorBlockTachoCount) - (pTwo->MotorBlockTachoCount)); - - if (pOne->TurnParameter != 0) - { - if ((pOne->MotorBlockTachoCount != 0) || (pTwo->MotorBlockTachoCount != 0)) - { - if (pOne->MotorTargetSpeed >= 0) - { - if (pOne->TurnParameter > 0) - { - TempTurnParameter = (SLONG)(((SLONG)pTwo->TurnParameter * (SLONG)pTwo->MotorTargetSpeed)/100); - } - else - { - TempTurnParameter = (SLONG)(((SLONG)pOne->TurnParameter * (SLONG)pOne->MotorTargetSpeed)/100); - } - } - else - { - if (pOne->TurnParameter > 0) - { - TempTurnParameter = (SLONG)(((SLONG)pOne->TurnParameter * (-(SLONG)pOne->MotorTargetSpeed))/100); - } - else - { - TempTurnParameter = (SLONG)(((SLONG)pTwo->TurnParameter * (-(SLONG)pTwo->MotorTargetSpeed))/100); - } - } - } - else - { - TempTurnParameter = pOne->TurnParameter; - } - } - else - { - TempTurnParameter = 0; - } - - SyncData.SyncTurnParameter += (SLONG)(((TempTurnParameter * (MAX_CAPTURE_COUNT))/INPUT_SCALE_FACTOR)*2); - //SyncTurnParameter should ophold difference between the two motors. - - SyncData.SyncTachoDif += SyncData.SyncTurnParameter; - SyncData.SyncTachoDif = dOutputBound (SyncData.SyncTachoDif, 500); - - PValue = SyncData.SyncTachoDif * (pOne->RegPParameter/REG_CONST_DIV); - - DValue = (SyncData.SyncTachoDif - SyncData.SyncOldError) * (pOne->RegDParameter/REG_CONST_DIV); - SyncData.SyncOldError = (SWORD)SyncData.SyncTachoDif; - - SyncData.SyncAccError += (SWORD)SyncData.SyncTachoDif; - SyncData.SyncAccError = dOutputBound (SyncData.SyncAccError, 900); - - IValue = SyncData.SyncAccError * (pOne->RegIParameter/REG_CONST_DIV); - - CorrectionValue = (PValue + IValue + DValue) / 4; - - MotorSpeed = pOne->MotorTargetSpeed - CorrectionValue; - MotorSpeed = dOutputBound (MotorSpeed, MAXIMUM_SPEED_FW); - - if (pOne->TurnParameter != 0) - { - if (pOne->MotorTargetSpeed > 0) - { - MotorSpeed = dOutputBound (MotorSpeed, pOne->MotorTargetSpeed); - } - else - { - MotorSpeed = dOutputBound (MotorSpeed, -pOne->MotorTargetSpeed); - } - } - pOne->MotorActualSpeed = (SBYTE)MotorSpeed; - - MotorSpeed = pTwo->MotorTargetSpeed + CorrectionValue; - MotorSpeed = dOutputBound (MotorSpeed, MAXIMUM_SPEED_FW); - - if (pOne->TurnParameter != 0) - { - if (pTwo->MotorTargetSpeed > 0) - { - MotorSpeed = dOutputBound (MotorSpeed, pTwo->MotorTargetSpeed); - } - else - { - MotorSpeed = dOutputBound (MotorSpeed, -pTwo->MotorTargetSpeed); - } - } - pTwo->MotorActualSpeed = (SBYTE)MotorSpeed; -} - -//Called when the motor is ramping down -void dOutputMotorReachedTachoLimit(UBYTE MotorNr) -{ - MOTORDATA * pOne = &(MotorData[MotorNr]); - if (pOne->RegulationMode & REGSTATE_SYNCHRONE) - { - UBYTE MotorOne, MotorTwo; - MotorOne = MotorNr; - MotorTwo = 0xFF; - UBYTE i; - for(i = MOTOR_A; i <= MOTOR_C; i++) { - if (i == MotorOne) - continue; - if (MotorData[i].RegulationMode & REGSTATE_SYNCHRONE) { - MotorTwo = i; - break; - } - } - pOne->MotorSetSpeed = 0; - pOne->MotorTargetSpeed = 0; - pOne->MotorActualSpeed = 0; - pOne->MotorRunState = MOTOR_RUN_STATE_IDLE; - pOne->RegulationMode = REGSTATE_IDLE; - if (MotorTwo != 0xFF) { - MOTORDATA * pTwo = &(MotorData[MotorTwo]); - pTwo->MotorSetSpeed = 0; - pTwo->MotorTargetSpeed = 0; - pTwo->MotorActualSpeed = 0; - pTwo->MotorRunState = MOTOR_RUN_STATE_IDLE; - pTwo->RegulationMode = REGSTATE_IDLE; - } - } - else - { - if (pOne->MotorSetSpeed == 0) - { - pOne->MotorTargetSpeed = 0; - pOne->MotorActualSpeed = 0; - } - pOne->MotorRunState = MOTOR_RUN_STATE_IDLE; - pOne->RegulationMode = REGSTATE_IDLE; - } -} - -/* Function used for control tacho limit when motors are synchronised */ -/* Special control is needed when the motor are turning */ -void dOutputSyncTachoLimitControl(UBYTE MotorNr) -{ - UBYTE MotorOne, MotorTwo; - - MotorOne = MotorNr; - MotorTwo = 0xFF; - // Synchronisation is done two times, as this function is called for each - // motor. This is the same behaviour as previous code. - UBYTE i; - for(i = MOTOR_A; i <= MOTOR_C; i++) { - if (i == MotorOne) - continue; - if (MotorData[i].RegulationMode & REGSTATE_SYNCHRONE) { - MotorTwo = i; - break; - } - } - if (MotorTwo == 0xFF) - MotorOne = 0xFF; - - if ((MotorOne != 0xFF) && (MotorTwo != 0xFF)) - { - MOTORDATA * pOne = &(MotorData[MotorOne]); - MOTORDATA * pTwo = &(MotorData[MotorTwo]); - if (pOne->TurnParameter != 0) - { - if (pOne->TurnParameter > 0) - { - if (pTwo->MotorTargetSpeed >= 0) - { - if ((SLONG)(pTwo->CurrentCaptureCount >= pTwo->MotorTachoCountToRun)) - { - pOne->MotorRunState = MOTOR_RUN_STATE_IDLE; - pTwo->MotorRunState = MOTOR_RUN_STATE_IDLE; - - pOne->CurrentCaptureCount = pTwo->CurrentCaptureCount; - pOne->MotorTachoCountToRun = pTwo->MotorTachoCountToRun; - } - } - else - { - if ((SLONG)(pOne->CurrentCaptureCount <= pOne->MotorTachoCountToRun)) - { - pOne->MotorRunState = MOTOR_RUN_STATE_IDLE; - pTwo->MotorRunState = MOTOR_RUN_STATE_IDLE; - - pTwo->CurrentCaptureCount = pOne->CurrentCaptureCount; - pTwo->MotorTachoCountToRun = pOne->MotorTachoCountToRun; - } - } - } - else - { - if (pOne->MotorTargetSpeed >= 0) - { - if ((SLONG)(pOne->CurrentCaptureCount >= pOne->MotorTachoCountToRun)) - { - pOne->MotorRunState = MOTOR_RUN_STATE_IDLE; - pTwo->MotorRunState = MOTOR_RUN_STATE_IDLE; - - pTwo->CurrentCaptureCount = pOne->CurrentCaptureCount; - pTwo->MotorTachoCountToRun = pOne->MotorTachoCountToRun; - } - } - else - { - if ((SLONG)(pTwo->CurrentCaptureCount <= pTwo->MotorTachoCountToRun)) - { - pOne->MotorRunState = MOTOR_RUN_STATE_IDLE; - pTwo->MotorRunState = MOTOR_RUN_STATE_IDLE; - - pOne->CurrentCaptureCount = pTwo->CurrentCaptureCount; - pOne->MotorTachoCountToRun = pTwo->MotorTachoCountToRun; - } - } - } - } - else - { - if (pOne->MotorSetSpeed > 0) - { - if ((pOne->CurrentCaptureCount >= pOne->MotorTachoCountToRun) || (pTwo->CurrentCaptureCount >= pTwo->MotorTachoCountToRun)) - { - pOne->MotorRunState = MOTOR_RUN_STATE_IDLE; - pTwo->MotorRunState = MOTOR_RUN_STATE_IDLE; - } - } - else - { - if (pOne->MotorSetSpeed < 0) - { - if ((pOne->CurrentCaptureCount <= pOne->MotorTachoCountToRun) || (pTwo->CurrentCaptureCount <= pTwo->MotorTachoCountToRun)) - { - pOne->MotorRunState = MOTOR_RUN_STATE_IDLE; - pTwo->MotorRunState = MOTOR_RUN_STATE_IDLE; - } - } - } - } - } -} - -/* Function which can evaluate which motor are synched */ -void dOutputMotorSyncStatus(UBYTE MotorNr, UBYTE *SyncMotorOne, UBYTE *SyncMotorTwo) -{ - if (MotorNr < MOTOR_C) - { - if (MotorNr == MOTOR_A) - { - *SyncMotorOne = MotorNr; - *SyncMotorTwo = *SyncMotorOne + 1; - if (MotorData[*SyncMotorTwo].RegulationMode & REGSTATE_SYNCHRONE) - { - //Synchronise motor A & B - } - else - { - *SyncMotorTwo = *SyncMotorOne + 2; - if (MotorData[*SyncMotorTwo].RegulationMode & REGSTATE_SYNCHRONE) - { - //Synchronise motor A & C - } - else - { - //Only Motor A has Sync setting => Do nothing, treat motor as motor without regulation - *SyncMotorTwo = 0xFF; - } - } - } - if (MotorNr == MOTOR_B) - { - *SyncMotorOne = MotorNr; - *SyncMotorTwo = *SyncMotorOne + 1; - if (MotorData[*SyncMotorTwo].RegulationMode & REGSTATE_SYNCHRONE) - { - if (!(MotorData[MOTOR_A].RegulationMode & REGSTATE_SYNCHRONE)) - { - //Synchronise motor B & C - } - } - else - { - //Only Motor B has Sync settings or Motor is sync. with Motor A and has therefore already been called - *SyncMotorTwo = 0xFF; - } - } - } - else - { - *SyncMotorOne = 0xFF; - *SyncMotorTwo = 0xFF; - } -} -/* Function which is called when motors are synchronized and the motor position is reset */ -void dOutputResetSyncMotors(UBYTE MotorNr) -{ - UBYTE MotorOne, MotorTwo; - - MotorOne = MotorNr; - MotorTwo = 0xFF; - UBYTE i; - for(i = MOTOR_A; i <= MOTOR_C; i++) { - if (i == MotorOne) - continue; - if (MotorData[i].RegulationMode & REGSTATE_SYNCHRONE) { - MotorTwo = i; - break; - } - } - if (MotorTwo == 0xFF) - MotorOne = 0xFF; - - MOTORDATA * pMD = &(MotorData[MotorNr]); - if ((MotorOne != 0xFF) && (MotorTwo != 0xFF)) - { - MOTORDATA * pTwo = &(MotorData[MotorTwo]); - pMD->CurrentCaptureCount = 0; - pMD->MotorTachoCountToRun = 0; - pMD->MotorTachoCountTarget = 0; - pTwo->CurrentCaptureCount = 0; - pTwo->MotorTachoCountToRun = 0; - pTwo->MotorTachoCountTarget = 0; - } - else - { - pMD->CurrentCaptureCount = 0; - pMD->MotorTachoCountToRun = 0; - pMD->MotorTachoCountTarget = 0; - } -} - -/* Function which is called when motors are synchronized and motor is ramping down */ -void dOutputRampDownSynch(UBYTE MotorNr) -{ - UBYTE MotorOne, MotorTwo; - - MotorOne = MotorNr; - MotorTwo = 0xFF; - UBYTE i; - for(i = MOTOR_A; i <= MOTOR_C; i++) { - if (i == MotorOne) - continue; - if (MotorData[i].RegulationMode & REGSTATE_SYNCHRONE) { - MotorTwo = i; - break; - } - } - if (MotorTwo == 0xFF) - MotorOne = 0xFF; - - if ((MotorOne != 0xFF) && (MotorTwo != 0xFF)) - { - MOTORDATA * pOne = &(MotorData[MotorOne]); - MOTORDATA * pTwo = &(MotorData[MotorTwo]); - if (pOne->TurnParameter != 0) - { - if (pOne->TurnParameter > 0) - { - if (pOne->MotorTargetSpeed >= 0) - { - if (pTwo->MotorActualSpeed < 0) - { - pTwo->MotorTargetSpeed--; - } - } - else - { - if (pTwo->MotorActualSpeed > 0) - { - pTwo->MotorTargetSpeed++; - } - } - } - else - { - if (pOne->MotorTargetSpeed >= 0) - { - if (pTwo->MotorActualSpeed < 0) - { - pTwo->MotorTargetSpeed--; - } - } - else - { - if (pTwo->MotorActualSpeed > 0) - { - pTwo->MotorTargetSpeed++; - } - } - } - } - } -} - diff --git a/AT91SAM7S256/Source/d_output.h b/AT91SAM7S256/Source/d_output.h deleted file mode 100644 index 4d5189b..0000000 --- a/AT91SAM7S256/Source/d_output.h +++ /dev/null @@ -1,103 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: d_output.h $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_outp $ -// -// Platform C -// - -#ifndef D_OUTPUT -#define D_OUTPUT - -#define NEW_MOTOR - -#ifdef NEW_MOTOR - -//Constant reffering to new motor -#define REG_CONST_DIV 32 // Constant which the PID constants value will be divided with -#define DEFAULT_P_GAIN_FACTOR 96//3 -#define DEFAULT_I_GAIN_FACTOR 32//1 -#define DEFAULT_D_GAIN_FACTOR 32//1 -#define MIN_MOVEMENT_POWER 10 -#define MAX_CAPTURE_COUNT 100 - -#else - -//Constant reffering to Old motor -#define REG_CONST_DIV 1 // Constant which the PID constants value will be divided with -#define DEFAULT_P_GAIN_FACTOR 3 -#define DEFAULT_I_GAIN_FACTOR 1 -#define DEFAULT_D_GAIN_FACTOR 1 -#define MIN_MOVEMENT_POWER 30 -#define MAX_CAPTURE_COUNT 80 - -#endif - -#define DEFAULT_MAX_SPEED 80 -#define DEFAULT_MAX_ACCELERATION 20 - -#define REGULATION_TIME 100 // Measured in 1 mS, regulation interval - -//Constant reffering to RegMode parameter -#define REGSTATE_IDLE 0x00 -#define REGSTATE_REGULATED 0x01 -#define REGSTATE_SYNCHRONE 0x02 -#define REGSTATE_POSITION 0x04 - -//Constant reffering to RunState parameter -#define MOTOR_RUN_STATE_IDLE 0x00 -#define MOTOR_RUN_STATE_RAMPUP 0x10 -#define MOTOR_RUN_STATE_RUNNING 0x20 -#define MOTOR_RUN_STATE_RAMPDOWN 0x40 -#define MOTOR_RUN_STATE_HOLD 0x60 - -// Constants related to Regulation Options -#define REGOPTION_NO_SATURATION 0x01 // Do not limit intermediary regulation results - - -enum -{ - MOTOR_A, - MOTOR_B, - MOTOR_C -}; - -void dOutputInit(void); -void dOutputExit(void); - -void dOutputCtrl(void); -void dOutputGetMotorParameters(UBYTE *CurrentMotorSpeed, SLONG *TachoCount, SLONG *BlockTachoCount, UBYTE *RunState, UBYTE *MotorOverloaded, SLONG *RotationCount); -void dOutputSetMode(UBYTE MotorNr, UBYTE Mode); -void dOutputSetSpeed (UBYTE MotorNr, UBYTE NewMotorRunState, SBYTE Speed, SBYTE TurnParameter); -void dOutputEnableRegulation(UBYTE MotorNr, UBYTE RegulationMode); -void dOutputDisableRegulation(UBYTE MotorNr); -void dOutputSetTachoLimit(UBYTE MotorNr, ULONG TachoCntToTravel); -void dOutputResetTachoLimit(UBYTE MotorNr); -void dOutputResetBlockTachoLimit(UBYTE MotorNr); -void dOutputResetRotationCaptureCount(UBYTE MotorNr); -void dOutputSetPIDParameters(UBYTE MotorNr, UBYTE NewRegPParameter, UBYTE NewRegIParameter, UBYTE NewRegDParameter); -void dOutputSetMax(UBYTE MotorNr, SBYTE NewMaxSpeed, SBYTE NewMaxAcceleration); -void dOutputSetRegulationTime(UBYTE NewRegulationTime); -void dOutputSetRegulationOptions(UBYTE NewRegulationOptions); - -void dOutputRegulateMotor(UBYTE MotorNr); -void dOutputCalculateRampUpParameter(UBYTE MotorNr, ULONG NewTachoLimit); -void dOutputRampDownFunction(UBYTE MotorNr); -void dOutputRampUpFunction(UBYTE MotorNr); -void dOutputTachoLimitControl(UBYTE MotorNr); -void dOutputAbsolutePositionRegulation(UBYTE MotorNr); -void dOutputCalculateMotorPosition(UBYTE MotorNr); -void dOutputSyncMotorPosition(UBYTE MotorOne, UBYTE MotorTwo); -void dOutputMotorReachedTachoLimit(UBYTE MotorNr); -void dOutputMotorIdleControl(UBYTE MotorNr); -void dOutputSyncTachoLimitControl(UBYTE MotorNr); -void dOutputMotorSyncStatus(UBYTE MotorNr, UBYTE *SyncMotorOne, UBYTE *SyncMotorTwo); -void dOutputResetSyncMotors(UBYTE MotorNr); - -#endif diff --git a/AT91SAM7S256/Source/d_output.r b/AT91SAM7S256/Source/d_output.r deleted file mode 100644 index 1a30c5f..0000000 --- a/AT91SAM7S256/Source/d_output.r +++ /dev/null @@ -1,306 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: d_output.r $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_outp $ -// -// Platform C -// - -#ifdef SAM7S256 - -#if defined (PROTOTYPE_PCB_3) || (PROTOTYPE_PCB_4) - -#define MOTOR_A_DIR AT91C_PIO_PA1 -#define MOTOR_A_INT AT91C_PIO_PA15 - -#define MOTOR_B_DIR AT91C_PIO_PA9 -#define MOTOR_B_INT AT91C_PIO_PA26 - -#define MOTOR_C_DIR AT91C_PIO_PA8 -#define MOTOR_C_INT AT91C_PIO_PA0 - -#else - -#define MOTOR_A_DIR AT91C_PIO_PA1 -#define MOTOR_A_INT AT91C_PIO_PA15 - -#define MOTOR_B_DIR AT91C_PIO_PA9 -#define MOTOR_B_INT AT91C_PIO_PA26 - -#define MOTOR_C_DIR AT91C_PIO_PA8 -#define MOTOR_C_INT AT91C_PIO_PA27 - -#endif - -#define FORWARD 0x01 -#define REVERSE -0x01 - -#define TIMER_0_ID12 (1L << AT91C_ID_TC0) -#define TIMER_1_ID13 (1L << AT91C_ID_TC1) -#define TIMER_2_ID14 (1L << AT91C_ID_TC2) - -typedef struct -{ - SLONG TachoCountTable; - SLONG TachoCountTableOld; - SBYTE MotorDirection; -}TACHOPARAMETERS; - -static TACHOPARAMETERS MotorTachoValue[3]; - -#define OUTPUTInit {\ - UBYTE Tmp;\ - for (Tmp = 0; Tmp < NOS_OF_AVR_OUTPUTS; Tmp++)\ - {\ - IoToAvr.PwmValue[Tmp] = 0;\ - }\ - IoToAvr.OutputMode = 0x00;\ - IoToAvr.PwmFreq = 8;\ - } - -#define INSERTSpeed(Motor, Speed) IoToAvr.PwmValue[Motor] = Speed - -#define INSERTMode(Motor, Mode) if (Mode & 0x02)\ - {\ - IoToAvr.OutputMode |= (0x01 << Motor);\ - }\ - else\ - {\ - IoToAvr.OutputMode &= ~(0x01 << Motor);\ - } - -#define ENABLEDebugOutput {\ - *AT91C_PIOA_PER = 0x20000000; /* Enable PIO on PA029 */\ - *AT91C_PIOA_OER = 0x20000000; /* PA029 set to Output */\ - } - -#define SETDebugOutputHigh *AT91C_PIOA_SODR = 0x20000000 - -#define SETDebugOutputLow *AT91C_PIOA_CODR = 0x20000000 - -#define ENABLECaptureMotorA {\ - *AT91C_PIOA_PDR = MOTOR_A_INT; /* Disable PIO on PA15 */\ - *AT91C_PIOA_BSR = MOTOR_A_INT; /* Enable Peripheral B on PA15 */\ - *AT91C_PIOA_PPUDR = MOTOR_A_INT | MOTOR_A_DIR; /* Disable Pull Up resistor on PA15 & PA1 */\ - *AT91C_PIOA_PER = MOTOR_A_DIR; /* Enable PIO on PA1 */\ - *AT91C_PIOA_ODR = MOTOR_A_DIR; /* PA1 set to input */\ - *AT91C_PIOA_IFER = MOTOR_A_INT | MOTOR_A_DIR; /* Enable filter on PA15 & PA1 */\ - *AT91C_PMC_PCER = TIMER_1_ID13; /* Enable clock for TC1*/\ - *AT91C_TCB_BMR = AT91C_TCB_TC1XC1S_NONE; /* No external clock signal XC2 */\ - *AT91C_TCB_BCR = 0x0; /* Clear SYNC */\ - *AT91C_TC1_CMR = *AT91C_TC1_CMR & 0X00000000; /* Clear all bits in TC1_CMR */\ - *AT91C_TC1_CMR = *AT91C_TC1_CMR & 0xFFFF7FFF; /* Enable capture mode */\ - *AT91C_TC1_CMR = *AT91C_TC1_CMR | AT91C_TC_CLKS_TIMER_DIV5_CLOCK; /* Set clock for timer to Clock5 = div 1024*/\ - *AT91C_TC1_CMR = *AT91C_TC1_CMR | AT91C_TC_ABETRG; /* Use external trigger for TIO1*/\ - *AT91C_TC1_CMR = *AT91C_TC1_CMR | AT91C_TC_EEVTEDG_BOTH; /* Trigger on both edges */\ - *AT91C_TC1_CMR = *AT91C_TC1_CMR | AT91C_TC_LDRA_RISING; /* RA loading register set */\ - *AT91C_AIC_IDCR = TIMER_1_ID13; /* Irq controller setup */\ - AT91C_AIC_SVR[13] = (unsigned int)CaptureAInt; \ - AT91C_AIC_SMR[13] = 0x05; /* Enable trigger on level */\ - *AT91C_AIC_ICCR = TIMER_1_ID13; /* Clear interrupt register PID13*/\ - *AT91C_TC1_IDR = 0xFF; /* Disable all interrupt from TC1 */\ - *AT91C_TC1_IER = 0x80; /* Enable interrupt from external trigger */\ - *AT91C_AIC_IECR = TIMER_1_ID13; /* Enable interrupt from TC1 */\ - *AT91C_TC1_CCR = 0x00; /* Clear registers before setting */\ - *AT91C_TC1_CCR = AT91C_TC_CLKEN; /* Enable clock */\ - } - -#define ENABLECaptureMotorB {\ - *AT91C_PIOA_PDR = MOTOR_B_INT; /* Disable PIO on PA26 */\ - *AT91C_PIOA_BSR = MOTOR_B_INT; /* Enable Peripheral B on PA26 */\ - *AT91C_PIOA_PER = MOTOR_B_DIR; /* Enable PIO on PA09 */\ - *AT91C_PIOA_PPUDR = MOTOR_B_INT | MOTOR_B_DIR; /* Disable Pull Up resistor on PA26 & PA09 */\ - *AT91C_PIOA_ODR = MOTOR_B_DIR; /* PA09 set to input */\ - *AT91C_PIOA_IFER = MOTOR_B_INT | MOTOR_B_DIR; /* Enable filter on PA26 & PA09 */\ - *AT91C_PMC_PCER = TIMER_2_ID14; /* Enable clock for TC2*/\ - *AT91C_TCB_BMR = AT91C_TCB_TC2XC2S_NONE; /* No external clock signal */\ - *AT91C_TCB_BCR = 0x0; /* Clear SYNC */\ - *AT91C_TC2_CMR = *AT91C_TC2_CMR & 0X00000000; /* Clear all bits in TC1_CMR */\ - *AT91C_TC2_CMR = *AT91C_TC2_CMR & 0xFFFF7FFF; /* Enable capture mode */\ - *AT91C_TC2_CMR = *AT91C_TC2_CMR | AT91C_TC_CLKS_TIMER_DIV5_CLOCK; /* Set clock for timer to Clock5 = div 1024*/\ - *AT91C_TC2_CMR = *AT91C_TC2_CMR | AT91C_TC_ABETRG; /* Use external trigger for TIO2*/\ - *AT91C_TC2_CMR = *AT91C_TC2_CMR | AT91C_TC_EEVTEDG_BOTH; /* Trigger on both edges */\ - *AT91C_TC2_CMR = *AT91C_TC2_CMR | AT91C_TC_LDRA_RISING; /* RA loading register set */\ - *AT91C_AIC_IDCR = TIMER_2_ID14; /* Irq controller setup */\ - AT91C_AIC_SVR[14] = (unsigned int)CaptureBInt; \ - AT91C_AIC_SMR[14] = 0x05; /* Enable trigger on level */\ - *AT91C_AIC_ICCR = TIMER_2_ID14; /* Clear interrupt register PID14*/\ - *AT91C_TC2_IDR = 0xFF; /* Disable all interrupt from TC2 */\ - *AT91C_TC2_IER = 0x80; /* Enable interrupts from external trigger */\ - *AT91C_AIC_IECR = TIMER_2_ID14; /* Enable interrupt from TC2 */\ - *AT91C_TC2_CCR = 0x00; /* Clear registers before setting */\ - *AT91C_TC2_CCR = AT91C_TC_CLKEN; /* Enable clock */\ - } - - #define ENABLECaptureMotorC {\ - *AT91C_PIOA_PDR = MOTOR_C_INT; /* Disable PIO on PA0 */\ - *AT91C_PIOA_BSR = MOTOR_C_INT; /* Enable Peripheral B on PA0 */\ - *AT91C_PIOA_PER = MOTOR_C_DIR; /* Enable PIO on PA08 */\ - *AT91C_PIOA_PPUDR = MOTOR_C_INT | MOTOR_C_DIR; /* Disable Pull Up resistor on PA0 & PA08 */\ - *AT91C_PIOA_ODR = MOTOR_C_DIR; /* PA08 set to input */\ - *AT91C_PIOA_IFER = MOTOR_C_INT | MOTOR_C_DIR; /* Enable filter on PA26 & PA09 */\ - *AT91C_PMC_PCER = TIMER_0_ID12; /* Enable clock for TC0*/\ - *AT91C_TCB_BMR = AT91C_TCB_TC0XC0S_NONE; /* No external clock signal */\ - *AT91C_TC0_CMR = *AT91C_TC0_CMR & 0X00000000; /* Clear all bits in TC0_CMR */\ - *AT91C_TC0_CMR = *AT91C_TC0_CMR & 0xFFFF7FFF; /* Enable capture mode */\ - *AT91C_TC0_CMR = *AT91C_TC0_CMR | AT91C_TC_CLKS_TIMER_DIV5_CLOCK; /* Set clock for timer to Clock5 = div 1024*/\ - *AT91C_TC0_CMR = *AT91C_TC0_CMR | AT91C_TC_ABETRG; /* Use external trigger for TI0*/\ - *AT91C_TC0_CMR = *AT91C_TC0_CMR | AT91C_TC_EEVTEDG_BOTH; /* Trigger on both edges */\ - *AT91C_TC0_CMR = *AT91C_TC0_CMR | AT91C_TC_LDRA_RISING; /* RA loading register set */\ - *AT91C_AIC_IDCR = TIMER_0_ID12; /* Disable interrupt */\ - AT91C_AIC_SVR[12] = (unsigned int)CaptureCInt; \ - AT91C_AIC_SMR[12] = 0x05; /* Enable trigger on level */\ - *AT91C_AIC_ICCR = TIMER_0_ID12; /* Clear interrupt register PID12*/\ - *AT91C_TC0_IDR = 0xFF; /* Disable all interrupt from TC0 */\ - *AT91C_TC0_IER = 0x80; /* Enable interrupts from external trigger */\ - *AT91C_AIC_IECR = TIMER_0_ID12; /* Enable interrupt from TC0 */\ - *AT91C_TC0_CCR = 0x00; /* Clear registers before setting */\ - *AT91C_TC0_CCR = AT91C_TC_CLKEN; /* Enable clock */\ - } - -__ramfunc void CaptureAInt(void) -{ - if (*AT91C_TC1_SR & AT91C_TC_MTIOA) - { - if (*AT91C_PIOA_PDSR & MOTOR_A_DIR) - { - MotorTachoValue[0].MotorDirection = REVERSE; //Motor is running reverse - MotorTachoValue[0].TachoCountTable--; - } - else - { - MotorTachoValue[0].MotorDirection = FORWARD; //Motor is running forward - MotorTachoValue[0].TachoCountTable++; - } - } - else - { - if (*AT91C_PIOA_PDSR & MOTOR_A_DIR) - { - MotorTachoValue[0].MotorDirection = FORWARD; - MotorTachoValue[0].TachoCountTable++; - } - else - { - MotorTachoValue[0].MotorDirection = REVERSE; - MotorTachoValue[0].TachoCountTable--; - } - } -} - -__ramfunc void CaptureBInt(void) -{ - if (*AT91C_TC2_SR & AT91C_TC_MTIOA) - { - if (*AT91C_PIOA_PDSR & MOTOR_B_DIR) - { - MotorTachoValue[1].MotorDirection = REVERSE; //Motor is running reverse - MotorTachoValue[1].TachoCountTable--; - } - else - { - MotorTachoValue[1].MotorDirection = FORWARD; //Motor is running forward - MotorTachoValue[1].TachoCountTable++; - } - } - else - { - if (*AT91C_PIOA_PDSR & MOTOR_B_DIR) - { - MotorTachoValue[1].MotorDirection = FORWARD; - MotorTachoValue[1].TachoCountTable++; - } - else - { - MotorTachoValue[1].MotorDirection = REVERSE; - MotorTachoValue[1].TachoCountTable--; - } - } -} - - -//__ramfunc void CaptureBInt(void) -//{ -// if (((bool)(*AT91C_TC2_SR & AT91C_TC_MTIOA))==((bool)(*AT91C_PIOA_PDSR & MOTOR_B_DIR))) -// { -// MotorTachoValue[1].MotorDirection = REVERSE; //Motor is running reverse -// MotorTachoValue[1].TachoCountTable--; -// } -// else -// { -// MotorTachoValue[1].MotorDirection = FORWARD; //Motor is running reverse -// MotorTachoValue[1].TachoCountTable++; -// } -//} - - -__ramfunc void CaptureCInt(void) -{ - if (*AT91C_TC0_SR & AT91C_TC_MTIOA) - { - if (*AT91C_PIOA_PDSR & MOTOR_C_DIR) - { - MotorTachoValue[2].MotorDirection = REVERSE; //Motor is running reverse - MotorTachoValue[2].TachoCountTable--; - } - else - { - MotorTachoValue[2].MotorDirection = FORWARD; //Motor is running forward - MotorTachoValue[2].TachoCountTable++; - } - } - else - { - if (*AT91C_PIOA_PDSR & MOTOR_C_DIR) - { - MotorTachoValue[2].MotorDirection = FORWARD; - MotorTachoValue[2].TachoCountTable++; - } - else - { - MotorTachoValue[2].MotorDirection = REVERSE; - MotorTachoValue[2].TachoCountTable--; - } - } -} - -#define OUTPUTExit {\ - *AT91C_AIC_IDCR = TIMER_0_ID12 | TIMER_1_ID13 | TIMER_2_ID14; /* Disable interrupts for the timers */\ - *AT91C_AIC_ICCR = TIMER_0_ID12 | TIMER_1_ID13 | TIMER_2_ID14; /* Clear penting interrupt register for timers*/\ - *AT91C_PMC_PCDR = TIMER_0_ID12 | TIMER_1_ID13 | TIMER_2_ID14; /* Disable the clock for each of the timers*/\ - *AT91C_PIOA_PER = MOTOR_A_DIR | MOTOR_A_INT | MOTOR_B_DIR | MOTOR_B_INT | MOTOR_C_DIR | MOTOR_C_INT; /* Enable PIO on PA15, PA11, PA26, PA09, PA27 & PA08 */\ - *AT91C_PIOA_ODR = MOTOR_A_DIR | MOTOR_A_INT | MOTOR_B_DIR | MOTOR_B_INT | MOTOR_C_DIR | MOTOR_C_INT; /* Set to input PA15, PA11, PA26, PA09, PA27 & PA08 */\ - *AT91C_PIOA_PPUDR = MOTOR_A_DIR | MOTOR_A_INT | MOTOR_B_DIR | MOTOR_B_INT | MOTOR_C_DIR | MOTOR_C_INT; /* Enable Pullup on PA15, PA11, PA26, PA09, PA27 & PA08 */\ - } - - -#define TACHOCountReset(MotorNr) {\ - MotorTachoValue[MotorNr].TachoCountTable = 0;\ - MotorTachoValue[MotorNr].TachoCountTableOld = 0;\ - } - -#define TACHOCaptureReadResetAll(MotorDataA,MotorDataB,MotorDataC){\ - MotorDataA = (MotorTachoValue[MOTOR_A].TachoCountTable - MotorTachoValue[MOTOR_A].TachoCountTableOld);\ - MotorTachoValue[MOTOR_A].TachoCountTableOld = MotorTachoValue[MOTOR_A].TachoCountTable;\ - MotorDataB = (MotorTachoValue[MOTOR_B].TachoCountTable - MotorTachoValue[MOTOR_B].TachoCountTableOld);\ - MotorTachoValue[MOTOR_B].TachoCountTableOld = MotorTachoValue[MOTOR_B].TachoCountTable;\ - MotorDataC = (MotorTachoValue[MOTOR_C].TachoCountTable - MotorTachoValue[MOTOR_C].TachoCountTableOld);\ - MotorTachoValue[MOTOR_C].TachoCountTableOld = MotorTachoValue[MOTOR_C].TachoCountTable;\ - } - - - - -#define GetMotorDirection(MotorNr) MotorTachoValue[MotorNr].MotorDirection - -#endif - -#ifdef PCWIN - -#endif diff --git a/AT91SAM7S256/Source/d_sound.c b/AT91SAM7S256/Source/d_sound.c deleted file mode 100644 index 72dfb60..0000000 --- a/AT91SAM7S256/Source/d_sound.c +++ /dev/null @@ -1,70 +0,0 @@ -// -// Programmer -// -// Date init 14.12.2004 -// -// Reviser $Author:: Dkandlun $ -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: d_sound.c $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_soun $ -// -// Platform C -// - -#include "stdconst.h" -#include "m_sched.h" -#include "d_sound.h" -#include "d_sound.r" - - -void dSoundInit(void) -{ - SOUNDInit; -} - - -void dSoundVolume(UBYTE Step) -{ - SOUNDVolume(Step); -} - - -UBYTE dSoundReady(void) -{ - return (SOUNDReady); -} - - -UBYTE dSoundStart(UBYTE *pSound,UWORD Length,UWORD SampleRate, UBYTE FileType) -{ - return (SOUNDStart(pSound,Length,SampleRate,FileType)); -} - - -UBYTE dSoundStop(void) -{ - return (SOUNDStop); -} - - -UBYTE dSoundTone(UBYTE *pMelody,UWORD Length,UBYTE Volume) -{ - return (SOUNDTone(pMelody,Length,Volume)); -} - - -void dSoundFreq(UWORD Hz,UWORD mS,UBYTE Volume) -{ - SOUNDFreq(Hz,mS,Volume); -} - - -void dSoundExit(void) -{ - SOUNDExit; -} diff --git a/AT91SAM7S256/Source/d_sound.h b/AT91SAM7S256/Source/d_sound.h deleted file mode 100644 index c580342..0000000 --- a/AT91SAM7S256/Source/d_sound.h +++ /dev/null @@ -1,42 +0,0 @@ -// -// Programmer -// -// Date init 14.12.2004 -// -// Reviser $Author:: Dkandlun $ -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: d_sound.h $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_soun $ -// -// Platform C -// - - -#ifndef D_SOUND -#define D_SOUND - -void dSoundInit(void); -void dSoundVolume(UBYTE Step); -UBYTE dSoundReady(void); -UBYTE dSoundStart(UBYTE *pSound,UWORD Length,UWORD SampleRate, UBYTE FileFormat); -UBYTE dSoundStop(void); -UBYTE dSoundTone(UBYTE *pMelody,UWORD Length,UBYTE Volume); -void dSoundFreq(UWORD Hz,UWORD mS,UBYTE Volume); -void dSoundExit(void); - -#define SOUNDVOLUMESTEPS 4 - -#define DURATION_MIN 10 // [mS] -#define FREQUENCY_MIN 220 // [Hz] -#define FREQUENCY_MAX 14080 // [Hz] - -#define SAMPLERATE_MIN 2000 // Min sample rate [sps] -#define SAMPLERATE_DEFAULT 8000 // Default sample rate [sps] -#define SAMPLERATE_MAX 16000 // Max sample rate [sps] - -#endif diff --git a/AT91SAM7S256/Source/d_sound.r b/AT91SAM7S256/Source/d_sound.r deleted file mode 100644 index 4851253..0000000 --- a/AT91SAM7S256/Source/d_sound.r +++ /dev/null @@ -1,515 +0,0 @@ -// -// Programmer -// -// Date init 14.12.2004 -// -// Reviser $Author:: Dkandlun $ -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: d_sound.r $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_soun $ -// -// Platform C -// - -#include "d_sound_adpcm.r" - -#ifdef SAM7S256 - -#define SAMPLEMIN 0 // Must be zero (no pwm/interrupt) -#define SAMPLEMAX 256 // Must be 256 (8 bit wave format) -#define SAMPLECENTER (((SAMPLEMAX - SAMPLEMIN) / 2) + SAMPLEMIN) - -#define SAMPLEWORD ULONG -#define SAMPLEWORDS 8 -#define SAMPLEWORDBITS (sizeof(SAMPLEWORD) * 8) -#define SAMPLEBITS (SAMPLEWORDS * SAMPLEWORDBITS) -#define SAMPLECONSTANT 3 // >> == (SAMPLEMAX / SAMPLEWORDBITS) - -#define SAMPLETONENO 16 // No of tone samples - -#define SAMPLEBUFFERS 2 - -#define INIT_PREV_VAL_ADPCM 0x7F -#define INIT_INDEX_ADPCM 20 - -SAMPLEWORD SampleBuffer[SAMPLEBUFFERS][SAMPLEWORDS]; -SAMPLEWORD ToneBuffer[SAMPLETONENO]; - -const SAMPLEWORD TonePattern[SOUNDVOLUMESTEPS + 1][SAMPLETONENO] = -{ - { - 0xF0F0F0F0,0xF0F0F0F0, // Step 0 = silence - 0xF0F0F0F0,0xF0F0F0F0, - 0xF0F0F0F0,0xF0F0F0F0, - 0xF0F0F0F0,0xF0F0F0F0, - 0xF0F0F0F0,0xF0F0F0F0, - 0xF0F0F0F0,0xF0F0F0F0, - 0xF0F0F0F0,0xF0F0F0F0, - 0xF0F0F0F0,0xF0F0F0F0 - }, - { - 0xF0F0F0F0,0xF0F0F0F0, // Step 1 = 1/512 - 0xF0F0F0F0,0xF0F0F0F0, - 0xF0F0F0F0,0xF0F0F0F8, - 0xF0F0F0F0,0xF0F0F0F0, - 0xF0F0F0F0,0xF0F0F0F0, - 0xF0F0F0F0,0xF0F0F0F0, - 0xF0F0F0F0,0xF0F0F0F0, - 0xF0F0F0F0,0xF0F0F0F0 - }, - { - 0xF0F0F0F0,0xF0F0F0F0, // Step 2 = 0,+3,+4,+3,0,-3,-4,-3 - 0xF0F0F0F0,0xF0F8F8F8, - 0xF0F0F8F8,0xF8F8F0F0, - 0xF8F8F8F0,0xF0F0F0F0, - 0xF0F0F0F0,0xF0F0F0F0, - 0xF0F0F0F0,0xF0E0E0E0, - 0xF0F0E0E0,0xE0E0F0F0, - 0xE0E0E0F0,0xF0F0F0F0 - }, - { - 0xF0F0F0F0,0xF0F0F0F0, // Step 3 = 0,+10,+14,+10,0,-10,-14,-10 - 0xF8F8F8F8,0xF8F8FCFC, - 0xF8F8FCFC,0xFCFCFCFC, - 0xFCFCF8F8,0xF8F8F8F8, - 0xF0F0F0F0,0xF0F0F0F0, - 0xE0E0E0E0,0xE0E0C0C0, - 0xE0E0C0C0,0xC0C0C0C0, - 0xC0C0E0E0,0xE0E0E0E0 - }, - { - 0xF0F0F0F0,0xF0F0F0F0, // Step 4 = 0,+22,+32,+22,0,-22,-32,-22 - 0xFCFCFCFC,0xFCFCFDFD, - 0xFFFFFFFF,0xFFFFFFFF, - 0xFDFDFCFC,0xFCFCFCFC, - 0xF0F0F0F0,0xF0F0F0F0, - 0xC0C0C0C0,0xC0C08080, - 0x00000000,0x00000000, - 0x8080C0C0,0xC0C0C0C0 - } -}; - -__ramdata -UBYTE FractionPattern[SAMPLEWORDS] = -{ - 0x00, // 0 -> 00000000 - 0x10, // 1 -> 00010000 - 0x22, // 2 -> 00100010 - 0x4A, // 3 -> 01001010 - 0x55, // 4 -> 01010101 - 0x6D, // 5 -> 01101101 - 0x77, // 6 -> 01110111 - 0x7F, // 7 -> 01111111 -}; - -typedef struct -{ - SWORD Valprev; // Previous output value - SWORD Index; // Index into stepsize table -}ADPCM_State; - -ULONG ToneCycles; // No of tone cycles -ULONG ToneCyclesReady; // No of tone cycles for ready -ULONG ClockNext; // Serial clock for next buffer - -UBYTE *pSoundPointer; // Pointer to sample in actual sound buffer -UBYTE *pSoundPointerNext; // Pointer to sample in next sound buffer - -UWORD SoundSamplesLeft; // Number of samples left on actual sound buffer -UWORD SoundSamplesLeftNext; // Number of samples left on next sound buffer - -UBYTE SampleBufferNo; // Sample buffer no in use - -UBYTE SoundReady; // Sound channel ready (idle) -UBYTE SoundDivider; // Volume - -UWORD MelodyPointer; -UBYTE CurrentFileFormat; // Hold current playing file type - -UBYTE Outdata[2]; // Output buffer used within the ADPCM algorithm -ADPCM_State State; // Struct holding ADPCM state - -#define SOUNDIntEnable {\ - *AT91C_SSC_IER = AT91C_SSC_ENDTX;\ - } - -#define SOUNDIntDisable {\ - *AT91C_SSC_IDR = AT91C_SSC_ENDTX;\ - } - -#define SOUNDEnable {\ - *AT91C_PIOA_PDR = AT91C_PA17_TD; /* Enable TD on PA17 */\ - } - -#define SOUNDDisable {\ - *AT91C_PIOA_PER = AT91C_PA17_TD; /* Disable TD on PA17 */\ - } - -ULONG SoundSampleRate(UWORD Rate) -{ - ULONG Result; - - if (Rate > SAMPLERATE_MAX) - { - Rate = SAMPLERATE_MAX; - } - if (Rate < SAMPLERATE_MIN) - { - Rate = SAMPLERATE_MIN; - } - Result = ((OSC / (2 * SAMPLEBITS)) / Rate) + 1; - - return (Result); -} - -__ramfunc void CalculateBitstream(SAMPLEWORD *pSampleBuffer,UBYTE Sample) -{ - ULONG IntegerMask; - ULONG FractionMask; - UBYTE Integer; - UBYTE Fraction; - UBYTE Mask; - UBYTE Tmp; - SWORD STmp; - - if (SoundDivider) - { - STmp = Sample; - STmp &= 0xFF; - STmp -= SAMPLECENTER; - STmp >>= (SOUNDVOLUMESTEPS - SoundDivider); - STmp += SAMPLECENTER; - Sample = (UBYTE)STmp; - SOUNDEnable; - } - else - { - SOUNDDisable; - } - - Tmp = 0; - IntegerMask = 0xFFFF0000; - Integer = Sample >> SAMPLECONSTANT; - Fraction = Sample - (Integer << SAMPLECONSTANT); - IntegerMask = 0xFFFFFFFF << (SAMPLEWORDBITS - Integer); - FractionMask = (IntegerMask >> 1) | IntegerMask; - Mask = FractionPattern[Fraction]; - while (Tmp < SAMPLEWORDS) - { - if ((Mask & (0x01 << Tmp))) - { - *pSampleBuffer = FractionMask; - } - else - { - *pSampleBuffer = IntegerMask; - } - pSampleBuffer++; - Tmp++; - } -} - -__ramfunc void SscHandler(void) -{ - static UBYTE ByteCnt = 0; - - if (SoundSamplesLeft) - { - if (0 == CurrentFileFormat) - { - CalculateBitstream(SampleBuffer[SampleBufferNo],*pSoundPointer); - *AT91C_SSC_TNPR = (unsigned int)SampleBuffer[SampleBufferNo]; - *AT91C_SSC_TNCR = SAMPLEWORDS; - - pSoundPointer++; - SoundSamplesLeft--; - if (!SoundSamplesLeft) - { - pSoundPointer = pSoundPointerNext; - SoundSamplesLeft = SoundSamplesLeftNext; - *AT91C_SSC_CMR = ClockNext; - SoundSamplesLeftNext = 0; - } - - if (++SampleBufferNo >= SAMPLEBUFFERS) - { - SampleBufferNo = 0; - } - } - else - { - if (0 == ByteCnt) - { - SoundADPCMDecoder(*pSoundPointer, Outdata, &State.Valprev, &State.Index); - CalculateBitstream(SampleBuffer[SampleBufferNo],Outdata[0]); - *AT91C_SSC_TNPR = (unsigned int)SampleBuffer[SampleBufferNo]; - *AT91C_SSC_TNCR = SAMPLEWORDS; - - if (++SampleBufferNo >= SAMPLEBUFFERS) - { - SampleBufferNo = 0; - } - - ByteCnt++; - } - else - { - CalculateBitstream(SampleBuffer[SampleBufferNo],Outdata[1]); - *AT91C_SSC_TNPR = (unsigned int)SampleBuffer[SampleBufferNo]; - *AT91C_SSC_TNCR = SAMPLEWORDS; - - pSoundPointer++; - SoundSamplesLeft--; - if (!SoundSamplesLeft) - { - pSoundPointer = pSoundPointerNext; - SoundSamplesLeft = SoundSamplesLeftNext; - *AT91C_SSC_CMR = ClockNext; - SoundSamplesLeftNext = 0; - } - - if (++SampleBufferNo >= SAMPLEBUFFERS) - { - SampleBufferNo = 0; - } - ByteCnt = 0; - } - } - } - else - { - if (ToneCycles) - { - ToneCycles--; - if (ToneCycles < ToneCyclesReady) - { - SoundReady = TRUE; - } - *AT91C_SSC_TNPR = (unsigned int)ToneBuffer; - *AT91C_SSC_TNCR = SAMPLETONENO; - if (SoundDivider) - { - SOUNDEnable; - } - else - { - SOUNDDisable; - } - } - else - { - SoundReady = TRUE; - SOUNDDisable; - SOUNDIntDisable; - } - } -} - -UBYTE SoundStart(UBYTE *Sound,UWORD Length,UWORD SampleRate, UBYTE NewFileFormat) -{ - UBYTE Result = FALSE; - - if (SoundReady == TRUE) - { - if (Length > 1) - { - CurrentFileFormat = NewFileFormat; - *AT91C_SSC_CMR = SoundSampleRate(SampleRate); - pSoundPointer = Sound; - SoundSamplesLeft = Length; - - if (0 == CurrentFileFormat) - { - CalculateBitstream(SampleBuffer[0],*pSoundPointer); - *AT91C_SSC_TPR = (unsigned int)SampleBuffer[0]; - *AT91C_SSC_TCR = SAMPLEWORDS; - pSoundPointer++; - SoundSamplesLeft--; - CalculateBitstream(SampleBuffer[1],*pSoundPointer); - *AT91C_SSC_TNPR = (unsigned int)SampleBuffer[1]; - *AT91C_SSC_TNCR = SAMPLEWORDS; - pSoundPointer++; - SoundSamplesLeft--; - } - else - { - State.Valprev = INIT_PREV_VAL_ADPCM; - State.Index = INIT_INDEX_ADPCM; - SoundADPCMDecoder(*pSoundPointer, Outdata, &State.Valprev, &State.Index); - CalculateBitstream(SampleBuffer[0],Outdata[0]); - *AT91C_SSC_TPR = (unsigned int)SampleBuffer[0]; - *AT91C_SSC_TCR = SAMPLEWORDS; - pSoundPointer++; - SoundSamplesLeft--; - CalculateBitstream(SampleBuffer[1],Outdata[1]); - *AT91C_SSC_TNPR = (unsigned int)SampleBuffer[1]; - *AT91C_SSC_TNCR = SAMPLEWORDS; - } - SampleBufferNo = 0; - SoundReady = FALSE; - SOUNDIntEnable; - *AT91C_SSC_PTCR = AT91C_PDC_TXTEN; - } - Result = TRUE; - } - else - { - if (!ToneCycles) - { - if (!SoundSamplesLeftNext) - { - CurrentFileFormat = NewFileFormat; - ClockNext = SoundSampleRate(SampleRate); - pSoundPointerNext = Sound; - SoundSamplesLeftNext = Length; - Result = TRUE; - } - } - } - - return (Result); -} - -UBYTE SoundStop(void) -{ - ToneCycles = 0; - SOUNDIntDisable; - SOUNDDisable; - SoundReady = TRUE; - SoundSamplesLeft = 0; - SoundSamplesLeftNext = 0; - MelodyPointer = 0; - - return (TRUE); -} - -void SoundVolume(UBYTE Step) -{ - if (Step > SOUNDVOLUMESTEPS) - { - Step = SOUNDVOLUMESTEPS; - } - SoundDivider = Step; -} - -void SoundFreq(UWORD Freq,UWORD mS,UBYTE Step) -{ - UBYTE Tmp; - - if (mS < DURATION_MIN) - { - mS = DURATION_MIN; - } - if (Freq) - { - if (Freq < FREQUENCY_MIN) - { - Freq = FREQUENCY_MIN; - } - if (Freq > FREQUENCY_MAX) - { - Freq = FREQUENCY_MAX; - } - if (Step > SOUNDVOLUMESTEPS) - { - Step = SOUNDVOLUMESTEPS; - } - } - else - { - Step = 0; - Freq = 1000; - } - SoundDivider = Step; - SoundSamplesLeft = 0; - SoundSamplesLeftNext = 0; - for (Tmp = 0;Tmp < SAMPLETONENO;Tmp++) - { - ToneBuffer[Tmp] = TonePattern[Step][Tmp]; - } - - *AT91C_SSC_CMR = (((ULONG)OSC / (2L * 512L)) / ((ULONG)Freq)) + 1L; - ToneCycles = ((ULONG)Freq * (ULONG)mS) / 1000L - 1L; - ToneCyclesReady = ((ULONG)Freq * (ULONG)2L) / 1000L + 1L; - - *AT91C_SSC_TNPR = (unsigned int)ToneBuffer; - *AT91C_SSC_TNCR = SAMPLETONENO; - *AT91C_SSC_PTCR = AT91C_PDC_TXTEN; - SoundReady = FALSE; - SOUNDIntEnable; -} - -UBYTE SoundTone(UBYTE *pMel,UWORD Length,UBYTE Step) -{ - UBYTE Result = FALSE; - UWORD Freq; - UWORD mS; - - if ((SoundReady == TRUE)) - { - if (MelodyPointer <= (Length - 4)) - { - Freq = (UWORD)pMel[MelodyPointer++] << 8; - Freq += (UWORD)pMel[MelodyPointer++]; - mS = (UWORD)pMel[MelodyPointer++] << 8; - mS += (UWORD)pMel[MelodyPointer++]; - SoundFreq(Freq,mS,Step); - } - else - { - MelodyPointer = 0; - Result = TRUE; - } - } - - return (Result); -} - -#define SOUNDInit {\ - SOUNDIntDisable;\ - SoundReady = TRUE;\ - MelodyPointer = 0;\ - *AT91C_PMC_PCER = (1L << AT91C_ID_SSC); /* Enable MCK clock */\ - *AT91C_PIOA_PER = AT91C_PA17_TD; /* Disable TD on PA17 */\ - *AT91C_PIOA_ODR = AT91C_PA17_TD;\ - *AT91C_PIOA_OWDR = AT91C_PA17_TD;\ - *AT91C_PIOA_MDDR = AT91C_PA17_TD;\ - *AT91C_PIOA_PPUDR = AT91C_PA17_TD;\ - *AT91C_PIOA_IFDR = AT91C_PA17_TD;\ - *AT91C_PIOA_CODR = AT91C_PA17_TD;\ - *AT91C_PIOA_IDR = AT91C_PA17_TD;\ - *AT91C_SSC_CR = AT91C_SSC_SWRST;\ - AT91C_AIC_SVR[AT91C_ID_SSC] = (unsigned int)SscHandler;\ - AT91C_AIC_SMR[AT91C_ID_SSC] = AT91C_AIC_PRIOR_LOWEST | AT91C_AIC_SRCTYPE_INT_EDGE_TRIGGERED; /* Set priority */\ - *AT91C_SSC_TCMR = AT91C_SSC_CKS_DIV + AT91C_SSC_CKO_CONTINOUS + AT91C_SSC_START_CONTINOUS;\ - *AT91C_SSC_TFMR = (SAMPLEWORDBITS - 1) + ((SAMPLEWORDS & 0xF) << 8) + AT91C_SSC_MSBF;\ - *AT91C_SSC_CR = AT91C_SSC_TXEN; /* TX enable */\ - *AT91C_AIC_ICCR = (1L << AT91C_ID_SSC); /* Clear interrupt */\ - *AT91C_AIC_IECR = (1L << AT91C_ID_SSC); /* Enable int. controller */\ - } - -#define SOUNDVolume(V) SoundVolume((UBYTE)V) - -#define SOUNDReady SoundReady - -#define SOUNDStart(pSnd,Lng,SR,FT) SoundStart(pSnd,Lng,SR,FT) - -#define SOUNDStop SoundStop() - -#define SOUNDTone(pMel,Lng,Vol) SoundTone(pMel,Lng,Vol) - -#define SOUNDFreq(Freq,Duration,Vol) SoundFreq(Freq,Duration,Vol) - -#define SOUNDExit {\ - SOUNDIntDisable;\ - SOUNDDisable;\ - *AT91C_AIC_IDCR = (1L << AT91C_ID_SSC);\ - } - - -#endif diff --git a/AT91SAM7S256/Source/d_sound_adpcm.r b/AT91SAM7S256/Source/d_sound_adpcm.r deleted file mode 100644 index f04a760..0000000 --- a/AT91SAM7S256/Source/d_sound_adpcm.r +++ /dev/null @@ -1,158 +0,0 @@ -//Playback of compressed sound files. This additional feature is being brought to you under the following license. -//Please adhere to its terms. -//The original code includes minor changes to function correctly within the LEGO MINDSTORMS NXT embedded system, -//but the main architecture are implemented as within the original code. - -//*********************************************************** -//Copyright 1992 by Stichting Mathematisch Centrum, Amsterdam, The -//Netherlands. -// -// All Rights Reserved -// -//Permission to use, copy, modify, and distribute this software and its -//documentation for any purpose and without fee is hereby granted, -//provided that the above copyright notice appear in all copies and that -//both that copyright notice and this permission notice appear in -//supporting documentation, and that the names of Stichting Mathematisch -//Centrum or CWI not be used in advertising or publicity pertaining to -//distribution of the software without specific, written prior permission. -// -//STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO -//THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -//FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE -//FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -//WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -//ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT -//OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -// -//******************************************************************/ - -// -// Programmer -// -// Date init 14.12.2004 -// -// Reviser $Author:: Dkandlun $ -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: d_sound_adpcm.r $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_sound_adpc $ -// -// Platform C -// - -#ifdef SAM7S256 - -__ramdata -static SWORD IndexTable[16] = -{ - -1, -1, -1, -1, 2, 4, 6, 8, - -1, -1, -1, -1, 2, 4, 6, 8, -}; - -__ramdata -static SWORD StepsizeTable[89] = -{ - 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, - 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, - 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, - 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, - 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, - 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, - 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, - 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, - 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 -}; - -__ramfunc void SoundADPCMDecoder(UBYTE Indata, UBYTE *Outdata, SWORD *pStateValprev, SWORD *pStateIndex) -{ - SWORD Step; // Stepsize - SWORD Valprev; // Virtual previous output value - SWORD Vpdiff; // Current change to valprev - SWORD Index; // Current step change index - UBYTE *pOut; // Output buffer pointer - UBYTE Sign; // Current adpcm sign bit - UBYTE Delta; // Current adpcm output value - UBYTE Bufferstep; // Toggle between High og Low nibble - UBYTE Len; // Nibble Counter - - pOut = Outdata; - - Valprev = *pStateValprev; - Index = *pStateIndex; - Step = StepsizeTable[Index]; - - Bufferstep = 0; - Len = 2; - - for (; Len > 0 ; Len--) //Step 1 - get the delta value and compute next index - { - if(Bufferstep) - { - Delta = Indata & 0x0F; - } - else - { - Delta = (Indata >> 4) & 0x0F; - } - Bufferstep = !Bufferstep; - - Index += IndexTable[Delta]; //Step 2 - Find new index value (for later) - if (Index < 0) - { - Index = 0; - } - else - { - if (Index > 88) - { - Index = 88; - } - } - - Sign = Delta & 8; //Step 3 - Separate sign and magnitude - Delta = Delta & 7; - - Vpdiff = Step >> 3; //Step 4 - Compute difference and new predicted value - - if (Delta & 4) - { - Vpdiff += Step; - } - if (Delta & 2) - { - Vpdiff += Step>>1; - } - if (Delta & 1) - { - Vpdiff += Step>>2; - } - - if (Sign) - Valprev -= Vpdiff; - else - Valprev += Vpdiff; - - if (Valprev > 255) //Step 5 - clamp output value - { - Valprev = 255; - } - else - { - if (Valprev < 0) - { - Valprev = 0; - } - } - Step = StepsizeTable[Index]; //Step 6 - Update step value - *pOut++ = (UBYTE)Valprev; //Step 7 - Output value - } - *pStateValprev = Valprev; //State.Valprev = Valprev; - *pStateIndex = Index; //State.Index = Index; -} - -#endif diff --git a/AT91SAM7S256/Source/d_timer.c b/AT91SAM7S256/Source/d_timer.c deleted file mode 100644 index cba73d0..0000000 --- a/AT91SAM7S256/Source/d_timer.c +++ /dev/null @@ -1,62 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date: 23-04-08 11:15 $ -// -// Filename $Workfile:: d_timer.c $ -// -// Version $Revision: 2 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_time $ -// -// Platform C -// - - -#include "stdconst.h" -#include "m_sched.h" -#include "d_timer.h" -#include "d_timer.r" - - -void dTimerInit(void) -{ - TIMERInit; -} - - -ULONG dTimerRead(void) -{ - ULONG V; - - TIMERReadAlt(V) - return (V); -} - -ULONG dTimerReadNoPoll(void) -{ - return (Timer1mS); -} - -ULONG dTimerReadHiRes(void) -{ - -// return ((*AT91C_PITC_PIIR)/3); following code is equivalent and about five times faster, see Hacker's Delight or exact division - ULONG tmp= ((*AT91C_PITC_PIIR)*2863311531); - if(tmp > 2863311531) - return tmp - 2863311531; - else if(tmp > 1431655766) - return tmp - 1431655766; - else - return tmp; -} - -ULONG dTimerGetNextMSTickCnt(void) { - return NextTimerValue; -} - -void dTimerExit(void) -{ - TIMERExit; -} - diff --git a/AT91SAM7S256/Source/d_timer.h b/AT91SAM7S256/Source/d_timer.h deleted file mode 100644 index 9d7eadb..0000000 --- a/AT91SAM7S256/Source/d_timer.h +++ /dev/null @@ -1,32 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date: 23-04-08 11:15 $ -// -// Filename $Workfile:: d_timer.h $ -// -// Version $Revision: 2 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_time $ -// -// Platform C -// - - -#ifndef D_TIMER -#define D_TIMER - -void dTimerInit(void); -ULONG dTimerRead(void); -ULONG dTimerReadNoPoll(void); -ULONG dTimerReadHiRes(void); - -ULONG dTimerGetNextMSTickCnt(void); -#define dTimerReadTicks() (*AT91C_PITC_PIIR) - -void dTimerExit(void); - -#endif - - - diff --git a/AT91SAM7S256/Source/d_timer.r b/AT91SAM7S256/Source/d_timer.r deleted file mode 100644 index 93c3a3b..0000000 --- a/AT91SAM7S256/Source/d_timer.r +++ /dev/null @@ -1,76 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 23-04-08 11:15 $ -// -// Filename $Workfile:: d_timer.r $ -// -// Version $Revision:: 2 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_time $ -// -// Platform C -// - - -#ifdef SAM7S256 - - -#define MS_1_TIME ((OSC/16)/1000) - -static ULONG TimerValue; -static ULONG NextTimerValue; -static ULONG Timer1mS; - -/* PIT timer is used as main timer - timer interval is 1mS */ - -#define TIMERInit TimerValue = ((*AT91C_PITC_PIIR) & AT91C_PITC_CPIV);\ - NextTimerValue = (((*AT91C_PITC_PIIR) + MS_1_TIME) & AT91C_PITC_CPIV);\ - Timer1mS = 0 - -#define TIMERRead(V) if (MS_1_TIME < ((((*AT91C_PITC_PIIR) & AT91C_PITC_CPIV) - TimerValue) & AT91C_PITC_CPIV))\ - {\ - TimerValue += MS_1_TIME;\ - TimerValue &= AT91C_PITC_CPIV;\ - Timer1mS++;\ - }\ - V = Timer1mS - -#define TIMERReadAlt(V) if((SLONG)((*AT91C_PITC_PIIR) - NextTimerValue) >= 0)\ - {\ - Timer1mS ++;\ - NextTimerValue += MS_1_TIME;\ - }\ - V = Timer1mS;\ - -#define TIMERReadSkip(V) diff= (((*AT91C_PITC_PIIR)) - NextTimerValue);\ - if (diff >= 0)\ - {\ - diff /= MS_1_TIME;\ - diff += 1;\ - Timer1mS += diff;\ - diff *= MS_1_TIME;\ - NextTimerValue += diff;\ - }\ - V = Timer1mS;\ - -#define TIMERExit - - - -#endif //SAM7S256 - - - -#ifdef _WINDOWS - -#include -#include - -#define TIMERInit timeBeginPeriod(1); - -#define TIMERRead(V) (V) = timeGetTime(); - -#define TIMERExit timeEndPeriod(1); - -#endif //_WINDOWS diff --git a/AT91SAM7S256/Source/d_usb.c b/AT91SAM7S256/Source/d_usb.c deleted file mode 100644 index 0caf317..0000000 --- a/AT91SAM7S256/Source/d_usb.c +++ /dev/null @@ -1,946 +0,0 @@ -// -// Programmer -// -// Date init 14.12.2004 -// -// Reviser $Author:: Dkandlun $ -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: d_usb.c $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_usb. $ -// -// Platform C -// - -#include "stdconst.h" -#include "m_sched.h" -#include "d_usb.h" -#include "d_usb.r" - -#define ENDPOINT_OUT 1 // HOST write -#define ENDPOINT_OUT_SIZE 64 -#define ENDPOINT_IN 2 // HOST read -#define ENDPOINT_IN_SIZE 64 - -#define AT91C_UDP_ISR ((AT91_REG *) 0xFFFB001C) // (UDP) Interrupt Status Register -#define AT91C_RSTC_URSTEN ((unsigned int) 0x1 << 0) // (RSTC) User Reset Enable - - // Endpoint Control and Status Registers -#define AT91C_UDP_CSR0 ((AT91_REG *) 0xFFFB0030) // Endpoint 0 Control and Status Register -#define AT91C_UDP_CSR1 ((AT91_REG *) 0xFFFB0034) // Endpoint 1 Control and Status Register -#define AT91C_UDP_CSR2 ((AT91_REG *) 0xFFFB0038) // Endpoint 2 Control and Status Register -#define AT91C_UDP_CSR3 ((AT91_REG *) 0xFFFB003C) // Endpoint 3 Control and Status Register - - // Endpoint FIFO Data Registers -#define AT91C_UDP_FDR0 ((AT91_REG *) 0xFFFB0050) // Endpoint 0 FIFO Data Register -#define AT91C_UDP_FDR1 ((AT91_REG *) 0xFFFB0054) // Endpoint 1 FIFO Data Register -#define AT91C_UDP_FDR2 ((AT91_REG *) 0xFFFB0058) // Endpoint 2 FIFO Data Register -#define AT91C_UDP_FDR3 ((AT91_REG *) 0xFFFB005C) // Endpoint 3 FIFO Data Register - -const UBYTE DeviceDescriptor[] = { - /* Device descriptor */ - 0x12, // bLength, size of this descriptor = 18 entries - 0x01, // bDescriptorType = 1 = DEVICE - 0x00, // bcdUSBL, USB spec. vers. 2.0 - 0x02, // bcdUSBH, - - 0x00, // bDeviceClass - 0x00, // bDeviceSubclass - 0x00, // bDeviceProtocol - 0x08, // bMaxPacketSize0, EndPointZero packet size = 8 - 0x94, // idVendorL, LEGO Group - 0x06, // idVendorH, - - 0x02, // idProductL, LEGO USB IR Tower = 0x01 - 0x00, // idProductH, - - 0x00, // bcdDeviceL, device is version (zero) - 0x00, // bcdDeviceH, - - 0x00, // iManufacturer, index of string descriptor describing manufacturer - 0x00, // iProduct, index of string descriptor describing product - 0x01, // iSerialNumber, index of string descriptor describing the device's - // serial no. - 0x01 // bNumConfigs, number of possible configurations (only one) -}; - -/* USB standard request codes */ - -#define STD_GET_STATUS_ZERO 0x0080 -#define STD_GET_STATUS_INTERFACE 0x0081 -#define STD_GET_STATUS_ENDPOINT 0x0082 - -#define STD_CLEAR_FEATURE_ZERO 0x0100 -#define STD_CLEAR_FEATURE_INTERFACE 0x0101 -#define STD_CLEAR_FEATURE_ENDPOINT 0x0102 - -#define STD_SET_FEATURE_ZERO 0x0300 -#define STD_SET_FEATURE_INTERFACE 0x0301 -#define STD_SET_FEATURE_ENDPOINT 0x0302 - -#define STD_SET_ADDRESS 0x0500 -#define STD_GET_DESCRIPTOR 0x0680 -#define STD_SET_DESCRIPTOR 0x0700 -#define STD_GET_CONFIGURATION 0x0880 -#define STD_SET_CONFIGURATION 0x0900 -#define STD_GET_INTERFACE 0x0A81 -#define STD_SET_INTERFACE 0x0B01 -#define STD_SYNCH_FRAME 0x0C82 - -/* USB constants, masks etc. */ - -#define END_OF_BUS_RESET ((unsigned int) 0x1 << 12) -#define SUSPEND_INT ((unsigned int) 0x1 << 8) -#define SUSPEND_RESUME ((unsigned int) 0x1 << 9) -#define WAKEUP ((unsigned int) 0x1 << 13) - -//USB spec allows 500ms for control transfers -#define USB_MAX_TIMEOUT 500 - -static UBYTE UsbHandleList[MAX_HANDLES]; -static UBYTE UsbHandleCnt; -static UWORD RequestedData; -static UBYTE BrickNameKnown; -enum -{ - USB_NOT_CONFIGURED, - USB_CONFIGURED, - USB_CONFIGURED_BUT_SUSPENDED -}; -static UBYTE UsbConnectionStates; - - -const UBYTE ConfigurationDescriptor[] = { - /* ============== CONFIGURATION 1 =========== */ - /* Configuration 1 descriptor */ - 0x09, // bLength, descriptor size in bytes - 0x02, // bDescriptorType, The constant Configuration - 0x20, // wTotalLengthL for 2 EP + Control - 0x00, // wTotalLengthH - - 0x01, // bNumInterfaces, Number of interfaces in the configuration - 0x01, // bConfigurationValue, Identifier for - // Set_Configuration and Get_Configuration requests - 0x00, // iConfiguration, Index of string descriptor for the configuration - 0xC0, // bmAttributes, Bit 7 shall always be set. See e.g. page 108 in the book: - // "USB Complete" by Jan Axelson. June 2001 - // Self powered only bit 6 = 1 (zero = buspowered USB 1.1 and up) - 0x00, // MaxPower, power required (mA./2) We're SELF-POWERED, so ZERO - - /* Interface Descriptor */ - 0x09, // bLength, descriptor size in bytes - 0x04, // bDescriptorType, the constant 0x04 = "INTERFACE" - 0x00, // bInterfaceNumber, No. identifying this interface - 0x00, // bAlternateSetting, value used to get an alternative interface - 0x02, // bNumEndpoints, No. of supported endpoints in addition to endpoint 0 - 0xFF, // bInterfaceClass, Specifies the class code = VENDOR Specific - 0xFF, // bInterfaceSubclass, Specifies the subclass code = VENDOR Specific - 0xFF, // bInterfaceProtocol, protocol code = VENDOR Specific - 0x00, // iInterface, index of string descriptor for the interface - - /* Endpoint 1 descriptor */ - 0x07, // bLength, descriptor length incl. this = 7 - 0x05, // bDescriptorType - 0x01, // bEndpointAddress, Endpoint 01 - OUT - 0x02, // bmAttributes BULK - ENDPOINT_OUT_SIZE, // wMaxPacketSize - 0x00, // - - 0x00, // bInterval - - /* Endpoint 2 descriptor */ - 0x07, // bLength, descriptor length incl. this = 7 - 0x05, // bDescriptorType - 0x82, // bEndpointAddress, Endpoint 02 - IN - 0x02, // bmAttributes BULK - ENDPOINT_IN_SIZE, // wMaxPacketSize - 0x00, // - - 0x00 // bInterval -}; - -UBYTE SerialNumberDescriptor[] = -{ - 0x1A, // bLength, descriptor length incl. this = 16 bytes - 0x03, // bDescriptorType - - 0x31, 0x00, // MSD of Lap (Lap[2,3]) in UNICode - 0x32, 0x00, // Lap[4,5] - 0x33, 0x00, // Lap[6,7] - 0x34, 0x00, // Lap[8,9] - 0x35, 0x00, // Lap[10,11] - 0x36, 0x00, // Lap[12,13] - 0x37, 0x00, // Lap[14,15] - 0x38, 0x00, // LSD of Lap (Lap[16,17]) in UNICode - - 0x30, 0x00, // MSD of Nap (Nap[18,19]) in UNICode - 0x30, 0x00, // LSD of Nap (Nap[20,21]) in UNICode - - 0x39, 0x00, // MSD of Uap in UNICode - 0x30, 0x00 // LSD of Uap in UNICode -}; - -const UBYTE LangIdDescriptor[] = -{ - 0x04, // Length - 0x03, // Type, 3 = CONSTANT String - 0x09, // English - 0x04 // subcode = U.S. English -}; - -static UCHAR CurrentConfiguration; // Configured or not. We've only 1 conf. so... Boolean -static ULONG CurrentReceiveBank; // Used for keep track of the PING-PONG buffers - -ULONG g_UsbTimeoutCounter; - -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) - -void dUsbDisconnect(void) -{ - USBDisconnect; -} - -void dUsbConnect(void) -{ - USBConnect; -} - -void dUsbStartTimeoutTimer(void) -{ - g_UsbTimeoutCounter = 0; - - USBGetActualTime; -} - -// A longer version of the USB timer. -// Table 7-14 of the USB 2.0 spec allows up to 500ms for standard request completion. -UBYTE dUsbTimedOut(void) -{ - if(USBTimedOut) - { - g_UsbTimeoutCounter++; - - USBGetActualTime; - } - - return (g_UsbTimeoutCounter >= USB_MAX_TIMEOUT) ? TRUE : FALSE; -} - - -UBYTE ConvertHighToHex(UBYTE TempChar) -{ - TempChar = (TempChar >> 4) & 0x0F; - if (TempChar > 0x09) - TempChar += 0x37; - else - TempChar += 0x30; - return TempChar; -} - -UBYTE ConvertLowToHex(UBYTE TempChar) -{ - TempChar &= 0x0F; - if (TempChar > 0x09) - TempChar += 0x37; - else - TempChar += 0x30; - return TempChar; -} - -void dUsbStoreBtAddress(UBYTE *pBtAddress) -{ - UBYTE NoToConvert; - - // make the Lap human readable (hmmm Hexadecimal) - NoToConvert = *pBtAddress++; - SerialNumberDescriptor[2] = ConvertHighToHex(NoToConvert); - SerialNumberDescriptor[4] = ConvertLowToHex(NoToConvert); - - NoToConvert = *pBtAddress++; - SerialNumberDescriptor[6] = ConvertHighToHex(NoToConvert); - SerialNumberDescriptor[8] = ConvertLowToHex(NoToConvert); - - NoToConvert = *pBtAddress++; - SerialNumberDescriptor[10] = ConvertHighToHex(NoToConvert); - SerialNumberDescriptor[12] = ConvertLowToHex(NoToConvert); - - NoToConvert = *pBtAddress++; - SerialNumberDescriptor[14] = ConvertHighToHex(NoToConvert); - SerialNumberDescriptor[16] = ConvertLowToHex(NoToConvert); - - // make the Uap human readable (hmmm Hexadecimal) - NoToConvert = *pBtAddress++; - SerialNumberDescriptor[18] = ConvertHighToHex(NoToConvert); - SerialNumberDescriptor[20] = ConvertLowToHex(NoToConvert); - - // make the Nap human readable (hmmm Hexadecimal) - NoToConvert = *pBtAddress++; - SerialNumberDescriptor[22] = ConvertHighToHex(NoToConvert); - SerialNumberDescriptor[24] = ConvertLowToHex(NoToConvert); - - USBConnect; // We're ready to participate in the real world - BrickNameKnown = TRUE; // OK for referencing :-) -} - - -ULONG dUsbRead(UBYTE *pData, ULONG Length) -{ - ULONG PacketSize, NumberOfBytesReceived; - - NumberOfBytesReceived = 0; - - while (Length) // Wished read size from user (Max length) - { - if ( !(BrickNameKnown)) // Right Brick??? - break; - - if ( !(dUsbIsConfigured()) ) - break; // Not configured - no time to waste - - if ( (*AT91C_UDP_CSR1) & CurrentReceiveBank ) // Data packet rx'ed in Current bank? - { - - PacketSize = MIN((*AT91C_UDP_CSR1) >> 16, Length); // Normalize number of bytes available in FIFO - Length -= PacketSize; // Rest of data to receive - - if (PacketSize < ENDPOINT_OUT_SIZE) // If data less, we only have one loop - Length = 0; - - while(PacketSize--) // While more data in this very packet... - pData[NumberOfBytesReceived++] = *AT91C_UDP_FDR1; // Fill in buffer - - *AT91C_UDP_CSR1 &= ~(CurrentReceiveBank); // Reset current bank pointer - - if (CurrentReceiveBank == AT91C_UDP_RX_DATA_BK0) // Current Receive Bank 0? - CurrentReceiveBank = AT91C_UDP_RX_DATA_BK1; // We better use Bank 1 - else - CurrentReceiveBank = AT91C_UDP_RX_DATA_BK0; // Okay, go for Bank 0 :-) - - } - - else Length = 0; // Leave and let's use the CPU cycles in a better way - - } - - return NumberOfBytesReceived; // Size of actually received stuff - -} - -ULONG dUsbWrite( const UBYTE *pData, ULONG Length) -{ - ULONG CharsEachTx = 0; - - // Send the very first (or only) packet - CharsEachTx = MIN(Length, ENDPOINT_IN_SIZE); // First transmission size - Length -= CharsEachTx; // Adjust the rest of transmission size - - while (CharsEachTx--) // While more chars in this chunk - *AT91C_UDP_FDR2 = *pData++; // Get rid off it one by one - // Pushing the data into the UDP TX-fifo - *AT91C_UDP_CSR2 |= AT91C_UDP_TXPKTRDY; // Signal "DO THE TX" the stuff is delivered... - - while (Length) // While more bytes (I.e. packets) ín total transmission - { // Start filling the second bank - - CharsEachTx = MIN(Length, ENDPOINT_IN_SIZE); - Length -= CharsEachTx; // Adjust total length - - while (CharsEachTx--) // While more chars in this chunk - *AT91C_UDP_FDR2 = *pData++; - - dUsbStartTimeoutTimer(); - while ( !((*AT91C_UDP_CSR2) & AT91C_UDP_TXCOMP) ) // Wait for the the first bank to be sent - if (dUsbTimedOut() || !(dUsbIsConfigured()) ) // Communication down..... Bail out - return Length; // Invalid function - return job length not done - - (*AT91C_UDP_CSR2) &= ~(AT91C_UDP_TXCOMP); // Reset transmit interrupt flag - - while ((*AT91C_UDP_CSR2) & AT91C_UDP_TXCOMP); // Wait until flag (H/W) is reset - - (*AT91C_UDP_CSR2) |= AT91C_UDP_TXPKTRDY; // We're ready to send next bank - - } // Loop while bytes to tx - - dUsbStartTimeoutTimer(); // Arm the timeout timing - while ( !((*AT91C_UDP_CSR2) & AT91C_UDP_TXCOMP) ) // Wait for transmission to complete - if ( !(dUsbIsConfigured()) || dUsbTimedOut()) // Communication down..... Bail out - return Length; // Invalid function - return job length not done - - (*AT91C_UDP_CSR2) &= ~(AT91C_UDP_TXCOMP); // Reset Interrupt flag - - while ((*AT91C_UDP_CSR2) & AT91C_UDP_TXCOMP); // Wait for H/W to settle..... - - return Length; // Return byte count NOT x-ferred - -} - -static void dUsbSendStall(void) -{ - (*AT91C_UDP_CSR0) |= AT91C_UDP_FORCESTALL; // Set STALL condition - while ( !((*AT91C_UDP_CSR0) & AT91C_UDP_ISOERROR) ); // Wait until stall ack'ed - - (*AT91C_UDP_CSR0) &= ~(AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR); // Reset again - while ((*AT91C_UDP_CSR0) & (AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR)); // Wait until H/W really reset -} - -static void dUsbSendZeroLengthPackage(void) -{ - // Signal that buffer is ready to send - (*AT91C_UDP_CSR0) |= AT91C_UDP_TXPKTRDY; - - dUsbStartTimeoutTimer(); - - // Wait for ACK handshake from host - while ( !((*AT91C_UDP_CSR0) & AT91C_UDP_TXCOMP) && !dUsbTimedOut()); - // Clear handshake flag - (*AT91C_UDP_CSR0) &= ~(AT91C_UDP_TXCOMP); - while ((*AT91C_UDP_CSR0) & AT91C_UDP_TXCOMP); -} - -static void dUsbSendViaControl(const UBYTE *pData, ULONG Length) -{ - ULONG BytesToTx = 0; - AT91_REG Temp_Csr; - UBYTE HaveToTxZeroLength = FALSE; - UBYTE ZeroCouldBeNeeded = FALSE; - - // If the amount of data requested is more than what can be sent, a 0-length - // packet may be required - if (RequestedData > Length) - { - ZeroCouldBeNeeded = TRUE; // Exact same size would be interpreted as EOP @ host - } - - do - { - // The endpoint size is 8 bytes. Limit each data phase to 8 bytes. - - BytesToTx = MIN(Length, 8); - Length -= BytesToTx; - - // If this is the last data phase containing data, but the host requested - // more, a 0-byte packet will be needed to terminate the data phase. - if(ZeroCouldBeNeeded && (Length == 0) && (BytesToTx == 8)) - { - HaveToTxZeroLength = TRUE; - } - - // Copy data to endpoint buffer - while (BytesToTx--) - { - (*AT91C_UDP_FDR0) = *pData++; - } - - // Signal that buffer is ready to send - (*AT91C_UDP_CSR0) |= AT91C_UDP_TXPKTRDY; - - dUsbStartTimeoutTimer(); - - // Wait for ACK handshake from host - do - { - Temp_Csr = (*AT91C_UDP_CSR0); - - // Return if the status phase occurs before the packet is accepted - if (Temp_Csr & AT91C_UDP_RX_DATA_BK0) - { - // Clear the PKTRDY flag - (*AT91C_UDP_CSR0) &= ~(AT91C_UDP_TXPKTRDY); - // Clear the status phase flag - (*AT91C_UDP_CSR0) &= ~(AT91C_UDP_RX_DATA_BK0); - return; - } - } - while (!(Temp_Csr & AT91C_UDP_TXCOMP) && !dUsbTimedOut()); - - // Clear handshake flag - (*AT91C_UDP_CSR0) &= ~(AT91C_UDP_TXCOMP); - - while ((*AT91C_UDP_CSR0) & AT91C_UDP_TXCOMP); - - } while (Length); - - if(HaveToTxZeroLength) - { - dUsbSendZeroLengthPackage(); - } - - dUsbStartTimeoutTimer(); - - // Wait for Status Phase - while(!((*AT91C_UDP_CSR0) & AT91C_UDP_RX_DATA_BK0) && !dUsbTimedOut()); - // Clear flag - (*AT91C_UDP_CSR0) &= ~(AT91C_UDP_RX_DATA_BK0); -} - -static void dUsbEnumerate(void) -{ - UBYTE bmRequestType, bRequest; - UWORD wValue, wIndex, wLength, wStatus; - - if ( !((*AT91C_UDP_CSR0) & AT91C_UDP_RXSETUP) ) // No setup package available - return; - // Bytes are popped from the FIFO one by one - - bmRequestType = *AT91C_UDP_FDR0; - bRequest = *AT91C_UDP_FDR0; - wValue = ((*AT91C_UDP_FDR0) & 0xFF); - wValue |= ((*AT91C_UDP_FDR0) << 8); - wIndex = ((*AT91C_UDP_FDR0) & 0xFF); - wIndex |= ((*AT91C_UDP_FDR0) << 8); - wLength = ((*AT91C_UDP_FDR0) & 0xFF); - wLength |= ((*AT91C_UDP_FDR0) << 8); - - if (bmRequestType & 0x80) // If a DEVICE-TO-HOST request - { - *AT91C_UDP_CSR0 |= AT91C_UDP_DIR; // Enables data IN transaction in the control data stage - while ( !((*AT91C_UDP_CSR0) & AT91C_UDP_DIR) ); // Repeat until the DIR bit is set - } - - *AT91C_UDP_CSR0 &= ~AT91C_UDP_RXSETUP; // Device firmware has read the setup data in FIFO - while ( ((*AT91C_UDP_CSR0) & AT91C_UDP_RXSETUP) ); // Wait until bit cleared - - // Handle supported standard device request from Table 9-3 in USB specification Rev 2.0 - - switch ((bRequest << 8) | bmRequestType) - { - case STD_GET_DESCRIPTOR: - - RequestedData = wLength; - - if (wValue == 0x100) // Return Device Descriptor - { - if (sizeof(DeviceDescriptor) > wLength) - { - dUsbSendViaControl(DeviceDescriptor, wLength); - } - else - { - dUsbSendViaControl(DeviceDescriptor, sizeof(DeviceDescriptor)); - } - } - else if (wValue == 0x200) // Return Configuration Descriptor - { - if (sizeof(ConfigurationDescriptor) > wLength) - { - dUsbSendViaControl(ConfigurationDescriptor, wLength); - } - else - { - dUsbSendViaControl(ConfigurationDescriptor, sizeof(ConfigurationDescriptor)); - } - } - else if ((wValue & 0xF00) == 0x300) - { - switch(wValue & 0xFF) - { - case 0x00: - if ((sizeof(LangIdDescriptor)) > wLength) - { - dUsbSendViaControl(LangIdDescriptor, wLength); - } - else - { - dUsbSendViaControl(LangIdDescriptor, sizeof(LangIdDescriptor)); - } - break; - - case 0x01: - if ((sizeof(SerialNumberDescriptor)) > wLength) - { - dUsbSendViaControl(SerialNumberDescriptor, wLength); - } - else - { - dUsbSendViaControl(SerialNumberDescriptor, sizeof(SerialNumberDescriptor)); - } - break; - - default: - dUsbSendStall(); // Illegal request :-( - break; - } - } - else - dUsbSendStall(); // Illegal request :-( - - break; - - case STD_SET_ADDRESS: - - // Status IN transfer - (*AT91C_UDP_CSR0) |= AT91C_UDP_TXPKTRDY; - - dUsbStartTimeoutTimer(); - - while((*AT91C_UDP_CSR0) & AT91C_UDP_TXPKTRDY && !dUsbTimedOut()); - - *AT91C_UDP_FADDR = (AT91C_UDP_FEN | wValue); // Set device address. No check for invalid address. - // Function endpoint enabled. - *AT91C_UDP_GLBSTATE = (wValue) ? AT91C_UDP_FADDEN : 0; // If Device address != 0 then flag device - // in ADDRESS STATE - break; - - case STD_SET_CONFIGURATION: - - CurrentConfiguration = wValue; // Low byte of wValue = wanted configuration - UsbConnectionStates = USB_CONFIGURED; - dUsbSendZeroLengthPackage(); // Signal request processed OK - - *AT91C_UDP_GLBSTATE = (wValue) ? AT91C_UDP_CONFG : AT91C_UDP_FADDEN; // If wanted configuration != 0 - - *AT91C_UDP_CSR1 = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT) : 0; // Endpoint 1 enabled and set as BULK OUT - *AT91C_UDP_CSR2 = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN) : 0; // Endpoint 2 enabled and set as BULK IN - *AT91C_UDP_CSR3 = (wValue) ? (AT91C_UDP_EPTYPE_INT_IN) : 0; // Endpoint 3 disabled and set as INTERRUPT IN - - break; - - case STD_GET_CONFIGURATION: // The actual configuration value is sent to HOST - - RequestedData = sizeof(CurrentConfiguration); - - dUsbSendViaControl((UBYTE *) &(CurrentConfiguration), sizeof(CurrentConfiguration)); - - break; - - case STD_GET_STATUS_ZERO: - - wStatus = 0x01; // Atmel has a 0x00, but we're not BUS-powered - RequestedData = sizeof(wStatus); - - dUsbSendViaControl((UBYTE *) &wStatus, sizeof(wStatus)); - - break; - - case STD_GET_STATUS_INTERFACE: // Everything reset to zero (reserved) - - wStatus = 0; - RequestedData = sizeof(wStatus); - - dUsbSendViaControl((UBYTE *) &wStatus, sizeof(wStatus)); - - break; - - case STD_GET_STATUS_ENDPOINT: - - wStatus = 0; - RequestedData = sizeof(wStatus); - wIndex &= 0x0F; // Mask the endpoint # - - if (((*AT91C_UDP_GLBSTATE) & AT91C_UDP_CONFG) && (wIndex <= 3)) // If device in CONFIGURED state - { // and ENDPOINT selected in valid range - - switch (wIndex) - { - - case 1: wStatus = ((*AT91C_UDP_CSR1) & AT91C_UDP_EPEDS) ? 0 : 1; // If an endpoint is halted, the HALT - // feature is set to 1, else reset - break; - - case 2: wStatus = ((*AT91C_UDP_CSR2) & AT91C_UDP_EPEDS) ? 0 : 1; - - break; - - case 3: wStatus = ((*AT91C_UDP_CSR3) & AT91C_UDP_EPEDS) ? 0 : 1; - - break; - default: - // We'll never come here, but we'll never say never....... - break; - } - - dUsbSendViaControl((UBYTE *) &wStatus, sizeof(wStatus)); - - } - - else if (((*AT91C_UDP_GLBSTATE) & AT91C_UDP_FADDEN) && (wIndex == 0)) - { - wStatus = ((*AT91C_UDP_CSR0) & AT91C_UDP_EPEDS) ? 0 : 1; // Return 1 if device in ADRESSED state - - dUsbSendViaControl((UBYTE *) &wStatus, sizeof(wStatus)); - } - else - - dUsbSendStall(); // Illegal request :-( - - break; - - case STD_SET_FEATURE_ZERO: - - dUsbSendStall(); // Illegal request :-( - - break; - - case STD_SET_FEATURE_INTERFACE: - - dUsbSendZeroLengthPackage(); // TextBook - - break; - - case STD_SET_FEATURE_ENDPOINT: - - wIndex &= 0x0F; - - if ((wValue == 0) && wIndex && (wIndex <= 3)) // Feature Selector = 0 ENDPOINT HALT and - { // endpoint isolated and validated - - switch (wIndex) - { - - case 1: (*AT91C_UDP_CSR1) = 0; - - break; - - case 2: (*AT91C_UDP_CSR2) = 0; - - break; - - case 3: (*AT91C_UDP_CSR3) = 0; - - break; - - default: - // We'll never come here, but we'll never say never....... - break; - - } - - dUsbSendZeroLengthPackage(); - - } - else - - dUsbSendStall(); // Illegal request :-( - - break; - - case STD_CLEAR_FEATURE_ZERO: - - dUsbSendStall(); // Illegal request :-( - - break; - - case STD_CLEAR_FEATURE_INTERFACE: - - dUsbSendZeroLengthPackage(); // No special - - break; - - case STD_CLEAR_FEATURE_ENDPOINT: - - wIndex &= 0x0F; - - if ((wValue == 0) && wIndex && (wIndex <= 3)) // Feature Selector = 0 => ENABLE A HALTED endpoint - { // and endpoint isolated and validated - - if (wIndex == 1) - (*AT91C_UDP_CSR1) = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT); // On duty again - else if (wIndex == 2) - (*AT91C_UDP_CSR2) = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN); // - - else if (wIndex == 3) - (*AT91C_UDP_CSR3) = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_INT_IN); // - - - dUsbSendZeroLengthPackage(); - - } - else - - dUsbSendStall(); // Illegal request :-( - - break; - - default: - - dUsbSendStall(); // Illegal request :-( - - break; - } -} - -UBYTE dUsbIsConfigured(void) -{ - - if (*AT91C_UDP_ISR & END_OF_BUS_RESET) // If "End Of Bus Reset Interrupt" - { // Somebody fallen in the wire? ;-) - - - *AT91C_UDP_ICR = END_OF_BUS_RESET; // Reset "End Of Bus Reset Interrupt" - *AT91C_UDP_ICR = SUSPEND_RESUME; // State unknown after reset, so we better clear - *AT91C_UDP_ICR = WAKEUP; // As above - - CurrentConfiguration = 0; // We're new and ready - UsbConnectionStates = USB_NOT_CONFIGURED; - - *AT91C_UDP_RSTEP = 0xFFFFFFFF; // Reset all implemented endpoints "and a few more" - *AT91C_UDP_RSTEP = 0x0; // Restored as zeroes - // Below our main crash thing, if it is missing ;-) - CurrentReceiveBank = AT91C_UDP_RX_DATA_BK0; // Start the PING-PONG buffers at a known state and order - - *AT91C_UDP_FADDR = AT91C_UDP_FEN; // Set FEN in the Function Address Register - // USB device is able to receive and transfer data - - *AT91C_UDP_CSR0 = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL); // Configure endpoint 0 - // AT91C_UDP_EPEDS = Endpoint enable - // AT91C_UDP_EPTYPE_CTRL = Endpoint type CONTROL - } - - else if (*AT91C_UDP_ISR & SUSPEND_INT) - { - if (UsbConnectionStates == USB_CONFIGURED) - { - UsbConnectionStates = USB_CONFIGURED_BUT_SUSPENDED; - } - else - { - UsbConnectionStates = USB_NOT_CONFIGURED; - } - - *AT91C_UDP_ICR = SUSPEND_INT; - CurrentReceiveBank = AT91C_UDP_RX_DATA_BK0; // Start the PING-PONG buffers at a known state and order - } - - else if (*AT91C_UDP_ISR & SUSPEND_RESUME) - { - if (UsbConnectionStates == USB_CONFIGURED_BUT_SUSPENDED) - { - UsbConnectionStates = USB_CONFIGURED; - } - else - { - UsbConnectionStates = USB_NOT_CONFIGURED; - } - - *AT91C_UDP_ICR = WAKEUP; - *AT91C_UDP_ICR = SUSPEND_RESUME; - } - - else if (*AT91C_UDP_ISR & AT91C_UDP_EPINT0) // If "Endpoint 0 Interrupt" - { - *AT91C_UDP_ICR = AT91C_UDP_EPINT0; // Reset "Endpoint 0 Interrupt" - if (BrickNameKnown) - dUsbEnumerate(); // Let's date & exchange "personal data" - } - - if (UsbConnectionStates == USB_CONFIGURED) - { - return TRUE; - } - else - { - return FALSE; - } - -} - - -void dUsbInsertHandle(UBYTE Handle) -{ - UBYTE Tmp; - - Tmp = 0; - while((UsbHandleList[Tmp] != MAX_HANDLES) && (Tmp < MAX_HANDLES)) - { - Tmp++; - } - UsbHandleList[Tmp] = Handle; -} - -void dUsbRemoveHandle(UBYTE Handle) -{ - UBYTE Tmp; - - Tmp = 0; - while (Tmp < MAX_HANDLES) - { - if (Handle == UsbHandleList[Tmp]) - { - UsbHandleList[Tmp] = MAX_HANDLES; - } - Tmp++; - } -} - -UWORD dUsbGetFirstHandle(void) -{ - UWORD RtnVal; - - UsbHandleCnt = 0; - RtnVal = dUsbGetNextHandle(); - - return(RtnVal); -} - -UWORD dUsbGetNextHandle(void) -{ - UBYTE Tmp; - UWORD RtnVal; - - RtnVal = 0; - Tmp = UsbHandleCnt; - while((Tmp < MAX_HANDLES) && (MAX_HANDLES == UsbHandleList[Tmp])) - { - Tmp++; - } - UsbHandleCnt = Tmp + 1; - - if (Tmp < MAX_HANDLES) - { - RtnVal |= UsbHandleList[Tmp]; - } - else - { - RtnVal = 0x8100; - } - - return(RtnVal); -} - -UWORD dUsbCheckConnection(void) -{ - UWORD ADValue; - UWORD Return; - - Return = FALSE; - USBReadADCValue(&ADValue); - - if (ADValue > 512) - { - Return = TRUE; - } - return(Return); -} - -void dUsbInit(void) -{ - UBYTE Tmp; - - // We could come from a SAMBA session and then we need - // to "introduce ourself in a polite way for the PNP manager - // We will pull the carpet and start a new session by removing - // the pull up of the D+ wire - - BrickNameKnown = FALSE; - dUsbStartTimeoutTimer(); // Let H/W settle - dUsbDisconnect(); // Pull the carpet - while(!USBTimedOut); // wait 1 mS. - - USBHwInit; // New session - - CurrentConfiguration = 0; // We're new born - UsbConnectionStates = USB_NOT_CONFIGURED; - CurrentReceiveBank = AT91C_UDP_RX_DATA_BK0; // Always start from Bank 0 - RequestedData = 0; - - for(Tmp = 0; Tmp < MAX_HANDLES; Tmp++) - { - UsbHandleList[Tmp] = MAX_HANDLES; - } -} - -void dUsbResetConfig(void) -{ - CurrentConfiguration = 0; // We've lost the connection - UsbConnectionStates = USB_NOT_CONFIGURED; -} - -void dUsbExit(void) -{ -// USBExit; -} diff --git a/AT91SAM7S256/Source/d_usb.h b/AT91SAM7S256/Source/d_usb.h deleted file mode 100644 index b8e78c4..0000000 --- a/AT91SAM7S256/Source/d_usb.h +++ /dev/null @@ -1,51 +0,0 @@ -// -// Programmer -// -// Date init 14.12.2004 -// -// Reviser $Author:: Dkandlun $ -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: d_usb.h $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_usb. $ -// -// Platform C -// - -#ifndef D_USB -#define D_USB - -//* public constants - -// LOW level commands - -#define OPENFILEWRITE 0x01 -#define OPENFILEREAD 0x02 -#define WRITEFILE 0x03 -#define CLOSEFILE 0x04 - -// Low level direct command escape - -#define DIRECTCOMMAND 0x80 // Escape sent to the Loader -#define USB_TIMEOUT 0x0BB8 // Equals approx. 1 mS. Used for recover a "broken" cable situation - -//* external function description - -void dUsbInit(void); -void dUsbExit(void); -ULONG dUsbRead(UBYTE *pData, ULONG Length); -ULONG dUsbWrite( const UBYTE *pData, ULONG Length); -UBYTE dUsbIsConfigured(void); - -void dUsbInsertHandle(UBYTE Handle); -void dUsbRemoveHandle(UBYTE Handle); -UWORD dUsbGetFirstHandle(void); -UWORD dUsbGetNextHandle(void); -UWORD dUsbCheckConnection(void); -void dUsbResetConfig(void); -void dUsbStoreBtAddress(UBYTE *pBtAddress); -#endif diff --git a/AT91SAM7S256/Source/d_usb.r b/AT91SAM7S256/Source/d_usb.r deleted file mode 100644 index 6c7a0c3..0000000 --- a/AT91SAM7S256/Source/d_usb.r +++ /dev/null @@ -1,65 +0,0 @@ -// -// Programmer -// -// Date init 14.12.2004 -// -// Reviser $Author:: Dkandlun $ -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: d_usb.r $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_usb. $ -// -// Platform C -// - -#ifdef SAM7S256 - -#ifdef PROTOTYPE_PCB_3 -#define ENABLEUsbPU *AT91C_PIOA_PER = AT91C_PIO_PA16; /* PIO allowed to control bit 16 */\ - *AT91C_PIOA_OER = AT91C_PIO_PA16; /* Output pin 16 enabled */\ - *AT91C_PIOA_SODR = AT91C_PIO_PA16 /* Pin 16 set = enable USB pull-up */ -#endif - -#ifdef PROTOTYPE_PCB_4 -#define ENABLEUsbPU *AT91C_PIOA_PER = AT91C_PIO_PA16; /* PIO allowed to control bit 16 */\ - *AT91C_PIOA_OER = AT91C_PIO_PA16; /* Output pin 16 enabled */\ - *AT91C_PIOA_CODR = AT91C_PIO_PA16 /* Pin 16 clear = enable USB pull-up */ - -#define DISABLEUsbPU *AT91C_PIOA_PER = AT91C_PIO_PA16; /* PIO allowed to control bit 16 */\ - *AT91C_PIOA_OER = AT91C_PIO_PA16; /* Output pin 16 enabled */\ - *AT91C_PIOA_SODR = AT91C_PIO_PA16 /* Pin 16 set = disable USB pull-up */ -#endif - - -#define USBHwInit *AT91C_CKGR_PLLR |= AT91C_CKGR_USBDIV_1; /* Set the PLL USB Divider (96MHz/2) */\ - *AT91C_PMC_SCER = AT91C_PMC_UDP; /* WRITE-ONLY REG! Enables the 48MHz USB clock UDPCK (SysClk) */\ - *AT91C_PMC_PCER = (1 << AT91C_ID_UDP); /* WRITE-ONLY REG! Enable USB clock (Peripheral Clock) */\ - \ - /* Enable UDP PullUp (USB_DP_PUP) : enable & Clear of the corresponding PIO */ \ - \ - /* Removed 22022006 14:20 pc ENABLEUsbPU BlueCore delay , No pull up before OK serial-no rec. from B.C.*/ - - -static ULONG USBTimeOut; - -#define USBTimedOut (USB_TIMEOUT < ((((*AT91C_PITC_PIIR) & AT91C_PITC_CPIV) - USBTimeOut) & AT91C_PITC_CPIV)) - -#define USBGetActualTime USBTimeOut = ((*AT91C_PITC_PIIR) & AT91C_PITC_CPIV) - -#define USBReadADCValue(ADValue) *ADValue = *AT91C_ADC_CDR4 - -#define USBExit - -#define USBDisconnect DISABLEUsbPU - -#define USBConnect ENABLEUsbPU - -#endif - -#ifdef PCWIN - -#endif diff --git a/AT91SAM7S256/Source/m_sched.c b/AT91SAM7S256/Source/m_sched.c deleted file mode 100644 index 7c69551..0000000 --- a/AT91SAM7S256/Source/m_sched.c +++ /dev/null @@ -1,94 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: m_sched.c $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/m_sche $ -// -// Platform C -// - - -#define INCLUDE_OS - -#define MODULEHEADERS 32 - -#include "stdconst.h" -#include "modules.h" -#include "m_sched.h" - -#include "c_comm.h" -#include "c_input.h" -#include "c_button.h" -#include "c_loader.h" -#include "c_sound.h" -#include "c_display.h" -#include "c_lowspeed.h" -#include "c_output.h" -#include "c_cmd.h" -#include "c_cmd.iom" -#include "c_ioctrl.h" -#include "c_ui.h" - - -static const HEADER* pModuleHeaders[MODULEHEADERS] = -{ - &cComm, - &cInput, - &cButton, - &cDisplay, - &cLoader, - &cLowSpeed, - &cOutput, - &cSound, - &cIOCtrl, - &cCmd, - &cUi, - 0 -}; - - -void mSchedInit(void) -{ - UWORD Tmp; - - Tmp = 0; - while(pModuleHeaders[Tmp]) - { - (*pModuleHeaders[Tmp]).cInit((void*) pModuleHeaders); - Tmp++; - } -} - - -UBYTE mSchedCtrl(void) -{ - UWORD Tmp; - - Tmp = 0; - while(pModuleHeaders[Tmp]) - { - (*pModuleHeaders[Tmp]).cCtrl(); - Tmp++; - } - - return(((IOMAPCMD*)(pModuleHeaders[ENTRY_CMD]->pIOMap))->Awake); -} - - -void mSchedExit(void) -{ - UWORD Tmp; - - Tmp = 0; - while(pModuleHeaders[Tmp]) - { - (*pModuleHeaders[Tmp]).cExit(); - Tmp++; - } -} - diff --git a/AT91SAM7S256/Source/m_sched.h b/AT91SAM7S256/Source/m_sched.h deleted file mode 100644 index b3bb27e..0000000 --- a/AT91SAM7S256/Source/m_sched.h +++ /dev/null @@ -1,135 +0,0 @@ -// -// Date init 14.12.2004 -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: m_sched.h $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/m_sche $ -// -// Platform C -// - - - -#define APPNAME "LMS01" - -#define COPYRIGHTSTRING "Let's samba nxt arm in arm, (c)LEGO System A/S" - -#define COPYRIGHTSTRINGLENGTH 46 /* Number of bytes checked in COPYRIGHTSTRING */ - - -#ifndef _WINDOWS - -#define SAM7SXX - -#ifdef SAM7SXX - - // - // Platform ATMEL ARM7 - // - // - -#define OSC 48054850L -#define SYSFREQ 1000 - - -#include "../SAM7S256/Include/sam7s256.h" - -#if defined (PROTOTYPE_PCB_3) || (PROTOTYPE_PCB_4) - -#define TSTPin AT91C_PIO_PA27 - -#else - -#define TSTPin AT91C_PIO_PA31 - -#endif - -#define TSTInit {\ - *AT91C_PIOA_PER = TSTPin;\ - *AT91C_PIOA_OER = TSTPin;\ - } - -#define TSTOn {\ - *AT91C_PIOA_SODR = TSTPin;\ - } - -#define TSTOff {\ - *AT91C_PIOA_CODR = TSTPin;\ - } - -#define TSTExit {\ - *AT91C_PIOA_ODR = TSTPin;\ - *AT91C_PIOA_CODR = TSTPin;\ - } - -/* Defines related to loader */ -#define MAX_HANDLES 16 - - -/* Defines related to I2c */ -#define BYTES_TO_TX 8 -#define BYTES_TO_RX 12 - -enum -{ - NOS_OF_AVR_OUTPUTS = 4, - NOS_OF_AVR_BTNS = 4, - NOS_OF_AVR_INPUTS = 4 -}; - -typedef struct -{ - UWORD AdValue[NOS_OF_AVR_INPUTS]; - UWORD Buttons; - UWORD Battery; -}IOFROMAVR; - -typedef struct -{ - UBYTE Power; - UBYTE PwmFreq; - SBYTE PwmValue[NOS_OF_AVR_OUTPUTS]; - UBYTE OutputMode; - UBYTE InputPower; -}IOTOAVR; - -extern IOTOAVR IoToAvr; -extern IOFROMAVR IoFromAvr; - -#ifdef INCLUDE_OS - -#include "../SAM7S256/Include/sam7s256.c" - -IOTOAVR IoToAvr; -IOFROMAVR IoFromAvr; - -#endif - -#endif - -#else - - // - // Platform PCWIN - // - // - -#define OSC 1192000L -#define SYSFREQ 1000 - -#include "Pcwin.h" - -#ifdef INCLUDE_OS - -#include "Pcwin.c" - -#endif - -#endif - - - diff --git a/AT91SAM7S256/Source/modules.h b/AT91SAM7S256/Source/modules.h deleted file mode 100644 index a5f3bb1..0000000 --- a/AT91SAM7S256/Source/modules.h +++ /dev/null @@ -1,338 +0,0 @@ -// -// Programmer -// -// Date init 14.12.2004 -// -// Reviser $Author:: Dktochpe $ -// -// Revision date $Date:: 19-02-08 8:15 $ -// -// Filename $Workfile:: modules.h $ -// -// Version $Revision:: 4 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/module $ -// -// Platform C -// - -#ifndef MODULE_HEADER -#define MODULE_HEADER - -#define FILENAME_LENGTH 19 // zero termination not included -#define FILEHEADER_LENGTH 8 // all simple file headers -#define DISPLAYLINE_LENGTH 16 // zero termination not included -#define ON_BRICK_PROGRAMSTEPS 5 // no of on brick program steps -#define STATUSTEXT_SIZE 8 // zero termination not included - -#define TXT_SOUND_EXT "rso" // Sound filename extension -#define TXT_LMS_EXT "rxe" // Mindstorms program filename extension -#define TXT_NXT_EXT "rpg" // Program filename extension -#define TXT_TRYME_EXT "rtm" // Try me program filename extension -#define TXT_DATA_EXT "log" // Datalog filename extension -#define TXT_SYS_EXT "sys" // System filename extension (hidden) -#define TXT_TMP_EXT "tmp" // Temporary filename extension (hidden) - - -/* Error codes from then Loader */ -enum -{ - SUCCESS = 0x0000, - INPROGRESS = 0x0001, - REQPIN = 0x0002, - NOMOREHANDLES = 0x8100, - NOSPACE = 0x8200, - NOMOREFILES = 0x8300, - EOFEXSPECTED = 0x8400, - ENDOFFILE = 0x8500, - NOTLINEARFILE = 0x8600, - FILENOTFOUND = 0x8700, - HANDLEALREADYCLOSED = 0x8800, - NOLINEARSPACE = 0x8900, - UNDEFINEDERROR = 0x8A00, - FILEISBUSY = 0x8B00, - NOWRITEBUFFERS = 0x8C00, - APPENDNOTPOSSIBLE = 0x8D00, - FILEISFULL = 0x8E00, - FILEEXISTS = 0x8F00, - MODULENOTFOUND = 0x9000, - OUTOFBOUNDERY = 0x9100, - ILLEGALFILENAME = 0x9200, - ILLEGALHANDLE = 0x9300, - BTBUSY = 0x9400, - BTCONNECTFAIL = 0x9500, - BTTIMEOUT = 0x9600, - FILETX_TIMEOUT = 0x9700, - FILETX_DSTEXISTS = 0x9800, - FILETX_SRCMISSING = 0x9900, - FILETX_STREAMERROR = 0x9A00, - FILETX_CLOSEERROR = 0x9B00 -}; - - -/* interface between comm and BC4 */ -enum -{ - MSG_BEGIN_INQUIRY, - MSG_CANCEL_INQUIRY, - MSG_CONNECT, - MSG_OPEN_PORT, - MSG_LOOKUP_NAME, - MSG_ADD_DEVICE, - MSG_REMOVE_DEVICE, - MSG_DUMP_LIST, - MSG_CLOSE_CONNECTION, - MSG_ACCEPT_CONNECTION, - MSG_PIN_CODE, - MSG_OPEN_STREAM, - MSG_START_HEART, - MSG_HEARTBEAT, - MSG_INQUIRY_RUNNING, - MSG_INQUIRY_RESULT, - MSG_INQUIRY_STOPPED, - MSG_LOOKUP_NAME_RESULT, - MSG_LOOKUP_NAME_FAILURE, - MSG_CONNECT_RESULT, - MSG_RESET_INDICATION, - MSG_REQUEST_PIN_CODE, - MSG_REQUEST_CONNECTION, - MSG_LIST_RESULT, - MSG_LIST_ITEM, - MSG_LIST_DUMP_STOPPED, - MSG_CLOSE_CONNECTION_RESULT, - MSG_PORT_OPEN_RESULT, - MSG_SET_DISCOVERABLE, - MSG_CLOSE_PORT, - MSG_CLOSE_PORT_RESULT, - MSG_PIN_CODE_ACK, - MSG_DISCOVERABLE_ACK, - MSG_SET_FRIENDLY_NAME, - MSG_SET_FRIENDLY_NAME_ACK, - MSG_GET_LINK_QUALITY, - MSG_LINK_QUALITY_RESULT, - MSG_SET_FACTORY_SETTINGS, - MSG_SET_FACTORY_SETTINGS_ACK, - MSG_GET_LOCAL_ADDR, - MSG_GET_LOCAL_ADDR_RESULT, - MSG_GET_FRIENDLY_NAME, - MSG_GET_DISCOVERABLE, - MSG_GET_PORT_OPEN, - MSG_GET_FRIENDLY_NAME_RESULT, - MSG_GET_DISCOVERABLE_RESULT, - MSG_GET_PORT_OPEN_RESULT, - MSG_GET_VERSION, - MSG_GET_VERSION_RESULT, - MSG_GET_BRICK_STATUSBYTE_RESULT, - MSG_SET_BRICK_STATUSBYTE_RESULT, - MSG_GET_BRICK_STATUSBYTE, - MSG_SET_BRICK_STATUSBYTE -}; - -#define SIZE_OF_BT_NAME 16 -#define SIZE_OF_BRICK_NAME 8 -#define SIZE_OF_CLASS_OF_DEVICE 4 -#define SIZE_OF_BT_PINCODE 16 -#define SIZE_OF_BDADDR 7 - - -enum -{ - ENTRY_COMM, - ENTRY_INPUT, - ENTRY_BUTTON, - ENTRY_DISPLAY, - ENTRY_LOADER, - ENTRY_LOWSPEED, - ENTRY_OUTPUT, - ENTRY_SOUND, - ENTRY_IOCTRL, - ENTRY_CMD, - ENTRY_UI, - ENTRY_FREE2, - ENTRY_FREE3, - ENTRY_FREE4, - ENTRY_FREE5 -}; - -typedef struct -{ - ULONG ModuleID; - UBYTE ModuleName[FILENAME_LENGTH + 1]; - void (*cInit)(void* pHeader); - void (*cCtrl)(void); - void (*cExit)(void); - void *pIOMap; - void *pVars; - UWORD IOMapSize; - UWORD VarsSize; - UWORD ModuleSize; -}HEADER; - -enum -{ - FILEFORMAT_SOUND = 0x0100, // rso - FILEFORMAT_SOUND_COMPRESSED = 0x0101, // rso - FILEFORMAT_BITMAP = 0x0200, - FILEFORMAT_FONT = 0x0300, - FILEFORMAT_ICON = 0x0400, - FILEFORMAT_TEXT = 0x0500, - FILEFORMAT_MELODY = 0x0600, - FILEFORMAT_MENU = 0x0700, // rms - FILEFORMAT_PROGRAM = 0x0800, // rpg - FILEFORMAT_DATALOG = 0x0900 // rdt -}; - -typedef struct -{ - UBYTE FormatMsb; - UBYTE FormatLsb; - UBYTE DateBytesMsb; - UBYTE DataBytesLsb; - UBYTE SampleRateMsb; - UBYTE SampleRateLsb; - UBYTE PlayModeMsb; - UBYTE PlayModeLsb; - UBYTE Data[]; -} -SOUND; - -typedef struct -{ - UBYTE FormatMsb; - UBYTE FormatLsb; - UBYTE DateBytesMsb; - UBYTE DataBytesLsb; - UBYTE StartX; - UBYTE StartY; - UBYTE PixelsX; - UBYTE PixelsY; - UBYTE Data[]; -} -BMPMAP; - -typedef struct -{ - UBYTE FormatMsb; - UBYTE FormatLsb; - UBYTE DataBytesMsb; - UBYTE DataBytesLsb; - UBYTE ItemsX; - UBYTE ItemsY; - UBYTE ItemPixelsX; - UBYTE ItemPixelsY; - UBYTE Data[]; -} -FONT; - -typedef struct -{ - UBYTE FormatMsb; - UBYTE FormatLsb; - UBYTE DataBytesMsb; - UBYTE DataBytesLsb; - UBYTE ItemsX; - UBYTE ItemsY; - UBYTE ItemPixelsX; - UBYTE ItemPixelsY; - UBYTE Data[]; -} -ICON; - -typedef struct -{ - UBYTE FormatMsb; - UBYTE FormatLsb; - UBYTE DataBytesMsb; - UBYTE DataBytesLsb; - UBYTE ItemsX; - UBYTE ItemsY; - UBYTE ItemCharsX; - UBYTE ItemCharsY; - UBYTE Data[]; -} -TXT; - -typedef struct -{ - UBYTE FormatMsb; - UBYTE FormatLsb; - UBYTE DateBytesMsb; - UBYTE DataBytesLsb; - UBYTE TonesMsb; - UBYTE TonesLsb; - UBYTE PlayModeMsb; - UBYTE PlayModeLsb; - UBYTE Data[]; // Data[0] = FreqMsb, Data[1] = FreqLsb, Data[2] = DurationMsb, Data[3] = DurationLsb .... -} -MELODY; - -typedef struct -{ - UBYTE FormatMsb; - UBYTE FormatLsb; - UBYTE DataBytesMsb; - UBYTE DataBytesLsb; - UBYTE Steps; - UBYTE NotUsed1; - UBYTE NotUsed2; - UBYTE NotUsed3; - UBYTE Data[]; -} -PROGRAM; - -typedef struct -{ - UBYTE FormatMsb; - UBYTE FormatLsb; - UBYTE DataBytesMsb; - UBYTE DataBytesLsb; - UBYTE TotalTime3; - UBYTE TotalTime2; - UBYTE TotalTime1; - UBYTE TotalTime0; - UBYTE Data[]; -} -DATALOG; - -#define ICON_TEXTLNG 15 // 15 characters -#define ICON_IMAGESIZE 72 // 24 x 24 pixels -#define MAX_MENUITEMS 256 - -typedef struct -{ - UBYTE ItemId67; // Menu item id - UBYTE ItemId45; // Menu item id - UBYTE ItemId23; // Menu item id - UBYTE ItemId01; // Menu item id - UBYTE SpecialMask3; // Menu item special mask (TBD) - UBYTE SpecialMask2; // Menu item special mask (TBD) - UBYTE SpecialMask1; // Menu item special mask (TBD) - UBYTE SpecialMask0; // Menu item special mask (TBD) - UBYTE FunctionIndex; // Menu item enter function call index - UBYTE FunctionParameter; // Menu item enter function parameter - UBYTE FileLoadNo; // Menu item enter menu file load no - UBYTE NextMenu; // Menu item enter next level menu no - UBYTE IconText[ICON_TEXTLNG + 1]; // Menu item icon text string - UBYTE IconImageNo; // Menu item icon image number -}MENUITEM; - -typedef struct -{ - UBYTE FormatMsb; - UBYTE FormatLsb; - UBYTE DataBytesMsb; - UBYTE DataBytesLsb; - UBYTE ItemSize; - UBYTE Items; - UBYTE ItemPixelsX; - UBYTE ItemPixelsY; - MENUITEM Data[MAX_MENUITEMS]; -} -MENU; - -typedef UBYTE (*FUNCTION)(UBYTE); // Menu function type - -#endif - - - diff --git a/AT91SAM7S256/Source/stdconst.h b/AT91SAM7S256/Source/stdconst.h deleted file mode 100644 index 6c08175..0000000 --- a/AT91SAM7S256/Source/stdconst.h +++ /dev/null @@ -1,74 +0,0 @@ -// -// Programmer -// -// Date init 14.12.2004 -// -// Reviser $Author:: Dkandlun $ -// -// Revision date $Date:: 14-11-07 12:40 $ -// -// Filename $Workfile:: stdconst.h $ -// -// Version $Revision:: 1 $ -// -// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/stdcon $ -// -// Platform C -// - - -#ifndef STDCONST -#define STDCONST - -#include "config.h" - -#ifndef NULL -#define NULL ((void *)0) -#endif - -#define TRUE 1 -#define FALSE 0 - -typedef unsigned char UCHAR; -typedef unsigned short USHORT; - -typedef unsigned char UBYTE; -typedef signed char SBYTE; -typedef unsigned short int UWORD; -typedef signed short int SWORD; -typedef unsigned long ULONG; -typedef signed long SLONG; - -typedef ULONG* PULONG; -typedef USHORT* PUSHORT; -typedef UCHAR* PUCHAR; -typedef char* PSZ; - -#define BASETYPES - -#ifdef __GNUC__ -#define DEFINE_DATA(type, name) \ - extern const type name ## _; \ - const type * const name = &name ## _; \ - const type name ## _ -#define BEGIN_DATA { -#define END_DATA } -#define POINTER_TO_DATA(name) (&name ## _) -#define SIZEOF_DATA(name) (sizeof_ ## name) -#else -#define DEFINE_DATA(type, name) \ - const type name[] -#define BEGIN_DATA -#define END_DATA -#define POINTER_TO_DATA(name) (name) -#define SIZEOF_DATA(name) (sizeof (name)) -#endif - -#ifdef __GNUC__ -#define __ramfunc __attribute__ ((section (".fastrun"), optimize ("no-jump-tables"))) -#define __ramdata __attribute__ ((section (".data"))) -#else -#define __ramdata -#endif - -#endif diff --git a/AT91SAM7S256/armdebug/.gitignore b/AT91SAM7S256/armdebug/.gitignore deleted file mode 100644 index 46f8223..0000000 --- a/AT91SAM7S256/armdebug/.gitignore +++ /dev/null @@ -1,41 +0,0 @@ -# Ignore tag -MASTER-REPO_DO-NOT-DELETE -*.lst -*.objdump -.DS_Store - -# Generally annoying things. -*.[oa] -*.pyc -*.bin -*.elf -*.rxe -*.map -*.orig -*.log -*~ -*.swp -\#*\# -.\#* - -# Python distutils creates this when building. -pynxt/build/ - -# XCode build stuff -FantomModule/build/ -*mode1v3 -*pbxuser - -# SCons cruft -.sconsign.dblite -.sconf_temp -build_flags.py - -# Precommit hooks drop a commit.msg file if they fail. -commit.msg - -# The option-cache -scons.options - -# pyfantom related -pyfantom.py diff --git a/AT91SAM7S256/armdebug/.project b/AT91SAM7S256/armdebug/.project deleted file mode 100644 index 15b12fc..0000000 --- a/AT91SAM7S256/armdebug/.project +++ /dev/null @@ -1,11 +0,0 @@ - - - armdebug - - - - - - - - diff --git a/AT91SAM7S256/armdebug/AUTHORS b/AT91SAM7S256/armdebug/AUTHORS deleted file mode 100644 index 169c2b6..0000000 --- a/AT91SAM7S256/armdebug/AUTHORS +++ /dev/null @@ -1,6 +0,0 @@ -The following people have contributed code, in various quantities, to armdebug. -A big thanks to all of them, armdebug is what it is in part thanks to each of -them. In alphabetical order: - -Nicolas Schodet -Tat Chee Wan diff --git a/AT91SAM7S256/armdebug/COPYING b/AT91SAM7S256/armdebug/COPYING deleted file mode 100644 index 86fae60..0000000 --- a/AT91SAM7S256/armdebug/COPYING +++ /dev/null @@ -1,9 +0,0 @@ -The armdebug project is dual licensed. - -You can either use the GNU GPLv2 license in GNU-GPLv2.txt, -or else the "LEGO Open Source License" in LEGO_Open_Source_License.doc -to redistribute the code. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. diff --git a/AT91SAM7S256/armdebug/Debugger/_c_arm_macros.h b/AT91SAM7S256/armdebug/Debugger/_c_arm_macros.h deleted file mode 100644 index 025542e..0000000 --- a/AT91SAM7S256/armdebug/Debugger/_c_arm_macros.h +++ /dev/null @@ -1,88 +0,0 @@ -/** @file _c_arm_macros.h - * @brief Define macros to support shared C and ASM headers - * - */ - -/* Copyright (C) 2010 the NxOS developers - * - * Module Developed by: TC Wan - * - * Thanks to Bartli (forum post @ embdev.net ARM programming with GCC/GNU tools forum) - * - * See AUTHORS for a full list of the developers. - * - * See COPYING for redistribution license - * - */ - -#ifndef __C_ARM_MACROS__ -#define __C_ARM_MACROS__ - - -#ifdef __ASSEMBLY__ - -#define NULL 0x0 -#define FALSE 0 -#define TRUE ~FALSE - -#define TYPEDEF @ -#define FUNCDEF @ - - .set last_enum_value, 0 - .macro enum_val name - .equiv \name, last_enum_value - .set last_enum_value, last_enum_value + 1 - .endm - -#define ENUM_BEGIN .set last_enum_value, 0 - -#define ENUM_VAL(name) enum_val name -#define ENUM_VALASSIGN(name, value) \ - .set last_enum_value, value ;\ - enum_val name -#define ENUM_END(enum_name) - -#else /* C Defines */ -/** Macro to control typedef generation - * - */ -#define TYPEDEF typedef - -/** Macro to control extern generation - * - */ -#ifndef FUNCDEF -#define FUNCDEF extern -#endif - -/** Macro to control typedef enum generation - * - */ -#define ENUM_BEGIN typedef enum { - -/** Macro to specify enum instance (auto value assignment) - * - */ -#define ENUM_VAL(name) name, - -/** Macro to control enum specification and value assignment -* -*/ -#define ENUM_VALASSIGN(name, value) name = value, - -/** Macro to control enum named type generation - * - */ -#define ENUM_END(enum_name) } enum_name; - -#endif - -/* Example of how to use the ENUM definition macros -ENUM_BEGIN -ENUM_VAL(INIT) -ENUM_VAL(RESET) -ENUM_VAL(CONFIGURED) -ENUM_END(enum_label) -*/ - -#endif /* __C_ARM_MACROS__ */ diff --git a/AT91SAM7S256/armdebug/Debugger/abort_handler.S b/AT91SAM7S256/armdebug/Debugger/abort_handler.S deleted file mode 100644 index dab25d1..0000000 --- a/AT91SAM7S256/armdebug/Debugger/abort_handler.S +++ /dev/null @@ -1,106 +0,0 @@ - -/* Copyright (C) 2007-2011 the NxOS developers - * - * Module Developed by: TC Wan - * - * See AUTHORS for a full list of the developers. - * - * Redistribution of this file is permitted under - * the terms of the GNU Public License (GPL) version 2. - */ -#define __ASSEMBLY__ -#include "debug_stub.h" -#include "debug_internals.h" - -#define PREFETCH_OFFSET 4 -#define DATA_OFFSET 8 - -/* Trap Abort Exceptions. - * On triggering, lr (R14) contains the previous mode's pc (R15). - * Based on example in Hohl, "ARM Assembly Language: Fundamentals and Techniques" - * Chapter 11, Example 11.1. - */ -/* - * NOTE: This routine closely mirrors the undef_handler routine, since we will store - * the ABORT stack frame in the UNDEF stack. - * In addition, since ARMDEBUG uses Abort mode, if the ABORT occurs while the - * debugger is running, the value of SP_abort is not valid. This should not happen - * in any case (it is a BUG if ARMDEBUG triggers an ABORT). - * - * We assume that the DEBUG stack holds only one stack frame and we will overwrite it. - * On entry, LR_undef contains the PC+4 for Prefetch Abort, and PC+8 for Data Abort. - * - * For the purpose of Debugging, the stack frame should present the PC (R15) as the address - * of the instruction that triggered the Abort. Hence we need to adjust R15 - * to point to the address of the ABORTed instruction. - * - * We will also store ABORT LR (next instruction pointer) and ABORT SPSR to the stack. - * - * For the handler, once the user registers have been stored in the DEBUG stack, the - * registers will be used as follows: - * - * R0: ABORT LR, then ABORT instruction address - * R1: SPSR - * R2: PC Offset, then Mode - * R3: DEBUG Stack Pointer (for Banked R13-R14 update) - * R4: Abort Type Enum - */ - -.text -.code 32 -.align 0 - - .extern dbg__display_abort_info - .extern dbg__abort_exception_handler - .extern default_prefetch_abort_handler - .extern default_data_abort_handler - - - dbg_interwork prefetch_abort_handler - ldr sp, =__debugger_stack__ - stmfd sp, {r0-r15}^ /* Save workspace, previous mode's pc via 'S' flag, R13-R15: placeholders */ - mov r2, #PREFETCH_OFFSET - mov r4, #DISP_ABORT_PREFETCH /* Display Abort Info Type */ - mov r5, #DBG_ABORT_PREFETCH /* Debugger Abort Type */ - b _common_abort_handler - - dbg_interwork data_abort_handler - ldr sp, =__debugger_stack__ - stmfd sp, {r0-r15}^ /* Save workspace, previous mode's pc via 'S' flag, R13-R15: placeholders */ - mov r2, #DATA_OFFSET - mov r4, #DISP_ABORT_DATA /* Display Abort Info Type */ - mov r5, #DBG_ABORT_DATA /* Debugger Abort Type */ - -_common_abort_handler: - sub r0, lr, r2 /* R0: Adjust PC to ABORTed instruction address */ - str r0, [sp, #-4] /* Save ABORTed Instruction PC to stack (R15 slot) */ - sub r3, sp, #4 /* Use R3 to write Banked R13-R14 of ABORT instruction, update R3 to point to R14 slot */ - - mrs r1, spsr /* Copy SPSR to r1 */ - tst r1, #CPSR_THUMB /* Check for Thumb Mode */ - addne r0, r0, #2 /* Is Thumb instruction, adjust PC for ABORT next instruction address */ - addeq r0, r0, #4 /* Is ARM instruction, adjust PC for ABORT next instruction address */ - sub sp, sp, #(4*16) /* Need to manually update SP(abort) */ - stmfd sp!, {r0,r1} /* Save ABORTed Next Instr Pointer (in R0) and previous mode's CPSR to stack */ - - and r2, r1, #CPSR_MODE /* Get previous mode */ - teq r2, #MODE_USR - beq _exit_abort_handler /* Can't switch back if we're in User mode! */ - -_store_prev_mode_banked_regs: - /* FIXME: We don't handle FIQ properly! */ - - orr r2, #(CPSR_FIQ | CPSR_IRQ) /* Disable Interrupts */ - msr cpsr_c, r2 /* Switch to previous mode */ - stmfd r3!, {sp, lr} /* Store Previous Mode's LR (R14), SP (R13) via R3 */ - msr cpsr_c, #(MODE_ABT | CPSR_FIQ | CPSR_IRQ) /* Revert to ABORT Mode */ - -_exit_abort_handler: - ldr sp, =__abort_stack__ /* Reinitialize stack pointer each time an Abort happens */ - bic sp, sp, #7 - mov r0, r4 /* Copy Display Abort Type Enum to R0 */ - bl dbg__display_abort_info /* Display Abort Type to LCD */ - mov r0, r5 /* Copy Debugger Abort Type Enum to R0 */ - b dbg__abort_exception_handler /* Invoke Debugger */ - - diff --git a/AT91SAM7S256/armdebug/Debugger/debug_comm.S b/AT91SAM7S256/armdebug/Debugger/debug_comm.S deleted file mode 100644 index b4590eb..0000000 --- a/AT91SAM7S256/armdebug/Debugger/debug_comm.S +++ /dev/null @@ -1,550 +0,0 @@ -/** @file debug_comm.S - * @brief GDB Server communications support routines - * - */ - -/* Copyright (C) 2007-2011 the NxOS developers - * - * Module Developed by: TC Wan - * - * See AUTHORS for a full list of the developers. - * - * See COPYING for redistribution license - * - */ - -#define __ASSEMBLY__ -#include "debug_macros.h" -#include "debug_stub.h" -#include "debug_internals.h" - - .extern dbg__sendCommMsg - - /* Hexutils function references */ - .extern hex2char - .extern char2hex - .extern byte2ascii - .extern halfword2ascii_be - .extern halfword2ascii_le - .extern word2ascii_be - .extern word2ascii_le - .extern ascii2hex_varlen_be - .extern ascii2byte - .extern ascii2halfword_be - .extern ascii2halfword_le - .extern ascii2word_be - .extern ascii2word_le - - -.bss -.align 4 - - .global debug_InCommBuf - .global debug_OutCommBuf -debug_InCommBuf: - .space USB_BUFSIZE,0 -debug_OutCommBuf: - .space USB_BUFSIZE,0 - -debug_msgRxBufPtr: - .word 0x0 -debug_msgTxBufPtr: - .word 0x0 - -debug_msgRxBuf_AppendPtr: - .word 0x0 -debug_msgTxBuf_AppendPtr: - .word 0x0 - - .equ RXAPPENDPTR_OFFSET, (debug_msgRxBuf_AppendPtr - debug_msgRxBufPtr) - .equ TXAPPENDPTR_OFFSET, (debug_msgTxBuf_AppendPtr - debug_msgTxBufPtr) - -debug_segmentRxNum: /* Current Rx Segment Number */ - .word 0x0 - -/* Comm Channel and NXT Received Message Length is now common to both NxOS and NXT Firmware */ -debug_nxtMsgLength: - .word 0x0 - - .global debug_nxtCommChannel -debug_nxtCommChannel: - .word 0x0 - - .global debug_nxtCommOverrun -debug_nxtCommOverrun: - .word 0x0 - - .equ NXTCOMMCHANNEL_OFFSET, (debug_nxtCommChannel - debug_nxtMsgLength) - .equ NXTCOMMOVERRUN_OFFSET, (debug_nxtCommOverrun - debug_nxtMsgLength) - -.data -.align 4 - -nxt_commcmd_header: - .byte NXT_GDBMSG_TELEGRAMTYPE, 0x00, 0x00 /* padded to 3 bytes */ - -.code 32 -.text -.align 4 -/* Debugger Communications Routines - * It does not make sense to pass information from the Debugger Module to the Comm. link one character - * at a time, especially if we're not using a native serial interface (e.g., EIA-232). Consequently - * a Message interface has been defined. This can still call getChar() and putChar() subroutines - * if so desired, but it'll be a purely internal matter. - * - * Message Format - * Since we need to use EP1&2 (Bulk channels) to communicate with the PC Host, the messages should - * follow the NXT Direct Commands message structure (this will allow for interoperability with NXT Firmware - * in addition to NxOS). The maximum length of any USB communications via the Bulk channel is 64 bytes. - * There is a one byte Telegram Type field which identifies the type of telegram, followed by the - * Telegram header and actual message. - * - * The LEGO Mindstorms Communications Protocol Direct Commands GDB Message format (including all headers) - * is as follows: - * - * GDB Command - * =========== - * Byte 0: Telegram Type Field (0x8d Direct Command, No response required) | NXT Msg Header - * Byte 1: Segment No (1-255, 0: Last Segment; limit is MSG_NUMSEGMENTS) | - * Byte 2: Telegram Size (Len of USB Buffer - 3, max is MSG_SEGMENTSIZE) | - * Byte 3-N: Message data | GDB Command - * - * The GDB Command (of size M) has the following format: - * Offset 0: '+'/'-' Command Received Status (Optional) - * Offset 1/0: '$' - * Offset 2/1: GDB Command char - * Offset 3 - (M-4): Command packet info - * Offset M-3: '#' - * Offset M-2: MSB of Checksum - * Offset M-1: LSB of Checksum - * - * To be safe, we assume that the Command Received Status is always sent by the GDB server. Therefore, - * The maximum size of a GDB Command packet is MSGBUF_SIZE - 5 ('+'/'-', '$', '#', 2 byte checksum) - * - * GDB Response - * ============ - * Byte 0: Telegram Type Field (0x8d Direct Command, No response required) | NXT Msg Header - * Byte 1: Segment No (1-255, 0: Last Segment; limit is MSG_NUMSEGMENTS) | - * Byte 2: Telegram Size (Len of USB Buffer - 3, max is MSG_SEGMENTSIZE) | - * Byte 3-N: Message data | GDB Response - * - * The GDB Retransmission Request has the following format: - * Offset 0: '-' Command Received Status - * - * The GDB Response (of size M) has the following format: - * Offset 0: '+' Command Received Status - * Offset 1: '$' - * Offset 2 - (M-4): Response packet info - * Offset M-3: '#' - * Offset M-2: MSB of Checksum - * Offset M-1: LSB of Checksum - * - * The maximum size of a GDB Response packet is MSGBUF_SIZE - 5 ('+', '$', '#', 2 byte checksum) - * - * Note: The Telegram Size is the actual size of the Message Data portion - * (i.e., excludes the three header bytes, includes the GDB Command/Response Packet checksum bytes - * in the last segment) - */ - -/* dbg__comm_init - * Initialize communications channel. - * On Entry: - * R0: MSG Rx Buf Pointer - * R1: MSG Tx Buf Pointer - */ - - dbg_interwork dbg__comm_init - stmfd sp!, {lr} - ldr r2, =debug_msgRxBufPtr - stmia r2!, {r0, r1} /* debug_msgRxBufPtr and debug_msgTxBufPtr */ - stmia r2!, {r0, r1} /* debug_msgRxBuf_AppendPtr and debug_msgTxBuf_AppendPtr */ - bl _dbg__comm_readbuf_reset - ldr r1, =debug_nxtMsgLength - mov r0, #0 - str r0, [r1, #NXTCOMMCHANNEL_OFFSET] /* Clear NXT Channel on INIT */ - ldmfd sp!, {pc} - - -_dbg__comm_readbuf_reset: - ldr r1, =debug_nxtMsgLength - mov r0, #0 - str r0, [r1] /* Clear Received Comm Message Length */ - bx lr - -/* dbg__copyNxtDebugMsg - * Copy NXT Debug Message to our own Buffers, indicate Msg Received status. - * Note: This routine is now used by both NXT Firmware and NxOS - * On Entry: - * R0: NXT Input Buf Pointer - * R1: NXT Communications Channel Enum (CmdBit) - * R2: NXT Raw Message Length - * On Exit: - * R0-R3: Destroyed - */ - dbg_interwork dbg__copyNxtDebugMsg - ldr r3, =debug_nxtMsgLength - str r1, [r3, #NXTCOMMCHANNEL_OFFSET] /* save Communications Channel first */ - ldr r1, [r3] /* Check if there's an unread message in the buffer */ - cmp r1, #0 - beq cont_dbg__copyNxtDebugMsg /* No unread message, so continue */ -exit_dbg__NxtDebugMsgOverrun: - ldr r1, [r3, #NXTCOMMOVERRUN_OFFSET] - add r1, r1, #1 - str r1, [r3, #NXTCOMMOVERRUN_OFFSET] /* update message overrun stats */ - b exit_dbg__copyNxtDebugMsg -cont_dbg__copyNxtDebugMsg: - str r2, [r3] - ldr r1, =debug_InCommBuf - _dbg_memcpy r1, r0, r2, r3 /* r3: scratch register */ -exit_dbg__copyNxtDebugMsg: - bx lr - -/* _dbg_reset_msgTxBuf_AppendPtr - * Internal variable to reset pointers. - * On Exit: - * R0: debug_msgTxBuf_AppendPtr - * R1: destroyed - */ -_dbg_reset_msgTxBuf_AppendPtr: - ldr r1, =debug_msgTxBufPtr /* Should not be modified */ - ldr r0, [r1] - str r0, [r1, #TXAPPENDPTR_OFFSET] - mov pc, lr - -/* _dbg__commHasMsg - * Internal Segment Reassembly Routine. - * On exit: - * r0: !0: (Availale Telegram Message Size), 0: no incoming message/segment - * r1: message segment number - */ -_dbg__commHasMsg: - stmfd sp!, {lr} - ldr r0, =debug_nxtMsgLength - ldr r0, [r0] /* R0 contains the Comm Buffer Size, including the NXT Direct Command Header */ - - ldr r2, =debug_InCommBuf - ldrb r1, [r2, #NXT_MSG_TELEGRAMTYPE_OFFSET] - cmp r1, #NXT_GDBMSG_TELEGRAMTYPE - bne invalid_CommMsg /* Invalid telegram type, ignore */ - - ldrb r1, [r2, #NXT_MSG_TELEGRAMSIZE_OFFSET] - sub r0, r0, r1 /* Comm Buffer Size - Telegram Size = 3 (header size) */ - cmp r0, #NXT_GDBMSG_START /* Start offset is equal to header size */ - bne invalid_CommMsg /* Invalid Message Length, ignore */ - - mov r0, r1 /* Telegram Message Size */ - ldrb r1, [r2, #NXT_MSG_SEGNUM_OFFSET] - b _exit_dbg__commHasMsg - -invalid_CommMsg: - bl _dbg__comm_readbuf_reset /* Next Comm telegram transaction */ - mov r0, #0 -_exit_dbg__commHasMsg: - ldmfd sp!, {pc} - -/* _copy_msg_from_commbuf - * Internal Comm buffer copy routine, handles segment reassembly. - * On entry: - * r0: number of bytes to copy - * r1: segment number - * On exit: - * r0: cummulative message length - * r1: segment number - * r2, r3: Destroyed - */ -_copy_msg_from_commbuf: - stmfd sp!, {r1,r4,r5,r6,lr} - movs r4, r0 - beq _exit_copy_msg_from_commbuf - - ldr r6, =debug_msgRxBufPtr /* Address of Pointers */ - ldr r5, [r6] /* Rx buffer Start Address */ - ldr r2, [r6, #RXAPPENDPTR_OFFSET] /* Append Pointer */ - - sub r3, r2, r5 /* r3: current length of message */ - add r3, r3, r4 /* new cummulative length of message */ - cmp r3, #MSGBUF_SIZE - movhi r4, #0 /* Buffer overflow! */ - strhi r5, [r6, #RXAPPENDPTR_OFFSET] /* Reset AppendPtr to beginning of Rx Buffer */ - bhi _exit_copy_msg_from_commbuf - - ldr r3, =debug_InCommBuf - add r3, r3, #NXT_GDBMSG_START - _dbg_memcpy r2, r3, r4, r0 /* r2 updated to point to next empty char slot in Rx buffer */ - sub r4, r2, r5 /* r4: cummulative length of message */ - - /* Update debug_msgRxBuf_AppendPtr */ - teq r1, #0 /* Check if this is last segment (segment 0) */ - streq r5, [r6, #RXAPPENDPTR_OFFSET] /* Reset AppendPtr to beginning of Rx Buffer if so */ - strne r2, [r6, #RXAPPENDPTR_OFFSET] /* Otherwise, update Append Pointer to receive next segment */ - -_exit_copy_msg_from_commbuf: - bl _dbg__comm_readbuf_reset /* Next Comm telegram transaction */ - mov r0, r4 /* Return cummulative message length in R0 */ - ldmfd sp!, {r1,r4,r5,r6,pc} /* Return segment number in R1 */ - - -/* _msgbuf_checksum - * Internal routine to calculate checksum character buffer. - * On entry: - * r0: pointer to character buffer to checksum (assume ASCIIZ terminated) - * On exit: - * r0: pointer to character buffer after ASCIIZ - * r1: checksum (8-bit binary) - * r2: message length - * r3: destroyed - */ -_msgbuf_checksum: - mov r1, #0 /* clear checksum */ - mov r2, #0 /* clear length */ -1: ldrb r3, [r0], #1 /* Iterate through buffer */ - add r1, r1, r3 /* cummulative sum of char */ - teq r3, #0 - addne r2, r2, #1 /* increment message length */ - bne 1b /* until ASCIIZ found */ - and r1, #BYTE0 /* Modulo 256 */ - mov pc, lr - -/* dbg__getDebugMsg - * Retrieve pending Debugger Message if available (Non-Blocking). - * On entry: - * No parameters (assume pointers were initialized previously using dbg__comm_init) - * On exit: - * r0: >0 = Valid GDB Message Length (incl '$', excluding '#' and checksum), - * 0 = no valid message (yet), -1 = error - * r1: GDB Message Buffer Pointer (incl '$', excluding '#' and checksum) - * r2, r3: Destroyed - * Note: If GDB Message were returned, it is ASCIIZ terminated, does not include '#' and checksum - */ - dbg_interwork dbg__getDebugMsg - stmfd sp!, {r4,r5,lr} - bl _dbg__commHasMsg /* r0: message length, r1: segment number */ - teq r0, #0 - beq exit_dbg__getDebugMsg /* no new message, exit with R0 = 0 */ - - ldr r4, =debug_segmentRxNum - ldr r2, [r4] /* Get current Segment Number */ - add r2, r2, #1 /* Expected Segment Number for comparison */ - teq r1, #0 - streq r1, [r4] /* Update current Segment Number with 0 since it is the last segment */ - beq _hasMsg2Copy - cmp r1, #MSG_NUMSEGMENTS /* Segment Number < MSG_NUMSEGMENTS? */ - bhs _invalid_segment - teq r1, r2 /* Valid Segment Number, check against Expected Segment Number */ - beq _hasMsg2Copy /* Segment Number matches Expected Segment Number, update buffers */ - -_invalid_segment: - bl _dbg__comm_readbuf_reset /* Invalid, Next Comm telegram transaction */ - mov r0, #0 /* Reset Segment Number */ - str r0, [r4] /* Update current Segment Number with 0 to prepare for new message */ - b exit_dbg__getMsgError /* Exit with error */ - -_hasMsg2Copy: - str r1, [r4] /* Update current Segment Number */ - bl _copy_msg_from_commbuf /* r0: cummulative message length, r1: segment number */ - teq r1, #0 - movne r0, #0 /* Incomplete message, ignore for now */ - bne exit_dbg__getDebugMsg /* Message not complete yet, exit */ - - /* Check for valid GDB message */ - mov r4, r0 /* keep message length in R4, assume to be within MSGBUF_SIZE */ - ldr r5, =debug_msgRxBufPtr - ldr r5, [r5] /* Rx buffer Start Address */ - -/* Need to account for Packet Acknowledgement */ -1: ldrb r0, [r5] - teq r0, #MSGBUF_CTRLC /* Look for Ctrl-C */ - moveq r0, r4 /* If found, set R0 to current message length */ - beq exit_dbg__getDebugMsg /* and return */ - teq r0, #MSGBUF_NAKCHAR /* Look for '-' */ - beq exit_dbg__getMsgError /* Error from Host, Retransmit previous message */ - teq r0, #MSGBUF_ACKCHAR /* Look for '+' */ - addeq r5, r5, #1 /* Adjust Buffer Start Pointer (excl '+') */ - subeq r4, r4, #1 /* Adjust Message Length */ - beq 1b /* Skip all Packet Acknowledgements */ - - /* Note: Here we assume that we won't get a single ACK '+' or NAK '-' character message. - * If we do, it'll be flagged as an error - */ - subs r2, r4, #MSGBUF_CHKSUMOFFSET /* Look for '#': Message Length - 3 = '#' offset */ - blt exit_dbg__getMsgError /* Message Length is too short, exit with error */ - ldrb r0, [r5, r2] - teq r0, #MSGBUF_CHKSUMCHAR - bne exit_dbg__getMsgError /* No checksum char '#', exit with error */ - - mov r1, #0 - strb r1, [r5, r2] /* Zero out '#' char for checksum calc later */ - -#ifdef CHECK_GDBSTARTCHAR - /* Checked in dbg__bkpt_waitCMD */ - ldrb r0, [r5] - teq r0, #MSGBUF_STARTCHAR /* Look for '$' */ - bne exit_dbg__getMsgError /* No start char '$', exit with error */ -#endif - - add r0, r5, #1 /* Checksum packet data (excl '$') */ - bl _msgbuf_checksum /* R2: length (excl '$'), R1: calculated checksum, R0: pointer to checksum in receive buffer */ - mov r3, r1 /* Keep calculated checksum in R3 (R1 destroyed by ascii2byte) */ - bl ascii2byte /* R0: received checksum, R1: address of next buffer location */ - teq r0, r3 /* Compare calculated checksum in R3 against received checksum in R0 */ - bne exit_dbg__getMsgError /* Checksums do not match, exit with error */ - - subeq r0, r4, #MSGBUF_CHKSUMOFFSET /* Update message length (incl '$') as return parameter */ - add r2, r2, #1 /* expected message length (from _msgbuf_checksum) */ - teq r0, r2 - beq exit_dbg__getDebugMsg /* Valid length, return */ - -exit_dbg__getMsgError: - /* We must first clear the existing message checksum */ - ldr r1, =debug_msgTxBufPtr /* R5: data structure base pointer */ - ldr r1, [r1] /* Tx buffer Start Address */ - -1: ldrb r0, [r1], #1 - teq r0, #MSGBUF_CHKSUMCHAR - bne 1b - - mov r0, #0 /* ASCIIZ */ - strb r0, [r1, #-1] /* Pointer R1 is now one past the MSGBUF_CHKSUMCHAR */ - - bl dbg__putDebugMsg /* Retransmit message */ - mov r0, #0 /* Flag no message received */ - -#if 0 - mov r0, #MSGBUF_MSGERROR -#endif - -exit_dbg__getDebugMsg: - mov r1, r5 /* Return GDB Message Buffer Pointer in R1 */ - ldmfd sp!, {r4,r5,pc} - - -/* _copy_msg_to_commbuf - * Internal Comm buffer copy routine, handles segment fragmentation. - * On entry: - * r0: number of bytes to copy - * r1: segment number - * On exit: - * r0: cummulative message length - * r1: segment number - * r2, r3: Destroyed - */ -_copy_msg_to_commbuf: - stmfd sp!, {r1,r4,r5,r6,lr} - ldr r6, =debug_msgTxBufPtr /* Address of Pointers */ - ldr r5, [r6, #TXAPPENDPTR_OFFSET] /* Retrieve Tx Append Pointer */ - - movs r4, r0 - beq _exit_copy_msg_to_commbuf - -#ifdef CHECK_TXLEN - add r0, r4, #NXT_GDBMSG_START /* offset = header size */ - cmp r0, #USB_BUFSIZE - bhi _exit_copy_msg_to_commbuf /* We let calling routine detect problem (segment number will increment) */ -#endif - - /* Fill in Comm Message Header */ - ldr r3, =debug_OutCommBuf - mov r2, #NXT_GDBMSG_TELEGRAMTYPE - strb r2, [r3], #1 /* Telegram type */ - strb r1, [r3], #1 /* Segment Number */ - strb r0, [r3], #1 /* Message Length */ - - mov r2, r5 /* Copy to R2 for updating */ - mov r1, r4 /* actual GDB message fragment length (exclude Comm header) */ - _dbg_memcpy r3, r2, r1, r0 /* This copies over the message fragment, r3, r2 updated */ - mov r5, r2 /* Updated Tx Append Pointer, keep in R5 for now */ - - add r0, r4, #NXT_GDBMSG_START /* Total Comm Buffer Size for Tx (NXT_GDBMSG_START offset = header size) */ - bl dbg__sendCommMsg /* Common interface routine to commnuncations drivers */ - cmp r0, #TRUE - ldrne r5, [r6, #TXAPPENDPTR_OFFSET] /* Tx failed, Retrieve Original Tx Append Pointer */ - streq r5, [r6, #TXAPPENDPTR_OFFSET] /* Tx succeeded, Update Tx Append Pointer to new position */ - -_exit_copy_msg_to_commbuf: - ldr r6, [r6] /* Retrieve Tx Buffer Start Address */ - sub r0, r5, r6 /* Return calculated cummulative message length (R0) */ - ldmfd sp!, {r1,r4,r5,r6,pc} /* Return segment number in R1 */ - -/* dbg__putDebugMsg - * Sends Debugger Message from calling routine after appending checksum (Blocking) . - * On entry: - * No parameters (assume pointers were initialized previously using dbg__comm_init) - * On exit: - * r0: status (0: success, -1: error) - * Note: GDB Message to be sent must be ASCIIZ terminated, does not include '#' and checksum - * Response packets start with '+' followed by '$' (2 bytes prefix) - */ - dbg_interwork dbg__putDebugMsg - stmfd sp!, {r4,r5,lr} - /* Perform Checksum Calculation */ - ldr r5, =debug_msgTxBufPtr /* R5: data structure base pointer */ - ldr r4, [r5] /* Tx buffer Start Address */ - str r4, [r5, #TXAPPENDPTR_OFFSET] /* Reset Tx buffer Append Pointer */ - add r0, r4, #2 /* skip '+' and '$' */ - bl _msgbuf_checksum /* R2: length (excl '+' and '$'), R1: calculated checksum, R0: pointer to checksum in tx buffer */ - -#ifdef CHECK_TXLEN - add r2, r2, #2 /* r2: returned length from _msgbuf_checksum, added with prefix length */ - sub r3, r0, r4 /* r3: calculated length from pointers (incl. prefix length) */ - teq r2, r3 - bne exit_dbg__putMsgError -#endif - - mov r3, #MSGBUF_CHKSUMCHAR - strb r3, [r0, #-1] /* Insert '#' */ - bl byte2ascii /* On return, R0 points to location after checksum bytes, R1 is original pointer to checksum */ - sub r4, r0, r4 /* R4 = Calculated total message length (incl '+' and '$', '#' and checksum bytes */ - cmp r4, #MSG_SEGMENTSIZE /* If total message length > MSG_SEGMENTSIZE */ - mov r1, #0 /* Initialize Segment Number = 0 (last segment) first */ - mov r0, #0 /* Initial cummulative message length */ - mov r5, #0 /* Previous cummulative message length */ - - /* We assume unsigned message lengths, so the arithmetic MUST NOT result in negative values */ -_cont_putMsg: - cmp r4, r0 - movls r0, #0 /* R0: Exit status (success) */ - bls exit_dbg__putDebugMsg /* If Total message length (r4) <= Cummulative message length (r0), we're done */ - add r2, r0, #MSG_SEGMENTSIZE /* R2: calculate new Max cummulative message length */ - cmp r4, r2 /* Check total message length (R4) against new Max cummulative message length (R2) */ - subls r0, r4, r0 /* if total message length (R4) <= new Max cummulative message length (R2), send remainder */ - movls r1, #0 /* Flag as last segment (Segment Number = 0) */ - movhi r0, #MSG_SEGMENTSIZE /* else send MSG_SEGMENTSIZE bytes */ - addhi r1, r1, #1 /* Increment Segment Number */ - cmp r1, #MSG_NUMSEGMENTS - bhs exit_dbg__putMsgError /* If Segment Number >= MSG_NUMSEGMENTS, flag error */ - bl _copy_msg_to_commbuf /* R0: cummulative message length, R1: segment number */ - teq r5, r0 /* Check if we managed to transmit the previous message */ - beq exit_dbg__putMsgError /* No, flag error */ - movne r5, r0 /* Update previous cummulative message length */ - b _cont_putMsg - -exit_dbg__putMsgError: - mov r0, #MSGBUF_MSGERROR -exit_dbg__putDebugMsg: - ldmfd sp!, {r4,r5,pc} - -/* dbg__sendAckOrNak - * Send Ack (for successful receipt of message) - * or Nak (for Retransmission due to received message Checksum error) (Blocking) . - * On entry: - * No parameters (assume pointers were initialized previously using dbg__comm_init) - * On exit: - * r0: status (0: success, -1: error) - * r1: destroyed - * Note: An Ack Or Nak is indicated by '+' or '-', which is prepended with the Comm header and sent (without checksum) - * Sending Ack is only done for Continue and Step commands, where GDB does not expect any replies. - */ - dbg_interwork dbg__sendAckOrNak - stmfd sp!, {lr} - ldr r1, =debug_msgTxBufPtr /* R2: data structure base pointer */ - ldr r0, [r1] /* Tx buffer Start Address */ - str r0, [r1, #TXAPPENDPTR_OFFSET] /* Reset Tx buffer Append Pointer */ - - mov r1, #0 /* Initialize Segment Number = 0 (last segment) */ - mov r0, #1 /* Retransmission message length = 1 */ - bl _copy_msg_to_commbuf /* R0: cummulative message length, R1: segment number */ - cmp r0, #1 /* Check if we managed to transmit the previous message */ - moveq r0, #0 /* R0: Exit status (success) */ - movne r0, #MSGBUF_MSGERROR /* R0: Exit status (error) */ - ldmfd sp!, {pc} - diff --git a/AT91SAM7S256/armdebug/Debugger/debug_hexutils.S b/AT91SAM7S256/armdebug/Debugger/debug_hexutils.S deleted file mode 100644 index 267406f..0000000 --- a/AT91SAM7S256/armdebug/Debugger/debug_hexutils.S +++ /dev/null @@ -1,459 +0,0 @@ -/** @file debug_hexutils.S - * @brief GDB hexadecimal conversion utility routines - * - */ - -/* Copyright (C) 2007-2011 the NxOS developers - * - * Module Developed by: TC Wan - * - * See AUTHORS for a full list of the developers. - * - * See COPYING for redistribution license - * - */ - - -#define __ASSEMBLY__ - -#include "debug_internals.h" - -.data -.align 4 - -hex2char_lut: - /* .ascii "0123456789ABCDEF" */ - /* Need to use lowercase hex chars to avoid confusion with GDB Error (E NN) response */ - .ascii "0123456789abcdef" - -/* Macros - */ - - -/* _hex2char_lut - * Internal routine to intialize the LUT address pointer - */ - .macro _hex2char_lut addrptr - ldr \addrptr, =hex2char_lut - .endm - -/* _hex2char_cont - * Internal routine that assumes that the LUT has been loaded. - * This macro accepts a byte sized hex value as a parameter register(7:0) and returns the - * ASCII equivalent in in the same register(7:0) - * The second parameter is the LUT address pointer register to use (assumed to be initialized) - * WARNING: Assumes that the value in register is sanity checked before invoking macro - */ - .macro _hex2char_cont reg, addrptr - ldrb \reg, [\addrptr, \reg] - .endm - -/* _hex2char - * This macro accepts a byte sized hex value as a parameter register(7:0) and returns the - * ASCII equivalent in in the same register(7:0) - * The second parameter is the LUT address pointer register to use (register content is destroyed) - * WARNING: Assumes that the value in register is sanity checked before invoking macro - */ - .macro _hex2char reg, addrptr - _hex2char_lut \addrptr - _hex2char_cont \reg, \addrptr - .endm - -/* _char2hex - * This macro accepts an ASCII char as a parameter register(7:0) and returns the - * equivalent byte sized hex value in in the same register(7:0) - * WARNING: Assumes that the char in register is a valid hex char before invoking macro - */ - .macro _char2hex reg - cmp \reg, #'A' /* If Alpha */ - bichs \reg, \reg, #ASCII_LOWER2UPPER_MASK /* Convert to Uppercase */ - subhs \reg, \reg, #7 /* Adjustment to allow for subtraction with 0x30 */ - sub \reg, \reg, #0x30 /* get final hex value */ - .endm - - -.code 32 -.text -.align 4 - - -/* Utility Routines - * GDB requires command parameters to be specified as Big Endian values. - * However, the read/write register command expect the register contents to be specified in target byte order. - * Hence we need both versions of multibyte conversion routines for word sized values. - */ - -/* hex2char - * This routine accepts a byte sized hex value in R0(7:0) and returns the - * ASCII equivalent in R0(7:0) - */ - .global hex2char - -hex2char: - stmfd sp!, {r1,lr} - and r0, #NIBBLE0 /* make sure that input is sane */ - _hex2char r0, r1 - ldmfd sp!, {r1,pc} - -/* char2hex - * This routine accepts an ASCII character in R0(7:0) and returns the - * equivalent byte sized hex value in R0(7:0). - * It accepts lowercase and uppercase ASCII Hex char inputs. - * Invalid inputs return -1 as the value -* On entry: - * R0: ASCII character - * On exit: - * R0: Hex value - */ - .global char2hex - -char2hex: - and r0, r0, #BYTE0 /* make sure that input is sane */ - cmp r0, #'0' - blo char2hex_error - cmp r0, #'9' - bls perform_char2hex - cmp r0, #'A' - blo char2hex_error - cmp r0, #'F' - bls perform_char2hex - cmp r0, #'a' - blo char2hex_error - cmp r0, #'f' - bhi char2hex_error - /* Validated Hex Char */ -perform_char2hex: - _char2hex r0 /* Return hex value in R0 */ - bx lr - -char2hex_error: - mov r0, #-1 /* Set Return value to Error value */ - bx lr - -/* byte2ascii_cont - * (Shared routine, does not perform sanity checks) - * On entry: - * R0: ASCII buffer pointer - * R1[7:0]: byte value - * On exit: - * R0: Address of next empty char slot in buffer - * R1: Destroyed - * - * This routine accepts an ASCII buffer pointer in R0 and a byte value in R1, - * and stores the ASCII equivalent byte value in the buffer pointed to by R0. - * Note: On return, R0 points to next empty char slot in buffer - */ -byte2ascii_cont: - stmfd sp!, {r2,r3,r4, lr} - lsl r2, r1, #24 /* Keep copy of input byte value R1[7:0], shifted to MSB R2[31:24] */ - mov r4, #2 /* Loop counter */ - _hex2char_lut r3 /* initialize LUT pointer */ -1: ror r2, r2, #28 /* Rotate MSNibble R2[31:28] into LSNibble position R2[3:0] */ - and r1, r2, #NIBBLE0 /* Mask out everything else, store Nibble in R1 */ - _hex2char_cont r1, r3 /* Convert nibble to ASCII char */ - strb r1, [r0], #1 - subs r4, r4, #1 /* decrement loop counter */ - bne 1b - ldmfd sp!, {r2,r3,r4, pc} - -/* byte2ascii - * On entry: - * R0: ASCII buffer pointer - * R1[7:0]: Byte value - * On exit: - * R0: Address of next empty char slot in buffer - * R1: Original Address of Buffer - * - * This routine accepts an ASCII buffer pointer in R0 and a byte value in R1, - * and stores the ASCII equivalent byte value in the buffer pointed to by R0. - * Note: On return, R0 points to the next empty char slot in buffer - */ - .global byte2ascii - -byte2ascii: - stmfd sp!, {r0, lr} /* Keep ASCII buffer pointer */ - and r1, #BYTE0 /* sanitize input */ - bl byte2ascii_cont - ldmfd sp!, {r1, pc} /* return original string pointer in R1 */ - -/* halfword2ascii_be - * Big Endian version of halfword2ascii conversion routine - * On entry: - * R0: ASCII buffer pointer - * R1[15:0]: Halfword value - * On exit: - * R0: Address of next empty char slot in buffer - * R1: Original Address of Buffer - * - * This routine accepts an ASCII buffer pointer in R0 and a halfword value in R1, - * and stores the ASCII equivalent halfword value in the buffer pointed to by R0. - * Note: On return, R0 points to the next empty char slot in buffer - */ - .global halfword2ascii_be -halfword2ascii_be: - stmfd sp!, {r0,r2,r3, lr} /* Keep ASCII buffer pointer */ - mov r3, #2 /* Loop Counter */ - mov r2, r1, lsl #16 /* copy of input halfword value R1[15:0], shifted to MSH R2[31:16] */ - b _conv_byte2ascii_be /* goto Byte conversion loop */ - -/* halfword2ascii_le - * Little Endian version of halfword2ascii conversion routine - * On entry: - * R0: ASCII buffer pointer - * R1[15:0]: Halfword value - * On exit: - * R0: Address of next empty char slot in buffer - * R1: Original Address of Buffer - * - * This routine accepts an ASCII buffer pointer in R0 and a halfword value in R1, - * and stores the ASCII equivalent halfword value in the buffer pointed to by R0. - * Note: On return, R0 points to the next empty char slot in buffer - */ - .global halfword2ascii_le -halfword2ascii_le: - stmfd sp!, {r0,r2,r3, lr} /* Keep ASCII buffer pointer */ - mov r3, #2 /* Loop Counter */ - b _conv_byte2ascii_le /* goto Byte conversion loop */ - - -/* word2ascii_be - * Big Endian version of word2ascii conversion routine - * On entry: - * R0: ASCII buffer pointer - * R1[31:0]: Word value - * On exit: - * R0: Address of next empty char slot in buffer - * R1: Original Address of Buffer - * - * This routine accepts an ASCII buffer pointer in R0 and a word value in R1, - * and stores the ASCII equivalent word value in the buffer pointed to by R0. - * Note: On return, R0 points to the next empty char slot in buffer - */ - .global word2ascii_be -word2ascii_be: - stmfd sp!, {r0,r2,r3, lr} /* Keep ASCII buffer pointer */ - mov r2, r1 /* copy of input word value R1[31:0] */ - mov r3, #4 /* Loop Counter */ - - /* Fall through to byte coversion loop */ - - -/* Big Endian Multibyte Convert: Rotate then convert */ -_conv_byte2ascii_be: - ror r2, r2, #24 /* Rotate MSB R2[31:24] into LSB position R2[7:0] */ - and r1, r2, #BYTE0 /* Copy byte value in R2[7:0] into R1 */ - bl byte2ascii_cont /* R0: next ASCII buffer location pointer, R1: destroyed */ - subs r3, r3, #1 - bne _conv_byte2ascii_be - ldmfd sp!, {r1,r2,r3, pc} - -/* word2ascii_le - * Little Endian version of word2ascii conversion routine - * On entry: - * R0: ASCII buffer pointer - * R1[31:0]: Word value - * On exit: - * R0: Address of next empty char slot in buffer - * R1: Original Address of Buffer - * - * This routine accepts an ASCII buffer pointer in R0 and a word value in R1, - * and stores the ASCII equivalent word value in the buffer pointed to by R0. - * Note: On return, R0 points to the next empty char slot in buffer - */ - .global word2ascii_le -word2ascii_le: - stmfd sp!, {r0,r2,r3, lr} /* Keep ASCII buffer pointer */ - mov r2, r1 /* copy of input word value R1[31:0] */ - mov r3, #4 /* Loop Counter */ - - /* Fall through to byte coversion loop */ - -/* Little Endian Multibyte Convert: Convert then rotate */ -_conv_byte2ascii_le: - and r1, r2, #BYTE0 /* Copy byte value in R2[7:0] into R1 */ - bl byte2ascii_cont /* R0: next ASCII buffer location pointer, R1: destroyed */ - ror r2, r2, #8 /* Rotate LSB+1 R2[15:8] into LSB position R2[7:0] */ - subs r3, r3, #1 - bne _conv_byte2ascii_le - ldmfd sp!, {r1,r2,r3, pc} - - -/* ascii2hex_varlen_be - * Big Endian version of ascii2hex_varlen conversion routine - * (There is no Little Endian Version) - * On entry: - * R0: ASCII buffer pointer - * On exit: - * R0: Hex value - * R1: Address of next char slot in buffer - * - * This routine accepts an ASCII buffer pointer in R0, - * and returns the hex value in R0 for up to 8 Hex characters. - * Note: On return, R1 points to the ASCII buffer location after the hex value chars. - */ - .global ascii2hex_varlen_be - -ascii2hex_varlen_be: - stmfd sp!, {r2,r3, lr} - mov r3, #CMD_REG_REGPARAMLEN /* Set max count to 8 (Max Register size) */ - mov r1, r0 /* Use R1 as ASCII buffer pointer */ - mov r2, #0 /* Initialize Cummulative Results */ -2: ldrb r0, [r1] /* Load ASCII char for Hex Value */ - bl char2hex /* on return, hex value in R0, -1 for error */ - cmp r0, #-1 - beq _exit_ascii2hex_varlen - orr r2, r0, r2, lsl #4 /* combined byte value */ - subs r3, r3, #1 /* Decrement Counter */ - add r1, r1, #1 /* Go to next char slot */ - bne 2b -_exit_ascii2hex_varlen: - mov r0, r2 /* Return results in R0 */ - ldmfd sp!, {r2,r3, pc} - - -/* ascii2byte - * On entry: - * R0: ASCII buffer pointer - * On exit: - * R0[7:0]: Byte value - * R1: Address of next char slot in buffer - * - * This routine accepts an ASCII buffer pointer in R0, - * and returns the byte value in R0[7:0]. - * Note: On return, R1 points to the ASCII buffer location after the current 2 chars. - * WARNING: This routine assumes that the input buffer was sanitized and contains valid Hex chars, - * otherwise it will return invalid results. - */ - .global ascii2byte - -ascii2byte: - stmfd sp!, {r2, lr} - mov r1, r0 /* Use R1 as ASCII buffer pointer */ - ldrb r0, [r1], #1 /* Load ASCII char for MSN */ - bl char2hex /* on return, hex value in R0, -1 for error (ignored) */ - mov r2, r0, lsl #4 /* Intermediate Results register */ - ldrb r0, [r1], #1 /* Load ASCII char for LSN */ - bl char2hex /* on return, hex value in R0, -1 for error (ignored) */ - orr r0, r2, r0 /* combined byte value */ - ldmfd sp!, {r2, pc} - -/* ascii2halfword_be - * Big Endian version of ascii2halfword conversion routine - * On entry: - * R0: ASCII buffer pointer - * On exit: - * R0[15:0]: Halfword value - * R1: Address of next char slot in buffer - * - * This routine accepts an ASCII buffer pointer in R0, - * and returns the Halfword value in R0[15:0]. - * Note: On return, R1 points to the ASCII buffer location after the current 4 chars. - * WARNING: This routine assumes that the input buffer was sanitized and contains valid Hex chars, - * otherwise it will return invalid results. - */ - .global ascii2halfword_be - -ascii2halfword_be: - stmfd sp!, {r2,r3, lr} - mov r3, #2 /* Loop counter */ - b _conv_ascii2byte_be - -/* ascii2halfword_le - * Little Endian version of ascii2halfword conversion routine - * On entry: - * R0: ASCII buffer pointer - * On exit: - * R0[15:0]: Halfword value - * R1: Address of next char slot in buffer - * - * This routine accepts an ASCII buffer pointer in R0, - * and returns the Halfword value in R0[15:0]. - * Note: On return, R1 points to the ASCII buffer location after the current 4 chars. - * WARNING: This routine assumes that the input buffer was sanitized and contains valid Hex chars, - * otherwise it will return invalid results. - */ - .global ascii2halfword_le - -ascii2halfword_le: - stmfd sp!, {r2,r3, lr} - mov r3, #2 /* Loop counter */ - b _conv_ascii2byte_le - - -/* ascii2word_be - * Big Endian version of ascii2word conversion routine - * On entry: - * R0: ASCII buffer pointer - * On exit: - * R0[31:0]: Word value - * R1: Address of next char slot in buffer - * - * This routine accepts an ASCII buffer pointer in R0, - * and returns the word value in R0[31:0]. - * Note: On return, R1 points to the ASCII buffer location after the current 8 chars. - * WARNING: This routine assumes that the input buffer was sanitized and contains valid Hex chars, - * otherwise it will return invalid results. - */ - .global ascii2word_be - -ascii2word_be: - stmfd sp!, {r2,r3, lr} - mov r3, #4 /* Loop counter */ - - /* Fall through to byte coversion loop */ - -_conv_ascii2byte_be: - teq r0, #0 - beq _exit_conv_ascii2byte_be /* exit if NULL pointer in R0 */ - mov r2, #0 /* Initialize Cummulative value */ -2: bl ascii2byte - orr r2, r0, r2, lsl #8 /* Merge current byte with cummulative value */ - mov r0, r1 /* Copy next char pointer to R0 for next byte */ - subs r3, r3, #1 - bne 2b - mov r0, r2 /* Copy it to R0 as return value */ - -_exit_conv_ascii2byte_be: - ldmfd sp!, {r2,r3, pc} /* return hex value in R0 */ - -/* ascii2word_le - * Litle Endian version of ascii2word conversion routine - * On entry: - * R0: ASCII buffer pointer - * On exit: - * R0[31:0]: Word value - * R1: Address of next char slot in buffer - * - * This routine accepts an ASCII buffer pointer in R0, - * and returns the word value in R0[31:0]. - * Note: On return, R1 points to the ASCII buffer location after the current 8 chars. - * WARNING: This routine assumes that the input buffer was sanitized and contains valid Hex chars, - * otherwise it will return invalid results. - */ - .global ascii2word_le - -ascii2word_le: - stmfd sp!, {r2,r3, lr} - mov r3, #4 /* Loop counter */ - - /* Fall through to byte coversion loop */ - -_conv_ascii2byte_le: - teq r0, #0 - beq _exit_conv_ascii2byte_le /* exit if NULL pointer in R0 */ - push {r3} /* Need to keep couter for final value adjustment */ - mov r2, #0 /* Initialize Cummulative value */ -2: bl ascii2byte - orr r2, r0, r2, ror #8 /* Merge current byte with cummulative value */ - mov r0, r1 /* Copy next char pointer to R0 for next byte */ - subs r3, r3, #1 - bne 2b - /* Cummulative value done, need to rotate it into the correct position for return value */ - pop {r3} /* retrieve counter */ - rsb r3, r3, #5 /* 5 - count */ - lsl r3, r3, #3 /* [(5-count) x 8] bits to rotate */ - mov r0, r2, ror r3 /* Copy it to R0 as return value */ - -_exit_conv_ascii2byte_le: - ldmfd sp!, {r2,r3, pc} /* return hex value in R0 */ - diff --git a/AT91SAM7S256/armdebug/Debugger/debug_internals.h b/AT91SAM7S256/armdebug/Debugger/debug_internals.h deleted file mode 100644 index bdab463..0000000 --- a/AT91SAM7S256/armdebug/Debugger/debug_internals.h +++ /dev/null @@ -1,395 +0,0 @@ -/** @file debug_internals.h - * @brief Shared C/ASM header file for debugger internal constants - * - */ - -/* Copyright (C) 2007-2011 the NxOS developers - * - * Module Developed by: TC Wan - * - * See AUTHORS for a full list of the developers. - * - * See COPYING for redistribution license - * - */ - -#ifndef __DEBUG_INTERNALS_H__ -#define __DEBUG_INTERNALS_H__ - -#include "_c_arm_macros.h" - - -/** @addtogroup debugger */ -/*@{*/ - - -/* Declarations go here. */ -/** @name Debug Message Constants. - * - * Debug Message Values - */ -/*@{*/ - -/* - * USB Buffer Sizes: Ctrl Intr Iso Bulk - * Full Speed Device 64 64 1023 64 - * High Speed Device 64 1024 1024 512 - */ - -#define USB_BUFSIZE 64 /* USB Buffer size for AT91SAM7S */ - -#define NXT_MSG_TELEGRAMTYPE_OFFSET 0 /* NXT Direct Command/Response Header */ -#define NXT_MSG_SEGNUM_OFFSET 1 -#define NXT_MSG_TELEGRAMSIZE_OFFSET 2 - -#define NXT_GDBMSG_TELEGRAMTYPE 0x8d /* GDB debugger specific, no Response required */ - -#define NXT_GDBMSG_START 3 /* Offset into USB Telegram buffer */ - -#define MSG_NUMSEGMENTS 3 /* For packet transfers */ -#define MSG_SEGMENTSIZE (USB_BUFSIZE - NXT_GDBMSG_START) /* 61 bytes per segment */ -#define MSGBUF_SIZE (MSG_SEGMENTSIZE*MSG_NUMSEGMENTS) /* Debug Message Buffer Size, 61 x 3 = 183 chars = ~80 bytes of actual data */ -#define MSGBUF_CHKSUMOFFSET 3 /* to be subtracted from message length */ -#define MSGBUF_IN_OVERHEADLEN 5 /* For calculating max message data length (exclude ASCIIZ char) */ -#define MSGBUF_OUT_OVERHEADLEN 5 /* For calculating max message data length (exclude ASCIIZ char) */ - -#define MSGBUF_CTRLC 0x03 /* For Out of Band Signaling: not implemented yet */ -#define MSGBUF_STARTCHAR '$' -#define MSGBUF_ACKCHAR '+' -#define MSGBUF_NAKCHAR '-' -#define MSGBUF_ERRCHAR 'E' -#define MSGBUF_SIGCHAR 'S' -#define MSGBUF_SETCHAR '=' -#define MSGBUF_CHKSUMCHAR '#' -#define MSGBUF_SEPCHAR ',' -#define MSGBUF_ARGCHAR ':' -#define MSGBUF_MSGERROR -1 -/*@}*/ - -/** @name Debug Command Lookup Constants. - * - * Debug Command Lookup - */ -/*@{*/ - -#define CMDINDEX_OUTOFRANGE -1 -/*@}*/ - -/** @name Debug Register Command Constants. - * - * Debug Register Command - */ -/*@{*/ -#define CMD_REG_NUMREGS 17 -#define CMD_REG_GETONE_MINPARAMLEN 1 -#define CMD_REG_GETONE_MAXPARAMLEN 2 -#define CMD_REG_GETALL_PARAMLEN 0 -#define CMD_REG_REGPARAMLEN 8 /* 32-bit ASCII Hex Value */ -#define CMD_REG_SETONE_MINPARAMLEN (2 + CMD_REG_REGPARAMLEN) -#define CMD_REG_SETONE_MAXPARAMLEN (3 + CMD_REG_REGPARAMLEN) -#define CMD_REG_SETALL_PARAMLEN (CMD_REG_NUMREGS*CMD_REG_REGPARAMLEN) -#define CMD_KILL_PARAMLEN 0 -#define CMD_DETACH_PARAMLEN 0 - -/*@}*/ - -/** @name Debug Memory Command Constants. - * - * Debug Memory Command - * FIXME: These limits are not enforced by the GDB client, it truncates addresses and lengths to remove leading '0's - * The PARAMLEN constants would probably be removed - */ -/*@{*/ -#define CMD_NUMITEMS_PARAMLEN 4 /* 16-bit ASCII Hex Value */ -#define CMD_MEM_READ_PARAMLEN (CMD_REG_REGPARAMLEN + CMD_NUMITEMS_PARAMLEN + 1) /* Address length is equivalent to reg param len */ -#define CMD_MEM_WRITE_MINPARAMLEN (CMD_REG_REGPARAMLEN + CMD_NUMITEMS_PARAMLEN + 2) /* Address length is equivalent to reg param len */ -#define CMD_MEM_SEPCHAR_OFFSET CMD_REG_REGPARAMLEN /* Address length is equivalent to reg param len */ -#define CMD_MEM_MAXOUTBUFLEN (MSGBUF_SIZE - MSGBUF_OUT_OVERHEADLEN) -#define CMD_MEM_MAXREADBYTES (CMD_MEM_MAXOUTBUFLEN/2) -#define CMD_MEM_MAXINBUFLEN (MSGBUF_SIZE - MSGBUF_IN_OVERHEADLEN) -#define CMD_MEM_MAXWRITEBYTES ((CMD_MEM_MAXINBUFLEN - CMD_MEM_WRITE_MINPARAMLEN)/2) -/*@}*/ - -/** @name Debug Continue and Step Command Constants. - * - * Debug Continue and Step Command - */ -/*@{*/ -#define CMD_CONTINUE_MINPARAMLEN 0 -#define CMD_STEP_MINPARAMLEN 0 -/*@}*/ - -/** @name Debug Query Command Constants. - * - * Debug Query Command - */ -/*@{*/ -#define CMD_QUERY_MINPARAMLEN 0 -#define CMD_QUERY_CURRTID_PARAMLEN 1 -#define CMD_QUERY_FTINFO_PARAMLEN 11 -#define CMD_QUERY_STINFO_PARAMLEN 11 -#define CMD_QUERY_CURRTID_CHAR 'C' -#define CMD_QUERY_FTINFO_CHAR 'f' -#define CMD_QUERY_STINFO_CHAR 's' -/*@}*/ - - -/** @name Debug Breakpoint Command Constants. - * - * Debug Breakpoint Command - */ -/*@{*/ - -#define CMD_BKPT_INSERT_MINPARAMLEN 5 -#define CMD_BKPT_REMOVE_MINPARAMLEN 5 - - -#define CMD_BKPT_TYPE_BREAK_MEMORY 0 -#define CMD_BKPT_TYPE_BREAK_HARD 1 /* Not supported */ -#define CMD_BKPT_TYPE_WATCH_WRITE 2 /* Not supported (yet) */ -#define CMD_BKPT_TYPE_WATCH_READ 3 /* Not supported (yet) */ -#define CMD_BKPT_TYPE_WATCH_ACCESS 4 /* Not supported (yet) */ - -#define CMD_BKPT_KIND_THUMB 2 -#define CMD_BKPT_KIND_THUMB2 3 /* Not supported */ -#define CMD_BKPT_KIND_ARM 4 - -#define CMD_BKPT_NOTFOUND -1 - -/*@}*/ - -/** @name Debug Stack Constants. - * - * Debug Stack Manipulation Values - */ -/*@{*/ -#define DBGSTACK_NEXTINSTR_INDEX 0 /* Next Instruction Address is at index 0 from bottom of Debug Stack */ -#define DBGSTACK_USERCPSR_INDEX 1 /* User CPSR (SPSR_UNDEF) is at index 1 from bottom of Debug Stack */ -#define DBGSTACK_USERREG_INDEX 2 /* R0 starts at index 2 from bottom of Debug Stack */ -#define DBGSTACK_USERSP_INDEX (DBGSTACK_USERREG_INDEX + REG_SP) /* SP is R13 */ -#define DBGSTACK_USERLR_INDEX (DBGSTACK_USERREG_INDEX + REG_LR) /* LR is R14 */ -#define DBGSTACK_USERPC_INDEX (DBGSTACK_USERREG_INDEX + REG_PC) /* PC is R15 */ -/*@}*/ - - -/** @name Exception Handler Vector Definitions. - * - * Exception Handler Vectors. - */ -/*@{*/ - -#define RESET_VECTOR 0x00000000 -#define UNDEF_VECTOR 0x00000004 -#define SVC_VECTOR 0x00000008 -#define PABRT_VECTOR 0x0000000C -#define DABRT_VECTOR 0x00000010 -#define RESERVED_VECTOR 0x00000014 -#define IRQ_VECTOR 0x00000018 -#define FIQ_VECTOR 0x0000001C - - -/*@}*/ - - -/** @name Bitmask Definitions. - * - * Various Bitmasks used for data manipulation. - */ -/*@{*/ -#define BKPT_STATE_THUMB_FLAG 0x01 /* Flag Thumb Breakpoint */ -#define ASCII_LOWER2UPPER_MASK 0x20 /* ASCII Conversion bitmask */ -#define NIBBLE0 0x0000000F /* Nibble 0 word(3:0) */ -#define NIBBLE1 0x000000F0 /* Nibble 1 word(7:4) */ -#define NIBBLE2 0x00000F00 /* Nibble 2 word(11:8) */ -#define NIBBLE3 0x0000F000 /* Nibble 3 word(15:12) */ -#define NIBBLE4 0x000F0000 /* Nibble 4 word(19:16) */ -#define NIBBLE5 0x00F00000 /* Nibble 5 word(23:20) */ -#define NIBBLE6 0x0F000000 /* Nibble 6 word(27:24) */ -#define NIBBLE7 0xF0000000 /* Nibble 7 word(31:28) */ -#define BYTE0 0x000000FF /* Byte 0 word(7:0) */ -#define BYTE1 0x0000FF00 /* Byte 1 word(15:8) */ -#define BYTE2 0x00FF0000 /* Byte 2 word(23:16) */ -#define BYTE3 0xFF000000 /* Byte 3 word(31:24) */ -#define HLFWRD0 0x0000FFFF /* Halfword 0 word(15:0) */ -#define HLFWRD1 0xFFFF0000 /* Halfword 0 word(31:16) */ -/*@}*/ - -/** @name CPSR Bit Definitions. - * - * Various Bit definitions for accessing the CPSR register. - */ -/*@{*/ -#define CPSR_THUMB 0x00000020 -#define CPSR_FIQ 0x00000040 -#define CPSR_IRQ 0x00000080 -#define CPSR_MODE 0x0000001F -#define CPSR_COND 0xF0000000 - -/* ARM Exception Modes */ -#define MODE_USR 0x10 /* User mode */ -#define MODE_FIQ 0x11 /* FIQ mode */ -#define MODE_IRQ 0x12 /* IRQ mode */ -#define MODE_SVC 0x13 /* Supervisor mode */ -#define MODE_ABT 0x17 /* Abort mode */ -#define MODE_UND 0x1B /* Undefined mode */ -#define MODE_SYS 0x1F /* System mode */ - -/* Condition Flags - * b31 b30 b29 b28 - * N Z C V - */ -#define CPSR_NFLAG 0x80000000 -#define CPSR_ZFLAG 0x40000000 -#define CPSR_CFLAG 0x20000000 -#define CPSR_VFLAG 0x10000000 - - -/* - * ARM Opcode Masks (for Parser) - */ -#define ARM_DATA_INSTR_MASK 0x0FBF0000 -#define ARM_DATA_INSTR_MSRMRS 0x010F0000 -#define ARM_DATA_INSTR_NORMAL 0x01E00000 -#define ARM_DATA_INSTR_IMMREG 0x02000000 - -#define ARM_LDR_INSTR_REGIMM 0x02000000 -#define ARM_LDR_INSTR_PREPOST 0x01000000 -#define ARM_LDR_INSTR_UPDOWN 0x00800000 - -#define ARM_LDM_INSTR_PREPOST 0x01000000 -#define ARM_LDM_INSTR_UPDOWN 0x00800000 - -#define ARM_BLX_INSTR_MASK 0xFE000000 -#define ARM_BLX_INSTR_BLX 0xFA000000 -#define ARM_BLX_INSTR_HBIT 0x01000000 - -#define ARM_SWI_INSTR_MASK 0x0F000000 -#define ARM_SWI_INSTR_VAL 0x0F000000 - - -/* - * Thumb Opcode Masks (for Parser) - */ -#define THUMB_BLX_INSTR_REG_RNMASK 0x0078 - -#define THUMB_BCOND_SWI_INSTR_CONDMASK 0x0F00 -#define THUMB_BCOND_SWI_COND_UNUSED 0x0E00 -#define THUMB_BCOND_SWI_INSTR_SWI 0x0F00 - -#define THUMB_BLX_INSTR_IMM_HBIT 0x0800 -#define THUMB_BLX_INSTR_IMM_MASK 0xF000 -#define THUMB_BLX_INSTR_IMM_BL 0xF000 -#define THUMB_BLX_INSTR_IMM_BLX 0xE000 - -/*@}*/ - -/** Debugger State Enums - * - * Debugger State. - * The enums must be consecutive, starting from 0 - */ -ENUM_BEGIN -ENUM_VALASSIGN(DBG_RESET, 0) /**< Initial State. */ -ENUM_VAL(DBG_INIT) /**< Debugger Initialized. */ -ENUM_VAL(DBG_CONFIGURED) /**< Debugger has been configured by GDB Server */ -ENUM_END(dbg_state_t) - -/** Breakpoint Type Enums - * - * Breakpoint Type. - * The enums must be consecutive, starting from 0 - */ -ENUM_BEGIN -ENUM_VALASSIGN(DBG_AUTO_BKPT,0) /**< RESERVED: Auto Breakpoint (Instruction resume after breakpoint). */ -ENUM_VAL(DBG_MANUAL_BKPT_ARM) /**< Manual ARM Breakpoint. */ -ENUM_VAL(DBG_NORMAL_BKPT_ARM) /**< Normal ARM Breakpoint (Single Step, Normal). */ -ENUM_VAL(DBG_MANUAL_BKPT_THUMB) /**< Manual Thumb Breakpoint. */ -ENUM_VAL(DBG_NORMAL_BKPT_THUMB) /**< Normal Thumb Breakpoint (Single Step, Normal). */ -ENUM_VAL(DBG_ABORT_PREFETCH) /**< Prefetch Abort. */ -ENUM_VAL(DBG_ABORT_DATA) /**< Data Abort. */ -ENUM_END(bkpt_type_t) - -/** Debugger Message Signal Enums - * - * Debugger Signal Message Enums. - * The enums must be consecutive, starting from 0 - */ -/* Need to sync with the Signal enums in ecos-common-hal_stub.c */ -ENUM_BEGIN -ENUM_VALASSIGN(MSG_SIG_DEFAULT, 0) /**< Default Signal Response. */ -ENUM_VAL(MSG_SIG_HUP) /**< Hangup Signal Response. */ -ENUM_VAL(MSG_SIG_INT) /**< Interrupt Signal Response. */ -ENUM_VAL(MSG_SIG_QUIT) /**< Quit Signal Response. */ -ENUM_VAL(MSG_SIG_ILL) /**< Illegal Instruction Signal Response (not reset when caught). */ -ENUM_VAL(MSG_SIG_TRAP) /**< Trace Trap Signal Response (not reset when caught). */ -ENUM_VAL(MSG_SIG_ABRT) /**< Abort Signal Response (replace SIGIOT). */ -ENUM_VAL(MSG_SIG_EMT) /**< EMT Instruciton Signal Response. */ -ENUM_VAL(MSG_SIG_FPE) /**< Floating Point Exception Signal Response. */ -ENUM_VAL(MSG_SIG_KILL) /**< Kill Signal Response (cannot be caught or ignored). */ -ENUM_VAL(MSG_SIG_BUS) /**< Bus Error Signal Response. */ -ENUM_VAL(MSG_SIG_SEGV) /**< Segmentation Violation Signal Response. */ -ENUM_VAL(MSG_SIG_SYS) /**< Bad Argument to System Call Signal Response. */ -ENUM_VAL(MSG_SIG_PIPE) /**< Write on a Pipe with No Reader Signal Response. */ -ENUM_VAL(MSG_SIG_ALRM) /**< Alarm Clock Signal Response. */ -ENUM_VAL(MSG_SIG_TERM) /**< Software Termination Signal from Kill Signal Response. */ -ENUM_END(dbg_msg_signo) - -/** Debugger Message Error Enums - * - * Debugger Error Message Enums. - * The enums must be consecutive, starting from 1 - */ -/* FIXME: Need to validate against the ecos-generic-stub.c Error enums */ -ENUM_BEGIN -ENUM_VALASSIGN(MSG_ERRIMPL, 0) /**< Stub (not implemented) Error. */ -ENUM_VAL(MSG_ERRINLENGTH) /**< Message Write Length Error. */ -ENUM_VAL(MSG_ERROUTLENGTH) /**< Message Read Length Error. */ -ENUM_VAL(MSG_ERRFORMAT) /**< Message Format Error. */ -ENUM_VAL(MSG_UNKNOWNCMD) /**< Unrecognized Command Error. */ -ENUM_VAL(MSG_UNKNOWNPARAM) /**< Unrecognized Parameter Error. */ -ENUM_VAL(MSG_UNKNOWNBRKPT) /**< Unrecognized Breakpoint Error. */ -ENUM_END(dbg_msg_errno) - -/** Register Enums - * - * Register Enums. - * Refer to eCOS's arm_stub.h for enum values - */ -ENUM_BEGIN -ENUM_VALASSIGN(REG_R0, 0) /**< User Reg R0 */ -ENUM_VAL(REG_R1) /**< User Reg R1 */ -ENUM_VAL(REG_R2) /**< User Reg R2 */ -ENUM_VAL(REG_R3) /**< User Reg R3 */ -ENUM_VAL(REG_R4) /**< User Reg R4 */ -ENUM_VAL(REG_R5) /**< User Reg R5 */ -ENUM_VAL(REG_R6) /**< User Reg R6 */ -ENUM_VAL(REG_R7) /**< User Reg R7 */ -ENUM_VAL(REG_R8) /**< User Reg R8 */ -ENUM_VAL(REG_R9) /**< User Reg R9 */ -ENUM_VAL(REG_R10) /**< User Reg R10 */ -ENUM_VAL(REG_R11) /**< User Reg R11 */ -ENUM_VAL(REG_R12) /**< User Reg R12 */ -ENUM_VAL(REG_SP) /**< Previous Mode SP (R13) */ -ENUM_VAL(REG_LR) /**< Previous Mode LR (R14) */ -ENUM_VAL(REG_PC) /**< Program Counter (R15) */ -ENUM_VALASSIGN(REG_FPSCR, 24) /**< Previous Mode FPSCR (dummy) */ -ENUM_VAL(REG_CPSR) /**< Previous Mode CPSR */ - -ENUM_END(register_enum_t) - -/** Abort Type Enums - * - * Abort Type used for interfacing with LCD Display routine. - * The enums must be consecutive, starting from 0 - * Note: The values must align with those defined in NxOS's _abort.h - */ -ENUM_BEGIN -ENUM_VALASSIGN(DISP_ABORT_PREFETCH,0) /**< Prefetch Abort. */ -ENUM_VAL(DISP_ABORT_DATA) /**< Data Abort. */ -ENUM_VAL(DISP_ABORT_SPURIOUS) /**< Spurious IRQ. */ -ENUM_VAL(DISP_ABORT_ILLEGAL) /**< Illegal Instruction. */ -ENUM_END(abort_type_t) - -/*@}*/ - -#endif /* __DEBUG_INTERNALS_H__ */ diff --git a/AT91SAM7S256/armdebug/Debugger/debug_macros.h b/AT91SAM7S256/armdebug/Debugger/debug_macros.h deleted file mode 100644 index d852f38..0000000 --- a/AT91SAM7S256/armdebug/Debugger/debug_macros.h +++ /dev/null @@ -1,463 +0,0 @@ -/** @file debug_macros.h - * @brief internal macros used by debug_stub routines - * - */ - -/* Copyright (C) 2007-2010 the NxOS developers - * - * Module Developed by: TC Wan - * - * See AUTHORS for a full list of the developers. - * - * See COPYING for redistribution license - * - */ - -#ifndef __DEBUG_MACROS_H__ -#define __DEBUG_MACROS_H__ - - - - -/*@{*/ - -/** _dbg_jumpTableHandler - * Call Jump Table Routine based on Index - * On entry: - * @param jumptableaddr is the address (constant) of the Jump Table - * @param jumpreg is the register used to perform the indirect jump - * @param indexreg contains jump table index value - */ - .macro _dbg_jumpTableHandler jumptableaddr, jumpreg, indexreg - - ldr \jumpreg, =\jumptableaddr - ldr \jumpreg, [\jumpreg, \indexreg, lsl #2] - mov lr, pc - bx \jumpreg /* Call Command Handler Routine */ - .endm - - -/** _dbg_thumbDecodeEntry - * Load Thumb Instruction Decoder Entry - * On entry: - * @param instrreg is the register to load the instruction into - * @param instrmask is the register to load the instruction mask into - * @param codehandler is the register to load the code handling routine into - * @param indexreg contains decode table index value - * NOTE: instrreg, instrmask, codehandler must be in increasing register number order - */ - .macro _dbg_thumbDecodeEntry instrreg, instrmask, codehandler, indexreg - - ldr \instrmask, =debug_thumbDecodeTable /* Temporary register */ - add \instrmask, \instrmask, \indexreg, lsl #3 - ldm \instrmask, {\instrreg, \codehandler} /* LSHW: IID, MSHW: IBM */ - mov \instrmask, \instrreg, lsr #16 - mov \instrreg, \instrreg, lsl #16 - mov \instrreg, \instrreg, lsr #16 /* Keep HLFWORD0 containing instruction */ - .endm - -/** _dbg_armDecodeEntry - * Load ARM Instruction Decoder Entry - * On entry: - * @param instrreg is the register to load the instruction into - * @param instrmask is the register to load the instruction mask into - * @param codehandler is the register to load the code handling routine into - * @param indexreg contains decode table index value - * NOTE: instrreg, instrmask, codehandler must be in increasing register number order - */ - .macro _dbg_armDecodeEntry instrreg, instrmask, codehandler, indexreg - - ldr \instrmask, =debug_armDecodeTable /* Temporary register */ - add \instrmask, \instrmask, \indexreg, lsl #3 - add \instrmask, \instrmask, \indexreg, lsl #2 /* 12 byte entries */ - ldm \instrmask, {\instrreg, \instrmask, \codehandler} - .endm - -/** _asciiz - * Terminate string given string buffer pointer in \strptr - * scratchreg is used as a scratch register (destroyed) - * - */ - .macro _asciiz strptr, scratchreg - mov \scratchreg, #0 /* ASCIIZ character */ - strb \scratchreg, [\strptr] /* Terminate ASCII string */ - .endm - - -/** _dbg_stpcpy - * _dbg_stpcpy macro - * On entry: - * deststrptr: Destination string - * sourcestrptr: Source string - * scratchreg: scratch register for copying - * On exit: - * deststrptr: Pointer to ASCIIZ character in destination string - * sourcestrptr: Pointer to next character slot in source string (after ASCIIZ) - * scratchreg: destroyed - */ - .macro _dbg_stpcpy deststrptr, sourcestrptr, scratchreg -1: ldrb \scratchreg, [\sourcestrptr], #1 - strb \scratchreg, [\deststrptr], #1 - teq \scratchreg, #0 - bne 1b - sub \deststrptr, \deststrptr, #1 /* Adjust Destination string pointer to point at ASCIIZ character */ - .endm - -/** _dbg_memcpy - * _dbg_stpcpy macro - * On entry: - * deststrptr: Destination string - * sourcestrptr: Source string - * sizereg: Number of bytes to copy - * scratchreg: scratch register for copying - * On exit: - * deststrptr: Pointer to next character slot in destination string - * sourcestrptr: Pointer to next character slot in source string - * sizereg, scratchreg: destroyed - */ - .macro _dbg_memcpy deststrptr, sourcestrptr, sizereg, scratchreg -1: ldrb \scratchreg, [\sourcestrptr], #1 - strb \scratchreg, [\deststrptr], #1 - subs \sizereg, \sizereg, #1 - bne 1b - .endm - -/** _dbg_CopyMsg2OutputBuf - * Copies source message to output buffer - * On entry: - * R2: source message buffer (ASCIIZ terminated) - * On exit: - * R0: Pointer to Output Buffer ASCIIZ location - * R2-R3: destroyed - */ - .macro _dbg_CopyMsg2OutputBuf - ldr r0, =debug_OutMsgBuf - _dbg_stpcpy r0, r2, r3 - .endm - -/** _dbg_CopyMsg2OutputBuf_withParam - * Internal Routine called to output message with parameters - * Return Message with byte-sized parameter - * On entry: - * R1: byte-sized param - * R2: source message buffer (ASCIIZ terminated) - * On exit: - * R0: Pointer to Output Buffer ASCIIZ location - * R1-R3: destroyed - */ - .macro _dbg_CopyMsg2OutputBuf_withParam - _dbg_CopyMsg2OutputBuf /* R1 unchanged */ - bl byte2ascii /* R0 points to buffer position after byte value */ - _asciiz r0, r1 - .endm - -/** _dbg_outputAckOnlyFlag - * Return Flag ('+') for Continue or Step - * On exit: - * R0: Pointer to Output Buffer ASCIIZ location - * R2-R3: destroyed - */ - .macro _dbg_outputAckOnlyFlag - ldr r2, =debug_AckOnlyFlag /* ASCIIZ terminated */ - _dbg_CopyMsg2OutputBuf - .endm - - -/** _dbg_outputRetransmitFlag - * Return Flag ('-') for Checksum Error (retransmission needed) - * On exit: - * R0: Pointer to Output Buffer ASCIIZ location - * R2-R3: destroyed - */ - .macro _dbg_outputRetransmitFlag - ldr r2, =debug_RetransmitFlag /* ASCIIZ terminated */ - _dbg_CopyMsg2OutputBuf - .endm - -/** _dbg_outputMsgValidResponse - * Return Message with valid response ('+$') - * On exit: - * R0: Pointer to Output Buffer next character slot location - * R2-R3: destroyed - */ - .macro _dbg_outputMsgValidResponse - ldr r2, =debug_ValidResponsePrefix - _dbg_CopyMsg2OutputBuf - .endm - -/** _dbg_outputMsgStatusOk - * Return Message with Ok ('+$OK') status - * On exit: - * R0: Pointer to Output Buffer ASCIIZ location - * R2-R3: destroyed - */ - .macro _dbg_outputMsgStatusOk - ldr r2, =debug_OkResponse /* ASCIIZ terminated */ - _dbg_CopyMsg2OutputBuf - .endm - -/** _dbg_outputMsgCurrTID - * Return Message with Default Thread ID ('+$QC0') - * On exit: - * R0: Pointer to Output Buffer ASCIIZ location - * R2-R3: destroyed - */ - .macro _dbg_outputMsgCurrTID - ldr r2, =debug_ThreadIDResponse /* ASCIIZ terminated */ - _dbg_CopyMsg2OutputBuf - .endm - -/** _dbg_outputMsgFirstThreadInfo - * Return Message with Default Current Thread ID ('+$m0') - * On exit: - * R0: Pointer to Output Buffer ASCIIZ location - * R2-R3: destroyed - */ - .macro _dbg_outputMsgFirstThreadInfo - ldr r2, =debug_FirstThreadInfoResponse /* ASCIIZ terminated */ - _dbg_CopyMsg2OutputBuf - .endm - -/** _dbg_outputMsgSubsequentThreadInfo - * Return Message with Default Current Thread ID ('+$m0') - * On exit: - * R0: Pointer to Output Buffer ASCIIZ location - * R2-R3: destroyed - */ - .macro _dbg_outputMsgSubsequentThreadInfo - ldr r2, =debug_SubsequentThreadInfoResponse /* ASCIIZ terminated */ - _dbg_CopyMsg2OutputBuf - .endm - -/** _dbg_outputMsgStatusErr - * Return Message with Error ('+$ENN') status - * On entry: - * R1: error code - * On exit: - * R0: Pointer to Output Buffer ASCIIZ location - * R1-R3: destroyed - */ - .macro _dbg_outputMsgStatusErr - ldr r2, =debug_ErrorResponsePrefix - _dbg_CopyMsg2OutputBuf_withParam - .endm - -/** _dbg_outputMsgStatusErrCode - * Return Message with Error ('+$ENN') status - * On exit: - * R0: Pointer to Output Buffer ASCIIZ location - * R1-R3: destroyed - */ - .macro _dbg_outputMsgStatusErrCode errcode - mov r1, #\errcode - _dbg_outputMsgStatusErr - .endm - -/** _dbg_outputMsgStatusSig - * Return Message with Signal ('+$SNN') status - * On entry: - * R1: signal code - * On exit: - * R0: Pointer to Output Buffer ASCIIZ location - * R1-R3: destroyed - */ - .macro _dbg_outputMsgStatusSig - ldr r2, =debug_SignalResponsePrefix - _dbg_CopyMsg2OutputBuf_withParam - .endm - -/** _dbg_outputMsgStatusSigCode - * Return Message with Signal ('+$SNN') status - * On exit: - * R0: Pointer to Output Buffer ASCIIZ location - * R1-R3: destroyed - */ - .macro _dbg_outputMsgStatusSigCode statuscode - mov r1, #\statuscode - _dbg_outputMsgStatusSig - .endm - - -/** _regenum2index - * Convert register enum to debugger stack index - * - * On entry: - * @param indexenum: enum representing Register to access - * @param indexreg: register to be used to store the debugger stack index value (0-max index) - * On exit: - * @param indexreg contains debugger stack index value (0-max index) - */ - .macro _regenum2index indexenum, indexreg - add \indexreg, \indexenum, #DBGSTACK_USERREG_INDEX /* Convert register index to Debug Stack index */ - .endm - -/** _getdbgregisterfromindex - * Retrieve register contents from debugger stack given index - * - * On entry: - * @param indexreg contains debugger stack index value (0-max index) - * On exit: - * @param indexreg: Breakpoint index (preserved) - * @param contentsreg: Register Contents for given index - */ - .macro _getdbgregisterfromindex indexreg, contentsreg - ldr \contentsreg, =__debugger_stack_bottom__ - ldr \contentsreg, [\contentsreg, \indexreg, lsl #2] - .endm - -/** _setdbgregisterfromindex - * Store register contents to debugger stack given index - * - * On entry: - * @param indexreg contains debugger stack index value (0-max index) - * @param contentsreg: Register Contents for given index - * @param addressreg: Scratch register for address pointer - * On exit: - * @param indexreg: Breakpoint index (preserved) - * @param contentsreg: Register Contents for given index - */ - .macro _setdbgregisterfromindex indexreg, contentsreg, addressreg - ldr \addressreg, =__debugger_stack_bottom__ - str \contentsreg, [\addressreg, \indexreg, lsl #2] - .endm - -/** _getdbgregister - * Retrieve register contents from debugger stack given immediate index value - * - * On entry: - * @param indexval contains debugger stack index value (0-max index) - * On exit: - * @param contentsreg: Register Contents for given index - */ - .macro _getdbgregister indexval, contentsreg - ldr \contentsreg, =__debugger_stack_bottom__ - ldr \contentsreg, [\contentsreg, #(\indexval << 2)] - .endm - -/** _setdbgregister - * Store register contents to debugger stack given immediate index value - * - * On entry: - * @param indexval contains debugger stack index value (0-max index) - * @param contentsreg: Register Contents for given index - * @param addressreg: Scratch register for address pointer - * On exit: - * @param contentsreg: Register Contents for given index - * @param addressreg: Destroyed - */ - .macro _setdbgregister indexval, contentsreg, addressreg - ldr \addressreg, =__debugger_stack_bottom__ - str \contentsreg, [\addressreg, #(\indexval << 2)] - .endm - -/** _index2bkptindex_addr - * Convert Breakpoint index to breakpoing entry address - * - * On entry: - * @param indexreg contains breakpoint index value - * On exit: - * @param indexreg: Breakpoint index (preserved) - * @param addrreg: Breakpoint Entry Address - */ - .macro _index2bkptindex_addr indexreg, addrreg - ldr \addrreg, =__breakpoints_start__ - add \addrreg, \addrreg, \indexreg, lsl #3 /* Calculate Breakpoint Entry Address */ - .endm - -/** _dbg_getstate - * Get Debugger State - * On exit: - * @param reg: Debugger State enum - */ - .macro _dbg_getstate reg - ldr \reg, =debug_state - ldrb \reg, [\reg] - .endm - -/** _dbg_setstate - * Set Debugger State to given value - * On exit: - * r0, r1: destroyed - */ - .macro _dbg_setstate state - mov r0, #\state - ldr r1, =debug_state - strb r0, [r1] - .endm - -/** _dbg_getmode - * Get Debugger Mode - * On exit: - * @param reg: Debugger Mode (Boolean) - */ - .macro _dbg_getmode reg - ldr \reg, =debug_mode - ldrb \reg, [\reg] - .endm - -/** _dbg_setmode - * Set Debugger Mode to given value - * On exit: - * r0, r1: destroyed - */ - .macro _dbg_setmode mode - mov r0, #\mode - ldr r1, =debug_mode - strb r0, [r1] - .endm - -/** _dbg_get_bkpt_type - * Get Breakpoint Type - * On exit: - * @param reg: Breakpoint Type - */ - .macro _dbg_get_bkpt_type reg - ldr \reg, =debug_bkpt_type - ldrb \reg, [\reg] - .endm - -/** _dbg_set_bkpt_type - * Set Breakpoint Type using value in reg - * On exit: - * @param reg: destroyed - * r1: destroyed - */ - .macro _dbg_set_bkpt_type reg - ldr r1, =debug_bkpt_type - strb \reg, [r1] - .endm - -/** _dbg_set_bkpt_type_val - * Set Breakpoint Type to given value - * On exit: - * r0, r1: destroyed - */ - .macro _dbg_set_bkpt_type_val bkpt_type - mov r0, #\bkpt_type - ldr r1, =debug_bkpt_type - strb r0, [r1] - .endm - -/** _dbg_getcurrbkpt_index - * Get current breakpoint index - * On exit: - * @param reg: Breakpoint index - */ - .macro _dbg_getcurrbkpt_index reg - ldr \reg, =debug_curr_breakpoint - ldrb \reg, [\reg] - .endm - -/** _dbg_setcurrbkpt_index - * Set current breakpoint index - * On exit: - * r1: destroyed - */ - .macro _dbg_setcurrbkpt_index reg - ldr r1, =debug_curr_breakpoint - strb \reg, [r1] - .endm - - /*@}*/ - -#endif /* __DEBUG_MACROS_H__ */ diff --git a/AT91SAM7S256/armdebug/Debugger/debug_opcodes.S b/AT91SAM7S256/armdebug/Debugger/debug_opcodes.S deleted file mode 100644 index c264338..0000000 --- a/AT91SAM7S256/armdebug/Debugger/debug_opcodes.S +++ /dev/null @@ -1,1031 +0,0 @@ -/** @file debug_opcodes.S - * @brief ARM Debugger Opcode Parsing Routines - * - */ - -/* Copyright (C) 2007-2011 the NxOS developers - * - * Module Developed by: TC Wan - * - * See AUTHORS for a full list of the developers. - * - * See COPYING for redistribution license - * - */ - -#define __ASSEMBLY__ -#include "debug_stub.h" -#include "debug_internals.h" -#include "debug_macros.h" - -.data -.align 4 -/* Rm Shifted Shift Type Jump Table - * On entry: - * R0: Register Rm - * R1: Shift/Rotate Amount - * On exit: - * R0: RmShifted result - * - */ -debug_regShiftJumpTable: - .word _reg_lsl /* 00 */ - .word _reg_lsr /* 01 */ - .word _reg_asr /* 02 */ - .word _reg_ror /* 03 */ - .word _reg_rrx /* 04 */ - -/* Data Processing Instruction Jump Table - * On entry: - * R0: Register Rn (Operand 1) value - * R1: Operand 2 value - * R2: Default Next Instruction Address - * R5[3:0]: CPSR condition codes - * On exit: - * R0: Calculated result - * R1, R2, R3: Destroyed - * - */ -debug_dataInstrJumpTable: - .word _opcode_and /* 00 */ - .word _opcode_eor /* 01 */ - .word _opcode_sub /* 02 */ - .word _opcode_rsb /* 03 */ - .word _opcode_add /* 04 */ - .word _opcode_adc /* 05 */ - .word _opcode_sbc /* 06 */ - .word _opcode_rsc /* 07 */ - .word _opcode_tst /* 08 */ - .word _opcode_teq /* 09 */ - .word _opcode_cmp /* 0A */ - .word _opcode_cmn /* 0B */ - .word _opcode_orr /* 0C */ - .word _opcode_mov /* 0D */ - .word _opcode_bic /* 0E */ - .word _opcode_mvn /* 0F */ - - -/* - * To determine the next instruction to execute, we need to check current (breakpointed) instruction - * and determine whether it will be executed or not. This necessitates a mini instruction decoder - * that can check the type of instruction, as well as if it'll affect the PC. - * The instruction decoder used here is table based. Each entry in the table consists of: - * Instruction Identifier (IID), Instruction Bitmask (IBM), Instruction Handler Address (IHA) - * Null entries are placed at the end of the table. - * - * This allows for a flexible approach to handling instructions that we're interested in, at the expense - * of memory usage. - * - * For ARM, the IID & IBM are both 4 bytes, whereas the Thumb IID & IBM are 2 bytes. - * The IHA is always 4 bytes. - */ - -/* ARM Instruction Decode Table - * .word IID, IBM, IHA (12 bytes) - */ - -/* WARNING: The sequence of matching instructions is important! - * Always check from more specific to more general IBMs - * for instructions sharing common opcode prefix bits. - */ -debug_armDecodeTable: - .word 0x012fff10, 0x0ffffff0, _arm_bx_blx_handler /* [Prefix:00] BX or BLX. Note v4t does not have BLX instr */ - .word 0x0000f000, 0x0c00f000, _arm_data_instr_handler /* [Prefix:00] Data Processing instr with Rd = R15 */ -/* .word 0x06000010, 0x0e000010, _arm_undef_handler */ /* [Prefix:01] Undefined instr: shouldn't occur, as it would've been trapped already. See _dbg_following_instruction_addr */ - .word 0x0410f000, 0x0410f000, _arm_ldr_pc_handler /* [Prefix:01] LDR with Rd = PC */ - .word 0x08108000, 0x0e108000, _arm_ldm_pc_handler /* [Prefix:10] LDM {pc} */ - .word 0x0a000000, 0x0e000000, _arm_b_bl_blx_handler /* [Prefix:10] B, BL or BLX. Note v4t does not have BLX instr */ - .word 0x0c000000, 0x0c000000, _arm_coproc_swi_handler /* [Prefix:11] Coprocessor instr or SWI */ - .word 0x0,0x0,0x0 /* Null Entry */ - -/* Thumb Instruction Decode Table - * .hword IID, IBM - * .word IHA (8 bytes) - */ - -/* WARNING: The sequence of matching instructions is important! - * Always check from more specific to more general IBMs - * for instructions sharing common opcode prefix bits. - */ -debug_thumbDecodeTable: - .hword 0x4700, 0xff07 - .word _thumb_bx_blx_handler /* [Prefix:01] BX or BLX. Note: Link (L:b7) is not checked in the mask */ - .hword 0xbd00, 0xff00 - .word _thumb_poppc_handler /* [Prefix:10] PUSH/POP, specifically POP {Rlist,PC} */ - .hword 0xd000, 0xf000 - .word _thumb_bcond_swi_handler /* [Prefix:11] B or SWI */ - .hword 0xe000, 0xf800 - .word _thumb_b_handler /* [Prefix:11] B */ - .hword 0xf000, 0xf000 - .word _thumb_long_bl_blx_handler /* [Prefix:11] Long BL or BLX (4 bytes) Note: b11 (H) indicates 1st or 2nd instr */ - .hword 0x0,0x0 - .word 0x0 /* Null Entry */ - -/* ARM Condition Code Mapping Table - * Converts Instruction encoding to SPSR Flags. - * b31 b30 b29 b28 - * N Z C V - * Indexed according to Instruction Encoding order (pg 30, Table 6, ATMEL ARM7TDMI Data Sheet) - * Condition Code stored in MSN(set), LSN(clr) order - * Note1: 0x00 = AL. NV is deprecated, treat as AL - * Note2: 0xFF indicates that the condition checks needs to be handled separately (complex checks) - * - * EQ: Z set - * NE: Z clr - * HS/CS: C set - * LO/CC: C clr - * MI: N set - * PL: N clr - * VS: V set - * VC: V clr - */ - - -debug_armCondCodeTable: - /* EQ, NE, HS/CS, LO/CC, MI, PL, VS, VC, HI, LS, GE, LT, GT, LE, AL, NV */ - .byte 0x40, 0x04, 0x20, 0x02, 0x80, 0x08, 0x10, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00 - -/* ARM Complex Condition Code Mapping Table - * Converts Instruction encoding to SPSR Flags. - * b31 b30 b29 b28 - * N Z C V - * Indexed according to Instruction Encoding order (pg 30, Table 6, ATMEL ARM7TDMI Data Sheet) - * for HI, LS, GE, LT, GT and LE instructions only - * Condition Code stored in the following order: - * b7 b6 b5 b4 b3 b2 b1 b0 - * AND CHKZ CHKC CHKNV - Z set C set N==V (bit set = 1) - * OR - - - - Z clr C clr N!=V (bit clr = 0) - * - * HI: C set AND Z clr - * LS: C clr OR Z set - * GE: N == V - * LT: N != V - * GT: Z clr AND (N == V) - * LE: Z set OR (N != V) - */ - -#define COMPLEX_CONDCODE_START 0x08 -#define COMPLEX_CONDCODE_NEQV_MASK 0x01 -#define COMPLEX_CONDCODE_CSET_MASK 0x02 -#define COMPLEX_CONDCODE_ZSET_MASK 0x04 -#define COMPLEX_CONDCODE_CHKNV_MASK 0x10 -#define COMPLEX_CONDCODE_CHKC_MASK 0x20 -#define COMPLEX_CONDCODE_CHKZ_MASK 0x40 -#define COMPLEX_CONDCODE_ANDOR_MASK 0x80 - -#define COMPLEX_CONDCODE_NFLAG 0x08 -#define COMPLEX_CONDCODE_ZFLAG 0x04 -#define COMPLEX_CONDCODE_CFLAG 0x02 -#define COMPLEX_CONDCODE_VFLAG 0x01 - - -debug_armComplexCCTable: - /* HI, LS, GE, LT, GT, LE */ - .byte 0xE2, 0x64, 0x11, 0x10, 0xD1, 0x54 - -.code 32 -.text -.align 4 - -/* dbg_following_instruction_addr - * Determine the address of the following instruction to execute. - * On entry: - * R0: Address of the instruction to be (re)executed - * On exit: - * R0: Destroyed - * R1: Following Instruction Address (31 bits, b0 = THUMB flag) - * R2-R7: Destroyed - * - * Here we make use of the Debugger Stack which contains the address of the aborted instruction that will be reexecuted - * when we resume the program. - * - * If it is a Manual Breakpoint inserted into the code, then we will need to update the aborted instruction - * address to skip the current aborted instruction and resume execution at the next instruction address, - * and the next instruction address to be returned to the calling routine is the following instruction - * address instead. - * - * We need to check the aborted instruction type, to see if it is a branch instruction, before we can determine - * the next instruction address (for inserting a Breakpoint). - */ - .global dbg_following_instruction_addr -dbg_following_instruction_addr: - stmfd sp!, {lr} -/* We assume that any BKPT instructions in the code will be Manual Breakpoints, - * i.e., the Debugger does not leave stray Single Step / Auto / Normal breakpoints in memory - */ - mov r6, r0 /* Keep instruction address in R6 */ - _getdbgregister DBGSTACK_USERCPSR_INDEX, r1 /* Retrieve User CPSR into R1 */ - and r0, r1, #CPSR_THUMB /* store Thumb Mode status in R0 */ - mov r5, r1, lsr #28 /* store CPSR condition flags in R5[3:0] */ - -_dbg_get_aborted_instr: -1: teq r0, #0 /* Check if it is ARM or Thumb instruction */ - ldrneh r4, [r6] /* Load Thumb instruction opcode using Addr in R6 into R4 */ - ldrne r2, =(BKPT16_INSTR | BKPT16_MANUAL_BKPT) /* check for Thumb Manual Breakpoint Instruction */ - ldreq r4, [r6] /* Load ARM instruction opcode using Addr in R6 into R4 */ - ldreq r2, =(BKPT32_INSTR | BKPT32_MANUAL_BKPT) /* check for ARM Manual Breakpoint Instruction */ - teq r4, r2 /* Is instruction opcode (R4) == Manual Breakpoint opcode (R2)? */ - bne 2f /* Not Manual breakpoint */ - teq r0, #0 /* Check if it is ARM or Thumb Manual Breakpoint */ - addne r6, r6, #2 /* Is Manual Breakpoint, Skip to next Thumb instruction */ - addeq r6, r6, #4 /* Is Manual Breakpoint, Skip to next ARM instruction */ - b 1b /* To protect against a sequence of Manual Breakpoint Instructions */ - -/* Here, R4 contains the instruction opcode which will be (re)executed when program resumes. - * We need to dissect it to see if it is a branch instruction. - * For ARM instructions, we also need to evaluate the current (breakpointed) instruction to see if it'll execute. - * If not, then the following instruction is at the address following the address of the opcode in R4 (Default Following Instruction Address in R6). - */ -2: - teq r0, #0 /* Check if current instruction is ARM or Thumb instruction */ - beq _following_instr_addr_for_arm -_following_instr_addr_for_thumb: - add r6, r6, #2 /* Store default following Thumb instruction address to R6 */ -#if 0 - /* Flag Thumb instruction only within the instruction handler */ - orr r6, r6, #BKPT_STATE_THUMB_FLAG /* Set b0 to indicate Thumb instruction */ -#endif - /* R4: Candidate Instruction Opcode - * R5[3:0]: CPSR condition codes - * R6: Default Following Instruction Address (PC+2) - */ - bl _eval_thumb_instruction /* following address is either ARM or Thumb */ - /* We must set this the Thumb bit only within the instruction handler since BX would switch modes */ - b _exit_dbg_following_instruction_addr - -_following_instr_addr_for_arm: - add r6, r6, #4 /* Store default following ARM instruction address to R6 */ - /* R4: Candidate Instruction Opcode - * R5[3:0]: CPSR condition codes - * R6: Default Following Instruction Address (PC+4) - */ - bl _eval_arm_instruction - -_exit_dbg_following_instruction_addr: - mov r1, r0 /* Return Actual Following Instruction Address in R1 (B0 set to indicate Thumb mode) */ - ldmfd sp!, {pc} - - -/* _eval_arm_instruction - * Evaluate ARM instruction to determine following instruction address - * On entry: - * R4: Opcode of instruction to be executed - * R5[3:0]: CPSR condition codes - * R6: Default Following Instruction Address (PC+4) - * On exit: - * R0: following instruction address (B0 set to indicate Thumb mode) - * R1-R7: destroyed - */ -_eval_arm_instruction: - stmfd sp!, {lr} - bl _dbg_check_arm_condcode /* Returns R0: will_execute (boolean) */ - teq r0, #FALSE - moveq r0, r6 /* If False (don't execute), so use Default Following Instruction Address */ - beq _exit_eval_arm_instruction /* and Return to caller */ - -_will_execute_arm_instr: - mov r0, #0 /* initialize ARM Decode Entry Table index register */ -1: - _dbg_armDecodeEntry r1, r2, r3, r0 /* instrreg (R1), instrmask (R2), codehandler (R3), indexreg (R0) */ - teq r1, #0 /* Check for Null Entry (End of Table marker) */ - moveq r0, r6 /* End of Table, no match found, so use Default Following Instruction Address */ - beq _exit_eval_arm_instruction - and r7, r4, r2 /* Use R7 to check masked instruction opcode (from R4) to see if it matches template (in R1) */ - teq r7, r1 - addne r0, r0, #1 /* No match, so keep looking */ - bne 1b - -_call_arm_code_handler: - mov lr, pc - bx r3 /* Call Code Handler with R4: Instruction Opcode, R5[3:0]: CPSR, R6: Default Following Instruction Address */ -_exit_eval_arm_instruction: - /* Returned Following Address Instruction in R0 (B0 set to indicate Thumb mode) */ - ldmfd sp!, {pc} - -/* _eval_thumb_instruction - * Evaluate Thumb instruction to determine following instruction address - * On entry: - * R4: Opcode of instruction to be executed - * R5[3:0]: CPSR condition codes - * R6: Default Following Instruction Address (PC+2) - * On exit: - * R0: following instruction address (B0 set to indicate Thumb mode) - * R1-R7: destroyed - */ -_eval_thumb_instruction: - stmfd sp!, {lr} - /* Only B instructions are conditionally executed, deal with it in that Code Handler */ - mov r0, #0 /* initialize Thumb Decode Entry Table index register */ -1: - _dbg_thumbDecodeEntry r1, r2, r3, r0 /* instrreg (R1), instrmask (R2), codehandler (R3), indexreg (R0) */ - teq r1, #0 /* Check for Null Entry (End of Table marker) */ - moveq r0, r6 /* End of Table, no match found, so use Default Following Instruction Address */ - orreq r0, r0, #BKPT_STATE_THUMB_FLAG /* Set R0[0] to flag Thumb mode */ - beq _exit_eval_thumb_instruction - - and r7, r4, r2 /* Use R5 to check masked instruction opcode (from R4) to see if it matches template (in R1) */ - teq r7, r1 - addne r0, r0, #1 /* No match, so keep looking */ - bne 1b - -_call_thumb_code_handler: - mov lr, pc - bx r3 /* Call Code Handler with R4: Instruction Opcode, R5[3:0]: CPSR, R6: Default Following Instruction Address */ -_exit_eval_thumb_instruction: - /* Returned Following Address Instruction in R0 */ - ldmfd sp!, {pc} - - -/**************************************************************************** - * - * Instruction Decode Routines - * - ****************************************************************************/ - -/* _dbg_check_arm_condcode - * Check ARM conditional execution code - * On entry: - * R4: Opcode of instruction to be executed - * R5[3:0]: CPSR condition codes - * On exit: - * R0: will_execute (boolean) - * R1-R3: Destroyed - */ - -_dbg_check_arm_condcode: - mov r0, #TRUE /* Default will_execute value */ - mov r3, r4, lsr #28 /* convert opcode's condition code to index (0-F) */ - ldr r2, =debug_armCondCodeTable - ldrb r1, [r2, r3] /* Get condition code mask */ -/* - * The following check is unnecessary as it is covered by the _dbg_cond_simple_checks checking algorithm - teq r1, #0 - beq _dbg_check_arm_condcode_exit -*/ - teq r1, #0xFF - bne _dbg_cond_simple_checks - - -/* - * Complex Checks: - * We assume that CHKNV and CHKC are mutually exclusive. - * In addition, it is possible for CHKNV, CHKC and CHKZ to - * be cleared, in which case it'll return True (default) - * - * - * will_execute = TRUE [default condition] - * If (CHKNV) set - * // Only N/V, and Z flags are involved - * NEQV_Flag = (N == V) - * will_execute = (NEQV_Flag == NEQV_Mask) - * - * If (CHKC) set - * // Only C and Z flags are involved - * will_execute = (C_Flag == CSet_Mask) - * - * If (CHKZ) set - * z_match = (Z_Flag == ZSet_Mask) - * If (AND bit set) - * will_execute = will_execute && z_match - * else - * will_execute = will_execute || z_match - * - */ -_dbg_cond_complex_checks: - sub r3, r3, #COMPLEX_CONDCODE_START /* Convert complex condition code in R3 to new index (0-3) */ - ldr r2, =debug_armComplexCCTable - ldrb r1, [r2, r3] /* Get complex condition code bitmap in R1 */ - -_cond_check_nv: - tst r1, #COMPLEX_CONDCODE_CHKNV_MASK - beq _cond_check_c /* CHECKNV not set, so skip */ - ands r2, r5, #(COMPLEX_CONDCODE_NFLAG | COMPLEX_CONDCODE_VFLAG) /* Is (N == V == 0)? */ - teqne r2, #(COMPLEX_CONDCODE_NFLAG | COMPLEX_CONDCODE_VFLAG) /* No, Is (N == V == 1)? */ - - moveq r2, #COMPLEX_CONDCODE_NEQV_MASK /* EQ: Either (N == V == 0) or (N == V == 1), set R2: COMPLEX_CONDCODE_NEQV_MASK */ - movne r2, #0 /* NE: N != V, clear R2 */ - and r3, r1, #COMPLEX_CONDCODE_NEQV_MASK /* R3: Extract NEQV Mask Value */ - teq r2, r3 /* Does N/V Condition match NEQV Mask value? */ - movne r0, #FALSE /* No, so will_execute = FALSE (for now) */ - b _cond_check_z - -#if 0 - bne _cond_nnev /* No, so (N != V) */ - - /* EQ: Either (N == V == 0) or (N == V == 1) */ -_cond_neqv: - tst r1, #COMPLEX_CONDCODE_NEQV_MASK /* Is (N == V) mask set? */ - moveq r0, #FALSE /* No, so will_execute = FALSE (for now) */ - b _cond_check_z - - /* Else, N != V */ -_cond_nnev: - tst r1, #COMPLEX_CONDCODE_NEQV_MASK /* Is (N == V) mask set? */ - movne r0, #FALSE /* Yes, so will_execute = FALSE (for now) */ - b _cond_check_z -#endif - -_cond_check_c: - tst r1, #COMPLEX_CONDCODE_CHKC_MASK - beq _cond_check_z /* CHECKC not set, so skip */ - - /* Use R2 to store C Flag, R3 to store CSet Mask */ - and r2, r5, #COMPLEX_CONDCODE_CFLAG /* r2 = C flag */ - and r3, r1, #COMPLEX_CONDCODE_CSET_MASK /* r3 = CSet mask */ - teq r2, r3 /* Does C flag == CSet mask */ - movne r0, #FALSE /* No, so C flag failed match */ - -_cond_check_z: - tst r1, #COMPLEX_CONDCODE_CHKZ_MASK - beq _dbg_check_arm_condcode_exit /* No additional checks needed, exit */ - - /* Use R2 to store Z Flag, R3 to store ZSet Mask */ - and r2, r5, #COMPLEX_CONDCODE_ZFLAG /* r2 = Z flag */ - and r3, r1, #COMPLEX_CONDCODE_ZSET_MASK /* r3 = ZSet mask */ - teq r2, r3 /* Does Z flag == ZSet mask */ - moveq r3, #TRUE /* Zero, so z flag matched */ - movne r3, #FALSE /* Non-zero, so z flag failed match */ - -_cond_andor: - tst r1, #COMPLEX_CONDCODE_ANDOR_MASK /* Is ANDOR mask set? */ - andne r0, r0, r3 /* Yes, so AND with will_execute */ - orreq r0, r0, r3 /* No, so OR with will_execute */ - b _dbg_check_arm_condcode_exit /* Return will_execute (R0) */ - -/* - * Simple Checks: - * We take advantage of the fact that only 1 bit would be set - * in the bitmask, by generating the corresponding actual - * CondSet[7:4], CondClr[3:0] value for comparison. - * - * will_execute = TRUE [default condition, equivalent to 0x00 (AL) ] - * Generate CondSetClr[7:0] from CPSR[3:0] - * will_execute = ((CondSetClr & BitMask) == BitMask) - * - */ -_dbg_cond_simple_checks: - eor r2, r5, #NIBBLE0 /* R2: CondClr[3:0] = Invert CPSR[3:0] */ - orr r2, r2, r5, lsl #4 /* R2: CondSet[7:4] | CondClr[3:0] */ - and r2, r2, r1 /* R2: CondSetClr[7:0] & Bitmask */ - teq r2, r1 /* ((cond_code & SetBitMask) == SetBitMask)? */ - movne r0, #FALSE /* Not equal, check failed */ - -_dbg_check_arm_condcode_exit: - bx lr /* Return to caller */ - -/* _arm_rmshifted_val - * Calculate value of Shifted Rm (operand) - * On entry: - * R0[11:0]: Shifted Rm operand - * On exit: - * R0: value of Shifted Rm - * R1, R2, R3: destroyed - */ -_arm_rmshifted_val: - stmfd sp!, {lr} - ldr r3, =(NIBBLE2|BYTE0) - and r3, r0, r3 /* 12 bit Shifted Register operand, copied to R3 */ - and r2, r3, #NIBBLE0 /* Register Rn Enum in R2 */ - _regenum2index r2, r2 /* Convert Enum into Index in R2 */ - _getdbgregisterfromindex r2, r0 /* Retrieve Register Rn contents from Index (R2) into R0 */ - - tst r3, #0x10 /* B4: Immediate (0) or Register (1) shift count */ - /* check bitshift op */ - and r3, r3, #0x60 /* shift type */ - mov r3, r3, lsr #5 /* convert into shift type jumptable index */ - bne _arm_get_reg_shift /* Flags set previously via TST r3 (B4) */ -_arm_calc_const_shift: - movs r1, r3, lsr #7 /* Immediate shift count, 5 bit unsigned value in R1 */ - bne _arm_calc_shifted_rm_val /* Non-zero shift count, process normally */ - /* Must check for RRX == ROR #0 */ - teq r3, #0x3 /* ROR == 0x3 */ - addeq r3, r3, #1 - b _arm_calc_shifted_rm_val - -_arm_get_reg_shift: - mov r2, r3, lsr #8 /* Register-based shift count, 4 bit register enum in R2 */ - _regenum2index r2, r2 /* Convert Enum into Index in R2 */ - _getdbgregisterfromindex r2, r1 /* Retrieve Register value (shift count) from Index (R2) into R1 */ - -_arm_calc_shifted_rm_val: - _dbg_jumpTableHandler debug_regShiftJumpTable, r2, r3 /* Calculate RmShifted value from R0: Rn Register val, R1: Shift/Rotate val */ - ldmfd sp!, {pc} - -/* Rm Shifted Shift Type Jump Table Routines - * On entry: - * R0: Register Rm - * R1: Shift/Rotate Amount - * On exit: - * R0: RmShifted result - * R1: destroyed - * - */ -_reg_lsl: - lsl r0, r0, r1 - bx lr - -_reg_lsr: - lsr r0, r0, r1 - bx lr - -_reg_asr: - asr r0, r0, r1 - bx lr - -_reg_ror: - ror r0, r0, r1 - bx lr - -_reg_rrx: - _getdbgregister DBGSTACK_USERCPSR_INDEX, r1 /* Retrieve CPSR contents into R1 */ - ands r1, r1, #CPSR_CFLAG /* Keep C Flag */ - movne r1, #0x80000000 /* Set B31 if C Flag set */ - lsr r0, r0, #1 /* Rm >> 1 */ - orr r0, r0, r1 /* Put C flag into B31 */ - bx lr - - -/* _arm_data_instr_handler - * ARM Data Processing Instruction with Rd == R15 - * On entry: - * R4: Opcode of instruction to be executed - * R5[3:0]: CPSR condition codes - * R6: Default Following Instruction Address (PC+4) - * On exit: - * R0: following instruction address - * R1-R7: Destroyed - */ -_arm_data_instr_handler: - stmfd sp!, {lr} - ldr r1, =ARM_DATA_INSTR_MASK - and r3, r4, r1 /* Keep base instruction Opcode in R3 */ - ldr r1, =ARM_DATA_INSTR_MSRMRS - teq r3, r1 /* Check for MSR / MRS instruction */ - -_arm_is_msr_mrs_instr: - moveq r0, r6 /* Copy default next instruciton address to R0 */ - beq _exit_arm_data_instr_handler /* Return default next instruction address */ - - /* Not MSR / MRS, so process normally */ -_arm_check_operand2_type: - tst r4, #ARM_DATA_INSTR_IMMREG /* Check for Immediate (1) or Register (0) Operand 2 */ - beq _arm_op2_is_reg - -_arm_op2_is_imm: - and r1, r4, #BYTE0 /* 8 bit unsigned constant in R1 */ - and r2, r4, #NIBBLE2 /* (rotate count / 2) in R2[11:8] */ - lsr r2, r2, #7 /* actual rotate count in R2[4:0] */ - ror r1, r1, r2 /* Rotated constant in R1 */ - b _arm_get_operand1_val - -_arm_op2_is_reg: - ldr r1, =(NIBBLE2|BYTE0) - and r0, r4, r1 /* 12 bit register operand in R1 */ - bl _arm_rmshifted_val /* R0 contains the Rm shifted val */ - mov r1, r0 /* R1: Operand2 val */ - -_arm_get_operand1_val: - bl _dbg_data_instr_retrieve_op1val /* R0: Register Rn (Operand1) val */ - -_arm_calc_data_instr_val: - and r3, r4, #ARM_DATA_INSTR_NORMAL /* Mask Instruction Opcode into R3[24:21] */ - lsr r3, r3, #21 /* Shift Data Processing Opcode into R3[3:0] */ - /* Calculate data instruction value from R0: Register Rn (Operand1) val, R1: Operand2 val, R5[3:0]: CPSR, R6: Default Next Instr Addr */ - _dbg_jumpTableHandler debug_dataInstrJumpTable, r2, r3 /* Next Instruction Address in R0 */ -_exit_arm_data_instr_handler: - ldmfd sp!, {pc} - -/* _dbg_data_instr_retrieve_op1val - * Retrieve Data Instruction Operand 1 value - * On entry: - * R4: Opcode of instruction to be executed - * R5[3:0]: CPSR condition codes - * R6: Default Next Instruction Address (PC+4) - * On exit: - * R0: Register Rn (Operand 1) value - * R2, R3: Destroyed - * - */ -_dbg_data_instr_retrieve_op1val: - and r3, r4, #NIBBLE4 /* Store Rn (Operand1) Register Enum into R3[19:16] */ - lsr r3, r3, #16 /* Shift into R3[3:0] */ - _regenum2index r3, r2 /* Convert Enum into Index in R2 */ - _getdbgregisterfromindex r2, r0 /* Retrieve Register contents from Index (R2) into R0 */ - teq r3, #REG_PC /* Check if it is PC relative */ - addeq r0, r0, #8 /* R0: Register Rn (Operand1) val; adjust for PC relative (+8) */ - bx lr - -/* Data Processing Instruction Jump Table Routines - * On entry: - * R0: Register Rn (Operand 1) value - * R1: Operand 2 value - * R5[3:0]: CPSR condition codes - * R6: Default Next Instruction Address (PC+4) - * On exit: - * R0: Calculated result - * R1, R2, R3: Destroyed - * - */ -_opcode_and: - and r0, r0, r1 - bx lr - -_opcode_eor: - eor r0, r0, r1 - bx lr - -_opcode_sub: - sub r0, r0, r1 - bx lr - -_opcode_rsb: - rsb r0, r0, r1 - bx lr - -_opcode_add: - add r0, r0, r1 - bx lr - -_opcode_adc: - /* Op1 + Op2 + C */ - tst r5, #(CPSR_CFLAG>> 28) /* R5[3:0] is shifted CPSR value: Test C Flag */ - add r0, r0, r1 - addne r0, r0, #1 /* Add C if set */ - bx lr - -_opcode_sbc: - /* Op1 - Op2 + C - 1 */ - tst r5, #(CPSR_CFLAG>> 28) /* R5[3:0] is shifted CPSR value: Test C Flag */ - sub r0, r0, r1 - subeq r0, r0, #1 /* If C clear, subtract 1, else (C - 1) = 0 */ - bx lr - -_opcode_rsc: - /* Op2 - Op1 + C - 1 */ - tst r5, #(CPSR_CFLAG>> 28) /* R5[3:0] is shifted CPSR value: Test C Flag */ - rsb r0, r0, r1 - subeq r0, r0, #1 /* If C clear, subtract 1, else (C - 1) = 0 */ - bx lr - -_opcode_tst: -_opcode_teq: -_opcode_cmp: -_opcode_cmn: - mov r0, r6 /* Next Instruction Address is not modified */ - bx lr - -_opcode_orr: - orr r0, r0, r1 - bx lr - -_opcode_mov: - mov r0, r1 /* Operand 1 is ignored */ - bx lr - -_opcode_bic: - bic r0, r0, r1 - bx lr - -_opcode_mvn: - mvn r0, r1 /* Operand 1 is ignored */ - bx lr - -/* _arm_bx_blx_handler - * BX or BLX Rm Handler. Note v4t does not have BLX instr - * On entry: - * R4: Opcode of instruction to be executed - * R5[3:0]: CPSR condition codes - * R6: Default Following Instruction Address (PC+4) - * On exit: - * R0: following instruction address (B0 set to indicate Thumb mode) - * R1,R2: destroyed - */ -_arm_bx_blx_handler: - stmfd sp!, {lr} - and r2, r4, #NIBBLE0 /* Register Rn Enum in R2 */ - _regenum2index r2, r1 /* Convert Enum into Index in R1 */ - _getdbgregisterfromindex r1, r0 /* Retrieve Register contents from Index (R1) into R0 */ - teq r2, #REG_PC - addeq r0, r0, #8 /* Adjust PC relative register value (for BX PC) */ - /* Here, the register value would have B0 set to indicate switch to Thumb mode */ - ldmfd sp!, {pc} - -/* _arm_ldr_pc_handler - * LDR with Rd = PC - * On entry: - * R4: Opcode of instruction to be executed - * R5[3:0]: CPSR condition codes - * R6: Default Following Instruction Address (PC+4) - * On exit: - * R0: following instruction address - * R1, R2, R3, R4, R5: destroyed - */ - -_arm_ldr_pc_handler: - stmfd sp!, {lr} - - mov r1, #0 /* R1: Post-Indexed Offset (cleared) */ - tst r4, #ARM_LDR_INSTR_PREPOST /* Pre (1) or Post (0) Indexed */ - beq _get_rn_val /* If Post-Indexed, just use Rn directly */ - - /* Pre-Indexed */ - ldr r0, =(NIBBLE2|BYTE0) - and r0, r4, r0 /* R0: 12 bit Immediate value or Shifted Reg operand */ - tst r4, #ARM_LDR_INSTR_REGIMM /* Register (1) or Immediate (0) */ - beq _calc_ldr_pc_offset /* Immediate value is already in R0 */ - -_get_shiftedreg_val: - bl _arm_rmshifted_val /* Convert Rm shifted operand in R0 into value in R0 */ - -_calc_ldr_pc_offset: - mov r1, r0 /* Keep Offset in R1 */ -_get_rn_val: - bl _dbg_data_instr_retrieve_op1val /* R0: Register Rn (Operand1) val */ -_calc_op1val_with_offset: - tst r4, #ARM_LDR_INSTR_UPDOWN /* Add (1) or Subtract (0) */ - addne r0, r0, r1 /* If Add, R0 = Rn + Offset */ - subeq r0, r0, r1 /* If Sub, R0 = Rn - Offset */ - -_get_ldr_pc_val_from_mem: - ldr r0, [r0] /* Retrieve value from Memory at address given in R0 */ - ldmfd sp!, {pc} - -/* _arm_ldm_pc_handler - * LDM {pc} - * On entry: - * R4: Opcode of instruction to be executed - * R5[3:0]: CPSR condition codes - * R6: Default Following Instruction Address (PC+4) - * On exit: - * R0: following instruction address - * R2, R3: destroyed - * - * Note: The algorithm from eCos arm_stub.c does not deal with the Pre/Post-Indexed addressing (P) bit. - * The algorithm here loads different content using LDM based on the value of the P bit. - */ -_arm_ldm_pc_handler: - stmfd sp!, {lr} - bl _dbg_data_instr_retrieve_op1val /* R0: Register Rn (Operand1) val */ - -_arm_get_regcount: - mov r2, #0 /* Initialize reg_count (R2) to 0 */ - mov r3, r4, lsl #16 /* Keep HLFWORD0 containing vector bits in R3[31:16] */ - /* This shortens the checking to a max of 16 iterations, since the PC bit should be set */ -1: movs r3, r3, lsl #1 /* count number of '1' bits */ - addcs r2, r2, #1 /* increment reg_count (R2) if C Flag set */ - bne 1b /* continue until vector is empty */ - - /* Pre-Incr: Rn += reg_count x 4 - * Post-Incr: Rn += (reg_count - 1) x 4 - * Pre-Decr: Rn -= 4 - * Post-Decr: Rn - */ - -_arm_check_updown_offset: - tst r4, #ARM_LDM_INSTR_UPDOWN /* Check Up (1) or Down (0) */ - beq _arm_check_prepost_decr - -_arm_check_prepost_incr: - tst r4, #ARM_LDM_INSTR_PREPOST /* Check Pre (1) or Post (0) */ - subeq r2, r2, #1 /* Post-Incr: Decrement reg_count in R2 */ - add r0, r0, r2, lsl #2 /* Increment Offset: Rn (R0) += reg_count (R2) x 4 */ - b _get_ldm_pc_val_from_mem - -_arm_check_prepost_decr: - tst r4, #ARM_LDM_INSTR_PREPOST /* Check Pre (1) or Post (0) */ - /* Post-Decr: Rn unchanged */ - subne r0, r0, #4 /* Pre-Decr: Rn (R0) -= 4 */ - -_get_ldm_pc_val_from_mem: - ldr r0, [r0] /* Retrieve stack content for new PC value */ - ldmfd sp!, {pc} - - -/* _arm_b_bl_blx_handler - * B, BL or BLX . Note v4t does not have BLX instr - * On entry: - * R4: Opcode of instruction to be executed - * R5[3:0]: CPSR condition codes - * R6: Default Following Instruction Address (PC+4) - * On exit: - * R0: following instruction address - * R1: destroyed - */ - -_arm_b_bl_blx_handler: - stmfd sp!, {lr} - -_arm_b_bl_blx_get_offset: - and r0, r4, #(BYTE2|BYTE1|BYTE0) /* Encoded Branch offset in R4[23:0] */ - lsl r0, r0, #(32-24) /* Shift to R0[31:8] */ - asr r0, r0, #(32-26) /* Actual Signed offset = Encode Offset x 4 in R0[25:0] */ - add r1, r6, #4 /* R1: (PC+4) + 4 */ - add r0, r0, r1 /* Calculate Branch Target Address R0: (PC+8) + signed offset */ - -#ifndef __ARM6OR7__ - /* armv5t or later, has BLX support */ - and r1, r4, #ARM_BLX_INSTR_MASK /* Mask out Condition Code and Opcode */ - teq r1, #ARM_BLX_INSTR_BLX /* Look for BLX */ - bne _exit_arm_b_bl_blx_handler /* No, it is a B/BL instruction */ - tst r4, #ARM_BLX_INSTR_HBIT /* H bit for Thumb Halfword Address */ - orrne r0, r0, #0x02 /* Set Halfword Address R0[1] */ - orr r0, r0, #BKPT_STATE_THUMB_FLAG /* Set R0[0] since BLX instr used to switch to Thumb mode */ -#endif - -_exit_arm_b_bl_blx_handler: - ldmfd sp!, {pc} - -/* _arm_coproc_swi_handler - * SVC (SWI) or Coprocessor instruction - * On entry: - * R4: Opcode of instruction to be executed - * R5[3:0]: CPSR condition codes - * R6: Default Following Instruction Address (PC+4) - * On exit: - * R0: following instruction address - */ - -_arm_coproc_swi_handler: - and r0, r4, #ARM_SWI_INSTR_MASK - teq r0, #ARM_SWI_INSTR_VAL /* SVC (SWI) instruction */ - - ldreq r0, =SVC_VECTOR /* SWI: Return SVC Vector Address */ - movne r0, r6 /* CoProc: Use default Following Instruction Address */ -_exit_arm_coproc_swi_handler: - bx lr - -/* _thumb_bx_blx_handler - * BX or BLX Handler. Note: Link (L:b7) is not checked in the mask; armv4t does not support BLX. - * On entry: - * R4: Opcode of instruction to be executed - * R5[3:0]: CPSR condition codes - * R6: Default Following Instruction Address (PC+2) - * On exit: - * R0: following instruction address (B0 set to indicate Thumb mode) - * R1, R2: destroyed - */ -_thumb_bx_blx_handler: - stmfd sp!, {lr} - and r2, r4, #THUMB_BLX_INSTR_REG_RNMASK /* Register Rn Enum in R2[6:3] (Hi-Reg indicated by B6) */ - mov r2, r2, lsr #3 /* Shift Rn Enum to R2[3:0] */ - _regenum2index r2, r1 /* Convert Enum into Index in R1 */ - _getdbgregisterfromindex r1, r0 /* Retrieve Register contents from Index (R1) into R0 */ - teq r2, #REG_PC - addeq r0, r0, #4 /* Adjust PC relative register value (for BX PC) */ - /* Here, the register value would have R0[0] set to indicate switch to Thumb mode */ - ldmfd sp!, {pc} - -/* _thumb_poppc_handler - * PUSH/POP, specifically POP {Rlist,PC} - * On entry: - * R4: Opcode of instruction to be executed - * R5[3:0]: CPSR condition codes - * R6: Default Following Instruction Address (PC+2) - * On exit: - * R0: following instruction address (B0 set to indicate Thumb mode) - * R1-R3: destroyed - */ -_thumb_poppc_handler: - stmfd sp!, {lr} - -_thumb_get_SP_val: - _getdbgregister DBGSTACK_USERSP_INDEX, r1 /* Retrieve SP contents into R1 */ - -_thumb_get_regcount: - mov r3, r4, lsl #24 /* Keep BYTE0 containing vector bits in R3[31:24] */ - /* POP is equivalent to LDMFD. Load PC is encoded in b8, - * the 8-bit vector is for Lo registers. - * This shortens the checking to a max of 8 iterations - */ -1: movs r3, r3, lsl #1 /* count number of '1' bits */ - addcs r1, r1, #4 /* Walk the stack to locate the PUSHed LR (POP PC) value */ - bne 1b /* continue until vector is empty */ - ldr r0, [r1] /* Retrieve new PC value */ -#if 0 - /* PC Value should have B0 set */ - orr r0, r0, #BKPT_STATE_THUMB_FLAG /* Force R0[0] since it is used to indicates Thumb mode */ -#endif - ldmfd sp!, {pc} - -/* _thumb_bcond_swi_handler - * B or SWI (SVC) - * On entry: - * R4: Opcode of instruction to be executed - * R5[3:0]: CPSR condition codes - * R6: Default Following Instruction Address (PC+2) - * On exit: - * R0: following instruction address (B0 set to indicate Thumb mode) - * R1-R3: destroyed - */ -_thumb_bcond_swi_handler: - stmfd sp!, {lr} - and r2, r4, #THUMB_BCOND_SWI_INSTR_CONDMASK /* Keep Condition Code R2[11:8] */ - teq r2, #THUMB_BCOND_SWI_INSTR_SWI /* SVC (SWI) instruction */ -_thumb_swi_instr: - ldreq r0, =SVC_VECTOR /* Return SVC Vector Address */ - beq _exit_thumb_bcond_swi_handler /* Switch to ARM mode for SVC */ -_thum_bcond_unused_instr: - teq r2, #THUMB_BCOND_SWI_COND_UNUSED - moveq r0, r6 /* False (don't execute), so use Default Following Instruction Address */ - beq _exit_thumb_bcond_instr - -_thumb_bcond_instr: - stmfd sp!, {r4} /* Preserve Opcode in R4 */ - lsl r4, r2, #(32-12) /* Shift condition code in R2[11:8] to R0[31:28] to match ARM cond-code format */ - bl _dbg_check_arm_condcode /* Use ARM condition code checking routine to test (R4, R6 unchanged) */ - ldmfd sp!, {r4} /* Restore Opcode in R4 */ - teq r0, #FALSE - moveq r0, r6 /* False (don't execute), so use Default Following Instruction Address */ - beq _exit_thumb_bcond_instr - -_thumb_calc_bcond_offset: - lsl r0, r4, #(32-8) /* Shift 8-bit offset in R4[7:0] to R0[31:24] */ - asr r0, r0, #(32-9) /* Convert into 9-bit signed offset in R0[8:0] */ - add r0, r6, r0 /* PC+2 + signed offset */ - add r0, r0, #2 /* PC+4 + signed offset */ -_exit_thumb_bcond_instr: - orr r0, r0, #BKPT_STATE_THUMB_FLAG /* Set R0[0] since it is used to indicates Thumb mode */ -_exit_thumb_bcond_swi_handler: - ldmfd sp!, {pc} - -/* _thumb_b_handler - * B - * On entry: - * R4: Opcode of instruction to be executed - * R5[3:0]: CPSR condition codes - * R6: Default Following Instruction Address (PC+2) - * On exit: - * R0: following instruction address (B0 set to indicate Thumb mode) - * R1: destroyed - * Note: The signed offset is 12-bits (encoded value x 2) - */ -_thumb_b_handler: - stmfd sp!, {lr} - lsl r0, r4, #(32-11) /* Shift 11-bit offset in R4[10:0] to R0[31:21] */ - asr r0, r0, #(32-12) /* Convert into 12-bit signed offset in R0[11:0] */ - add r0, r6, r0 /* PC+2 + signed offset */ - add r0, r0, #2 /* PC+4 + signed offset */ - orr r0, r0, #BKPT_STATE_THUMB_FLAG /* Set R0[0] since it is used to indicates Thumb mode */ - ldmfd sp!, {pc} - -/* _thumb_long_bl_blx_handler - * Long BL or BLX (4 bytes) Note: b11 (H) indicates 1st or 2nd instr; armv4t does not support BLX. - * On entry: - * R4: Opcode of instruction to be executed - * R5[3:0]: CPSR condition codes - * R6: Default Following Instruction Address (PC+2) - * On exit: - * R0: following instruction address (B0 set to indicate Thumb mode) - * R1, R2, R3: destroyed - * R6: Subseqent Instruction Address (PC+4) if first instruction is valid, else unchanged (PC+2) - * Note: The BL instruction (0xFxxx) should be in pairs (Dual 16-bit instructions). - * The first instruction should have (H=0) to indicate the upper 11 bits of the encoded offset - * The second instruction should have (H=1) to indicate the lower 11 bits of the encoded offset - * The signed offset is 23 bits (encoded value x 2) - * - * Note2: The BLX instruction (0xExxx) encodes the first instruciton using BL (0xFxxx) with H=0, - * while the second instruction has a different opcode value (0xExxx), with H=1. - * BLX is only used to switch to an ARM target. - */ -_thumb_long_bl_blx_handler: - stmfd sp!, {lr} -_thumb_check_1st_bl_blx_instruction: - tst r4, #THUMB_BLX_INSTR_IMM_HBIT /* Check H bit */ - bne _return_default_thumb_following_instr /* H=1 as first instruction shouldn't happen */ -_thumb_check_2nd_bl_blx_instruction: - ldrh r3, [r6] /* Get second instruction in pair at PC+2 into R3 */ - add r6, r6, #2 /* Skip to Subsequent Instruction (PC+4) */ - tst r3, #THUMB_BLX_INSTR_IMM_HBIT /* Check H bit */ - beq _return_default_thumb_following_instr /* H=0 as second instruction shouldn't happen */ - -_thumb_concat_branch_offset: - lsl r0, r4, #(32-11) /* Shift first instruction 11-bit offset in R4[10:0] to R0[31:21] */ - asr r0, r0, #(32-23) /* Convert into 12-bit signed offset in R0[22:12] */ - lsl r2, r3, #(32-11) /* Shift second instruction 11-bit offset in R3[10:0] to R2[31:21] */ - lsr r2, r2, #(32-12) /* Convert into 12-bit unsigned offset in R2[11:0] */ - orr r0, r0, r2 /* Combine offsets */ - add r0, r6, r0 /* PC+4 + signed offset */ - -_thumb_check_bl_blx_pair: - and r3, r3, #THUMB_BLX_INSTR_IMM_MASK /* Keep second instruction opcode in R3 */ - teq r3, #THUMB_BLX_INSTR_IMM_BL /* Look for BL */ - beq _flag_thumb_instr_addr /* Return BL target address in R0 */ - -#ifndef __ARM6OR7__ - /* v5t or higher architecture */ - teq r3, #THUMB_BLX_INSTR_IMM_BLX /* Look for BLX */ - biceq r0, r0, #0x03 /* Match, Force ARM address */ - beq _exit_thumb_long_bl_blx_handler -#endif - -_return_default_thumb_following_instr: - /* FIXME: This assumes that once the 4-byte sequence check fails, it will return PC+4, - * regardless of whether the second instruction is a valid BL/BLX instruction or not. - */ - mov r0, r6 /* Return default Following/Subsequent Instruction Address */ -_flag_thumb_instr_addr: - orr r0, r0, #BKPT_STATE_THUMB_FLAG /* Set R0[0] since it is used to indicates Thumb mode */ - -_exit_thumb_long_bl_blx_handler: - ldmfd sp!, {pc} - diff --git a/AT91SAM7S256/armdebug/Debugger/debug_runlooptasks.S b/AT91SAM7S256/armdebug/Debugger/debug_runlooptasks.S deleted file mode 100644 index a9eb50a..0000000 --- a/AT91SAM7S256/armdebug/Debugger/debug_runlooptasks.S +++ /dev/null @@ -1,411 +0,0 @@ -/** @file debug_runlooptasks.S - * @brief GDB Server platform Run Loop - * - */ - -/* Copyright (C) 2007-2011 the NxOS developers - * - * Module Developed by: TC Wan - * - * See AUTHORS for a full list of the developers. - * - * See COPYING for redistribution license - * - */ - -/* - * This file contains platform specific code. - * This include ABORT Mode Debugger Run Loop operation, - * as well as Debugger Interfacing code to the platform code. - */ - -/* - * The Debugger has to implement a Run Loop in ABORT mode - * since the hardware is still running. Consequently, - * the communications subsystems such as USB (and Bluetooth?) - * which is used to communicate with the Host needs to be - * serviced in order for actual data transmission and reception - * to take place. Currently we're reusing the platform's - * communication routines to do the actual tx/rx, so it means - * that it is not possible to set breakpoints in those modules. - * In addition, since the platform communication modules may - * handle other tasks, it is currently possible to enter an - * indeterminate state where certain communication messages trigger - * a platform response which cannot be handled by the Debugger Run Loop. - * The alternative is to implement our own communications routines, but - * that will take even more code. - * - * FIXME: It may become necessary to hack the platform communications - * routines to detect that we're in the Debugger Run Loop and not the - * normal run loop to avoid system crashes, but the current goal is to - * have as minimal changes to the platform code as possible. - * - * Since there are two Run Loops for the platform, the way in which - * they interact is as follows: - * - * [Platform Run Loop] - DBG_INIT/ GDB Cmd/ BKPT -> [Debugger Run Loop] - * \ <------ GO/ STEP/ CONT ----- / - * ... ... - * ... Handle GDB Cmd/Resp - * ... ... - * {normal runloop {communications / - * processing} watchdog routines} - * ^-------v v-------^ - * - * The Platform will invoke dbg__bkpt_init() after hardware and system initialization, - * before entering the Platform Run Loop. This configures the Debugger, but does not - * invoke the Debugger Run Loop unless a Manual Breakpoint is found in the platform code. - * - * Subsequently, the Debugger Run Loop will be triggered by Breakpoints, or - * when the communications subsystem receives a GDB Command. - * - * The Debugger Run Loop is actually dbg__bkpt_waitCMD(), this file contains - * the Run Loop Tasks which needs to be invoked periodically by the Run Loop, - * to minimize the coupling between the ARMDEBUG modules and the Platform. - * - * Note: The Debugger Run Loop does not handle Hardware Shutdown, it is - * assumed that we wouldn't need to do so in Debug Mode. - * - */ -#define __ASSEMBLY__ - -#define REBOOT_POWERDOWN -#include "debug_runlooptasks.h" - -#include "debug_internals.h" -#include "debug_macros.h" -#include "debug_stub.h" - - .code 32 - .align 4 - -#ifdef __NXOS__ -/**************************************************************************** - * - * NxOS Run Loop - * - ****************************************************************************/ - dbg_interwork dbg__runloopTasks -/* Currently, there's nothing that needs to be done in the NxOS Run Loop */ - push {lr} - mov r0, #1 /* 1 ms delay */ - bl nx_systick_wait_ms - pop {pc} - -#else -/**************************************************************************** - * - * NXT Firmware Run Loop - * - ****************************************************************************/ - dbg_interwork dbg__runloopTasks - push {lr} - /* FIXME: Add necessary cXXXCtrl calls here */ - bl cCommCtrl - /* OSWatchdogWrite is a NULL function in the NXT Firmware?! */ - pop {pc} -#endif - -#ifdef __NXOS__ -/**************************************************************************** - * - * NxOS Reboot Routine - * - ****************************************************************************/ - dbg_interwork dbg__reboot -#ifdef REBOOT_POWERDOWN - b nx_core_halt /* Shutdown Brick, won't return */ -#else - b nx_core_reset /* Reboot Brick, won't return */ -#endif - -#else -/**************************************************************************** - * - * NXT Firmware Reboot Routine - * - ****************************************************************************/ - dbg_interwork dbg__reboot - /* Powerdown Sequence - dIOCtrlSetPower((POWERDOWN>>8)); - dIOCtrlTransfer(); - - Reboot Sequence - dIOCtrlSetPower((UBYTE)(BOOT>>8)); - dIOCtrlSetPwm((UBYTE)BOOT); - dIOCtrlTransfer(); - */ - - /* We implement the powerdown sequence for now */ - -#ifdef REBOOT_POWERDOWN - /* Powerdown sequence */ - ldr r0, =((POWERDOWN >> 8) & 0xFF) - ldr r1, =dIOCtrlSetPower - mov lr,pc - bx r1 -#else - /* Reboot sequence: this forces SAMBA mode??!! */ - ldr r0, =((BOOT >> 8) & 0xFF) - ldr r1, =dIOCtrlSetPower - mov lr,pc - bx r1 - - ldr r0, =(BOOT & 0xFF) - ldr r1, =dIOCtrlSetPwm - mov lr,pc - bx r1 -#endif - -_dbg__reboot_wait: - ldr r1, =dIOCtrlTransfer - mov lr,pc - bx r1 - - b _dbg__reboot_wait /* Wait for AVR... */ -#endif - -#ifdef __NXOS__ -/**************************************************************************** - * - * NxOS Abort Info LCD Display Routine - * - ****************************************************************************/ -/* On entry: - * r0: abort type - * On exit: - * r0-r3: destroyed - */ - dbg_interwork dbg__display_abort_info - push {lr} - _getdbgregister DBGSTACK_USERPC_INDEX, r1 /* Retrieve User PC into R2 */ - _getdbgregister DBGSTACK_USERCPSR_INDEX, r2 /* Retrieve User CPSR into R2 */ - bl nx__abort_info /* void nx__abort_info(U32 data, U32 pc, U32 cpsr); */ - pop {pc} - -#else -/**************************************************************************** - * - * NXT Firmware Abort Info LCD Display Routine - * - ****************************************************************************/ - dbg_interwork dbg__display_abort_info -/* FIXME: Inteface with NXT Firmware LCD Display routines */ - push {lr} - pop {pc} -#endif - -#ifdef __NXOS__ - .extern debug_OutCommBuf -/**************************************************************************** - * - * NxOS Communications Driver Interface Routine - * - ****************************************************************************/ -/* dbg__sendCommMsg - * Internal send routine (interfaces with drivers). - * On entry: - * R0: Total Message Buffer length - * On exit: - * R0: Tx Status (TRUE if data sent) - * R1-R3: Destroyed - */ - dbg_interwork dbg__sendCommMsg - stmfd sp!, {r4, lr} - mov r4, r0 /* Keep Comm Buffer length in R4 */ - /* Check USB bus status, transmit message if possible */ - bl nx_usb_is_connected /* R0 = TRUE (#1) if USB is ready */ - teq r0, #0 /* FALSE == #0; - We can't check for True condition since values - used by C-Compiler & ARMDEBUG are different */ - beq dbg__sendCommMsgFailed - - /* Actual transmission (blocking) */ - ldr r0, =debug_OutCommBuf /* data pointer parameter */ - mov r1, r4 /* Comm buffer length */ - bl nx_usb_write - -1: bl nx_usb_data_written /* R0 = True if data has been sent */ - teq r0, #0 /* FALSE == #0; - We can't check for True condition since values - used by C-Compiler & ARMDEBUG are different */ - /* FIXME: implement timeout */ - beq 1b /* Busy Wait Loop */ - - mov r0, #TRUE - b exit_dbg__sendCommMsg -dbg__sendCommMsgFailed: - mov r0, #FALSE - -exit_dbg__sendCommMsg: - ldmfd sp!, {r4, pc} - - -#else -/**************************************************************************** - * - * NXT Firmware Communications Driver Interface Routine - * - ****************************************************************************/ -/* dbg__sendCommMsg - * Internal send routine (interfaces with drivers). - * On entry: - * R0: Total Message Buffer length - * On exit: - R0: Tx Status (TRUE if data sent) - */ - dbg_interwork dbg__sendCommMsg - stmfd sp!, {r4, lr} - mov r4, r0 /* Keep Comm Buffer length in R4 */ - ldr r0, =debug_nxtCommChannel - ldr r0, [r0] /* Get Channel Enum */ - teq r0, #BT_CMD_READY - beq dbg__sendBTMsg - teq r0, #USB_CMD_READY - beq dbg__sendUSBMsg - b dbg__sendCommMsgFailed /* Channel Enum Doesn't Match, shouldn't happen? */ - -dbg__sendBTMsg: - /* NXT BT routines do not have any configuration checks */ - ldr r0, =debug_OutCommBuf /* data pointer parameter */ - mov r1, r4 /* BT Bytes to Send */ - mov r2, r4 /* BT Message Size */ - bl dBtSendMsg /* Send it via Bluetooth (complete message) */ - mov r0, #TRUE /* Always flag Success */ - b exit_dbg__sendCommMsg - -dbg__sendUSBMsg: - /* Check USB bus status, transmit message if possible */ - bl dUsbIsConfigured /* R0: UByte status, TRUE / FALSE */ - teq r0, #nxt_UBYTE_TRUE - bne dbg__sendCommMsgFailed - - /* Actual transmission (blocking) */ - ldr r0, =debug_OutCommBuf /* data pointer parameter */ - mov r1, r4 /* Comm buffer length */ - bl dUsbWrite /* call NXT Firmware USB driver, return 0: done, !0: remaining chars */ - teq r0, #0 /* Tx done if returned length is 0 */ - moveq r0, #TRUE /* Convert NXT firmware return value to our Status (TRUE/FALSE) */ - beq exit_dbg__sendCommMsg -dbg__sendCommMsgFailed: - mov r0, #FALSE - -exit_dbg__sendCommMsg: - ldmfd sp!, {r4, pc} -#endif - - -#ifdef __NXOS__ -/**************************************************************************** - * - * GDB Debugger Invocation Routine for NxOS - * - ****************************************************************************/ - .code 32 - .align 4 - - .extern dbg__install_singlestep - .extern dbg__activate_singlestep - .extern irq_stack_frame_address -/* nxos__handleDebug - * Prepare to switch to Debug Mode - * int nxos__handleDebug(U8 *buffer, comm_chan_t channel, U32 length); - * - * This routine is called from NxOS Fantom library to setup - * Single Step Breakpoint in preparation for Debugger invocation if we're in - * normal execution mode. - * - * It returns to complete the IRQ handling normally, after which the single - * step breakpoint will be triggered, and the incoming GDB message will then - * be processed in the dbg__bkpt_waitCMD() loop. - * - * If we're in Debugger Mode already, then just return and let the - * dbg__bkpt_waitCMD() loop handle it normally. - * - * If we're operating in normal NxOS mode, return True (!0) - * If we're already in Debugger Mode, return False (0) - */ - dbg_interwork nxos__handleDebug - push {lr} - /* This routine is called from nx__irq_handler() via fantom_filter_packet(). - * The operating mode should already have been configured by the IRQ interrupt handler. - * - * The IRQ Stack Frame Pointer will contains the LR and SPSR from the topmost interrupted task - * if it is non-zero (NxOS supports nested IRQs) - */ - bl dbg__copyNxtDebugMsg /* Copy to Debugger Message Buffer, Remember Comm Channel */ - mov r0, #FALSE /* Setup Default Return value (False) */ - _dbg_getmode r1 /* Get Debug Mode */ - cmp r1, #(TRUE & BYTE0) /* Confine it to Byte size */ - /* If Debug Mode is TRUE, this means that we're already running the Debugger */ - beq exit_nxos__handleDebug /* Yes, return False */ - - /* Retrieve ISR Return Address */ - ldr r3, =irq_stack_frame_address - ldr r3, [r3] /* Get Interrupt Stack Pointer */ - teq r3, #0 - beq exit_nxos__handleDebug /* NULL Interrupt Stack Frame Pointer, exit (status: False) */ - -nxos_switch2debug: - /* Since the Interrupt Stack Frame Pointer points to the top of the stack frame, - * we'll have to use Load Empty Ascending Stack (LDMEA == LDMDB) to access the variables - */ - ldmdb r3, {r1,r2} /* R1: LR, R2: SPSR */ - tst r2, #CPSR_THUMB /* Check for Thumb Mode */ - orrne r1, r1, #1 /* Configure for Thumb Single Step Breakpoint */ - bl dbg__install_singlestep /* Setup Single Step, next instruction address returned in r1 */ - bl dbg__activate_singlestep - mov r0, #TRUE /* We're going to switch to Debug Mode (via Single Step Breakpoint) */ - -exit_nxos__handleDebug: - pop {r1} - bx r1 /* In case we have Interworking from different caller mode */ - -#else - -/**************************************************************************** - * - * GDB Debugger Invocation Routine for NXT Firmware - * - ****************************************************************************/ - .code 16 - .align 2 - - .extern dbg__copyNxtDebugMsg - .global cCommHandleDebug - .thumb_func - .type cCommHandleDebug, %function -/* cCommHandleDebug - * Switch Mode to Debugger. - * Used by NXT Firmware only - * - * UWORD cCommHandleDebug(UBYTE *pInBuf, UBYTE CmdBit, UWORD MsgLength); - * - * This routine is called from cCommInterprete either in normal operation mode (SVC) - * or else when we're in debug mode (ABORT) which uses the cCommCtrl() routine to handle - * I/O with the Host. - * - * On entry, the message is copied from the NXT buffer into our own buffers. - * - * If this is accessed from normal operation mode, we need to switch mode to - * ABORT mode to handle the incoming message using a Manual Breakpoint instruction. - * When DEBUG is exited, the execution resumes from the instruction following the Breakpoint. - */ -cCommHandleDebug: -/* Arg Registers are not preserved since this is invoked explicitly */ - push {lr} /* store arg registers */ - bl dbg__copyNxtDebugMsg /* Copy to Debugger Message Buffer, Remember Comm Channel */ - _dbg_getmode r0 /* Get Debug Mode */ - cmp r0, #(TRUE & BYTE0) /* Confine it to Byte size */ - - /* If Debug Mode is TRUE, this means that we're already running the Debugger */ - beq _cCommHandleDebug_cont - /* Else, we're in normal operation mode (SVC), or other mode (??!) and need to force a switch to Debug mode */ - dbg__bkpt_thumb -_cCommHandleDebug_cont: - mov r0, #0 /* FIXME: Return Status */ - pop {r1} /* Can't Pop LR directly */ - bx r1 /* Safe code: actually we should be able to Pop PC since the caller is Thumb Mode */ - - .ltorg -#endif diff --git a/AT91SAM7S256/armdebug/Debugger/debug_runlooptasks.h b/AT91SAM7S256/armdebug/Debugger/debug_runlooptasks.h deleted file mode 100644 index a2ae956..0000000 --- a/AT91SAM7S256/armdebug/Debugger/debug_runlooptasks.h +++ /dev/null @@ -1,81 +0,0 @@ -/** @file debug_runlooptasks.h - * @brief Shared C/ASM header file for debugger communications - * - */ - -/* Copyright (C) 2007-2011 the NxOS developers - * - * Module Developed by: TC Wan - * - * See AUTHORS for a full list of the developers. - * - * See COPYING for redistribution license - * - */ - -#ifndef __DEBUG_RUNLOOPTASKS_H__ -#define __DEBUG_RUNLOOPTASKS_H__ - -#include "_c_arm_macros.h" - -/* This is a place holder header file to allow for interfacing with C Routines in either - * NxOS or NXT Firmware. - * - * Since the header files from the original source trees were meant for C programs, we can't - * include them directly. Here we just use .extern to reference the routines. - */ - -#ifdef __NXOS__ - .extern nx__abort_info - .extern nx_systick_wait_ms - - .extern nx_usb_is_connected - .extern nx_usb_can_write - .extern nx_usb_write - .extern nx_usb_data_written - .extern nx_usb_read - .extern nx_usb_data_read - .extern nx_core_reset - .extern nx_core_halt - -#else /* NXT Firmware */ - - .extern cCommInit - .extern cCommCtrl - .extern cCommExit - .extern dUsbWrite - .extern dUsbRead - .extern dUsbIsConfigured - .extern dBtSendMsg - /** - * True value used by Thumb mode in NXT - */ - .equ nxt_UBYTE_TRUE, 1 - /** - * False value used by Thumb mode in NXT - */ - .equ nxt_UBYTE_FALSE, 0 - /** - * USB Command Indicator - */ - .equ USB_CMD_READY, 0x01 /* From c_comm.iom */ - /** - * BT Command Indicator - */ - .equ BT_CMD_READY, 0x02 /* From c_comm.iom */ - - .extern dIOCtrlSetPower - .extern dIOCtrlSetPwm - .extern dIOCtrlTransfer - /** - * NXT Boot Magic Value - */ - .equ BOOT, 0xA55A /* from c_ioctrl.iom */ - /** - * NXT Powerdown Magic Value - */ - .equ POWERDOWN, 0x5A00 /* from c_ioctrl.iom */ - -#endif - -#endif diff --git a/AT91SAM7S256/armdebug/Debugger/debug_stack.ld b/AT91SAM7S256/armdebug/Debugger/debug_stack.ld deleted file mode 100644 index 8fc4cb7..0000000 --- a/AT91SAM7S256/armdebug/Debugger/debug_stack.ld +++ /dev/null @@ -1,15 +0,0 @@ -/* The following linker definitions should be placed in the stack section */ - - /* debugger state */ - __debugger_stack_bottom__ = . ; - . += 0x48; /* 16 previous mode registers + SPSR + UNDEF Next Instruction Address */ - __debugger_stack__ = .; - __debugger_stack_top__ = . ; - - /* breakpoints */ - __breakpoints_start__ = . ; - . += 0x40; /* Single Stepping Breakpoint + 7 Breakpoints */ - __breakpoints_end__ = . ; - -/* Symbols */ - __breakpoints_num__ = (__breakpoints_end__ - __breakpoints_start__) / 8; diff --git a/AT91SAM7S256/armdebug/Debugger/debug_stub.S b/AT91SAM7S256/armdebug/Debugger/debug_stub.S deleted file mode 100644 index a7b2d56..0000000 --- a/AT91SAM7S256/armdebug/Debugger/debug_stub.S +++ /dev/null @@ -1,1579 +0,0 @@ -/** @file debug_stub.S - * @brief ARM Breakpoint Debugger support routines - * - */ - -/* Copyright (C) 2007-2011 the NxOS developers - * - * Module Developed by: TC Wan - * - * See AUTHORS for a full list of the developers. - * - * See COPYING for redistribution license - * - */ - - /* GDB sparc-stub.c comments header included below to document GDB Server Remote protocol */ - /* This header has been modified to include additional commands not documented in the header stub */ - - /**************************************************************************** - - THIS SOFTWARE IS NOT COPYRIGHTED - - HP offers the following for use in the public domain. HP makes no - warranty with regard to the software or it's performance and the - user accepts the software "AS IS" with all faults. - - HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD - TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - -****************************************************************************/ - -/**************************************************************************** - * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $ - * - * Module name: remcom.c $ - * Revision: 1.34 $ - * Date: 91/03/09 12:29:49 $ - * Contributor: Lake Stevens Instrument Division$ - * - * Description: low level support for gdb debugger. $ - * - * Considerations: only works on target hardware $ - * - * Written by: Glenn Engel $ - * ModuleState: Experimental $ - * - * NOTES: See Below $ - * - * Modified for SPARC by Stu Grossman, Cygnus Support. - * - * This code has been extensively tested on the Fujitsu SPARClite demo board. - * - * To enable debugger support, two things need to happen. One, a - * call to set_debug_traps() is necessary in order to allow any breakpoints - * or error conditions to be properly intercepted and reported to gdb. - * Two, a breakpoint needs to be generated to begin communication. This - * is most easily accomplished by a call to breakpoint(). Breakpoint() - * simulates a breakpoint by executing a trap #1. - * - ************* - * - * The following gdb commands are supported: - * - * command function Return value - * - * g return the value of the CPU registers hex data or ENN - * GrrrrRRRR.. set the value of the CPU registers OK or ENN - * where register values are given as - * 32-bit hex values in the sequence: - * User R0, R1, ..., R15, CPSR - * px get the value of one register (x) hex data or ENN - * Px=rrrr set the value of one register (x) to OK or ENN - * 32-bit hex value rrrr. - * x = ['0','F'] for R0-R15, ['10','17'] for F0-F7 (dummy) - * '18' for FPSCR (dummy), '19' for User CPSR - * - * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN - * MAA..AA,LLLL:bb..bb - * Write LLLL bytes at address AA.AA OK or ENN - * - * D Detach (equivalent to continue Ack Only - * at current address) - * c Resume at current address SNN ( signal NN) - * cAA..AA Continue at address AA..AA SNN - * - * s Step one instruction SNN - * sAA..AA Step one instruction from AA..AA SNN - * - * k kill - * - * ? What was the last sigval ? SNN (signal NN) - * - * zt,AA..AA,k Remove a Breakpoint of type t at addr OK or ENN - * AA..AA of kind k - * Zt,AA..AA,k Insert a Breakpoint of type t at addr OK or ENN - * AA..AA of kind k - * t 0: memory breakpoint - * 1: hardware breakpoint - * 2: write watchpoint - * 3: read watchpoint - * 4: access watchpoint - * k: 2 (16-bit Thumb), 3 (32-bit Thumb2) - * or 4 (32-bit ARM) for t=[0,1] - * Num. bytes to watch for t=[2,4] - * - * All commands and responses are sent with a packet which includes a - * checksum. A packet consists of - * - * $#. - * - * where - * :: - * :: < two hex digits computed as modulo 256 sum of > - * - * When a packet is received, it is first acknowledged with either '+' or '-'. - * '+' indicates a successful transfer. '-' indicates a failed transfer. - * - * Example: - * - * Host: Reply: - * $m0,10#2a +$00010203040506070809101112131415#42 - * - ****************************************************************************/ - /* Modified GDB Server Remote Protocol definition from GDB's sparc-stub.c Comment Header included above - * Additional commands from GDB Reference Appendix D.2 - * - * Note: ARMDEBUG can only implement Memory Breakpoints t=0. Hardware breakpoints requires a JTAG debugger. - * Currently, watchpoints are not implemented as they require hardware support as well (need verification). - * - * GDB requires command parameters to be specified as Big Endian values. - * However, the read/write register command expect the register contents to be specified in target byte order. - * The default target byte order is Little Endian for the AT91SAM7xxx processor in the NXT. - * If Big Endian target byte order is required, the __BIG_ENDIAN__ preprocessor label should be defined. - */ - -/* FIXME: The Hex value arguments passed by GDB does not have fixed lengths! Although the standard says - * there should be x digits, it does not follow this requirement. e.g., register index. - */ - - -#define __ASSEMBLY__ -#include "debug_stub.h" -#include "debug_internals.h" -#include "debug_macros.h" - - /* Opcode Parser function reference */ - .extern dbg_following_instruction_addr - - /* Hexutils function references */ - .extern hex2char - .extern char2hex - .extern byte2ascii - .extern halfword2ascii_be - .extern halfword2ascii_le - .extern word2ascii_be - .extern word2ascii_le - .extern ascii2hex_varlen_be - .extern ascii2byte - .extern ascii2halfword_be - .extern ascii2halfword_le - .extern ascii2word_be - .extern ascii2word_le - -/* Macro definitions */ - -/* _check_msgseparator - * Look for separator ',' - * On entry: - * bufferptr: points to the parameter buffer [can't be R0] - * On exit: - * R0: destroyed - * bufferptr: points to the next character location in the parameter buffer - * Flags: Updated - */ - - .macro _check_msgseparator bufferptr - ldrb r0, [\bufferptr], #1 /* get separator */ - cmp r0, #MSGBUF_SEPCHAR - .endm - -/* _check_msgargument - * Look for argument ':' - * On entry: - * bufferptr: points to the parameter buffer [can't be R0] - * On exit: - * R0: destroyed - * bufferptr: points to the next character location in the parameter buffer - * Flags: Updated - */ - - .macro _check_msgargument bufferptr - ldrb r0, [\bufferptr], #1 /* get separator */ - cmp r0, #MSGBUF_ARGCHAR - .endm - -/* _check_msgassignment - * Look for assignment '=' - * On entry: - * bufferptr: points to the parameter buffer [can't be R0] - * On exit: - * R0: destroyed - * bufferptr: points to the next character location in the parameter buffer - * Flags: Updated - */ - - .macro _check_msgassignment bufferptr - ldrb r0, [\bufferptr], #1 /* get separator */ - cmp r0, #MSGBUF_SETCHAR - .endm - -.bss -.align 4 -debug_InMsgBuf: - .space MSGBUF_SIZE,0 -debug_OutMsgBuf: - .space MSGBUF_SIZE,0 - - /* Make Debugger State accessible from other modules */ - .global debug_state - .global debug_mode - .global debug_bkpt_type - .global debug_curr_breakpoint - -debug_state: - .byte 0x0 /* dbg_state_t variable */ -debug_mode: - .byte 0x0 /* Boolean variable */ -debug_bkpt_type: - .byte 0x0 /* bkpt_type_t variable */ -debug_curr_breakpoint: - .byte 0x0 - -.data -.align 4 -debug_RetransmitFlag: - .byte '-',0 - -debug_AckOnlyFlag: - .byte '+',0 - -debug_ValidResponsePrefix: - .byte '+','$',0 - -debug_ErrorResponsePrefix: - .byte '+','$','E',0 - -debug_SignalResponsePrefix: - .byte '+','$','S',0 - -debug_OkResponse: - .byte '+','$','O','K',0 - -debug_ThreadIDResponse: - .byte '+','$','Q','C','0',0 /* 0: Any thread */ - -debug_FirstThreadInfoResponse: - .byte '+','$','m','0',0 /* 0: One default thread */ -debug_SubsequentThreadInfoResponse: - .byte '+','$','l',0 /* End of Thread List */ - -/* The CmdIndexTable and CmdJumpTable must be kept in sync */ -debug_cmdIndexTable: - .byte 'g','G','p','P','m','M','D','c','s','k','z','Z','?','q','Q',0 - -/* Command Handlers - * On entry: - * R0: Input Message Parameter Buffer address pointer (points to contents after '$' and '') - */ -.align 4 -debug_cmdJumpTable: - .word _dbg__cmd_GetAllRegs /* 'g' */ - .word _dbg__cmd_SetAllRegs /* 'G' */ - .word _dbg__cmd_GetOneReg /* 'p' */ - .word _dbg__cmd_SetOneReg /* 'P' */ - .word _dbg__cmd_ReadMem /* 'm' */ - .word _dbg__cmd_WriteMem /* 'M' */ - .word _dbg__cmd_Detach /* 'D' */ - .word _dbg__cmd_Continue /* 'c' */ -#ifdef __NXOS__ - .word _dbg__cmd_Step /* 's' */ -#else - /* NXT Firmware does not support Stepping */ - .word _dbg__nop /* 's' */ -#endif - .word _dbg__cmd_Kill /* 'k' */ - .word _dbg__cmd_RemoveBreakpoint /* 'z' */ - .word _dbg__cmd_InsertBreakpoint /* 'Z' */ - .word _dbg__cmd_Status /* '?' */ - .word _dbg__cmd_Query /* 'q' */ - .word _dbg__nop /* 'Q' */ - .word 0 - -.code 32 -.text -.align 4 - .extern __breakpoints_num__ - .extern dbg__getDebugMsg /* Read a message from the communications link */ - .extern dbg__putDebugMsg /* Write a message to the communications link */ - .extern dbg__sendAckOrNak /* Send Ack or Nak to indicate success/failure of message receipt */ - .extern dbg__runloopTasks /* Platform specific Run Loop processing */ - - -/* The Debugger Interface can handle a total of (n-1) Breakpoint States and 1 Single Stepping State, - * where n is a power of 2. The value of n is given by __breakpoints_num__ defined in the linker file. - * - * In addition, a Debugger Stack contains the User Mode Register Stack Frame + SPSR + Bkpt Instr Addr. - * These are currently stored in the .stack area in RAM, so there is no fixed address - * location that is used for this purpose. - * - * The Breakpoint feature assumes that the program is executed in RAM. It is not possible - * to set dynamic breakpoints for programs executed from Flash in the AT91SAM7S which lacks - * instruction breakpointing support in hardware without using JTAG. The only type of breakpoints - * that can be supported in Flash based programs are Static (predefined) breakpoints inserted into - * the code. - * - * Each Breakpoint State i is a struct comprising the Breakpoint Address + Memory Contents - * stored in 8 bytes as: - * [High Memory Address] - * ADDR [i*8+4]: Memory Contents (32 bits) - * ADDR [i*8]: Breakpoint Address (31 bits, b0 = THUMB flag [not implemented yet]) - * [Low Memory Address] - * - * A Non-zero Breakpoint Address means that the breakpoint is active, whereas the memory contents - * contains the instruction which resided at that address initially (now replaced by a BKPT - * instruction). - * Note: Currently it is not possible to resume execution of a program with breakpoints enabled - * after a RESET, since the RESET will clear all contents of the stack, destroying the instruction - * contained in a given breakpoint. - * Fortunately the NXT will also need to reload the program into RAM so this is not expected to be - * an issue. - * - * The Memory Map for the Debugger State is as follows: - * - * [High Memory Address] __breakpoints_end__ - * Breakpoint 07 State - * Breakpoint 06 State - * ... - * Breakpoint 02 State - * Breakpoint 01 State - * Single Step State __debugger_stack__ / __breakpoints_start__ - * Previous Mode R15 - * Previous Mode R14 - * Previous Mode R13 - * ... - * User Mode R02 - * User Mode R01 - * User Mode R00 - * Previous Mode CPSR (UNDEF SPSR) - * UNDEF Next Instr Addr __debugger_stack_bottom__ - * [Low Memory Address] - * - * Each Breakpoint State will initially be zeroed. - * - */ - /* FIXME: The Debugger Stack Frame is probably not 100% consistent with the order that - GDB expects in the g/G messages. CSPR is probably located above R15 */ - -/**************************************************************************** - * - * GDB Debugger Init and Breakpoint Handler Routines - * - ****************************************************************************/ - .code 32 - .align 4 -/* dbg__bkpt_init - * GDB set_debug_traps() routine - * On entry: - * None - * On exit: - * r0-r3: destroyed - */ - dbg_interwork dbg__bkpt_init - push {lr} - bl _dbg__clear_breakpoints - mov r2, #0 - ldr r1, =debug_curr_breakpoint - strb r2, [r1] - ldr r0, =debug_InMsgBuf - strb r2, [r0] - ldr r1, =debug_OutMsgBuf - strb r2, [r1] - bl dbg__comm_init /* Pass R0: Rx Buffer, R1: Tx Buffer to comm submodule */ - -/* FIXME: Initialize other stuff here */ - _dbg_setstate DBG_INIT - _dbg_setmode FALSE /* Debug Mode = False */ - pop {lr} - bx lr /* Must return via BX; may have been called from Thumb mode (NXT Firmware) */ - - -/* _dbg__flush_icache - * Flush the Instruction cache - * Defined by GDB Stub, but not needed for ARMv4T architecture - */ -_dbg__flush_icache: - /* nop */ - bx lr - -/* _dbg__switch2undefmode - * Common internal routine to return execution to user program - */ -_dbg__switch2undefmode: - bl _dbg__flush_icache - msr cpsr_c, #(MODE_UND | CPSR_FIQ | CPSR_IRQ) /* Configure Undef Mode */ - _dbg_setmode FALSE /* Debug Mode = False */ - ldr lr, =resume_execution - mov pc, lr /* Exit via UNDEF mode */ - -/* dbg__abort_exception_handler - * Handle Abort Exceptions - * On entry: - * r0: Abort Type Enum - * On exit: - * routine does not 'exit' in the normal sense - */ - dbg_interwork dbg__abort_exception_handler - _dbg_set_bkpt_type r0 /* Set Breakpoint Type given value in R0 */ - b dbg__bkpt_waitCMD - -/* dbg__thumb_bkpt_handler - * GDB handle_exception() routine (Thumb Mode) - * On entry: - * r0: Breakpoint index value - * On exit: - * routine does not 'exit' in the normal sense - */ - dbg_interwork dbg__thumb_bkpt_handler - /* On entry, r0 contains breakpoint index value */ - _dbg_setcurrbkpt_index r0 /* keep current breakpoint index in memory */ - ldr r1, =BKPT16_MANUAL_BKPT - teq r0, r1 - moveq r0, #DBG_MANUAL_BKPT_THUMB /* Manual Thumb Breakpoint, process it */ - beq _restore_normal_breakpoints - -_process_normal_breakpoint_thumb: - ldr r1, =__breakpoints_num__ - cmp r0, r1 /* Sanity check that index is in range */ - bhs dbg__bkpt_offset_outofrange /* Exceeded Offset Range */ - mov r0, #DBG_NORMAL_BKPT_THUMB /* It is a valid normal breakpoint */ - b _restore_normal_breakpoints - -/* dbg__arm_bkpt_handler - * GDB handle_exception() routine (ARM Mode) - * On entry: - * r0: breakpoint index value - * On exit: - * routine does not 'exit' in the normal sense - */ - dbg_interwork dbg__arm_bkpt_handler - /* On entry, r0 contains breakpoint index value */ - _dbg_setcurrbkpt_index r0 /* keep current breakpoint index in memory */ - ldr r1, =BKPT32_MANUAL_BKPT - teq r0, r1 - moveq r0, #DBG_MANUAL_BKPT_ARM /* Manual ARM Breakpoint, process it */ - beq _restore_normal_breakpoints - -_process_normal_breakpoint_arm: - ldr r1, =__breakpoints_num__ - cmp r0, r1 /* Sanity check that index is in range */ - bhs dbg__bkpt_offset_outofrange /* Exceeded Offset Range */ - mov r0, #DBG_NORMAL_BKPT_ARM /* It is a valid normal breakpoint */ -/* b _restore_normal_breakpoints */ - -_restore_normal_breakpoints: - _dbg_set_bkpt_type r0 /* Set Breakpoint Type given value in R0 */ - bl _dbg__restore_breakpoints /* includes restoring single step */ - bl _dbg__clear_singlestep - bl _dbg__flush_icache -/* b dbg__bkpt_waitCMD */ - -dbg__bkpt_inactive: -/* b dbg__bkpt_waitCMD */ - -dbg__bkpt_offset_outofrange: -/* b dbg__bkpt_waitCMD */ - -/* dbg__bkpt_waitCMD - * GDB Stub Remote Command Handler - */ - -/**************************************************************************** - * - * GDB Server Command Processing Routines - * - ****************************************************************************/ - dbg_interwork dbg__bkpt_waitCMD - /* We enter this code section when a Breakpoint Triggers */ - _dbg_setmode TRUE /* Debug Mode = True */ - msr cpsr_c, #(MODE_ABT) /* Re-enable Interrupts */ - - _dbg_getstate r0 - cmp r0, #DBG_CONFIGURED - blo dbg__bkpt_waitCMD_cont /* Not configured yet, don't send Breakpoint Signal Response */ - bl _dbg__cmd_Status /* Send signal response to the GDB server */ - -dbg__bkpt_waitCMD_cont: - bl dbg__runloopTasks /* Execute housekeeping tasks while in ABRT mode */ - bl dbg__getDebugMsg /* Read new message from Debugger, buflen in R0, 0 if none, -1 if error, msgbuf pointer in R1 */ - cmp r0, #0 - beq dbg__bkpt_waitCMD_cont /* No message yet, do housekeeping tasks */ - bgt _proc_command /* valid message, process it */ - bl __dbg__procChecksumError /* Message invalid, checksum error? */ - b dbg__bkpt_waitCMD_cont - -_proc_command: -/* Message now has Ctrl-C or $\0 */ - mov r4, r1 /* Use R4 as buffer pointer */ - ldrb r0, [r4], #1 /* Look for Ctrl-C or '$' */ - teq r0, #MSGBUF_CTRLC - bne _dbg_check_gdb_command - /* Ctrl-C detected, do nothing (wait for next command from GDB) */ -#if 0 - /* On entering the Debugger via Ctrl-C, _dbg__cmd_Status has already sent a reply, so just keep quiet */ - bl __dbg__procAckOnly /* send Ack */ -#endif - b dbg__bkpt_waitCMD_cont - -_dbg_check_gdb_command: - teq r0, #MSGBUF_STARTCHAR - movne r1, #MSG_ERRFORMAT /* Message Format invalid (not '$') */ - bne _dbg__cmdError /* Shouldn't happen */ - ldrb r0, [r4], #1 /* Look for command char */ - bl _dbg__cmdChar2Index /* Index in R0 */ - mov r1, #CMDINDEX_OUTOFRANGE - teq r0, r1 - bne _dbg__cmdExists /* Found valid command, execute it */ -_dbg_unknown_command: - bl _dbg__nop /* Command character not recognized, send empty response to GDB server */ - b dbg__bkpt_waitCMD_cont - -#if 0 - moveq r1, #MSG_UNKNOWNCMD /* Out of range, Command character not recognized */ - beq _dbg__cmdError /* Send response to GDB server */ -#endif - -_dbg__cmdExists: - mov r3, r0 /* put Command Handler Index in R3 */ - mov r0, r4 /* R0 now contains Input Message Buffer Parameter Pointer (previously in R4) */ - _dbg_jumpTableHandler debug_cmdJumpTable, r2, r3 /* Call Command Handler Routine, use R2 as jump address pointer */ - b dbg__bkpt_waitCMD_cont - -_dbg__cmdError: - _dbg_outputMsgStatusErr - bl dbg__putDebugMsg /* Send error response to the GDB server */ - b dbg__bkpt_waitCMD_cont - - -/* __dbg__procOkOnly - * Send OK to GDB due to Detach - * On entry: - * None - * On exit: - * r0-r3: destroyed - */ -__dbg__procOkOnly: - stmfd sp!, {lr} - _dbg_outputMsgStatusOk /* Acknowledge Detach command from GDB server */ -_cont_procOkOnly: - bl dbg__putDebugMsg /* Send OK response to the GDB server */ - cmp r0, #0 - beq _cont_procOkOnly_exit /* Sending of OK succeeded */ - bl dbg__runloopTasks /* Service run loop tasks */ - b _cont_procOkOnly /* Retry OK transmission */ -_cont_procOkOnly_exit: - ldmfd sp!, {pc} - - -/* __dbg__procAckOnly - * Send Ack to GDB due to Continue or Step - * On entry: - * None - * On exit: - * r0-r3: destroyed - */ -__dbg__procAckOnly: - stmfd sp!, {lr} - _dbg_outputAckOnlyFlag - b _cont_sendAckOrNak /* Acknowledge Continue or Step command from GDB server */ - -/* __dbg__procChecksumError - * Request Retransmission from GDB due to Checksum error - * On entry: - * None - * On exit: - * r0-r3: destroyed - */ -__dbg__procChecksumError: - stmfd sp!, {lr} - _dbg_outputRetransmitFlag - /* b _cont_sendAckOrNak */ /* Acknowledge Continue or Step command from GDB server */ - -_cont_sendAckOrNak: - bl dbg__sendAckOrNak /* send Ack or Nak to GDB server */ - cmp r0, #0 - beq _cont_sendAckOrNak_exit /* Sending of Ack or Nak succeeded */ - bl dbg__runloopTasks /* Service run loop tasks */ - b _cont_sendAckOrNak /* Retry Ack or Nak transmission */ -_cont_sendAckOrNak_exit: - ldmfd sp!, {pc} - -/* _dbg__cmdChar2Index - * Convert Command Character to Jump Table Index - * On entry: - * r0: command character - * On exit: - * r0: jump table index (-1 for command not found) - * R1: destroyed - * R2: destroyed - * R3: destroyed - */ -_dbg__cmdChar2Index: - mov r1, r0 /* Copy command character to r1 */ - mov r0, #0 /* Clear return value */ - ldr r3, =debug_cmdIndexTable /* Convert command to index using r3 as Index Lookup Address Pointer */ -1: ldrb r2, [r3, r0] /* Get table entry */ - teq r2, #0 - moveq r0, #CMDINDEX_OUTOFRANGE /* End of Index Table, Not found */ - beq _exit_cmdIndexTable - teq r1, r2 - addne r0, #1 /* Increment Index */ - bne 1b /* No match, skip to next command char */ -_exit_cmdIndexTable: - bx lr - -/* __dbg__cmdParamLen - * Determines the length of the parameter buffer for a given command - * On entry: - * R0: parameter buffer pointer (contents after '$' and '') - * On exit: - * R0: Address of parameter buffer (preserved) - * R1: length - */ -__dbg__cmdParamLen: - stmfd sp!, {r0,r2,lr} /* R2: scratch register */ - mov r1, #0 -1: ldrb r2, [r0], #1 - teq r2, #0 - addne r1, r1, #1 - bne 1b - ldmfd sp!, {r0,r2,pc} - -/* __dbg__procCmdOk - * Common subroutine exit stub to return Command Ok Status for Command Handlers - * DO NOT CALL THIS STUB DIRECTLY! It Assumes that the return address is in the stack. - * - */ -__dbg__procCmdOk: - _dbg_outputMsgStatusOk - b __dbg__sendDebugMsgExit - -/* __dbg__procUnimplementedError - * Common subroutine exit stub to handle Unimplemented GDB Command Error - * DO NOT CALL THIS STUB DIRECTLY! It Assumes that the return address is in the stack. - * Note: GDB Remote Protocol specifies returning blank message ('+$') - * - */ -__dbg__procUnimplementedError: - _dbg_outputMsgValidResponse - b __dbg__sendDebugMsgExit - -/* __dbg__procCmdParamError - * Common subroutine exit stub to handle Command Parameter Error for Command Handlers - * DO NOT CALL THIS STUB DIRECTLY! It Assumes that the return address is in the stack. - * - */ -__dbg__procCmdParamError: - mov r1, #MSG_UNKNOWNPARAM - b __dbg__procErrorMsg - -/* __dbg__procCmdReturnInputLengthError - * Common subroutine exit stub to handle Command Input Length Error for Command Handlers - * DO NOT CALL THIS STUB DIRECTLY! It Assumes that the return address is in the stack. - * - */ -__dbg__procCmdReturnInputLengthError: - mov r1, #MSG_ERRINLENGTH - b __dbg__procErrorMsg - -/* __dbg__procCmdReturnOutputLengthError - * Common subroutine exit stub to handle Command Return Output Error for Command Handlers - * DO NOT CALL THIS STUB DIRECTLY! It Assumes that the return address is in the stack. - * - */ -__dbg__procCmdReturnOutputLengthError: - mov r1, #MSG_ERROUTLENGTH - b __dbg__procErrorMsg - -/* __dbg__procBreakpointAddrError - * Common subroutine exit stub to handle Breakpoint Address Error for Breakpoint Insert/Remove Handlers - * DO NOT CALL THIS STUB DIRECTLY! It Assumes that the return address is in the stack. - * - */ -__dbg__procBreakpointAddrError: - mov r1, #MSG_UNKNOWNBRKPT -/* b __dbg__procErrorMsg */ - - -__dbg__procErrorMsg: - _dbg_outputMsgStatusErr - /* b __dbg__sendDebugMsgExit */ - -__dbg__sendDebugMsgExit: - bl dbg__putDebugMsg /* Send error response to the GDB server */ - ldmfd sp!, {pc} - -/* _dbg__cmd_Status - * Status Command Handler - * On entry: - * r0: parameter buffer (contents after '$' and '') - * On exit: - * r0, r1, r2, r3: destroyed - */ -_dbg__cmd_Status: - stmfd sp!, {lr} - _dbg_get_bkpt_type r0 -_check_data_abort_exception: - teq r0, #DBG_ABORT_DATA - moveq r1, #MSG_SIG_BUS /* Bus Error */ - beq _exit_dmg__cmd_Status -_check_prefetch_abort_exception: - teq r0, #DBG_ABORT_PREFETCH - moveq r1, #MSG_SIG_ABRT /* FIMXE: Look for a better Signal number */ - beq _exit_dmg__cmd_Status -_default_breakpoint_exception: - mov r1, #MSG_SIG_DEFAULT /* Dummy Signal number */ - -_exit_dmg__cmd_Status: - _dbg_outputMsgStatusSig - b __dbg__sendDebugMsgExit - -/* _dbg__cmd_Query - * Query Command Handler - * On entry: - * r0: parameter buffer (contents after '$' and '') - * [varied, see GDB General Packets query docs] - * http://sourceware.org/gdb/current/onlinedocs/gdb/General-Query-Packets.html - * On exit: - * r0, r1, r2, r3: destroyed - */ -_dbg__cmd_Query: - stmfd sp!, {r0,r1, lr} - _dbg_setstate DBG_CONFIGURED /* We have exchanged query messages with the GDB server */ - ldmfd sp!, {r0, r1} /* Restore parameters needed for subsequent processing */ - bl __dbg__cmdParamLen - cmp r1, #CMD_QUERY_MINPARAMLEN - beq _dbg__cmd_Query_default - - ldrb r2, [r0] /* Get First Query Param Char */ -_dbg__cmd_Query_check_C: - teq r2, #CMD_QUERY_CURRTID_CHAR /* Handle Current Thread ID Query */ - bne _dbg__cmd_Query_check_fThreadInfo - cmp r1, #CMD_QUERY_CURRTID_PARAMLEN - bne _dbg__cmd_Query_default - _dbg_outputMsgCurrTID - b __dbg__sendDebugMsgExit -_dbg__cmd_Query_check_fThreadInfo: - teq r2, #CMD_QUERY_FTINFO_CHAR /* Handle fThreadInfo Query */ - bne _dbg__cmd_Query_check_sThreadInfo - cmp r1, #CMD_QUERY_FTINFO_PARAMLEN - bne _dbg__cmd_Query_default - _dbg_outputMsgFirstThreadInfo - b __dbg__sendDebugMsgExit -_dbg__cmd_Query_check_sThreadInfo: - teq r2, #CMD_QUERY_STINFO_CHAR /* Handle sThreadInfo ID Query */ - bne _dbg__cmd_Query_default - cmp r1, #CMD_QUERY_STINFO_PARAMLEN - bne _dbg__cmd_Query_default - _dbg_outputMsgSubsequentThreadInfo - b __dbg__sendDebugMsgExit - -_dbg__cmd_Query_default: - b __dbg__procUnimplementedError /* FIXME: return an empty message to GDB (no modifiable settings) */ - - -/* _dbg__cmd_GetOneReg - * Get One Register Value Command Handler - * Valid command parameter x is from '0' to 'F' for User Mode Registers R0-R15, - * '18' for FPSCR (dummy), and '19' for CPSR - * On entry: - * r0: parameter buffer pointer (contents after '$' and '') - * x - * On exit: - * r0, r1, r2, r3, r4: destroyed - * - */ -_dbg__cmd_GetOneReg: - stmfd sp!, {lr} - bl __dbg__cmdParamLen - cmp r1, #CMD_REG_GETONE_MINPARAMLEN /* Check for correct length */ - blo __dbg__procCmdParamError /* Unexpected input, report error */ - cmp r1, #CMD_REG_GETONE_MAXPARAMLEN /* Check for correct length */ - bhi __dbg__procCmdParamError /* Unexpected input, report error */ - bl ascii2hex_varlen_be /* convert ASCII reg enum to Hex (in R0), R1 has address of next buffer char */ - -_dbg__proc_getRegister: - mov r4, r0 /* Keep register index safe */ - _dbg_outputMsgValidResponse /* R0: address of output message buffer data pointer (after response prefix) */ - mov r1, r4 /* Move register index value to R1 */ - bl _dbg_outputOneRegValue /* update output buffer */ - _asciiz r0, r1 - bl dbg__putDebugMsg /* Send response to the GDB server */ - ldmfd sp!, {pc} - -/* _dbg_outputOneRegValue - * Given Register Enum (0-F: R0-R15, 0x19: CPSR, OtherVal: dummy), output hex char to buffer - * On entry: - * r0: output message buffer pointer - * r1: register enum (0-F, 0x19) - * On exit: - * r0: updated (points to next character slot at end of Output Buffer) - * r1: original output message buffer pointer - * r2: destroyed - */ -_dbg_outputOneRegValue: - stmfd sp!, {lr} - cmp r1, #REG_PC - addls r2, r1, #DBGSTACK_USERREG_INDEX /* Convert register enum to Debug Stack index */ - bls _retrieve_RegVal - - cmp r1, #REG_CPSR - moveq r2, #DBGSTACK_USERCPSR_INDEX /* convert register enum to Debug Stack index */ - beq _retrieve_RegVal - - bhi _exit_dbg_outputOneRegValue /* No match (reg enum > REG_CPSR), skip */ - -#if 0 - cmp r1, #REG_FPSCR - bne _exit_dbg_outputOneRegValue /* No match, skip */ -#endif - -_output_dummy_regval: - /* Output Dummy Register value (for F0-F7, FPSR) */ - /* FIXME: F0-F7 expects output value that is more than 32-bits */ - mov r1, #0 - b _output2buffer /* Output all zeros for F0-F7, FPSCR */ - -_retrieve_RegVal: - _getdbgregisterfromindex r2, r1 /* Retrieve Register contents into R1 */ - -_output2buffer: - -#ifdef __BIG_ENDIAN__ - bl word2ascii_be /* Convert and put hex chars into Output Message Buffer */ -#else - bl word2ascii_le /* Convert and put hex chars into Output Message Buffer */ -#endif - -_exit_dbg_outputOneRegValue: - ldmfd sp!, {pc} - -/* _dbg__cmd_GetAllRegs - * Get All Register Values Command Handler - * Output Buffer returns register values in the order: User R0, R1, R2, ..., R15 - * On entry: - * r0: parameter buffer pointer (contents after '$' and '') - * (no parameters) - * On exit: - * r0, r1, r2, r3: destroyed - */ -_dbg__cmd_GetAllRegs: - stmfd sp!, {lr} - bl __dbg__cmdParamLen - teq r1, #CMD_REG_GETALL_PARAMLEN /* Check for correct length */ - bne __dbg__procCmdParamError /* Unexpected input, report error */ - - _dbg_outputMsgValidResponse /* R0: address of output message buffer data pointer (after response prefix) */ - - /* We must return R0-R15, then CPSR */ - mov r3, #REG_R0 /* Output User Register Values first */ -1: mov r1, r3 - bl _dbg_outputOneRegValue /* update output buffer */ - add r3, r3, #1 /* increment index */ - cmp r3, #REG_PC - bls 1b /* process all the registers */ -#if 0 -_get_cpsr: - /* GDB will query for CPSR value specifically */ - mov r1, #REG_CPSR /* Output User CPSR Value last */ - bl _dbg_outputOneRegValue /* update output buffer */ -#endif - _asciiz r0, r1 - bl dbg__putDebugMsg /* Send response to the GDB server */ - ldmfd sp!, {pc} - -/* _dbg_setOneRegValue - * Given Register Enum (0-F: R0-R15, 0x19: CPSR, OtherVal: dummy), output hex char to buffer - * On entry: - * r0: parameter buffer pointer - * r1: register enum (0-F, 0x19) - * On exit: - * r0: (Updated) Address of parameter in buffer - * r1, r2, r3: destroyed - * - * FIXME: This routine assumes that the input buffer contains exactly 8-Hex digits for each register value. - */ -_dbg_setOneRegValue: - stmfd sp!, {lr} - cmp r1, #REG_PC - addls r2, r1, #DBGSTACK_USERREG_INDEX /* Convert register enum to Debug Stack index */ - bls _store_RegVal - - cmp r1, #REG_CPSR - moveq r2, #DBGSTACK_USERCPSR_INDEX /* convert register enum to Debug Stack index */ - beq _store_RegVal - - bhi _exit_dbg_setOneRegValue /* No match (reg enum > REG_CPSR), skip */ - -#if 0 - cmp r1, #REG_FPSCR - bne _exit_dbg_setOneRegValue /* No match, skip */ -#endif - -_set_dummy_regval: - /* FIXME: This assumes that we will never get FP reg values (96-bits) in this routine */ - /* Set dummy FPSCR value (ignored) */ - add r1, r0, #CMD_REG_REGPARAMLEN /* Just increment the pointer */ - b _done_store_RegVal - -_store_RegVal: -#ifdef __BIG_ENDIAN__ - bl ascii2word_be -#else - bl ascii2word_le -#endif - /* R0: value, R1: pointer to next char in buffer */ - _setdbgregisterfromindex r2, r0, r3 /* Set Register contents in R0, using index in R2, and scratch register R3 */ -_done_store_RegVal: - mov r0, r1 /* Copy buffer pointer to next parameter to R0 for return value */ -_exit_dbg_setOneRegValue: - ldmfd sp!, {pc} - - -/* _dbg__cmd_SetOneReg - * Set One Register Value Command Handler - * Valid command parameter x is from '0' to 'F' for User Mode Registers R0-R15, - * '18' for FPSCR (dummy), and '19' for CPSR - * On entry: - * r0: parameter buffer pointer (contents after '$' and '') - * x=rrrr - * On exit: - * r0, r1, r2, r3, r4: destroyed - * - */ -_dbg__cmd_SetOneReg: - stmfd sp!, {lr} - bl __dbg__cmdParamLen - cmp r1, #CMD_REG_SETONE_MINPARAMLEN /* Check for correct length */ - blo __dbg__procCmdParamError /* Unexpected input, report error */ - cmp r1, #CMD_REG_SETONE_MAXPARAMLEN /* Check for correct length */ - bhi __dbg__procCmdParamError /* Unexpected input, report error */ - - /* FIXME: We can't set FP regs. - * Fortunately the values required by FP regs are 96 bits (24 nibbles) - * so it fails the CMD_REG_SETONE_MAXPARAMLEN check - */ - - bl ascii2hex_varlen_be /* convert ASCII reg enum to Hex (in R0), R1 has address of next buffer char */ - cmp r0, #REG_FPSCR - beq __dbg__procCmdParamError /* Don't allow setting of FPSCR */ - mov r4, r0 /* Keep enum in R4 */ - _check_msgassignment r1 /* R1 points to next char in buffer */ - bne __dbg__procCmdParamError /* Can't find '=' */ - -_dbg__proc_setRegister: - mov r0, r1 /* move parameter buffer pointer to R0 */ - mov r1, r4 /* and retrieve enum to R1 to call _dbg_setOneRegValue */ - bl _dbg_setOneRegValue - b __dbg__procCmdOk - -/* _dbg__cmd_SetAllReg - * Set All Register Values Command Handler - * On entry: - * r0: parameter buffer pointer (contents after '$' and '') - * rrrrRRRRrrrr... (17 registers) - * On exit: - * r0, r1, r2, r3, r4: destroyed - * - */ -_dbg__cmd_SetAllRegs: - /* Assumes that the registers are in the sequence R0, R1, ... R15 */ - stmfd sp!, {lr} - bl __dbg__cmdParamLen /* R0: pointer to parameters in buffer */ - teq r1, #CMD_REG_SETALL_PARAMLEN /* Check for correct length */ - bne __dbg__procCmdParamError /* Unexpected input, report error */ - mov r4, #REG_R0 /* R4: register enum, starting with enum for R0 */ -1: mov r1, r4 /* Copy enum to R1; R0 already points to current parameter */ - bl _dbg_setOneRegValue /* R0: next parameter address pointer */ - add r4, r4, #1 /* increment index */ - cmp r4, #REG_PC - bls 1b - - ldrb r0, [r0] - teq r0, #0 /* Look for ASCIIZ character to terminate loop */ - beq __dbg__procCmdOk - bne __dbg__procCmdParamError /* Unexpected input, report error */ - -/* _dbg__nop - * NOP Command Handler (placeholder) - * On entry: - * r0: parameter buffer (contents after '$' and '') - * On exit: - * r0, r1, r2, r3: destroyed - */ -_dbg__nop: - stmfd sp!, {lr} - b __dbg__procUnimplementedError - -/* _dbg__cmd_ReadMem - * Read Memory Contents Command Handler - * Output Buffer returns memory contents - * On entry: - * r0: parameter buffer pointer (contents after '$' and '') - * AA..AA,LLLL - * On exit: - * r0, r1, r2, r3, r4, r5: destroyed - */ -_dbg__cmd_ReadMem: - stmfd sp!, {lr} - bl __dbg__cmdParamLen -#if 0 - teq r1, #CMD_MEM_READ_PARAMLEN /* Check for correct length */ - bne __dbg__procCmdParamError /* Unexpected input, report error */ - bl ascii2word_be /* convert ASCII address location to Hex (in R0), R1 has address of next buffer char */ -#endif - bl ascii2hex_varlen_be /* convert ASCII address to Hex (in R0), R1 has address of next buffer char */ - mov r5, r0 /* Keep Address location in R5 */ - _check_msgseparator r1 - bne __dbg__procCmdParamError /* Can't find ',' */ - mov r0, r1 /* move buffer pointer to R0 for subsequent processing */ - bl ascii2hex_varlen_be /* convert ASCII length to Hex (in R0), R1 has address of next buffer char */ - cmp r0, #CMD_MEM_MAXREADBYTES /* Don't overflow our buffer (2 x CMD_MEM_MAXREADBYTES) */ - bhi __dbg__procCmdReturnOutputLengthError /* Requested Length greater than buffer size, return error */ - mov r4, r0 /* Keep numbytes in R4 */ - /* FIXME: Should validate the address? */ - - _dbg_outputMsgValidResponse /* R0: address of output message buffer data pointer (after response prefix) */ -1: ldrb r1, [r5], #1 - bl byte2ascii /* update output buffer */ - subs r4, r4, #1 - bne 1b - - _asciiz r0, r1 - bl dbg__putDebugMsg /* Send response to the GDB server */ - ldmfd sp!, {pc} - - -/* _dbg__cmd_WriteMem - * Write Memory Contents Command Handler - * On entry: - * r0: parameter buffer pointer (contents after '$' and '') - * AA..AA,LLLL::bb..bb - * On exit: - * r0, r1, r2, r3, r4: destroyed - */ -_dbg__cmd_WriteMem: - stmfd sp!, {lr} - bl __dbg__cmdParamLen -#if 0 - cmp r1, #CMD_MEM_WRITE_MINPARAMLEN /* Check for correct (minimum) length */ - blo __dbg__procCmdParamError /* Unexpected input, report error */ - sub r4, r1, #CMD_MEM_WRITE_MINPARAMLEN /* R4: Number of ASCII Hex chars for byte writes */ - bl ascii2word_be /* convert ASCII address location to Hex (in R0), R1 has address of next buffer char */ -#endif - bl ascii2hex_varlen_be /* convert ASCII address to Hex (in R0), R1 has address of next buffer char */ - mov r3, r0 /* Keep Address location in R3 */ - _check_msgseparator r1 - bne __dbg__procCmdParamError /* Can't find ',' */ - mov r0, r1 /* move buffer pointer to R0 for subsequent processing */ - bl ascii2hex_varlen_be /* convert ASCII length to Hex (in R0), R1 has address of next buffer char */ - cmp r0, r4, asr #1 /* is Number of bytes to write == (number of ASCII Hex Chars / 2)? */ - bne __dbg__procCmdParamError /* Number of bytes does not match argument length */ - cmp r0, #CMD_MEM_MAXWRITEBYTES /* Don't overflow our buffer (2 x CMD_MEM_MAXWRITEBYTES) */ - bhi __dbg__procCmdReturnInputLengthError /* Requested Length greater than buffer size, return error */ - mov r4, r0 /* Keep numbytes in R4 */ - /* FIXME: Should validate the address? */ - _check_msgargument r1 - bne __dbg__procCmdParamError /* Can't find ':' */ - -1: mov r0, r1 - bl ascii2byte /* convert ASCII Hex value into byte value */ - strb r0, [r3], #1 /* Store into memory location */ - subs r4, r4, #1 - bne 1b - b __dbg__procCmdOk - -/* _dbg__cmd_Detach - * Detach User Program Execution Command Handler - * Treat this as being equivalent to 'Continue' without any arguments - * - * On entry: - * r0: parameter buffer pointer (contents after '$' and '') - * (No Parameters) - * On exit: - * r0-r7: destroyed - * Note: This routine does not return to caller. Instead it switches - * operating mode to UNDEF and returns to previously active program - */ -_dbg__cmd_Detach: - stmfd sp!, {lr} /* In case unexpected parameters were received */ - bl __dbg__cmdParamLen - teq r1, #CMD_DETACH_PARAMLEN /* Check for correct length */ - bne __dbg__procCmdParamError /* Unexpected input, report error */ - - ldmfd sp!, {lr} /* Cleanup stack, since we won't return to the Debugger Run Loop */ - _dbg_setstate DBG_INIT /* Reset the Debug State */ - bl __dbg__procOkOnly /* send OK to keep GDB server happy */ - b _dbg__cont_check_breakpoint_type /* Continue from current PC */ - -/* _dbg__cmd_Continue - * Continue User Program Execution Command Handler - * Setup breakpoints before resuming execution of program. - * - * If Address is specified, update the next instruction address to specified address - * - * If this is a Normal Breakpoint, then we resume from current (Breakpoint) exception address - * Else (it is a Manual Breakpoint or Address Specified) - * We need to resume from the next instruction address - * On entry: - * r0: parameter buffer pointer (contents after '$' and '') - * Optional: AA..AA - * On exit: - * r0-r7: destroyed - * Note: This routine does not return to caller. Instead it switches - * operating mode to UNDEF and returns to previously active program - */ -_dbg__cmd_Continue: - /* Don't put anything on the stack, we won't return to the Debugger Run Loop */ - bl __dbg__cmdParamLen - cmp r1, #CMD_CONTINUE_MINPARAMLEN /* Check for correct parameter length */ - bne _dbg__cont_fromAddr /* Address is specified */ - bl __dbg__procAckOnly /* send Ack to keep GDB server happy */ - b _dbg__cont_check_breakpoint_type /* Continue from current PC */ - -_dbg__cont_fromAddr: - bl ascii2hex_varlen_be /* convert ASCII address to Hex (in R0), R1 has address of next buffer char */ - /* Continue from Specified Address */ - _setdbgregister DBGSTACK_NEXTINSTR_INDEX, r0, r1 /* Set Next Instruction Pointer for Resume using contents of R0, and scratch register R1 */ - bl __dbg__procAckOnly /* send Ack to keep GDB server happy */ - b _dbg__cont_is_manual_bkpt_or_address_specified - -_dbg__cont_check_breakpoint_type: - _dbg_get_bkpt_type r0 - teq r0, #DBG_MANUAL_BKPT_ARM - beq _dbg__cont_is_manual_bkpt_or_address_specified - teq r0, #DBG_MANUAL_BKPT_THUMB - beq _dbg__cont_is_manual_bkpt_or_address_specified - -_dbg__cont_is_normal_breakpoint: - _getdbgregister DBGSTACK_USERPC_INDEX, r0 /* Retrieve Aborted Instruction PC from the Debug Stack into R0 */ - _setdbgregister DBGSTACK_NEXTINSTR_INDEX, r0, r1 /* Set Next Instruction Pointer for Resume using contents of R0, and scratch register R1 */ - /* GDB knows to Step from a breakpointed instruction before continuing when - * Continue is issued, so it is safe to activate all defined breakpoints and continue. - */ -_dbg__cont_is_manual_bkpt_or_address_specified: - bl _dbg__activate_breakpoints /* Restore exisiting breakpoints */ - b _dbg__switch2undefmode - -/* _dbg__cmd_Step - * Step User Program Execution Command Handler - * Setup breakpoints before resuming execution of program. - * - * If Address is specified, update the next instruction address to specified address - * - * If this is a Normal Breakpoint, then we need to install a Step Breakpoint at next instruction address - * and resume from current (Breakpoint) exception address - * Else (it is a Manual Breakpoint or Address specified) - * We need to install a Step Breakpoint at the following instruction address (after the next instruction address) - * and resume from the next instruction address - * On entry: - * r0: parameter buffer pointer (contents after '$' and '') - * Optional: AA..AA - * On exit: - * r0-r7: destroyed - * Note: This routine does not return to caller. Instead it switches - * operating mode to UNDEF and returns to previously active program - */ -_dbg__cmd_Step: - /* Don't put anything on the stack, we won't return to the Debugger Run Loop */ - bl __dbg__cmdParamLen - cmp r1, #CMD_STEP_MINPARAMLEN /* Check for correct parameter length */ - beq _dbg__step_check_breakpoint_type /* Step from current PC */ - -_dbg__step_fromAddr: - bl ascii2hex_varlen_be /* convert ASCII address to Hex (in R0), R1 has address of next buffer char */ - /* Step from Specified Address */ - _setdbgregister DBGSTACK_NEXTINSTR_INDEX, r0, r1 /* Set Next Instruction Pointer for Resume using contents of R0, and scratch register R1 */ - b _dbg__step_is_manual_bkpt_or_address_specified - -_dbg__step_check_breakpoint_type: - _dbg_get_bkpt_type r0 - teq r0, #DBG_MANUAL_BKPT_ARM - beq _dbg__step_is_manual_bkpt - teq r0, #DBG_MANUAL_BKPT_THUMB - beq _dbg__step_is_manual_bkpt - -_dbg__step_is_normal_breakpoint: - _getdbgregister DBGSTACK_USERPC_INDEX, r0 /* Retrieve Aborted Instruction PC from the Debug Stack into R0 */ - _setdbgregister DBGSTACK_NEXTINSTR_INDEX, r0, r1 /* Set Next Instruction Pointer for Resume usinh contents in R0, and scratch register R1 */ - b _dbg__step_is_manual_bkpt_or_address_specified - -_dbg__step_is_manual_bkpt: - _getdbgregister DBGSTACK_NEXTINSTR_INDEX, r0 /* Retrieve Next Instruction Pointer for Resume into R1 */ - /* b _dbg__step_is_manual_bkpt_or_address_specified */ - -_dbg__step_is_manual_bkpt_or_address_specified: - bl dbg_following_instruction_addr /* following instruction address returned in r1 */ - bl dbg__install_singlestep /* Setup Single Step, next instruction address returned in r1 */ - bl dbg__activate_singlestep -#if 0 - /* Disable ACK transmit, let the next Breakpoint generate the Signal Response */ - bl __dbg__procAckOnly /* send Ack to keep GDB server happy */ -#endif - b _dbg__switch2undefmode - -/* _dbg__cmd_Kill - * Kill User Program Execution Command Handler - * Kill Program, this is accomplished by rebooting the Brick - * - * On entry: - * r0: parameter buffer pointer (contents after '$' and '') - * (No Parameters) - * On exit: - * r0-r7: destroyed - * Note: This routine does not return to caller. Instead it calls - * the relevant system routine to reboot the Brick - */ -_dbg__cmd_Kill: - stmfd sp!, {lr} /* In case unexpected parameters were received */ - bl __dbg__cmdParamLen - teq r1, #CMD_KILL_PARAMLEN /* Check for correct length */ - bne __dbg__procCmdParamError /* Unexpected input, report error */ - - bl __dbg__procAckOnly /* send Ack to keep GDB server happy */ - b dbg__reboot /* Goodbye.... */ - -/* _dbg__proc_brkpt_params - * Process Breakpoint Parameters - * On entry: - * r0: parameter buffer pointer (contents after '$' and '') - * t,AA..AA,k - * On exit: - * r0: non-zero = breakpoint address; 0 = parameter error - * r1: destroyed - * r2: destroyed - * r3: destroyed - */ -_dbg__proc_brkpt_params: - /* FIXME: Add support for watchpoints */ - stmfd sp!, {lr} - mov r3, r0 /* Keep parameter buffer address in R3 */ - ldrb r0, [r3], #1 /* get breakpoint type t */ - bl char2hex - cmp r0, #CMD_BKPT_TYPE_BREAK_MEMORY - bne _dbg__proc_brkpt_params_error /* We only support memory breakpoints for now */ - _check_msgseparator r3 - bne _dbg__proc_brkpt_params_error /* Something wrong with the parameters */ - mov r0, r3 /* Check Address */ - bl ascii2hex_varlen_be /* convert ASCII address to Hex (in R0), R1 has address of next buffer char */ - mov r3, r0 /* Keep breakpoint address in R3 */ - _check_msgseparator r1 - bne _dbg__proc_brkpt_params_error /* Something wrong with the parameters */ - ldrb r0, [r1], #1 /* get breakpoint kind k */ - bl char2hex - cmp r0, #CMD_BKPT_KIND_THUMB - orreq r3, r3, #1 /* Mark Thumb breakpoints */ - beq _exit_dbg__proc_brkpt_params - cmp r0, #CMD_BKPT_KIND_ARM - beq _exit_dbg__proc_brkpt_params /* ARM breakpoint */ - -_dbg__proc_brkpt_params_error: - mov r3, #0 /* Unrecognized breakpoint type */ -_exit_dbg__proc_brkpt_params: - mov r0, r3 /* return breakpoint address */ - ldmfd sp!, {pc} - -/* _dbg__cmd_InsertBreakpoint - * Add Breakpoint - * On entry: - * r0: parameter buffer pointer (contents after '$' and '') - * t,AA..AA,k - * On exit: - * r0, r1, r2, r3: destroyed - */ -_dbg__cmd_InsertBreakpoint: - stmfd sp!, {lr} - bl __dbg__cmdParamLen - teq r1, #CMD_BKPT_INSERT_MINPARAMLEN /* Check for correct length */ - blo __dbg__procCmdParamError /* Unexpected input, report error */ - bl _dbg__proc_brkpt_params /* R0: Breakpoint Address */ - teq r0, #0 - beq __dbg__procBreakpointAddrError /* Thumb2 instructions, or unknown kind */ - mov r3, r0 /* Keep breakpoint address in R3 */ - mov r0, #0 /* Empty Breakpoint entry */ - bl _dbg_find_breakpoint_slot /* Look for an available breakpoint slot, return index in R0 */ - cmp r0, #CMD_BKPT_NOTFOUND - beq __dbg__procBreakpointAddrError /* No empty slot! */ - mov r1, r3 /* Move breakpoint address to R1 */ - bl _dbg__install_one_breakpoint /* r0: index, r1: instruction address */ - b __dbg__procCmdOk - -/* _dbg__cmd_RemoveBreakpoint - * Remove Breakpoint - * On entry: - * r0: parameter buffer pointer (contents after '$' and '') - * t,AA..AA,k - * On exit: - * r0, r1, r2, r3: destroyed - */ -_dbg__cmd_RemoveBreakpoint: - stmfd sp!, {lr} - bl __dbg__cmdParamLen - teq r1, #CMD_BKPT_REMOVE_MINPARAMLEN /* Check for correct length */ - blo __dbg__procCmdParamError /* Unexpected input, report error */ - bl _dbg__proc_brkpt_params /* R0: Breakpoint Address */ - teq r0, #0 - beq __dbg__procBreakpointAddrError /* Thumb2 instructions, or unknown kind */ - bl _dbg_find_breakpoint_slot /* Look for matching breakpoint slot, return index in R0 */ - cmp r0, #CMD_BKPT_NOTFOUND - beq __dbg__procBreakpointAddrError /* Specified Breakpoint not found! */ - _index2bkptindex_addr r0, r1 /* Calculate Breakpoint Entry Address */ - mov r0, r1 /* Move it to R0 for subroutine call */ - bl _dbg__clear_one_breakpoint /* R0: address of breakpoint to clear */ - b __dbg__procCmdOk - -/**************************************************************************** - * - * Breakpoint Manipulation Routines - * - ****************************************************************************/ -/* _dbg_find_breakpoint_slot - * Find the matching Breakpoint Slot. - * This is both used to find empty slots (pass R0=0x0000) or - * occupied slots (pass R0=) - * - * On Entry: - * R0: Breakpoint Address - * On Exit: - * R0: Matching Index (-1: not found) - * - * NOTE: This routine performs exact match, i.e., breakpoint address MUST be configured - * for ARM or Thumb (bit 0 clear/set) as appropriate - */ - -_dbg_find_breakpoint_slot: - stmfd sp!, {r1,r2,r3, lr} - mov r1, #1 /* Only consider Breakpoints 1-7 */ - ldr r3, =__breakpoints_num__ -1: - _index2bkptindex_addr r1, r2 /* Calculate Breakpoint Entry Address */ - ldr r2, [r2] /* Get actual breakpoint entry (instruction address) */ - cmp r0, r2 - beq _found_breakpoint_slot - add r1, r1, #1 /* no match, check next */ - cmp r1, r3 - blo 1b /* continue checking only if we don't exceed __breakpoints_num__ */ - -_notfound_breakpoint_slot: - mov r1, #CMD_BKPT_NOTFOUND -_found_breakpoint_slot: - mov r0, r1 /* Return value in R0 */ - ldmfd sp!, {r1,r2,r3, pc} - -/* _dbg__clear_singlestep - * Clear the Single Step Breakpoint - */ -_dbg__clear_singlestep: - ldr r0, =__breakpoints_start__ /* Single Step Breakpoint is at the beginning of the Breakpoint State Struct */ -/* b _dbg__clear_one_breakpoint */ - -/* _dbg__clear_one_breakpoint - * On entry, R0 contains the Breakpoint State slot address to be cleared - * - */ -_dbg__clear_one_breakpoint: - mov r1, #0 - mov r2, #0 - stmea r0!, {r1, r2} /* clear Breakpoint state */ - bx lr - -/* _dbg__clear_breakpoints - * Routine iterates through the array of breakpoints (incl single step breakpoint) and clears the breakpoint - */ -_dbg__clear_breakpoints: - stmfd sp!, {lr} - ldr r0, =__breakpoints_start__ /* Single Step Breakpoint is at the beginning of the Breakpoint State Struct */ - ldr r3, =__breakpoints_end__ /* start from top of the table */ -3: bl _dbg__clear_one_breakpoint - cmp r0, r3 - blo 3b - ldmfd sp!, {pc} - -/* dbg__install_singlestep - * Install the Single Step Breakpoint - * - * On entry: - * R1: Instruction Address (31 bits, b0 = THUMB flag) - * On exit: - * R0: Breakpoint index (preserved) - * R1: Instruction Address (preserved) - * R2: Breakpoint Instruction - * R3: Breakpoint Entry address - */ - dbg_interwork dbg__install_singlestep - mov r0, #0 -/* b _dbg__install_one_breakpoint */ - -/* _dbg__install_one_breakpoint - * Install breakpoint entry into Breakpoint State Table - * - * On entry: - * R0: Breakpoint index (assumed valid) - * R1: Instruction Address (31 bits, b0 = THUMB flag) - * On exit: - * R0: Breakpoint index (preserved) - * R1: Instruction Address (preserved) - * R2: Breakpoint Instruction - * R3: Breakpoint Entry address - */ -_dbg__install_one_breakpoint: -/* Check for Thumb bit */ - tst r1, #BKPT_STATE_THUMB_FLAG /* 1: Thumb instruction */ -/* Assume that the address entry is valid, otherwise we should sanitize it (mask out b1) */ - bic r2, r1, #BKPT_STATE_THUMB_FLAG /* R2: Instruction Address; clear Thumb Flag for accessing Memory */ - ldreq r2, [r2] /* if 0: load ARM instruction from address location */ - ldrneh r2, [r2] /* else load Thumb instruction */ - _index2bkptindex_addr r0, r3 /* Calculate Breakpoint Entry Address */ - stm r3, {r1, r2} - bx lr - - -/* _dbg__restore_singlestep - * Restores the contents of the single step breakpoint to memory - * - * On entry: - * None - * On exit: - * R0-R2: Destroyed - */ -_dbg__restore_singlestep: - mov r0, #0 /* single step breakpoint index */ - _index2bkptindex_addr r0, r1 /* Calculate Single Step Breakpoint Entry Address */ - ldm r1, {r1, r2} /* r1: Breakpoint Address, r2: Breakpoint Instruction */ - teq r1, #0 - bxeq lr /* Exit if not active */ -/* b _dbg__restore_one_breakpoint */ - -/* _dbg__restore_one_breakpoint - * Restores the contents to memory for one breakpoint - * - * On entry: - * R0: Breakpoint index (assumed valid) [not used -- can be used for validating BKPT] - * R1: Breakpoint Address (assumed valid) - * R2: Breakpoint Instruction (assumed valid) - * On exit: - * R0: Breakpoint index (preserved) - * R1: B0 cleared if Thumb Instruction Address - * R2: Breakpoint Instruction (preserved) - */ -_dbg__restore_one_breakpoint: -/* Check for Thumb bit */ - tst r1, #BKPT_STATE_THUMB_FLAG /* 1: Thumb instruction */ -/* Assume that the address entry is valid, otherwise we should sanitize it (mask out b1) */ - streq r2, [r1] /* if 0: restore ARM instruction to address location */ - bicne r1, #BKPT_STATE_THUMB_FLAG /* else, clear Thumb Flag */ - strneh r2, [r1] /* store Thumb instruction */ - bx lr - -/* _dbg__restore_breakpoints - * Routine iterates through the array of breakpoints (incl single step breakpoint) and restores the contents to memory - * Only Active breakpoints (i.e., Non-zero Address) are processed. - * - * On entry: - * None - * On exit: - * R0-R6: Destroyed - */ -_dbg__restore_breakpoints: - stmfd sp!, {lr} - ldr r6, =_dbg__restore_one_breakpoint - b __dbg__iterate_breakpoint_array - -/* dbg__activate_singlestep - * Activate the single step breakpoint to memory - * - * On entry: - * None - * On exit: - * R0-R3: Destroyed - */ - dbg_interwork dbg__activate_singlestep - mov r0, #0 /* single step breakpoint index */ - _index2bkptindex_addr r0, r1 /* Calculate Single Step Breakpoint Entry Address */ - ldm r1, {r1, r2} /* r1: Breakpoint Address, r2: Breakpoint Instruction */ - teq r1, #0 - bxeq lr /* Exit if not active */ -/* b _dbg__activate_one_breakpoint */ - -/* _dbg__activate_one_breakpoint - * Activate one breakpoint to memory - * - * On entry: - * R0: Breakpoint index (assumed valid) - * R1: Breakpoint Address (assumed valid) - * R2: Breakpoint Instruction (assumed valid) - * On exit: - * R0: Breakpoint index (preserved) - * R1-R3: Destroyed - */ -_dbg__activate_one_breakpoint: -/* Check for Thumb bit */ - tst r1, #BKPT_STATE_THUMB_FLAG /* 1: Thumb instruction */ - bne _nx_is_thumb_bp -_nx_is_arm_bp: -/* Assume that the address entry is valid, otherwise we should sanitize it (mask out b1) */ - ldr r3, [r1] /* if 0: load ARM instruction from address location */ - teq r2, r3 /* check that the two instructions are identical */ - bne _dbg__breakpoint_invalid_arm - ldr r2, =BKPT32_INSTR /* ARM BKPT instruction */ - orr r2, r2, r0 /* Merge Breakpoint index */ - str r2, [r1] /* Store it into memory location */ -_dbg__breakpoint_invalid_arm: - bx lr -_nx_is_thumb_bp: - bic r1, #BKPT_STATE_THUMB_FLAG /* else, clear Thumb Flag */ - ldrh r3, [r1] /* load Thumb instruction from address location */ - teq r2, r3 /* check that the two instructions are identical */ - bne _dbg__breakpoint_invalid_thumb - ldr r2, =BKPT16_INSTR /* Thumb BKPT instruction */ - orr r2, r2, r0 /* Merge Breakpoint index */ - strh r2, [r1] /* Store it into memory location */ -_dbg__breakpoint_invalid_thumb: - bx lr - -/* _dbg__activate_breakpoints - * Routine iterates through the array of breakpoints (incl single step breakpoint) and activates them - * Only Active breakpoints (i.e., Non-zero Address) are processed. - * - * On entry: - * None - * On exit: - * R0-R6: Destroyed - */ -_dbg__activate_breakpoints: - stmfd sp!, {lr} - ldr r6, =_dbg__activate_one_breakpoint - b __dbg__iterate_breakpoint_array - - -/* __dbg__iterate_breakpoint_array - * WARNING: DO NOT CALL THIS ROUTINE DIRECTLY. - * Internal Routine, assumes that lr has been push to stack - * - * Common routine to iterate through the array of breakpoints (incl single step breakpoint) - * Only Active breakpoints (i.e., Non-zero Address entries) are processed. - * - * On Entry: - * R0: Breakpoint index - * R1: Breakpoint Address - * R2: Breakpoint Instruction - * R6: Handler Routine - * On exit: - * R0-R5: Destroyed - * R6: Handler routine (preserved) - * - */ -__dbg__iterate_breakpoint_array: - ldr r5, =__breakpoints_end__ /* start from top of the table (Assume __breakpoints_end__ > __breakpoints_start__) */ - ldr r4, =__breakpoints_start__ /* end address check */ - ldr r0, =__breakpoints_num__ /* Number of Breakpoints (incl Single Step) (Assume Non-Zero) */ -4: sub r0, r0, #1 /* Decrement breakpoint index in r0 */ - ldmea r5!, {r1, r2} /* r1: Breakpoint Address, r2: Breakpoint Instruction */ - teq r1, #0 /* Is it active? */ - movne lr, pc - bxne r6 /* active entry */ - cmp r5, r4 - bhi 4b /* if (pointer > start of Breakpoint Table address), get next slot */ - ldmfd sp!, {pc} - diff --git a/AT91SAM7S256/armdebug/Debugger/debug_stub.h b/AT91SAM7S256/armdebug/Debugger/debug_stub.h deleted file mode 100644 index 2430e77..0000000 --- a/AT91SAM7S256/armdebug/Debugger/debug_stub.h +++ /dev/null @@ -1,165 +0,0 @@ -/** @file debug_stub.h - * @brief Shared C/ASM header file for debugger stub - * - */ - -/* Copyright (C) 2007-2010 the NxOS developers - * - * Module Developed by: TC Wan - * - * See AUTHORS for a full list of the developers. - * - * See COPYING for redistribution license - * - */ - -#ifndef __DEBUG_STUB_H__ -#define __DEBUG_STUB_H__ - -#include "_c_arm_macros.h" - -/** @name BKPT suppport constants - * - * ARM and Thumb Breakpoint Instructions. - */ -/*@{*/ - -#define __ARM6OR7__ - -#ifdef __ARM6OR7__ -#define BKPT32_INSTR 0xE7200070 /* ARM6 and ARM7 does not trap unused opcodes (BKPT overlap with control instructions), \ - CPU has unpredictable behavior. Ref: Steve Furber, ARM SoC Architecture 2nd Ed, pg. 143 */ -#else -#define BKPT32_INSTR 0xE1200070 /* ARM BKPT instruction, will work in ARMv5T and above */ -#endif - -#define BKPT32_ENUM_MASK 0x000FFF0F /* ARM BKPT Enum Mask */ -#define BKPT32_AUTO_BKPT 0x00080000 /* RESERVED: ARM BKPT Auto-Step Flag (for CONT support) */ -#define BKPT32_MANUAL_BKPT 0x0007FF0F /* Manually inserted ARM Breakpoint */ - -#define BKPT16_INSTR 0xBE00 /* Thumb BKPT instruction */ -#define BKPT16_ENUM_MASK 0x00FF /* Thumb BKPT Enum Mask */ -#define BKPT16_AUTO_BKPT 0x0080 /* RESERVED: Thumb BKPT Auto-Step Flag (for CONT support) */ -#define BKPT16_MANUAL_BKPT 0x007F /* Manually inserted Thumb Breakpoint */ -/*@}*/ - -#ifndef __ASSEMBLY__ - -/* Define C stuff */ -/** @defgroup debug_public */ -/*@{*/ - - -/** Initialize Debugger. - * Equivalent to GDB set_debug_traps() routine - */ -FUNCDEF void dbg__bkpt_init(void); - -#ifdef __NXOS__ - -/** Communication Channel Enums - * - * Communication Channel Enums. - */ -ENUM_BEGIN -ENUM_VALASSIGN(COMM_USB, 1) /**< USB Communications */ -ENUM_VAL(COMM_BT) /**< Bluetooth Communications */ -ENUM_END(comm_chan_t) - -/** Enable switch to Debugger Mode from NxOS operational mode - * Returns 0 if no mode switch needed (already in Debug mode) - * !0 if mode switch will happen - * Used by NxOS only - */ -/* Note: This platform specific routine is found in debug_runlooptasks.S */ -FUNCDEF int nxos__handleDebug(U8 *buffer, comm_chan_t channel, U32 length); -#else -/** Switch Mode to Debugger. - * Used by NXT Firmware only - */ -/* Note: This platform specific routine is found in debug_runlooptasks.S */ -FUNCDEF UWORD cCommHandleDebug(UBYTE *pInBuf, UBYTE CmdBit, UWORD MsgLength); -#endif - -/** Debugger Handler Routine (called by Exception Handler Trap). - * Equivalent to GDB handle_exception() routine - */ -FUNCDEF void dbg__bkpt_handler(void); - -/** dbg_breakpoint_arm. - * Equivalent to GDB breakpoint() routine for ARM code - */ -/* FUNCDEF void dbg_breakpoint_arm(void); */ -static inline void dbg_breakpoint_arm(void) -{ - asm volatile (".word %a0" - : /* Output (empty) */ - : "X" (BKPT32_INSTR | BKPT32_MANUAL_BKPT) - ); -} - -#if 0 /* Old asm definitions, in case gas does not recognize %a0 operand */ - -#ifdef __ARM6OR7__ -static inline void dbg_breakpoint_arm(void) { asm volatile (".word 0xE727FF7F" /* (BKPT32_INSTR | BKPT32_MANUAL_BKPT) */ ); } -#else -static inline void dbg_breakpoint_arm(void) { asm volatile (".word 0xE127FF7F" /* (BKPT32_INSTR | BKPT32_MANUAL_BKPT) */ ); } -#endif - -#endif - -/** dbg_breakpoint_thumb. - * Equivalent to GDB breakpoint() routine for Thumb code - */ -/* FUNCDEF void dbg_breakpoint_thumb(void); */ -static inline void dbg_breakpoint_thumb(void) -{ - asm volatile (".hword %a0" - : /* Output (empty) */ - : "X" (BKPT16_INSTR | BKPT16_MANUAL_BKPT) - ); -} - -#if 0 /* Old asm definitions, in case gas does not recognize %a0 operand */ - -static inline void dbg_breakpoint_thumb(void) { asm volatile (".hword 0xBE7F" /* (BKPT16_INSTR | BKPT16_MANUAL_BKPT) */); } - -#endif - -/*@}*/ - -#else -/* Define Assembly stuff */ - -/* dbg__bkpt_arm - * GDB breakpoint() for ARM mode - */ - .macro dbg__bkpt_arm - .word (BKPT32_INSTR | BKPT32_MANUAL_BKPT) - .endm - -/* dbg__bkpt_thumb - * GDB breakpoint() for Thumb mode - */ - .macro dbg__bkpt_thumb - .hword (BKPT16_INSTR | BKPT16_MANUAL_BKPT) - .endm - -/** Macro to declare Interworking ARM Routine - * - * dbg_interwork - * - * Note: declared as a private macro since ARMDEBUG is also used by NIF - */ - .macro dbg_interwork arm_routine - .align 4 - .arm - .type \arm_routine, %function @ Needed by new binutils (>2.21) - .global \arm_routine -\arm_routine: - .endm - -#endif - /*@}*/ - -#endif /* __DEBUG_STUB_H__ */ diff --git a/AT91SAM7S256/armdebug/Debugger/debug_test.S b/AT91SAM7S256/armdebug/Debugger/debug_test.S deleted file mode 100644 index 2cb87a0..0000000 --- a/AT91SAM7S256/armdebug/Debugger/debug_test.S +++ /dev/null @@ -1,161 +0,0 @@ -/** @file debug_test.S - * @brief Test Routines to trigger ARM and Thumb Manual Breakpoints - * - */ - -/* Copyright (C) 2007-2011 the NxOS developers - * - * Module Developed by: TC Wan - * - * See AUTHORS for a full list of the developers. - * - * See COPYING for redistribution license - * - */ -#define __ASSEMBLY__ -#include "debug_stub.h" - -.text -.align 4 -.code 32 - -/********************************************** - * dbg__test_arm_bkpt Test Routine - * - */ - dbg_interwork dbg__test_arm_bkpt - stmfd sp!,{lr} - dbg__bkpt_arm /* Trigger ARM Manual Breakpoint */ - ldmfd sp!,{pc} - - -/********************************************** - * dbg__test_arm_instrstep Test Routine - * Used to test GDB Stepping command - * This routine exercises the mov, add, ldr, ldm, b, bl, - * and bx instructions which modify the PC (R15) - * In addition, conditional instructions are also evaluated. - * - */ - dbg_interwork dbg__test_arm_instrstep - stmfd sp!, {lr} - bl dbg__test_arm_instr_sub1 - ldr r1, =test_arm_3 /* R1: pointer to test_arm_3 */ - ldr r2, =test_arm_2 /* R2: pointer to test_arm_2 */ - mov pc, r1 - -test_arm_1: - subs r0, r0, #1 - addne pc, r2, #4 /* If R0 > 0, keep branching to a new location */ - /* else R0 == 0 */ - b exit_dbg__test_arm_instrstep - -test_arm_2: - sub r0, r0, #1 - cmp r0, #5 - bgt test_arm_1 - ldrle pc, =exit_dbg__test_arm_instrstep - b exit_dbg__test_arm_instrstep - -test_arm_3: - sub r0, r0, #1 - teq r0, #8 - beq test_arm_1 - ldrne r3, =test_arm_3 - bx r3 - -exit_dbg__test_arm_instrstep: - bl dbg__test_thumb_instr_sub1 - ldmfd sp!, {pc} - - .global dbg__test_arm_instr_sub1 -dbg__test_arm_instr_sub1: - mov r0, #10 - bx lr - - .global dbg__test_arm_instr_sub1 -dbg__test_arm_instr_sub2: - stmfd sp!, {r4, lr} - mov r0, #TRUE - ldmfd sp!, {r4, pc} - -/********************************************** - * dbg__test_thumb_bkpt Test Routine - * - */ - dbg_interwork dbg__test_thumb_bkpt - stmfd sp!,{lr} -/* ldr r0, =_thumb_entry - orr r0, r0, #1 @ Set Thumb mode - mov lr, pc - bx r0 -*/ - bl _thumb_entry - ldmfd sp!,{pc} - -.code 16 - .thumb_func - .type _thumb_entry, %function -_thumb_entry: - dbg__bkpt_thumb - bx lr - - -/********************************************** - * dbg__test_thumb_instrstep Test Routine - * Used to test GDB Stepping command - * - */ - .global dbg__test_thumb_instrstep - .thumb_func - .type dbg__test_thumb_instrstep, %function -dbg__test_thumb_instrstep: - push {lr} - bl dbg__test_thumb_instr_sub1 - bl dbg__test_thumb_instr_sub2 - -test_thumb_1: - sub r0, #1 - bne test_thumb_2 - /* else R0 == 0 */ - b exit_dbg__test_thumb_instrstep - -test_thumb_2: - sub r0, #1 - cmp r0, #5 - bls test_thumb_1 - bhi test_thumb_3 - beq test_thumb_2 - b test_thumb_1 - -test_thumb_3: - sub r0, #1 - cmp r0, #0xB - blo load_test_thumb_1 - ldr r2, =test_thumb_3+1 /* Need to set Thumb bit */ - b exit_test_thumb_3 -load_test_thumb_1: - ldr r2, =test_thumb_1+1 /* Need to set Thumb bit */ -exit_test_thumb_3: - bx r2 - -exit_dbg__test_thumb_instrstep: - bl dbg__test_arm_instr_sub1 - pop {r1} - bx r1 - - .thumb_func - .type dbg__test_thumb_instr_sub1, %function -dbg__test_thumb_instr_sub1: - mov r0, #0x0F - bx lr - - .thumb_func - .type dbg__test_thumb_instr_sub2, %function -dbg__test_thumb_instr_sub2: - push {lr} - mov r1, #FALSE - pop {pc} - - -.end diff --git a/AT91SAM7S256/armdebug/Debugger/debug_test.h b/AT91SAM7S256/armdebug/Debugger/debug_test.h deleted file mode 100644 index b8e6634..0000000 --- a/AT91SAM7S256/armdebug/Debugger/debug_test.h +++ /dev/null @@ -1,50 +0,0 @@ -/** @file debug_test.h - * @brief C header file for debugger test routines - * - */ - -/* Copyright (C) 2007-2010 the NxOS developers - * - * Module Developed by: TC Wan - * - * See AUTHORS for a full list of the developers. - * - * See COPYING for redistribution license - * - */ - -#ifndef __DEBUG_TEST_H__ -#define __DEBUG_TEST_H__ - -#include "_c_arm_macros.h" - -#ifndef __ASSEMBLY__ - -/* Define C stuff */ -/** @defgroup debug_public */ -/*@{*/ - -/** - * Insert ARM Breakpoint instruction into code stream - */ -FUNCDEF void dbg__test_arm_bkpt(void); -/** - * Insert Thumb Breakpoint instruction into code stream - */ -FUNCDEF void dbg__test_thumb_bkpt(void); - -/** - * Dummy function for testing ARM instruction stepping - */ -FUNCDEF void dbg__test_arm_instrstep(void); -/** - * Dummy function for testing Thumb instruction stepping - */ -FUNCDEF void dbg__test_thumb_instrstep(void); - - /*@}*/ - -#endif - - -#endif /* __DEBUG_TEST_H__ */ diff --git a/AT91SAM7S256/armdebug/Debugger/undef_handler.S b/AT91SAM7S256/armdebug/Debugger/undef_handler.S deleted file mode 100644 index cfbaae3..0000000 --- a/AT91SAM7S256/armdebug/Debugger/undef_handler.S +++ /dev/null @@ -1,144 +0,0 @@ - -/* Copyright (C) 2007-2010 the NxOS developers - * - * Module Developed by: TC Wan - * - * See AUTHORS for a full list of the developers. - * - * Redistribution of this file is permitted under - * the terms of the GNU Public License (GPL) version 2. - */ -#define __ASSEMBLY__ -#include "debug_stub.h" -#include "debug_internals.h" - - -.text -.code 32 -.align 0 - - .extern dbg__thumb_bkpt_handler - .extern dbg__arm_bkpt_handler - .extern default_undef_handler - -/* Remote GDB Debugger relies on BKPT instruction being trapped here - * In ARMv4t, it is an Illegal (Undefined) Instruction. - * On triggering, lr (R14) contains the previous mode's pc (R15). - * Based on example in Hohl, "ARM Assembly Language: Fundamentals and Techniques" - * Chapter 11, Example 11.1. - */ - /** undef_handler - * We assume that the DEBUG stack holds only one stack frame and we will overwrite it. - * On entry, LR_undef points to one instruction past the UNDEF instruction. - * - * For the purpose of Debugging, the stack frame should present the PC (R15) as the address - * of the instruction that triggered the Breakpoint. Hence we need to adjust R15 - * to point to the address of the UNDEF instruction. This is what the JTAG debugger - * does. - * - * We will also store UNDEF LR (next instruction pointer) and UNDEF SPSR to the stack. - * - * For the handler, once the user registers have been stored in the DEBUG stack, the - * registers will be used as follows: - * - * R0: UNDEF LR, then UNDEF instruction address, finally UNDEF instruction word / BKPT index - * R1: SPSR - * R2: Mode - * R3: Debug Stack Pointer (for Banked R13-R14 update) - */ - dbg_interwork undef_handler - ldr sp, =__debugger_stack__ - stmfd sp, {r0-r15}^ /* Save workspace, previous mode's pc via 'S' flag, R13-R15: placeholders */ - mov r3, sp /* Use R3 to write Banked R13-R14, and actual PC of UNDEF instruction */ - sub sp, sp, #(4*16) /* Need to manually update SP(undef) */ - - mov r0, lr /* Keep Next Instruction address after UNDEF instruction in R0 */ - mrs r1, spsr /* Copy SPSR to r1 */ - stmfd sp!, {r0,r1} /* Save User's Next Instr Pointer (in UNDEF LR) and previous mode's CPSR to stack */ - - tst r1, #CPSR_THUMB /* Check for Thumb Mode */ - subne r0, r0, #2 /* Is Thumb instruction, adjust PC for UNDEF instruction address */ - subeq r0, r0, #4 /* Is ARM instruction, adjust PC for UNDEF instruction address */ - str r0, [r3, #-4]! /* Save PC to stack (R15 slot) */ - - and r2, r1, #CPSR_MODE /* Get previous mode */ - teq r2, #MODE_USR - beq _skip_banked_registers /* Can't switch back if we're in User mode! */ - -_store_prev_mode_banked_regs: - /* FIXME: We don't handle FIQ properly! */ - - orr r2, #(CPSR_FIQ | CPSR_IRQ) /* Disable Interrupts */ - msr cpsr_c, r2 /* Switch to previous mode */ - stmfd r3!, {sp, lr} /* Store Previous Mode's LR (R14), SP (R13) via R3 */ - msr cpsr_c, #(MODE_UND | CPSR_FIQ | CPSR_IRQ) /* Revert to Undef Mode */ - -_skip_banked_registers: - tst r1, #CPSR_THUMB /* Check for Thumb Mode */ - beq _is_arm /* Clear, so it's ARM mode */ -_is_thumb: - ldrh r0, [r0] /* load UNDEF instruction into r0 */ - ldr r1, =BKPT16_ENUM_MASK /* Thumb BKPT enum mask */ - bic r2, r0, r1 /* leave only opcode */ - ldr r1, =BKPT16_INSTR /* check for Thumb Breakpoint Instruction */ - teq r2, r1 - bne default_undef_handler - ldr r1, =BKPT16_ENUM_MASK /* get Thumb BKPT Enum Mask */ - ldr r2, =dbg__thumb_bkpt_handler /* handle BKPT, BKPT index in r0 */ - b _exit_undef_handler -_is_arm: - ldr r0, [r0] /* load UNDEF instruction into r0 */ - ldr r1, =BKPT32_ENUM_MASK /* ARM BKPT enum mask */ - bic r2, r0, r1 /* leave only opcode */ - ldr r1, =BKPT32_INSTR /* check for ARM Breakpoint Instruction */ - teq r2, r1 - bne default_undef_handler - ldr r1, =BKPT32_ENUM_MASK /* get ARM BKPT Enum Mask */ - ldr r2, =dbg__arm_bkpt_handler /* handle BKPT, BKPT index in r0 */ -_exit_undef_handler: - and r0, r1, r0 /* Keep index value */ - msr cpsr_c, #(MODE_ABT | CPSR_FIQ | CPSR_IRQ) /* Switch to Abort Mode, Disable Interrupts */ - ldr sp, =__abort_stack__ /* Reinitialize stack pointer each time a Breakpoint happens */ - bic sp, sp, #7 - mov pc, r2 /* Invoke Debugger */ - -/** resume_execution - * This routine is called by the Debugger prior to returning control to - * the executing program. - * It updates the SPSR_UNDEF with the Debug Stack value, and - * restores all registers R0-R14 to the previously active mode. - * Then, it uses the Next Instruction Address Pointer to return - * execution control to the previously executing program. - */ -/* On Entry, SP(undef) points to the Next Instruction Address. - * If the instruction which triggered the Breakpoint need to be - * reexecuted, it should be placed in the Next Instruction Address slot - * by ABORT mode before coming here - */ - dbg_interwork resume_execution - ldr lr, =__debugger_stack_bottom__ /* Use LR(undef) for Debug Stack Access */ - add r1, lr, #(DBGSTACK_USERSP_INDEX*4) /* Use R1 for Previous Mode SP (R13) and LR (R14) access */ - ldr r0, [lr, #(DBGSTACK_USERCPSR_INDEX*4)]! /* LR updated, Retrieve SPSR into R0 */ - msr spsr, r0 /* Update SPSR for return to program being debugged */ - and r0, r0, #CPSR_MODE /* Get previous mode */ - teq r0, #MODE_USR - bne _restore_prev_mode_banked_regs /* Can't switch back if we're in User mode! */ - - /* Previous mode was User Mode */ - ldmed lr, {r0-r14}^ /* We use LDMED since LR is pointing to USERCPSR not R0 */ - b _really_resume_execution - -_restore_prev_mode_banked_regs: - /* FIXME: We don't handle FIQ properly! */ - orr r0, #(CPSR_FIQ | CPSR_IRQ) /* Disable Interrupts */ - msr cpsr_c, r0 /* Switch to previous mode */ - ldmfd r1, {sp, lr} /* Restore Previous Mode's LR (R14), SP (R13) via R1 */ - msr cpsr_c, #(MODE_UND | CPSR_FIQ | CPSR_IRQ) /* Revert to Undef Mode */ - ldmed lr, {r0-r12} /* We use LDMED since LR is pointing to USERCPSR not R0 */ - -_really_resume_execution: - ldmfd sp, {pc}^ /* Exit to Previous Mode using Next Instruction Address */ - - - - diff --git a/AT91SAM7S256/armdebug/Doxyfile b/AT91SAM7S256/armdebug/Doxyfile deleted file mode 100644 index 6266354..0000000 --- a/AT91SAM7S256/armdebug/Doxyfile +++ /dev/null @@ -1,243 +0,0 @@ -# Doxyfile 1.5.3-20071008 - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- -DOXYFILE_ENCODING = UTF-8 -PROJECT_NAME = "NxOS Debugger" -PROJECT_NUMBER = -OUTPUT_DIRECTORY = ../doc/debug -CREATE_SUBDIRS = NO -OUTPUT_LANGUAGE = English -BRIEF_MEMBER_DESC = YES -REPEAT_BRIEF = YES -ABBREVIATE_BRIEF = "The $name class" \ - "The $name widget" \ - "The $name file" \ - is \ - provides \ - specifies \ - contains \ - represents \ - a \ - an \ - the -ALWAYS_DETAILED_SEC = NO -INLINE_INHERITED_MEMB = NO -FULL_PATH_NAMES = YES -STRIP_FROM_PATH = -STRIP_FROM_INC_PATH = -SHORT_NAMES = NO -JAVADOC_AUTOBRIEF = NO -QT_AUTOBRIEF = NO -MULTILINE_CPP_IS_BRIEF = NO -#DETAILS_AT_TOP = NO -INHERIT_DOCS = YES -SEPARATE_MEMBER_PAGES = NO -TAB_SIZE = 8 -ALIASES = -OPTIMIZE_OUTPUT_FOR_C = YES -OPTIMIZE_OUTPUT_JAVA = NO -BUILTIN_STL_SUPPORT = NO -CPP_CLI_SUPPORT = NO -SIP_SUPPORT = NO -DISTRIBUTE_GROUP_DOC = NO -SUBGROUPING = YES -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- -EXTRACT_ALL = NO -EXTRACT_PRIVATE = YES -EXTRACT_STATIC = YES -EXTRACT_LOCAL_CLASSES = YES -EXTRACT_LOCAL_METHODS = NO -EXTRACT_ANON_NSPACES = NO -HIDE_UNDOC_MEMBERS = NO -HIDE_UNDOC_CLASSES = NO -HIDE_FRIEND_COMPOUNDS = NO -HIDE_IN_BODY_DOCS = NO -INTERNAL_DOCS = YES -CASE_SENSE_NAMES = YES -HIDE_SCOPE_NAMES = NO -SHOW_INCLUDE_FILES = YES -INLINE_INFO = YES -SORT_MEMBER_DOCS = YES -SORT_BRIEF_DOCS = NO -SORT_BY_SCOPE_NAME = NO -GENERATE_TODOLIST = YES -GENERATE_TESTLIST = YES -GENERATE_BUGLIST = YES -GENERATE_DEPRECATEDLIST= YES -ENABLED_SECTIONS = -MAX_INITIALIZER_LINES = 30 -SHOW_USED_FILES = YES -SHOW_DIRECTORIES = NO -FILE_VERSION_FILTER = -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- -QUIET = NO -WARNINGS = YES -WARN_IF_UNDOCUMENTED = YES -WARN_IF_DOC_ERROR = YES -WARN_NO_PARAMDOC = NO -WARN_FORMAT = "$file:$line: $text" -WARN_LOGFILE = -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- -INPUT = . -INPUT_ENCODING = UTF-8 -FILE_PATTERNS = *.h -RECURSIVE = YES -EXCLUDE = at91sam7s256.h -EXCLUDE_SYMLINKS = NO -EXCLUDE_PATTERNS = -EXCLUDE_SYMBOLS = -EXAMPLE_PATH = -EXAMPLE_PATTERNS = * -EXAMPLE_RECURSIVE = NO -IMAGE_PATH = -INPUT_FILTER = -FILTER_PATTERNS = -FILTER_SOURCE_FILES = NO -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- -SOURCE_BROWSER = NO -INLINE_SOURCES = NO -STRIP_CODE_COMMENTS = YES -REFERENCED_BY_RELATION = NO -REFERENCES_RELATION = NO -REFERENCES_LINK_SOURCE = YES -USE_HTAGS = NO -VERBATIM_HEADERS = NO -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- -ALPHABETICAL_INDEX = NO -COLS_IN_ALPHA_INDEX = 5 -IGNORE_PREFIX = -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- -GENERATE_HTML = YES -HTML_OUTPUT = html -HTML_FILE_EXTENSION = .html -HTML_HEADER = -HTML_FOOTER = -HTML_STYLESHEET = -HTML_ALIGN_MEMBERS = YES -GENERATE_HTMLHELP = NO -HTML_DYNAMIC_SECTIONS = NO -CHM_FILE = -HHC_LOCATION = -GENERATE_CHI = NO -BINARY_TOC = NO -TOC_EXPAND = NO -DISABLE_INDEX = NO -ENUM_VALUES_PER_LINE = 1 -GENERATE_TREEVIEW = YES -TREEVIEW_WIDTH = 280 -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- -GENERATE_LATEX = NO -LATEX_OUTPUT = latex -LATEX_CMD_NAME = latex -MAKEINDEX_CMD_NAME = makeindex -COMPACT_LATEX = NO -PAPER_TYPE = a4wide -EXTRA_PACKAGES = -LATEX_HEADER = -PDF_HYPERLINKS = YES -USE_PDFLATEX = YES -LATEX_BATCHMODE = NO -LATEX_HIDE_INDICES = NO -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- -GENERATE_RTF = NO -RTF_OUTPUT = rtf -COMPACT_RTF = NO -RTF_HYPERLINKS = NO -RTF_STYLESHEET_FILE = -RTF_EXTENSIONS_FILE = -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- -GENERATE_MAN = NO -MAN_OUTPUT = man -MAN_EXTENSION = .3 -MAN_LINKS = NO -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- -GENERATE_XML = NO -XML_OUTPUT = xml -XML_SCHEMA = -XML_DTD = -XML_PROGRAMLISTING = YES -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- -GENERATE_AUTOGEN_DEF = NO -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- -GENERATE_PERLMOD = NO -PERLMOD_LATEX = NO -PERLMOD_PRETTY = YES -PERLMOD_MAKEVAR_PREFIX = -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- -ENABLE_PREPROCESSING = YES -#MACRO_EXPANSION = NO -MACRO_EXPANSION = YES -EXPAND_ONLY_PREDEF = NO -SEARCH_INCLUDES = YES -INCLUDE_PATH = -INCLUDE_FILE_PATTERNS = -PREDEFINED = -EXPAND_AS_DEFINED = -SKIP_FUNCTION_MACROS = YES -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- -TAGFILES = -GENERATE_TAGFILE = -ALLEXTERNALS = NO -EXTERNAL_GROUPS = YES -PERL_PATH = /usr/bin/perl -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- -CLASS_DIAGRAMS = NO -MSCGEN_PATH = -HIDE_UNDOC_RELATIONS = YES -HAVE_DOT = NO -CLASS_GRAPH = YES -COLLABORATION_GRAPH = YES -GROUP_GRAPHS = YES -UML_LOOK = NO -TEMPLATE_RELATIONS = NO -INCLUDE_GRAPH = YES -INCLUDED_BY_GRAPH = YES -CALL_GRAPH = NO -CALLER_GRAPH = NO -GRAPHICAL_HIERARCHY = YES -DIRECTORY_GRAPH = YES -DOT_IMAGE_FORMAT = png -DOT_PATH = -DOTFILE_DIRS = -DOT_GRAPH_MAX_NODES = 50 -MAX_DOT_GRAPH_DEPTH = 1000 -DOT_TRANSPARENT = YES -DOT_MULTI_TARGETS = NO -GENERATE_LEGEND = YES -DOT_CLEANUP = YES -#--------------------------------------------------------------------------- -# Configuration::additions related to the search engine -#--------------------------------------------------------------------------- -SEARCHENGINE = NO diff --git a/AT91SAM7S256/armdebug/GNU-GPLv2.txt b/AT91SAM7S256/armdebug/GNU-GPLv2.txt deleted file mode 100644 index 5b6e7c6..0000000 --- a/AT91SAM7S256/armdebug/GNU-GPLv2.txt +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/AT91SAM7S256/armdebug/Host/README b/AT91SAM7S256/armdebug/Host/README deleted file mode 100644 index 1b6537e..0000000 --- a/AT91SAM7S256/armdebug/Host/README +++ /dev/null @@ -1,26 +0,0 @@ -The nxt-gdb-server.py script is initially developed by Nicolas Schodet. - -It depends on the following libraries: - - nxt-python v2.2.x http://code.google.com/p/nxt-python/ - -Additional Dependencies For Windows and MacOSX: - - Fantom Drivers from LEGO - -Additional Dependencies For Linux: - - pyusb v0.4x http://pyusb.wiki.sourceforge.net - - libusb v0.1.x http://libusb.org/ - - Currently, it does not work with libusb v1.x; on Mac OSX, it causes segfaults. - - Installation - ============ - - There is no specific installation requirements (at this moment). Just run the python script - in a terminal window. - - Usage - ===== - - 1. Connect the USB cable from the PC Host to the NXT - 2. start nxt-gdb-server.py - 3. start arm-none-eabi-gdb, configured as remote for port 2828 (default) diff --git a/AT91SAM7S256/armdebug/Host/gdb-commands.txt b/AT91SAM7S256/armdebug/Host/gdb-commands.txt deleted file mode 100644 index 3135a1e..0000000 --- a/AT91SAM7S256/armdebug/Host/gdb-commands.txt +++ /dev/null @@ -1,43 +0,0 @@ -# This file contains hand coded GDB commands for testing the GDB Server <-> NXT interface - -# Display all Registers -$g#67 - -# Display R0 -$p0#A0 - -# Display R1 -$p1#A1 - -# Display PC -$pF#B6 - -# Display FPSCR (dummy) -$p18#D9 - -# Display User CPSR -$p19#DA - -# Query Status -$?#3F - -# Query Thread -$qC#B4 - -# Set R1 to 0xAA -$P1=000000AA#60 - -# Read 16 bytes of Memory from 0x00201d74 (padding bytes after debug_mode + 4 bytes of debug_InUSBBuf) -$m00201D74,0010#FC - -# Write 2 bytes of memory to 0x00201d74 (padding bytes after debug_mode) -$M00201D74,0002:AA55#03 - -# Write 2 bytes of memory to 0x00201d74 (padding bytes after debug_mode) -$M00201D74,0002:9966#F5 - -# GDB Read Instruction at Address (PC) -+$m1001de,4#58 - -# Continue Execution -$c#63 diff --git a/AT91SAM7S256/armdebug/Host/nxt-gdb-server.py b/AT91SAM7S256/armdebug/Host/nxt-gdb-server.py deleted file mode 100755 index 03a95d3..0000000 --- a/AT91SAM7S256/armdebug/Host/nxt-gdb-server.py +++ /dev/null @@ -1,254 +0,0 @@ -#!/usr/bin/env python -# -# Copyright (C) 2011 the NxOS developers -# -# Module Developed by: Nicolas Schodet -# TC Wan -# -# See AUTHORS for a full list of the developers. -# -# See COPYING for redistribution license -# -# Exchange GDB messages with the NXT brick. -# -# Every message is encapsulated with the debug command and message length. -# This can be used by the firmware to make the distinction between debug -# messages and regular messages. -# -import nxt.locator -import socket -import optparse -import select -try: - import pyfantom -except ImportError: - import usb -import struct -import sys - -CTRLC = chr(3) -NAKCHAR = '-' -ACKCHAR = '+' -STATUS_QUERY = "$?#3F" -DEFAULT_PORT = 2828 -SELECT_TIMEOUT = 0.1 -DEBUG = False -DEBUG2 = False -NXT_RECV_ERR = -1 - -# Libusb 0.12.x blocks on USB reads -LIBUSB_RECEIVE_BLOCKING = True - -class NXTGDBServer: - - # Socket read size. - recv_size = 1024 - - # Maximum message size. - pack_size = 61 - - # Debug command header, no reply. - debug_command = 0x8d - - def __init__ (self, port, nowait): - """Initialise server.""" - self.nowait = nowait - self.port = port - self.in_buf = '' - self.brick = None - - def pack (self, data, segment_no): - """Return packed data to send to NXT.""" - # Insert command and length. - assert len (data) <= self.pack_size - return struct.pack ('BBB', self.debug_command, segment_no, len (data)) + data - - def unpack (self, data): - """Return unpacked data from NXT.""" - # May be improved, for now, check command and announced length. - if len (data) == 0: - return '', 0 # No message, exit - if len (data) < 3: - return '', NXT_RECV_ERR - header, body = data[0:3], data[3:] - command, segment_no, length = struct.unpack ('BBB', header) - if command != self.debug_command or length != len (body): - return '', NXT_RECV_ERR - return body, segment_no - - def segment (self, data): - """Split messages in GDB commands and make segments with each command.""" - segs = [ ] - self.in_buf += data - - # Find ACK '+' - end = self.in_buf.find (ACKCHAR) - while end == 0: - self.in_buf = self.in_buf[end+1:] # Strip out any leading ACKCHAR - if DEBUG2: - print "stripped ACK, remain: ", self.in_buf - end = self.in_buf.find (ACKCHAR) - - # Find NAK '-' - end = self.in_buf.find (NAKCHAR) - if end == 0: - msg, self.in_buf = self.in_buf[0:end+1], self.in_buf[end+1:] - segs.append (self.pack (msg, 0)) - end = self.in_buf.find (NAKCHAR) - - # Find Ctrl-C (assumed to be by itself and not following a normal command) - end = self.in_buf.find (CTRLC) - if end >= 0: - msg, self.in_buf = self.in_buf[0:end+1], self.in_buf[end+1:] - assert len (msg) <= self.pack_size, "Ctrl-C Command Packet too long!" - segs.append (self.pack (msg, 0)) - end = self.in_buf.find (CTRLC) - - end = self.in_buf.find ('#') - # Is # found and enough place for the checkum? - while end >= 0 and end < len (self.in_buf) - 2: - msg, self.in_buf = self.in_buf[0:end + 3], self.in_buf[end + 3:] - i = 0 - gdbprefix = msg[i] - while gdbprefix in [ACKCHAR]: - # Ignore any '+' - i += 1 - gdbprefix = msg[i] - if DEBUG2: - print "Checking '", gdbprefix, "'" - assert gdbprefix == '$', "not a GDB command" - # Make segments. - seg_no = 0 - while msg: - seg, msg = msg[0:self.pack_size], msg[self.pack_size:] - seg_no += 1 - if not msg: # Last segment. - seg_no = 0 - segs.append (self.pack (seg, seg_no)) - # Look for next one. - end = self.in_buf.find ('#') - return segs - - def reassemble (self, sock): - msg = '' - prev_segno = 0 - segno = NXT_RECV_ERR # force initial pass through while loop - while segno != 0: - try: - s, segno = self.unpack (sock.recv ()) - if len (s) == 0: - if segno == 0 and prev_segno == 0: - return '' # No message pending - else: - segno = NXT_RECV_ERR # Keep waiting for segments - # Ignore error packets - if segno >= 0: - # Check segno, if non-zero it must be monotonically increasing from 1, otherwise 0 - if segno > 0: - assert segno == prev_segno + 1, "segno = %s, prev_segno = %s" % (segno, prev_segno) - prev_segno = segno - msg += s - except IOError as e: - # Some pyusb are buggy, ignore some "errors". - if e.args != ('No error', ): - raise e - return msg - - def run (self): - """Endless run loop.""" - # Create the listening socket. - s = socket.socket (socket.AF_INET, socket.SOCK_STREAM) - s.setsockopt (socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - s.bind (('', self.port)) - s.listen (1) - while True: - # We should open the NXT connection first, otherwise Python startup delay - # may cause GDB to misbehave - if not self.nowait: - dummy = raw_input('Waiting...Press when NXT GDB Stub is ready. ') - # Open connection to the NXT brick. - self.brick = nxt.locator.find_one_brick () - self.brick.sock.debug = DEBUG - # Wait for a connection. - print "Waiting for GDB connection on port %s..." % self.port - client, addr = s.accept () - print "Client from", addr - # Work loop, wait for a message from client socket or NXT brick. - while client is not None: - data = '' - # Wait for a message from client or timeout. - rlist, wlist, xlist = select.select ([ client ], [ ], [ ], - SELECT_TIMEOUT) - for c in rlist: - assert c is client - # Data from client, read it and forward it to NXT brick. - data = client.recv (self.recv_size) - data = data.strip() - if len (data) > 0: - #if len (data) == 1 and data.find(CTRLC) >= 0: - # print "CTRL-C Received!" - # data = STATUS_QUERY - if DEBUG: - if data[0] == CTRLC: - print "[GDB->NXT] " - else: - print "[GDB->NXT] %s" % data - segments = self.segment (data) - data = '' - for seg in segments: - try: - self.brick.sock.send (seg) - except IOError as e: - # Some pyusb are buggy, ignore some "errors". - if e.args != ('No error', ): - raise e - if segments != [] and LIBUSB_RECEIVE_BLOCKING: - if DEBUG2: - print "Accessing Blocking sock.recv()" - data = self.reassemble (self.brick.sock) - else: - client.close () - client = None - if not LIBUSB_RECEIVE_BLOCKING: - if DEBUG2: - print "Accessing Non-Blocking sock.recv()" - data = self.reassemble (self.brick.sock) - - # Is there something from NXT brick? - if data: - if DEBUG: - print "[NXT->GDB] %s" % data - if client: - client.send (data) - data = '' - self.brick.sock.close() - print "Connection closed." - if self.nowait: - break - -if __name__ == '__main__': - # Read options from command line. - parser = optparse.OptionParser (description = """ - Gateway between the GNU debugger and a NXT brick. - """) - parser.add_option ('-p', '--port', type = 'int', default = DEFAULT_PORT, - help = "server listening port (default: %default)", metavar = "PORT") - parser.add_option ('-v', '--verbose', action='store_true', dest='verbose', default = False, - help = "verbose mode (default: %default)") - parser.add_option ('-n', '--nowait', action='store_true', dest='nowait', default = False, - help = "Don't wait for NXT GDB Stub Setup before connecting (default: %default)") - (options, args) = parser.parse_args () - if args: - parser.error ("Too many arguments") - # Run. - try: - DEBUG = options.verbose - if DEBUG: - print "Debug Mode Enabled!" - server = NXTGDBServer (options.port, options.nowait) - server.run () - except KeyboardInterrupt: - print "\n\nException caught. Bye!" - if server.brick is not None: - server.brick.sock.close() - sys.exit() diff --git a/AT91SAM7S256/armdebug/LEGO_Open_Source_License.doc b/AT91SAM7S256/armdebug/LEGO_Open_Source_License.doc deleted file mode 100644 index 94b65e6..0000000 Binary files a/AT91SAM7S256/armdebug/LEGO_Open_Source_License.doc and /dev/null differ diff --git a/AT91SAM7S256/armdebug/README b/AT91SAM7S256/armdebug/README deleted file mode 100644 index 4660b1e..0000000 --- a/AT91SAM7S256/armdebug/README +++ /dev/null @@ -1,16 +0,0 @@ -Introduction -============ -armdebug is an ARM Assembly Language Instruction debugger for the NXT. -It is intended for embedding in the NXT firmware (e.g. NXT Improved Firmware), -as well as for use with NxOS. - -Contents -======== -The various folders contents are as follows: -Debugger: GDB client driver for NXT (need to be embedded in firmware code) -Host: GDB Server for PC Host - -LICENSES -======== -The armdebug code is dual-licensed. Please see COPYING for more details. -Other projects included in this repository have their respective licenses. diff --git a/AT91SAM7S256/armdebug/SConscript b/AT91SAM7S256/armdebug/SConscript deleted file mode 100644 index c495847..0000000 --- a/AT91SAM7S256/armdebug/SConscript +++ /dev/null @@ -1,13 +0,0 @@ -# This scons build script is used by NxOS - -from glob import glob - -Import('env') - - -for source in glob('Debugger/*.[cS]'): - obj = env.Object(source.split('.')[0], source) - env.Append(NXOS_DEBUG=obj) - -if env['WITH_DOXYGEN']: - env.Doxygen('Doxyfile') diff --git a/AT91SAM7S256/armdebug/SConstruct b/AT91SAM7S256/armdebug/SConstruct deleted file mode 100644 index fa88d7a..0000000 --- a/AT91SAM7S256/armdebug/SConstruct +++ /dev/null @@ -1,182 +0,0 @@ -# -*- mode: python -*- -############################################################### -# This scons build script is used to check the armdebug project -# code for syntax errors. It does not build working executable -# code since it links to external routines. -############################################################### - -import os -import os.path -import new -from glob import glob - -############################################################### -# Utility functions. -############################################################### - -# Similar to env.WhereIs, but always searches os.environ. -def find_on_path(filename): - paths = os.environ.get('PATH') - if not paths: - return None - for p in paths.split(':'): - path = os.path.abspath(os.path.join(p, filename)) - if os.path.isfile(path): - return p - return None - -# Run the given gcc binary, and parses its output to work out the gcc -# version. -def determine_gcc_version(gcc_binary): - stdout = os.popen('%s --version' % gcc_binary) - gcc_output = stdout.read().split() - stdout.close() - grab_next = False - for token in gcc_output: - if grab_next: - return token - elif token[-1] == ')': - grab_next = True - return None - -# Check that a given cross-compiler tool exists. If it does, the path is -# added to the build environment, and the given environment variable is -# set to the tool name. -# -# This is used to check for the presence of a working cross-compiler -# toolchain, and to properly set up the environment to do it. See below -# in the configuration section for details. -def CheckTool(context, envname, toolname=None, hostprefix=None): - toolname = toolname or envname.lower() - if hostprefix is None: - hostprefix = '%s-' % context.env['CROSS_COMPILE_HOST'] - toolname = '%s%s' % (hostprefix, toolname) - context.Message("Checking for %s..." % toolname) - toolpath = find_on_path(toolname) - if not toolpath: - context.Result('not found') - return False - else: - context.Result('ok') - context.env[envname] = toolname - context.env.AppendENVPath('PATH', toolpath) - return True - -# Find the correct variant and version of libgcc.a in the cross-compiler -# toolchain. -def CheckLibGcc(context, gccname): - context.Message("Locating a cross-compiled libgcc...") - toolpath = find_on_path(gccname) - if not toolpath: - context.Result("%s not found" % toolname) - return False - gcc_version = determine_gcc_version(gccname) - if not gcc_version: - context.Result("Could not determine gcc version") - return False - gcc_install_dir = os.path.split(os.path.normpath(toolpath))[0] - for libdir in ['interwork', 'thumb', '']: - libgcc_path = os.path.join(gcc_install_dir, 'lib', 'gcc', - context.env['CROSS_COMPILE_HOST'], - gcc_version, libdir, 'libgcc.a') - if os.path.isfile(libgcc_path): - break - if not os.path.isfile(libgcc_path): - context.Result("libgcc.a not found") - return False - context.Result("ok - " + libgcc_path) - context.env.Append(LIBGCC=libgcc_path) - return True - -def CheckDoxygen(context): - context.Message("Looking for Doxygen...") - doxypath = find_on_path('doxygen') - if doxypath: - context.Result("ok") - context.env.AppendENVPath('PATH', doxypath) - context.env['WITH_DOXYGEN'] = True - else: - context.Result("not found") - context.env['WITH_DOXYGEN'] = False - - - -############################################################### -# Options that can be provided on the commandline -############################################################### - -opts = Variables('scons.options', ARGUMENTS) - -opts.Add(PathVariable('gccprefix', - 'Prefix of the cross-gcc to use (by default arm-none-eabi)', - 'arm-none-eabi', PathVariable.PathAccept)) - -Help(''' -Type: 'scons' to build object files. - - - To use another cross-gcc than arm-none-eabi-gcc: - scons gccprefix=arm-softfloat-eabi - -Options are saved persistent in the file 'scons.options'. That means -after you have called e.g. 'scons gccprefix=arm-softfloat-eabi' it's enough -to call only 'scons' to build both using the new gcc version again. -''') - -############################################################### -# Construct and configure a cross-compiler environment -############################################################### -env = Environment(options = opts, - tools = ['gcc', 'as', 'gnulink', 'ar'], - toolpath = ['scons_tools'], - LIBGCC = [], CPPPATH = '#', - WITH_DOXYGEN = False) -opts.Update(env) -opts.Save('scons.options', env) - -if not env.GetOption('clean'): - conf = Configure(env, custom_tests = {'CheckTool': CheckTool, - 'CheckLibGcc': CheckLibGcc, - 'CheckDoxygen': CheckDoxygen}) - conf.env['CROSS_COMPILE_HOST'] = env['gccprefix'] - if not (conf.CheckTool('CC', 'gcc') and conf.CheckTool('AR') and - conf.CheckTool('OBJCOPY') and conf.CheckTool('LINK', 'ld') and - conf.CheckLibGcc(conf.env['CC'])): - print "Missing or incomplete arm-elf toolchain, cannot continue!" - Exit(1) - env = conf.Finish() - -mycflags = ['-mcpu=arm7tdmi', '-Os', '-Wextra', '-Wall', '-Werror', - '-Wno-div-by-zero', '-Wfloat-equal', '-Wshadow', - '-Wpointer-arith', '-Wbad-function-cast', - '-Wmissing-prototypes', '-ffreestanding', - '-fsigned-char', '-ffunction-sections', '-std=gnu99', - '-fdata-sections', '-fomit-frame-pointer', '-msoft-float'] -myasflags = ['-Wall', '-Werror', '-Os']; -if str(env['LIBGCC']).find('interwork') != -1: - mycflags.append('-mthumb-interwork') - myasflags.append('-Wa,-mcpu=arm7tdmi,-mfpu=softfpa,-mthumb-interwork') -elif str(env['LIBGCC']).find('thumb') != -1: - mycflags.append('-mthumb') - myasflags.append('-Wa,-mcpu=arm7tdmi,-mfpu=softfpa,-mthumb') -else: - myasflags.append('-Wa,-mcpu=arm7tdmi,-mfpu=softfpa') -mycflags.append('-g') -mycflags.append('-ggdb') -# Big Endian Output (disabled by default) -#mycflags.append('-D__BIG_ENDIAN__') -# Test build for NxOS (Comment out for NXT Firmware) -mycflags.append('-D__NXOS__') - -myasflags.append('-g') -myasflags.append('-ggdb') -# Big Endian Output (disabled by default) -#mycflags.append('-D__BIG_ENDIAN__') -# Test build for NxOS (Comment out for NXT Firmware) -myasflags.append('-D__NXOS__') - -env.Replace(CCFLAGS = mycflags, ASFLAGS = myasflags ) - -# Build the baseplate, and all selected application kernels. - -numProcs = os.sysconf('SC_NPROCESSORS_ONLN') -SConscript(['SConscript'], 'numProcs env CheckTool') diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3d6e4d2 --- /dev/null +++ b/Makefile @@ -0,0 +1,116 @@ +BASE = . +SRCDIR = $(BASE)/src +LIBDIR = $(BASE)/lib +DBGDIR = $(BASE)/armdebug/Debugger +CPUINCDIR = $(BASE)/include +STARTUPDIR = $(BASE)/startup + +DATE_FMT = +%Y-%m-%dT%H:%M +ifndef SOURCE_DATE_EPOCH + SOURCE_DATE_EPOCH = $(shell git log -1 --pretty=%ct) +endif +BUILD_DATE ?= $(shell LC_ALL=C date -u -d "@$(SOURCE_DATE_EPOCH)" "$(DATE_FMT)" 2>/dev/null \ + || LC_ALL=C date -u -r "$(SOURCE_DATE_EPOCH)" "$(DATE_FMT)" 2>/dev/null \ + || LC_ALL=C date -u "$(DATE_FMT)") + +TARGET = nxt_firmware + +# Set to 'y' to enable embedded debuger. +ARMDEBUG = n + +ARM_SOURCES = +THUMB_SOURCES = c_button.c c_cmd.c c_comm.c c_display.c c_input.c c_ioctrl.c \ + c_loader.c c_lowspeed.c c_output.c c_sound.c c_ui.c \ + d_bt.c d_button.c d_display.c d_hispeed.c d_input.c \ + d_ioctrl.c d_loader.c d_lowspeed.c d_output.c d_sound.c \ + d_timer.c d_usb.c \ + m_sched.c \ + abort.c errno.c sbrk.c strtod.c sscanf.c \ + Cstartup_SAM7.c + +ASM_ARM_SOURCE = Cstartup.S +ASM_THUMB_SOURCE = + +vpath %.c $(SRCDIR) +vpath %.c $(LIBDIR) +vpath %.c $(STARTUPDIR) +vpath %.S $(STARTUPDIR) + +INCLUDES = -I$(CPUINCDIR) + +MCU = arm7tdmi +STARTOFUSERFLASH_DEFINES = -DSTARTOFUSERFLASH_FROM_LINKER=1 +VERSION_DEFINES = -D'BUILD_DATE="$(BUILD_DATE)"' +DEFINES = -DPROTOTYPE_PCB_4 -DNEW_MENU -DROM_RUN -DVECTORS_IN_RAM \ + $(STARTOFUSERFLASH_DEFINES) $(VERSION_DEFINES) +OPTIMIZE = -Os -fno-strict-aliasing \ + -ffunction-sections -fdata-sections +WARNINGS = -Wall -W -Wundef -Wno-unused -Wno-format +THUMB_INTERWORK = -mthumb-interwork +CFLAGS = -g -mcpu=$(MCU) $(THUMB) $(THUMB_INTERWORK) $(WARNINGS) $(OPTIMIZE) +ASFLAGS = -g -mcpu=$(MCU) $(THUMB) $(THUMB_INTERWORK) +CPPFLAGS = $(INCLUDES) $(DEFINES) -MMD +LDSCRIPT = $(LIBDIR)/nxt.ld +LDFLAGS = -nostdlib -T $(LDSCRIPT) -Wl,--gc-sections +LDLIBS = -lc -lm -lgcc -lnosys + +ifeq ($(ARMDEBUG),y) +ASM_ARM_SOURCE += abort_handler.S undef_handler.S debug_hexutils.S \ + debug_stub.S debug_comm.S debug_opcodes.S \ + debug_runlooptasks.S +vpath %.S $(DBGDIR) +DEFINES += -DARMDEBUG +INCLUDES += -I$(DBGDIR) +endif + +CROSS_COMPILE = arm-none-eabi- +CC = $(CROSS_COMPILE)gcc +OBJDUMP = $(CROSS_COMPILE)objdump +OBJCOPY = $(CROSS_COMPILE)objcopy + +FWFLASH = fwflash + +ARM_OBJECTS = $(ARM_SOURCES:%.c=%.o) $(ASM_ARM_SOURCE:%.S=%.o) +THUMB_OBJECTS = $(THUMB_SOURCES:%.c=%.o) $(THUMB_ARM_SOURCE:%.S=%.o) +OBJECTS = $(ARM_OBJECTS) $(THUMB_OBJECTS) + +all: bin + +elf: $(TARGET).elf +bin: $(TARGET).bin +sym: $(TARGET).sym +lst: $(TARGET).lst + +$(TARGET).elf: THUMB = -mthumb +$(TARGET).elf: $(OBJECTS) $(LDSCRIPT) + $(LINK.c) $(OBJECTS) $(LOADLIBES) $(LDLIBS) -o $@ + +%.bin: %.elf + $(OBJCOPY) --pad-to=0x140000 --gap-fill=0xff -O binary $< $@ + +%.sym: %.elf + $(OBJDUMP) -h -t $< > $@ + +%.lst: %.elf + $(OBJDUMP) -S $< > $@ + +$(THUMB_OBJECTS): THUMB = -mthumb + +-include $(OBJECTS:%.o=%.d) + +LAST_BUILD_DATE=none +-include version.mak +ifneq ($(LAST_BUILD_DATE),$(BUILD_DATE)) +.PHONY: version.mak +version.mak: + echo "LAST_BUILD_DATE = $(BUILD_DATE)" > $@ +endif + +c_ui.o: version.mak + +program: $(TARGET).bin + $(FWFLASH) $(TARGET).bin + +clean: + rm -f $(TARGET).elf $(TARGET).bin $(TARGET).sym $(TARGET).lst \ + $(OBJECTS) $(OBJECTS:%.o=%.d) version.mak diff --git a/README b/README index 4da7744..bcdcdab 100644 --- a/README +++ b/README @@ -10,9 +10,9 @@ including documentation, building guides, and more: Quick start ----------- -To build the firmware, run make in the AT91SAM7S256/SAM7S256/gcc directory. It -will produce a nxt_firmware.bin file that you can flash with your tool of -choice. For example, you can use fwflash from libnxt. +To build the firmware, run make in this directory. It will produce a +nxt_firmware.bin file that you can flash with your tool of choice. For +example, you can use fwflash from libnxt. License diff --git a/armdebug/.gitignore b/armdebug/.gitignore new file mode 100644 index 0000000..46f8223 --- /dev/null +++ b/armdebug/.gitignore @@ -0,0 +1,41 @@ +# Ignore tag +MASTER-REPO_DO-NOT-DELETE +*.lst +*.objdump +.DS_Store + +# Generally annoying things. +*.[oa] +*.pyc +*.bin +*.elf +*.rxe +*.map +*.orig +*.log +*~ +*.swp +\#*\# +.\#* + +# Python distutils creates this when building. +pynxt/build/ + +# XCode build stuff +FantomModule/build/ +*mode1v3 +*pbxuser + +# SCons cruft +.sconsign.dblite +.sconf_temp +build_flags.py + +# Precommit hooks drop a commit.msg file if they fail. +commit.msg + +# The option-cache +scons.options + +# pyfantom related +pyfantom.py diff --git a/armdebug/.project b/armdebug/.project new file mode 100644 index 0000000..15b12fc --- /dev/null +++ b/armdebug/.project @@ -0,0 +1,11 @@ + + + armdebug + + + + + + + + diff --git a/armdebug/AUTHORS b/armdebug/AUTHORS new file mode 100644 index 0000000..169c2b6 --- /dev/null +++ b/armdebug/AUTHORS @@ -0,0 +1,6 @@ +The following people have contributed code, in various quantities, to armdebug. +A big thanks to all of them, armdebug is what it is in part thanks to each of +them. In alphabetical order: + +Nicolas Schodet +Tat Chee Wan diff --git a/armdebug/COPYING b/armdebug/COPYING new file mode 100644 index 0000000..86fae60 --- /dev/null +++ b/armdebug/COPYING @@ -0,0 +1,9 @@ +The armdebug project is dual licensed. + +You can either use the GNU GPLv2 license in GNU-GPLv2.txt, +or else the "LEGO Open Source License" in LEGO_Open_Source_License.doc +to redistribute the code. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. diff --git a/armdebug/Debugger/_c_arm_macros.h b/armdebug/Debugger/_c_arm_macros.h new file mode 100644 index 0000000..025542e --- /dev/null +++ b/armdebug/Debugger/_c_arm_macros.h @@ -0,0 +1,88 @@ +/** @file _c_arm_macros.h + * @brief Define macros to support shared C and ASM headers + * + */ + +/* Copyright (C) 2010 the NxOS developers + * + * Module Developed by: TC Wan + * + * Thanks to Bartli (forum post @ embdev.net ARM programming with GCC/GNU tools forum) + * + * See AUTHORS for a full list of the developers. + * + * See COPYING for redistribution license + * + */ + +#ifndef __C_ARM_MACROS__ +#define __C_ARM_MACROS__ + + +#ifdef __ASSEMBLY__ + +#define NULL 0x0 +#define FALSE 0 +#define TRUE ~FALSE + +#define TYPEDEF @ +#define FUNCDEF @ + + .set last_enum_value, 0 + .macro enum_val name + .equiv \name, last_enum_value + .set last_enum_value, last_enum_value + 1 + .endm + +#define ENUM_BEGIN .set last_enum_value, 0 + +#define ENUM_VAL(name) enum_val name +#define ENUM_VALASSIGN(name, value) \ + .set last_enum_value, value ;\ + enum_val name +#define ENUM_END(enum_name) + +#else /* C Defines */ +/** Macro to control typedef generation + * + */ +#define TYPEDEF typedef + +/** Macro to control extern generation + * + */ +#ifndef FUNCDEF +#define FUNCDEF extern +#endif + +/** Macro to control typedef enum generation + * + */ +#define ENUM_BEGIN typedef enum { + +/** Macro to specify enum instance (auto value assignment) + * + */ +#define ENUM_VAL(name) name, + +/** Macro to control enum specification and value assignment +* +*/ +#define ENUM_VALASSIGN(name, value) name = value, + +/** Macro to control enum named type generation + * + */ +#define ENUM_END(enum_name) } enum_name; + +#endif + +/* Example of how to use the ENUM definition macros +ENUM_BEGIN +ENUM_VAL(INIT) +ENUM_VAL(RESET) +ENUM_VAL(CONFIGURED) +ENUM_END(enum_label) +*/ + +#endif /* __C_ARM_MACROS__ */ diff --git a/armdebug/Debugger/abort_handler.S b/armdebug/Debugger/abort_handler.S new file mode 100644 index 0000000..dab25d1 --- /dev/null +++ b/armdebug/Debugger/abort_handler.S @@ -0,0 +1,106 @@ + +/* Copyright (C) 2007-2011 the NxOS developers + * + * Module Developed by: TC Wan + * + * See AUTHORS for a full list of the developers. + * + * Redistribution of this file is permitted under + * the terms of the GNU Public License (GPL) version 2. + */ +#define __ASSEMBLY__ +#include "debug_stub.h" +#include "debug_internals.h" + +#define PREFETCH_OFFSET 4 +#define DATA_OFFSET 8 + +/* Trap Abort Exceptions. + * On triggering, lr (R14) contains the previous mode's pc (R15). + * Based on example in Hohl, "ARM Assembly Language: Fundamentals and Techniques" + * Chapter 11, Example 11.1. + */ +/* + * NOTE: This routine closely mirrors the undef_handler routine, since we will store + * the ABORT stack frame in the UNDEF stack. + * In addition, since ARMDEBUG uses Abort mode, if the ABORT occurs while the + * debugger is running, the value of SP_abort is not valid. This should not happen + * in any case (it is a BUG if ARMDEBUG triggers an ABORT). + * + * We assume that the DEBUG stack holds only one stack frame and we will overwrite it. + * On entry, LR_undef contains the PC+4 for Prefetch Abort, and PC+8 for Data Abort. + * + * For the purpose of Debugging, the stack frame should present the PC (R15) as the address + * of the instruction that triggered the Abort. Hence we need to adjust R15 + * to point to the address of the ABORTed instruction. + * + * We will also store ABORT LR (next instruction pointer) and ABORT SPSR to the stack. + * + * For the handler, once the user registers have been stored in the DEBUG stack, the + * registers will be used as follows: + * + * R0: ABORT LR, then ABORT instruction address + * R1: SPSR + * R2: PC Offset, then Mode + * R3: DEBUG Stack Pointer (for Banked R13-R14 update) + * R4: Abort Type Enum + */ + +.text +.code 32 +.align 0 + + .extern dbg__display_abort_info + .extern dbg__abort_exception_handler + .extern default_prefetch_abort_handler + .extern default_data_abort_handler + + + dbg_interwork prefetch_abort_handler + ldr sp, =__debugger_stack__ + stmfd sp, {r0-r15}^ /* Save workspace, previous mode's pc via 'S' flag, R13-R15: placeholders */ + mov r2, #PREFETCH_OFFSET + mov r4, #DISP_ABORT_PREFETCH /* Display Abort Info Type */ + mov r5, #DBG_ABORT_PREFETCH /* Debugger Abort Type */ + b _common_abort_handler + + dbg_interwork data_abort_handler + ldr sp, =__debugger_stack__ + stmfd sp, {r0-r15}^ /* Save workspace, previous mode's pc via 'S' flag, R13-R15: placeholders */ + mov r2, #DATA_OFFSET + mov r4, #DISP_ABORT_DATA /* Display Abort Info Type */ + mov r5, #DBG_ABORT_DATA /* Debugger Abort Type */ + +_common_abort_handler: + sub r0, lr, r2 /* R0: Adjust PC to ABORTed instruction address */ + str r0, [sp, #-4] /* Save ABORTed Instruction PC to stack (R15 slot) */ + sub r3, sp, #4 /* Use R3 to write Banked R13-R14 of ABORT instruction, update R3 to point to R14 slot */ + + mrs r1, spsr /* Copy SPSR to r1 */ + tst r1, #CPSR_THUMB /* Check for Thumb Mode */ + addne r0, r0, #2 /* Is Thumb instruction, adjust PC for ABORT next instruction address */ + addeq r0, r0, #4 /* Is ARM instruction, adjust PC for ABORT next instruction address */ + sub sp, sp, #(4*16) /* Need to manually update SP(abort) */ + stmfd sp!, {r0,r1} /* Save ABORTed Next Instr Pointer (in R0) and previous mode's CPSR to stack */ + + and r2, r1, #CPSR_MODE /* Get previous mode */ + teq r2, #MODE_USR + beq _exit_abort_handler /* Can't switch back if we're in User mode! */ + +_store_prev_mode_banked_regs: + /* FIXME: We don't handle FIQ properly! */ + + orr r2, #(CPSR_FIQ | CPSR_IRQ) /* Disable Interrupts */ + msr cpsr_c, r2 /* Switch to previous mode */ + stmfd r3!, {sp, lr} /* Store Previous Mode's LR (R14), SP (R13) via R3 */ + msr cpsr_c, #(MODE_ABT | CPSR_FIQ | CPSR_IRQ) /* Revert to ABORT Mode */ + +_exit_abort_handler: + ldr sp, =__abort_stack__ /* Reinitialize stack pointer each time an Abort happens */ + bic sp, sp, #7 + mov r0, r4 /* Copy Display Abort Type Enum to R0 */ + bl dbg__display_abort_info /* Display Abort Type to LCD */ + mov r0, r5 /* Copy Debugger Abort Type Enum to R0 */ + b dbg__abort_exception_handler /* Invoke Debugger */ + + diff --git a/armdebug/Debugger/debug_comm.S b/armdebug/Debugger/debug_comm.S new file mode 100644 index 0000000..b4590eb --- /dev/null +++ b/armdebug/Debugger/debug_comm.S @@ -0,0 +1,550 @@ +/** @file debug_comm.S + * @brief GDB Server communications support routines + * + */ + +/* Copyright (C) 2007-2011 the NxOS developers + * + * Module Developed by: TC Wan + * + * See AUTHORS for a full list of the developers. + * + * See COPYING for redistribution license + * + */ + +#define __ASSEMBLY__ +#include "debug_macros.h" +#include "debug_stub.h" +#include "debug_internals.h" + + .extern dbg__sendCommMsg + + /* Hexutils function references */ + .extern hex2char + .extern char2hex + .extern byte2ascii + .extern halfword2ascii_be + .extern halfword2ascii_le + .extern word2ascii_be + .extern word2ascii_le + .extern ascii2hex_varlen_be + .extern ascii2byte + .extern ascii2halfword_be + .extern ascii2halfword_le + .extern ascii2word_be + .extern ascii2word_le + + +.bss +.align 4 + + .global debug_InCommBuf + .global debug_OutCommBuf +debug_InCommBuf: + .space USB_BUFSIZE,0 +debug_OutCommBuf: + .space USB_BUFSIZE,0 + +debug_msgRxBufPtr: + .word 0x0 +debug_msgTxBufPtr: + .word 0x0 + +debug_msgRxBuf_AppendPtr: + .word 0x0 +debug_msgTxBuf_AppendPtr: + .word 0x0 + + .equ RXAPPENDPTR_OFFSET, (debug_msgRxBuf_AppendPtr - debug_msgRxBufPtr) + .equ TXAPPENDPTR_OFFSET, (debug_msgTxBuf_AppendPtr - debug_msgTxBufPtr) + +debug_segmentRxNum: /* Current Rx Segment Number */ + .word 0x0 + +/* Comm Channel and NXT Received Message Length is now common to both NxOS and NXT Firmware */ +debug_nxtMsgLength: + .word 0x0 + + .global debug_nxtCommChannel +debug_nxtCommChannel: + .word 0x0 + + .global debug_nxtCommOverrun +debug_nxtCommOverrun: + .word 0x0 + + .equ NXTCOMMCHANNEL_OFFSET, (debug_nxtCommChannel - debug_nxtMsgLength) + .equ NXTCOMMOVERRUN_OFFSET, (debug_nxtCommOverrun - debug_nxtMsgLength) + +.data +.align 4 + +nxt_commcmd_header: + .byte NXT_GDBMSG_TELEGRAMTYPE, 0x00, 0x00 /* padded to 3 bytes */ + +.code 32 +.text +.align 4 +/* Debugger Communications Routines + * It does not make sense to pass information from the Debugger Module to the Comm. link one character + * at a time, especially if we're not using a native serial interface (e.g., EIA-232). Consequently + * a Message interface has been defined. This can still call getChar() and putChar() subroutines + * if so desired, but it'll be a purely internal matter. + * + * Message Format + * Since we need to use EP1&2 (Bulk channels) to communicate with the PC Host, the messages should + * follow the NXT Direct Commands message structure (this will allow for interoperability with NXT Firmware + * in addition to NxOS). The maximum length of any USB communications via the Bulk channel is 64 bytes. + * There is a one byte Telegram Type field which identifies the type of telegram, followed by the + * Telegram header and actual message. + * + * The LEGO Mindstorms Communications Protocol Direct Commands GDB Message format (including all headers) + * is as follows: + * + * GDB Command + * =========== + * Byte 0: Telegram Type Field (0x8d Direct Command, No response required) | NXT Msg Header + * Byte 1: Segment No (1-255, 0: Last Segment; limit is MSG_NUMSEGMENTS) | + * Byte 2: Telegram Size (Len of USB Buffer - 3, max is MSG_SEGMENTSIZE) | + * Byte 3-N: Message data | GDB Command + * + * The GDB Command (of size M) has the following format: + * Offset 0: '+'/'-' Command Received Status (Optional) + * Offset 1/0: '$' + * Offset 2/1: GDB Command char + * Offset 3 - (M-4): Command packet info + * Offset M-3: '#' + * Offset M-2: MSB of Checksum + * Offset M-1: LSB of Checksum + * + * To be safe, we assume that the Command Received Status is always sent by the GDB server. Therefore, + * The maximum size of a GDB Command packet is MSGBUF_SIZE - 5 ('+'/'-', '$', '#', 2 byte checksum) + * + * GDB Response + * ============ + * Byte 0: Telegram Type Field (0x8d Direct Command, No response required) | NXT Msg Header + * Byte 1: Segment No (1-255, 0: Last Segment; limit is MSG_NUMSEGMENTS) | + * Byte 2: Telegram Size (Len of USB Buffer - 3, max is MSG_SEGMENTSIZE) | + * Byte 3-N: Message data | GDB Response + * + * The GDB Retransmission Request has the following format: + * Offset 0: '-' Command Received Status + * + * The GDB Response (of size M) has the following format: + * Offset 0: '+' Command Received Status + * Offset 1: '$' + * Offset 2 - (M-4): Response packet info + * Offset M-3: '#' + * Offset M-2: MSB of Checksum + * Offset M-1: LSB of Checksum + * + * The maximum size of a GDB Response packet is MSGBUF_SIZE - 5 ('+', '$', '#', 2 byte checksum) + * + * Note: The Telegram Size is the actual size of the Message Data portion + * (i.e., excludes the three header bytes, includes the GDB Command/Response Packet checksum bytes + * in the last segment) + */ + +/* dbg__comm_init + * Initialize communications channel. + * On Entry: + * R0: MSG Rx Buf Pointer + * R1: MSG Tx Buf Pointer + */ + + dbg_interwork dbg__comm_init + stmfd sp!, {lr} + ldr r2, =debug_msgRxBufPtr + stmia r2!, {r0, r1} /* debug_msgRxBufPtr and debug_msgTxBufPtr */ + stmia r2!, {r0, r1} /* debug_msgRxBuf_AppendPtr and debug_msgTxBuf_AppendPtr */ + bl _dbg__comm_readbuf_reset + ldr r1, =debug_nxtMsgLength + mov r0, #0 + str r0, [r1, #NXTCOMMCHANNEL_OFFSET] /* Clear NXT Channel on INIT */ + ldmfd sp!, {pc} + + +_dbg__comm_readbuf_reset: + ldr r1, =debug_nxtMsgLength + mov r0, #0 + str r0, [r1] /* Clear Received Comm Message Length */ + bx lr + +/* dbg__copyNxtDebugMsg + * Copy NXT Debug Message to our own Buffers, indicate Msg Received status. + * Note: This routine is now used by both NXT Firmware and NxOS + * On Entry: + * R0: NXT Input Buf Pointer + * R1: NXT Communications Channel Enum (CmdBit) + * R2: NXT Raw Message Length + * On Exit: + * R0-R3: Destroyed + */ + dbg_interwork dbg__copyNxtDebugMsg + ldr r3, =debug_nxtMsgLength + str r1, [r3, #NXTCOMMCHANNEL_OFFSET] /* save Communications Channel first */ + ldr r1, [r3] /* Check if there's an unread message in the buffer */ + cmp r1, #0 + beq cont_dbg__copyNxtDebugMsg /* No unread message, so continue */ +exit_dbg__NxtDebugMsgOverrun: + ldr r1, [r3, #NXTCOMMOVERRUN_OFFSET] + add r1, r1, #1 + str r1, [r3, #NXTCOMMOVERRUN_OFFSET] /* update message overrun stats */ + b exit_dbg__copyNxtDebugMsg +cont_dbg__copyNxtDebugMsg: + str r2, [r3] + ldr r1, =debug_InCommBuf + _dbg_memcpy r1, r0, r2, r3 /* r3: scratch register */ +exit_dbg__copyNxtDebugMsg: + bx lr + +/* _dbg_reset_msgTxBuf_AppendPtr + * Internal variable to reset pointers. + * On Exit: + * R0: debug_msgTxBuf_AppendPtr + * R1: destroyed + */ +_dbg_reset_msgTxBuf_AppendPtr: + ldr r1, =debug_msgTxBufPtr /* Should not be modified */ + ldr r0, [r1] + str r0, [r1, #TXAPPENDPTR_OFFSET] + mov pc, lr + +/* _dbg__commHasMsg + * Internal Segment Reassembly Routine. + * On exit: + * r0: !0: (Availale Telegram Message Size), 0: no incoming message/segment + * r1: message segment number + */ +_dbg__commHasMsg: + stmfd sp!, {lr} + ldr r0, =debug_nxtMsgLength + ldr r0, [r0] /* R0 contains the Comm Buffer Size, including the NXT Direct Command Header */ + + ldr r2, =debug_InCommBuf + ldrb r1, [r2, #NXT_MSG_TELEGRAMTYPE_OFFSET] + cmp r1, #NXT_GDBMSG_TELEGRAMTYPE + bne invalid_CommMsg /* Invalid telegram type, ignore */ + + ldrb r1, [r2, #NXT_MSG_TELEGRAMSIZE_OFFSET] + sub r0, r0, r1 /* Comm Buffer Size - Telegram Size = 3 (header size) */ + cmp r0, #NXT_GDBMSG_START /* Start offset is equal to header size */ + bne invalid_CommMsg /* Invalid Message Length, ignore */ + + mov r0, r1 /* Telegram Message Size */ + ldrb r1, [r2, #NXT_MSG_SEGNUM_OFFSET] + b _exit_dbg__commHasMsg + +invalid_CommMsg: + bl _dbg__comm_readbuf_reset /* Next Comm telegram transaction */ + mov r0, #0 +_exit_dbg__commHasMsg: + ldmfd sp!, {pc} + +/* _copy_msg_from_commbuf + * Internal Comm buffer copy routine, handles segment reassembly. + * On entry: + * r0: number of bytes to copy + * r1: segment number + * On exit: + * r0: cummulative message length + * r1: segment number + * r2, r3: Destroyed + */ +_copy_msg_from_commbuf: + stmfd sp!, {r1,r4,r5,r6,lr} + movs r4, r0 + beq _exit_copy_msg_from_commbuf + + ldr r6, =debug_msgRxBufPtr /* Address of Pointers */ + ldr r5, [r6] /* Rx buffer Start Address */ + ldr r2, [r6, #RXAPPENDPTR_OFFSET] /* Append Pointer */ + + sub r3, r2, r5 /* r3: current length of message */ + add r3, r3, r4 /* new cummulative length of message */ + cmp r3, #MSGBUF_SIZE + movhi r4, #0 /* Buffer overflow! */ + strhi r5, [r6, #RXAPPENDPTR_OFFSET] /* Reset AppendPtr to beginning of Rx Buffer */ + bhi _exit_copy_msg_from_commbuf + + ldr r3, =debug_InCommBuf + add r3, r3, #NXT_GDBMSG_START + _dbg_memcpy r2, r3, r4, r0 /* r2 updated to point to next empty char slot in Rx buffer */ + sub r4, r2, r5 /* r4: cummulative length of message */ + + /* Update debug_msgRxBuf_AppendPtr */ + teq r1, #0 /* Check if this is last segment (segment 0) */ + streq r5, [r6, #RXAPPENDPTR_OFFSET] /* Reset AppendPtr to beginning of Rx Buffer if so */ + strne r2, [r6, #RXAPPENDPTR_OFFSET] /* Otherwise, update Append Pointer to receive next segment */ + +_exit_copy_msg_from_commbuf: + bl _dbg__comm_readbuf_reset /* Next Comm telegram transaction */ + mov r0, r4 /* Return cummulative message length in R0 */ + ldmfd sp!, {r1,r4,r5,r6,pc} /* Return segment number in R1 */ + + +/* _msgbuf_checksum + * Internal routine to calculate checksum character buffer. + * On entry: + * r0: pointer to character buffer to checksum (assume ASCIIZ terminated) + * On exit: + * r0: pointer to character buffer after ASCIIZ + * r1: checksum (8-bit binary) + * r2: message length + * r3: destroyed + */ +_msgbuf_checksum: + mov r1, #0 /* clear checksum */ + mov r2, #0 /* clear length */ +1: ldrb r3, [r0], #1 /* Iterate through buffer */ + add r1, r1, r3 /* cummulative sum of char */ + teq r3, #0 + addne r2, r2, #1 /* increment message length */ + bne 1b /* until ASCIIZ found */ + and r1, #BYTE0 /* Modulo 256 */ + mov pc, lr + +/* dbg__getDebugMsg + * Retrieve pending Debugger Message if available (Non-Blocking). + * On entry: + * No parameters (assume pointers were initialized previously using dbg__comm_init) + * On exit: + * r0: >0 = Valid GDB Message Length (incl '$', excluding '#' and checksum), + * 0 = no valid message (yet), -1 = error + * r1: GDB Message Buffer Pointer (incl '$', excluding '#' and checksum) + * r2, r3: Destroyed + * Note: If GDB Message were returned, it is ASCIIZ terminated, does not include '#' and checksum + */ + dbg_interwork dbg__getDebugMsg + stmfd sp!, {r4,r5,lr} + bl _dbg__commHasMsg /* r0: message length, r1: segment number */ + teq r0, #0 + beq exit_dbg__getDebugMsg /* no new message, exit with R0 = 0 */ + + ldr r4, =debug_segmentRxNum + ldr r2, [r4] /* Get current Segment Number */ + add r2, r2, #1 /* Expected Segment Number for comparison */ + teq r1, #0 + streq r1, [r4] /* Update current Segment Number with 0 since it is the last segment */ + beq _hasMsg2Copy + cmp r1, #MSG_NUMSEGMENTS /* Segment Number < MSG_NUMSEGMENTS? */ + bhs _invalid_segment + teq r1, r2 /* Valid Segment Number, check against Expected Segment Number */ + beq _hasMsg2Copy /* Segment Number matches Expected Segment Number, update buffers */ + +_invalid_segment: + bl _dbg__comm_readbuf_reset /* Invalid, Next Comm telegram transaction */ + mov r0, #0 /* Reset Segment Number */ + str r0, [r4] /* Update current Segment Number with 0 to prepare for new message */ + b exit_dbg__getMsgError /* Exit with error */ + +_hasMsg2Copy: + str r1, [r4] /* Update current Segment Number */ + bl _copy_msg_from_commbuf /* r0: cummulative message length, r1: segment number */ + teq r1, #0 + movne r0, #0 /* Incomplete message, ignore for now */ + bne exit_dbg__getDebugMsg /* Message not complete yet, exit */ + + /* Check for valid GDB message */ + mov r4, r0 /* keep message length in R4, assume to be within MSGBUF_SIZE */ + ldr r5, =debug_msgRxBufPtr + ldr r5, [r5] /* Rx buffer Start Address */ + +/* Need to account for Packet Acknowledgement */ +1: ldrb r0, [r5] + teq r0, #MSGBUF_CTRLC /* Look for Ctrl-C */ + moveq r0, r4 /* If found, set R0 to current message length */ + beq exit_dbg__getDebugMsg /* and return */ + teq r0, #MSGBUF_NAKCHAR /* Look for '-' */ + beq exit_dbg__getMsgError /* Error from Host, Retransmit previous message */ + teq r0, #MSGBUF_ACKCHAR /* Look for '+' */ + addeq r5, r5, #1 /* Adjust Buffer Start Pointer (excl '+') */ + subeq r4, r4, #1 /* Adjust Message Length */ + beq 1b /* Skip all Packet Acknowledgements */ + + /* Note: Here we assume that we won't get a single ACK '+' or NAK '-' character message. + * If we do, it'll be flagged as an error + */ + subs r2, r4, #MSGBUF_CHKSUMOFFSET /* Look for '#': Message Length - 3 = '#' offset */ + blt exit_dbg__getMsgError /* Message Length is too short, exit with error */ + ldrb r0, [r5, r2] + teq r0, #MSGBUF_CHKSUMCHAR + bne exit_dbg__getMsgError /* No checksum char '#', exit with error */ + + mov r1, #0 + strb r1, [r5, r2] /* Zero out '#' char for checksum calc later */ + +#ifdef CHECK_GDBSTARTCHAR + /* Checked in dbg__bkpt_waitCMD */ + ldrb r0, [r5] + teq r0, #MSGBUF_STARTCHAR /* Look for '$' */ + bne exit_dbg__getMsgError /* No start char '$', exit with error */ +#endif + + add r0, r5, #1 /* Checksum packet data (excl '$') */ + bl _msgbuf_checksum /* R2: length (excl '$'), R1: calculated checksum, R0: pointer to checksum in receive buffer */ + mov r3, r1 /* Keep calculated checksum in R3 (R1 destroyed by ascii2byte) */ + bl ascii2byte /* R0: received checksum, R1: address of next buffer location */ + teq r0, r3 /* Compare calculated checksum in R3 against received checksum in R0 */ + bne exit_dbg__getMsgError /* Checksums do not match, exit with error */ + + subeq r0, r4, #MSGBUF_CHKSUMOFFSET /* Update message length (incl '$') as return parameter */ + add r2, r2, #1 /* expected message length (from _msgbuf_checksum) */ + teq r0, r2 + beq exit_dbg__getDebugMsg /* Valid length, return */ + +exit_dbg__getMsgError: + /* We must first clear the existing message checksum */ + ldr r1, =debug_msgTxBufPtr /* R5: data structure base pointer */ + ldr r1, [r1] /* Tx buffer Start Address */ + +1: ldrb r0, [r1], #1 + teq r0, #MSGBUF_CHKSUMCHAR + bne 1b + + mov r0, #0 /* ASCIIZ */ + strb r0, [r1, #-1] /* Pointer R1 is now one past the MSGBUF_CHKSUMCHAR */ + + bl dbg__putDebugMsg /* Retransmit message */ + mov r0, #0 /* Flag no message received */ + +#if 0 + mov r0, #MSGBUF_MSGERROR +#endif + +exit_dbg__getDebugMsg: + mov r1, r5 /* Return GDB Message Buffer Pointer in R1 */ + ldmfd sp!, {r4,r5,pc} + + +/* _copy_msg_to_commbuf + * Internal Comm buffer copy routine, handles segment fragmentation. + * On entry: + * r0: number of bytes to copy + * r1: segment number + * On exit: + * r0: cummulative message length + * r1: segment number + * r2, r3: Destroyed + */ +_copy_msg_to_commbuf: + stmfd sp!, {r1,r4,r5,r6,lr} + ldr r6, =debug_msgTxBufPtr /* Address of Pointers */ + ldr r5, [r6, #TXAPPENDPTR_OFFSET] /* Retrieve Tx Append Pointer */ + + movs r4, r0 + beq _exit_copy_msg_to_commbuf + +#ifdef CHECK_TXLEN + add r0, r4, #NXT_GDBMSG_START /* offset = header size */ + cmp r0, #USB_BUFSIZE + bhi _exit_copy_msg_to_commbuf /* We let calling routine detect problem (segment number will increment) */ +#endif + + /* Fill in Comm Message Header */ + ldr r3, =debug_OutCommBuf + mov r2, #NXT_GDBMSG_TELEGRAMTYPE + strb r2, [r3], #1 /* Telegram type */ + strb r1, [r3], #1 /* Segment Number */ + strb r0, [r3], #1 /* Message Length */ + + mov r2, r5 /* Copy to R2 for updating */ + mov r1, r4 /* actual GDB message fragment length (exclude Comm header) */ + _dbg_memcpy r3, r2, r1, r0 /* This copies over the message fragment, r3, r2 updated */ + mov r5, r2 /* Updated Tx Append Pointer, keep in R5 for now */ + + add r0, r4, #NXT_GDBMSG_START /* Total Comm Buffer Size for Tx (NXT_GDBMSG_START offset = header size) */ + bl dbg__sendCommMsg /* Common interface routine to commnuncations drivers */ + cmp r0, #TRUE + ldrne r5, [r6, #TXAPPENDPTR_OFFSET] /* Tx failed, Retrieve Original Tx Append Pointer */ + streq r5, [r6, #TXAPPENDPTR_OFFSET] /* Tx succeeded, Update Tx Append Pointer to new position */ + +_exit_copy_msg_to_commbuf: + ldr r6, [r6] /* Retrieve Tx Buffer Start Address */ + sub r0, r5, r6 /* Return calculated cummulative message length (R0) */ + ldmfd sp!, {r1,r4,r5,r6,pc} /* Return segment number in R1 */ + +/* dbg__putDebugMsg + * Sends Debugger Message from calling routine after appending checksum (Blocking) . + * On entry: + * No parameters (assume pointers were initialized previously using dbg__comm_init) + * On exit: + * r0: status (0: success, -1: error) + * Note: GDB Message to be sent must be ASCIIZ terminated, does not include '#' and checksum + * Response packets start with '+' followed by '$' (2 bytes prefix) + */ + dbg_interwork dbg__putDebugMsg + stmfd sp!, {r4,r5,lr} + /* Perform Checksum Calculation */ + ldr r5, =debug_msgTxBufPtr /* R5: data structure base pointer */ + ldr r4, [r5] /* Tx buffer Start Address */ + str r4, [r5, #TXAPPENDPTR_OFFSET] /* Reset Tx buffer Append Pointer */ + add r0, r4, #2 /* skip '+' and '$' */ + bl _msgbuf_checksum /* R2: length (excl '+' and '$'), R1: calculated checksum, R0: pointer to checksum in tx buffer */ + +#ifdef CHECK_TXLEN + add r2, r2, #2 /* r2: returned length from _msgbuf_checksum, added with prefix length */ + sub r3, r0, r4 /* r3: calculated length from pointers (incl. prefix length) */ + teq r2, r3 + bne exit_dbg__putMsgError +#endif + + mov r3, #MSGBUF_CHKSUMCHAR + strb r3, [r0, #-1] /* Insert '#' */ + bl byte2ascii /* On return, R0 points to location after checksum bytes, R1 is original pointer to checksum */ + sub r4, r0, r4 /* R4 = Calculated total message length (incl '+' and '$', '#' and checksum bytes */ + cmp r4, #MSG_SEGMENTSIZE /* If total message length > MSG_SEGMENTSIZE */ + mov r1, #0 /* Initialize Segment Number = 0 (last segment) first */ + mov r0, #0 /* Initial cummulative message length */ + mov r5, #0 /* Previous cummulative message length */ + + /* We assume unsigned message lengths, so the arithmetic MUST NOT result in negative values */ +_cont_putMsg: + cmp r4, r0 + movls r0, #0 /* R0: Exit status (success) */ + bls exit_dbg__putDebugMsg /* If Total message length (r4) <= Cummulative message length (r0), we're done */ + add r2, r0, #MSG_SEGMENTSIZE /* R2: calculate new Max cummulative message length */ + cmp r4, r2 /* Check total message length (R4) against new Max cummulative message length (R2) */ + subls r0, r4, r0 /* if total message length (R4) <= new Max cummulative message length (R2), send remainder */ + movls r1, #0 /* Flag as last segment (Segment Number = 0) */ + movhi r0, #MSG_SEGMENTSIZE /* else send MSG_SEGMENTSIZE bytes */ + addhi r1, r1, #1 /* Increment Segment Number */ + cmp r1, #MSG_NUMSEGMENTS + bhs exit_dbg__putMsgError /* If Segment Number >= MSG_NUMSEGMENTS, flag error */ + bl _copy_msg_to_commbuf /* R0: cummulative message length, R1: segment number */ + teq r5, r0 /* Check if we managed to transmit the previous message */ + beq exit_dbg__putMsgError /* No, flag error */ + movne r5, r0 /* Update previous cummulative message length */ + b _cont_putMsg + +exit_dbg__putMsgError: + mov r0, #MSGBUF_MSGERROR +exit_dbg__putDebugMsg: + ldmfd sp!, {r4,r5,pc} + +/* dbg__sendAckOrNak + * Send Ack (for successful receipt of message) + * or Nak (for Retransmission due to received message Checksum error) (Blocking) . + * On entry: + * No parameters (assume pointers were initialized previously using dbg__comm_init) + * On exit: + * r0: status (0: success, -1: error) + * r1: destroyed + * Note: An Ack Or Nak is indicated by '+' or '-', which is prepended with the Comm header and sent (without checksum) + * Sending Ack is only done for Continue and Step commands, where GDB does not expect any replies. + */ + dbg_interwork dbg__sendAckOrNak + stmfd sp!, {lr} + ldr r1, =debug_msgTxBufPtr /* R2: data structure base pointer */ + ldr r0, [r1] /* Tx buffer Start Address */ + str r0, [r1, #TXAPPENDPTR_OFFSET] /* Reset Tx buffer Append Pointer */ + + mov r1, #0 /* Initialize Segment Number = 0 (last segment) */ + mov r0, #1 /* Retransmission message length = 1 */ + bl _copy_msg_to_commbuf /* R0: cummulative message length, R1: segment number */ + cmp r0, #1 /* Check if we managed to transmit the previous message */ + moveq r0, #0 /* R0: Exit status (success) */ + movne r0, #MSGBUF_MSGERROR /* R0: Exit status (error) */ + ldmfd sp!, {pc} + diff --git a/armdebug/Debugger/debug_hexutils.S b/armdebug/Debugger/debug_hexutils.S new file mode 100644 index 0000000..267406f --- /dev/null +++ b/armdebug/Debugger/debug_hexutils.S @@ -0,0 +1,459 @@ +/** @file debug_hexutils.S + * @brief GDB hexadecimal conversion utility routines + * + */ + +/* Copyright (C) 2007-2011 the NxOS developers + * + * Module Developed by: TC Wan + * + * See AUTHORS for a full list of the developers. + * + * See COPYING for redistribution license + * + */ + + +#define __ASSEMBLY__ + +#include "debug_internals.h" + +.data +.align 4 + +hex2char_lut: + /* .ascii "0123456789ABCDEF" */ + /* Need to use lowercase hex chars to avoid confusion with GDB Error (E NN) response */ + .ascii "0123456789abcdef" + +/* Macros + */ + + +/* _hex2char_lut + * Internal routine to intialize the LUT address pointer + */ + .macro _hex2char_lut addrptr + ldr \addrptr, =hex2char_lut + .endm + +/* _hex2char_cont + * Internal routine that assumes that the LUT has been loaded. + * This macro accepts a byte sized hex value as a parameter register(7:0) and returns the + * ASCII equivalent in in the same register(7:0) + * The second parameter is the LUT address pointer register to use (assumed to be initialized) + * WARNING: Assumes that the value in register is sanity checked before invoking macro + */ + .macro _hex2char_cont reg, addrptr + ldrb \reg, [\addrptr, \reg] + .endm + +/* _hex2char + * This macro accepts a byte sized hex value as a parameter register(7:0) and returns the + * ASCII equivalent in in the same register(7:0) + * The second parameter is the LUT address pointer register to use (register content is destroyed) + * WARNING: Assumes that the value in register is sanity checked before invoking macro + */ + .macro _hex2char reg, addrptr + _hex2char_lut \addrptr + _hex2char_cont \reg, \addrptr + .endm + +/* _char2hex + * This macro accepts an ASCII char as a parameter register(7:0) and returns the + * equivalent byte sized hex value in in the same register(7:0) + * WARNING: Assumes that the char in register is a valid hex char before invoking macro + */ + .macro _char2hex reg + cmp \reg, #'A' /* If Alpha */ + bichs \reg, \reg, #ASCII_LOWER2UPPER_MASK /* Convert to Uppercase */ + subhs \reg, \reg, #7 /* Adjustment to allow for subtraction with 0x30 */ + sub \reg, \reg, #0x30 /* get final hex value */ + .endm + + +.code 32 +.text +.align 4 + + +/* Utility Routines + * GDB requires command parameters to be specified as Big Endian values. + * However, the read/write register command expect the register contents to be specified in target byte order. + * Hence we need both versions of multibyte conversion routines for word sized values. + */ + +/* hex2char + * This routine accepts a byte sized hex value in R0(7:0) and returns the + * ASCII equivalent in R0(7:0) + */ + .global hex2char + +hex2char: + stmfd sp!, {r1,lr} + and r0, #NIBBLE0 /* make sure that input is sane */ + _hex2char r0, r1 + ldmfd sp!, {r1,pc} + +/* char2hex + * This routine accepts an ASCII character in R0(7:0) and returns the + * equivalent byte sized hex value in R0(7:0). + * It accepts lowercase and uppercase ASCII Hex char inputs. + * Invalid inputs return -1 as the value +* On entry: + * R0: ASCII character + * On exit: + * R0: Hex value + */ + .global char2hex + +char2hex: + and r0, r0, #BYTE0 /* make sure that input is sane */ + cmp r0, #'0' + blo char2hex_error + cmp r0, #'9' + bls perform_char2hex + cmp r0, #'A' + blo char2hex_error + cmp r0, #'F' + bls perform_char2hex + cmp r0, #'a' + blo char2hex_error + cmp r0, #'f' + bhi char2hex_error + /* Validated Hex Char */ +perform_char2hex: + _char2hex r0 /* Return hex value in R0 */ + bx lr + +char2hex_error: + mov r0, #-1 /* Set Return value to Error value */ + bx lr + +/* byte2ascii_cont + * (Shared routine, does not perform sanity checks) + * On entry: + * R0: ASCII buffer pointer + * R1[7:0]: byte value + * On exit: + * R0: Address of next empty char slot in buffer + * R1: Destroyed + * + * This routine accepts an ASCII buffer pointer in R0 and a byte value in R1, + * and stores the ASCII equivalent byte value in the buffer pointed to by R0. + * Note: On return, R0 points to next empty char slot in buffer + */ +byte2ascii_cont: + stmfd sp!, {r2,r3,r4, lr} + lsl r2, r1, #24 /* Keep copy of input byte value R1[7:0], shifted to MSB R2[31:24] */ + mov r4, #2 /* Loop counter */ + _hex2char_lut r3 /* initialize LUT pointer */ +1: ror r2, r2, #28 /* Rotate MSNibble R2[31:28] into LSNibble position R2[3:0] */ + and r1, r2, #NIBBLE0 /* Mask out everything else, store Nibble in R1 */ + _hex2char_cont r1, r3 /* Convert nibble to ASCII char */ + strb r1, [r0], #1 + subs r4, r4, #1 /* decrement loop counter */ + bne 1b + ldmfd sp!, {r2,r3,r4, pc} + +/* byte2ascii + * On entry: + * R0: ASCII buffer pointer + * R1[7:0]: Byte value + * On exit: + * R0: Address of next empty char slot in buffer + * R1: Original Address of Buffer + * + * This routine accepts an ASCII buffer pointer in R0 and a byte value in R1, + * and stores the ASCII equivalent byte value in the buffer pointed to by R0. + * Note: On return, R0 points to the next empty char slot in buffer + */ + .global byte2ascii + +byte2ascii: + stmfd sp!, {r0, lr} /* Keep ASCII buffer pointer */ + and r1, #BYTE0 /* sanitize input */ + bl byte2ascii_cont + ldmfd sp!, {r1, pc} /* return original string pointer in R1 */ + +/* halfword2ascii_be + * Big Endian version of halfword2ascii conversion routine + * On entry: + * R0: ASCII buffer pointer + * R1[15:0]: Halfword value + * On exit: + * R0: Address of next empty char slot in buffer + * R1: Original Address of Buffer + * + * This routine accepts an ASCII buffer pointer in R0 and a halfword value in R1, + * and stores the ASCII equivalent halfword value in the buffer pointed to by R0. + * Note: On return, R0 points to the next empty char slot in buffer + */ + .global halfword2ascii_be +halfword2ascii_be: + stmfd sp!, {r0,r2,r3, lr} /* Keep ASCII buffer pointer */ + mov r3, #2 /* Loop Counter */ + mov r2, r1, lsl #16 /* copy of input halfword value R1[15:0], shifted to MSH R2[31:16] */ + b _conv_byte2ascii_be /* goto Byte conversion loop */ + +/* halfword2ascii_le + * Little Endian version of halfword2ascii conversion routine + * On entry: + * R0: ASCII buffer pointer + * R1[15:0]: Halfword value + * On exit: + * R0: Address of next empty char slot in buffer + * R1: Original Address of Buffer + * + * This routine accepts an ASCII buffer pointer in R0 and a halfword value in R1, + * and stores the ASCII equivalent halfword value in the buffer pointed to by R0. + * Note: On return, R0 points to the next empty char slot in buffer + */ + .global halfword2ascii_le +halfword2ascii_le: + stmfd sp!, {r0,r2,r3, lr} /* Keep ASCII buffer pointer */ + mov r3, #2 /* Loop Counter */ + b _conv_byte2ascii_le /* goto Byte conversion loop */ + + +/* word2ascii_be + * Big Endian version of word2ascii conversion routine + * On entry: + * R0: ASCII buffer pointer + * R1[31:0]: Word value + * On exit: + * R0: Address of next empty char slot in buffer + * R1: Original Address of Buffer + * + * This routine accepts an ASCII buffer pointer in R0 and a word value in R1, + * and stores the ASCII equivalent word value in the buffer pointed to by R0. + * Note: On return, R0 points to the next empty char slot in buffer + */ + .global word2ascii_be +word2ascii_be: + stmfd sp!, {r0,r2,r3, lr} /* Keep ASCII buffer pointer */ + mov r2, r1 /* copy of input word value R1[31:0] */ + mov r3, #4 /* Loop Counter */ + + /* Fall through to byte coversion loop */ + + +/* Big Endian Multibyte Convert: Rotate then convert */ +_conv_byte2ascii_be: + ror r2, r2, #24 /* Rotate MSB R2[31:24] into LSB position R2[7:0] */ + and r1, r2, #BYTE0 /* Copy byte value in R2[7:0] into R1 */ + bl byte2ascii_cont /* R0: next ASCII buffer location pointer, R1: destroyed */ + subs r3, r3, #1 + bne _conv_byte2ascii_be + ldmfd sp!, {r1,r2,r3, pc} + +/* word2ascii_le + * Little Endian version of word2ascii conversion routine + * On entry: + * R0: ASCII buffer pointer + * R1[31:0]: Word value + * On exit: + * R0: Address of next empty char slot in buffer + * R1: Original Address of Buffer + * + * This routine accepts an ASCII buffer pointer in R0 and a word value in R1, + * and stores the ASCII equivalent word value in the buffer pointed to by R0. + * Note: On return, R0 points to the next empty char slot in buffer + */ + .global word2ascii_le +word2ascii_le: + stmfd sp!, {r0,r2,r3, lr} /* Keep ASCII buffer pointer */ + mov r2, r1 /* copy of input word value R1[31:0] */ + mov r3, #4 /* Loop Counter */ + + /* Fall through to byte coversion loop */ + +/* Little Endian Multibyte Convert: Convert then rotate */ +_conv_byte2ascii_le: + and r1, r2, #BYTE0 /* Copy byte value in R2[7:0] into R1 */ + bl byte2ascii_cont /* R0: next ASCII buffer location pointer, R1: destroyed */ + ror r2, r2, #8 /* Rotate LSB+1 R2[15:8] into LSB position R2[7:0] */ + subs r3, r3, #1 + bne _conv_byte2ascii_le + ldmfd sp!, {r1,r2,r3, pc} + + +/* ascii2hex_varlen_be + * Big Endian version of ascii2hex_varlen conversion routine + * (There is no Little Endian Version) + * On entry: + * R0: ASCII buffer pointer + * On exit: + * R0: Hex value + * R1: Address of next char slot in buffer + * + * This routine accepts an ASCII buffer pointer in R0, + * and returns the hex value in R0 for up to 8 Hex characters. + * Note: On return, R1 points to the ASCII buffer location after the hex value chars. + */ + .global ascii2hex_varlen_be + +ascii2hex_varlen_be: + stmfd sp!, {r2,r3, lr} + mov r3, #CMD_REG_REGPARAMLEN /* Set max count to 8 (Max Register size) */ + mov r1, r0 /* Use R1 as ASCII buffer pointer */ + mov r2, #0 /* Initialize Cummulative Results */ +2: ldrb r0, [r1] /* Load ASCII char for Hex Value */ + bl char2hex /* on return, hex value in R0, -1 for error */ + cmp r0, #-1 + beq _exit_ascii2hex_varlen + orr r2, r0, r2, lsl #4 /* combined byte value */ + subs r3, r3, #1 /* Decrement Counter */ + add r1, r1, #1 /* Go to next char slot */ + bne 2b +_exit_ascii2hex_varlen: + mov r0, r2 /* Return results in R0 */ + ldmfd sp!, {r2,r3, pc} + + +/* ascii2byte + * On entry: + * R0: ASCII buffer pointer + * On exit: + * R0[7:0]: Byte value + * R1: Address of next char slot in buffer + * + * This routine accepts an ASCII buffer pointer in R0, + * and returns the byte value in R0[7:0]. + * Note: On return, R1 points to the ASCII buffer location after the current 2 chars. + * WARNING: This routine assumes that the input buffer was sanitized and contains valid Hex chars, + * otherwise it will return invalid results. + */ + .global ascii2byte + +ascii2byte: + stmfd sp!, {r2, lr} + mov r1, r0 /* Use R1 as ASCII buffer pointer */ + ldrb r0, [r1], #1 /* Load ASCII char for MSN */ + bl char2hex /* on return, hex value in R0, -1 for error (ignored) */ + mov r2, r0, lsl #4 /* Intermediate Results register */ + ldrb r0, [r1], #1 /* Load ASCII char for LSN */ + bl char2hex /* on return, hex value in R0, -1 for error (ignored) */ + orr r0, r2, r0 /* combined byte value */ + ldmfd sp!, {r2, pc} + +/* ascii2halfword_be + * Big Endian version of ascii2halfword conversion routine + * On entry: + * R0: ASCII buffer pointer + * On exit: + * R0[15:0]: Halfword value + * R1: Address of next char slot in buffer + * + * This routine accepts an ASCII buffer pointer in R0, + * and returns the Halfword value in R0[15:0]. + * Note: On return, R1 points to the ASCII buffer location after the current 4 chars. + * WARNING: This routine assumes that the input buffer was sanitized and contains valid Hex chars, + * otherwise it will return invalid results. + */ + .global ascii2halfword_be + +ascii2halfword_be: + stmfd sp!, {r2,r3, lr} + mov r3, #2 /* Loop counter */ + b _conv_ascii2byte_be + +/* ascii2halfword_le + * Little Endian version of ascii2halfword conversion routine + * On entry: + * R0: ASCII buffer pointer + * On exit: + * R0[15:0]: Halfword value + * R1: Address of next char slot in buffer + * + * This routine accepts an ASCII buffer pointer in R0, + * and returns the Halfword value in R0[15:0]. + * Note: On return, R1 points to the ASCII buffer location after the current 4 chars. + * WARNING: This routine assumes that the input buffer was sanitized and contains valid Hex chars, + * otherwise it will return invalid results. + */ + .global ascii2halfword_le + +ascii2halfword_le: + stmfd sp!, {r2,r3, lr} + mov r3, #2 /* Loop counter */ + b _conv_ascii2byte_le + + +/* ascii2word_be + * Big Endian version of ascii2word conversion routine + * On entry: + * R0: ASCII buffer pointer + * On exit: + * R0[31:0]: Word value + * R1: Address of next char slot in buffer + * + * This routine accepts an ASCII buffer pointer in R0, + * and returns the word value in R0[31:0]. + * Note: On return, R1 points to the ASCII buffer location after the current 8 chars. + * WARNING: This routine assumes that the input buffer was sanitized and contains valid Hex chars, + * otherwise it will return invalid results. + */ + .global ascii2word_be + +ascii2word_be: + stmfd sp!, {r2,r3, lr} + mov r3, #4 /* Loop counter */ + + /* Fall through to byte coversion loop */ + +_conv_ascii2byte_be: + teq r0, #0 + beq _exit_conv_ascii2byte_be /* exit if NULL pointer in R0 */ + mov r2, #0 /* Initialize Cummulative value */ +2: bl ascii2byte + orr r2, r0, r2, lsl #8 /* Merge current byte with cummulative value */ + mov r0, r1 /* Copy next char pointer to R0 for next byte */ + subs r3, r3, #1 + bne 2b + mov r0, r2 /* Copy it to R0 as return value */ + +_exit_conv_ascii2byte_be: + ldmfd sp!, {r2,r3, pc} /* return hex value in R0 */ + +/* ascii2word_le + * Litle Endian version of ascii2word conversion routine + * On entry: + * R0: ASCII buffer pointer + * On exit: + * R0[31:0]: Word value + * R1: Address of next char slot in buffer + * + * This routine accepts an ASCII buffer pointer in R0, + * and returns the word value in R0[31:0]. + * Note: On return, R1 points to the ASCII buffer location after the current 8 chars. + * WARNING: This routine assumes that the input buffer was sanitized and contains valid Hex chars, + * otherwise it will return invalid results. + */ + .global ascii2word_le + +ascii2word_le: + stmfd sp!, {r2,r3, lr} + mov r3, #4 /* Loop counter */ + + /* Fall through to byte coversion loop */ + +_conv_ascii2byte_le: + teq r0, #0 + beq _exit_conv_ascii2byte_le /* exit if NULL pointer in R0 */ + push {r3} /* Need to keep couter for final value adjustment */ + mov r2, #0 /* Initialize Cummulative value */ +2: bl ascii2byte + orr r2, r0, r2, ror #8 /* Merge current byte with cummulative value */ + mov r0, r1 /* Copy next char pointer to R0 for next byte */ + subs r3, r3, #1 + bne 2b + /* Cummulative value done, need to rotate it into the correct position for return value */ + pop {r3} /* retrieve counter */ + rsb r3, r3, #5 /* 5 - count */ + lsl r3, r3, #3 /* [(5-count) x 8] bits to rotate */ + mov r0, r2, ror r3 /* Copy it to R0 as return value */ + +_exit_conv_ascii2byte_le: + ldmfd sp!, {r2,r3, pc} /* return hex value in R0 */ + diff --git a/armdebug/Debugger/debug_internals.h b/armdebug/Debugger/debug_internals.h new file mode 100644 index 0000000..bdab463 --- /dev/null +++ b/armdebug/Debugger/debug_internals.h @@ -0,0 +1,395 @@ +/** @file debug_internals.h + * @brief Shared C/ASM header file for debugger internal constants + * + */ + +/* Copyright (C) 2007-2011 the NxOS developers + * + * Module Developed by: TC Wan + * + * See AUTHORS for a full list of the developers. + * + * See COPYING for redistribution license + * + */ + +#ifndef __DEBUG_INTERNALS_H__ +#define __DEBUG_INTERNALS_H__ + +#include "_c_arm_macros.h" + + +/** @addtogroup debugger */ +/*@{*/ + + +/* Declarations go here. */ +/** @name Debug Message Constants. + * + * Debug Message Values + */ +/*@{*/ + +/* + * USB Buffer Sizes: Ctrl Intr Iso Bulk + * Full Speed Device 64 64 1023 64 + * High Speed Device 64 1024 1024 512 + */ + +#define USB_BUFSIZE 64 /* USB Buffer size for AT91SAM7S */ + +#define NXT_MSG_TELEGRAMTYPE_OFFSET 0 /* NXT Direct Command/Response Header */ +#define NXT_MSG_SEGNUM_OFFSET 1 +#define NXT_MSG_TELEGRAMSIZE_OFFSET 2 + +#define NXT_GDBMSG_TELEGRAMTYPE 0x8d /* GDB debugger specific, no Response required */ + +#define NXT_GDBMSG_START 3 /* Offset into USB Telegram buffer */ + +#define MSG_NUMSEGMENTS 3 /* For packet transfers */ +#define MSG_SEGMENTSIZE (USB_BUFSIZE - NXT_GDBMSG_START) /* 61 bytes per segment */ +#define MSGBUF_SIZE (MSG_SEGMENTSIZE*MSG_NUMSEGMENTS) /* Debug Message Buffer Size, 61 x 3 = 183 chars = ~80 bytes of actual data */ +#define MSGBUF_CHKSUMOFFSET 3 /* to be subtracted from message length */ +#define MSGBUF_IN_OVERHEADLEN 5 /* For calculating max message data length (exclude ASCIIZ char) */ +#define MSGBUF_OUT_OVERHEADLEN 5 /* For calculating max message data length (exclude ASCIIZ char) */ + +#define MSGBUF_CTRLC 0x03 /* For Out of Band Signaling: not implemented yet */ +#define MSGBUF_STARTCHAR '$' +#define MSGBUF_ACKCHAR '+' +#define MSGBUF_NAKCHAR '-' +#define MSGBUF_ERRCHAR 'E' +#define MSGBUF_SIGCHAR 'S' +#define MSGBUF_SETCHAR '=' +#define MSGBUF_CHKSUMCHAR '#' +#define MSGBUF_SEPCHAR ',' +#define MSGBUF_ARGCHAR ':' +#define MSGBUF_MSGERROR -1 +/*@}*/ + +/** @name Debug Command Lookup Constants. + * + * Debug Command Lookup + */ +/*@{*/ + +#define CMDINDEX_OUTOFRANGE -1 +/*@}*/ + +/** @name Debug Register Command Constants. + * + * Debug Register Command + */ +/*@{*/ +#define CMD_REG_NUMREGS 17 +#define CMD_REG_GETONE_MINPARAMLEN 1 +#define CMD_REG_GETONE_MAXPARAMLEN 2 +#define CMD_REG_GETALL_PARAMLEN 0 +#define CMD_REG_REGPARAMLEN 8 /* 32-bit ASCII Hex Value */ +#define CMD_REG_SETONE_MINPARAMLEN (2 + CMD_REG_REGPARAMLEN) +#define CMD_REG_SETONE_MAXPARAMLEN (3 + CMD_REG_REGPARAMLEN) +#define CMD_REG_SETALL_PARAMLEN (CMD_REG_NUMREGS*CMD_REG_REGPARAMLEN) +#define CMD_KILL_PARAMLEN 0 +#define CMD_DETACH_PARAMLEN 0 + +/*@}*/ + +/** @name Debug Memory Command Constants. + * + * Debug Memory Command + * FIXME: These limits are not enforced by the GDB client, it truncates addresses and lengths to remove leading '0's + * The PARAMLEN constants would probably be removed + */ +/*@{*/ +#define CMD_NUMITEMS_PARAMLEN 4 /* 16-bit ASCII Hex Value */ +#define CMD_MEM_READ_PARAMLEN (CMD_REG_REGPARAMLEN + CMD_NUMITEMS_PARAMLEN + 1) /* Address length is equivalent to reg param len */ +#define CMD_MEM_WRITE_MINPARAMLEN (CMD_REG_REGPARAMLEN + CMD_NUMITEMS_PARAMLEN + 2) /* Address length is equivalent to reg param len */ +#define CMD_MEM_SEPCHAR_OFFSET CMD_REG_REGPARAMLEN /* Address length is equivalent to reg param len */ +#define CMD_MEM_MAXOUTBUFLEN (MSGBUF_SIZE - MSGBUF_OUT_OVERHEADLEN) +#define CMD_MEM_MAXREADBYTES (CMD_MEM_MAXOUTBUFLEN/2) +#define CMD_MEM_MAXINBUFLEN (MSGBUF_SIZE - MSGBUF_IN_OVERHEADLEN) +#define CMD_MEM_MAXWRITEBYTES ((CMD_MEM_MAXINBUFLEN - CMD_MEM_WRITE_MINPARAMLEN)/2) +/*@}*/ + +/** @name Debug Continue and Step Command Constants. + * + * Debug Continue and Step Command + */ +/*@{*/ +#define CMD_CONTINUE_MINPARAMLEN 0 +#define CMD_STEP_MINPARAMLEN 0 +/*@}*/ + +/** @name Debug Query Command Constants. + * + * Debug Query Command + */ +/*@{*/ +#define CMD_QUERY_MINPARAMLEN 0 +#define CMD_QUERY_CURRTID_PARAMLEN 1 +#define CMD_QUERY_FTINFO_PARAMLEN 11 +#define CMD_QUERY_STINFO_PARAMLEN 11 +#define CMD_QUERY_CURRTID_CHAR 'C' +#define CMD_QUERY_FTINFO_CHAR 'f' +#define CMD_QUERY_STINFO_CHAR 's' +/*@}*/ + + +/** @name Debug Breakpoint Command Constants. + * + * Debug Breakpoint Command + */ +/*@{*/ + +#define CMD_BKPT_INSERT_MINPARAMLEN 5 +#define CMD_BKPT_REMOVE_MINPARAMLEN 5 + + +#define CMD_BKPT_TYPE_BREAK_MEMORY 0 +#define CMD_BKPT_TYPE_BREAK_HARD 1 /* Not supported */ +#define CMD_BKPT_TYPE_WATCH_WRITE 2 /* Not supported (yet) */ +#define CMD_BKPT_TYPE_WATCH_READ 3 /* Not supported (yet) */ +#define CMD_BKPT_TYPE_WATCH_ACCESS 4 /* Not supported (yet) */ + +#define CMD_BKPT_KIND_THUMB 2 +#define CMD_BKPT_KIND_THUMB2 3 /* Not supported */ +#define CMD_BKPT_KIND_ARM 4 + +#define CMD_BKPT_NOTFOUND -1 + +/*@}*/ + +/** @name Debug Stack Constants. + * + * Debug Stack Manipulation Values + */ +/*@{*/ +#define DBGSTACK_NEXTINSTR_INDEX 0 /* Next Instruction Address is at index 0 from bottom of Debug Stack */ +#define DBGSTACK_USERCPSR_INDEX 1 /* User CPSR (SPSR_UNDEF) is at index 1 from bottom of Debug Stack */ +#define DBGSTACK_USERREG_INDEX 2 /* R0 starts at index 2 from bottom of Debug Stack */ +#define DBGSTACK_USERSP_INDEX (DBGSTACK_USERREG_INDEX + REG_SP) /* SP is R13 */ +#define DBGSTACK_USERLR_INDEX (DBGSTACK_USERREG_INDEX + REG_LR) /* LR is R14 */ +#define DBGSTACK_USERPC_INDEX (DBGSTACK_USERREG_INDEX + REG_PC) /* PC is R15 */ +/*@}*/ + + +/** @name Exception Handler Vector Definitions. + * + * Exception Handler Vectors. + */ +/*@{*/ + +#define RESET_VECTOR 0x00000000 +#define UNDEF_VECTOR 0x00000004 +#define SVC_VECTOR 0x00000008 +#define PABRT_VECTOR 0x0000000C +#define DABRT_VECTOR 0x00000010 +#define RESERVED_VECTOR 0x00000014 +#define IRQ_VECTOR 0x00000018 +#define FIQ_VECTOR 0x0000001C + + +/*@}*/ + + +/** @name Bitmask Definitions. + * + * Various Bitmasks used for data manipulation. + */ +/*@{*/ +#define BKPT_STATE_THUMB_FLAG 0x01 /* Flag Thumb Breakpoint */ +#define ASCII_LOWER2UPPER_MASK 0x20 /* ASCII Conversion bitmask */ +#define NIBBLE0 0x0000000F /* Nibble 0 word(3:0) */ +#define NIBBLE1 0x000000F0 /* Nibble 1 word(7:4) */ +#define NIBBLE2 0x00000F00 /* Nibble 2 word(11:8) */ +#define NIBBLE3 0x0000F000 /* Nibble 3 word(15:12) */ +#define NIBBLE4 0x000F0000 /* Nibble 4 word(19:16) */ +#define NIBBLE5 0x00F00000 /* Nibble 5 word(23:20) */ +#define NIBBLE6 0x0F000000 /* Nibble 6 word(27:24) */ +#define NIBBLE7 0xF0000000 /* Nibble 7 word(31:28) */ +#define BYTE0 0x000000FF /* Byte 0 word(7:0) */ +#define BYTE1 0x0000FF00 /* Byte 1 word(15:8) */ +#define BYTE2 0x00FF0000 /* Byte 2 word(23:16) */ +#define BYTE3 0xFF000000 /* Byte 3 word(31:24) */ +#define HLFWRD0 0x0000FFFF /* Halfword 0 word(15:0) */ +#define HLFWRD1 0xFFFF0000 /* Halfword 0 word(31:16) */ +/*@}*/ + +/** @name CPSR Bit Definitions. + * + * Various Bit definitions for accessing the CPSR register. + */ +/*@{*/ +#define CPSR_THUMB 0x00000020 +#define CPSR_FIQ 0x00000040 +#define CPSR_IRQ 0x00000080 +#define CPSR_MODE 0x0000001F +#define CPSR_COND 0xF0000000 + +/* ARM Exception Modes */ +#define MODE_USR 0x10 /* User mode */ +#define MODE_FIQ 0x11 /* FIQ mode */ +#define MODE_IRQ 0x12 /* IRQ mode */ +#define MODE_SVC 0x13 /* Supervisor mode */ +#define MODE_ABT 0x17 /* Abort mode */ +#define MODE_UND 0x1B /* Undefined mode */ +#define MODE_SYS 0x1F /* System mode */ + +/* Condition Flags + * b31 b30 b29 b28 + * N Z C V + */ +#define CPSR_NFLAG 0x80000000 +#define CPSR_ZFLAG 0x40000000 +#define CPSR_CFLAG 0x20000000 +#define CPSR_VFLAG 0x10000000 + + +/* + * ARM Opcode Masks (for Parser) + */ +#define ARM_DATA_INSTR_MASK 0x0FBF0000 +#define ARM_DATA_INSTR_MSRMRS 0x010F0000 +#define ARM_DATA_INSTR_NORMAL 0x01E00000 +#define ARM_DATA_INSTR_IMMREG 0x02000000 + +#define ARM_LDR_INSTR_REGIMM 0x02000000 +#define ARM_LDR_INSTR_PREPOST 0x01000000 +#define ARM_LDR_INSTR_UPDOWN 0x00800000 + +#define ARM_LDM_INSTR_PREPOST 0x01000000 +#define ARM_LDM_INSTR_UPDOWN 0x00800000 + +#define ARM_BLX_INSTR_MASK 0xFE000000 +#define ARM_BLX_INSTR_BLX 0xFA000000 +#define ARM_BLX_INSTR_HBIT 0x01000000 + +#define ARM_SWI_INSTR_MASK 0x0F000000 +#define ARM_SWI_INSTR_VAL 0x0F000000 + + +/* + * Thumb Opcode Masks (for Parser) + */ +#define THUMB_BLX_INSTR_REG_RNMASK 0x0078 + +#define THUMB_BCOND_SWI_INSTR_CONDMASK 0x0F00 +#define THUMB_BCOND_SWI_COND_UNUSED 0x0E00 +#define THUMB_BCOND_SWI_INSTR_SWI 0x0F00 + +#define THUMB_BLX_INSTR_IMM_HBIT 0x0800 +#define THUMB_BLX_INSTR_IMM_MASK 0xF000 +#define THUMB_BLX_INSTR_IMM_BL 0xF000 +#define THUMB_BLX_INSTR_IMM_BLX 0xE000 + +/*@}*/ + +/** Debugger State Enums + * + * Debugger State. + * The enums must be consecutive, starting from 0 + */ +ENUM_BEGIN +ENUM_VALASSIGN(DBG_RESET, 0) /**< Initial State. */ +ENUM_VAL(DBG_INIT) /**< Debugger Initialized. */ +ENUM_VAL(DBG_CONFIGURED) /**< Debugger has been configured by GDB Server */ +ENUM_END(dbg_state_t) + +/** Breakpoint Type Enums + * + * Breakpoint Type. + * The enums must be consecutive, starting from 0 + */ +ENUM_BEGIN +ENUM_VALASSIGN(DBG_AUTO_BKPT,0) /**< RESERVED: Auto Breakpoint (Instruction resume after breakpoint). */ +ENUM_VAL(DBG_MANUAL_BKPT_ARM) /**< Manual ARM Breakpoint. */ +ENUM_VAL(DBG_NORMAL_BKPT_ARM) /**< Normal ARM Breakpoint (Single Step, Normal). */ +ENUM_VAL(DBG_MANUAL_BKPT_THUMB) /**< Manual Thumb Breakpoint. */ +ENUM_VAL(DBG_NORMAL_BKPT_THUMB) /**< Normal Thumb Breakpoint (Single Step, Normal). */ +ENUM_VAL(DBG_ABORT_PREFETCH) /**< Prefetch Abort. */ +ENUM_VAL(DBG_ABORT_DATA) /**< Data Abort. */ +ENUM_END(bkpt_type_t) + +/** Debugger Message Signal Enums + * + * Debugger Signal Message Enums. + * The enums must be consecutive, starting from 0 + */ +/* Need to sync with the Signal enums in ecos-common-hal_stub.c */ +ENUM_BEGIN +ENUM_VALASSIGN(MSG_SIG_DEFAULT, 0) /**< Default Signal Response. */ +ENUM_VAL(MSG_SIG_HUP) /**< Hangup Signal Response. */ +ENUM_VAL(MSG_SIG_INT) /**< Interrupt Signal Response. */ +ENUM_VAL(MSG_SIG_QUIT) /**< Quit Signal Response. */ +ENUM_VAL(MSG_SIG_ILL) /**< Illegal Instruction Signal Response (not reset when caught). */ +ENUM_VAL(MSG_SIG_TRAP) /**< Trace Trap Signal Response (not reset when caught). */ +ENUM_VAL(MSG_SIG_ABRT) /**< Abort Signal Response (replace SIGIOT). */ +ENUM_VAL(MSG_SIG_EMT) /**< EMT Instruciton Signal Response. */ +ENUM_VAL(MSG_SIG_FPE) /**< Floating Point Exception Signal Response. */ +ENUM_VAL(MSG_SIG_KILL) /**< Kill Signal Response (cannot be caught or ignored). */ +ENUM_VAL(MSG_SIG_BUS) /**< Bus Error Signal Response. */ +ENUM_VAL(MSG_SIG_SEGV) /**< Segmentation Violation Signal Response. */ +ENUM_VAL(MSG_SIG_SYS) /**< Bad Argument to System Call Signal Response. */ +ENUM_VAL(MSG_SIG_PIPE) /**< Write on a Pipe with No Reader Signal Response. */ +ENUM_VAL(MSG_SIG_ALRM) /**< Alarm Clock Signal Response. */ +ENUM_VAL(MSG_SIG_TERM) /**< Software Termination Signal from Kill Signal Response. */ +ENUM_END(dbg_msg_signo) + +/** Debugger Message Error Enums + * + * Debugger Error Message Enums. + * The enums must be consecutive, starting from 1 + */ +/* FIXME: Need to validate against the ecos-generic-stub.c Error enums */ +ENUM_BEGIN +ENUM_VALASSIGN(MSG_ERRIMPL, 0) /**< Stub (not implemented) Error. */ +ENUM_VAL(MSG_ERRINLENGTH) /**< Message Write Length Error. */ +ENUM_VAL(MSG_ERROUTLENGTH) /**< Message Read Length Error. */ +ENUM_VAL(MSG_ERRFORMAT) /**< Message Format Error. */ +ENUM_VAL(MSG_UNKNOWNCMD) /**< Unrecognized Command Error. */ +ENUM_VAL(MSG_UNKNOWNPARAM) /**< Unrecognized Parameter Error. */ +ENUM_VAL(MSG_UNKNOWNBRKPT) /**< Unrecognized Breakpoint Error. */ +ENUM_END(dbg_msg_errno) + +/** Register Enums + * + * Register Enums. + * Refer to eCOS's arm_stub.h for enum values + */ +ENUM_BEGIN +ENUM_VALASSIGN(REG_R0, 0) /**< User Reg R0 */ +ENUM_VAL(REG_R1) /**< User Reg R1 */ +ENUM_VAL(REG_R2) /**< User Reg R2 */ +ENUM_VAL(REG_R3) /**< User Reg R3 */ +ENUM_VAL(REG_R4) /**< User Reg R4 */ +ENUM_VAL(REG_R5) /**< User Reg R5 */ +ENUM_VAL(REG_R6) /**< User Reg R6 */ +ENUM_VAL(REG_R7) /**< User Reg R7 */ +ENUM_VAL(REG_R8) /**< User Reg R8 */ +ENUM_VAL(REG_R9) /**< User Reg R9 */ +ENUM_VAL(REG_R10) /**< User Reg R10 */ +ENUM_VAL(REG_R11) /**< User Reg R11 */ +ENUM_VAL(REG_R12) /**< User Reg R12 */ +ENUM_VAL(REG_SP) /**< Previous Mode SP (R13) */ +ENUM_VAL(REG_LR) /**< Previous Mode LR (R14) */ +ENUM_VAL(REG_PC) /**< Program Counter (R15) */ +ENUM_VALASSIGN(REG_FPSCR, 24) /**< Previous Mode FPSCR (dummy) */ +ENUM_VAL(REG_CPSR) /**< Previous Mode CPSR */ + +ENUM_END(register_enum_t) + +/** Abort Type Enums + * + * Abort Type used for interfacing with LCD Display routine. + * The enums must be consecutive, starting from 0 + * Note: The values must align with those defined in NxOS's _abort.h + */ +ENUM_BEGIN +ENUM_VALASSIGN(DISP_ABORT_PREFETCH,0) /**< Prefetch Abort. */ +ENUM_VAL(DISP_ABORT_DATA) /**< Data Abort. */ +ENUM_VAL(DISP_ABORT_SPURIOUS) /**< Spurious IRQ. */ +ENUM_VAL(DISP_ABORT_ILLEGAL) /**< Illegal Instruction. */ +ENUM_END(abort_type_t) + +/*@}*/ + +#endif /* __DEBUG_INTERNALS_H__ */ diff --git a/armdebug/Debugger/debug_macros.h b/armdebug/Debugger/debug_macros.h new file mode 100644 index 0000000..d852f38 --- /dev/null +++ b/armdebug/Debugger/debug_macros.h @@ -0,0 +1,463 @@ +/** @file debug_macros.h + * @brief internal macros used by debug_stub routines + * + */ + +/* Copyright (C) 2007-2010 the NxOS developers + * + * Module Developed by: TC Wan + * + * See AUTHORS for a full list of the developers. + * + * See COPYING for redistribution license + * + */ + +#ifndef __DEBUG_MACROS_H__ +#define __DEBUG_MACROS_H__ + + + + +/*@{*/ + +/** _dbg_jumpTableHandler + * Call Jump Table Routine based on Index + * On entry: + * @param jumptableaddr is the address (constant) of the Jump Table + * @param jumpreg is the register used to perform the indirect jump + * @param indexreg contains jump table index value + */ + .macro _dbg_jumpTableHandler jumptableaddr, jumpreg, indexreg + + ldr \jumpreg, =\jumptableaddr + ldr \jumpreg, [\jumpreg, \indexreg, lsl #2] + mov lr, pc + bx \jumpreg /* Call Command Handler Routine */ + .endm + + +/** _dbg_thumbDecodeEntry + * Load Thumb Instruction Decoder Entry + * On entry: + * @param instrreg is the register to load the instruction into + * @param instrmask is the register to load the instruction mask into + * @param codehandler is the register to load the code handling routine into + * @param indexreg contains decode table index value + * NOTE: instrreg, instrmask, codehandler must be in increasing register number order + */ + .macro _dbg_thumbDecodeEntry instrreg, instrmask, codehandler, indexreg + + ldr \instrmask, =debug_thumbDecodeTable /* Temporary register */ + add \instrmask, \instrmask, \indexreg, lsl #3 + ldm \instrmask, {\instrreg, \codehandler} /* LSHW: IID, MSHW: IBM */ + mov \instrmask, \instrreg, lsr #16 + mov \instrreg, \instrreg, lsl #16 + mov \instrreg, \instrreg, lsr #16 /* Keep HLFWORD0 containing instruction */ + .endm + +/** _dbg_armDecodeEntry + * Load ARM Instruction Decoder Entry + * On entry: + * @param instrreg is the register to load the instruction into + * @param instrmask is the register to load the instruction mask into + * @param codehandler is the register to load the code handling routine into + * @param indexreg contains decode table index value + * NOTE: instrreg, instrmask, codehandler must be in increasing register number order + */ + .macro _dbg_armDecodeEntry instrreg, instrmask, codehandler, indexreg + + ldr \instrmask, =debug_armDecodeTable /* Temporary register */ + add \instrmask, \instrmask, \indexreg, lsl #3 + add \instrmask, \instrmask, \indexreg, lsl #2 /* 12 byte entries */ + ldm \instrmask, {\instrreg, \instrmask, \codehandler} + .endm + +/** _asciiz + * Terminate string given string buffer pointer in \strptr + * scratchreg is used as a scratch register (destroyed) + * + */ + .macro _asciiz strptr, scratchreg + mov \scratchreg, #0 /* ASCIIZ character */ + strb \scratchreg, [\strptr] /* Terminate ASCII string */ + .endm + + +/** _dbg_stpcpy + * _dbg_stpcpy macro + * On entry: + * deststrptr: Destination string + * sourcestrptr: Source string + * scratchreg: scratch register for copying + * On exit: + * deststrptr: Pointer to ASCIIZ character in destination string + * sourcestrptr: Pointer to next character slot in source string (after ASCIIZ) + * scratchreg: destroyed + */ + .macro _dbg_stpcpy deststrptr, sourcestrptr, scratchreg +1: ldrb \scratchreg, [\sourcestrptr], #1 + strb \scratchreg, [\deststrptr], #1 + teq \scratchreg, #0 + bne 1b + sub \deststrptr, \deststrptr, #1 /* Adjust Destination string pointer to point at ASCIIZ character */ + .endm + +/** _dbg_memcpy + * _dbg_stpcpy macro + * On entry: + * deststrptr: Destination string + * sourcestrptr: Source string + * sizereg: Number of bytes to copy + * scratchreg: scratch register for copying + * On exit: + * deststrptr: Pointer to next character slot in destination string + * sourcestrptr: Pointer to next character slot in source string + * sizereg, scratchreg: destroyed + */ + .macro _dbg_memcpy deststrptr, sourcestrptr, sizereg, scratchreg +1: ldrb \scratchreg, [\sourcestrptr], #1 + strb \scratchreg, [\deststrptr], #1 + subs \sizereg, \sizereg, #1 + bne 1b + .endm + +/** _dbg_CopyMsg2OutputBuf + * Copies source message to output buffer + * On entry: + * R2: source message buffer (ASCIIZ terminated) + * On exit: + * R0: Pointer to Output Buffer ASCIIZ location + * R2-R3: destroyed + */ + .macro _dbg_CopyMsg2OutputBuf + ldr r0, =debug_OutMsgBuf + _dbg_stpcpy r0, r2, r3 + .endm + +/** _dbg_CopyMsg2OutputBuf_withParam + * Internal Routine called to output message with parameters + * Return Message with byte-sized parameter + * On entry: + * R1: byte-sized param + * R2: source message buffer (ASCIIZ terminated) + * On exit: + * R0: Pointer to Output Buffer ASCIIZ location + * R1-R3: destroyed + */ + .macro _dbg_CopyMsg2OutputBuf_withParam + _dbg_CopyMsg2OutputBuf /* R1 unchanged */ + bl byte2ascii /* R0 points to buffer position after byte value */ + _asciiz r0, r1 + .endm + +/** _dbg_outputAckOnlyFlag + * Return Flag ('+') for Continue or Step + * On exit: + * R0: Pointer to Output Buffer ASCIIZ location + * R2-R3: destroyed + */ + .macro _dbg_outputAckOnlyFlag + ldr r2, =debug_AckOnlyFlag /* ASCIIZ terminated */ + _dbg_CopyMsg2OutputBuf + .endm + + +/** _dbg_outputRetransmitFlag + * Return Flag ('-') for Checksum Error (retransmission needed) + * On exit: + * R0: Pointer to Output Buffer ASCIIZ location + * R2-R3: destroyed + */ + .macro _dbg_outputRetransmitFlag + ldr r2, =debug_RetransmitFlag /* ASCIIZ terminated */ + _dbg_CopyMsg2OutputBuf + .endm + +/** _dbg_outputMsgValidResponse + * Return Message with valid response ('+$') + * On exit: + * R0: Pointer to Output Buffer next character slot location + * R2-R3: destroyed + */ + .macro _dbg_outputMsgValidResponse + ldr r2, =debug_ValidResponsePrefix + _dbg_CopyMsg2OutputBuf + .endm + +/** _dbg_outputMsgStatusOk + * Return Message with Ok ('+$OK') status + * On exit: + * R0: Pointer to Output Buffer ASCIIZ location + * R2-R3: destroyed + */ + .macro _dbg_outputMsgStatusOk + ldr r2, =debug_OkResponse /* ASCIIZ terminated */ + _dbg_CopyMsg2OutputBuf + .endm + +/** _dbg_outputMsgCurrTID + * Return Message with Default Thread ID ('+$QC0') + * On exit: + * R0: Pointer to Output Buffer ASCIIZ location + * R2-R3: destroyed + */ + .macro _dbg_outputMsgCurrTID + ldr r2, =debug_ThreadIDResponse /* ASCIIZ terminated */ + _dbg_CopyMsg2OutputBuf + .endm + +/** _dbg_outputMsgFirstThreadInfo + * Return Message with Default Current Thread ID ('+$m0') + * On exit: + * R0: Pointer to Output Buffer ASCIIZ location + * R2-R3: destroyed + */ + .macro _dbg_outputMsgFirstThreadInfo + ldr r2, =debug_FirstThreadInfoResponse /* ASCIIZ terminated */ + _dbg_CopyMsg2OutputBuf + .endm + +/** _dbg_outputMsgSubsequentThreadInfo + * Return Message with Default Current Thread ID ('+$m0') + * On exit: + * R0: Pointer to Output Buffer ASCIIZ location + * R2-R3: destroyed + */ + .macro _dbg_outputMsgSubsequentThreadInfo + ldr r2, =debug_SubsequentThreadInfoResponse /* ASCIIZ terminated */ + _dbg_CopyMsg2OutputBuf + .endm + +/** _dbg_outputMsgStatusErr + * Return Message with Error ('+$ENN') status + * On entry: + * R1: error code + * On exit: + * R0: Pointer to Output Buffer ASCIIZ location + * R1-R3: destroyed + */ + .macro _dbg_outputMsgStatusErr + ldr r2, =debug_ErrorResponsePrefix + _dbg_CopyMsg2OutputBuf_withParam + .endm + +/** _dbg_outputMsgStatusErrCode + * Return Message with Error ('+$ENN') status + * On exit: + * R0: Pointer to Output Buffer ASCIIZ location + * R1-R3: destroyed + */ + .macro _dbg_outputMsgStatusErrCode errcode + mov r1, #\errcode + _dbg_outputMsgStatusErr + .endm + +/** _dbg_outputMsgStatusSig + * Return Message with Signal ('+$SNN') status + * On entry: + * R1: signal code + * On exit: + * R0: Pointer to Output Buffer ASCIIZ location + * R1-R3: destroyed + */ + .macro _dbg_outputMsgStatusSig + ldr r2, =debug_SignalResponsePrefix + _dbg_CopyMsg2OutputBuf_withParam + .endm + +/** _dbg_outputMsgStatusSigCode + * Return Message with Signal ('+$SNN') status + * On exit: + * R0: Pointer to Output Buffer ASCIIZ location + * R1-R3: destroyed + */ + .macro _dbg_outputMsgStatusSigCode statuscode + mov r1, #\statuscode + _dbg_outputMsgStatusSig + .endm + + +/** _regenum2index + * Convert register enum to debugger stack index + * + * On entry: + * @param indexenum: enum representing Register to access + * @param indexreg: register to be used to store the debugger stack index value (0-max index) + * On exit: + * @param indexreg contains debugger stack index value (0-max index) + */ + .macro _regenum2index indexenum, indexreg + add \indexreg, \indexenum, #DBGSTACK_USERREG_INDEX /* Convert register index to Debug Stack index */ + .endm + +/** _getdbgregisterfromindex + * Retrieve register contents from debugger stack given index + * + * On entry: + * @param indexreg contains debugger stack index value (0-max index) + * On exit: + * @param indexreg: Breakpoint index (preserved) + * @param contentsreg: Register Contents for given index + */ + .macro _getdbgregisterfromindex indexreg, contentsreg + ldr \contentsreg, =__debugger_stack_bottom__ + ldr \contentsreg, [\contentsreg, \indexreg, lsl #2] + .endm + +/** _setdbgregisterfromindex + * Store register contents to debugger stack given index + * + * On entry: + * @param indexreg contains debugger stack index value (0-max index) + * @param contentsreg: Register Contents for given index + * @param addressreg: Scratch register for address pointer + * On exit: + * @param indexreg: Breakpoint index (preserved) + * @param contentsreg: Register Contents for given index + */ + .macro _setdbgregisterfromindex indexreg, contentsreg, addressreg + ldr \addressreg, =__debugger_stack_bottom__ + str \contentsreg, [\addressreg, \indexreg, lsl #2] + .endm + +/** _getdbgregister + * Retrieve register contents from debugger stack given immediate index value + * + * On entry: + * @param indexval contains debugger stack index value (0-max index) + * On exit: + * @param contentsreg: Register Contents for given index + */ + .macro _getdbgregister indexval, contentsreg + ldr \contentsreg, =__debugger_stack_bottom__ + ldr \contentsreg, [\contentsreg, #(\indexval << 2)] + .endm + +/** _setdbgregister + * Store register contents to debugger stack given immediate index value + * + * On entry: + * @param indexval contains debugger stack index value (0-max index) + * @param contentsreg: Register Contents for given index + * @param addressreg: Scratch register for address pointer + * On exit: + * @param contentsreg: Register Contents for given index + * @param addressreg: Destroyed + */ + .macro _setdbgregister indexval, contentsreg, addressreg + ldr \addressreg, =__debugger_stack_bottom__ + str \contentsreg, [\addressreg, #(\indexval << 2)] + .endm + +/** _index2bkptindex_addr + * Convert Breakpoint index to breakpoing entry address + * + * On entry: + * @param indexreg contains breakpoint index value + * On exit: + * @param indexreg: Breakpoint index (preserved) + * @param addrreg: Breakpoint Entry Address + */ + .macro _index2bkptindex_addr indexreg, addrreg + ldr \addrreg, =__breakpoints_start__ + add \addrreg, \addrreg, \indexreg, lsl #3 /* Calculate Breakpoint Entry Address */ + .endm + +/** _dbg_getstate + * Get Debugger State + * On exit: + * @param reg: Debugger State enum + */ + .macro _dbg_getstate reg + ldr \reg, =debug_state + ldrb \reg, [\reg] + .endm + +/** _dbg_setstate + * Set Debugger State to given value + * On exit: + * r0, r1: destroyed + */ + .macro _dbg_setstate state + mov r0, #\state + ldr r1, =debug_state + strb r0, [r1] + .endm + +/** _dbg_getmode + * Get Debugger Mode + * On exit: + * @param reg: Debugger Mode (Boolean) + */ + .macro _dbg_getmode reg + ldr \reg, =debug_mode + ldrb \reg, [\reg] + .endm + +/** _dbg_setmode + * Set Debugger Mode to given value + * On exit: + * r0, r1: destroyed + */ + .macro _dbg_setmode mode + mov r0, #\mode + ldr r1, =debug_mode + strb r0, [r1] + .endm + +/** _dbg_get_bkpt_type + * Get Breakpoint Type + * On exit: + * @param reg: Breakpoint Type + */ + .macro _dbg_get_bkpt_type reg + ldr \reg, =debug_bkpt_type + ldrb \reg, [\reg] + .endm + +/** _dbg_set_bkpt_type + * Set Breakpoint Type using value in reg + * On exit: + * @param reg: destroyed + * r1: destroyed + */ + .macro _dbg_set_bkpt_type reg + ldr r1, =debug_bkpt_type + strb \reg, [r1] + .endm + +/** _dbg_set_bkpt_type_val + * Set Breakpoint Type to given value + * On exit: + * r0, r1: destroyed + */ + .macro _dbg_set_bkpt_type_val bkpt_type + mov r0, #\bkpt_type + ldr r1, =debug_bkpt_type + strb r0, [r1] + .endm + +/** _dbg_getcurrbkpt_index + * Get current breakpoint index + * On exit: + * @param reg: Breakpoint index + */ + .macro _dbg_getcurrbkpt_index reg + ldr \reg, =debug_curr_breakpoint + ldrb \reg, [\reg] + .endm + +/** _dbg_setcurrbkpt_index + * Set current breakpoint index + * On exit: + * r1: destroyed + */ + .macro _dbg_setcurrbkpt_index reg + ldr r1, =debug_curr_breakpoint + strb \reg, [r1] + .endm + + /*@}*/ + +#endif /* __DEBUG_MACROS_H__ */ diff --git a/armdebug/Debugger/debug_opcodes.S b/armdebug/Debugger/debug_opcodes.S new file mode 100644 index 0000000..c264338 --- /dev/null +++ b/armdebug/Debugger/debug_opcodes.S @@ -0,0 +1,1031 @@ +/** @file debug_opcodes.S + * @brief ARM Debugger Opcode Parsing Routines + * + */ + +/* Copyright (C) 2007-2011 the NxOS developers + * + * Module Developed by: TC Wan + * + * See AUTHORS for a full list of the developers. + * + * See COPYING for redistribution license + * + */ + +#define __ASSEMBLY__ +#include "debug_stub.h" +#include "debug_internals.h" +#include "debug_macros.h" + +.data +.align 4 +/* Rm Shifted Shift Type Jump Table + * On entry: + * R0: Register Rm + * R1: Shift/Rotate Amount + * On exit: + * R0: RmShifted result + * + */ +debug_regShiftJumpTable: + .word _reg_lsl /* 00 */ + .word _reg_lsr /* 01 */ + .word _reg_asr /* 02 */ + .word _reg_ror /* 03 */ + .word _reg_rrx /* 04 */ + +/* Data Processing Instruction Jump Table + * On entry: + * R0: Register Rn (Operand 1) value + * R1: Operand 2 value + * R2: Default Next Instruction Address + * R5[3:0]: CPSR condition codes + * On exit: + * R0: Calculated result + * R1, R2, R3: Destroyed + * + */ +debug_dataInstrJumpTable: + .word _opcode_and /* 00 */ + .word _opcode_eor /* 01 */ + .word _opcode_sub /* 02 */ + .word _opcode_rsb /* 03 */ + .word _opcode_add /* 04 */ + .word _opcode_adc /* 05 */ + .word _opcode_sbc /* 06 */ + .word _opcode_rsc /* 07 */ + .word _opcode_tst /* 08 */ + .word _opcode_teq /* 09 */ + .word _opcode_cmp /* 0A */ + .word _opcode_cmn /* 0B */ + .word _opcode_orr /* 0C */ + .word _opcode_mov /* 0D */ + .word _opcode_bic /* 0E */ + .word _opcode_mvn /* 0F */ + + +/* + * To determine the next instruction to execute, we need to check current (breakpointed) instruction + * and determine whether it will be executed or not. This necessitates a mini instruction decoder + * that can check the type of instruction, as well as if it'll affect the PC. + * The instruction decoder used here is table based. Each entry in the table consists of: + * Instruction Identifier (IID), Instruction Bitmask (IBM), Instruction Handler Address (IHA) + * Null entries are placed at the end of the table. + * + * This allows for a flexible approach to handling instructions that we're interested in, at the expense + * of memory usage. + * + * For ARM, the IID & IBM are both 4 bytes, whereas the Thumb IID & IBM are 2 bytes. + * The IHA is always 4 bytes. + */ + +/* ARM Instruction Decode Table + * .word IID, IBM, IHA (12 bytes) + */ + +/* WARNING: The sequence of matching instructions is important! + * Always check from more specific to more general IBMs + * for instructions sharing common opcode prefix bits. + */ +debug_armDecodeTable: + .word 0x012fff10, 0x0ffffff0, _arm_bx_blx_handler /* [Prefix:00] BX or BLX. Note v4t does not have BLX instr */ + .word 0x0000f000, 0x0c00f000, _arm_data_instr_handler /* [Prefix:00] Data Processing instr with Rd = R15 */ +/* .word 0x06000010, 0x0e000010, _arm_undef_handler */ /* [Prefix:01] Undefined instr: shouldn't occur, as it would've been trapped already. See _dbg_following_instruction_addr */ + .word 0x0410f000, 0x0410f000, _arm_ldr_pc_handler /* [Prefix:01] LDR with Rd = PC */ + .word 0x08108000, 0x0e108000, _arm_ldm_pc_handler /* [Prefix:10] LDM {pc} */ + .word 0x0a000000, 0x0e000000, _arm_b_bl_blx_handler /* [Prefix:10] B, BL or BLX. Note v4t does not have BLX instr */ + .word 0x0c000000, 0x0c000000, _arm_coproc_swi_handler /* [Prefix:11] Coprocessor instr or SWI */ + .word 0x0,0x0,0x0 /* Null Entry */ + +/* Thumb Instruction Decode Table + * .hword IID, IBM + * .word IHA (8 bytes) + */ + +/* WARNING: The sequence of matching instructions is important! + * Always check from more specific to more general IBMs + * for instructions sharing common opcode prefix bits. + */ +debug_thumbDecodeTable: + .hword 0x4700, 0xff07 + .word _thumb_bx_blx_handler /* [Prefix:01] BX or BLX. Note: Link (L:b7) is not checked in the mask */ + .hword 0xbd00, 0xff00 + .word _thumb_poppc_handler /* [Prefix:10] PUSH/POP, specifically POP {Rlist,PC} */ + .hword 0xd000, 0xf000 + .word _thumb_bcond_swi_handler /* [Prefix:11] B or SWI */ + .hword 0xe000, 0xf800 + .word _thumb_b_handler /* [Prefix:11] B */ + .hword 0xf000, 0xf000 + .word _thumb_long_bl_blx_handler /* [Prefix:11] Long BL or BLX (4 bytes) Note: b11 (H) indicates 1st or 2nd instr */ + .hword 0x0,0x0 + .word 0x0 /* Null Entry */ + +/* ARM Condition Code Mapping Table + * Converts Instruction encoding to SPSR Flags. + * b31 b30 b29 b28 + * N Z C V + * Indexed according to Instruction Encoding order (pg 30, Table 6, ATMEL ARM7TDMI Data Sheet) + * Condition Code stored in MSN(set), LSN(clr) order + * Note1: 0x00 = AL. NV is deprecated, treat as AL + * Note2: 0xFF indicates that the condition checks needs to be handled separately (complex checks) + * + * EQ: Z set + * NE: Z clr + * HS/CS: C set + * LO/CC: C clr + * MI: N set + * PL: N clr + * VS: V set + * VC: V clr + */ + + +debug_armCondCodeTable: + /* EQ, NE, HS/CS, LO/CC, MI, PL, VS, VC, HI, LS, GE, LT, GT, LE, AL, NV */ + .byte 0x40, 0x04, 0x20, 0x02, 0x80, 0x08, 0x10, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00 + +/* ARM Complex Condition Code Mapping Table + * Converts Instruction encoding to SPSR Flags. + * b31 b30 b29 b28 + * N Z C V + * Indexed according to Instruction Encoding order (pg 30, Table 6, ATMEL ARM7TDMI Data Sheet) + * for HI, LS, GE, LT, GT and LE instructions only + * Condition Code stored in the following order: + * b7 b6 b5 b4 b3 b2 b1 b0 + * AND CHKZ CHKC CHKNV - Z set C set N==V (bit set = 1) + * OR - - - - Z clr C clr N!=V (bit clr = 0) + * + * HI: C set AND Z clr + * LS: C clr OR Z set + * GE: N == V + * LT: N != V + * GT: Z clr AND (N == V) + * LE: Z set OR (N != V) + */ + +#define COMPLEX_CONDCODE_START 0x08 +#define COMPLEX_CONDCODE_NEQV_MASK 0x01 +#define COMPLEX_CONDCODE_CSET_MASK 0x02 +#define COMPLEX_CONDCODE_ZSET_MASK 0x04 +#define COMPLEX_CONDCODE_CHKNV_MASK 0x10 +#define COMPLEX_CONDCODE_CHKC_MASK 0x20 +#define COMPLEX_CONDCODE_CHKZ_MASK 0x40 +#define COMPLEX_CONDCODE_ANDOR_MASK 0x80 + +#define COMPLEX_CONDCODE_NFLAG 0x08 +#define COMPLEX_CONDCODE_ZFLAG 0x04 +#define COMPLEX_CONDCODE_CFLAG 0x02 +#define COMPLEX_CONDCODE_VFLAG 0x01 + + +debug_armComplexCCTable: + /* HI, LS, GE, LT, GT, LE */ + .byte 0xE2, 0x64, 0x11, 0x10, 0xD1, 0x54 + +.code 32 +.text +.align 4 + +/* dbg_following_instruction_addr + * Determine the address of the following instruction to execute. + * On entry: + * R0: Address of the instruction to be (re)executed + * On exit: + * R0: Destroyed + * R1: Following Instruction Address (31 bits, b0 = THUMB flag) + * R2-R7: Destroyed + * + * Here we make use of the Debugger Stack which contains the address of the aborted instruction that will be reexecuted + * when we resume the program. + * + * If it is a Manual Breakpoint inserted into the code, then we will need to update the aborted instruction + * address to skip the current aborted instruction and resume execution at the next instruction address, + * and the next instruction address to be returned to the calling routine is the following instruction + * address instead. + * + * We need to check the aborted instruction type, to see if it is a branch instruction, before we can determine + * the next instruction address (for inserting a Breakpoint). + */ + .global dbg_following_instruction_addr +dbg_following_instruction_addr: + stmfd sp!, {lr} +/* We assume that any BKPT instructions in the code will be Manual Breakpoints, + * i.e., the Debugger does not leave stray Single Step / Auto / Normal breakpoints in memory + */ + mov r6, r0 /* Keep instruction address in R6 */ + _getdbgregister DBGSTACK_USERCPSR_INDEX, r1 /* Retrieve User CPSR into R1 */ + and r0, r1, #CPSR_THUMB /* store Thumb Mode status in R0 */ + mov r5, r1, lsr #28 /* store CPSR condition flags in R5[3:0] */ + +_dbg_get_aborted_instr: +1: teq r0, #0 /* Check if it is ARM or Thumb instruction */ + ldrneh r4, [r6] /* Load Thumb instruction opcode using Addr in R6 into R4 */ + ldrne r2, =(BKPT16_INSTR | BKPT16_MANUAL_BKPT) /* check for Thumb Manual Breakpoint Instruction */ + ldreq r4, [r6] /* Load ARM instruction opcode using Addr in R6 into R4 */ + ldreq r2, =(BKPT32_INSTR | BKPT32_MANUAL_BKPT) /* check for ARM Manual Breakpoint Instruction */ + teq r4, r2 /* Is instruction opcode (R4) == Manual Breakpoint opcode (R2)? */ + bne 2f /* Not Manual breakpoint */ + teq r0, #0 /* Check if it is ARM or Thumb Manual Breakpoint */ + addne r6, r6, #2 /* Is Manual Breakpoint, Skip to next Thumb instruction */ + addeq r6, r6, #4 /* Is Manual Breakpoint, Skip to next ARM instruction */ + b 1b /* To protect against a sequence of Manual Breakpoint Instructions */ + +/* Here, R4 contains the instruction opcode which will be (re)executed when program resumes. + * We need to dissect it to see if it is a branch instruction. + * For ARM instructions, we also need to evaluate the current (breakpointed) instruction to see if it'll execute. + * If not, then the following instruction is at the address following the address of the opcode in R4 (Default Following Instruction Address in R6). + */ +2: + teq r0, #0 /* Check if current instruction is ARM or Thumb instruction */ + beq _following_instr_addr_for_arm +_following_instr_addr_for_thumb: + add r6, r6, #2 /* Store default following Thumb instruction address to R6 */ +#if 0 + /* Flag Thumb instruction only within the instruction handler */ + orr r6, r6, #BKPT_STATE_THUMB_FLAG /* Set b0 to indicate Thumb instruction */ +#endif + /* R4: Candidate Instruction Opcode + * R5[3:0]: CPSR condition codes + * R6: Default Following Instruction Address (PC+2) + */ + bl _eval_thumb_instruction /* following address is either ARM or Thumb */ + /* We must set this the Thumb bit only within the instruction handler since BX would switch modes */ + b _exit_dbg_following_instruction_addr + +_following_instr_addr_for_arm: + add r6, r6, #4 /* Store default following ARM instruction address to R6 */ + /* R4: Candidate Instruction Opcode + * R5[3:0]: CPSR condition codes + * R6: Default Following Instruction Address (PC+4) + */ + bl _eval_arm_instruction + +_exit_dbg_following_instruction_addr: + mov r1, r0 /* Return Actual Following Instruction Address in R1 (B0 set to indicate Thumb mode) */ + ldmfd sp!, {pc} + + +/* _eval_arm_instruction + * Evaluate ARM instruction to determine following instruction address + * On entry: + * R4: Opcode of instruction to be executed + * R5[3:0]: CPSR condition codes + * R6: Default Following Instruction Address (PC+4) + * On exit: + * R0: following instruction address (B0 set to indicate Thumb mode) + * R1-R7: destroyed + */ +_eval_arm_instruction: + stmfd sp!, {lr} + bl _dbg_check_arm_condcode /* Returns R0: will_execute (boolean) */ + teq r0, #FALSE + moveq r0, r6 /* If False (don't execute), so use Default Following Instruction Address */ + beq _exit_eval_arm_instruction /* and Return to caller */ + +_will_execute_arm_instr: + mov r0, #0 /* initialize ARM Decode Entry Table index register */ +1: + _dbg_armDecodeEntry r1, r2, r3, r0 /* instrreg (R1), instrmask (R2), codehandler (R3), indexreg (R0) */ + teq r1, #0 /* Check for Null Entry (End of Table marker) */ + moveq r0, r6 /* End of Table, no match found, so use Default Following Instruction Address */ + beq _exit_eval_arm_instruction + and r7, r4, r2 /* Use R7 to check masked instruction opcode (from R4) to see if it matches template (in R1) */ + teq r7, r1 + addne r0, r0, #1 /* No match, so keep looking */ + bne 1b + +_call_arm_code_handler: + mov lr, pc + bx r3 /* Call Code Handler with R4: Instruction Opcode, R5[3:0]: CPSR, R6: Default Following Instruction Address */ +_exit_eval_arm_instruction: + /* Returned Following Address Instruction in R0 (B0 set to indicate Thumb mode) */ + ldmfd sp!, {pc} + +/* _eval_thumb_instruction + * Evaluate Thumb instruction to determine following instruction address + * On entry: + * R4: Opcode of instruction to be executed + * R5[3:0]: CPSR condition codes + * R6: Default Following Instruction Address (PC+2) + * On exit: + * R0: following instruction address (B0 set to indicate Thumb mode) + * R1-R7: destroyed + */ +_eval_thumb_instruction: + stmfd sp!, {lr} + /* Only B instructions are conditionally executed, deal with it in that Code Handler */ + mov r0, #0 /* initialize Thumb Decode Entry Table index register */ +1: + _dbg_thumbDecodeEntry r1, r2, r3, r0 /* instrreg (R1), instrmask (R2), codehandler (R3), indexreg (R0) */ + teq r1, #0 /* Check for Null Entry (End of Table marker) */ + moveq r0, r6 /* End of Table, no match found, so use Default Following Instruction Address */ + orreq r0, r0, #BKPT_STATE_THUMB_FLAG /* Set R0[0] to flag Thumb mode */ + beq _exit_eval_thumb_instruction + + and r7, r4, r2 /* Use R5 to check masked instruction opcode (from R4) to see if it matches template (in R1) */ + teq r7, r1 + addne r0, r0, #1 /* No match, so keep looking */ + bne 1b + +_call_thumb_code_handler: + mov lr, pc + bx r3 /* Call Code Handler with R4: Instruction Opcode, R5[3:0]: CPSR, R6: Default Following Instruction Address */ +_exit_eval_thumb_instruction: + /* Returned Following Address Instruction in R0 */ + ldmfd sp!, {pc} + + +/**************************************************************************** + * + * Instruction Decode Routines + * + ****************************************************************************/ + +/* _dbg_check_arm_condcode + * Check ARM conditional execution code + * On entry: + * R4: Opcode of instruction to be executed + * R5[3:0]: CPSR condition codes + * On exit: + * R0: will_execute (boolean) + * R1-R3: Destroyed + */ + +_dbg_check_arm_condcode: + mov r0, #TRUE /* Default will_execute value */ + mov r3, r4, lsr #28 /* convert opcode's condition code to index (0-F) */ + ldr r2, =debug_armCondCodeTable + ldrb r1, [r2, r3] /* Get condition code mask */ +/* + * The following check is unnecessary as it is covered by the _dbg_cond_simple_checks checking algorithm + teq r1, #0 + beq _dbg_check_arm_condcode_exit +*/ + teq r1, #0xFF + bne _dbg_cond_simple_checks + + +/* + * Complex Checks: + * We assume that CHKNV and CHKC are mutually exclusive. + * In addition, it is possible for CHKNV, CHKC and CHKZ to + * be cleared, in which case it'll return True (default) + * + * + * will_execute = TRUE [default condition] + * If (CHKNV) set + * // Only N/V, and Z flags are involved + * NEQV_Flag = (N == V) + * will_execute = (NEQV_Flag == NEQV_Mask) + * + * If (CHKC) set + * // Only C and Z flags are involved + * will_execute = (C_Flag == CSet_Mask) + * + * If (CHKZ) set + * z_match = (Z_Flag == ZSet_Mask) + * If (AND bit set) + * will_execute = will_execute && z_match + * else + * will_execute = will_execute || z_match + * + */ +_dbg_cond_complex_checks: + sub r3, r3, #COMPLEX_CONDCODE_START /* Convert complex condition code in R3 to new index (0-3) */ + ldr r2, =debug_armComplexCCTable + ldrb r1, [r2, r3] /* Get complex condition code bitmap in R1 */ + +_cond_check_nv: + tst r1, #COMPLEX_CONDCODE_CHKNV_MASK + beq _cond_check_c /* CHECKNV not set, so skip */ + ands r2, r5, #(COMPLEX_CONDCODE_NFLAG | COMPLEX_CONDCODE_VFLAG) /* Is (N == V == 0)? */ + teqne r2, #(COMPLEX_CONDCODE_NFLAG | COMPLEX_CONDCODE_VFLAG) /* No, Is (N == V == 1)? */ + + moveq r2, #COMPLEX_CONDCODE_NEQV_MASK /* EQ: Either (N == V == 0) or (N == V == 1), set R2: COMPLEX_CONDCODE_NEQV_MASK */ + movne r2, #0 /* NE: N != V, clear R2 */ + and r3, r1, #COMPLEX_CONDCODE_NEQV_MASK /* R3: Extract NEQV Mask Value */ + teq r2, r3 /* Does N/V Condition match NEQV Mask value? */ + movne r0, #FALSE /* No, so will_execute = FALSE (for now) */ + b _cond_check_z + +#if 0 + bne _cond_nnev /* No, so (N != V) */ + + /* EQ: Either (N == V == 0) or (N == V == 1) */ +_cond_neqv: + tst r1, #COMPLEX_CONDCODE_NEQV_MASK /* Is (N == V) mask set? */ + moveq r0, #FALSE /* No, so will_execute = FALSE (for now) */ + b _cond_check_z + + /* Else, N != V */ +_cond_nnev: + tst r1, #COMPLEX_CONDCODE_NEQV_MASK /* Is (N == V) mask set? */ + movne r0, #FALSE /* Yes, so will_execute = FALSE (for now) */ + b _cond_check_z +#endif + +_cond_check_c: + tst r1, #COMPLEX_CONDCODE_CHKC_MASK + beq _cond_check_z /* CHECKC not set, so skip */ + + /* Use R2 to store C Flag, R3 to store CSet Mask */ + and r2, r5, #COMPLEX_CONDCODE_CFLAG /* r2 = C flag */ + and r3, r1, #COMPLEX_CONDCODE_CSET_MASK /* r3 = CSet mask */ + teq r2, r3 /* Does C flag == CSet mask */ + movne r0, #FALSE /* No, so C flag failed match */ + +_cond_check_z: + tst r1, #COMPLEX_CONDCODE_CHKZ_MASK + beq _dbg_check_arm_condcode_exit /* No additional checks needed, exit */ + + /* Use R2 to store Z Flag, R3 to store ZSet Mask */ + and r2, r5, #COMPLEX_CONDCODE_ZFLAG /* r2 = Z flag */ + and r3, r1, #COMPLEX_CONDCODE_ZSET_MASK /* r3 = ZSet mask */ + teq r2, r3 /* Does Z flag == ZSet mask */ + moveq r3, #TRUE /* Zero, so z flag matched */ + movne r3, #FALSE /* Non-zero, so z flag failed match */ + +_cond_andor: + tst r1, #COMPLEX_CONDCODE_ANDOR_MASK /* Is ANDOR mask set? */ + andne r0, r0, r3 /* Yes, so AND with will_execute */ + orreq r0, r0, r3 /* No, so OR with will_execute */ + b _dbg_check_arm_condcode_exit /* Return will_execute (R0) */ + +/* + * Simple Checks: + * We take advantage of the fact that only 1 bit would be set + * in the bitmask, by generating the corresponding actual + * CondSet[7:4], CondClr[3:0] value for comparison. + * + * will_execute = TRUE [default condition, equivalent to 0x00 (AL) ] + * Generate CondSetClr[7:0] from CPSR[3:0] + * will_execute = ((CondSetClr & BitMask) == BitMask) + * + */ +_dbg_cond_simple_checks: + eor r2, r5, #NIBBLE0 /* R2: CondClr[3:0] = Invert CPSR[3:0] */ + orr r2, r2, r5, lsl #4 /* R2: CondSet[7:4] | CondClr[3:0] */ + and r2, r2, r1 /* R2: CondSetClr[7:0] & Bitmask */ + teq r2, r1 /* ((cond_code & SetBitMask) == SetBitMask)? */ + movne r0, #FALSE /* Not equal, check failed */ + +_dbg_check_arm_condcode_exit: + bx lr /* Return to caller */ + +/* _arm_rmshifted_val + * Calculate value of Shifted Rm (operand) + * On entry: + * R0[11:0]: Shifted Rm operand + * On exit: + * R0: value of Shifted Rm + * R1, R2, R3: destroyed + */ +_arm_rmshifted_val: + stmfd sp!, {lr} + ldr r3, =(NIBBLE2|BYTE0) + and r3, r0, r3 /* 12 bit Shifted Register operand, copied to R3 */ + and r2, r3, #NIBBLE0 /* Register Rn Enum in R2 */ + _regenum2index r2, r2 /* Convert Enum into Index in R2 */ + _getdbgregisterfromindex r2, r0 /* Retrieve Register Rn contents from Index (R2) into R0 */ + + tst r3, #0x10 /* B4: Immediate (0) or Register (1) shift count */ + /* check bitshift op */ + and r3, r3, #0x60 /* shift type */ + mov r3, r3, lsr #5 /* convert into shift type jumptable index */ + bne _arm_get_reg_shift /* Flags set previously via TST r3 (B4) */ +_arm_calc_const_shift: + movs r1, r3, lsr #7 /* Immediate shift count, 5 bit unsigned value in R1 */ + bne _arm_calc_shifted_rm_val /* Non-zero shift count, process normally */ + /* Must check for RRX == ROR #0 */ + teq r3, #0x3 /* ROR == 0x3 */ + addeq r3, r3, #1 + b _arm_calc_shifted_rm_val + +_arm_get_reg_shift: + mov r2, r3, lsr #8 /* Register-based shift count, 4 bit register enum in R2 */ + _regenum2index r2, r2 /* Convert Enum into Index in R2 */ + _getdbgregisterfromindex r2, r1 /* Retrieve Register value (shift count) from Index (R2) into R1 */ + +_arm_calc_shifted_rm_val: + _dbg_jumpTableHandler debug_regShiftJumpTable, r2, r3 /* Calculate RmShifted value from R0: Rn Register val, R1: Shift/Rotate val */ + ldmfd sp!, {pc} + +/* Rm Shifted Shift Type Jump Table Routines + * On entry: + * R0: Register Rm + * R1: Shift/Rotate Amount + * On exit: + * R0: RmShifted result + * R1: destroyed + * + */ +_reg_lsl: + lsl r0, r0, r1 + bx lr + +_reg_lsr: + lsr r0, r0, r1 + bx lr + +_reg_asr: + asr r0, r0, r1 + bx lr + +_reg_ror: + ror r0, r0, r1 + bx lr + +_reg_rrx: + _getdbgregister DBGSTACK_USERCPSR_INDEX, r1 /* Retrieve CPSR contents into R1 */ + ands r1, r1, #CPSR_CFLAG /* Keep C Flag */ + movne r1, #0x80000000 /* Set B31 if C Flag set */ + lsr r0, r0, #1 /* Rm >> 1 */ + orr r0, r0, r1 /* Put C flag into B31 */ + bx lr + + +/* _arm_data_instr_handler + * ARM Data Processing Instruction with Rd == R15 + * On entry: + * R4: Opcode of instruction to be executed + * R5[3:0]: CPSR condition codes + * R6: Default Following Instruction Address (PC+4) + * On exit: + * R0: following instruction address + * R1-R7: Destroyed + */ +_arm_data_instr_handler: + stmfd sp!, {lr} + ldr r1, =ARM_DATA_INSTR_MASK + and r3, r4, r1 /* Keep base instruction Opcode in R3 */ + ldr r1, =ARM_DATA_INSTR_MSRMRS + teq r3, r1 /* Check for MSR / MRS instruction */ + +_arm_is_msr_mrs_instr: + moveq r0, r6 /* Copy default next instruciton address to R0 */ + beq _exit_arm_data_instr_handler /* Return default next instruction address */ + + /* Not MSR / MRS, so process normally */ +_arm_check_operand2_type: + tst r4, #ARM_DATA_INSTR_IMMREG /* Check for Immediate (1) or Register (0) Operand 2 */ + beq _arm_op2_is_reg + +_arm_op2_is_imm: + and r1, r4, #BYTE0 /* 8 bit unsigned constant in R1 */ + and r2, r4, #NIBBLE2 /* (rotate count / 2) in R2[11:8] */ + lsr r2, r2, #7 /* actual rotate count in R2[4:0] */ + ror r1, r1, r2 /* Rotated constant in R1 */ + b _arm_get_operand1_val + +_arm_op2_is_reg: + ldr r1, =(NIBBLE2|BYTE0) + and r0, r4, r1 /* 12 bit register operand in R1 */ + bl _arm_rmshifted_val /* R0 contains the Rm shifted val */ + mov r1, r0 /* R1: Operand2 val */ + +_arm_get_operand1_val: + bl _dbg_data_instr_retrieve_op1val /* R0: Register Rn (Operand1) val */ + +_arm_calc_data_instr_val: + and r3, r4, #ARM_DATA_INSTR_NORMAL /* Mask Instruction Opcode into R3[24:21] */ + lsr r3, r3, #21 /* Shift Data Processing Opcode into R3[3:0] */ + /* Calculate data instruction value from R0: Register Rn (Operand1) val, R1: Operand2 val, R5[3:0]: CPSR, R6: Default Next Instr Addr */ + _dbg_jumpTableHandler debug_dataInstrJumpTable, r2, r3 /* Next Instruction Address in R0 */ +_exit_arm_data_instr_handler: + ldmfd sp!, {pc} + +/* _dbg_data_instr_retrieve_op1val + * Retrieve Data Instruction Operand 1 value + * On entry: + * R4: Opcode of instruction to be executed + * R5[3:0]: CPSR condition codes + * R6: Default Next Instruction Address (PC+4) + * On exit: + * R0: Register Rn (Operand 1) value + * R2, R3: Destroyed + * + */ +_dbg_data_instr_retrieve_op1val: + and r3, r4, #NIBBLE4 /* Store Rn (Operand1) Register Enum into R3[19:16] */ + lsr r3, r3, #16 /* Shift into R3[3:0] */ + _regenum2index r3, r2 /* Convert Enum into Index in R2 */ + _getdbgregisterfromindex r2, r0 /* Retrieve Register contents from Index (R2) into R0 */ + teq r3, #REG_PC /* Check if it is PC relative */ + addeq r0, r0, #8 /* R0: Register Rn (Operand1) val; adjust for PC relative (+8) */ + bx lr + +/* Data Processing Instruction Jump Table Routines + * On entry: + * R0: Register Rn (Operand 1) value + * R1: Operand 2 value + * R5[3:0]: CPSR condition codes + * R6: Default Next Instruction Address (PC+4) + * On exit: + * R0: Calculated result + * R1, R2, R3: Destroyed + * + */ +_opcode_and: + and r0, r0, r1 + bx lr + +_opcode_eor: + eor r0, r0, r1 + bx lr + +_opcode_sub: + sub r0, r0, r1 + bx lr + +_opcode_rsb: + rsb r0, r0, r1 + bx lr + +_opcode_add: + add r0, r0, r1 + bx lr + +_opcode_adc: + /* Op1 + Op2 + C */ + tst r5, #(CPSR_CFLAG>> 28) /* R5[3:0] is shifted CPSR value: Test C Flag */ + add r0, r0, r1 + addne r0, r0, #1 /* Add C if set */ + bx lr + +_opcode_sbc: + /* Op1 - Op2 + C - 1 */ + tst r5, #(CPSR_CFLAG>> 28) /* R5[3:0] is shifted CPSR value: Test C Flag */ + sub r0, r0, r1 + subeq r0, r0, #1 /* If C clear, subtract 1, else (C - 1) = 0 */ + bx lr + +_opcode_rsc: + /* Op2 - Op1 + C - 1 */ + tst r5, #(CPSR_CFLAG>> 28) /* R5[3:0] is shifted CPSR value: Test C Flag */ + rsb r0, r0, r1 + subeq r0, r0, #1 /* If C clear, subtract 1, else (C - 1) = 0 */ + bx lr + +_opcode_tst: +_opcode_teq: +_opcode_cmp: +_opcode_cmn: + mov r0, r6 /* Next Instruction Address is not modified */ + bx lr + +_opcode_orr: + orr r0, r0, r1 + bx lr + +_opcode_mov: + mov r0, r1 /* Operand 1 is ignored */ + bx lr + +_opcode_bic: + bic r0, r0, r1 + bx lr + +_opcode_mvn: + mvn r0, r1 /* Operand 1 is ignored */ + bx lr + +/* _arm_bx_blx_handler + * BX or BLX Rm Handler. Note v4t does not have BLX instr + * On entry: + * R4: Opcode of instruction to be executed + * R5[3:0]: CPSR condition codes + * R6: Default Following Instruction Address (PC+4) + * On exit: + * R0: following instruction address (B0 set to indicate Thumb mode) + * R1,R2: destroyed + */ +_arm_bx_blx_handler: + stmfd sp!, {lr} + and r2, r4, #NIBBLE0 /* Register Rn Enum in R2 */ + _regenum2index r2, r1 /* Convert Enum into Index in R1 */ + _getdbgregisterfromindex r1, r0 /* Retrieve Register contents from Index (R1) into R0 */ + teq r2, #REG_PC + addeq r0, r0, #8 /* Adjust PC relative register value (for BX PC) */ + /* Here, the register value would have B0 set to indicate switch to Thumb mode */ + ldmfd sp!, {pc} + +/* _arm_ldr_pc_handler + * LDR with Rd = PC + * On entry: + * R4: Opcode of instruction to be executed + * R5[3:0]: CPSR condition codes + * R6: Default Following Instruction Address (PC+4) + * On exit: + * R0: following instruction address + * R1, R2, R3, R4, R5: destroyed + */ + +_arm_ldr_pc_handler: + stmfd sp!, {lr} + + mov r1, #0 /* R1: Post-Indexed Offset (cleared) */ + tst r4, #ARM_LDR_INSTR_PREPOST /* Pre (1) or Post (0) Indexed */ + beq _get_rn_val /* If Post-Indexed, just use Rn directly */ + + /* Pre-Indexed */ + ldr r0, =(NIBBLE2|BYTE0) + and r0, r4, r0 /* R0: 12 bit Immediate value or Shifted Reg operand */ + tst r4, #ARM_LDR_INSTR_REGIMM /* Register (1) or Immediate (0) */ + beq _calc_ldr_pc_offset /* Immediate value is already in R0 */ + +_get_shiftedreg_val: + bl _arm_rmshifted_val /* Convert Rm shifted operand in R0 into value in R0 */ + +_calc_ldr_pc_offset: + mov r1, r0 /* Keep Offset in R1 */ +_get_rn_val: + bl _dbg_data_instr_retrieve_op1val /* R0: Register Rn (Operand1) val */ +_calc_op1val_with_offset: + tst r4, #ARM_LDR_INSTR_UPDOWN /* Add (1) or Subtract (0) */ + addne r0, r0, r1 /* If Add, R0 = Rn + Offset */ + subeq r0, r0, r1 /* If Sub, R0 = Rn - Offset */ + +_get_ldr_pc_val_from_mem: + ldr r0, [r0] /* Retrieve value from Memory at address given in R0 */ + ldmfd sp!, {pc} + +/* _arm_ldm_pc_handler + * LDM {pc} + * On entry: + * R4: Opcode of instruction to be executed + * R5[3:0]: CPSR condition codes + * R6: Default Following Instruction Address (PC+4) + * On exit: + * R0: following instruction address + * R2, R3: destroyed + * + * Note: The algorithm from eCos arm_stub.c does not deal with the Pre/Post-Indexed addressing (P) bit. + * The algorithm here loads different content using LDM based on the value of the P bit. + */ +_arm_ldm_pc_handler: + stmfd sp!, {lr} + bl _dbg_data_instr_retrieve_op1val /* R0: Register Rn (Operand1) val */ + +_arm_get_regcount: + mov r2, #0 /* Initialize reg_count (R2) to 0 */ + mov r3, r4, lsl #16 /* Keep HLFWORD0 containing vector bits in R3[31:16] */ + /* This shortens the checking to a max of 16 iterations, since the PC bit should be set */ +1: movs r3, r3, lsl #1 /* count number of '1' bits */ + addcs r2, r2, #1 /* increment reg_count (R2) if C Flag set */ + bne 1b /* continue until vector is empty */ + + /* Pre-Incr: Rn += reg_count x 4 + * Post-Incr: Rn += (reg_count - 1) x 4 + * Pre-Decr: Rn -= 4 + * Post-Decr: Rn + */ + +_arm_check_updown_offset: + tst r4, #ARM_LDM_INSTR_UPDOWN /* Check Up (1) or Down (0) */ + beq _arm_check_prepost_decr + +_arm_check_prepost_incr: + tst r4, #ARM_LDM_INSTR_PREPOST /* Check Pre (1) or Post (0) */ + subeq r2, r2, #1 /* Post-Incr: Decrement reg_count in R2 */ + add r0, r0, r2, lsl #2 /* Increment Offset: Rn (R0) += reg_count (R2) x 4 */ + b _get_ldm_pc_val_from_mem + +_arm_check_prepost_decr: + tst r4, #ARM_LDM_INSTR_PREPOST /* Check Pre (1) or Post (0) */ + /* Post-Decr: Rn unchanged */ + subne r0, r0, #4 /* Pre-Decr: Rn (R0) -= 4 */ + +_get_ldm_pc_val_from_mem: + ldr r0, [r0] /* Retrieve stack content for new PC value */ + ldmfd sp!, {pc} + + +/* _arm_b_bl_blx_handler + * B, BL or BLX . Note v4t does not have BLX instr + * On entry: + * R4: Opcode of instruction to be executed + * R5[3:0]: CPSR condition codes + * R6: Default Following Instruction Address (PC+4) + * On exit: + * R0: following instruction address + * R1: destroyed + */ + +_arm_b_bl_blx_handler: + stmfd sp!, {lr} + +_arm_b_bl_blx_get_offset: + and r0, r4, #(BYTE2|BYTE1|BYTE0) /* Encoded Branch offset in R4[23:0] */ + lsl r0, r0, #(32-24) /* Shift to R0[31:8] */ + asr r0, r0, #(32-26) /* Actual Signed offset = Encode Offset x 4 in R0[25:0] */ + add r1, r6, #4 /* R1: (PC+4) + 4 */ + add r0, r0, r1 /* Calculate Branch Target Address R0: (PC+8) + signed offset */ + +#ifndef __ARM6OR7__ + /* armv5t or later, has BLX support */ + and r1, r4, #ARM_BLX_INSTR_MASK /* Mask out Condition Code and Opcode */ + teq r1, #ARM_BLX_INSTR_BLX /* Look for BLX */ + bne _exit_arm_b_bl_blx_handler /* No, it is a B/BL instruction */ + tst r4, #ARM_BLX_INSTR_HBIT /* H bit for Thumb Halfword Address */ + orrne r0, r0, #0x02 /* Set Halfword Address R0[1] */ + orr r0, r0, #BKPT_STATE_THUMB_FLAG /* Set R0[0] since BLX instr used to switch to Thumb mode */ +#endif + +_exit_arm_b_bl_blx_handler: + ldmfd sp!, {pc} + +/* _arm_coproc_swi_handler + * SVC (SWI) or Coprocessor instruction + * On entry: + * R4: Opcode of instruction to be executed + * R5[3:0]: CPSR condition codes + * R6: Default Following Instruction Address (PC+4) + * On exit: + * R0: following instruction address + */ + +_arm_coproc_swi_handler: + and r0, r4, #ARM_SWI_INSTR_MASK + teq r0, #ARM_SWI_INSTR_VAL /* SVC (SWI) instruction */ + + ldreq r0, =SVC_VECTOR /* SWI: Return SVC Vector Address */ + movne r0, r6 /* CoProc: Use default Following Instruction Address */ +_exit_arm_coproc_swi_handler: + bx lr + +/* _thumb_bx_blx_handler + * BX or BLX Handler. Note: Link (L:b7) is not checked in the mask; armv4t does not support BLX. + * On entry: + * R4: Opcode of instruction to be executed + * R5[3:0]: CPSR condition codes + * R6: Default Following Instruction Address (PC+2) + * On exit: + * R0: following instruction address (B0 set to indicate Thumb mode) + * R1, R2: destroyed + */ +_thumb_bx_blx_handler: + stmfd sp!, {lr} + and r2, r4, #THUMB_BLX_INSTR_REG_RNMASK /* Register Rn Enum in R2[6:3] (Hi-Reg indicated by B6) */ + mov r2, r2, lsr #3 /* Shift Rn Enum to R2[3:0] */ + _regenum2index r2, r1 /* Convert Enum into Index in R1 */ + _getdbgregisterfromindex r1, r0 /* Retrieve Register contents from Index (R1) into R0 */ + teq r2, #REG_PC + addeq r0, r0, #4 /* Adjust PC relative register value (for BX PC) */ + /* Here, the register value would have R0[0] set to indicate switch to Thumb mode */ + ldmfd sp!, {pc} + +/* _thumb_poppc_handler + * PUSH/POP, specifically POP {Rlist,PC} + * On entry: + * R4: Opcode of instruction to be executed + * R5[3:0]: CPSR condition codes + * R6: Default Following Instruction Address (PC+2) + * On exit: + * R0: following instruction address (B0 set to indicate Thumb mode) + * R1-R3: destroyed + */ +_thumb_poppc_handler: + stmfd sp!, {lr} + +_thumb_get_SP_val: + _getdbgregister DBGSTACK_USERSP_INDEX, r1 /* Retrieve SP contents into R1 */ + +_thumb_get_regcount: + mov r3, r4, lsl #24 /* Keep BYTE0 containing vector bits in R3[31:24] */ + /* POP is equivalent to LDMFD. Load PC is encoded in b8, + * the 8-bit vector is for Lo registers. + * This shortens the checking to a max of 8 iterations + */ +1: movs r3, r3, lsl #1 /* count number of '1' bits */ + addcs r1, r1, #4 /* Walk the stack to locate the PUSHed LR (POP PC) value */ + bne 1b /* continue until vector is empty */ + ldr r0, [r1] /* Retrieve new PC value */ +#if 0 + /* PC Value should have B0 set */ + orr r0, r0, #BKPT_STATE_THUMB_FLAG /* Force R0[0] since it is used to indicates Thumb mode */ +#endif + ldmfd sp!, {pc} + +/* _thumb_bcond_swi_handler + * B or SWI (SVC) + * On entry: + * R4: Opcode of instruction to be executed + * R5[3:0]: CPSR condition codes + * R6: Default Following Instruction Address (PC+2) + * On exit: + * R0: following instruction address (B0 set to indicate Thumb mode) + * R1-R3: destroyed + */ +_thumb_bcond_swi_handler: + stmfd sp!, {lr} + and r2, r4, #THUMB_BCOND_SWI_INSTR_CONDMASK /* Keep Condition Code R2[11:8] */ + teq r2, #THUMB_BCOND_SWI_INSTR_SWI /* SVC (SWI) instruction */ +_thumb_swi_instr: + ldreq r0, =SVC_VECTOR /* Return SVC Vector Address */ + beq _exit_thumb_bcond_swi_handler /* Switch to ARM mode for SVC */ +_thum_bcond_unused_instr: + teq r2, #THUMB_BCOND_SWI_COND_UNUSED + moveq r0, r6 /* False (don't execute), so use Default Following Instruction Address */ + beq _exit_thumb_bcond_instr + +_thumb_bcond_instr: + stmfd sp!, {r4} /* Preserve Opcode in R4 */ + lsl r4, r2, #(32-12) /* Shift condition code in R2[11:8] to R0[31:28] to match ARM cond-code format */ + bl _dbg_check_arm_condcode /* Use ARM condition code checking routine to test (R4, R6 unchanged) */ + ldmfd sp!, {r4} /* Restore Opcode in R4 */ + teq r0, #FALSE + moveq r0, r6 /* False (don't execute), so use Default Following Instruction Address */ + beq _exit_thumb_bcond_instr + +_thumb_calc_bcond_offset: + lsl r0, r4, #(32-8) /* Shift 8-bit offset in R4[7:0] to R0[31:24] */ + asr r0, r0, #(32-9) /* Convert into 9-bit signed offset in R0[8:0] */ + add r0, r6, r0 /* PC+2 + signed offset */ + add r0, r0, #2 /* PC+4 + signed offset */ +_exit_thumb_bcond_instr: + orr r0, r0, #BKPT_STATE_THUMB_FLAG /* Set R0[0] since it is used to indicates Thumb mode */ +_exit_thumb_bcond_swi_handler: + ldmfd sp!, {pc} + +/* _thumb_b_handler + * B + * On entry: + * R4: Opcode of instruction to be executed + * R5[3:0]: CPSR condition codes + * R6: Default Following Instruction Address (PC+2) + * On exit: + * R0: following instruction address (B0 set to indicate Thumb mode) + * R1: destroyed + * Note: The signed offset is 12-bits (encoded value x 2) + */ +_thumb_b_handler: + stmfd sp!, {lr} + lsl r0, r4, #(32-11) /* Shift 11-bit offset in R4[10:0] to R0[31:21] */ + asr r0, r0, #(32-12) /* Convert into 12-bit signed offset in R0[11:0] */ + add r0, r6, r0 /* PC+2 + signed offset */ + add r0, r0, #2 /* PC+4 + signed offset */ + orr r0, r0, #BKPT_STATE_THUMB_FLAG /* Set R0[0] since it is used to indicates Thumb mode */ + ldmfd sp!, {pc} + +/* _thumb_long_bl_blx_handler + * Long BL or BLX (4 bytes) Note: b11 (H) indicates 1st or 2nd instr; armv4t does not support BLX. + * On entry: + * R4: Opcode of instruction to be executed + * R5[3:0]: CPSR condition codes + * R6: Default Following Instruction Address (PC+2) + * On exit: + * R0: following instruction address (B0 set to indicate Thumb mode) + * R1, R2, R3: destroyed + * R6: Subseqent Instruction Address (PC+4) if first instruction is valid, else unchanged (PC+2) + * Note: The BL instruction (0xFxxx) should be in pairs (Dual 16-bit instructions). + * The first instruction should have (H=0) to indicate the upper 11 bits of the encoded offset + * The second instruction should have (H=1) to indicate the lower 11 bits of the encoded offset + * The signed offset is 23 bits (encoded value x 2) + * + * Note2: The BLX instruction (0xExxx) encodes the first instruciton using BL (0xFxxx) with H=0, + * while the second instruction has a different opcode value (0xExxx), with H=1. + * BLX is only used to switch to an ARM target. + */ +_thumb_long_bl_blx_handler: + stmfd sp!, {lr} +_thumb_check_1st_bl_blx_instruction: + tst r4, #THUMB_BLX_INSTR_IMM_HBIT /* Check H bit */ + bne _return_default_thumb_following_instr /* H=1 as first instruction shouldn't happen */ +_thumb_check_2nd_bl_blx_instruction: + ldrh r3, [r6] /* Get second instruction in pair at PC+2 into R3 */ + add r6, r6, #2 /* Skip to Subsequent Instruction (PC+4) */ + tst r3, #THUMB_BLX_INSTR_IMM_HBIT /* Check H bit */ + beq _return_default_thumb_following_instr /* H=0 as second instruction shouldn't happen */ + +_thumb_concat_branch_offset: + lsl r0, r4, #(32-11) /* Shift first instruction 11-bit offset in R4[10:0] to R0[31:21] */ + asr r0, r0, #(32-23) /* Convert into 12-bit signed offset in R0[22:12] */ + lsl r2, r3, #(32-11) /* Shift second instruction 11-bit offset in R3[10:0] to R2[31:21] */ + lsr r2, r2, #(32-12) /* Convert into 12-bit unsigned offset in R2[11:0] */ + orr r0, r0, r2 /* Combine offsets */ + add r0, r6, r0 /* PC+4 + signed offset */ + +_thumb_check_bl_blx_pair: + and r3, r3, #THUMB_BLX_INSTR_IMM_MASK /* Keep second instruction opcode in R3 */ + teq r3, #THUMB_BLX_INSTR_IMM_BL /* Look for BL */ + beq _flag_thumb_instr_addr /* Return BL target address in R0 */ + +#ifndef __ARM6OR7__ + /* v5t or higher architecture */ + teq r3, #THUMB_BLX_INSTR_IMM_BLX /* Look for BLX */ + biceq r0, r0, #0x03 /* Match, Force ARM address */ + beq _exit_thumb_long_bl_blx_handler +#endif + +_return_default_thumb_following_instr: + /* FIXME: This assumes that once the 4-byte sequence check fails, it will return PC+4, + * regardless of whether the second instruction is a valid BL/BLX instruction or not. + */ + mov r0, r6 /* Return default Following/Subsequent Instruction Address */ +_flag_thumb_instr_addr: + orr r0, r0, #BKPT_STATE_THUMB_FLAG /* Set R0[0] since it is used to indicates Thumb mode */ + +_exit_thumb_long_bl_blx_handler: + ldmfd sp!, {pc} + diff --git a/armdebug/Debugger/debug_runlooptasks.S b/armdebug/Debugger/debug_runlooptasks.S new file mode 100644 index 0000000..a9eb50a --- /dev/null +++ b/armdebug/Debugger/debug_runlooptasks.S @@ -0,0 +1,411 @@ +/** @file debug_runlooptasks.S + * @brief GDB Server platform Run Loop + * + */ + +/* Copyright (C) 2007-2011 the NxOS developers + * + * Module Developed by: TC Wan + * + * See AUTHORS for a full list of the developers. + * + * See COPYING for redistribution license + * + */ + +/* + * This file contains platform specific code. + * This include ABORT Mode Debugger Run Loop operation, + * as well as Debugger Interfacing code to the platform code. + */ + +/* + * The Debugger has to implement a Run Loop in ABORT mode + * since the hardware is still running. Consequently, + * the communications subsystems such as USB (and Bluetooth?) + * which is used to communicate with the Host needs to be + * serviced in order for actual data transmission and reception + * to take place. Currently we're reusing the platform's + * communication routines to do the actual tx/rx, so it means + * that it is not possible to set breakpoints in those modules. + * In addition, since the platform communication modules may + * handle other tasks, it is currently possible to enter an + * indeterminate state where certain communication messages trigger + * a platform response which cannot be handled by the Debugger Run Loop. + * The alternative is to implement our own communications routines, but + * that will take even more code. + * + * FIXME: It may become necessary to hack the platform communications + * routines to detect that we're in the Debugger Run Loop and not the + * normal run loop to avoid system crashes, but the current goal is to + * have as minimal changes to the platform code as possible. + * + * Since there are two Run Loops for the platform, the way in which + * they interact is as follows: + * + * [Platform Run Loop] - DBG_INIT/ GDB Cmd/ BKPT -> [Debugger Run Loop] + * \ <------ GO/ STEP/ CONT ----- / + * ... ... + * ... Handle GDB Cmd/Resp + * ... ... + * {normal runloop {communications / + * processing} watchdog routines} + * ^-------v v-------^ + * + * The Platform will invoke dbg__bkpt_init() after hardware and system initialization, + * before entering the Platform Run Loop. This configures the Debugger, but does not + * invoke the Debugger Run Loop unless a Manual Breakpoint is found in the platform code. + * + * Subsequently, the Debugger Run Loop will be triggered by Breakpoints, or + * when the communications subsystem receives a GDB Command. + * + * The Debugger Run Loop is actually dbg__bkpt_waitCMD(), this file contains + * the Run Loop Tasks which needs to be invoked periodically by the Run Loop, + * to minimize the coupling between the ARMDEBUG modules and the Platform. + * + * Note: The Debugger Run Loop does not handle Hardware Shutdown, it is + * assumed that we wouldn't need to do so in Debug Mode. + * + */ +#define __ASSEMBLY__ + +#define REBOOT_POWERDOWN +#include "debug_runlooptasks.h" + +#include "debug_internals.h" +#include "debug_macros.h" +#include "debug_stub.h" + + .code 32 + .align 4 + +#ifdef __NXOS__ +/**************************************************************************** + * + * NxOS Run Loop + * + ****************************************************************************/ + dbg_interwork dbg__runloopTasks +/* Currently, there's nothing that needs to be done in the NxOS Run Loop */ + push {lr} + mov r0, #1 /* 1 ms delay */ + bl nx_systick_wait_ms + pop {pc} + +#else +/**************************************************************************** + * + * NXT Firmware Run Loop + * + ****************************************************************************/ + dbg_interwork dbg__runloopTasks + push {lr} + /* FIXME: Add necessary cXXXCtrl calls here */ + bl cCommCtrl + /* OSWatchdogWrite is a NULL function in the NXT Firmware?! */ + pop {pc} +#endif + +#ifdef __NXOS__ +/**************************************************************************** + * + * NxOS Reboot Routine + * + ****************************************************************************/ + dbg_interwork dbg__reboot +#ifdef REBOOT_POWERDOWN + b nx_core_halt /* Shutdown Brick, won't return */ +#else + b nx_core_reset /* Reboot Brick, won't return */ +#endif + +#else +/**************************************************************************** + * + * NXT Firmware Reboot Routine + * + ****************************************************************************/ + dbg_interwork dbg__reboot + /* Powerdown Sequence + dIOCtrlSetPower((POWERDOWN>>8)); + dIOCtrlTransfer(); + + Reboot Sequence + dIOCtrlSetPower((UBYTE)(BOOT>>8)); + dIOCtrlSetPwm((UBYTE)BOOT); + dIOCtrlTransfer(); + */ + + /* We implement the powerdown sequence for now */ + +#ifdef REBOOT_POWERDOWN + /* Powerdown sequence */ + ldr r0, =((POWERDOWN >> 8) & 0xFF) + ldr r1, =dIOCtrlSetPower + mov lr,pc + bx r1 +#else + /* Reboot sequence: this forces SAMBA mode??!! */ + ldr r0, =((BOOT >> 8) & 0xFF) + ldr r1, =dIOCtrlSetPower + mov lr,pc + bx r1 + + ldr r0, =(BOOT & 0xFF) + ldr r1, =dIOCtrlSetPwm + mov lr,pc + bx r1 +#endif + +_dbg__reboot_wait: + ldr r1, =dIOCtrlTransfer + mov lr,pc + bx r1 + + b _dbg__reboot_wait /* Wait for AVR... */ +#endif + +#ifdef __NXOS__ +/**************************************************************************** + * + * NxOS Abort Info LCD Display Routine + * + ****************************************************************************/ +/* On entry: + * r0: abort type + * On exit: + * r0-r3: destroyed + */ + dbg_interwork dbg__display_abort_info + push {lr} + _getdbgregister DBGSTACK_USERPC_INDEX, r1 /* Retrieve User PC into R2 */ + _getdbgregister DBGSTACK_USERCPSR_INDEX, r2 /* Retrieve User CPSR into R2 */ + bl nx__abort_info /* void nx__abort_info(U32 data, U32 pc, U32 cpsr); */ + pop {pc} + +#else +/**************************************************************************** + * + * NXT Firmware Abort Info LCD Display Routine + * + ****************************************************************************/ + dbg_interwork dbg__display_abort_info +/* FIXME: Inteface with NXT Firmware LCD Display routines */ + push {lr} + pop {pc} +#endif + +#ifdef __NXOS__ + .extern debug_OutCommBuf +/**************************************************************************** + * + * NxOS Communications Driver Interface Routine + * + ****************************************************************************/ +/* dbg__sendCommMsg + * Internal send routine (interfaces with drivers). + * On entry: + * R0: Total Message Buffer length + * On exit: + * R0: Tx Status (TRUE if data sent) + * R1-R3: Destroyed + */ + dbg_interwork dbg__sendCommMsg + stmfd sp!, {r4, lr} + mov r4, r0 /* Keep Comm Buffer length in R4 */ + /* Check USB bus status, transmit message if possible */ + bl nx_usb_is_connected /* R0 = TRUE (#1) if USB is ready */ + teq r0, #0 /* FALSE == #0; + We can't check for True condition since values + used by C-Compiler & ARMDEBUG are different */ + beq dbg__sendCommMsgFailed + + /* Actual transmission (blocking) */ + ldr r0, =debug_OutCommBuf /* data pointer parameter */ + mov r1, r4 /* Comm buffer length */ + bl nx_usb_write + +1: bl nx_usb_data_written /* R0 = True if data has been sent */ + teq r0, #0 /* FALSE == #0; + We can't check for True condition since values + used by C-Compiler & ARMDEBUG are different */ + /* FIXME: implement timeout */ + beq 1b /* Busy Wait Loop */ + + mov r0, #TRUE + b exit_dbg__sendCommMsg +dbg__sendCommMsgFailed: + mov r0, #FALSE + +exit_dbg__sendCommMsg: + ldmfd sp!, {r4, pc} + + +#else +/**************************************************************************** + * + * NXT Firmware Communications Driver Interface Routine + * + ****************************************************************************/ +/* dbg__sendCommMsg + * Internal send routine (interfaces with drivers). + * On entry: + * R0: Total Message Buffer length + * On exit: + R0: Tx Status (TRUE if data sent) + */ + dbg_interwork dbg__sendCommMsg + stmfd sp!, {r4, lr} + mov r4, r0 /* Keep Comm Buffer length in R4 */ + ldr r0, =debug_nxtCommChannel + ldr r0, [r0] /* Get Channel Enum */ + teq r0, #BT_CMD_READY + beq dbg__sendBTMsg + teq r0, #USB_CMD_READY + beq dbg__sendUSBMsg + b dbg__sendCommMsgFailed /* Channel Enum Doesn't Match, shouldn't happen? */ + +dbg__sendBTMsg: + /* NXT BT routines do not have any configuration checks */ + ldr r0, =debug_OutCommBuf /* data pointer parameter */ + mov r1, r4 /* BT Bytes to Send */ + mov r2, r4 /* BT Message Size */ + bl dBtSendMsg /* Send it via Bluetooth (complete message) */ + mov r0, #TRUE /* Always flag Success */ + b exit_dbg__sendCommMsg + +dbg__sendUSBMsg: + /* Check USB bus status, transmit message if possible */ + bl dUsbIsConfigured /* R0: UByte status, TRUE / FALSE */ + teq r0, #nxt_UBYTE_TRUE + bne dbg__sendCommMsgFailed + + /* Actual transmission (blocking) */ + ldr r0, =debug_OutCommBuf /* data pointer parameter */ + mov r1, r4 /* Comm buffer length */ + bl dUsbWrite /* call NXT Firmware USB driver, return 0: done, !0: remaining chars */ + teq r0, #0 /* Tx done if returned length is 0 */ + moveq r0, #TRUE /* Convert NXT firmware return value to our Status (TRUE/FALSE) */ + beq exit_dbg__sendCommMsg +dbg__sendCommMsgFailed: + mov r0, #FALSE + +exit_dbg__sendCommMsg: + ldmfd sp!, {r4, pc} +#endif + + +#ifdef __NXOS__ +/**************************************************************************** + * + * GDB Debugger Invocation Routine for NxOS + * + ****************************************************************************/ + .code 32 + .align 4 + + .extern dbg__install_singlestep + .extern dbg__activate_singlestep + .extern irq_stack_frame_address +/* nxos__handleDebug + * Prepare to switch to Debug Mode + * int nxos__handleDebug(U8 *buffer, comm_chan_t channel, U32 length); + * + * This routine is called from NxOS Fantom library to setup + * Single Step Breakpoint in preparation for Debugger invocation if we're in + * normal execution mode. + * + * It returns to complete the IRQ handling normally, after which the single + * step breakpoint will be triggered, and the incoming GDB message will then + * be processed in the dbg__bkpt_waitCMD() loop. + * + * If we're in Debugger Mode already, then just return and let the + * dbg__bkpt_waitCMD() loop handle it normally. + * + * If we're operating in normal NxOS mode, return True (!0) + * If we're already in Debugger Mode, return False (0) + */ + dbg_interwork nxos__handleDebug + push {lr} + /* This routine is called from nx__irq_handler() via fantom_filter_packet(). + * The operating mode should already have been configured by the IRQ interrupt handler. + * + * The IRQ Stack Frame Pointer will contains the LR and SPSR from the topmost interrupted task + * if it is non-zero (NxOS supports nested IRQs) + */ + bl dbg__copyNxtDebugMsg /* Copy to Debugger Message Buffer, Remember Comm Channel */ + mov r0, #FALSE /* Setup Default Return value (False) */ + _dbg_getmode r1 /* Get Debug Mode */ + cmp r1, #(TRUE & BYTE0) /* Confine it to Byte size */ + /* If Debug Mode is TRUE, this means that we're already running the Debugger */ + beq exit_nxos__handleDebug /* Yes, return False */ + + /* Retrieve ISR Return Address */ + ldr r3, =irq_stack_frame_address + ldr r3, [r3] /* Get Interrupt Stack Pointer */ + teq r3, #0 + beq exit_nxos__handleDebug /* NULL Interrupt Stack Frame Pointer, exit (status: False) */ + +nxos_switch2debug: + /* Since the Interrupt Stack Frame Pointer points to the top of the stack frame, + * we'll have to use Load Empty Ascending Stack (LDMEA == LDMDB) to access the variables + */ + ldmdb r3, {r1,r2} /* R1: LR, R2: SPSR */ + tst r2, #CPSR_THUMB /* Check for Thumb Mode */ + orrne r1, r1, #1 /* Configure for Thumb Single Step Breakpoint */ + bl dbg__install_singlestep /* Setup Single Step, next instruction address returned in r1 */ + bl dbg__activate_singlestep + mov r0, #TRUE /* We're going to switch to Debug Mode (via Single Step Breakpoint) */ + +exit_nxos__handleDebug: + pop {r1} + bx r1 /* In case we have Interworking from different caller mode */ + +#else + +/**************************************************************************** + * + * GDB Debugger Invocation Routine for NXT Firmware + * + ****************************************************************************/ + .code 16 + .align 2 + + .extern dbg__copyNxtDebugMsg + .global cCommHandleDebug + .thumb_func + .type cCommHandleDebug, %function +/* cCommHandleDebug + * Switch Mode to Debugger. + * Used by NXT Firmware only + * + * UWORD cCommHandleDebug(UBYTE *pInBuf, UBYTE CmdBit, UWORD MsgLength); + * + * This routine is called from cCommInterprete either in normal operation mode (SVC) + * or else when we're in debug mode (ABORT) which uses the cCommCtrl() routine to handle + * I/O with the Host. + * + * On entry, the message is copied from the NXT buffer into our own buffers. + * + * If this is accessed from normal operation mode, we need to switch mode to + * ABORT mode to handle the incoming message using a Manual Breakpoint instruction. + * When DEBUG is exited, the execution resumes from the instruction following the Breakpoint. + */ +cCommHandleDebug: +/* Arg Registers are not preserved since this is invoked explicitly */ + push {lr} /* store arg registers */ + bl dbg__copyNxtDebugMsg /* Copy to Debugger Message Buffer, Remember Comm Channel */ + _dbg_getmode r0 /* Get Debug Mode */ + cmp r0, #(TRUE & BYTE0) /* Confine it to Byte size */ + + /* If Debug Mode is TRUE, this means that we're already running the Debugger */ + beq _cCommHandleDebug_cont + /* Else, we're in normal operation mode (SVC), or other mode (??!) and need to force a switch to Debug mode */ + dbg__bkpt_thumb +_cCommHandleDebug_cont: + mov r0, #0 /* FIXME: Return Status */ + pop {r1} /* Can't Pop LR directly */ + bx r1 /* Safe code: actually we should be able to Pop PC since the caller is Thumb Mode */ + + .ltorg +#endif diff --git a/armdebug/Debugger/debug_runlooptasks.h b/armdebug/Debugger/debug_runlooptasks.h new file mode 100644 index 0000000..a2ae956 --- /dev/null +++ b/armdebug/Debugger/debug_runlooptasks.h @@ -0,0 +1,81 @@ +/** @file debug_runlooptasks.h + * @brief Shared C/ASM header file for debugger communications + * + */ + +/* Copyright (C) 2007-2011 the NxOS developers + * + * Module Developed by: TC Wan + * + * See AUTHORS for a full list of the developers. + * + * See COPYING for redistribution license + * + */ + +#ifndef __DEBUG_RUNLOOPTASKS_H__ +#define __DEBUG_RUNLOOPTASKS_H__ + +#include "_c_arm_macros.h" + +/* This is a place holder header file to allow for interfacing with C Routines in either + * NxOS or NXT Firmware. + * + * Since the header files from the original source trees were meant for C programs, we can't + * include them directly. Here we just use .extern to reference the routines. + */ + +#ifdef __NXOS__ + .extern nx__abort_info + .extern nx_systick_wait_ms + + .extern nx_usb_is_connected + .extern nx_usb_can_write + .extern nx_usb_write + .extern nx_usb_data_written + .extern nx_usb_read + .extern nx_usb_data_read + .extern nx_core_reset + .extern nx_core_halt + +#else /* NXT Firmware */ + + .extern cCommInit + .extern cCommCtrl + .extern cCommExit + .extern dUsbWrite + .extern dUsbRead + .extern dUsbIsConfigured + .extern dBtSendMsg + /** + * True value used by Thumb mode in NXT + */ + .equ nxt_UBYTE_TRUE, 1 + /** + * False value used by Thumb mode in NXT + */ + .equ nxt_UBYTE_FALSE, 0 + /** + * USB Command Indicator + */ + .equ USB_CMD_READY, 0x01 /* From c_comm.iom */ + /** + * BT Command Indicator + */ + .equ BT_CMD_READY, 0x02 /* From c_comm.iom */ + + .extern dIOCtrlSetPower + .extern dIOCtrlSetPwm + .extern dIOCtrlTransfer + /** + * NXT Boot Magic Value + */ + .equ BOOT, 0xA55A /* from c_ioctrl.iom */ + /** + * NXT Powerdown Magic Value + */ + .equ POWERDOWN, 0x5A00 /* from c_ioctrl.iom */ + +#endif + +#endif diff --git a/armdebug/Debugger/debug_stack.ld b/armdebug/Debugger/debug_stack.ld new file mode 100644 index 0000000..8fc4cb7 --- /dev/null +++ b/armdebug/Debugger/debug_stack.ld @@ -0,0 +1,15 @@ +/* The following linker definitions should be placed in the stack section */ + + /* debugger state */ + __debugger_stack_bottom__ = . ; + . += 0x48; /* 16 previous mode registers + SPSR + UNDEF Next Instruction Address */ + __debugger_stack__ = .; + __debugger_stack_top__ = . ; + + /* breakpoints */ + __breakpoints_start__ = . ; + . += 0x40; /* Single Stepping Breakpoint + 7 Breakpoints */ + __breakpoints_end__ = . ; + +/* Symbols */ + __breakpoints_num__ = (__breakpoints_end__ - __breakpoints_start__) / 8; diff --git a/armdebug/Debugger/debug_stub.S b/armdebug/Debugger/debug_stub.S new file mode 100644 index 0000000..a7b2d56 --- /dev/null +++ b/armdebug/Debugger/debug_stub.S @@ -0,0 +1,1579 @@ +/** @file debug_stub.S + * @brief ARM Breakpoint Debugger support routines + * + */ + +/* Copyright (C) 2007-2011 the NxOS developers + * + * Module Developed by: TC Wan + * + * See AUTHORS for a full list of the developers. + * + * See COPYING for redistribution license + * + */ + + /* GDB sparc-stub.c comments header included below to document GDB Server Remote protocol */ + /* This header has been modified to include additional commands not documented in the header stub */ + + /**************************************************************************** + + THIS SOFTWARE IS NOT COPYRIGHTED + + HP offers the following for use in the public domain. HP makes no + warranty with regard to the software or it's performance and the + user accepts the software "AS IS" with all faults. + + HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD + TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +****************************************************************************/ + +/**************************************************************************** + * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $ + * + * Module name: remcom.c $ + * Revision: 1.34 $ + * Date: 91/03/09 12:29:49 $ + * Contributor: Lake Stevens Instrument Division$ + * + * Description: low level support for gdb debugger. $ + * + * Considerations: only works on target hardware $ + * + * Written by: Glenn Engel $ + * ModuleState: Experimental $ + * + * NOTES: See Below $ + * + * Modified for SPARC by Stu Grossman, Cygnus Support. + * + * This code has been extensively tested on the Fujitsu SPARClite demo board. + * + * To enable debugger support, two things need to happen. One, a + * call to set_debug_traps() is necessary in order to allow any breakpoints + * or error conditions to be properly intercepted and reported to gdb. + * Two, a breakpoint needs to be generated to begin communication. This + * is most easily accomplished by a call to breakpoint(). Breakpoint() + * simulates a breakpoint by executing a trap #1. + * + ************* + * + * The following gdb commands are supported: + * + * command function Return value + * + * g return the value of the CPU registers hex data or ENN + * GrrrrRRRR.. set the value of the CPU registers OK or ENN + * where register values are given as + * 32-bit hex values in the sequence: + * User R0, R1, ..., R15, CPSR + * px get the value of one register (x) hex data or ENN + * Px=rrrr set the value of one register (x) to OK or ENN + * 32-bit hex value rrrr. + * x = ['0','F'] for R0-R15, ['10','17'] for F0-F7 (dummy) + * '18' for FPSCR (dummy), '19' for User CPSR + * + * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN + * MAA..AA,LLLL:bb..bb + * Write LLLL bytes at address AA.AA OK or ENN + * + * D Detach (equivalent to continue Ack Only + * at current address) + * c Resume at current address SNN ( signal NN) + * cAA..AA Continue at address AA..AA SNN + * + * s Step one instruction SNN + * sAA..AA Step one instruction from AA..AA SNN + * + * k kill + * + * ? What was the last sigval ? SNN (signal NN) + * + * zt,AA..AA,k Remove a Breakpoint of type t at addr OK or ENN + * AA..AA of kind k + * Zt,AA..AA,k Insert a Breakpoint of type t at addr OK or ENN + * AA..AA of kind k + * t 0: memory breakpoint + * 1: hardware breakpoint + * 2: write watchpoint + * 3: read watchpoint + * 4: access watchpoint + * k: 2 (16-bit Thumb), 3 (32-bit Thumb2) + * or 4 (32-bit ARM) for t=[0,1] + * Num. bytes to watch for t=[2,4] + * + * All commands and responses are sent with a packet which includes a + * checksum. A packet consists of + * + * $#. + * + * where + * :: + * :: < two hex digits computed as modulo 256 sum of > + * + * When a packet is received, it is first acknowledged with either '+' or '-'. + * '+' indicates a successful transfer. '-' indicates a failed transfer. + * + * Example: + * + * Host: Reply: + * $m0,10#2a +$00010203040506070809101112131415#42 + * + ****************************************************************************/ + /* Modified GDB Server Remote Protocol definition from GDB's sparc-stub.c Comment Header included above + * Additional commands from GDB Reference Appendix D.2 + * + * Note: ARMDEBUG can only implement Memory Breakpoints t=0. Hardware breakpoints requires a JTAG debugger. + * Currently, watchpoints are not implemented as they require hardware support as well (need verification). + * + * GDB requires command parameters to be specified as Big Endian values. + * However, the read/write register command expect the register contents to be specified in target byte order. + * The default target byte order is Little Endian for the AT91SAM7xxx processor in the NXT. + * If Big Endian target byte order is required, the __BIG_ENDIAN__ preprocessor label should be defined. + */ + +/* FIXME: The Hex value arguments passed by GDB does not have fixed lengths! Although the standard says + * there should be x digits, it does not follow this requirement. e.g., register index. + */ + + +#define __ASSEMBLY__ +#include "debug_stub.h" +#include "debug_internals.h" +#include "debug_macros.h" + + /* Opcode Parser function reference */ + .extern dbg_following_instruction_addr + + /* Hexutils function references */ + .extern hex2char + .extern char2hex + .extern byte2ascii + .extern halfword2ascii_be + .extern halfword2ascii_le + .extern word2ascii_be + .extern word2ascii_le + .extern ascii2hex_varlen_be + .extern ascii2byte + .extern ascii2halfword_be + .extern ascii2halfword_le + .extern ascii2word_be + .extern ascii2word_le + +/* Macro definitions */ + +/* _check_msgseparator + * Look for separator ',' + * On entry: + * bufferptr: points to the parameter buffer [can't be R0] + * On exit: + * R0: destroyed + * bufferptr: points to the next character location in the parameter buffer + * Flags: Updated + */ + + .macro _check_msgseparator bufferptr + ldrb r0, [\bufferptr], #1 /* get separator */ + cmp r0, #MSGBUF_SEPCHAR + .endm + +/* _check_msgargument + * Look for argument ':' + * On entry: + * bufferptr: points to the parameter buffer [can't be R0] + * On exit: + * R0: destroyed + * bufferptr: points to the next character location in the parameter buffer + * Flags: Updated + */ + + .macro _check_msgargument bufferptr + ldrb r0, [\bufferptr], #1 /* get separator */ + cmp r0, #MSGBUF_ARGCHAR + .endm + +/* _check_msgassignment + * Look for assignment '=' + * On entry: + * bufferptr: points to the parameter buffer [can't be R0] + * On exit: + * R0: destroyed + * bufferptr: points to the next character location in the parameter buffer + * Flags: Updated + */ + + .macro _check_msgassignment bufferptr + ldrb r0, [\bufferptr], #1 /* get separator */ + cmp r0, #MSGBUF_SETCHAR + .endm + +.bss +.align 4 +debug_InMsgBuf: + .space MSGBUF_SIZE,0 +debug_OutMsgBuf: + .space MSGBUF_SIZE,0 + + /* Make Debugger State accessible from other modules */ + .global debug_state + .global debug_mode + .global debug_bkpt_type + .global debug_curr_breakpoint + +debug_state: + .byte 0x0 /* dbg_state_t variable */ +debug_mode: + .byte 0x0 /* Boolean variable */ +debug_bkpt_type: + .byte 0x0 /* bkpt_type_t variable */ +debug_curr_breakpoint: + .byte 0x0 + +.data +.align 4 +debug_RetransmitFlag: + .byte '-',0 + +debug_AckOnlyFlag: + .byte '+',0 + +debug_ValidResponsePrefix: + .byte '+','$',0 + +debug_ErrorResponsePrefix: + .byte '+','$','E',0 + +debug_SignalResponsePrefix: + .byte '+','$','S',0 + +debug_OkResponse: + .byte '+','$','O','K',0 + +debug_ThreadIDResponse: + .byte '+','$','Q','C','0',0 /* 0: Any thread */ + +debug_FirstThreadInfoResponse: + .byte '+','$','m','0',0 /* 0: One default thread */ +debug_SubsequentThreadInfoResponse: + .byte '+','$','l',0 /* End of Thread List */ + +/* The CmdIndexTable and CmdJumpTable must be kept in sync */ +debug_cmdIndexTable: + .byte 'g','G','p','P','m','M','D','c','s','k','z','Z','?','q','Q',0 + +/* Command Handlers + * On entry: + * R0: Input Message Parameter Buffer address pointer (points to contents after '$' and '') + */ +.align 4 +debug_cmdJumpTable: + .word _dbg__cmd_GetAllRegs /* 'g' */ + .word _dbg__cmd_SetAllRegs /* 'G' */ + .word _dbg__cmd_GetOneReg /* 'p' */ + .word _dbg__cmd_SetOneReg /* 'P' */ + .word _dbg__cmd_ReadMem /* 'm' */ + .word _dbg__cmd_WriteMem /* 'M' */ + .word _dbg__cmd_Detach /* 'D' */ + .word _dbg__cmd_Continue /* 'c' */ +#ifdef __NXOS__ + .word _dbg__cmd_Step /* 's' */ +#else + /* NXT Firmware does not support Stepping */ + .word _dbg__nop /* 's' */ +#endif + .word _dbg__cmd_Kill /* 'k' */ + .word _dbg__cmd_RemoveBreakpoint /* 'z' */ + .word _dbg__cmd_InsertBreakpoint /* 'Z' */ + .word _dbg__cmd_Status /* '?' */ + .word _dbg__cmd_Query /* 'q' */ + .word _dbg__nop /* 'Q' */ + .word 0 + +.code 32 +.text +.align 4 + .extern __breakpoints_num__ + .extern dbg__getDebugMsg /* Read a message from the communications link */ + .extern dbg__putDebugMsg /* Write a message to the communications link */ + .extern dbg__sendAckOrNak /* Send Ack or Nak to indicate success/failure of message receipt */ + .extern dbg__runloopTasks /* Platform specific Run Loop processing */ + + +/* The Debugger Interface can handle a total of (n-1) Breakpoint States and 1 Single Stepping State, + * where n is a power of 2. The value of n is given by __breakpoints_num__ defined in the linker file. + * + * In addition, a Debugger Stack contains the User Mode Register Stack Frame + SPSR + Bkpt Instr Addr. + * These are currently stored in the .stack area in RAM, so there is no fixed address + * location that is used for this purpose. + * + * The Breakpoint feature assumes that the program is executed in RAM. It is not possible + * to set dynamic breakpoints for programs executed from Flash in the AT91SAM7S which lacks + * instruction breakpointing support in hardware without using JTAG. The only type of breakpoints + * that can be supported in Flash based programs are Static (predefined) breakpoints inserted into + * the code. + * + * Each Breakpoint State i is a struct comprising the Breakpoint Address + Memory Contents + * stored in 8 bytes as: + * [High Memory Address] + * ADDR [i*8+4]: Memory Contents (32 bits) + * ADDR [i*8]: Breakpoint Address (31 bits, b0 = THUMB flag [not implemented yet]) + * [Low Memory Address] + * + * A Non-zero Breakpoint Address means that the breakpoint is active, whereas the memory contents + * contains the instruction which resided at that address initially (now replaced by a BKPT + * instruction). + * Note: Currently it is not possible to resume execution of a program with breakpoints enabled + * after a RESET, since the RESET will clear all contents of the stack, destroying the instruction + * contained in a given breakpoint. + * Fortunately the NXT will also need to reload the program into RAM so this is not expected to be + * an issue. + * + * The Memory Map for the Debugger State is as follows: + * + * [High Memory Address] __breakpoints_end__ + * Breakpoint 07 State + * Breakpoint 06 State + * ... + * Breakpoint 02 State + * Breakpoint 01 State + * Single Step State __debugger_stack__ / __breakpoints_start__ + * Previous Mode R15 + * Previous Mode R14 + * Previous Mode R13 + * ... + * User Mode R02 + * User Mode R01 + * User Mode R00 + * Previous Mode CPSR (UNDEF SPSR) + * UNDEF Next Instr Addr __debugger_stack_bottom__ + * [Low Memory Address] + * + * Each Breakpoint State will initially be zeroed. + * + */ + /* FIXME: The Debugger Stack Frame is probably not 100% consistent with the order that + GDB expects in the g/G messages. CSPR is probably located above R15 */ + +/**************************************************************************** + * + * GDB Debugger Init and Breakpoint Handler Routines + * + ****************************************************************************/ + .code 32 + .align 4 +/* dbg__bkpt_init + * GDB set_debug_traps() routine + * On entry: + * None + * On exit: + * r0-r3: destroyed + */ + dbg_interwork dbg__bkpt_init + push {lr} + bl _dbg__clear_breakpoints + mov r2, #0 + ldr r1, =debug_curr_breakpoint + strb r2, [r1] + ldr r0, =debug_InMsgBuf + strb r2, [r0] + ldr r1, =debug_OutMsgBuf + strb r2, [r1] + bl dbg__comm_init /* Pass R0: Rx Buffer, R1: Tx Buffer to comm submodule */ + +/* FIXME: Initialize other stuff here */ + _dbg_setstate DBG_INIT + _dbg_setmode FALSE /* Debug Mode = False */ + pop {lr} + bx lr /* Must return via BX; may have been called from Thumb mode (NXT Firmware) */ + + +/* _dbg__flush_icache + * Flush the Instruction cache + * Defined by GDB Stub, but not needed for ARMv4T architecture + */ +_dbg__flush_icache: + /* nop */ + bx lr + +/* _dbg__switch2undefmode + * Common internal routine to return execution to user program + */ +_dbg__switch2undefmode: + bl _dbg__flush_icache + msr cpsr_c, #(MODE_UND | CPSR_FIQ | CPSR_IRQ) /* Configure Undef Mode */ + _dbg_setmode FALSE /* Debug Mode = False */ + ldr lr, =resume_execution + mov pc, lr /* Exit via UNDEF mode */ + +/* dbg__abort_exception_handler + * Handle Abort Exceptions + * On entry: + * r0: Abort Type Enum + * On exit: + * routine does not 'exit' in the normal sense + */ + dbg_interwork dbg__abort_exception_handler + _dbg_set_bkpt_type r0 /* Set Breakpoint Type given value in R0 */ + b dbg__bkpt_waitCMD + +/* dbg__thumb_bkpt_handler + * GDB handle_exception() routine (Thumb Mode) + * On entry: + * r0: Breakpoint index value + * On exit: + * routine does not 'exit' in the normal sense + */ + dbg_interwork dbg__thumb_bkpt_handler + /* On entry, r0 contains breakpoint index value */ + _dbg_setcurrbkpt_index r0 /* keep current breakpoint index in memory */ + ldr r1, =BKPT16_MANUAL_BKPT + teq r0, r1 + moveq r0, #DBG_MANUAL_BKPT_THUMB /* Manual Thumb Breakpoint, process it */ + beq _restore_normal_breakpoints + +_process_normal_breakpoint_thumb: + ldr r1, =__breakpoints_num__ + cmp r0, r1 /* Sanity check that index is in range */ + bhs dbg__bkpt_offset_outofrange /* Exceeded Offset Range */ + mov r0, #DBG_NORMAL_BKPT_THUMB /* It is a valid normal breakpoint */ + b _restore_normal_breakpoints + +/* dbg__arm_bkpt_handler + * GDB handle_exception() routine (ARM Mode) + * On entry: + * r0: breakpoint index value + * On exit: + * routine does not 'exit' in the normal sense + */ + dbg_interwork dbg__arm_bkpt_handler + /* On entry, r0 contains breakpoint index value */ + _dbg_setcurrbkpt_index r0 /* keep current breakpoint index in memory */ + ldr r1, =BKPT32_MANUAL_BKPT + teq r0, r1 + moveq r0, #DBG_MANUAL_BKPT_ARM /* Manual ARM Breakpoint, process it */ + beq _restore_normal_breakpoints + +_process_normal_breakpoint_arm: + ldr r1, =__breakpoints_num__ + cmp r0, r1 /* Sanity check that index is in range */ + bhs dbg__bkpt_offset_outofrange /* Exceeded Offset Range */ + mov r0, #DBG_NORMAL_BKPT_ARM /* It is a valid normal breakpoint */ +/* b _restore_normal_breakpoints */ + +_restore_normal_breakpoints: + _dbg_set_bkpt_type r0 /* Set Breakpoint Type given value in R0 */ + bl _dbg__restore_breakpoints /* includes restoring single step */ + bl _dbg__clear_singlestep + bl _dbg__flush_icache +/* b dbg__bkpt_waitCMD */ + +dbg__bkpt_inactive: +/* b dbg__bkpt_waitCMD */ + +dbg__bkpt_offset_outofrange: +/* b dbg__bkpt_waitCMD */ + +/* dbg__bkpt_waitCMD + * GDB Stub Remote Command Handler + */ + +/**************************************************************************** + * + * GDB Server Command Processing Routines + * + ****************************************************************************/ + dbg_interwork dbg__bkpt_waitCMD + /* We enter this code section when a Breakpoint Triggers */ + _dbg_setmode TRUE /* Debug Mode = True */ + msr cpsr_c, #(MODE_ABT) /* Re-enable Interrupts */ + + _dbg_getstate r0 + cmp r0, #DBG_CONFIGURED + blo dbg__bkpt_waitCMD_cont /* Not configured yet, don't send Breakpoint Signal Response */ + bl _dbg__cmd_Status /* Send signal response to the GDB server */ + +dbg__bkpt_waitCMD_cont: + bl dbg__runloopTasks /* Execute housekeeping tasks while in ABRT mode */ + bl dbg__getDebugMsg /* Read new message from Debugger, buflen in R0, 0 if none, -1 if error, msgbuf pointer in R1 */ + cmp r0, #0 + beq dbg__bkpt_waitCMD_cont /* No message yet, do housekeeping tasks */ + bgt _proc_command /* valid message, process it */ + bl __dbg__procChecksumError /* Message invalid, checksum error? */ + b dbg__bkpt_waitCMD_cont + +_proc_command: +/* Message now has Ctrl-C or $\0 */ + mov r4, r1 /* Use R4 as buffer pointer */ + ldrb r0, [r4], #1 /* Look for Ctrl-C or '$' */ + teq r0, #MSGBUF_CTRLC + bne _dbg_check_gdb_command + /* Ctrl-C detected, do nothing (wait for next command from GDB) */ +#if 0 + /* On entering the Debugger via Ctrl-C, _dbg__cmd_Status has already sent a reply, so just keep quiet */ + bl __dbg__procAckOnly /* send Ack */ +#endif + b dbg__bkpt_waitCMD_cont + +_dbg_check_gdb_command: + teq r0, #MSGBUF_STARTCHAR + movne r1, #MSG_ERRFORMAT /* Message Format invalid (not '$') */ + bne _dbg__cmdError /* Shouldn't happen */ + ldrb r0, [r4], #1 /* Look for command char */ + bl _dbg__cmdChar2Index /* Index in R0 */ + mov r1, #CMDINDEX_OUTOFRANGE + teq r0, r1 + bne _dbg__cmdExists /* Found valid command, execute it */ +_dbg_unknown_command: + bl _dbg__nop /* Command character not recognized, send empty response to GDB server */ + b dbg__bkpt_waitCMD_cont + +#if 0 + moveq r1, #MSG_UNKNOWNCMD /* Out of range, Command character not recognized */ + beq _dbg__cmdError /* Send response to GDB server */ +#endif + +_dbg__cmdExists: + mov r3, r0 /* put Command Handler Index in R3 */ + mov r0, r4 /* R0 now contains Input Message Buffer Parameter Pointer (previously in R4) */ + _dbg_jumpTableHandler debug_cmdJumpTable, r2, r3 /* Call Command Handler Routine, use R2 as jump address pointer */ + b dbg__bkpt_waitCMD_cont + +_dbg__cmdError: + _dbg_outputMsgStatusErr + bl dbg__putDebugMsg /* Send error response to the GDB server */ + b dbg__bkpt_waitCMD_cont + + +/* __dbg__procOkOnly + * Send OK to GDB due to Detach + * On entry: + * None + * On exit: + * r0-r3: destroyed + */ +__dbg__procOkOnly: + stmfd sp!, {lr} + _dbg_outputMsgStatusOk /* Acknowledge Detach command from GDB server */ +_cont_procOkOnly: + bl dbg__putDebugMsg /* Send OK response to the GDB server */ + cmp r0, #0 + beq _cont_procOkOnly_exit /* Sending of OK succeeded */ + bl dbg__runloopTasks /* Service run loop tasks */ + b _cont_procOkOnly /* Retry OK transmission */ +_cont_procOkOnly_exit: + ldmfd sp!, {pc} + + +/* __dbg__procAckOnly + * Send Ack to GDB due to Continue or Step + * On entry: + * None + * On exit: + * r0-r3: destroyed + */ +__dbg__procAckOnly: + stmfd sp!, {lr} + _dbg_outputAckOnlyFlag + b _cont_sendAckOrNak /* Acknowledge Continue or Step command from GDB server */ + +/* __dbg__procChecksumError + * Request Retransmission from GDB due to Checksum error + * On entry: + * None + * On exit: + * r0-r3: destroyed + */ +__dbg__procChecksumError: + stmfd sp!, {lr} + _dbg_outputRetransmitFlag + /* b _cont_sendAckOrNak */ /* Acknowledge Continue or Step command from GDB server */ + +_cont_sendAckOrNak: + bl dbg__sendAckOrNak /* send Ack or Nak to GDB server */ + cmp r0, #0 + beq _cont_sendAckOrNak_exit /* Sending of Ack or Nak succeeded */ + bl dbg__runloopTasks /* Service run loop tasks */ + b _cont_sendAckOrNak /* Retry Ack or Nak transmission */ +_cont_sendAckOrNak_exit: + ldmfd sp!, {pc} + +/* _dbg__cmdChar2Index + * Convert Command Character to Jump Table Index + * On entry: + * r0: command character + * On exit: + * r0: jump table index (-1 for command not found) + * R1: destroyed + * R2: destroyed + * R3: destroyed + */ +_dbg__cmdChar2Index: + mov r1, r0 /* Copy command character to r1 */ + mov r0, #0 /* Clear return value */ + ldr r3, =debug_cmdIndexTable /* Convert command to index using r3 as Index Lookup Address Pointer */ +1: ldrb r2, [r3, r0] /* Get table entry */ + teq r2, #0 + moveq r0, #CMDINDEX_OUTOFRANGE /* End of Index Table, Not found */ + beq _exit_cmdIndexTable + teq r1, r2 + addne r0, #1 /* Increment Index */ + bne 1b /* No match, skip to next command char */ +_exit_cmdIndexTable: + bx lr + +/* __dbg__cmdParamLen + * Determines the length of the parameter buffer for a given command + * On entry: + * R0: parameter buffer pointer (contents after '$' and '') + * On exit: + * R0: Address of parameter buffer (preserved) + * R1: length + */ +__dbg__cmdParamLen: + stmfd sp!, {r0,r2,lr} /* R2: scratch register */ + mov r1, #0 +1: ldrb r2, [r0], #1 + teq r2, #0 + addne r1, r1, #1 + bne 1b + ldmfd sp!, {r0,r2,pc} + +/* __dbg__procCmdOk + * Common subroutine exit stub to return Command Ok Status for Command Handlers + * DO NOT CALL THIS STUB DIRECTLY! It Assumes that the return address is in the stack. + * + */ +__dbg__procCmdOk: + _dbg_outputMsgStatusOk + b __dbg__sendDebugMsgExit + +/* __dbg__procUnimplementedError + * Common subroutine exit stub to handle Unimplemented GDB Command Error + * DO NOT CALL THIS STUB DIRECTLY! It Assumes that the return address is in the stack. + * Note: GDB Remote Protocol specifies returning blank message ('+$') + * + */ +__dbg__procUnimplementedError: + _dbg_outputMsgValidResponse + b __dbg__sendDebugMsgExit + +/* __dbg__procCmdParamError + * Common subroutine exit stub to handle Command Parameter Error for Command Handlers + * DO NOT CALL THIS STUB DIRECTLY! It Assumes that the return address is in the stack. + * + */ +__dbg__procCmdParamError: + mov r1, #MSG_UNKNOWNPARAM + b __dbg__procErrorMsg + +/* __dbg__procCmdReturnInputLengthError + * Common subroutine exit stub to handle Command Input Length Error for Command Handlers + * DO NOT CALL THIS STUB DIRECTLY! It Assumes that the return address is in the stack. + * + */ +__dbg__procCmdReturnInputLengthError: + mov r1, #MSG_ERRINLENGTH + b __dbg__procErrorMsg + +/* __dbg__procCmdReturnOutputLengthError + * Common subroutine exit stub to handle Command Return Output Error for Command Handlers + * DO NOT CALL THIS STUB DIRECTLY! It Assumes that the return address is in the stack. + * + */ +__dbg__procCmdReturnOutputLengthError: + mov r1, #MSG_ERROUTLENGTH + b __dbg__procErrorMsg + +/* __dbg__procBreakpointAddrError + * Common subroutine exit stub to handle Breakpoint Address Error for Breakpoint Insert/Remove Handlers + * DO NOT CALL THIS STUB DIRECTLY! It Assumes that the return address is in the stack. + * + */ +__dbg__procBreakpointAddrError: + mov r1, #MSG_UNKNOWNBRKPT +/* b __dbg__procErrorMsg */ + + +__dbg__procErrorMsg: + _dbg_outputMsgStatusErr + /* b __dbg__sendDebugMsgExit */ + +__dbg__sendDebugMsgExit: + bl dbg__putDebugMsg /* Send error response to the GDB server */ + ldmfd sp!, {pc} + +/* _dbg__cmd_Status + * Status Command Handler + * On entry: + * r0: parameter buffer (contents after '$' and '') + * On exit: + * r0, r1, r2, r3: destroyed + */ +_dbg__cmd_Status: + stmfd sp!, {lr} + _dbg_get_bkpt_type r0 +_check_data_abort_exception: + teq r0, #DBG_ABORT_DATA + moveq r1, #MSG_SIG_BUS /* Bus Error */ + beq _exit_dmg__cmd_Status +_check_prefetch_abort_exception: + teq r0, #DBG_ABORT_PREFETCH + moveq r1, #MSG_SIG_ABRT /* FIMXE: Look for a better Signal number */ + beq _exit_dmg__cmd_Status +_default_breakpoint_exception: + mov r1, #MSG_SIG_DEFAULT /* Dummy Signal number */ + +_exit_dmg__cmd_Status: + _dbg_outputMsgStatusSig + b __dbg__sendDebugMsgExit + +/* _dbg__cmd_Query + * Query Command Handler + * On entry: + * r0: parameter buffer (contents after '$' and '') + * [varied, see GDB General Packets query docs] + * http://sourceware.org/gdb/current/onlinedocs/gdb/General-Query-Packets.html + * On exit: + * r0, r1, r2, r3: destroyed + */ +_dbg__cmd_Query: + stmfd sp!, {r0,r1, lr} + _dbg_setstate DBG_CONFIGURED /* We have exchanged query messages with the GDB server */ + ldmfd sp!, {r0, r1} /* Restore parameters needed for subsequent processing */ + bl __dbg__cmdParamLen + cmp r1, #CMD_QUERY_MINPARAMLEN + beq _dbg__cmd_Query_default + + ldrb r2, [r0] /* Get First Query Param Char */ +_dbg__cmd_Query_check_C: + teq r2, #CMD_QUERY_CURRTID_CHAR /* Handle Current Thread ID Query */ + bne _dbg__cmd_Query_check_fThreadInfo + cmp r1, #CMD_QUERY_CURRTID_PARAMLEN + bne _dbg__cmd_Query_default + _dbg_outputMsgCurrTID + b __dbg__sendDebugMsgExit +_dbg__cmd_Query_check_fThreadInfo: + teq r2, #CMD_QUERY_FTINFO_CHAR /* Handle fThreadInfo Query */ + bne _dbg__cmd_Query_check_sThreadInfo + cmp r1, #CMD_QUERY_FTINFO_PARAMLEN + bne _dbg__cmd_Query_default + _dbg_outputMsgFirstThreadInfo + b __dbg__sendDebugMsgExit +_dbg__cmd_Query_check_sThreadInfo: + teq r2, #CMD_QUERY_STINFO_CHAR /* Handle sThreadInfo ID Query */ + bne _dbg__cmd_Query_default + cmp r1, #CMD_QUERY_STINFO_PARAMLEN + bne _dbg__cmd_Query_default + _dbg_outputMsgSubsequentThreadInfo + b __dbg__sendDebugMsgExit + +_dbg__cmd_Query_default: + b __dbg__procUnimplementedError /* FIXME: return an empty message to GDB (no modifiable settings) */ + + +/* _dbg__cmd_GetOneReg + * Get One Register Value Command Handler + * Valid command parameter x is from '0' to 'F' for User Mode Registers R0-R15, + * '18' for FPSCR (dummy), and '19' for CPSR + * On entry: + * r0: parameter buffer pointer (contents after '$' and '') + * x + * On exit: + * r0, r1, r2, r3, r4: destroyed + * + */ +_dbg__cmd_GetOneReg: + stmfd sp!, {lr} + bl __dbg__cmdParamLen + cmp r1, #CMD_REG_GETONE_MINPARAMLEN /* Check for correct length */ + blo __dbg__procCmdParamError /* Unexpected input, report error */ + cmp r1, #CMD_REG_GETONE_MAXPARAMLEN /* Check for correct length */ + bhi __dbg__procCmdParamError /* Unexpected input, report error */ + bl ascii2hex_varlen_be /* convert ASCII reg enum to Hex (in R0), R1 has address of next buffer char */ + +_dbg__proc_getRegister: + mov r4, r0 /* Keep register index safe */ + _dbg_outputMsgValidResponse /* R0: address of output message buffer data pointer (after response prefix) */ + mov r1, r4 /* Move register index value to R1 */ + bl _dbg_outputOneRegValue /* update output buffer */ + _asciiz r0, r1 + bl dbg__putDebugMsg /* Send response to the GDB server */ + ldmfd sp!, {pc} + +/* _dbg_outputOneRegValue + * Given Register Enum (0-F: R0-R15, 0x19: CPSR, OtherVal: dummy), output hex char to buffer + * On entry: + * r0: output message buffer pointer + * r1: register enum (0-F, 0x19) + * On exit: + * r0: updated (points to next character slot at end of Output Buffer) + * r1: original output message buffer pointer + * r2: destroyed + */ +_dbg_outputOneRegValue: + stmfd sp!, {lr} + cmp r1, #REG_PC + addls r2, r1, #DBGSTACK_USERREG_INDEX /* Convert register enum to Debug Stack index */ + bls _retrieve_RegVal + + cmp r1, #REG_CPSR + moveq r2, #DBGSTACK_USERCPSR_INDEX /* convert register enum to Debug Stack index */ + beq _retrieve_RegVal + + bhi _exit_dbg_outputOneRegValue /* No match (reg enum > REG_CPSR), skip */ + +#if 0 + cmp r1, #REG_FPSCR + bne _exit_dbg_outputOneRegValue /* No match, skip */ +#endif + +_output_dummy_regval: + /* Output Dummy Register value (for F0-F7, FPSR) */ + /* FIXME: F0-F7 expects output value that is more than 32-bits */ + mov r1, #0 + b _output2buffer /* Output all zeros for F0-F7, FPSCR */ + +_retrieve_RegVal: + _getdbgregisterfromindex r2, r1 /* Retrieve Register contents into R1 */ + +_output2buffer: + +#ifdef __BIG_ENDIAN__ + bl word2ascii_be /* Convert and put hex chars into Output Message Buffer */ +#else + bl word2ascii_le /* Convert and put hex chars into Output Message Buffer */ +#endif + +_exit_dbg_outputOneRegValue: + ldmfd sp!, {pc} + +/* _dbg__cmd_GetAllRegs + * Get All Register Values Command Handler + * Output Buffer returns register values in the order: User R0, R1, R2, ..., R15 + * On entry: + * r0: parameter buffer pointer (contents after '$' and '') + * (no parameters) + * On exit: + * r0, r1, r2, r3: destroyed + */ +_dbg__cmd_GetAllRegs: + stmfd sp!, {lr} + bl __dbg__cmdParamLen + teq r1, #CMD_REG_GETALL_PARAMLEN /* Check for correct length */ + bne __dbg__procCmdParamError /* Unexpected input, report error */ + + _dbg_outputMsgValidResponse /* R0: address of output message buffer data pointer (after response prefix) */ + + /* We must return R0-R15, then CPSR */ + mov r3, #REG_R0 /* Output User Register Values first */ +1: mov r1, r3 + bl _dbg_outputOneRegValue /* update output buffer */ + add r3, r3, #1 /* increment index */ + cmp r3, #REG_PC + bls 1b /* process all the registers */ +#if 0 +_get_cpsr: + /* GDB will query for CPSR value specifically */ + mov r1, #REG_CPSR /* Output User CPSR Value last */ + bl _dbg_outputOneRegValue /* update output buffer */ +#endif + _asciiz r0, r1 + bl dbg__putDebugMsg /* Send response to the GDB server */ + ldmfd sp!, {pc} + +/* _dbg_setOneRegValue + * Given Register Enum (0-F: R0-R15, 0x19: CPSR, OtherVal: dummy), output hex char to buffer + * On entry: + * r0: parameter buffer pointer + * r1: register enum (0-F, 0x19) + * On exit: + * r0: (Updated) Address of parameter in buffer + * r1, r2, r3: destroyed + * + * FIXME: This routine assumes that the input buffer contains exactly 8-Hex digits for each register value. + */ +_dbg_setOneRegValue: + stmfd sp!, {lr} + cmp r1, #REG_PC + addls r2, r1, #DBGSTACK_USERREG_INDEX /* Convert register enum to Debug Stack index */ + bls _store_RegVal + + cmp r1, #REG_CPSR + moveq r2, #DBGSTACK_USERCPSR_INDEX /* convert register enum to Debug Stack index */ + beq _store_RegVal + + bhi _exit_dbg_setOneRegValue /* No match (reg enum > REG_CPSR), skip */ + +#if 0 + cmp r1, #REG_FPSCR + bne _exit_dbg_setOneRegValue /* No match, skip */ +#endif + +_set_dummy_regval: + /* FIXME: This assumes that we will never get FP reg values (96-bits) in this routine */ + /* Set dummy FPSCR value (ignored) */ + add r1, r0, #CMD_REG_REGPARAMLEN /* Just increment the pointer */ + b _done_store_RegVal + +_store_RegVal: +#ifdef __BIG_ENDIAN__ + bl ascii2word_be +#else + bl ascii2word_le +#endif + /* R0: value, R1: pointer to next char in buffer */ + _setdbgregisterfromindex r2, r0, r3 /* Set Register contents in R0, using index in R2, and scratch register R3 */ +_done_store_RegVal: + mov r0, r1 /* Copy buffer pointer to next parameter to R0 for return value */ +_exit_dbg_setOneRegValue: + ldmfd sp!, {pc} + + +/* _dbg__cmd_SetOneReg + * Set One Register Value Command Handler + * Valid command parameter x is from '0' to 'F' for User Mode Registers R0-R15, + * '18' for FPSCR (dummy), and '19' for CPSR + * On entry: + * r0: parameter buffer pointer (contents after '$' and '') + * x=rrrr + * On exit: + * r0, r1, r2, r3, r4: destroyed + * + */ +_dbg__cmd_SetOneReg: + stmfd sp!, {lr} + bl __dbg__cmdParamLen + cmp r1, #CMD_REG_SETONE_MINPARAMLEN /* Check for correct length */ + blo __dbg__procCmdParamError /* Unexpected input, report error */ + cmp r1, #CMD_REG_SETONE_MAXPARAMLEN /* Check for correct length */ + bhi __dbg__procCmdParamError /* Unexpected input, report error */ + + /* FIXME: We can't set FP regs. + * Fortunately the values required by FP regs are 96 bits (24 nibbles) + * so it fails the CMD_REG_SETONE_MAXPARAMLEN check + */ + + bl ascii2hex_varlen_be /* convert ASCII reg enum to Hex (in R0), R1 has address of next buffer char */ + cmp r0, #REG_FPSCR + beq __dbg__procCmdParamError /* Don't allow setting of FPSCR */ + mov r4, r0 /* Keep enum in R4 */ + _check_msgassignment r1 /* R1 points to next char in buffer */ + bne __dbg__procCmdParamError /* Can't find '=' */ + +_dbg__proc_setRegister: + mov r0, r1 /* move parameter buffer pointer to R0 */ + mov r1, r4 /* and retrieve enum to R1 to call _dbg_setOneRegValue */ + bl _dbg_setOneRegValue + b __dbg__procCmdOk + +/* _dbg__cmd_SetAllReg + * Set All Register Values Command Handler + * On entry: + * r0: parameter buffer pointer (contents after '$' and '') + * rrrrRRRRrrrr... (17 registers) + * On exit: + * r0, r1, r2, r3, r4: destroyed + * + */ +_dbg__cmd_SetAllRegs: + /* Assumes that the registers are in the sequence R0, R1, ... R15 */ + stmfd sp!, {lr} + bl __dbg__cmdParamLen /* R0: pointer to parameters in buffer */ + teq r1, #CMD_REG_SETALL_PARAMLEN /* Check for correct length */ + bne __dbg__procCmdParamError /* Unexpected input, report error */ + mov r4, #REG_R0 /* R4: register enum, starting with enum for R0 */ +1: mov r1, r4 /* Copy enum to R1; R0 already points to current parameter */ + bl _dbg_setOneRegValue /* R0: next parameter address pointer */ + add r4, r4, #1 /* increment index */ + cmp r4, #REG_PC + bls 1b + + ldrb r0, [r0] + teq r0, #0 /* Look for ASCIIZ character to terminate loop */ + beq __dbg__procCmdOk + bne __dbg__procCmdParamError /* Unexpected input, report error */ + +/* _dbg__nop + * NOP Command Handler (placeholder) + * On entry: + * r0: parameter buffer (contents after '$' and '') + * On exit: + * r0, r1, r2, r3: destroyed + */ +_dbg__nop: + stmfd sp!, {lr} + b __dbg__procUnimplementedError + +/* _dbg__cmd_ReadMem + * Read Memory Contents Command Handler + * Output Buffer returns memory contents + * On entry: + * r0: parameter buffer pointer (contents after '$' and '') + * AA..AA,LLLL + * On exit: + * r0, r1, r2, r3, r4, r5: destroyed + */ +_dbg__cmd_ReadMem: + stmfd sp!, {lr} + bl __dbg__cmdParamLen +#if 0 + teq r1, #CMD_MEM_READ_PARAMLEN /* Check for correct length */ + bne __dbg__procCmdParamError /* Unexpected input, report error */ + bl ascii2word_be /* convert ASCII address location to Hex (in R0), R1 has address of next buffer char */ +#endif + bl ascii2hex_varlen_be /* convert ASCII address to Hex (in R0), R1 has address of next buffer char */ + mov r5, r0 /* Keep Address location in R5 */ + _check_msgseparator r1 + bne __dbg__procCmdParamError /* Can't find ',' */ + mov r0, r1 /* move buffer pointer to R0 for subsequent processing */ + bl ascii2hex_varlen_be /* convert ASCII length to Hex (in R0), R1 has address of next buffer char */ + cmp r0, #CMD_MEM_MAXREADBYTES /* Don't overflow our buffer (2 x CMD_MEM_MAXREADBYTES) */ + bhi __dbg__procCmdReturnOutputLengthError /* Requested Length greater than buffer size, return error */ + mov r4, r0 /* Keep numbytes in R4 */ + /* FIXME: Should validate the address? */ + + _dbg_outputMsgValidResponse /* R0: address of output message buffer data pointer (after response prefix) */ +1: ldrb r1, [r5], #1 + bl byte2ascii /* update output buffer */ + subs r4, r4, #1 + bne 1b + + _asciiz r0, r1 + bl dbg__putDebugMsg /* Send response to the GDB server */ + ldmfd sp!, {pc} + + +/* _dbg__cmd_WriteMem + * Write Memory Contents Command Handler + * On entry: + * r0: parameter buffer pointer (contents after '$' and '') + * AA..AA,LLLL::bb..bb + * On exit: + * r0, r1, r2, r3, r4: destroyed + */ +_dbg__cmd_WriteMem: + stmfd sp!, {lr} + bl __dbg__cmdParamLen +#if 0 + cmp r1, #CMD_MEM_WRITE_MINPARAMLEN /* Check for correct (minimum) length */ + blo __dbg__procCmdParamError /* Unexpected input, report error */ + sub r4, r1, #CMD_MEM_WRITE_MINPARAMLEN /* R4: Number of ASCII Hex chars for byte writes */ + bl ascii2word_be /* convert ASCII address location to Hex (in R0), R1 has address of next buffer char */ +#endif + bl ascii2hex_varlen_be /* convert ASCII address to Hex (in R0), R1 has address of next buffer char */ + mov r3, r0 /* Keep Address location in R3 */ + _check_msgseparator r1 + bne __dbg__procCmdParamError /* Can't find ',' */ + mov r0, r1 /* move buffer pointer to R0 for subsequent processing */ + bl ascii2hex_varlen_be /* convert ASCII length to Hex (in R0), R1 has address of next buffer char */ + cmp r0, r4, asr #1 /* is Number of bytes to write == (number of ASCII Hex Chars / 2)? */ + bne __dbg__procCmdParamError /* Number of bytes does not match argument length */ + cmp r0, #CMD_MEM_MAXWRITEBYTES /* Don't overflow our buffer (2 x CMD_MEM_MAXWRITEBYTES) */ + bhi __dbg__procCmdReturnInputLengthError /* Requested Length greater than buffer size, return error */ + mov r4, r0 /* Keep numbytes in R4 */ + /* FIXME: Should validate the address? */ + _check_msgargument r1 + bne __dbg__procCmdParamError /* Can't find ':' */ + +1: mov r0, r1 + bl ascii2byte /* convert ASCII Hex value into byte value */ + strb r0, [r3], #1 /* Store into memory location */ + subs r4, r4, #1 + bne 1b + b __dbg__procCmdOk + +/* _dbg__cmd_Detach + * Detach User Program Execution Command Handler + * Treat this as being equivalent to 'Continue' without any arguments + * + * On entry: + * r0: parameter buffer pointer (contents after '$' and '') + * (No Parameters) + * On exit: + * r0-r7: destroyed + * Note: This routine does not return to caller. Instead it switches + * operating mode to UNDEF and returns to previously active program + */ +_dbg__cmd_Detach: + stmfd sp!, {lr} /* In case unexpected parameters were received */ + bl __dbg__cmdParamLen + teq r1, #CMD_DETACH_PARAMLEN /* Check for correct length */ + bne __dbg__procCmdParamError /* Unexpected input, report error */ + + ldmfd sp!, {lr} /* Cleanup stack, since we won't return to the Debugger Run Loop */ + _dbg_setstate DBG_INIT /* Reset the Debug State */ + bl __dbg__procOkOnly /* send OK to keep GDB server happy */ + b _dbg__cont_check_breakpoint_type /* Continue from current PC */ + +/* _dbg__cmd_Continue + * Continue User Program Execution Command Handler + * Setup breakpoints before resuming execution of program. + * + * If Address is specified, update the next instruction address to specified address + * + * If this is a Normal Breakpoint, then we resume from current (Breakpoint) exception address + * Else (it is a Manual Breakpoint or Address Specified) + * We need to resume from the next instruction address + * On entry: + * r0: parameter buffer pointer (contents after '$' and '') + * Optional: AA..AA + * On exit: + * r0-r7: destroyed + * Note: This routine does not return to caller. Instead it switches + * operating mode to UNDEF and returns to previously active program + */ +_dbg__cmd_Continue: + /* Don't put anything on the stack, we won't return to the Debugger Run Loop */ + bl __dbg__cmdParamLen + cmp r1, #CMD_CONTINUE_MINPARAMLEN /* Check for correct parameter length */ + bne _dbg__cont_fromAddr /* Address is specified */ + bl __dbg__procAckOnly /* send Ack to keep GDB server happy */ + b _dbg__cont_check_breakpoint_type /* Continue from current PC */ + +_dbg__cont_fromAddr: + bl ascii2hex_varlen_be /* convert ASCII address to Hex (in R0), R1 has address of next buffer char */ + /* Continue from Specified Address */ + _setdbgregister DBGSTACK_NEXTINSTR_INDEX, r0, r1 /* Set Next Instruction Pointer for Resume using contents of R0, and scratch register R1 */ + bl __dbg__procAckOnly /* send Ack to keep GDB server happy */ + b _dbg__cont_is_manual_bkpt_or_address_specified + +_dbg__cont_check_breakpoint_type: + _dbg_get_bkpt_type r0 + teq r0, #DBG_MANUAL_BKPT_ARM + beq _dbg__cont_is_manual_bkpt_or_address_specified + teq r0, #DBG_MANUAL_BKPT_THUMB + beq _dbg__cont_is_manual_bkpt_or_address_specified + +_dbg__cont_is_normal_breakpoint: + _getdbgregister DBGSTACK_USERPC_INDEX, r0 /* Retrieve Aborted Instruction PC from the Debug Stack into R0 */ + _setdbgregister DBGSTACK_NEXTINSTR_INDEX, r0, r1 /* Set Next Instruction Pointer for Resume using contents of R0, and scratch register R1 */ + /* GDB knows to Step from a breakpointed instruction before continuing when + * Continue is issued, so it is safe to activate all defined breakpoints and continue. + */ +_dbg__cont_is_manual_bkpt_or_address_specified: + bl _dbg__activate_breakpoints /* Restore exisiting breakpoints */ + b _dbg__switch2undefmode + +/* _dbg__cmd_Step + * Step User Program Execution Command Handler + * Setup breakpoints before resuming execution of program. + * + * If Address is specified, update the next instruction address to specified address + * + * If this is a Normal Breakpoint, then we need to install a Step Breakpoint at next instruction address + * and resume from current (Breakpoint) exception address + * Else (it is a Manual Breakpoint or Address specified) + * We need to install a Step Breakpoint at the following instruction address (after the next instruction address) + * and resume from the next instruction address + * On entry: + * r0: parameter buffer pointer (contents after '$' and '') + * Optional: AA..AA + * On exit: + * r0-r7: destroyed + * Note: This routine does not return to caller. Instead it switches + * operating mode to UNDEF and returns to previously active program + */ +_dbg__cmd_Step: + /* Don't put anything on the stack, we won't return to the Debugger Run Loop */ + bl __dbg__cmdParamLen + cmp r1, #CMD_STEP_MINPARAMLEN /* Check for correct parameter length */ + beq _dbg__step_check_breakpoint_type /* Step from current PC */ + +_dbg__step_fromAddr: + bl ascii2hex_varlen_be /* convert ASCII address to Hex (in R0), R1 has address of next buffer char */ + /* Step from Specified Address */ + _setdbgregister DBGSTACK_NEXTINSTR_INDEX, r0, r1 /* Set Next Instruction Pointer for Resume using contents of R0, and scratch register R1 */ + b _dbg__step_is_manual_bkpt_or_address_specified + +_dbg__step_check_breakpoint_type: + _dbg_get_bkpt_type r0 + teq r0, #DBG_MANUAL_BKPT_ARM + beq _dbg__step_is_manual_bkpt + teq r0, #DBG_MANUAL_BKPT_THUMB + beq _dbg__step_is_manual_bkpt + +_dbg__step_is_normal_breakpoint: + _getdbgregister DBGSTACK_USERPC_INDEX, r0 /* Retrieve Aborted Instruction PC from the Debug Stack into R0 */ + _setdbgregister DBGSTACK_NEXTINSTR_INDEX, r0, r1 /* Set Next Instruction Pointer for Resume usinh contents in R0, and scratch register R1 */ + b _dbg__step_is_manual_bkpt_or_address_specified + +_dbg__step_is_manual_bkpt: + _getdbgregister DBGSTACK_NEXTINSTR_INDEX, r0 /* Retrieve Next Instruction Pointer for Resume into R1 */ + /* b _dbg__step_is_manual_bkpt_or_address_specified */ + +_dbg__step_is_manual_bkpt_or_address_specified: + bl dbg_following_instruction_addr /* following instruction address returned in r1 */ + bl dbg__install_singlestep /* Setup Single Step, next instruction address returned in r1 */ + bl dbg__activate_singlestep +#if 0 + /* Disable ACK transmit, let the next Breakpoint generate the Signal Response */ + bl __dbg__procAckOnly /* send Ack to keep GDB server happy */ +#endif + b _dbg__switch2undefmode + +/* _dbg__cmd_Kill + * Kill User Program Execution Command Handler + * Kill Program, this is accomplished by rebooting the Brick + * + * On entry: + * r0: parameter buffer pointer (contents after '$' and '') + * (No Parameters) + * On exit: + * r0-r7: destroyed + * Note: This routine does not return to caller. Instead it calls + * the relevant system routine to reboot the Brick + */ +_dbg__cmd_Kill: + stmfd sp!, {lr} /* In case unexpected parameters were received */ + bl __dbg__cmdParamLen + teq r1, #CMD_KILL_PARAMLEN /* Check for correct length */ + bne __dbg__procCmdParamError /* Unexpected input, report error */ + + bl __dbg__procAckOnly /* send Ack to keep GDB server happy */ + b dbg__reboot /* Goodbye.... */ + +/* _dbg__proc_brkpt_params + * Process Breakpoint Parameters + * On entry: + * r0: parameter buffer pointer (contents after '$' and '') + * t,AA..AA,k + * On exit: + * r0: non-zero = breakpoint address; 0 = parameter error + * r1: destroyed + * r2: destroyed + * r3: destroyed + */ +_dbg__proc_brkpt_params: + /* FIXME: Add support for watchpoints */ + stmfd sp!, {lr} + mov r3, r0 /* Keep parameter buffer address in R3 */ + ldrb r0, [r3], #1 /* get breakpoint type t */ + bl char2hex + cmp r0, #CMD_BKPT_TYPE_BREAK_MEMORY + bne _dbg__proc_brkpt_params_error /* We only support memory breakpoints for now */ + _check_msgseparator r3 + bne _dbg__proc_brkpt_params_error /* Something wrong with the parameters */ + mov r0, r3 /* Check Address */ + bl ascii2hex_varlen_be /* convert ASCII address to Hex (in R0), R1 has address of next buffer char */ + mov r3, r0 /* Keep breakpoint address in R3 */ + _check_msgseparator r1 + bne _dbg__proc_brkpt_params_error /* Something wrong with the parameters */ + ldrb r0, [r1], #1 /* get breakpoint kind k */ + bl char2hex + cmp r0, #CMD_BKPT_KIND_THUMB + orreq r3, r3, #1 /* Mark Thumb breakpoints */ + beq _exit_dbg__proc_brkpt_params + cmp r0, #CMD_BKPT_KIND_ARM + beq _exit_dbg__proc_brkpt_params /* ARM breakpoint */ + +_dbg__proc_brkpt_params_error: + mov r3, #0 /* Unrecognized breakpoint type */ +_exit_dbg__proc_brkpt_params: + mov r0, r3 /* return breakpoint address */ + ldmfd sp!, {pc} + +/* _dbg__cmd_InsertBreakpoint + * Add Breakpoint + * On entry: + * r0: parameter buffer pointer (contents after '$' and '') + * t,AA..AA,k + * On exit: + * r0, r1, r2, r3: destroyed + */ +_dbg__cmd_InsertBreakpoint: + stmfd sp!, {lr} + bl __dbg__cmdParamLen + teq r1, #CMD_BKPT_INSERT_MINPARAMLEN /* Check for correct length */ + blo __dbg__procCmdParamError /* Unexpected input, report error */ + bl _dbg__proc_brkpt_params /* R0: Breakpoint Address */ + teq r0, #0 + beq __dbg__procBreakpointAddrError /* Thumb2 instructions, or unknown kind */ + mov r3, r0 /* Keep breakpoint address in R3 */ + mov r0, #0 /* Empty Breakpoint entry */ + bl _dbg_find_breakpoint_slot /* Look for an available breakpoint slot, return index in R0 */ + cmp r0, #CMD_BKPT_NOTFOUND + beq __dbg__procBreakpointAddrError /* No empty slot! */ + mov r1, r3 /* Move breakpoint address to R1 */ + bl _dbg__install_one_breakpoint /* r0: index, r1: instruction address */ + b __dbg__procCmdOk + +/* _dbg__cmd_RemoveBreakpoint + * Remove Breakpoint + * On entry: + * r0: parameter buffer pointer (contents after '$' and '') + * t,AA..AA,k + * On exit: + * r0, r1, r2, r3: destroyed + */ +_dbg__cmd_RemoveBreakpoint: + stmfd sp!, {lr} + bl __dbg__cmdParamLen + teq r1, #CMD_BKPT_REMOVE_MINPARAMLEN /* Check for correct length */ + blo __dbg__procCmdParamError /* Unexpected input, report error */ + bl _dbg__proc_brkpt_params /* R0: Breakpoint Address */ + teq r0, #0 + beq __dbg__procBreakpointAddrError /* Thumb2 instructions, or unknown kind */ + bl _dbg_find_breakpoint_slot /* Look for matching breakpoint slot, return index in R0 */ + cmp r0, #CMD_BKPT_NOTFOUND + beq __dbg__procBreakpointAddrError /* Specified Breakpoint not found! */ + _index2bkptindex_addr r0, r1 /* Calculate Breakpoint Entry Address */ + mov r0, r1 /* Move it to R0 for subroutine call */ + bl _dbg__clear_one_breakpoint /* R0: address of breakpoint to clear */ + b __dbg__procCmdOk + +/**************************************************************************** + * + * Breakpoint Manipulation Routines + * + ****************************************************************************/ +/* _dbg_find_breakpoint_slot + * Find the matching Breakpoint Slot. + * This is both used to find empty slots (pass R0=0x0000) or + * occupied slots (pass R0=) + * + * On Entry: + * R0: Breakpoint Address + * On Exit: + * R0: Matching Index (-1: not found) + * + * NOTE: This routine performs exact match, i.e., breakpoint address MUST be configured + * for ARM or Thumb (bit 0 clear/set) as appropriate + */ + +_dbg_find_breakpoint_slot: + stmfd sp!, {r1,r2,r3, lr} + mov r1, #1 /* Only consider Breakpoints 1-7 */ + ldr r3, =__breakpoints_num__ +1: + _index2bkptindex_addr r1, r2 /* Calculate Breakpoint Entry Address */ + ldr r2, [r2] /* Get actual breakpoint entry (instruction address) */ + cmp r0, r2 + beq _found_breakpoint_slot + add r1, r1, #1 /* no match, check next */ + cmp r1, r3 + blo 1b /* continue checking only if we don't exceed __breakpoints_num__ */ + +_notfound_breakpoint_slot: + mov r1, #CMD_BKPT_NOTFOUND +_found_breakpoint_slot: + mov r0, r1 /* Return value in R0 */ + ldmfd sp!, {r1,r2,r3, pc} + +/* _dbg__clear_singlestep + * Clear the Single Step Breakpoint + */ +_dbg__clear_singlestep: + ldr r0, =__breakpoints_start__ /* Single Step Breakpoint is at the beginning of the Breakpoint State Struct */ +/* b _dbg__clear_one_breakpoint */ + +/* _dbg__clear_one_breakpoint + * On entry, R0 contains the Breakpoint State slot address to be cleared + * + */ +_dbg__clear_one_breakpoint: + mov r1, #0 + mov r2, #0 + stmea r0!, {r1, r2} /* clear Breakpoint state */ + bx lr + +/* _dbg__clear_breakpoints + * Routine iterates through the array of breakpoints (incl single step breakpoint) and clears the breakpoint + */ +_dbg__clear_breakpoints: + stmfd sp!, {lr} + ldr r0, =__breakpoints_start__ /* Single Step Breakpoint is at the beginning of the Breakpoint State Struct */ + ldr r3, =__breakpoints_end__ /* start from top of the table */ +3: bl _dbg__clear_one_breakpoint + cmp r0, r3 + blo 3b + ldmfd sp!, {pc} + +/* dbg__install_singlestep + * Install the Single Step Breakpoint + * + * On entry: + * R1: Instruction Address (31 bits, b0 = THUMB flag) + * On exit: + * R0: Breakpoint index (preserved) + * R1: Instruction Address (preserved) + * R2: Breakpoint Instruction + * R3: Breakpoint Entry address + */ + dbg_interwork dbg__install_singlestep + mov r0, #0 +/* b _dbg__install_one_breakpoint */ + +/* _dbg__install_one_breakpoint + * Install breakpoint entry into Breakpoint State Table + * + * On entry: + * R0: Breakpoint index (assumed valid) + * R1: Instruction Address (31 bits, b0 = THUMB flag) + * On exit: + * R0: Breakpoint index (preserved) + * R1: Instruction Address (preserved) + * R2: Breakpoint Instruction + * R3: Breakpoint Entry address + */ +_dbg__install_one_breakpoint: +/* Check for Thumb bit */ + tst r1, #BKPT_STATE_THUMB_FLAG /* 1: Thumb instruction */ +/* Assume that the address entry is valid, otherwise we should sanitize it (mask out b1) */ + bic r2, r1, #BKPT_STATE_THUMB_FLAG /* R2: Instruction Address; clear Thumb Flag for accessing Memory */ + ldreq r2, [r2] /* if 0: load ARM instruction from address location */ + ldrneh r2, [r2] /* else load Thumb instruction */ + _index2bkptindex_addr r0, r3 /* Calculate Breakpoint Entry Address */ + stm r3, {r1, r2} + bx lr + + +/* _dbg__restore_singlestep + * Restores the contents of the single step breakpoint to memory + * + * On entry: + * None + * On exit: + * R0-R2: Destroyed + */ +_dbg__restore_singlestep: + mov r0, #0 /* single step breakpoint index */ + _index2bkptindex_addr r0, r1 /* Calculate Single Step Breakpoint Entry Address */ + ldm r1, {r1, r2} /* r1: Breakpoint Address, r2: Breakpoint Instruction */ + teq r1, #0 + bxeq lr /* Exit if not active */ +/* b _dbg__restore_one_breakpoint */ + +/* _dbg__restore_one_breakpoint + * Restores the contents to memory for one breakpoint + * + * On entry: + * R0: Breakpoint index (assumed valid) [not used -- can be used for validating BKPT] + * R1: Breakpoint Address (assumed valid) + * R2: Breakpoint Instruction (assumed valid) + * On exit: + * R0: Breakpoint index (preserved) + * R1: B0 cleared if Thumb Instruction Address + * R2: Breakpoint Instruction (preserved) + */ +_dbg__restore_one_breakpoint: +/* Check for Thumb bit */ + tst r1, #BKPT_STATE_THUMB_FLAG /* 1: Thumb instruction */ +/* Assume that the address entry is valid, otherwise we should sanitize it (mask out b1) */ + streq r2, [r1] /* if 0: restore ARM instruction to address location */ + bicne r1, #BKPT_STATE_THUMB_FLAG /* else, clear Thumb Flag */ + strneh r2, [r1] /* store Thumb instruction */ + bx lr + +/* _dbg__restore_breakpoints + * Routine iterates through the array of breakpoints (incl single step breakpoint) and restores the contents to memory + * Only Active breakpoints (i.e., Non-zero Address) are processed. + * + * On entry: + * None + * On exit: + * R0-R6: Destroyed + */ +_dbg__restore_breakpoints: + stmfd sp!, {lr} + ldr r6, =_dbg__restore_one_breakpoint + b __dbg__iterate_breakpoint_array + +/* dbg__activate_singlestep + * Activate the single step breakpoint to memory + * + * On entry: + * None + * On exit: + * R0-R3: Destroyed + */ + dbg_interwork dbg__activate_singlestep + mov r0, #0 /* single step breakpoint index */ + _index2bkptindex_addr r0, r1 /* Calculate Single Step Breakpoint Entry Address */ + ldm r1, {r1, r2} /* r1: Breakpoint Address, r2: Breakpoint Instruction */ + teq r1, #0 + bxeq lr /* Exit if not active */ +/* b _dbg__activate_one_breakpoint */ + +/* _dbg__activate_one_breakpoint + * Activate one breakpoint to memory + * + * On entry: + * R0: Breakpoint index (assumed valid) + * R1: Breakpoint Address (assumed valid) + * R2: Breakpoint Instruction (assumed valid) + * On exit: + * R0: Breakpoint index (preserved) + * R1-R3: Destroyed + */ +_dbg__activate_one_breakpoint: +/* Check for Thumb bit */ + tst r1, #BKPT_STATE_THUMB_FLAG /* 1: Thumb instruction */ + bne _nx_is_thumb_bp +_nx_is_arm_bp: +/* Assume that the address entry is valid, otherwise we should sanitize it (mask out b1) */ + ldr r3, [r1] /* if 0: load ARM instruction from address location */ + teq r2, r3 /* check that the two instructions are identical */ + bne _dbg__breakpoint_invalid_arm + ldr r2, =BKPT32_INSTR /* ARM BKPT instruction */ + orr r2, r2, r0 /* Merge Breakpoint index */ + str r2, [r1] /* Store it into memory location */ +_dbg__breakpoint_invalid_arm: + bx lr +_nx_is_thumb_bp: + bic r1, #BKPT_STATE_THUMB_FLAG /* else, clear Thumb Flag */ + ldrh r3, [r1] /* load Thumb instruction from address location */ + teq r2, r3 /* check that the two instructions are identical */ + bne _dbg__breakpoint_invalid_thumb + ldr r2, =BKPT16_INSTR /* Thumb BKPT instruction */ + orr r2, r2, r0 /* Merge Breakpoint index */ + strh r2, [r1] /* Store it into memory location */ +_dbg__breakpoint_invalid_thumb: + bx lr + +/* _dbg__activate_breakpoints + * Routine iterates through the array of breakpoints (incl single step breakpoint) and activates them + * Only Active breakpoints (i.e., Non-zero Address) are processed. + * + * On entry: + * None + * On exit: + * R0-R6: Destroyed + */ +_dbg__activate_breakpoints: + stmfd sp!, {lr} + ldr r6, =_dbg__activate_one_breakpoint + b __dbg__iterate_breakpoint_array + + +/* __dbg__iterate_breakpoint_array + * WARNING: DO NOT CALL THIS ROUTINE DIRECTLY. + * Internal Routine, assumes that lr has been push to stack + * + * Common routine to iterate through the array of breakpoints (incl single step breakpoint) + * Only Active breakpoints (i.e., Non-zero Address entries) are processed. + * + * On Entry: + * R0: Breakpoint index + * R1: Breakpoint Address + * R2: Breakpoint Instruction + * R6: Handler Routine + * On exit: + * R0-R5: Destroyed + * R6: Handler routine (preserved) + * + */ +__dbg__iterate_breakpoint_array: + ldr r5, =__breakpoints_end__ /* start from top of the table (Assume __breakpoints_end__ > __breakpoints_start__) */ + ldr r4, =__breakpoints_start__ /* end address check */ + ldr r0, =__breakpoints_num__ /* Number of Breakpoints (incl Single Step) (Assume Non-Zero) */ +4: sub r0, r0, #1 /* Decrement breakpoint index in r0 */ + ldmea r5!, {r1, r2} /* r1: Breakpoint Address, r2: Breakpoint Instruction */ + teq r1, #0 /* Is it active? */ + movne lr, pc + bxne r6 /* active entry */ + cmp r5, r4 + bhi 4b /* if (pointer > start of Breakpoint Table address), get next slot */ + ldmfd sp!, {pc} + diff --git a/armdebug/Debugger/debug_stub.h b/armdebug/Debugger/debug_stub.h new file mode 100644 index 0000000..2430e77 --- /dev/null +++ b/armdebug/Debugger/debug_stub.h @@ -0,0 +1,165 @@ +/** @file debug_stub.h + * @brief Shared C/ASM header file for debugger stub + * + */ + +/* Copyright (C) 2007-2010 the NxOS developers + * + * Module Developed by: TC Wan + * + * See AUTHORS for a full list of the developers. + * + * See COPYING for redistribution license + * + */ + +#ifndef __DEBUG_STUB_H__ +#define __DEBUG_STUB_H__ + +#include "_c_arm_macros.h" + +/** @name BKPT suppport constants + * + * ARM and Thumb Breakpoint Instructions. + */ +/*@{*/ + +#define __ARM6OR7__ + +#ifdef __ARM6OR7__ +#define BKPT32_INSTR 0xE7200070 /* ARM6 and ARM7 does not trap unused opcodes (BKPT overlap with control instructions), \ + CPU has unpredictable behavior. Ref: Steve Furber, ARM SoC Architecture 2nd Ed, pg. 143 */ +#else +#define BKPT32_INSTR 0xE1200070 /* ARM BKPT instruction, will work in ARMv5T and above */ +#endif + +#define BKPT32_ENUM_MASK 0x000FFF0F /* ARM BKPT Enum Mask */ +#define BKPT32_AUTO_BKPT 0x00080000 /* RESERVED: ARM BKPT Auto-Step Flag (for CONT support) */ +#define BKPT32_MANUAL_BKPT 0x0007FF0F /* Manually inserted ARM Breakpoint */ + +#define BKPT16_INSTR 0xBE00 /* Thumb BKPT instruction */ +#define BKPT16_ENUM_MASK 0x00FF /* Thumb BKPT Enum Mask */ +#define BKPT16_AUTO_BKPT 0x0080 /* RESERVED: Thumb BKPT Auto-Step Flag (for CONT support) */ +#define BKPT16_MANUAL_BKPT 0x007F /* Manually inserted Thumb Breakpoint */ +/*@}*/ + +#ifndef __ASSEMBLY__ + +/* Define C stuff */ +/** @defgroup debug_public */ +/*@{*/ + + +/** Initialize Debugger. + * Equivalent to GDB set_debug_traps() routine + */ +FUNCDEF void dbg__bkpt_init(void); + +#ifdef __NXOS__ + +/** Communication Channel Enums + * + * Communication Channel Enums. + */ +ENUM_BEGIN +ENUM_VALASSIGN(COMM_USB, 1) /**< USB Communications */ +ENUM_VAL(COMM_BT) /**< Bluetooth Communications */ +ENUM_END(comm_chan_t) + +/** Enable switch to Debugger Mode from NxOS operational mode + * Returns 0 if no mode switch needed (already in Debug mode) + * !0 if mode switch will happen + * Used by NxOS only + */ +/* Note: This platform specific routine is found in debug_runlooptasks.S */ +FUNCDEF int nxos__handleDebug(U8 *buffer, comm_chan_t channel, U32 length); +#else +/** Switch Mode to Debugger. + * Used by NXT Firmware only + */ +/* Note: This platform specific routine is found in debug_runlooptasks.S */ +FUNCDEF UWORD cCommHandleDebug(UBYTE *pInBuf, UBYTE CmdBit, UWORD MsgLength); +#endif + +/** Debugger Handler Routine (called by Exception Handler Trap). + * Equivalent to GDB handle_exception() routine + */ +FUNCDEF void dbg__bkpt_handler(void); + +/** dbg_breakpoint_arm. + * Equivalent to GDB breakpoint() routine for ARM code + */ +/* FUNCDEF void dbg_breakpoint_arm(void); */ +static inline void dbg_breakpoint_arm(void) +{ + asm volatile (".word %a0" + : /* Output (empty) */ + : "X" (BKPT32_INSTR | BKPT32_MANUAL_BKPT) + ); +} + +#if 0 /* Old asm definitions, in case gas does not recognize %a0 operand */ + +#ifdef __ARM6OR7__ +static inline void dbg_breakpoint_arm(void) { asm volatile (".word 0xE727FF7F" /* (BKPT32_INSTR | BKPT32_MANUAL_BKPT) */ ); } +#else +static inline void dbg_breakpoint_arm(void) { asm volatile (".word 0xE127FF7F" /* (BKPT32_INSTR | BKPT32_MANUAL_BKPT) */ ); } +#endif + +#endif + +/** dbg_breakpoint_thumb. + * Equivalent to GDB breakpoint() routine for Thumb code + */ +/* FUNCDEF void dbg_breakpoint_thumb(void); */ +static inline void dbg_breakpoint_thumb(void) +{ + asm volatile (".hword %a0" + : /* Output (empty) */ + : "X" (BKPT16_INSTR | BKPT16_MANUAL_BKPT) + ); +} + +#if 0 /* Old asm definitions, in case gas does not recognize %a0 operand */ + +static inline void dbg_breakpoint_thumb(void) { asm volatile (".hword 0xBE7F" /* (BKPT16_INSTR | BKPT16_MANUAL_BKPT) */); } + +#endif + +/*@}*/ + +#else +/* Define Assembly stuff */ + +/* dbg__bkpt_arm + * GDB breakpoint() for ARM mode + */ + .macro dbg__bkpt_arm + .word (BKPT32_INSTR | BKPT32_MANUAL_BKPT) + .endm + +/* dbg__bkpt_thumb + * GDB breakpoint() for Thumb mode + */ + .macro dbg__bkpt_thumb + .hword (BKPT16_INSTR | BKPT16_MANUAL_BKPT) + .endm + +/** Macro to declare Interworking ARM Routine + * + * dbg_interwork + * + * Note: declared as a private macro since ARMDEBUG is also used by NIF + */ + .macro dbg_interwork arm_routine + .align 4 + .arm + .type \arm_routine, %function @ Needed by new binutils (>2.21) + .global \arm_routine +\arm_routine: + .endm + +#endif + /*@}*/ + +#endif /* __DEBUG_STUB_H__ */ diff --git a/armdebug/Debugger/debug_test.S b/armdebug/Debugger/debug_test.S new file mode 100644 index 0000000..2cb87a0 --- /dev/null +++ b/armdebug/Debugger/debug_test.S @@ -0,0 +1,161 @@ +/** @file debug_test.S + * @brief Test Routines to trigger ARM and Thumb Manual Breakpoints + * + */ + +/* Copyright (C) 2007-2011 the NxOS developers + * + * Module Developed by: TC Wan + * + * See AUTHORS for a full list of the developers. + * + * See COPYING for redistribution license + * + */ +#define __ASSEMBLY__ +#include "debug_stub.h" + +.text +.align 4 +.code 32 + +/********************************************** + * dbg__test_arm_bkpt Test Routine + * + */ + dbg_interwork dbg__test_arm_bkpt + stmfd sp!,{lr} + dbg__bkpt_arm /* Trigger ARM Manual Breakpoint */ + ldmfd sp!,{pc} + + +/********************************************** + * dbg__test_arm_instrstep Test Routine + * Used to test GDB Stepping command + * This routine exercises the mov, add, ldr, ldm, b, bl, + * and bx instructions which modify the PC (R15) + * In addition, conditional instructions are also evaluated. + * + */ + dbg_interwork dbg__test_arm_instrstep + stmfd sp!, {lr} + bl dbg__test_arm_instr_sub1 + ldr r1, =test_arm_3 /* R1: pointer to test_arm_3 */ + ldr r2, =test_arm_2 /* R2: pointer to test_arm_2 */ + mov pc, r1 + +test_arm_1: + subs r0, r0, #1 + addne pc, r2, #4 /* If R0 > 0, keep branching to a new location */ + /* else R0 == 0 */ + b exit_dbg__test_arm_instrstep + +test_arm_2: + sub r0, r0, #1 + cmp r0, #5 + bgt test_arm_1 + ldrle pc, =exit_dbg__test_arm_instrstep + b exit_dbg__test_arm_instrstep + +test_arm_3: + sub r0, r0, #1 + teq r0, #8 + beq test_arm_1 + ldrne r3, =test_arm_3 + bx r3 + +exit_dbg__test_arm_instrstep: + bl dbg__test_thumb_instr_sub1 + ldmfd sp!, {pc} + + .global dbg__test_arm_instr_sub1 +dbg__test_arm_instr_sub1: + mov r0, #10 + bx lr + + .global dbg__test_arm_instr_sub1 +dbg__test_arm_instr_sub2: + stmfd sp!, {r4, lr} + mov r0, #TRUE + ldmfd sp!, {r4, pc} + +/********************************************** + * dbg__test_thumb_bkpt Test Routine + * + */ + dbg_interwork dbg__test_thumb_bkpt + stmfd sp!,{lr} +/* ldr r0, =_thumb_entry + orr r0, r0, #1 @ Set Thumb mode + mov lr, pc + bx r0 +*/ + bl _thumb_entry + ldmfd sp!,{pc} + +.code 16 + .thumb_func + .type _thumb_entry, %function +_thumb_entry: + dbg__bkpt_thumb + bx lr + + +/********************************************** + * dbg__test_thumb_instrstep Test Routine + * Used to test GDB Stepping command + * + */ + .global dbg__test_thumb_instrstep + .thumb_func + .type dbg__test_thumb_instrstep, %function +dbg__test_thumb_instrstep: + push {lr} + bl dbg__test_thumb_instr_sub1 + bl dbg__test_thumb_instr_sub2 + +test_thumb_1: + sub r0, #1 + bne test_thumb_2 + /* else R0 == 0 */ + b exit_dbg__test_thumb_instrstep + +test_thumb_2: + sub r0, #1 + cmp r0, #5 + bls test_thumb_1 + bhi test_thumb_3 + beq test_thumb_2 + b test_thumb_1 + +test_thumb_3: + sub r0, #1 + cmp r0, #0xB + blo load_test_thumb_1 + ldr r2, =test_thumb_3+1 /* Need to set Thumb bit */ + b exit_test_thumb_3 +load_test_thumb_1: + ldr r2, =test_thumb_1+1 /* Need to set Thumb bit */ +exit_test_thumb_3: + bx r2 + +exit_dbg__test_thumb_instrstep: + bl dbg__test_arm_instr_sub1 + pop {r1} + bx r1 + + .thumb_func + .type dbg__test_thumb_instr_sub1, %function +dbg__test_thumb_instr_sub1: + mov r0, #0x0F + bx lr + + .thumb_func + .type dbg__test_thumb_instr_sub2, %function +dbg__test_thumb_instr_sub2: + push {lr} + mov r1, #FALSE + pop {pc} + + +.end diff --git a/armdebug/Debugger/debug_test.h b/armdebug/Debugger/debug_test.h new file mode 100644 index 0000000..b8e6634 --- /dev/null +++ b/armdebug/Debugger/debug_test.h @@ -0,0 +1,50 @@ +/** @file debug_test.h + * @brief C header file for debugger test routines + * + */ + +/* Copyright (C) 2007-2010 the NxOS developers + * + * Module Developed by: TC Wan + * + * See AUTHORS for a full list of the developers. + * + * See COPYING for redistribution license + * + */ + +#ifndef __DEBUG_TEST_H__ +#define __DEBUG_TEST_H__ + +#include "_c_arm_macros.h" + +#ifndef __ASSEMBLY__ + +/* Define C stuff */ +/** @defgroup debug_public */ +/*@{*/ + +/** + * Insert ARM Breakpoint instruction into code stream + */ +FUNCDEF void dbg__test_arm_bkpt(void); +/** + * Insert Thumb Breakpoint instruction into code stream + */ +FUNCDEF void dbg__test_thumb_bkpt(void); + +/** + * Dummy function for testing ARM instruction stepping + */ +FUNCDEF void dbg__test_arm_instrstep(void); +/** + * Dummy function for testing Thumb instruction stepping + */ +FUNCDEF void dbg__test_thumb_instrstep(void); + + /*@}*/ + +#endif + + +#endif /* __DEBUG_TEST_H__ */ diff --git a/armdebug/Debugger/undef_handler.S b/armdebug/Debugger/undef_handler.S new file mode 100644 index 0000000..cfbaae3 --- /dev/null +++ b/armdebug/Debugger/undef_handler.S @@ -0,0 +1,144 @@ + +/* Copyright (C) 2007-2010 the NxOS developers + * + * Module Developed by: TC Wan + * + * See AUTHORS for a full list of the developers. + * + * Redistribution of this file is permitted under + * the terms of the GNU Public License (GPL) version 2. + */ +#define __ASSEMBLY__ +#include "debug_stub.h" +#include "debug_internals.h" + + +.text +.code 32 +.align 0 + + .extern dbg__thumb_bkpt_handler + .extern dbg__arm_bkpt_handler + .extern default_undef_handler + +/* Remote GDB Debugger relies on BKPT instruction being trapped here + * In ARMv4t, it is an Illegal (Undefined) Instruction. + * On triggering, lr (R14) contains the previous mode's pc (R15). + * Based on example in Hohl, "ARM Assembly Language: Fundamentals and Techniques" + * Chapter 11, Example 11.1. + */ + /** undef_handler + * We assume that the DEBUG stack holds only one stack frame and we will overwrite it. + * On entry, LR_undef points to one instruction past the UNDEF instruction. + * + * For the purpose of Debugging, the stack frame should present the PC (R15) as the address + * of the instruction that triggered the Breakpoint. Hence we need to adjust R15 + * to point to the address of the UNDEF instruction. This is what the JTAG debugger + * does. + * + * We will also store UNDEF LR (next instruction pointer) and UNDEF SPSR to the stack. + * + * For the handler, once the user registers have been stored in the DEBUG stack, the + * registers will be used as follows: + * + * R0: UNDEF LR, then UNDEF instruction address, finally UNDEF instruction word / BKPT index + * R1: SPSR + * R2: Mode + * R3: Debug Stack Pointer (for Banked R13-R14 update) + */ + dbg_interwork undef_handler + ldr sp, =__debugger_stack__ + stmfd sp, {r0-r15}^ /* Save workspace, previous mode's pc via 'S' flag, R13-R15: placeholders */ + mov r3, sp /* Use R3 to write Banked R13-R14, and actual PC of UNDEF instruction */ + sub sp, sp, #(4*16) /* Need to manually update SP(undef) */ + + mov r0, lr /* Keep Next Instruction address after UNDEF instruction in R0 */ + mrs r1, spsr /* Copy SPSR to r1 */ + stmfd sp!, {r0,r1} /* Save User's Next Instr Pointer (in UNDEF LR) and previous mode's CPSR to stack */ + + tst r1, #CPSR_THUMB /* Check for Thumb Mode */ + subne r0, r0, #2 /* Is Thumb instruction, adjust PC for UNDEF instruction address */ + subeq r0, r0, #4 /* Is ARM instruction, adjust PC for UNDEF instruction address */ + str r0, [r3, #-4]! /* Save PC to stack (R15 slot) */ + + and r2, r1, #CPSR_MODE /* Get previous mode */ + teq r2, #MODE_USR + beq _skip_banked_registers /* Can't switch back if we're in User mode! */ + +_store_prev_mode_banked_regs: + /* FIXME: We don't handle FIQ properly! */ + + orr r2, #(CPSR_FIQ | CPSR_IRQ) /* Disable Interrupts */ + msr cpsr_c, r2 /* Switch to previous mode */ + stmfd r3!, {sp, lr} /* Store Previous Mode's LR (R14), SP (R13) via R3 */ + msr cpsr_c, #(MODE_UND | CPSR_FIQ | CPSR_IRQ) /* Revert to Undef Mode */ + +_skip_banked_registers: + tst r1, #CPSR_THUMB /* Check for Thumb Mode */ + beq _is_arm /* Clear, so it's ARM mode */ +_is_thumb: + ldrh r0, [r0] /* load UNDEF instruction into r0 */ + ldr r1, =BKPT16_ENUM_MASK /* Thumb BKPT enum mask */ + bic r2, r0, r1 /* leave only opcode */ + ldr r1, =BKPT16_INSTR /* check for Thumb Breakpoint Instruction */ + teq r2, r1 + bne default_undef_handler + ldr r1, =BKPT16_ENUM_MASK /* get Thumb BKPT Enum Mask */ + ldr r2, =dbg__thumb_bkpt_handler /* handle BKPT, BKPT index in r0 */ + b _exit_undef_handler +_is_arm: + ldr r0, [r0] /* load UNDEF instruction into r0 */ + ldr r1, =BKPT32_ENUM_MASK /* ARM BKPT enum mask */ + bic r2, r0, r1 /* leave only opcode */ + ldr r1, =BKPT32_INSTR /* check for ARM Breakpoint Instruction */ + teq r2, r1 + bne default_undef_handler + ldr r1, =BKPT32_ENUM_MASK /* get ARM BKPT Enum Mask */ + ldr r2, =dbg__arm_bkpt_handler /* handle BKPT, BKPT index in r0 */ +_exit_undef_handler: + and r0, r1, r0 /* Keep index value */ + msr cpsr_c, #(MODE_ABT | CPSR_FIQ | CPSR_IRQ) /* Switch to Abort Mode, Disable Interrupts */ + ldr sp, =__abort_stack__ /* Reinitialize stack pointer each time a Breakpoint happens */ + bic sp, sp, #7 + mov pc, r2 /* Invoke Debugger */ + +/** resume_execution + * This routine is called by the Debugger prior to returning control to + * the executing program. + * It updates the SPSR_UNDEF with the Debug Stack value, and + * restores all registers R0-R14 to the previously active mode. + * Then, it uses the Next Instruction Address Pointer to return + * execution control to the previously executing program. + */ +/* On Entry, SP(undef) points to the Next Instruction Address. + * If the instruction which triggered the Breakpoint need to be + * reexecuted, it should be placed in the Next Instruction Address slot + * by ABORT mode before coming here + */ + dbg_interwork resume_execution + ldr lr, =__debugger_stack_bottom__ /* Use LR(undef) for Debug Stack Access */ + add r1, lr, #(DBGSTACK_USERSP_INDEX*4) /* Use R1 for Previous Mode SP (R13) and LR (R14) access */ + ldr r0, [lr, #(DBGSTACK_USERCPSR_INDEX*4)]! /* LR updated, Retrieve SPSR into R0 */ + msr spsr, r0 /* Update SPSR for return to program being debugged */ + and r0, r0, #CPSR_MODE /* Get previous mode */ + teq r0, #MODE_USR + bne _restore_prev_mode_banked_regs /* Can't switch back if we're in User mode! */ + + /* Previous mode was User Mode */ + ldmed lr, {r0-r14}^ /* We use LDMED since LR is pointing to USERCPSR not R0 */ + b _really_resume_execution + +_restore_prev_mode_banked_regs: + /* FIXME: We don't handle FIQ properly! */ + orr r0, #(CPSR_FIQ | CPSR_IRQ) /* Disable Interrupts */ + msr cpsr_c, r0 /* Switch to previous mode */ + ldmfd r1, {sp, lr} /* Restore Previous Mode's LR (R14), SP (R13) via R1 */ + msr cpsr_c, #(MODE_UND | CPSR_FIQ | CPSR_IRQ) /* Revert to Undef Mode */ + ldmed lr, {r0-r12} /* We use LDMED since LR is pointing to USERCPSR not R0 */ + +_really_resume_execution: + ldmfd sp, {pc}^ /* Exit to Previous Mode using Next Instruction Address */ + + + + diff --git a/armdebug/Doxyfile b/armdebug/Doxyfile new file mode 100644 index 0000000..6266354 --- /dev/null +++ b/armdebug/Doxyfile @@ -0,0 +1,243 @@ +# Doxyfile 1.5.3-20071008 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = "NxOS Debugger" +PROJECT_NUMBER = +OUTPUT_DIRECTORY = ../doc/debug +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +QT_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +#DETAILS_AT_TOP = NO +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 8 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = YES +OPTIMIZE_OUTPUT_JAVA = NO +BUILTIN_STL_SUPPORT = NO +CPP_CLI_SUPPORT = NO +SIP_SUPPORT = NO +DISTRIBUTE_GROUP_DOC = NO +SUBGROUPING = YES +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = NO +EXTRACT_PRIVATE = YES +EXTRACT_STATIC = YES +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +EXTRACT_ANON_NSPACES = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = YES +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_DIRECTORIES = NO +FILE_VERSION_FILTER = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = . +INPUT_ENCODING = UTF-8 +FILE_PATTERNS = *.h +RECURSIVE = YES +EXCLUDE = at91sam7s256.h +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXCLUDE_SYMBOLS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = * +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = NO +REFERENCES_LINK_SOURCE = YES +USE_HTAGS = NO +VERBATIM_HEADERS = NO +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +HTML_DYNAMIC_SECTIONS = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 1 +GENERATE_TREEVIEW = YES +TREEVIEW_WIDTH = 280 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +#MACRO_EXPANSION = NO +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = NO +MSCGEN_PATH = +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +CALLER_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +DOT_GRAPH_MAX_NODES = 50 +MAX_DOT_GRAPH_DEPTH = 1000 +DOT_TRANSPARENT = YES +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO diff --git a/armdebug/GNU-GPLv2.txt b/armdebug/GNU-GPLv2.txt new file mode 100644 index 0000000..5b6e7c6 --- /dev/null +++ b/armdebug/GNU-GPLv2.txt @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/armdebug/Host/README b/armdebug/Host/README new file mode 100644 index 0000000..1b6537e --- /dev/null +++ b/armdebug/Host/README @@ -0,0 +1,26 @@ +The nxt-gdb-server.py script is initially developed by Nicolas Schodet. + +It depends on the following libraries: + - nxt-python v2.2.x http://code.google.com/p/nxt-python/ + +Additional Dependencies For Windows and MacOSX: + - Fantom Drivers from LEGO + +Additional Dependencies For Linux: + - pyusb v0.4x http://pyusb.wiki.sourceforge.net + - libusb v0.1.x http://libusb.org/ + + Currently, it does not work with libusb v1.x; on Mac OSX, it causes segfaults. + + Installation + ============ + + There is no specific installation requirements (at this moment). Just run the python script + in a terminal window. + + Usage + ===== + + 1. Connect the USB cable from the PC Host to the NXT + 2. start nxt-gdb-server.py + 3. start arm-none-eabi-gdb, configured as remote for port 2828 (default) diff --git a/armdebug/Host/gdb-commands.txt b/armdebug/Host/gdb-commands.txt new file mode 100644 index 0000000..3135a1e --- /dev/null +++ b/armdebug/Host/gdb-commands.txt @@ -0,0 +1,43 @@ +# This file contains hand coded GDB commands for testing the GDB Server <-> NXT interface + +# Display all Registers +$g#67 + +# Display R0 +$p0#A0 + +# Display R1 +$p1#A1 + +# Display PC +$pF#B6 + +# Display FPSCR (dummy) +$p18#D9 + +# Display User CPSR +$p19#DA + +# Query Status +$?#3F + +# Query Thread +$qC#B4 + +# Set R1 to 0xAA +$P1=000000AA#60 + +# Read 16 bytes of Memory from 0x00201d74 (padding bytes after debug_mode + 4 bytes of debug_InUSBBuf) +$m00201D74,0010#FC + +# Write 2 bytes of memory to 0x00201d74 (padding bytes after debug_mode) +$M00201D74,0002:AA55#03 + +# Write 2 bytes of memory to 0x00201d74 (padding bytes after debug_mode) +$M00201D74,0002:9966#F5 + +# GDB Read Instruction at Address (PC) ++$m1001de,4#58 + +# Continue Execution +$c#63 diff --git a/armdebug/Host/nxt-gdb-server.py b/armdebug/Host/nxt-gdb-server.py new file mode 100755 index 0000000..03a95d3 --- /dev/null +++ b/armdebug/Host/nxt-gdb-server.py @@ -0,0 +1,254 @@ +#!/usr/bin/env python +# +# Copyright (C) 2011 the NxOS developers +# +# Module Developed by: Nicolas Schodet +# TC Wan +# +# See AUTHORS for a full list of the developers. +# +# See COPYING for redistribution license +# +# Exchange GDB messages with the NXT brick. +# +# Every message is encapsulated with the debug command and message length. +# This can be used by the firmware to make the distinction between debug +# messages and regular messages. +# +import nxt.locator +import socket +import optparse +import select +try: + import pyfantom +except ImportError: + import usb +import struct +import sys + +CTRLC = chr(3) +NAKCHAR = '-' +ACKCHAR = '+' +STATUS_QUERY = "$?#3F" +DEFAULT_PORT = 2828 +SELECT_TIMEOUT = 0.1 +DEBUG = False +DEBUG2 = False +NXT_RECV_ERR = -1 + +# Libusb 0.12.x blocks on USB reads +LIBUSB_RECEIVE_BLOCKING = True + +class NXTGDBServer: + + # Socket read size. + recv_size = 1024 + + # Maximum message size. + pack_size = 61 + + # Debug command header, no reply. + debug_command = 0x8d + + def __init__ (self, port, nowait): + """Initialise server.""" + self.nowait = nowait + self.port = port + self.in_buf = '' + self.brick = None + + def pack (self, data, segment_no): + """Return packed data to send to NXT.""" + # Insert command and length. + assert len (data) <= self.pack_size + return struct.pack ('BBB', self.debug_command, segment_no, len (data)) + data + + def unpack (self, data): + """Return unpacked data from NXT.""" + # May be improved, for now, check command and announced length. + if len (data) == 0: + return '', 0 # No message, exit + if len (data) < 3: + return '', NXT_RECV_ERR + header, body = data[0:3], data[3:] + command, segment_no, length = struct.unpack ('BBB', header) + if command != self.debug_command or length != len (body): + return '', NXT_RECV_ERR + return body, segment_no + + def segment (self, data): + """Split messages in GDB commands and make segments with each command.""" + segs = [ ] + self.in_buf += data + + # Find ACK '+' + end = self.in_buf.find (ACKCHAR) + while end == 0: + self.in_buf = self.in_buf[end+1:] # Strip out any leading ACKCHAR + if DEBUG2: + print "stripped ACK, remain: ", self.in_buf + end = self.in_buf.find (ACKCHAR) + + # Find NAK '-' + end = self.in_buf.find (NAKCHAR) + if end == 0: + msg, self.in_buf = self.in_buf[0:end+1], self.in_buf[end+1:] + segs.append (self.pack (msg, 0)) + end = self.in_buf.find (NAKCHAR) + + # Find Ctrl-C (assumed to be by itself and not following a normal command) + end = self.in_buf.find (CTRLC) + if end >= 0: + msg, self.in_buf = self.in_buf[0:end+1], self.in_buf[end+1:] + assert len (msg) <= self.pack_size, "Ctrl-C Command Packet too long!" + segs.append (self.pack (msg, 0)) + end = self.in_buf.find (CTRLC) + + end = self.in_buf.find ('#') + # Is # found and enough place for the checkum? + while end >= 0 and end < len (self.in_buf) - 2: + msg, self.in_buf = self.in_buf[0:end + 3], self.in_buf[end + 3:] + i = 0 + gdbprefix = msg[i] + while gdbprefix in [ACKCHAR]: + # Ignore any '+' + i += 1 + gdbprefix = msg[i] + if DEBUG2: + print "Checking '", gdbprefix, "'" + assert gdbprefix == '$', "not a GDB command" + # Make segments. + seg_no = 0 + while msg: + seg, msg = msg[0:self.pack_size], msg[self.pack_size:] + seg_no += 1 + if not msg: # Last segment. + seg_no = 0 + segs.append (self.pack (seg, seg_no)) + # Look for next one. + end = self.in_buf.find ('#') + return segs + + def reassemble (self, sock): + msg = '' + prev_segno = 0 + segno = NXT_RECV_ERR # force initial pass through while loop + while segno != 0: + try: + s, segno = self.unpack (sock.recv ()) + if len (s) == 0: + if segno == 0 and prev_segno == 0: + return '' # No message pending + else: + segno = NXT_RECV_ERR # Keep waiting for segments + # Ignore error packets + if segno >= 0: + # Check segno, if non-zero it must be monotonically increasing from 1, otherwise 0 + if segno > 0: + assert segno == prev_segno + 1, "segno = %s, prev_segno = %s" % (segno, prev_segno) + prev_segno = segno + msg += s + except IOError as e: + # Some pyusb are buggy, ignore some "errors". + if e.args != ('No error', ): + raise e + return msg + + def run (self): + """Endless run loop.""" + # Create the listening socket. + s = socket.socket (socket.AF_INET, socket.SOCK_STREAM) + s.setsockopt (socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + s.bind (('', self.port)) + s.listen (1) + while True: + # We should open the NXT connection first, otherwise Python startup delay + # may cause GDB to misbehave + if not self.nowait: + dummy = raw_input('Waiting...Press when NXT GDB Stub is ready. ') + # Open connection to the NXT brick. + self.brick = nxt.locator.find_one_brick () + self.brick.sock.debug = DEBUG + # Wait for a connection. + print "Waiting for GDB connection on port %s..." % self.port + client, addr = s.accept () + print "Client from", addr + # Work loop, wait for a message from client socket or NXT brick. + while client is not None: + data = '' + # Wait for a message from client or timeout. + rlist, wlist, xlist = select.select ([ client ], [ ], [ ], + SELECT_TIMEOUT) + for c in rlist: + assert c is client + # Data from client, read it and forward it to NXT brick. + data = client.recv (self.recv_size) + data = data.strip() + if len (data) > 0: + #if len (data) == 1 and data.find(CTRLC) >= 0: + # print "CTRL-C Received!" + # data = STATUS_QUERY + if DEBUG: + if data[0] == CTRLC: + print "[GDB->NXT] " + else: + print "[GDB->NXT] %s" % data + segments = self.segment (data) + data = '' + for seg in segments: + try: + self.brick.sock.send (seg) + except IOError as e: + # Some pyusb are buggy, ignore some "errors". + if e.args != ('No error', ): + raise e + if segments != [] and LIBUSB_RECEIVE_BLOCKING: + if DEBUG2: + print "Accessing Blocking sock.recv()" + data = self.reassemble (self.brick.sock) + else: + client.close () + client = None + if not LIBUSB_RECEIVE_BLOCKING: + if DEBUG2: + print "Accessing Non-Blocking sock.recv()" + data = self.reassemble (self.brick.sock) + + # Is there something from NXT brick? + if data: + if DEBUG: + print "[NXT->GDB] %s" % data + if client: + client.send (data) + data = '' + self.brick.sock.close() + print "Connection closed." + if self.nowait: + break + +if __name__ == '__main__': + # Read options from command line. + parser = optparse.OptionParser (description = """ + Gateway between the GNU debugger and a NXT brick. + """) + parser.add_option ('-p', '--port', type = 'int', default = DEFAULT_PORT, + help = "server listening port (default: %default)", metavar = "PORT") + parser.add_option ('-v', '--verbose', action='store_true', dest='verbose', default = False, + help = "verbose mode (default: %default)") + parser.add_option ('-n', '--nowait', action='store_true', dest='nowait', default = False, + help = "Don't wait for NXT GDB Stub Setup before connecting (default: %default)") + (options, args) = parser.parse_args () + if args: + parser.error ("Too many arguments") + # Run. + try: + DEBUG = options.verbose + if DEBUG: + print "Debug Mode Enabled!" + server = NXTGDBServer (options.port, options.nowait) + server.run () + except KeyboardInterrupt: + print "\n\nException caught. Bye!" + if server.brick is not None: + server.brick.sock.close() + sys.exit() diff --git a/armdebug/LEGO_Open_Source_License.doc b/armdebug/LEGO_Open_Source_License.doc new file mode 100644 index 0000000..94b65e6 Binary files /dev/null and b/armdebug/LEGO_Open_Source_License.doc differ diff --git a/armdebug/README b/armdebug/README new file mode 100644 index 0000000..4660b1e --- /dev/null +++ b/armdebug/README @@ -0,0 +1,16 @@ +Introduction +============ +armdebug is an ARM Assembly Language Instruction debugger for the NXT. +It is intended for embedding in the NXT firmware (e.g. NXT Improved Firmware), +as well as for use with NxOS. + +Contents +======== +The various folders contents are as follows: +Debugger: GDB client driver for NXT (need to be embedded in firmware code) +Host: GDB Server for PC Host + +LICENSES +======== +The armdebug code is dual-licensed. Please see COPYING for more details. +Other projects included in this repository have their respective licenses. diff --git a/armdebug/SConscript b/armdebug/SConscript new file mode 100644 index 0000000..c495847 --- /dev/null +++ b/armdebug/SConscript @@ -0,0 +1,13 @@ +# This scons build script is used by NxOS + +from glob import glob + +Import('env') + + +for source in glob('Debugger/*.[cS]'): + obj = env.Object(source.split('.')[0], source) + env.Append(NXOS_DEBUG=obj) + +if env['WITH_DOXYGEN']: + env.Doxygen('Doxyfile') diff --git a/armdebug/SConstruct b/armdebug/SConstruct new file mode 100644 index 0000000..fa88d7a --- /dev/null +++ b/armdebug/SConstruct @@ -0,0 +1,182 @@ +# -*- mode: python -*- +############################################################### +# This scons build script is used to check the armdebug project +# code for syntax errors. It does not build working executable +# code since it links to external routines. +############################################################### + +import os +import os.path +import new +from glob import glob + +############################################################### +# Utility functions. +############################################################### + +# Similar to env.WhereIs, but always searches os.environ. +def find_on_path(filename): + paths = os.environ.get('PATH') + if not paths: + return None + for p in paths.split(':'): + path = os.path.abspath(os.path.join(p, filename)) + if os.path.isfile(path): + return p + return None + +# Run the given gcc binary, and parses its output to work out the gcc +# version. +def determine_gcc_version(gcc_binary): + stdout = os.popen('%s --version' % gcc_binary) + gcc_output = stdout.read().split() + stdout.close() + grab_next = False + for token in gcc_output: + if grab_next: + return token + elif token[-1] == ')': + grab_next = True + return None + +# Check that a given cross-compiler tool exists. If it does, the path is +# added to the build environment, and the given environment variable is +# set to the tool name. +# +# This is used to check for the presence of a working cross-compiler +# toolchain, and to properly set up the environment to do it. See below +# in the configuration section for details. +def CheckTool(context, envname, toolname=None, hostprefix=None): + toolname = toolname or envname.lower() + if hostprefix is None: + hostprefix = '%s-' % context.env['CROSS_COMPILE_HOST'] + toolname = '%s%s' % (hostprefix, toolname) + context.Message("Checking for %s..." % toolname) + toolpath = find_on_path(toolname) + if not toolpath: + context.Result('not found') + return False + else: + context.Result('ok') + context.env[envname] = toolname + context.env.AppendENVPath('PATH', toolpath) + return True + +# Find the correct variant and version of libgcc.a in the cross-compiler +# toolchain. +def CheckLibGcc(context, gccname): + context.Message("Locating a cross-compiled libgcc...") + toolpath = find_on_path(gccname) + if not toolpath: + context.Result("%s not found" % toolname) + return False + gcc_version = determine_gcc_version(gccname) + if not gcc_version: + context.Result("Could not determine gcc version") + return False + gcc_install_dir = os.path.split(os.path.normpath(toolpath))[0] + for libdir in ['interwork', 'thumb', '']: + libgcc_path = os.path.join(gcc_install_dir, 'lib', 'gcc', + context.env['CROSS_COMPILE_HOST'], + gcc_version, libdir, 'libgcc.a') + if os.path.isfile(libgcc_path): + break + if not os.path.isfile(libgcc_path): + context.Result("libgcc.a not found") + return False + context.Result("ok - " + libgcc_path) + context.env.Append(LIBGCC=libgcc_path) + return True + +def CheckDoxygen(context): + context.Message("Looking for Doxygen...") + doxypath = find_on_path('doxygen') + if doxypath: + context.Result("ok") + context.env.AppendENVPath('PATH', doxypath) + context.env['WITH_DOXYGEN'] = True + else: + context.Result("not found") + context.env['WITH_DOXYGEN'] = False + + + +############################################################### +# Options that can be provided on the commandline +############################################################### + +opts = Variables('scons.options', ARGUMENTS) + +opts.Add(PathVariable('gccprefix', + 'Prefix of the cross-gcc to use (by default arm-none-eabi)', + 'arm-none-eabi', PathVariable.PathAccept)) + +Help(''' +Type: 'scons' to build object files. + + - To use another cross-gcc than arm-none-eabi-gcc: + scons gccprefix=arm-softfloat-eabi + +Options are saved persistent in the file 'scons.options'. That means +after you have called e.g. 'scons gccprefix=arm-softfloat-eabi' it's enough +to call only 'scons' to build both using the new gcc version again. +''') + +############################################################### +# Construct and configure a cross-compiler environment +############################################################### +env = Environment(options = opts, + tools = ['gcc', 'as', 'gnulink', 'ar'], + toolpath = ['scons_tools'], + LIBGCC = [], CPPPATH = '#', + WITH_DOXYGEN = False) +opts.Update(env) +opts.Save('scons.options', env) + +if not env.GetOption('clean'): + conf = Configure(env, custom_tests = {'CheckTool': CheckTool, + 'CheckLibGcc': CheckLibGcc, + 'CheckDoxygen': CheckDoxygen}) + conf.env['CROSS_COMPILE_HOST'] = env['gccprefix'] + if not (conf.CheckTool('CC', 'gcc') and conf.CheckTool('AR') and + conf.CheckTool('OBJCOPY') and conf.CheckTool('LINK', 'ld') and + conf.CheckLibGcc(conf.env['CC'])): + print "Missing or incomplete arm-elf toolchain, cannot continue!" + Exit(1) + env = conf.Finish() + +mycflags = ['-mcpu=arm7tdmi', '-Os', '-Wextra', '-Wall', '-Werror', + '-Wno-div-by-zero', '-Wfloat-equal', '-Wshadow', + '-Wpointer-arith', '-Wbad-function-cast', + '-Wmissing-prototypes', '-ffreestanding', + '-fsigned-char', '-ffunction-sections', '-std=gnu99', + '-fdata-sections', '-fomit-frame-pointer', '-msoft-float'] +myasflags = ['-Wall', '-Werror', '-Os']; +if str(env['LIBGCC']).find('interwork') != -1: + mycflags.append('-mthumb-interwork') + myasflags.append('-Wa,-mcpu=arm7tdmi,-mfpu=softfpa,-mthumb-interwork') +elif str(env['LIBGCC']).find('thumb') != -1: + mycflags.append('-mthumb') + myasflags.append('-Wa,-mcpu=arm7tdmi,-mfpu=softfpa,-mthumb') +else: + myasflags.append('-Wa,-mcpu=arm7tdmi,-mfpu=softfpa') +mycflags.append('-g') +mycflags.append('-ggdb') +# Big Endian Output (disabled by default) +#mycflags.append('-D__BIG_ENDIAN__') +# Test build for NxOS (Comment out for NXT Firmware) +mycflags.append('-D__NXOS__') + +myasflags.append('-g') +myasflags.append('-ggdb') +# Big Endian Output (disabled by default) +#mycflags.append('-D__BIG_ENDIAN__') +# Test build for NxOS (Comment out for NXT Firmware) +myasflags.append('-D__NXOS__') + +env.Replace(CCFLAGS = mycflags, ASFLAGS = myasflags ) + +# Build the baseplate, and all selected application kernels. + +numProcs = os.sysconf('SC_NPROCESSORS_ONLN') +SConscript(['SConscript'], 'numProcs env CheckTool') diff --git a/include/AT91SAM7S256.h b/include/AT91SAM7S256.h new file mode 100644 index 0000000..168e5ac --- /dev/null +++ b/include/AT91SAM7S256.h @@ -0,0 +1,1920 @@ +// ---------------------------------------------------------------------------- +// ATMEL Microcontroller Software Support - ROUSSET - +// ---------------------------------------------------------------------------- +// DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE +// DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// ---------------------------------------------------------------------------- +// File Name : AT91SAM7S256.h +// Object : AT91SAM7S256 definitions +// Generated : AT91 SW Application Group 03/08/2005 (15:46:13) +// +// CVS Reference : /AT91SAM7S256.pl/1.8/Wed Feb 9 15:29:26 2005// +// CVS Reference : /SYS_SAM7S.pl/1.2/Tue Feb 1 17:01:52 2005// +// CVS Reference : /MC_SAM7S.pl/1.2/Tue Feb 1 17:01:00 2005// +// CVS Reference : /PMC_SAM7S_USB.pl/1.4/Tue Feb 8 13:58:22 2005// +// CVS Reference : /RSTC_SAM7S.pl/1.1/Tue Feb 1 16:16:35 2005// +// CVS Reference : /RTTC_6081A.pl/1.2/Tue Nov 9 14:43:58 2004// +// CVS Reference : /PITC_6079A.pl/1.2/Tue Nov 9 14:43:56 2004// +// CVS Reference : /WDTC_6080A.pl/1.3/Tue Nov 9 14:44:00 2004// +// CVS Reference : /VREG_6085B.pl/1.1/Tue Feb 1 16:05:48 2005// +// CVS Reference : /UDP_6083C.pl/1.1/Mon Jan 31 13:01:46 2005// +// CVS Reference : /AIC_6075A.pl/1.1/Fri Jun 28 10:36:48 2002// +// CVS Reference : /PIO_6057A.pl/1.2/Thu Feb 3 10:18:28 2005// +// CVS Reference : /DBGU_6059D.pl/1.1/Mon Jan 31 13:15:32 2005// +// CVS Reference : /US_6089C.pl/1.1/Mon Jul 12 18:23:26 2004// +// CVS Reference : /SPI_6088D.pl/1.2/Mon Feb 14 07:24:18 2005// +// CVS Reference : /SSC_6078A.pl/1.1/Tue Jul 13 07:45:40 2004// +// CVS Reference : /TC_6082A.pl/1.6/Fri Feb 18 13:53:30 2005// +// CVS Reference : /TWI_6061A.pl/1.1/Tue Jul 13 07:38:06 2004// +// CVS Reference : /PDC_6074C.pl/1.2/Thu Feb 3 08:48:54 2005// +// CVS Reference : /ADC_6051C.pl/1.1/Fri Oct 17 09:12:38 2003// +// CVS Reference : /PWM_6044D.pl/1.1/Tue Apr 27 14:53:52 2004// +// ---------------------------------------------------------------------------- + +#ifndef AT91SAM7S256_H +#define AT91SAM7S256_H + +typedef volatile unsigned int AT91_REG;// Hardware register definition + +// ***************************************************************************** +// SOFTWARE API DEFINITION FOR System Peripherals +// ***************************************************************************** +typedef struct _AT91S_SYS { + AT91_REG AIC_SMR[32]; // Source Mode Register + AT91_REG AIC_SVR[32]; // Source Vector Register + AT91_REG AIC_IVR; // IRQ Vector Register + AT91_REG AIC_FVR; // FIQ Vector Register + AT91_REG AIC_ISR; // Interrupt Status Register + AT91_REG AIC_IPR; // Interrupt Pending Register + AT91_REG AIC_IMR; // Interrupt Mask Register + AT91_REG AIC_CISR; // Core Interrupt Status Register + AT91_REG Reserved0[2]; // + AT91_REG AIC_IECR; // Interrupt Enable Command Register + AT91_REG AIC_IDCR; // Interrupt Disable Command Register + AT91_REG AIC_ICCR; // Interrupt Clear Command Register + AT91_REG AIC_ISCR; // Interrupt Set Command Register + AT91_REG AIC_EOICR; // End of Interrupt Command Register + AT91_REG AIC_SPU; // Spurious Vector Register + AT91_REG AIC_DCR; // Debug Control Register (Protect) + AT91_REG Reserved1[1]; // + AT91_REG AIC_FFER; // Fast Forcing Enable Register + AT91_REG AIC_FFDR; // Fast Forcing Disable Register + AT91_REG AIC_FFSR; // Fast Forcing Status Register + AT91_REG Reserved2[45]; // + AT91_REG DBGU_CR; // Control Register + AT91_REG DBGU_MR; // Mode Register + AT91_REG DBGU_IER; // Interrupt Enable Register + AT91_REG DBGU_IDR; // Interrupt Disable Register + AT91_REG DBGU_IMR; // Interrupt Mask Register + AT91_REG DBGU_CSR; // Channel Status Register + AT91_REG DBGU_RHR; // Receiver Holding Register + AT91_REG DBGU_THR; // Transmitter Holding Register + AT91_REG DBGU_BRGR; // Baud Rate Generator Register + AT91_REG Reserved3[7]; // + AT91_REG DBGU_CIDR; // Chip ID Register + AT91_REG DBGU_EXID; // Chip ID Extension Register + AT91_REG DBGU_FNTR; // Force NTRST Register + AT91_REG Reserved4[45]; // + AT91_REG DBGU_RPR; // Receive Pointer Register + AT91_REG DBGU_RCR; // Receive Counter Register + AT91_REG DBGU_TPR; // Transmit Pointer Register + AT91_REG DBGU_TCR; // Transmit Counter Register + AT91_REG DBGU_RNPR; // Receive Next Pointer Register + AT91_REG DBGU_RNCR; // Receive Next Counter Register + AT91_REG DBGU_TNPR; // Transmit Next Pointer Register + AT91_REG DBGU_TNCR; // Transmit Next Counter Register + AT91_REG DBGU_PTCR; // PDC Transfer Control Register + AT91_REG DBGU_PTSR; // PDC Transfer Status Register + AT91_REG Reserved5[54]; // + AT91_REG PIOA_PER; // PIO Enable Register + AT91_REG PIOA_PDR; // PIO Disable Register + AT91_REG PIOA_PSR; // PIO Status Register + AT91_REG Reserved6[1]; // + AT91_REG PIOA_OER; // Output Enable Register + AT91_REG PIOA_ODR; // Output Disable Registerr + AT91_REG PIOA_OSR; // Output Status Register + AT91_REG Reserved7[1]; // + AT91_REG PIOA_IFER; // Input Filter Enable Register + AT91_REG PIOA_IFDR; // Input Filter Disable Register + AT91_REG PIOA_IFSR; // Input Filter Status Register + AT91_REG Reserved8[1]; // + AT91_REG PIOA_SODR; // Set Output Data Register + AT91_REG PIOA_CODR; // Clear Output Data Register + AT91_REG PIOA_ODSR; // Output Data Status Register + AT91_REG PIOA_PDSR; // Pin Data Status Register + AT91_REG PIOA_IER; // Interrupt Enable Register + AT91_REG PIOA_IDR; // Interrupt Disable Register + AT91_REG PIOA_IMR; // Interrupt Mask Register + AT91_REG PIOA_ISR; // Interrupt Status Register + AT91_REG PIOA_MDER; // Multi-driver Enable Register + AT91_REG PIOA_MDDR; // Multi-driver Disable Register + AT91_REG PIOA_MDSR; // Multi-driver Status Register + AT91_REG Reserved9[1]; // + AT91_REG PIOA_PPUDR; // Pull-up Disable Register + AT91_REG PIOA_PPUER; // Pull-up Enable Register + AT91_REG PIOA_PPUSR; // Pull-up Status Register + AT91_REG Reserved10[1]; // + AT91_REG PIOA_ASR; // Select A Register + AT91_REG PIOA_BSR; // Select B Register + AT91_REG PIOA_ABSR; // AB Select Status Register + AT91_REG Reserved11[9]; // + AT91_REG PIOA_OWER; // Output Write Enable Register + AT91_REG PIOA_OWDR; // Output Write Disable Register + AT91_REG PIOA_OWSR; // Output Write Status Register + AT91_REG Reserved12[469]; // + AT91_REG PMC_SCER; // System Clock Enable Register + AT91_REG PMC_SCDR; // System Clock Disable Register + AT91_REG PMC_SCSR; // System Clock Status Register + AT91_REG Reserved13[1]; // + AT91_REG PMC_PCER; // Peripheral Clock Enable Register + AT91_REG PMC_PCDR; // Peripheral Clock Disable Register + AT91_REG PMC_PCSR; // Peripheral Clock Status Register + AT91_REG Reserved14[1]; // + AT91_REG PMC_MOR; // Main Oscillator Register + AT91_REG PMC_MCFR; // Main Clock Frequency Register + AT91_REG Reserved15[1]; // + AT91_REG PMC_PLLR; // PLL Register + AT91_REG PMC_MCKR; // Master Clock Register + AT91_REG Reserved16[3]; // + AT91_REG PMC_PCKR[3]; // Programmable Clock Register + AT91_REG Reserved17[5]; // + AT91_REG PMC_IER; // Interrupt Enable Register + AT91_REG PMC_IDR; // Interrupt Disable Register + AT91_REG PMC_SR; // Status Register + AT91_REG PMC_IMR; // Interrupt Mask Register + AT91_REG Reserved18[36]; // + AT91_REG RSTC_RCR; // Reset Control Register + AT91_REG RSTC_RSR; // Reset Status Register + AT91_REG RSTC_RMR; // Reset Mode Register + AT91_REG Reserved19[5]; // + AT91_REG RTTC_RTMR; // Real-time Mode Register + AT91_REG RTTC_RTAR; // Real-time Alarm Register + AT91_REG RTTC_RTVR; // Real-time Value Register + AT91_REG RTTC_RTSR; // Real-time Status Register + AT91_REG PITC_PIMR; // Period Interval Mode Register + AT91_REG PITC_PISR; // Period Interval Status Register + AT91_REG PITC_PIVR; // Period Interval Value Register + AT91_REG PITC_PIIR; // Period Interval Image Register + AT91_REG WDTC_WDCR; // Watchdog Control Register + AT91_REG WDTC_WDMR; // Watchdog Mode Register + AT91_REG WDTC_WDSR; // Watchdog Status Register + AT91_REG Reserved20[5]; // + AT91_REG VREG_MR; // Voltage Regulator Mode Register +} AT91S_SYS, *AT91PS_SYS; + + +// ***************************************************************************** +// SOFTWARE API DEFINITION FOR Advanced Interrupt Controller +// ***************************************************************************** +typedef struct _AT91S_AIC { + AT91_REG AIC_SMR[32]; // Source Mode Register + AT91_REG AIC_SVR[32]; // Source Vector Register + AT91_REG AIC_IVR; // IRQ Vector Register + AT91_REG AIC_FVR; // FIQ Vector Register + AT91_REG AIC_ISR; // Interrupt Status Register + AT91_REG AIC_IPR; // Interrupt Pending Register + AT91_REG AIC_IMR; // Interrupt Mask Register + AT91_REG AIC_CISR; // Core Interrupt Status Register + AT91_REG Reserved0[2]; // + AT91_REG AIC_IECR; // Interrupt Enable Command Register + AT91_REG AIC_IDCR; // Interrupt Disable Command Register + AT91_REG AIC_ICCR; // Interrupt Clear Command Register + AT91_REG AIC_ISCR; // Interrupt Set Command Register + AT91_REG AIC_EOICR; // End of Interrupt Command Register + AT91_REG AIC_SPU; // Spurious Vector Register + AT91_REG AIC_DCR; // Debug Control Register (Protect) + AT91_REG Reserved1[1]; // + AT91_REG AIC_FFER; // Fast Forcing Enable Register + AT91_REG AIC_FFDR; // Fast Forcing Disable Register + AT91_REG AIC_FFSR; // Fast Forcing Status Register +} AT91S_AIC, *AT91PS_AIC; + +// -------- AIC_SMR : (AIC Offset: 0x0) Control Register -------- +#define AT91C_AIC_PRIOR ((unsigned int) 0x7 << 0) // (AIC) Priority Level +#define AT91C_AIC_PRIOR_LOWEST ((unsigned int) 0x0) // (AIC) Lowest priority level +#define AT91C_AIC_PRIOR_HIGHEST ((unsigned int) 0x7) // (AIC) Highest priority level +#define AT91C_AIC_SRCTYPE ((unsigned int) 0x3 << 5) // (AIC) Interrupt Source Type +#define AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE ((unsigned int) 0x0 << 5) // (AIC) Internal Sources Code Label Level Sensitive +#define AT91C_AIC_SRCTYPE_INT_EDGE_TRIGGERED ((unsigned int) 0x1 << 5) // (AIC) Internal Sources Code Label Edge triggered +#define AT91C_AIC_SRCTYPE_EXT_HIGH_LEVEL ((unsigned int) 0x2 << 5) // (AIC) External Sources Code Label High-level Sensitive +#define AT91C_AIC_SRCTYPE_EXT_POSITIVE_EDGE ((unsigned int) 0x3 << 5) // (AIC) External Sources Code Label Positive Edge triggered +// -------- AIC_CISR : (AIC Offset: 0x114) AIC Core Interrupt Status Register -------- +#define AT91C_AIC_NFIQ ((unsigned int) 0x1 << 0) // (AIC) NFIQ Status +#define AT91C_AIC_NIRQ ((unsigned int) 0x1 << 1) // (AIC) NIRQ Status +// -------- AIC_DCR : (AIC Offset: 0x138) AIC Debug Control Register (Protect) -------- +#define AT91C_AIC_DCR_PROT ((unsigned int) 0x1 << 0) // (AIC) Protection Mode +#define AT91C_AIC_DCR_GMSK ((unsigned int) 0x1 << 1) // (AIC) General Mask + +// ***************************************************************************** +// SOFTWARE API DEFINITION FOR Peripheral DMA Controller +// ***************************************************************************** +typedef struct _AT91S_PDC { + AT91_REG PDC_RPR; // Receive Pointer Register + AT91_REG PDC_RCR; // Receive Counter Register + AT91_REG PDC_TPR; // Transmit Pointer Register + AT91_REG PDC_TCR; // Transmit Counter Register + AT91_REG PDC_RNPR; // Receive Next Pointer Register + AT91_REG PDC_RNCR; // Receive Next Counter Register + AT91_REG PDC_TNPR; // Transmit Next Pointer Register + AT91_REG PDC_TNCR; // Transmit Next Counter Register + AT91_REG PDC_PTCR; // PDC Transfer Control Register + AT91_REG PDC_PTSR; // PDC Transfer Status Register +} AT91S_PDC, *AT91PS_PDC; + +// -------- PDC_PTCR : (PDC Offset: 0x20) PDC Transfer Control Register -------- +#define AT91C_PDC_RXTEN ((unsigned int) 0x1 << 0) // (PDC) Receiver Transfer Enable +#define AT91C_PDC_RXTDIS ((unsigned int) 0x1 << 1) // (PDC) Receiver Transfer Disable +#define AT91C_PDC_TXTEN ((unsigned int) 0x1 << 8) // (PDC) Transmitter Transfer Enable +#define AT91C_PDC_TXTDIS ((unsigned int) 0x1 << 9) // (PDC) Transmitter Transfer Disable +// -------- PDC_PTSR : (PDC Offset: 0x24) PDC Transfer Status Register -------- + +// ***************************************************************************** +// SOFTWARE API DEFINITION FOR Debug Unit +// ***************************************************************************** +typedef struct _AT91S_DBGU { + AT91_REG DBGU_CR; // Control Register + AT91_REG DBGU_MR; // Mode Register + AT91_REG DBGU_IER; // Interrupt Enable Register + AT91_REG DBGU_IDR; // Interrupt Disable Register + AT91_REG DBGU_IMR; // Interrupt Mask Register + AT91_REG DBGU_CSR; // Channel Status Register + AT91_REG DBGU_RHR; // Receiver Holding Register + AT91_REG DBGU_THR; // Transmitter Holding Register + AT91_REG DBGU_BRGR; // Baud Rate Generator Register + AT91_REG Reserved0[7]; // + AT91_REG DBGU_CIDR; // Chip ID Register + AT91_REG DBGU_EXID; // Chip ID Extension Register + AT91_REG DBGU_FNTR; // Force NTRST Register + AT91_REG Reserved1[45]; // + AT91_REG DBGU_RPR; // Receive Pointer Register + AT91_REG DBGU_RCR; // Receive Counter Register + AT91_REG DBGU_TPR; // Transmit Pointer Register + AT91_REG DBGU_TCR; // Transmit Counter Register + AT91_REG DBGU_RNPR; // Receive Next Pointer Register + AT91_REG DBGU_RNCR; // Receive Next Counter Register + AT91_REG DBGU_TNPR; // Transmit Next Pointer Register + AT91_REG DBGU_TNCR; // Transmit Next Counter Register + AT91_REG DBGU_PTCR; // PDC Transfer Control Register + AT91_REG DBGU_PTSR; // PDC Transfer Status Register +} AT91S_DBGU, *AT91PS_DBGU; + +// -------- DBGU_CR : (DBGU Offset: 0x0) Debug Unit Control Register -------- +#define AT91C_US_RSTRX ((unsigned int) 0x1 << 2) // (DBGU) Reset Receiver +#define AT91C_US_RSTTX ((unsigned int) 0x1 << 3) // (DBGU) Reset Transmitter +#define AT91C_US_RXEN ((unsigned int) 0x1 << 4) // (DBGU) Receiver Enable +#define AT91C_US_RXDIS ((unsigned int) 0x1 << 5) // (DBGU) Receiver Disable +#define AT91C_US_TXEN ((unsigned int) 0x1 << 6) // (DBGU) Transmitter Enable +#define AT91C_US_TXDIS ((unsigned int) 0x1 << 7) // (DBGU) Transmitter Disable +#define AT91C_US_RSTSTA ((unsigned int) 0x1 << 8) // (DBGU) Reset Status Bits +// -------- DBGU_MR : (DBGU Offset: 0x4) Debug Unit Mode Register -------- +#define AT91C_US_PAR ((unsigned int) 0x7 << 9) // (DBGU) Parity type +#define AT91C_US_PAR_EVEN ((unsigned int) 0x0 << 9) // (DBGU) Even Parity +#define AT91C_US_PAR_ODD ((unsigned int) 0x1 << 9) // (DBGU) Odd Parity +#define AT91C_US_PAR_SPACE ((unsigned int) 0x2 << 9) // (DBGU) Parity forced to 0 (Space) +#define AT91C_US_PAR_MARK ((unsigned int) 0x3 << 9) // (DBGU) Parity forced to 1 (Mark) +#define AT91C_US_PAR_NONE ((unsigned int) 0x4 << 9) // (DBGU) No Parity +#define AT91C_US_PAR_MULTI_DROP ((unsigned int) 0x6 << 9) // (DBGU) Multi-drop mode +#define AT91C_US_CHMODE ((unsigned int) 0x3 << 14) // (DBGU) Channel Mode +#define AT91C_US_CHMODE_NORMAL ((unsigned int) 0x0 << 14) // (DBGU) Normal Mode: The USART channel operates as an RX/TX USART. +#define AT91C_US_CHMODE_AUTO ((unsigned int) 0x1 << 14) // (DBGU) Automatic Echo: Receiver Data Input is connected to the TXD pin. +#define AT91C_US_CHMODE_LOCAL ((unsigned int) 0x2 << 14) // (DBGU) Local Loopback: Transmitter Output Signal is connected to Receiver Input Signal. +#define AT91C_US_CHMODE_REMOTE ((unsigned int) 0x3 << 14) // (DBGU) Remote Loopback: RXD pin is internally connected to TXD pin. +// -------- DBGU_IER : (DBGU Offset: 0x8) Debug Unit Interrupt Enable Register -------- +#define AT91C_US_RXRDY ((unsigned int) 0x1 << 0) // (DBGU) RXRDY Interrupt +#define AT91C_US_TXRDY ((unsigned int) 0x1 << 1) // (DBGU) TXRDY Interrupt +#define AT91C_US_ENDRX ((unsigned int) 0x1 << 3) // (DBGU) End of Receive Transfer Interrupt +#define AT91C_US_ENDTX ((unsigned int) 0x1 << 4) // (DBGU) End of Transmit Interrupt +#define AT91C_US_OVRE ((unsigned int) 0x1 << 5) // (DBGU) Overrun Interrupt +#define AT91C_US_FRAME ((unsigned int) 0x1 << 6) // (DBGU) Framing Error Interrupt +#define AT91C_US_PARE ((unsigned int) 0x1 << 7) // (DBGU) Parity Error Interrupt +#define AT91C_US_TXEMPTY ((unsigned int) 0x1 << 9) // (DBGU) TXEMPTY Interrupt +#define AT91C_US_TXBUFE ((unsigned int) 0x1 << 11) // (DBGU) TXBUFE Interrupt +#define AT91C_US_RXBUFF ((unsigned int) 0x1 << 12) // (DBGU) RXBUFF Interrupt +#define AT91C_US_COMM_TX ((unsigned int) 0x1 << 30) // (DBGU) COMM_TX Interrupt +#define AT91C_US_COMM_RX ((unsigned int) 0x1 << 31) // (DBGU) COMM_RX Interrupt +// -------- DBGU_IDR : (DBGU Offset: 0xc) Debug Unit Interrupt Disable Register -------- +// -------- DBGU_IMR : (DBGU Offset: 0x10) Debug Unit Interrupt Mask Register -------- +// -------- DBGU_CSR : (DBGU Offset: 0x14) Debug Unit Channel Status Register -------- +// -------- DBGU_FNTR : (DBGU Offset: 0x48) Debug Unit FORCE_NTRST Register -------- +#define AT91C_US_FORCE_NTRST ((unsigned int) 0x1 << 0) // (DBGU) Force NTRST in JTAG + +// ***************************************************************************** +// SOFTWARE API DEFINITION FOR Parallel Input Output Controler +// ***************************************************************************** +typedef struct _AT91S_PIO { + AT91_REG PIO_PER; // PIO Enable Register + AT91_REG PIO_PDR; // PIO Disable Register + AT91_REG PIO_PSR; // PIO Status Register + AT91_REG Reserved0[1]; // + AT91_REG PIO_OER; // Output Enable Register + AT91_REG PIO_ODR; // Output Disable Registerr + AT91_REG PIO_OSR; // Output Status Register + AT91_REG Reserved1[1]; // + AT91_REG PIO_IFER; // Input Filter Enable Register + AT91_REG PIO_IFDR; // Input Filter Disable Register + AT91_REG PIO_IFSR; // Input Filter Status Register + AT91_REG Reserved2[1]; // + AT91_REG PIO_SODR; // Set Output Data Register + AT91_REG PIO_CODR; // Clear Output Data Register + AT91_REG PIO_ODSR; // Output Data Status Register + AT91_REG PIO_PDSR; // Pin Data Status Register + AT91_REG PIO_IER; // Interrupt Enable Register + AT91_REG PIO_IDR; // Interrupt Disable Register + AT91_REG PIO_IMR; // Interrupt Mask Register + AT91_REG PIO_ISR; // Interrupt Status Register + AT91_REG PIO_MDER; // Multi-driver Enable Register + AT91_REG PIO_MDDR; // Multi-driver Disable Register + AT91_REG PIO_MDSR; // Multi-driver Status Register + AT91_REG Reserved3[1]; // + AT91_REG PIO_PPUDR; // Pull-up Disable Register + AT91_REG PIO_PPUER; // Pull-up Enable Register + AT91_REG PIO_PPUSR; // Pull-up Status Register + AT91_REG Reserved4[1]; // + AT91_REG PIO_ASR; // Select A Register + AT91_REG PIO_BSR; // Select B Register + AT91_REG PIO_ABSR; // AB Select Status Register + AT91_REG Reserved5[9]; // + AT91_REG PIO_OWER; // Output Write Enable Register + AT91_REG PIO_OWDR; // Output Write Disable Register + AT91_REG PIO_OWSR; // Output Write Status Register +} AT91S_PIO, *AT91PS_PIO; + + +// ***************************************************************************** +// SOFTWARE API DEFINITION FOR Clock Generator Controler +// ***************************************************************************** +typedef struct _AT91S_CKGR { + AT91_REG CKGR_MOR; // Main Oscillator Register + AT91_REG CKGR_MCFR; // Main Clock Frequency Register + AT91_REG Reserved0[1]; // + AT91_REG CKGR_PLLR; // PLL Register +} AT91S_CKGR, *AT91PS_CKGR; + +// -------- CKGR_MOR : (CKGR Offset: 0x0) Main Oscillator Register -------- +#define AT91C_CKGR_MOSCEN ((unsigned int) 0x1 << 0) // (CKGR) Main Oscillator Enable +#define AT91C_CKGR_OSCBYPASS ((unsigned int) 0x1 << 1) // (CKGR) Main Oscillator Bypass +#define AT91C_CKGR_OSCOUNT ((unsigned int) 0xFF << 8) // (CKGR) Main Oscillator Start-up Time +// -------- CKGR_MCFR : (CKGR Offset: 0x4) Main Clock Frequency Register -------- +#define AT91C_CKGR_MAINF ((unsigned int) 0xFFFF << 0) // (CKGR) Main Clock Frequency +#define AT91C_CKGR_MAINRDY ((unsigned int) 0x1 << 16) // (CKGR) Main Clock Ready +// -------- CKGR_PLLR : (CKGR Offset: 0xc) PLL B Register -------- +#define AT91C_CKGR_DIV ((unsigned int) 0xFF << 0) // (CKGR) Divider Selected +#define AT91C_CKGR_DIV_0 ((unsigned int) 0x0) // (CKGR) Divider output is 0 +#define AT91C_CKGR_DIV_BYPASS ((unsigned int) 0x1) // (CKGR) Divider is bypassed +#define AT91C_CKGR_PLLCOUNT ((unsigned int) 0x3F << 8) // (CKGR) PLL Counter +#define AT91C_CKGR_OUT ((unsigned int) 0x3 << 14) // (CKGR) PLL Output Frequency Range +#define AT91C_CKGR_OUT_0 ((unsigned int) 0x0 << 14) // (CKGR) Please refer to the PLL datasheet +#define AT91C_CKGR_OUT_1 ((unsigned int) 0x1 << 14) // (CKGR) Please refer to the PLL datasheet +#define AT91C_CKGR_OUT_2 ((unsigned int) 0x2 << 14) // (CKGR) Please refer to the PLL datasheet +#define AT91C_CKGR_OUT_3 ((unsigned int) 0x3 << 14) // (CKGR) Please refer to the PLL datasheet +#define AT91C_CKGR_MUL ((unsigned int) 0x7FF << 16) // (CKGR) PLL Multiplier +#define AT91C_CKGR_USBDIV ((unsigned int) 0x3 << 28) // (CKGR) Divider for USB Clocks +#define AT91C_CKGR_USBDIV_0 ((unsigned int) 0x0 << 28) // (CKGR) Divider output is PLL clock output +#define AT91C_CKGR_USBDIV_1 ((unsigned int) 0x1 << 28) // (CKGR) Divider output is PLL clock output divided by 2 +#define AT91C_CKGR_USBDIV_2 ((unsigned int) 0x2 << 28) // (CKGR) Divider output is PLL clock output divided by 4 + +// ***************************************************************************** +// SOFTWARE API DEFINITION FOR Power Management Controler +// ***************************************************************************** +typedef struct _AT91S_PMC { + AT91_REG PMC_SCER; // System Clock Enable Register + AT91_REG PMC_SCDR; // System Clock Disable Register + AT91_REG PMC_SCSR; // System Clock Status Register + AT91_REG Reserved0[1]; // + AT91_REG PMC_PCER; // Peripheral Clock Enable Register + AT91_REG PMC_PCDR; // Peripheral Clock Disable Register + AT91_REG PMC_PCSR; // Peripheral Clock Status Register + AT91_REG Reserved1[1]; // + AT91_REG PMC_MOR; // Main Oscillator Register + AT91_REG PMC_MCFR; // Main Clock Frequency Register + AT91_REG Reserved2[1]; // + AT91_REG PMC_PLLR; // PLL Register + AT91_REG PMC_MCKR; // Master Clock Register + AT91_REG Reserved3[3]; // + AT91_REG PMC_PCKR[3]; // Programmable Clock Register + AT91_REG Reserved4[5]; // + AT91_REG PMC_IER; // Interrupt Enable Register + AT91_REG PMC_IDR; // Interrupt Disable Register + AT91_REG PMC_SR; // Status Register + AT91_REG PMC_IMR; // Interrupt Mask Register +} AT91S_PMC, *AT91PS_PMC; + +// -------- PMC_SCER : (PMC Offset: 0x0) System Clock Enable Register -------- +#define AT91C_PMC_PCK ((unsigned int) 0x1 << 0) // (PMC) Processor Clock +#define AT91C_PMC_UDP ((unsigned int) 0x1 << 7) // (PMC) USB Device Port Clock +#define AT91C_PMC_PCK0 ((unsigned int) 0x1 << 8) // (PMC) Programmable Clock Output +#define AT91C_PMC_PCK1 ((unsigned int) 0x1 << 9) // (PMC) Programmable Clock Output +#define AT91C_PMC_PCK2 ((unsigned int) 0x1 << 10) // (PMC) Programmable Clock Output +// -------- PMC_SCDR : (PMC Offset: 0x4) System Clock Disable Register -------- +// -------- PMC_SCSR : (PMC Offset: 0x8) System Clock Status Register -------- +// -------- CKGR_MOR : (PMC Offset: 0x20) Main Oscillator Register -------- +// -------- CKGR_MCFR : (PMC Offset: 0x24) Main Clock Frequency Register -------- +// -------- CKGR_PLLR : (PMC Offset: 0x2c) PLL B Register -------- +// -------- PMC_MCKR : (PMC Offset: 0x30) Master Clock Register -------- +#define AT91C_PMC_CSS ((unsigned int) 0x3 << 0) // (PMC) Programmable Clock Selection +#define AT91C_PMC_CSS_SLOW_CLK ((unsigned int) 0x0) // (PMC) Slow Clock is selected +#define AT91C_PMC_CSS_MAIN_CLK ((unsigned int) 0x1) // (PMC) Main Clock is selected +#define AT91C_PMC_CSS_PLL_CLK ((unsigned int) 0x3) // (PMC) Clock from PLL is selected +#define AT91C_PMC_PRES ((unsigned int) 0x7 << 2) // (PMC) Programmable Clock Prescaler +#define AT91C_PMC_PRES_CLK ((unsigned int) 0x0 << 2) // (PMC) Selected clock +#define AT91C_PMC_PRES_CLK_2 ((unsigned int) 0x1 << 2) // (PMC) Selected clock divided by 2 +#define AT91C_PMC_PRES_CLK_4 ((unsigned int) 0x2 << 2) // (PMC) Selected clock divided by 4 +#define AT91C_PMC_PRES_CLK_8 ((unsigned int) 0x3 << 2) // (PMC) Selected clock divided by 8 +#define AT91C_PMC_PRES_CLK_16 ((unsigned int) 0x4 << 2) // (PMC) Selected clock divided by 16 +#define AT91C_PMC_PRES_CLK_32 ((unsigned int) 0x5 << 2) // (PMC) Selected clock divided by 32 +#define AT91C_PMC_PRES_CLK_64 ((unsigned int) 0x6 << 2) // (PMC) Selected clock divided by 64 +// -------- PMC_PCKR : (PMC Offset: 0x40) Programmable Clock Register -------- +// -------- PMC_IER : (PMC Offset: 0x60) PMC Interrupt Enable Register -------- +#define AT91C_PMC_MOSCS ((unsigned int) 0x1 << 0) // (PMC) MOSC Status/Enable/Disable/Mask +#define AT91C_PMC_LOCK ((unsigned int) 0x1 << 2) // (PMC) PLL Status/Enable/Disable/Mask +#define AT91C_PMC_MCKRDY ((unsigned int) 0x1 << 3) // (PMC) MCK_RDY Status/Enable/Disable/Mask +#define AT91C_PMC_PCK0RDY ((unsigned int) 0x1 << 8) // (PMC) PCK0_RDY Status/Enable/Disable/Mask +#define AT91C_PMC_PCK1RDY ((unsigned int) 0x1 << 9) // (PMC) PCK1_RDY Status/Enable/Disable/Mask +#define AT91C_PMC_PCK2RDY ((unsigned int) 0x1 << 10) // (PMC) PCK2_RDY Status/Enable/Disable/Mask +// -------- PMC_IDR : (PMC Offset: 0x64) PMC Interrupt Disable Register -------- +// -------- PMC_SR : (PMC Offset: 0x68) PMC Status Register -------- +// -------- PMC_IMR : (PMC Offset: 0x6c) PMC Interrupt Mask Register -------- + +// ***************************************************************************** +// SOFTWARE API DEFINITION FOR Reset Controller Interface +// ***************************************************************************** +typedef struct _AT91S_RSTC { + AT91_REG RSTC_RCR; // Reset Control Register + AT91_REG RSTC_RSR; // Reset Status Register + AT91_REG RSTC_RMR; // Reset Mode Register +} AT91S_RSTC, *AT91PS_RSTC; + +// -------- RSTC_RCR : (RSTC Offset: 0x0) Reset Control Register -------- +#define AT91C_RSTC_PROCRST ((unsigned int) 0x1 << 0) // (RSTC) Processor Reset +#define AT91C_RSTC_PERRST ((unsigned int) 0x1 << 2) // (RSTC) Peripheral Reset +#define AT91C_RSTC_EXTRST ((unsigned int) 0x1 << 3) // (RSTC) External Reset +#define AT91C_RSTC_KEY ((unsigned int) 0xFF << 24) // (RSTC) Password +// -------- RSTC_RSR : (RSTC Offset: 0x4) Reset Status Register -------- +#define AT91C_RSTC_URSTS ((unsigned int) 0x1 << 0) // (RSTC) User Reset Status +#define AT91C_RSTC_BODSTS ((unsigned int) 0x1 << 1) // (RSTC) Brownout Detection Status +#define AT91C_RSTC_RSTTYP ((unsigned int) 0x7 << 8) // (RSTC) Reset Type +#define AT91C_RSTC_RSTTYP_POWERUP ((unsigned int) 0x0 << 8) // (RSTC) Power-up Reset. VDDCORE rising. +#define AT91C_RSTC_RSTTYP_WAKEUP ((unsigned int) 0x1 << 8) // (RSTC) WakeUp Reset. VDDCORE rising. +#define AT91C_RSTC_RSTTYP_WATCHDOG ((unsigned int) 0x2 << 8) // (RSTC) Watchdog Reset. Watchdog overflow occured. +#define AT91C_RSTC_RSTTYP_SOFTWARE ((unsigned int) 0x3 << 8) // (RSTC) Software Reset. Processor reset required by the software. +#define AT91C_RSTC_RSTTYP_USER ((unsigned int) 0x4 << 8) // (RSTC) User Reset. NRST pin detected low. +#define AT91C_RSTC_RSTTYP_BROWNOUT ((unsigned int) 0x5 << 8) // (RSTC) Brownout Reset occured. +#define AT91C_RSTC_NRSTL ((unsigned int) 0x1 << 16) // (RSTC) NRST pin level +#define AT91C_RSTC_SRCMP ((unsigned int) 0x1 << 17) // (RSTC) Software Reset Command in Progress. +// -------- RSTC_RMR : (RSTC Offset: 0x8) Reset Mode Register -------- +#define AT91C_RSTC_URSTEN ((unsigned int) 0x1 << 0) // (RSTC) User Reset Enable +#define AT91C_RSTC_URSTIEN ((unsigned int) 0x1 << 4) // (RSTC) User Reset Interrupt Enable +#define AT91C_RSTC_ERSTL ((unsigned int) 0xF << 8) // (RSTC) User Reset Enable +#define AT91C_RSTC_BODIEN ((unsigned int) 0x1 << 16) // (RSTC) Brownout Detection Interrupt Enable + +// ***************************************************************************** +// SOFTWARE API DEFINITION FOR Real Time Timer Controller Interface +// ***************************************************************************** +typedef struct _AT91S_RTTC { + AT91_REG RTTC_RTMR; // Real-time Mode Register + AT91_REG RTTC_RTAR; // Real-time Alarm Register + AT91_REG RTTC_RTVR; // Real-time Value Register + AT91_REG RTTC_RTSR; // Real-time Status Register +} AT91S_RTTC, *AT91PS_RTTC; + +// -------- RTTC_RTMR : (RTTC Offset: 0x0) Real-time Mode Register -------- +#define AT91C_RTTC_RTPRES ((unsigned int) 0xFFFF << 0) // (RTTC) Real-time Timer Prescaler Value +#define AT91C_RTTC_ALMIEN ((unsigned int) 0x1 << 16) // (RTTC) Alarm Interrupt Enable +#define AT91C_RTTC_RTTINCIEN ((unsigned int) 0x1 << 17) // (RTTC) Real Time Timer Increment Interrupt Enable +#define AT91C_RTTC_RTTRST ((unsigned int) 0x1 << 18) // (RTTC) Real Time Timer Restart +// -------- RTTC_RTAR : (RTTC Offset: 0x4) Real-time Alarm Register -------- +#define AT91C_RTTC_ALMV ((unsigned int) 0x0 << 0) // (RTTC) Alarm Value +// -------- RTTC_RTVR : (RTTC Offset: 0x8) Current Real-time Value Register -------- +#define AT91C_RTTC_CRTV ((unsigned int) 0x0 << 0) // (RTTC) Current Real-time Value +// -------- RTTC_RTSR : (RTTC Offset: 0xc) Real-time Status Register -------- +#define AT91C_RTTC_ALMS ((unsigned int) 0x1 << 0) // (RTTC) Real-time Alarm Status +#define AT91C_RTTC_RTTINC ((unsigned int) 0x1 << 1) // (RTTC) Real-time Timer Increment + +// ***************************************************************************** +// SOFTWARE API DEFINITION FOR Periodic Interval Timer Controller Interface +// ***************************************************************************** +typedef struct _AT91S_PITC { + AT91_REG PITC_PIMR; // Period Interval Mode Register + AT91_REG PITC_PISR; // Period Interval Status Register + AT91_REG PITC_PIVR; // Period Interval Value Register + AT91_REG PITC_PIIR; // Period Interval Image Register +} AT91S_PITC, *AT91PS_PITC; + +// -------- PITC_PIMR : (PITC Offset: 0x0) Periodic Interval Mode Register -------- +#define AT91C_PITC_PIV ((unsigned int) 0xFFFFF << 0) // (PITC) Periodic Interval Value +#define AT91C_PITC_PITEN ((unsigned int) 0x1 << 24) // (PITC) Periodic Interval Timer Enabled +#define AT91C_PITC_PITIEN ((unsigned int) 0x1 << 25) // (PITC) Periodic Interval Timer Interrupt Enable +// -------- PITC_PISR : (PITC Offset: 0x4) Periodic Interval Status Register -------- +#define AT91C_PITC_PITS ((unsigned int) 0x1 << 0) // (PITC) Periodic Interval Timer Status +// -------- PITC_PIVR : (PITC Offset: 0x8) Periodic Interval Value Register -------- +#define AT91C_PITC_CPIV ((unsigned int) 0xFFFFF << 0) // (PITC) Current Periodic Interval Value +#define AT91C_PITC_PICNT ((unsigned int) 0xFFF << 20) // (PITC) Periodic Interval Counter +// -------- PITC_PIIR : (PITC Offset: 0xc) Periodic Interval Image Register -------- + +// ***************************************************************************** +// SOFTWARE API DEFINITION FOR Watchdog Timer Controller Interface +// ***************************************************************************** +typedef struct _AT91S_WDTC { + AT91_REG WDTC_WDCR; // Watchdog Control Register + AT91_REG WDTC_WDMR; // Watchdog Mode Register + AT91_REG WDTC_WDSR; // Watchdog Status Register +} AT91S_WDTC, *AT91PS_WDTC; + +// -------- WDTC_WDCR : (WDTC Offset: 0x0) Periodic Interval Image Register -------- +#define AT91C_WDTC_WDRSTT ((unsigned int) 0x1 << 0) // (WDTC) Watchdog Restart +#define AT91C_WDTC_KEY ((unsigned int) 0xFF << 24) // (WDTC) Watchdog KEY Password +// -------- WDTC_WDMR : (WDTC Offset: 0x4) Watchdog Mode Register -------- +#define AT91C_WDTC_WDV ((unsigned int) 0xFFF << 0) // (WDTC) Watchdog Timer Restart +#define AT91C_WDTC_WDFIEN ((unsigned int) 0x1 << 12) // (WDTC) Watchdog Fault Interrupt Enable +#define AT91C_WDTC_WDRSTEN ((unsigned int) 0x1 << 13) // (WDTC) Watchdog Reset Enable +#define AT91C_WDTC_WDRPROC ((unsigned int) 0x1 << 14) // (WDTC) Watchdog Timer Restart +#define AT91C_WDTC_WDDIS ((unsigned int) 0x1 << 15) // (WDTC) Watchdog Disable +#define AT91C_WDTC_WDD ((unsigned int) 0xFFF << 16) // (WDTC) Watchdog Delta Value +#define AT91C_WDTC_WDDBGHLT ((unsigned int) 0x1 << 28) // (WDTC) Watchdog Debug Halt +#define AT91C_WDTC_WDIDLEHLT ((unsigned int) 0x1 << 29) // (WDTC) Watchdog Idle Halt +// -------- WDTC_WDSR : (WDTC Offset: 0x8) Watchdog Status Register -------- +#define AT91C_WDTC_WDUNF ((unsigned int) 0x1 << 0) // (WDTC) Watchdog Underflow +#define AT91C_WDTC_WDERR ((unsigned int) 0x1 << 1) // (WDTC) Watchdog Error + +// ***************************************************************************** +// SOFTWARE API DEFINITION FOR Voltage Regulator Mode Controller Interface +// ***************************************************************************** +typedef struct _AT91S_VREG { + AT91_REG VREG_MR; // Voltage Regulator Mode Register +} AT91S_VREG, *AT91PS_VREG; + +// -------- VREG_MR : (VREG Offset: 0x0) Voltage Regulator Mode Register -------- +#define AT91C_VREG_PSTDBY ((unsigned int) 0x1 << 0) // (VREG) Voltage Regulator Power Standby Mode + +// ***************************************************************************** +// SOFTWARE API DEFINITION FOR Memory Controller Interface +// ***************************************************************************** +typedef struct _AT91S_MC { + AT91_REG MC_RCR; // MC Remap Control Register + AT91_REG MC_ASR; // MC Abort Status Register + AT91_REG MC_AASR; // MC Abort Address Status Register + AT91_REG Reserved0[21]; // + AT91_REG MC_FMR; // MC Flash Mode Register + AT91_REG MC_FCR; // MC Flash Command Register + AT91_REG MC_FSR; // MC Flash Status Register +} AT91S_MC, *AT91PS_MC; + +// -------- MC_RCR : (MC Offset: 0x0) MC Remap Control Register -------- +#define AT91C_MC_RCB ((unsigned int) 0x1 << 0) // (MC) Remap Command Bit +// -------- MC_ASR : (MC Offset: 0x4) MC Abort Status Register -------- +#define AT91C_MC_UNDADD ((unsigned int) 0x1 << 0) // (MC) Undefined Addess Abort Status +#define AT91C_MC_MISADD ((unsigned int) 0x1 << 1) // (MC) Misaligned Addess Abort Status +#define AT91C_MC_ABTSZ ((unsigned int) 0x3 << 8) // (MC) Abort Size Status +#define AT91C_MC_ABTSZ_BYTE ((unsigned int) 0x0 << 8) // (MC) Byte +#define AT91C_MC_ABTSZ_HWORD ((unsigned int) 0x1 << 8) // (MC) Half-word +#define AT91C_MC_ABTSZ_WORD ((unsigned int) 0x2 << 8) // (MC) Word +#define AT91C_MC_ABTTYP ((unsigned int) 0x3 << 10) // (MC) Abort Type Status +#define AT91C_MC_ABTTYP_DATAR ((unsigned int) 0x0 << 10) // (MC) Data Read +#define AT91C_MC_ABTTYP_DATAW ((unsigned int) 0x1 << 10) // (MC) Data Write +#define AT91C_MC_ABTTYP_FETCH ((unsigned int) 0x2 << 10) // (MC) Code Fetch +#define AT91C_MC_MST0 ((unsigned int) 0x1 << 16) // (MC) Master 0 Abort Source +#define AT91C_MC_MST1 ((unsigned int) 0x1 << 17) // (MC) Master 1 Abort Source +#define AT91C_MC_SVMST0 ((unsigned int) 0x1 << 24) // (MC) Saved Master 0 Abort Source +#define AT91C_MC_SVMST1 ((unsigned int) 0x1 << 25) // (MC) Saved Master 1 Abort Source +// -------- MC_FMR : (MC Offset: 0x60) MC Flash Mode Register -------- +#define AT91C_MC_FRDY ((unsigned int) 0x1 << 0) // (MC) Flash Ready +#define AT91C_MC_LOCKE ((unsigned int) 0x1 << 2) // (MC) Lock Error +#define AT91C_MC_PROGE ((unsigned int) 0x1 << 3) // (MC) Programming Error +#define AT91C_MC_NEBP ((unsigned int) 0x1 << 7) // (MC) No Erase Before Programming +#define AT91C_MC_FWS ((unsigned int) 0x3 << 8) // (MC) Flash Wait State +#define AT91C_MC_FWS_0FWS ((unsigned int) 0x0 << 8) // (MC) 1 cycle for Read, 2 for Write operations +#define AT91C_MC_FWS_1FWS ((unsigned int) 0x1 << 8) // (MC) 2 cycles for Read, 3 for Write operations +#define AT91C_MC_FWS_2FWS ((unsigned int) 0x2 << 8) // (MC) 3 cycles for Read, 4 for Write operations +#define AT91C_MC_FWS_3FWS ((unsigned int) 0x3 << 8) // (MC) 4 cycles for Read, 4 for Write operations +#define AT91C_MC_FMCN ((unsigned int) 0xFF << 16) // (MC) Flash Microsecond Cycle Number +// -------- MC_FCR : (MC Offset: 0x64) MC Flash Command Register -------- +#define AT91C_MC_FCMD ((unsigned int) 0xF << 0) // (MC) Flash Command +#define AT91C_MC_FCMD_START_PROG ((unsigned int) 0x1) // (MC) Starts the programming of th epage specified by PAGEN. +#define AT91C_MC_FCMD_LOCK ((unsigned int) 0x2) // (MC) Starts a lock sequence of the sector defined by the bits 4 to 7 of the field PAGEN. +#define AT91C_MC_FCMD_PROG_AND_LOCK ((unsigned int) 0x3) // (MC) The lock sequence automatically happens after the programming sequence is completed. +#define AT91C_MC_FCMD_UNLOCK ((unsigned int) 0x4) // (MC) Starts an unlock sequence of the sector defined by the bits 4 to 7 of the field PAGEN. +#define AT91C_MC_FCMD_ERASE_ALL ((unsigned int) 0x8) // (MC) Starts the erase of the entire flash.If at least a page is locked, the command is cancelled. +#define AT91C_MC_FCMD_SET_GP_NVM ((unsigned int) 0xB) // (MC) Set General Purpose NVM bits. +#define AT91C_MC_FCMD_CLR_GP_NVM ((unsigned int) 0xD) // (MC) Clear General Purpose NVM bits. +#define AT91C_MC_FCMD_SET_SECURITY ((unsigned int) 0xF) // (MC) Set Security Bit. +#define AT91C_MC_PAGEN ((unsigned int) 0x3FF << 8) // (MC) Page Number +#define AT91C_MC_KEY ((unsigned int) 0xFF << 24) // (MC) Writing Protect Key +// -------- MC_FSR : (MC Offset: 0x68) MC Flash Command Register -------- +#define AT91C_MC_SECURITY ((unsigned int) 0x1 << 4) // (MC) Security Bit Status +#define AT91C_MC_GPNVM0 ((unsigned int) 0x1 << 8) // (MC) Sector 0 Lock Status +#define AT91C_MC_GPNVM1 ((unsigned int) 0x1 << 9) // (MC) Sector 1 Lock Status +#define AT91C_MC_GPNVM2 ((unsigned int) 0x1 << 10) // (MC) Sector 2 Lock Status +#define AT91C_MC_GPNVM3 ((unsigned int) 0x1 << 11) // (MC) Sector 3 Lock Status +#define AT91C_MC_GPNVM4 ((unsigned int) 0x1 << 12) // (MC) Sector 4 Lock Status +#define AT91C_MC_GPNVM5 ((unsigned int) 0x1 << 13) // (MC) Sector 5 Lock Status +#define AT91C_MC_GPNVM6 ((unsigned int) 0x1 << 14) // (MC) Sector 6 Lock Status +#define AT91C_MC_GPNVM7 ((unsigned int) 0x1 << 15) // (MC) Sector 7 Lock Status +#define AT91C_MC_LOCKS0 ((unsigned int) 0x1 << 16) // (MC) Sector 0 Lock Status +#define AT91C_MC_LOCKS1 ((unsigned int) 0x1 << 17) // (MC) Sector 1 Lock Status +#define AT91C_MC_LOCKS2 ((unsigned int) 0x1 << 18) // (MC) Sector 2 Lock Status +#define AT91C_MC_LOCKS3 ((unsigned int) 0x1 << 19) // (MC) Sector 3 Lock Status +#define AT91C_MC_LOCKS4 ((unsigned int) 0x1 << 20) // (MC) Sector 4 Lock Status +#define AT91C_MC_LOCKS5 ((unsigned int) 0x1 << 21) // (MC) Sector 5 Lock Status +#define AT91C_MC_LOCKS6 ((unsigned int) 0x1 << 22) // (MC) Sector 6 Lock Status +#define AT91C_MC_LOCKS7 ((unsigned int) 0x1 << 23) // (MC) Sector 7 Lock Status +#define AT91C_MC_LOCKS8 ((unsigned int) 0x1 << 24) // (MC) Sector 8 Lock Status +#define AT91C_MC_LOCKS9 ((unsigned int) 0x1 << 25) // (MC) Sector 9 Lock Status +#define AT91C_MC_LOCKS10 ((unsigned int) 0x1 << 26) // (MC) Sector 10 Lock Status +#define AT91C_MC_LOCKS11 ((unsigned int) 0x1 << 27) // (MC) Sector 11 Lock Status +#define AT91C_MC_LOCKS12 ((unsigned int) 0x1 << 28) // (MC) Sector 12 Lock Status +#define AT91C_MC_LOCKS13 ((unsigned int) 0x1 << 29) // (MC) Sector 13 Lock Status +#define AT91C_MC_LOCKS14 ((unsigned int) 0x1 << 30) // (MC) Sector 14 Lock Status +#define AT91C_MC_LOCKS15 ((unsigned int) 0x1 << 31) // (MC) Sector 15 Lock Status + +// ***************************************************************************** +// SOFTWARE API DEFINITION FOR Serial Parallel Interface +// ***************************************************************************** +typedef struct _AT91S_SPI { + AT91_REG SPI_CR; // Control Register + AT91_REG SPI_MR; // Mode Register + AT91_REG SPI_RDR; // Receive Data Register + AT91_REG SPI_TDR; // Transmit Data Register + AT91_REG SPI_SR; // Status Register + AT91_REG SPI_IER; // Interrupt Enable Register + AT91_REG SPI_IDR; // Interrupt Disable Register + AT91_REG SPI_IMR; // Interrupt Mask Register + AT91_REG Reserved0[4]; // + AT91_REG SPI_CSR[4]; // Chip Select Register + AT91_REG Reserved1[48]; // + AT91_REG SPI_RPR; // Receive Pointer Register + AT91_REG SPI_RCR; // Receive Counter Register + AT91_REG SPI_TPR; // Transmit Pointer Register + AT91_REG SPI_TCR; // Transmit Counter Register + AT91_REG SPI_RNPR; // Receive Next Pointer Register + AT91_REG SPI_RNCR; // Receive Next Counter Register + AT91_REG SPI_TNPR; // Transmit Next Pointer Register + AT91_REG SPI_TNCR; // Transmit Next Counter Register + AT91_REG SPI_PTCR; // PDC Transfer Control Register + AT91_REG SPI_PTSR; // PDC Transfer Status Register +} AT91S_SPI, *AT91PS_SPI; + +// -------- SPI_CR : (SPI Offset: 0x0) SPI Control Register -------- +#define AT91C_SPI_SPIEN ((unsigned int) 0x1 << 0) // (SPI) SPI Enable +#define AT91C_SPI_SPIDIS ((unsigned int) 0x1 << 1) // (SPI) SPI Disable +#define AT91C_SPI_SWRST ((unsigned int) 0x1 << 7) // (SPI) SPI Software reset +#define AT91C_SPI_LASTXFER ((unsigned int) 0x1 << 24) // (SPI) SPI Last Transfer +// -------- SPI_MR : (SPI Offset: 0x4) SPI Mode Register -------- +#define AT91C_SPI_MSTR ((unsigned int) 0x1 << 0) // (SPI) Master/Slave Mode +#define AT91C_SPI_PS ((unsigned int) 0x1 << 1) // (SPI) Peripheral Select +#define AT91C_SPI_PS_FIXED ((unsigned int) 0x0 << 1) // (SPI) Fixed Peripheral Select +#define AT91C_SPI_PS_VARIABLE ((unsigned int) 0x1 << 1) // (SPI) Variable Peripheral Select +#define AT91C_SPI_PCSDEC ((unsigned int) 0x1 << 2) // (SPI) Chip Select Decode +#define AT91C_SPI_FDIV ((unsigned int) 0x1 << 3) // (SPI) Clock Selection +#define AT91C_SPI_MODFDIS ((unsigned int) 0x1 << 4) // (SPI) Mode Fault Detection +#define AT91C_SPI_LLB ((unsigned int) 0x1 << 7) // (SPI) Clock Selection +#define AT91C_SPI_PCS ((unsigned int) 0xF << 16) // (SPI) Peripheral Chip Select +#define AT91C_SPI_DLYBCS ((unsigned int) 0xFF << 24) // (SPI) Delay Between Chip Selects +// -------- SPI_RDR : (SPI Offset: 0x8) Receive Data Register -------- +#define AT91C_SPI_RD ((unsigned int) 0xFFFF << 0) // (SPI) Receive Data +#define AT91C_SPI_RPCS ((unsigned int) 0xF << 16) // (SPI) Peripheral Chip Select Status +// -------- SPI_TDR : (SPI Offset: 0xc) Transmit Data Register -------- +#define AT91C_SPI_TD ((unsigned int) 0xFFFF << 0) // (SPI) Transmit Data +#define AT91C_SPI_TPCS ((unsigned int) 0xF << 16) // (SPI) Peripheral Chip Select Status +// -------- SPI_SR : (SPI Offset: 0x10) Status Register -------- +#define AT91C_SPI_RDRF ((unsigned int) 0x1 << 0) // (SPI) Receive Data Register Full +#define AT91C_SPI_TDRE ((unsigned int) 0x1 << 1) // (SPI) Transmit Data Register Empty +#define AT91C_SPI_MODF ((unsigned int) 0x1 << 2) // (SPI) Mode Fault Error +#define AT91C_SPI_OVRES ((unsigned int) 0x1 << 3) // (SPI) Overrun Error Status +#define AT91C_SPI_ENDRX ((unsigned int) 0x1 << 4) // (SPI) End of Receiver Transfer +#define AT91C_SPI_ENDTX ((unsigned int) 0x1 << 5) // (SPI) End of Receiver Transfer +#define AT91C_SPI_RXBUFF ((unsigned int) 0x1 << 6) // (SPI) RXBUFF Interrupt +#define AT91C_SPI_TXBUFE ((unsigned int) 0x1 << 7) // (SPI) TXBUFE Interrupt +#define AT91C_SPI_NSSR ((unsigned int) 0x1 << 8) // (SPI) NSSR Interrupt +#define AT91C_SPI_TXEMPTY ((unsigned int) 0x1 << 9) // (SPI) TXEMPTY Interrupt +#define AT91C_SPI_SPIENS ((unsigned int) 0x1 << 16) // (SPI) Enable Status +// -------- SPI_IER : (SPI Offset: 0x14) Interrupt Enable Register -------- +// -------- SPI_IDR : (SPI Offset: 0x18) Interrupt Disable Register -------- +// -------- SPI_IMR : (SPI Offset: 0x1c) Interrupt Mask Register -------- +// -------- SPI_CSR : (SPI Offset: 0x30) Chip Select Register -------- +#define AT91C_SPI_CPOL ((unsigned int) 0x1 << 0) // (SPI) Clock Polarity +#define AT91C_SPI_NCPHA ((unsigned int) 0x1 << 1) // (SPI) Clock Phase +#define AT91C_SPI_CSAAT ((unsigned int) 0x1 << 3) // (SPI) Chip Select Active After Transfer +#define AT91C_SPI_BITS ((unsigned int) 0xF << 4) // (SPI) Bits Per Transfer +#define AT91C_SPI_BITS_8 ((unsigned int) 0x0 << 4) // (SPI) 8 Bits Per transfer +#define AT91C_SPI_BITS_9 ((unsigned int) 0x1 << 4) // (SPI) 9 Bits Per transfer +#define AT91C_SPI_BITS_10 ((unsigned int) 0x2 << 4) // (SPI) 10 Bits Per transfer +#define AT91C_SPI_BITS_11 ((unsigned int) 0x3 << 4) // (SPI) 11 Bits Per transfer +#define AT91C_SPI_BITS_12 ((unsigned int) 0x4 << 4) // (SPI) 12 Bits Per transfer +#define AT91C_SPI_BITS_13 ((unsigned int) 0x5 << 4) // (SPI) 13 Bits Per transfer +#define AT91C_SPI_BITS_14 ((unsigned int) 0x6 << 4) // (SPI) 14 Bits Per transfer +#define AT91C_SPI_BITS_15 ((unsigned int) 0x7 << 4) // (SPI) 15 Bits Per transfer +#define AT91C_SPI_BITS_16 ((unsigned int) 0x8 << 4) // (SPI) 16 Bits Per transfer +#define AT91C_SPI_SCBR ((unsigned int) 0xFF << 8) // (SPI) Serial Clock Baud Rate +#define AT91C_SPI_DLYBS ((unsigned int) 0xFF << 16) // (SPI) Serial Clock Baud Rate +#define AT91C_SPI_DLYBCT ((unsigned int) 0xFF << 24) // (SPI) Delay Between Consecutive Transfers + +// ***************************************************************************** +// SOFTWARE API DEFINITION FOR Analog to Digital Convertor +// ***************************************************************************** +typedef struct _AT91S_ADC { + AT91_REG ADC_CR; // ADC Control Register + AT91_REG ADC_MR; // ADC Mode Register + AT91_REG Reserved0[2]; // + AT91_REG ADC_CHER; // ADC Channel Enable Register + AT91_REG ADC_CHDR; // ADC Channel Disable Register + AT91_REG ADC_CHSR; // ADC Channel Status Register + AT91_REG ADC_SR; // ADC Status Register + AT91_REG ADC_LCDR; // ADC Last Converted Data Register + AT91_REG ADC_IER; // ADC Interrupt Enable Register + AT91_REG ADC_IDR; // ADC Interrupt Disable Register + AT91_REG ADC_IMR; // ADC Interrupt Mask Register + AT91_REG ADC_CDR0; // ADC Channel Data Register 0 + AT91_REG ADC_CDR1; // ADC Channel Data Register 1 + AT91_REG ADC_CDR2; // ADC Channel Data Register 2 + AT91_REG ADC_CDR3; // ADC Channel Data Register 3 + AT91_REG ADC_CDR4; // ADC Channel Data Register 4 + AT91_REG ADC_CDR5; // ADC Channel Data Register 5 + AT91_REG ADC_CDR6; // ADC Channel Data Register 6 + AT91_REG ADC_CDR7; // ADC Channel Data Register 7 + AT91_REG Reserved1[44]; // + AT91_REG ADC_RPR; // Receive Pointer Register + AT91_REG ADC_RCR; // Receive Counter Register + AT91_REG ADC_TPR; // Transmit Pointer Register + AT91_REG ADC_TCR; // Transmit Counter Register + AT91_REG ADC_RNPR; // Receive Next Pointer Register + AT91_REG ADC_RNCR; // Receive Next Counter Register + AT91_REG ADC_TNPR; // Transmit Next Pointer Register + AT91_REG ADC_TNCR; // Transmit Next Counter Register + AT91_REG ADC_PTCR; // PDC Transfer Control Register + AT91_REG ADC_PTSR; // PDC Transfer Status Register +} AT91S_ADC, *AT91PS_ADC; + +// -------- ADC_CR : (ADC Offset: 0x0) ADC Control Register -------- +#define AT91C_ADC_SWRST ((unsigned int) 0x1 << 0) // (ADC) Software Reset +#define AT91C_ADC_START ((unsigned int) 0x1 << 1) // (ADC) Start Conversion +// -------- ADC_MR : (ADC Offset: 0x4) ADC Mode Register -------- +#define AT91C_ADC_TRGEN ((unsigned int) 0x1 << 0) // (ADC) Trigger Enable +#define AT91C_ADC_TRGEN_DIS ((unsigned int) 0x0) // (ADC) Hradware triggers are disabled. Starting a conversion is only possible by software +#define AT91C_ADC_TRGEN_EN ((unsigned int) 0x1) // (ADC) Hardware trigger selected by TRGSEL field is enabled. +#define AT91C_ADC_TRGSEL ((unsigned int) 0x7 << 1) // (ADC) Trigger Selection +#define AT91C_ADC_TRGSEL_TIOA0 ((unsigned int) 0x0 << 1) // (ADC) Selected TRGSEL = TIAO0 +#define AT91C_ADC_TRGSEL_TIOA1 ((unsigned int) 0x1 << 1) // (ADC) Selected TRGSEL = TIAO1 +#define AT91C_ADC_TRGSEL_TIOA2 ((unsigned int) 0x2 << 1) // (ADC) Selected TRGSEL = TIAO2 +#define AT91C_ADC_TRGSEL_TIOA3 ((unsigned int) 0x3 << 1) // (ADC) Selected TRGSEL = TIAO3 +#define AT91C_ADC_TRGSEL_TIOA4 ((unsigned int) 0x4 << 1) // (ADC) Selected TRGSEL = TIAO4 +#define AT91C_ADC_TRGSEL_TIOA5 ((unsigned int) 0x5 << 1) // (ADC) Selected TRGSEL = TIAO5 +#define AT91C_ADC_TRGSEL_EXT ((unsigned int) 0x6 << 1) // (ADC) Selected TRGSEL = External Trigger +#define AT91C_ADC_LOWRES ((unsigned int) 0x1 << 4) // (ADC) Resolution. +#define AT91C_ADC_LOWRES_10_BIT ((unsigned int) 0x0 << 4) // (ADC) 10-bit resolution +#define AT91C_ADC_LOWRES_8_BIT ((unsigned int) 0x1 << 4) // (ADC) 8-bit resolution +#define AT91C_ADC_SLEEP ((unsigned int) 0x1 << 5) // (ADC) Sleep Mode +#define AT91C_ADC_SLEEP_NORMAL_MODE ((unsigned int) 0x0 << 5) // (ADC) Normal Mode +#define AT91C_ADC_SLEEP_MODE ((unsigned int) 0x1 << 5) // (ADC) Sleep Mode +#define AT91C_ADC_PRESCAL ((unsigned int) 0x3F << 8) // (ADC) Prescaler rate selection +#define AT91C_ADC_STARTUP ((unsigned int) 0x1F << 16) // (ADC) Startup Time +#define AT91C_ADC_SHTIM ((unsigned int) 0xF << 24) // (ADC) Sample & Hold Time +// -------- ADC_CHER : (ADC Offset: 0x10) ADC Channel Enable Register -------- +#define AT91C_ADC_CH0 ((unsigned int) 0x1 << 0) // (ADC) Channel 0 +#define AT91C_ADC_CH1 ((unsigned int) 0x1 << 1) // (ADC) Channel 1 +#define AT91C_ADC_CH2 ((unsigned int) 0x1 << 2) // (ADC) Channel 2 +#define AT91C_ADC_CH3 ((unsigned int) 0x1 << 3) // (ADC) Channel 3 +#define AT91C_ADC_CH4 ((unsigned int) 0x1 << 4) // (ADC) Channel 4 +#define AT91C_ADC_CH5 ((unsigned int) 0x1 << 5) // (ADC) Channel 5 +#define AT91C_ADC_CH6 ((unsigned int) 0x1 << 6) // (ADC) Channel 6 +#define AT91C_ADC_CH7 ((unsigned int) 0x1 << 7) // (ADC) Channel 7 +// -------- ADC_CHDR : (ADC Offset: 0x14) ADC Channel Disable Register -------- +// -------- ADC_CHSR : (ADC Offset: 0x18) ADC Channel Status Register -------- +// -------- ADC_SR : (ADC Offset: 0x1c) ADC Status Register -------- +#define AT91C_ADC_EOC0 ((unsigned int) 0x1 << 0) // (ADC) End of Conversion +#define AT91C_ADC_EOC1 ((unsigned int) 0x1 << 1) // (ADC) End of Conversion +#define AT91C_ADC_EOC2 ((unsigned int) 0x1 << 2) // (ADC) End of Conversion +#define AT91C_ADC_EOC3 ((unsigned int) 0x1 << 3) // (ADC) End of Conversion +#define AT91C_ADC_EOC4 ((unsigned int) 0x1 << 4) // (ADC) End of Conversion +#define AT91C_ADC_EOC5 ((unsigned int) 0x1 << 5) // (ADC) End of Conversion +#define AT91C_ADC_EOC6 ((unsigned int) 0x1 << 6) // (ADC) End of Conversion +#define AT91C_ADC_EOC7 ((unsigned int) 0x1 << 7) // (ADC) End of Conversion +#define AT91C_ADC_OVRE0 ((unsigned int) 0x1 << 8) // (ADC) Overrun Error +#define AT91C_ADC_OVRE1 ((unsigned int) 0x1 << 9) // (ADC) Overrun Error +#define AT91C_ADC_OVRE2 ((unsigned int) 0x1 << 10) // (ADC) Overrun Error +#define AT91C_ADC_OVRE3 ((unsigned int) 0x1 << 11) // (ADC) Overrun Error +#define AT91C_ADC_OVRE4 ((unsigned int) 0x1 << 12) // (ADC) Overrun Error +#define AT91C_ADC_OVRE5 ((unsigned int) 0x1 << 13) // (ADC) Overrun Error +#define AT91C_ADC_OVRE6 ((unsigned int) 0x1 << 14) // (ADC) Overrun Error +#define AT91C_ADC_OVRE7 ((unsigned int) 0x1 << 15) // (ADC) Overrun Error +#define AT91C_ADC_DRDY ((unsigned int) 0x1 << 16) // (ADC) Data Ready +#define AT91C_ADC_GOVRE ((unsigned int) 0x1 << 17) // (ADC) General Overrun +#define AT91C_ADC_ENDRX ((unsigned int) 0x1 << 18) // (ADC) End of Receiver Transfer +#define AT91C_ADC_RXBUFF ((unsigned int) 0x1 << 19) // (ADC) RXBUFF Interrupt +// -------- ADC_LCDR : (ADC Offset: 0x20) ADC Last Converted Data Register -------- +#define AT91C_ADC_LDATA ((unsigned int) 0x3FF << 0) // (ADC) Last Data Converted +// -------- ADC_IER : (ADC Offset: 0x24) ADC Interrupt Enable Register -------- +// -------- ADC_IDR : (ADC Offset: 0x28) ADC Interrupt Disable Register -------- +// -------- ADC_IMR : (ADC Offset: 0x2c) ADC Interrupt Mask Register -------- +// -------- ADC_CDR0 : (ADC Offset: 0x30) ADC Channel Data Register 0 -------- +#define AT91C_ADC_DATA ((unsigned int) 0x3FF << 0) // (ADC) Converted Data +// -------- ADC_CDR1 : (ADC Offset: 0x34) ADC Channel Data Register 1 -------- +// -------- ADC_CDR2 : (ADC Offset: 0x38) ADC Channel Data Register 2 -------- +// -------- ADC_CDR3 : (ADC Offset: 0x3c) ADC Channel Data Register 3 -------- +// -------- ADC_CDR4 : (ADC Offset: 0x40) ADC Channel Data Register 4 -------- +// -------- ADC_CDR5 : (ADC Offset: 0x44) ADC Channel Data Register 5 -------- +// -------- ADC_CDR6 : (ADC Offset: 0x48) ADC Channel Data Register 6 -------- +// -------- ADC_CDR7 : (ADC Offset: 0x4c) ADC Channel Data Register 7 -------- + +// ***************************************************************************** +// SOFTWARE API DEFINITION FOR Synchronous Serial Controller Interface +// ***************************************************************************** +typedef struct _AT91S_SSC { + AT91_REG SSC_CR; // Control Register + AT91_REG SSC_CMR; // Clock Mode Register + AT91_REG Reserved0[2]; // + AT91_REG SSC_RCMR; // Receive Clock ModeRegister + AT91_REG SSC_RFMR; // Receive Frame Mode Register + AT91_REG SSC_TCMR; // Transmit Clock Mode Register + AT91_REG SSC_TFMR; // Transmit Frame Mode Register + AT91_REG SSC_RHR; // Receive Holding Register + AT91_REG SSC_THR; // Transmit Holding Register + AT91_REG Reserved1[2]; // + AT91_REG SSC_RSHR; // Receive Sync Holding Register + AT91_REG SSC_TSHR; // Transmit Sync Holding Register + AT91_REG Reserved2[2]; // + AT91_REG SSC_SR; // Status Register + AT91_REG SSC_IER; // Interrupt Enable Register + AT91_REG SSC_IDR; // Interrupt Disable Register + AT91_REG SSC_IMR; // Interrupt Mask Register + AT91_REG Reserved3[44]; // + AT91_REG SSC_RPR; // Receive Pointer Register + AT91_REG SSC_RCR; // Receive Counter Register + AT91_REG SSC_TPR; // Transmit Pointer Register + AT91_REG SSC_TCR; // Transmit Counter Register + AT91_REG SSC_RNPR; // Receive Next Pointer Register + AT91_REG SSC_RNCR; // Receive Next Counter Register + AT91_REG SSC_TNPR; // Transmit Next Pointer Register + AT91_REG SSC_TNCR; // Transmit Next Counter Register + AT91_REG SSC_PTCR; // PDC Transfer Control Register + AT91_REG SSC_PTSR; // PDC Transfer Status Register +} AT91S_SSC, *AT91PS_SSC; + +// -------- SSC_CR : (SSC Offset: 0x0) SSC Control Register -------- +#define AT91C_SSC_RXEN ((unsigned int) 0x1 << 0) // (SSC) Receive Enable +#define AT91C_SSC_RXDIS ((unsigned int) 0x1 << 1) // (SSC) Receive Disable +#define AT91C_SSC_TXEN ((unsigned int) 0x1 << 8) // (SSC) Transmit Enable +#define AT91C_SSC_TXDIS ((unsigned int) 0x1 << 9) // (SSC) Transmit Disable +#define AT91C_SSC_SWRST ((unsigned int) 0x1 << 15) // (SSC) Software Reset +// -------- SSC_RCMR : (SSC Offset: 0x10) SSC Receive Clock Mode Register -------- +#define AT91C_SSC_CKS ((unsigned int) 0x3 << 0) // (SSC) Receive/Transmit Clock Selection +#define AT91C_SSC_CKS_DIV ((unsigned int) 0x0) // (SSC) Divided Clock +#define AT91C_SSC_CKS_TK ((unsigned int) 0x1) // (SSC) TK Clock signal +#define AT91C_SSC_CKS_RK ((unsigned int) 0x2) // (SSC) RK pin +#define AT91C_SSC_CKO ((unsigned int) 0x7 << 2) // (SSC) Receive/Transmit Clock Output Mode Selection +#define AT91C_SSC_CKO_NONE ((unsigned int) 0x0 << 2) // (SSC) Receive/Transmit Clock Output Mode: None RK pin: Input-only +#define AT91C_SSC_CKO_CONTINOUS ((unsigned int) 0x1 << 2) // (SSC) Continuous Receive/Transmit Clock RK pin: Output +#define AT91C_SSC_CKO_DATA_TX ((unsigned int) 0x2 << 2) // (SSC) Receive/Transmit Clock only during data transfers RK pin: Output +#define AT91C_SSC_CKI ((unsigned int) 0x1 << 5) // (SSC) Receive/Transmit Clock Inversion +#define AT91C_SSC_START ((unsigned int) 0xF << 8) // (SSC) Receive/Transmit Start Selection +#define AT91C_SSC_START_CONTINOUS ((unsigned int) 0x0 << 8) // (SSC) Continuous, as soon as the receiver is enabled, and immediately after the end of transfer of the previous data. +#define AT91C_SSC_START_TX ((unsigned int) 0x1 << 8) // (SSC) Transmit/Receive start +#define AT91C_SSC_START_LOW_RF ((unsigned int) 0x2 << 8) // (SSC) Detection of a low level on RF input +#define AT91C_SSC_START_HIGH_RF ((unsigned int) 0x3 << 8) // (SSC) Detection of a high level on RF input +#define AT91C_SSC_START_FALL_RF ((unsigned int) 0x4 << 8) // (SSC) Detection of a falling edge on RF input +#define AT91C_SSC_START_RISE_RF ((unsigned int) 0x5 << 8) // (SSC) Detection of a rising edge on RF input +#define AT91C_SSC_START_LEVEL_RF ((unsigned int) 0x6 << 8) // (SSC) Detection of any level change on RF input +#define AT91C_SSC_START_EDGE_RF ((unsigned int) 0x7 << 8) // (SSC) Detection of any edge on RF input +#define AT91C_SSC_START_0 ((unsigned int) 0x8 << 8) // (SSC) Compare 0 +#define AT91C_SSC_STTDLY ((unsigned int) 0xFF << 16) // (SSC) Receive/Transmit Start Delay +#define AT91C_SSC_PERIOD ((unsigned int) 0xFF << 24) // (SSC) Receive/Transmit Period Divider Selection +// -------- SSC_RFMR : (SSC Offset: 0x14) SSC Receive Frame Mode Register -------- +#define AT91C_SSC_DATLEN ((unsigned int) 0x1F << 0) // (SSC) Data Length +#define AT91C_SSC_LOOP ((unsigned int) 0x1 << 5) // (SSC) Loop Mode +#define AT91C_SSC_MSBF ((unsigned int) 0x1 << 7) // (SSC) Most Significant Bit First +#define AT91C_SSC_DATNB ((unsigned int) 0xF << 8) // (SSC) Data Number per Frame +#define AT91C_SSC_FSLEN ((unsigned int) 0xF << 16) // (SSC) Receive/Transmit Frame Sync length +#define AT91C_SSC_FSOS ((unsigned int) 0x7 << 20) // (SSC) Receive/Transmit Frame Sync Output Selection +#define AT91C_SSC_FSOS_NONE ((unsigned int) 0x0 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: None RK pin Input-only +#define AT91C_SSC_FSOS_NEGATIVE ((unsigned int) 0x1 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Negative Pulse +#define AT91C_SSC_FSOS_POSITIVE ((unsigned int) 0x2 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Positive Pulse +#define AT91C_SSC_FSOS_LOW ((unsigned int) 0x3 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Driver Low during data transfer +#define AT91C_SSC_FSOS_HIGH ((unsigned int) 0x4 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Driver High during data transfer +#define AT91C_SSC_FSOS_TOGGLE ((unsigned int) 0x5 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Toggling at each start of data transfer +#define AT91C_SSC_FSEDGE ((unsigned int) 0x1 << 24) // (SSC) Frame Sync Edge Detection +// -------- SSC_TCMR : (SSC Offset: 0x18) SSC Transmit Clock Mode Register -------- +// -------- SSC_TFMR : (SSC Offset: 0x1c) SSC Transmit Frame Mode Register -------- +#define AT91C_SSC_DATDEF ((unsigned int) 0x1 << 5) // (SSC) Data Default Value +#define AT91C_SSC_FSDEN ((unsigned int) 0x1 << 23) // (SSC) Frame Sync Data Enable +// -------- SSC_SR : (SSC Offset: 0x40) SSC Status Register -------- +#define AT91C_SSC_TXRDY ((unsigned int) 0x1 << 0) // (SSC) Transmit Ready +#define AT91C_SSC_TXEMPTY ((unsigned int) 0x1 << 1) // (SSC) Transmit Empty +#define AT91C_SSC_ENDTX ((unsigned int) 0x1 << 2) // (SSC) End Of Transmission +#define AT91C_SSC_TXBUFE ((unsigned int) 0x1 << 3) // (SSC) Transmit Buffer Empty +#define AT91C_SSC_RXRDY ((unsigned int) 0x1 << 4) // (SSC) Receive Ready +#define AT91C_SSC_OVRUN ((unsigned int) 0x1 << 5) // (SSC) Receive Overrun +#define AT91C_SSC_ENDRX ((unsigned int) 0x1 << 6) // (SSC) End of Reception +#define AT91C_SSC_RXBUFF ((unsigned int) 0x1 << 7) // (SSC) Receive Buffer Full +#define AT91C_SSC_TXSYN ((unsigned int) 0x1 << 10) // (SSC) Transmit Sync +#define AT91C_SSC_RXSYN ((unsigned int) 0x1 << 11) // (SSC) Receive Sync +#define AT91C_SSC_TXENA ((unsigned int) 0x1 << 16) // (SSC) Transmit Enable +#define AT91C_SSC_RXENA ((unsigned int) 0x1 << 17) // (SSC) Receive Enable +// -------- SSC_IER : (SSC Offset: 0x44) SSC Interrupt Enable Register -------- +// -------- SSC_IDR : (SSC Offset: 0x48) SSC Interrupt Disable Register -------- +// -------- SSC_IMR : (SSC Offset: 0x4c) SSC Interrupt Mask Register -------- + +// ***************************************************************************** +// SOFTWARE API DEFINITION FOR Usart +// ***************************************************************************** +typedef struct _AT91S_USART { + AT91_REG US_CR; // Control Register + AT91_REG US_MR; // Mode Register + AT91_REG US_IER; // Interrupt Enable Register + AT91_REG US_IDR; // Interrupt Disable Register + AT91_REG US_IMR; // Interrupt Mask Register + AT91_REG US_CSR; // Channel Status Register + AT91_REG US_RHR; // Receiver Holding Register + AT91_REG US_THR; // Transmitter Holding Register + AT91_REG US_BRGR; // Baud Rate Generator Register + AT91_REG US_RTOR; // Receiver Time-out Register + AT91_REG US_TTGR; // Transmitter Time-guard Register + AT91_REG Reserved0[5]; // + AT91_REG US_FIDI; // FI_DI_Ratio Register + AT91_REG US_NER; // Nb Errors Register + AT91_REG Reserved1[1]; // + AT91_REG US_IF; // IRDA_FILTER Register + AT91_REG Reserved2[44]; // + AT91_REG US_RPR; // Receive Pointer Register + AT91_REG US_RCR; // Receive Counter Register + AT91_REG US_TPR; // Transmit Pointer Register + AT91_REG US_TCR; // Transmit Counter Register + AT91_REG US_RNPR; // Receive Next Pointer Register + AT91_REG US_RNCR; // Receive Next Counter Register + AT91_REG US_TNPR; // Transmit Next Pointer Register + AT91_REG US_TNCR; // Transmit Next Counter Register + AT91_REG US_PTCR; // PDC Transfer Control Register + AT91_REG US_PTSR; // PDC Transfer Status Register +} AT91S_USART, *AT91PS_USART; + +// -------- US_CR : (USART Offset: 0x0) Debug Unit Control Register -------- +#define AT91C_US_STTBRK ((unsigned int) 0x1 << 9) // (USART) Start Break +#define AT91C_US_STPBRK ((unsigned int) 0x1 << 10) // (USART) Stop Break +#define AT91C_US_STTTO ((unsigned int) 0x1 << 11) // (USART) Start Time-out +#define AT91C_US_SENDA ((unsigned int) 0x1 << 12) // (USART) Send Address +#define AT91C_US_RSTIT ((unsigned int) 0x1 << 13) // (USART) Reset Iterations +#define AT91C_US_RSTNACK ((unsigned int) 0x1 << 14) // (USART) Reset Non Acknowledge +#define AT91C_US_RETTO ((unsigned int) 0x1 << 15) // (USART) Rearm Time-out +#define AT91C_US_DTREN ((unsigned int) 0x1 << 16) // (USART) Data Terminal ready Enable +#define AT91C_US_DTRDIS ((unsigned int) 0x1 << 17) // (USART) Data Terminal ready Disable +#define AT91C_US_RTSEN ((unsigned int) 0x1 << 18) // (USART) Request to Send enable +#define AT91C_US_RTSDIS ((unsigned int) 0x1 << 19) // (USART) Request to Send Disable +// -------- US_MR : (USART Offset: 0x4) Debug Unit Mode Register -------- +#define AT91C_US_USMODE ((unsigned int) 0xF << 0) // (USART) Usart mode +#define AT91C_US_USMODE_NORMAL ((unsigned int) 0x0) // (USART) Normal +#define AT91C_US_USMODE_RS485 ((unsigned int) 0x1) // (USART) RS485 +#define AT91C_US_USMODE_HWHSH ((unsigned int) 0x2) // (USART) Hardware Handshaking +#define AT91C_US_USMODE_MODEM ((unsigned int) 0x3) // (USART) Modem +#define AT91C_US_USMODE_ISO7816_0 ((unsigned int) 0x4) // (USART) ISO7816 protocol: T = 0 +#define AT91C_US_USMODE_ISO7816_1 ((unsigned int) 0x6) // (USART) ISO7816 protocol: T = 1 +#define AT91C_US_USMODE_IRDA ((unsigned int) 0x8) // (USART) IrDA +#define AT91C_US_USMODE_SWHSH ((unsigned int) 0xC) // (USART) Software Handshaking +#define AT91C_US_CLKS ((unsigned int) 0x3 << 4) // (USART) Clock Selection (Baud Rate generator Input Clock +#define AT91C_US_CLKS_CLOCK ((unsigned int) 0x0 << 4) // (USART) Clock +#define AT91C_US_CLKS_FDIV1 ((unsigned int) 0x1 << 4) // (USART) fdiv1 +#define AT91C_US_CLKS_SLOW ((unsigned int) 0x2 << 4) // (USART) slow_clock (ARM) +#define AT91C_US_CLKS_EXT ((unsigned int) 0x3 << 4) // (USART) External (SCK) +#define AT91C_US_CHRL ((unsigned int) 0x3 << 6) // (USART) Clock Selection (Baud Rate generator Input Clock +#define AT91C_US_CHRL_5_BITS ((unsigned int) 0x0 << 6) // (USART) Character Length: 5 bits +#define AT91C_US_CHRL_6_BITS ((unsigned int) 0x1 << 6) // (USART) Character Length: 6 bits +#define AT91C_US_CHRL_7_BITS ((unsigned int) 0x2 << 6) // (USART) Character Length: 7 bits +#define AT91C_US_CHRL_8_BITS ((unsigned int) 0x3 << 6) // (USART) Character Length: 8 bits +#define AT91C_US_SYNC ((unsigned int) 0x1 << 8) // (USART) Synchronous Mode Select +#define AT91C_US_NBSTOP ((unsigned int) 0x3 << 12) // (USART) Number of Stop bits +#define AT91C_US_NBSTOP_1_BIT ((unsigned int) 0x0 << 12) // (USART) 1 stop bit +#define AT91C_US_NBSTOP_15_BIT ((unsigned int) 0x1 << 12) // (USART) Asynchronous (SYNC=0) 2 stop bits Synchronous (SYNC=1) 2 stop bits +#define AT91C_US_NBSTOP_2_BIT ((unsigned int) 0x2 << 12) // (USART) 2 stop bits +#define AT91C_US_MSBF ((unsigned int) 0x1 << 16) // (USART) Bit Order +#define AT91C_US_MODE9 ((unsigned int) 0x1 << 17) // (USART) 9-bit Character length +#define AT91C_US_CKLO ((unsigned int) 0x1 << 18) // (USART) Clock Output Select +#define AT91C_US_OVER ((unsigned int) 0x1 << 19) // (USART) Over Sampling Mode +#define AT91C_US_INACK ((unsigned int) 0x1 << 20) // (USART) Inhibit Non Acknowledge +#define AT91C_US_DSNACK ((unsigned int) 0x1 << 21) // (USART) Disable Successive NACK +#define AT91C_US_MAX_ITER ((unsigned int) 0x1 << 24) // (USART) Number of Repetitions +#define AT91C_US_FILTER ((unsigned int) 0x1 << 28) // (USART) Receive Line Filter +// -------- US_IER : (USART Offset: 0x8) Debug Unit Interrupt Enable Register -------- +#define AT91C_US_RXBRK ((unsigned int) 0x1 << 2) // (USART) Break Received/End of Break +#define AT91C_US_TIMEOUT ((unsigned int) 0x1 << 8) // (USART) Receiver Time-out +#define AT91C_US_ITERATION ((unsigned int) 0x1 << 10) // (USART) Max number of Repetitions Reached +#define AT91C_US_NACK ((unsigned int) 0x1 << 13) // (USART) Non Acknowledge +#define AT91C_US_RIIC ((unsigned int) 0x1 << 16) // (USART) Ring INdicator Input Change Flag +#define AT91C_US_DSRIC ((unsigned int) 0x1 << 17) // (USART) Data Set Ready Input Change Flag +#define AT91C_US_DCDIC ((unsigned int) 0x1 << 18) // (USART) Data Carrier Flag +#define AT91C_US_CTSIC ((unsigned int) 0x1 << 19) // (USART) Clear To Send Input Change Flag +// -------- US_IDR : (USART Offset: 0xc) Debug Unit Interrupt Disable Register -------- +// -------- US_IMR : (USART Offset: 0x10) Debug Unit Interrupt Mask Register -------- +// -------- US_CSR : (USART Offset: 0x14) Debug Unit Channel Status Register -------- +#define AT91C_US_RI ((unsigned int) 0x1 << 20) // (USART) Image of RI Input +#define AT91C_US_DSR ((unsigned int) 0x1 << 21) // (USART) Image of DSR Input +#define AT91C_US_DCD ((unsigned int) 0x1 << 22) // (USART) Image of DCD Input +#define AT91C_US_CTS ((unsigned int) 0x1 << 23) // (USART) Image of CTS Input + +// ***************************************************************************** +// SOFTWARE API DEFINITION FOR Two-wire Interface +// ***************************************************************************** +typedef struct _AT91S_TWI { + AT91_REG TWI_CR; // Control Register + AT91_REG TWI_MMR; // Master Mode Register + AT91_REG Reserved0[1]; // + AT91_REG TWI_IADR; // Internal Address Register + AT91_REG TWI_CWGR; // Clock Waveform Generator Register + AT91_REG Reserved1[3]; // + AT91_REG TWI_SR; // Status Register + AT91_REG TWI_IER; // Interrupt Enable Register + AT91_REG TWI_IDR; // Interrupt Disable Register + AT91_REG TWI_IMR; // Interrupt Mask Register + AT91_REG TWI_RHR; // Receive Holding Register + AT91_REG TWI_THR; // Transmit Holding Register +} AT91S_TWI, *AT91PS_TWI; + +// -------- TWI_CR : (TWI Offset: 0x0) TWI Control Register -------- +#define AT91C_TWI_START ((unsigned int) 0x1 << 0) // (TWI) Send a START Condition +#define AT91C_TWI_STOP ((unsigned int) 0x1 << 1) // (TWI) Send a STOP Condition +#define AT91C_TWI_MSEN ((unsigned int) 0x1 << 2) // (TWI) TWI Master Transfer Enabled +#define AT91C_TWI_MSDIS ((unsigned int) 0x1 << 3) // (TWI) TWI Master Transfer Disabled +#define AT91C_TWI_SWRST ((unsigned int) 0x1 << 7) // (TWI) Software Reset +// -------- TWI_MMR : (TWI Offset: 0x4) TWI Master Mode Register -------- +#define AT91C_TWI_IADRSZ ((unsigned int) 0x3 << 8) // (TWI) Internal Device Address Size +#define AT91C_TWI_IADRSZ_NO ((unsigned int) 0x0 << 8) // (TWI) No internal device address +#define AT91C_TWI_IADRSZ_1_BYTE ((unsigned int) 0x1 << 8) // (TWI) One-byte internal device address +#define AT91C_TWI_IADRSZ_2_BYTE ((unsigned int) 0x2 << 8) // (TWI) Two-byte internal device address +#define AT91C_TWI_IADRSZ_3_BYTE ((unsigned int) 0x3 << 8) // (TWI) Three-byte internal device address +#define AT91C_TWI_MREAD ((unsigned int) 0x1 << 12) // (TWI) Master Read Direction +#define AT91C_TWI_DADR ((unsigned int) 0x7F << 16) // (TWI) Device Address +// -------- TWI_CWGR : (TWI Offset: 0x10) TWI Clock Waveform Generator Register -------- +#define AT91C_TWI_CLDIV ((unsigned int) 0xFF << 0) // (TWI) Clock Low Divider +#define AT91C_TWI_CHDIV ((unsigned int) 0xFF << 8) // (TWI) Clock High Divider +#define AT91C_TWI_CKDIV ((unsigned int) 0x7 << 16) // (TWI) Clock Divider +// -------- TWI_SR : (TWI Offset: 0x20) TWI Status Register -------- +#define AT91C_TWI_TXCOMP ((unsigned int) 0x1 << 0) // (TWI) Transmission Completed +#define AT91C_TWI_RXRDY ((unsigned int) 0x1 << 1) // (TWI) Receive holding register ReaDY +#define AT91C_TWI_TXRDY ((unsigned int) 0x1 << 2) // (TWI) Transmit holding register ReaDY +#define AT91C_TWI_OVRE ((unsigned int) 0x1 << 6) // (TWI) Overrun Error +#define AT91C_TWI_UNRE ((unsigned int) 0x1 << 7) // (TWI) Underrun Error +#define AT91C_TWI_NACK ((unsigned int) 0x1 << 8) // (TWI) Not Acknowledged +// -------- TWI_IER : (TWI Offset: 0x24) TWI Interrupt Enable Register -------- +// -------- TWI_IDR : (TWI Offset: 0x28) TWI Interrupt Disable Register -------- +// -------- TWI_IMR : (TWI Offset: 0x2c) TWI Interrupt Mask Register -------- + +// ***************************************************************************** +// SOFTWARE API DEFINITION FOR Timer Counter Channel Interface +// ***************************************************************************** +typedef struct _AT91S_TC { + AT91_REG TC_CCR; // Channel Control Register + AT91_REG TC_CMR; // Channel Mode Register (Capture Mode / Waveform Mode) + AT91_REG Reserved0[2]; // + AT91_REG TC_CV; // Counter Value + AT91_REG TC_RA; // Register A + AT91_REG TC_RB; // Register B + AT91_REG TC_RC; // Register C + AT91_REG TC_SR; // Status Register + AT91_REG TC_IER; // Interrupt Enable Register + AT91_REG TC_IDR; // Interrupt Disable Register + AT91_REG TC_IMR; // Interrupt Mask Register +} AT91S_TC, *AT91PS_TC; + +// -------- TC_CCR : (TC Offset: 0x0) TC Channel Control Register -------- +#define AT91C_TC_CLKEN ((unsigned int) 0x1 << 0) // (TC) Counter Clock Enable Command +#define AT91C_TC_CLKDIS ((unsigned int) 0x1 << 1) // (TC) Counter Clock Disable Command +#define AT91C_TC_SWTRG ((unsigned int) 0x1 << 2) // (TC) Software Trigger Command +// -------- TC_CMR : (TC Offset: 0x4) TC Channel Mode Register: Capture Mode / Waveform Mode -------- +#define AT91C_TC_CLKS ((unsigned int) 0x7 << 0) // (TC) Clock Selection +#define AT91C_TC_CLKS_TIMER_DIV1_CLOCK ((unsigned int) 0x0) // (TC) Clock selected: TIMER_DIV1_CLOCK +#define AT91C_TC_CLKS_TIMER_DIV2_CLOCK ((unsigned int) 0x1) // (TC) Clock selected: TIMER_DIV2_CLOCK +#define AT91C_TC_CLKS_TIMER_DIV3_CLOCK ((unsigned int) 0x2) // (TC) Clock selected: TIMER_DIV3_CLOCK +#define AT91C_TC_CLKS_TIMER_DIV4_CLOCK ((unsigned int) 0x3) // (TC) Clock selected: TIMER_DIV4_CLOCK +#define AT91C_TC_CLKS_TIMER_DIV5_CLOCK ((unsigned int) 0x4) // (TC) Clock selected: TIMER_DIV5_CLOCK +#define AT91C_TC_CLKS_XC0 ((unsigned int) 0x5) // (TC) Clock selected: XC0 +#define AT91C_TC_CLKS_XC1 ((unsigned int) 0x6) // (TC) Clock selected: XC1 +#define AT91C_TC_CLKS_XC2 ((unsigned int) 0x7) // (TC) Clock selected: XC2 +#define AT91C_TC_CLKI ((unsigned int) 0x1 << 3) // (TC) Clock Invert +#define AT91C_TC_BURST ((unsigned int) 0x3 << 4) // (TC) Burst Signal Selection +#define AT91C_TC_BURST_NONE ((unsigned int) 0x0 << 4) // (TC) The clock is not gated by an external signal +#define AT91C_TC_BURST_XC0 ((unsigned int) 0x1 << 4) // (TC) XC0 is ANDed with the selected clock +#define AT91C_TC_BURST_XC1 ((unsigned int) 0x2 << 4) // (TC) XC1 is ANDed with the selected clock +#define AT91C_TC_BURST_XC2 ((unsigned int) 0x3 << 4) // (TC) XC2 is ANDed with the selected clock +#define AT91C_TC_CPCSTOP ((unsigned int) 0x1 << 6) // (TC) Counter Clock Stopped with RC Compare +#define AT91C_TC_LDBSTOP ((unsigned int) 0x1 << 6) // (TC) Counter Clock Stopped with RB Loading +#define AT91C_TC_CPCDIS ((unsigned int) 0x1 << 7) // (TC) Counter Clock Disable with RC Compare +#define AT91C_TC_LDBDIS ((unsigned int) 0x1 << 7) // (TC) Counter Clock Disabled with RB Loading +#define AT91C_TC_ETRGEDG ((unsigned int) 0x3 << 8) // (TC) External Trigger Edge Selection +#define AT91C_TC_ETRGEDG_NONE ((unsigned int) 0x0 << 8) // (TC) Edge: None +#define AT91C_TC_ETRGEDG_RISING ((unsigned int) 0x1 << 8) // (TC) Edge: rising edge +#define AT91C_TC_ETRGEDG_FALLING ((unsigned int) 0x2 << 8) // (TC) Edge: falling edge +#define AT91C_TC_ETRGEDG_BOTH ((unsigned int) 0x3 << 8) // (TC) Edge: each edge +#define AT91C_TC_EEVTEDG ((unsigned int) 0x3 << 8) // (TC) External Event Edge Selection +#define AT91C_TC_EEVTEDG_NONE ((unsigned int) 0x0 << 8) // (TC) Edge: None +#define AT91C_TC_EEVTEDG_RISING ((unsigned int) 0x1 << 8) // (TC) Edge: rising edge +#define AT91C_TC_EEVTEDG_FALLING ((unsigned int) 0x2 << 8) // (TC) Edge: falling edge +#define AT91C_TC_EEVTEDG_BOTH ((unsigned int) 0x3 << 8) // (TC) Edge: each edge +#define AT91C_TC_EEVT ((unsigned int) 0x3 << 10) // (TC) External Event Selection +#define AT91C_TC_EEVT_TIOB ((unsigned int) 0x0 << 10) // (TC) Signal selected as external event: TIOB TIOB direction: input +#define AT91C_TC_EEVT_XC0 ((unsigned int) 0x1 << 10) // (TC) Signal selected as external event: XC0 TIOB direction: output +#define AT91C_TC_EEVT_XC1 ((unsigned int) 0x2 << 10) // (TC) Signal selected as external event: XC1 TIOB direction: output +#define AT91C_TC_EEVT_XC2 ((unsigned int) 0x3 << 10) // (TC) Signal selected as external event: XC2 TIOB direction: output +#define AT91C_TC_ABETRG ((unsigned int) 0x1 << 10) // (TC) TIOA or TIOB External Trigger Selection +#define AT91C_TC_ENETRG ((unsigned int) 0x1 << 12) // (TC) External Event Trigger enable +#define AT91C_TC_WAVESEL ((unsigned int) 0x3 << 13) // (TC) Waveform Selection +#define AT91C_TC_WAVESEL_UP ((unsigned int) 0x0 << 13) // (TC) UP mode without atomatic trigger on RC Compare +#define AT91C_TC_WAVESEL_UPDOWN ((unsigned int) 0x1 << 13) // (TC) UPDOWN mode without automatic trigger on RC Compare +#define AT91C_TC_WAVESEL_UP_AUTO ((unsigned int) 0x2 << 13) // (TC) UP mode with automatic trigger on RC Compare +#define AT91C_TC_WAVESEL_UPDOWN_AUTO ((unsigned int) 0x3 << 13) // (TC) UPDOWN mode with automatic trigger on RC Compare +#define AT91C_TC_CPCTRG ((unsigned int) 0x1 << 14) // (TC) RC Compare Trigger Enable +#define AT91C_TC_WAVE ((unsigned int) 0x1 << 15) // (TC) +#define AT91C_TC_ACPA ((unsigned int) 0x3 << 16) // (TC) RA Compare Effect on TIOA +#define AT91C_TC_ACPA_NONE ((unsigned int) 0x0 << 16) // (TC) Effect: none +#define AT91C_TC_ACPA_SET ((unsigned int) 0x1 << 16) // (TC) Effect: set +#define AT91C_TC_ACPA_CLEAR ((unsigned int) 0x2 << 16) // (TC) Effect: clear +#define AT91C_TC_ACPA_TOGGLE ((unsigned int) 0x3 << 16) // (TC) Effect: toggle +#define AT91C_TC_LDRA ((unsigned int) 0x3 << 16) // (TC) RA Loading Selection +#define AT91C_TC_LDRA_NONE ((unsigned int) 0x0 << 16) // (TC) Edge: None +#define AT91C_TC_LDRA_RISING ((unsigned int) 0x1 << 16) // (TC) Edge: rising edge of TIOA +#define AT91C_TC_LDRA_FALLING ((unsigned int) 0x2 << 16) // (TC) Edge: falling edge of TIOA +#define AT91C_TC_LDRA_BOTH ((unsigned int) 0x3 << 16) // (TC) Edge: each edge of TIOA +#define AT91C_TC_ACPC ((unsigned int) 0x3 << 18) // (TC) RC Compare Effect on TIOA +#define AT91C_TC_ACPC_NONE ((unsigned int) 0x0 << 18) // (TC) Effect: none +#define AT91C_TC_ACPC_SET ((unsigned int) 0x1 << 18) // (TC) Effect: set +#define AT91C_TC_ACPC_CLEAR ((unsigned int) 0x2 << 18) // (TC) Effect: clear +#define AT91C_TC_ACPC_TOGGLE ((unsigned int) 0x3 << 18) // (TC) Effect: toggle +#define AT91C_TC_LDRB ((unsigned int) 0x3 << 18) // (TC) RB Loading Selection +#define AT91C_TC_LDRB_NONE ((unsigned int) 0x0 << 18) // (TC) Edge: None +#define AT91C_TC_LDRB_RISING ((unsigned int) 0x1 << 18) // (TC) Edge: rising edge of TIOA +#define AT91C_TC_LDRB_FALLING ((unsigned int) 0x2 << 18) // (TC) Edge: falling edge of TIOA +#define AT91C_TC_LDRB_BOTH ((unsigned int) 0x3 << 18) // (TC) Edge: each edge of TIOA +#define AT91C_TC_AEEVT ((unsigned int) 0x3 << 20) // (TC) External Event Effect on TIOA +#define AT91C_TC_AEEVT_NONE ((unsigned int) 0x0 << 20) // (TC) Effect: none +#define AT91C_TC_AEEVT_SET ((unsigned int) 0x1 << 20) // (TC) Effect: set +#define AT91C_TC_AEEVT_CLEAR ((unsigned int) 0x2 << 20) // (TC) Effect: clear +#define AT91C_TC_AEEVT_TOGGLE ((unsigned int) 0x3 << 20) // (TC) Effect: toggle +#define AT91C_TC_ASWTRG ((unsigned int) 0x3 << 22) // (TC) Software Trigger Effect on TIOA +#define AT91C_TC_ASWTRG_NONE ((unsigned int) 0x0 << 22) // (TC) Effect: none +#define AT91C_TC_ASWTRG_SET ((unsigned int) 0x1 << 22) // (TC) Effect: set +#define AT91C_TC_ASWTRG_CLEAR ((unsigned int) 0x2 << 22) // (TC) Effect: clear +#define AT91C_TC_ASWTRG_TOGGLE ((unsigned int) 0x3 << 22) // (TC) Effect: toggle +#define AT91C_TC_BCPB ((unsigned int) 0x3 << 24) // (TC) RB Compare Effect on TIOB +#define AT91C_TC_BCPB_NONE ((unsigned int) 0x0 << 24) // (TC) Effect: none +#define AT91C_TC_BCPB_SET ((unsigned int) 0x1 << 24) // (TC) Effect: set +#define AT91C_TC_BCPB_CLEAR ((unsigned int) 0x2 << 24) // (TC) Effect: clear +#define AT91C_TC_BCPB_TOGGLE ((unsigned int) 0x3 << 24) // (TC) Effect: toggle +#define AT91C_TC_BCPC ((unsigned int) 0x3 << 26) // (TC) RC Compare Effect on TIOB +#define AT91C_TC_BCPC_NONE ((unsigned int) 0x0 << 26) // (TC) Effect: none +#define AT91C_TC_BCPC_SET ((unsigned int) 0x1 << 26) // (TC) Effect: set +#define AT91C_TC_BCPC_CLEAR ((unsigned int) 0x2 << 26) // (TC) Effect: clear +#define AT91C_TC_BCPC_TOGGLE ((unsigned int) 0x3 << 26) // (TC) Effect: toggle +#define AT91C_TC_BEEVT ((unsigned int) 0x3 << 28) // (TC) External Event Effect on TIOB +#define AT91C_TC_BEEVT_NONE ((unsigned int) 0x0 << 28) // (TC) Effect: none +#define AT91C_TC_BEEVT_SET ((unsigned int) 0x1 << 28) // (TC) Effect: set +#define AT91C_TC_BEEVT_CLEAR ((unsigned int) 0x2 << 28) // (TC) Effect: clear +#define AT91C_TC_BEEVT_TOGGLE ((unsigned int) 0x3 << 28) // (TC) Effect: toggle +#define AT91C_TC_BSWTRG ((unsigned int) 0x3 << 30) // (TC) Software Trigger Effect on TIOB +#define AT91C_TC_BSWTRG_NONE ((unsigned int) 0x0 << 30) // (TC) Effect: none +#define AT91C_TC_BSWTRG_SET ((unsigned int) 0x1 << 30) // (TC) Effect: set +#define AT91C_TC_BSWTRG_CLEAR ((unsigned int) 0x2 << 30) // (TC) Effect: clear +#define AT91C_TC_BSWTRG_TOGGLE ((unsigned int) 0x3 << 30) // (TC) Effect: toggle +// -------- TC_SR : (TC Offset: 0x20) TC Channel Status Register -------- +#define AT91C_TC_COVFS ((unsigned int) 0x1 << 0) // (TC) Counter Overflow +#define AT91C_TC_LOVRS ((unsigned int) 0x1 << 1) // (TC) Load Overrun +#define AT91C_TC_CPAS ((unsigned int) 0x1 << 2) // (TC) RA Compare +#define AT91C_TC_CPBS ((unsigned int) 0x1 << 3) // (TC) RB Compare +#define AT91C_TC_CPCS ((unsigned int) 0x1 << 4) // (TC) RC Compare +#define AT91C_TC_LDRAS ((unsigned int) 0x1 << 5) // (TC) RA Loading +#define AT91C_TC_LDRBS ((unsigned int) 0x1 << 6) // (TC) RB Loading +#define AT91C_TC_ETRGS ((unsigned int) 0x1 << 7) // (TC) External Trigger +#define AT91C_TC_CLKSTA ((unsigned int) 0x1 << 16) // (TC) Clock Enabling +#define AT91C_TC_MTIOA ((unsigned int) 0x1 << 17) // (TC) TIOA Mirror +#define AT91C_TC_MTIOB ((unsigned int) 0x1 << 18) // (TC) TIOA Mirror +// -------- TC_IER : (TC Offset: 0x24) TC Channel Interrupt Enable Register -------- +// -------- TC_IDR : (TC Offset: 0x28) TC Channel Interrupt Disable Register -------- +// -------- TC_IMR : (TC Offset: 0x2c) TC Channel Interrupt Mask Register -------- + +// ***************************************************************************** +// SOFTWARE API DEFINITION FOR Timer Counter Interface +// ***************************************************************************** +typedef struct _AT91S_TCB { + AT91S_TC TCB_TC0; // TC Channel 0 + AT91_REG Reserved0[4]; // + AT91S_TC TCB_TC1; // TC Channel 1 + AT91_REG Reserved1[4]; // + AT91S_TC TCB_TC2; // TC Channel 2 + AT91_REG Reserved2[4]; // + AT91_REG TCB_BCR; // TC Block Control Register + AT91_REG TCB_BMR; // TC Block Mode Register +} AT91S_TCB, *AT91PS_TCB; + +// -------- TCB_BCR : (TCB Offset: 0xc0) TC Block Control Register -------- +#define AT91C_TCB_SYNC ((unsigned int) 0x1 << 0) // (TCB) Synchro Command +// -------- TCB_BMR : (TCB Offset: 0xc4) TC Block Mode Register -------- +#define AT91C_TCB_TC0XC0S ((unsigned int) 0x3 << 0) // (TCB) External Clock Signal 0 Selection +#define AT91C_TCB_TC0XC0S_TCLK0 ((unsigned int) 0x0) // (TCB) TCLK0 connected to XC0 +#define AT91C_TCB_TC0XC0S_NONE ((unsigned int) 0x1) // (TCB) None signal connected to XC0 +#define AT91C_TCB_TC0XC0S_TIOA1 ((unsigned int) 0x2) // (TCB) TIOA1 connected to XC0 +#define AT91C_TCB_TC0XC0S_TIOA2 ((unsigned int) 0x3) // (TCB) TIOA2 connected to XC0 +#define AT91C_TCB_TC1XC1S ((unsigned int) 0x3 << 2) // (TCB) External Clock Signal 1 Selection +#define AT91C_TCB_TC1XC1S_TCLK1 ((unsigned int) 0x0 << 2) // (TCB) TCLK1 connected to XC1 +#define AT91C_TCB_TC1XC1S_NONE ((unsigned int) 0x1 << 2) // (TCB) None signal connected to XC1 +#define AT91C_TCB_TC1XC1S_TIOA0 ((unsigned int) 0x2 << 2) // (TCB) TIOA0 connected to XC1 +#define AT91C_TCB_TC1XC1S_TIOA2 ((unsigned int) 0x3 << 2) // (TCB) TIOA2 connected to XC1 +#define AT91C_TCB_TC2XC2S ((unsigned int) 0x3 << 4) // (TCB) External Clock Signal 2 Selection +#define AT91C_TCB_TC2XC2S_TCLK2 ((unsigned int) 0x0 << 4) // (TCB) TCLK2 connected to XC2 +#define AT91C_TCB_TC2XC2S_NONE ((unsigned int) 0x1 << 4) // (TCB) None signal connected to XC2 +#define AT91C_TCB_TC2XC2S_TIOA0 ((unsigned int) 0x2 << 4) // (TCB) TIOA0 connected to XC2 +#define AT91C_TCB_TC2XC2S_TIOA1 ((unsigned int) 0x3 << 4) // (TCB) TIOA2 connected to XC2 + +// ***************************************************************************** +// SOFTWARE API DEFINITION FOR PWMC Channel Interface +// ***************************************************************************** +typedef struct _AT91S_PWMC_CH { + AT91_REG PWMC_CMR; // Channel Mode Register + AT91_REG PWMC_CDTYR; // Channel Duty Cycle Register + AT91_REG PWMC_CPRDR; // Channel Period Register + AT91_REG PWMC_CCNTR; // Channel Counter Register + AT91_REG PWMC_CUPDR; // Channel Update Register + AT91_REG PWMC_Reserved[3]; // Reserved +} AT91S_PWMC_CH, *AT91PS_PWMC_CH; + +// -------- PWMC_CMR : (PWMC_CH Offset: 0x0) PWMC Channel Mode Register -------- +#define AT91C_PWMC_CPRE ((unsigned int) 0xF << 0) // (PWMC_CH) Channel Pre-scaler : PWMC_CLKx +#define AT91C_PWMC_CPRE_MCK ((unsigned int) 0x0) // (PWMC_CH) +#define AT91C_PWMC_CPRE_MCKA ((unsigned int) 0xB) // (PWMC_CH) +#define AT91C_PWMC_CPRE_MCKB ((unsigned int) 0xC) // (PWMC_CH) +#define AT91C_PWMC_CALG ((unsigned int) 0x1 << 8) // (PWMC_CH) Channel Alignment +#define AT91C_PWMC_CPOL ((unsigned int) 0x1 << 9) // (PWMC_CH) Channel Polarity +#define AT91C_PWMC_CPD ((unsigned int) 0x1 << 10) // (PWMC_CH) Channel Update Period +// -------- PWMC_CDTYR : (PWMC_CH Offset: 0x4) PWMC Channel Duty Cycle Register -------- +#define AT91C_PWMC_CDTY ((unsigned int) 0x0 << 0) // (PWMC_CH) Channel Duty Cycle +// -------- PWMC_CPRDR : (PWMC_CH Offset: 0x8) PWMC Channel Period Register -------- +#define AT91C_PWMC_CPRD ((unsigned int) 0x0 << 0) // (PWMC_CH) Channel Period +// -------- PWMC_CCNTR : (PWMC_CH Offset: 0xc) PWMC Channel Counter Register -------- +#define AT91C_PWMC_CCNT ((unsigned int) 0x0 << 0) // (PWMC_CH) Channel Counter +// -------- PWMC_CUPDR : (PWMC_CH Offset: 0x10) PWMC Channel Update Register -------- +#define AT91C_PWMC_CUPD ((unsigned int) 0x0 << 0) // (PWMC_CH) Channel Update + +// ***************************************************************************** +// SOFTWARE API DEFINITION FOR Pulse Width Modulation Controller Interface +// ***************************************************************************** +typedef struct _AT91S_PWMC { + AT91_REG PWMC_MR; // PWMC Mode Register + AT91_REG PWMC_ENA; // PWMC Enable Register + AT91_REG PWMC_DIS; // PWMC Disable Register + AT91_REG PWMC_SR; // PWMC Status Register + AT91_REG PWMC_IER; // PWMC Interrupt Enable Register + AT91_REG PWMC_IDR; // PWMC Interrupt Disable Register + AT91_REG PWMC_IMR; // PWMC Interrupt Mask Register + AT91_REG PWMC_ISR; // PWMC Interrupt Status Register + AT91_REG Reserved0[55]; // + AT91_REG PWMC_VR; // PWMC Version Register + AT91_REG Reserved1[64]; // + AT91S_PWMC_CH PWMC_CH[32]; // PWMC Channel 0 +} AT91S_PWMC, *AT91PS_PWMC; + +// -------- PWMC_MR : (PWMC Offset: 0x0) PWMC Mode Register -------- +#define AT91C_PWMC_DIVA ((unsigned int) 0xFF << 0) // (PWMC) CLKA divide factor. +#define AT91C_PWMC_PREA ((unsigned int) 0xF << 8) // (PWMC) Divider Input Clock Prescaler A +#define AT91C_PWMC_PREA_MCK ((unsigned int) 0x0 << 8) // (PWMC) +#define AT91C_PWMC_DIVB ((unsigned int) 0xFF << 16) // (PWMC) CLKB divide factor. +#define AT91C_PWMC_PREB ((unsigned int) 0xF << 24) // (PWMC) Divider Input Clock Prescaler B +#define AT91C_PWMC_PREB_MCK ((unsigned int) 0x0 << 24) // (PWMC) +// -------- PWMC_ENA : (PWMC Offset: 0x4) PWMC Enable Register -------- +#define AT91C_PWMC_CHID0 ((unsigned int) 0x1 << 0) // (PWMC) Channel ID 0 +#define AT91C_PWMC_CHID1 ((unsigned int) 0x1 << 1) // (PWMC) Channel ID 1 +#define AT91C_PWMC_CHID2 ((unsigned int) 0x1 << 2) // (PWMC) Channel ID 2 +#define AT91C_PWMC_CHID3 ((unsigned int) 0x1 << 3) // (PWMC) Channel ID 3 +#define AT91C_PWMC_CHID4 ((unsigned int) 0x1 << 4) // (PWMC) Channel ID 4 +#define AT91C_PWMC_CHID5 ((unsigned int) 0x1 << 5) // (PWMC) Channel ID 5 +#define AT91C_PWMC_CHID6 ((unsigned int) 0x1 << 6) // (PWMC) Channel ID 6 +#define AT91C_PWMC_CHID7 ((unsigned int) 0x1 << 7) // (PWMC) Channel ID 7 +// -------- PWMC_DIS : (PWMC Offset: 0x8) PWMC Disable Register -------- +// -------- PWMC_SR : (PWMC Offset: 0xc) PWMC Status Register -------- +// -------- PWMC_IER : (PWMC Offset: 0x10) PWMC Interrupt Enable Register -------- +// -------- PWMC_IDR : (PWMC Offset: 0x14) PWMC Interrupt Disable Register -------- +// -------- PWMC_IMR : (PWMC Offset: 0x18) PWMC Interrupt Mask Register -------- +// -------- PWMC_ISR : (PWMC Offset: 0x1c) PWMC Interrupt Status Register -------- + +// ***************************************************************************** +// SOFTWARE API DEFINITION FOR USB Device Interface +// ***************************************************************************** +typedef struct _AT91S_UDP { + AT91_REG UDP_NUM; // Frame Number Register + AT91_REG UDP_GLBSTATE; // Global State Register + AT91_REG UDP_FADDR; // Function Address Register + AT91_REG Reserved0[1]; // + AT91_REG UDP_IER; // Interrupt Enable Register + AT91_REG UDP_IDR; // Interrupt Disable Register + AT91_REG UDP_IMR; // Interrupt Mask Register + AT91_REG UDP_ISR; // Interrupt Status Register + AT91_REG UDP_ICR; // Interrupt Clear Register + AT91_REG Reserved1[1]; // + AT91_REG UDP_RSTEP; // Reset Endpoint Register + AT91_REG Reserved2[1]; // + AT91_REG UDP_CSR[8]; // Endpoint Control and Status Register + AT91_REG UDP_FDR[8]; // Endpoint FIFO Data Register + AT91_REG Reserved3[1]; // + AT91_REG UDP_TXVC; // Transceiver Control Register +} AT91S_UDP, *AT91PS_UDP; + +// -------- UDP_FRM_NUM : (UDP Offset: 0x0) USB Frame Number Register -------- +#define AT91C_UDP_FRM_NUM ((unsigned int) 0x7FF << 0) // (UDP) Frame Number as Defined in the Packet Field Formats +#define AT91C_UDP_FRM_ERR ((unsigned int) 0x1 << 16) // (UDP) Frame Error +#define AT91C_UDP_FRM_OK ((unsigned int) 0x1 << 17) // (UDP) Frame OK +// -------- UDP_GLB_STATE : (UDP Offset: 0x4) USB Global State Register -------- +#define AT91C_UDP_FADDEN ((unsigned int) 0x1 << 0) // (UDP) Function Address Enable +#define AT91C_UDP_CONFG ((unsigned int) 0x1 << 1) // (UDP) Configured +#define AT91C_UDP_ESR ((unsigned int) 0x1 << 2) // (UDP) Enable Send Resume +#define AT91C_UDP_RSMINPR ((unsigned int) 0x1 << 3) // (UDP) A Resume Has Been Sent to the Host +#define AT91C_UDP_RMWUPE ((unsigned int) 0x1 << 4) // (UDP) Remote Wake Up Enable +// -------- UDP_FADDR : (UDP Offset: 0x8) USB Function Address Register -------- +#define AT91C_UDP_FADD ((unsigned int) 0xFF << 0) // (UDP) Function Address Value +#define AT91C_UDP_FEN ((unsigned int) 0x1 << 8) // (UDP) Function Enable +// -------- UDP_IER : (UDP Offset: 0x10) USB Interrupt Enable Register -------- +#define AT91C_UDP_EPINT0 ((unsigned int) 0x1 << 0) // (UDP) Endpoint 0 Interrupt +#define AT91C_UDP_EPINT1 ((unsigned int) 0x1 << 1) // (UDP) Endpoint 0 Interrupt +#define AT91C_UDP_EPINT2 ((unsigned int) 0x1 << 2) // (UDP) Endpoint 2 Interrupt +#define AT91C_UDP_EPINT3 ((unsigned int) 0x1 << 3) // (UDP) Endpoint 3 Interrupt +#define AT91C_UDP_EPINT4 ((unsigned int) 0x1 << 4) // (UDP) Endpoint 4 Interrupt +#define AT91C_UDP_EPINT5 ((unsigned int) 0x1 << 5) // (UDP) Endpoint 5 Interrupt +#define AT91C_UDP_EPINT6 ((unsigned int) 0x1 << 6) // (UDP) Endpoint 6 Interrupt +#define AT91C_UDP_EPINT7 ((unsigned int) 0x1 << 7) // (UDP) Endpoint 7 Interrupt +#define AT91C_UDP_RXSUSP ((unsigned int) 0x1 << 8) // (UDP) USB Suspend Interrupt +#define AT91C_UDP_RXRSM ((unsigned int) 0x1 << 9) // (UDP) USB Resume Interrupt +#define AT91C_UDP_EXTRSM ((unsigned int) 0x1 << 10) // (UDP) USB External Resume Interrupt +#define AT91C_UDP_SOFINT ((unsigned int) 0x1 << 11) // (UDP) USB Start Of frame Interrupt +#define AT91C_UDP_WAKEUP ((unsigned int) 0x1 << 13) // (UDP) USB Resume Interrupt +// -------- UDP_IDR : (UDP Offset: 0x14) USB Interrupt Disable Register -------- +// -------- UDP_IMR : (UDP Offset: 0x18) USB Interrupt Mask Register -------- +// -------- UDP_ISR : (UDP Offset: 0x1c) USB Interrupt Status Register -------- +#define AT91C_UDP_ENDBUSRES ((unsigned int) 0x1 << 12) // (UDP) USB End Of Bus Reset Interrupt +// -------- UDP_ICR : (UDP Offset: 0x20) USB Interrupt Clear Register -------- +// -------- UDP_RST_EP : (UDP Offset: 0x28) USB Reset Endpoint Register -------- +#define AT91C_UDP_EP0 ((unsigned int) 0x1 << 0) // (UDP) Reset Endpoint 0 +#define AT91C_UDP_EP1 ((unsigned int) 0x1 << 1) // (UDP) Reset Endpoint 1 +#define AT91C_UDP_EP2 ((unsigned int) 0x1 << 2) // (UDP) Reset Endpoint 2 +#define AT91C_UDP_EP3 ((unsigned int) 0x1 << 3) // (UDP) Reset Endpoint 3 +#define AT91C_UDP_EP4 ((unsigned int) 0x1 << 4) // (UDP) Reset Endpoint 4 +#define AT91C_UDP_EP5 ((unsigned int) 0x1 << 5) // (UDP) Reset Endpoint 5 +#define AT91C_UDP_EP6 ((unsigned int) 0x1 << 6) // (UDP) Reset Endpoint 6 +#define AT91C_UDP_EP7 ((unsigned int) 0x1 << 7) // (UDP) Reset Endpoint 7 +// -------- UDP_CSR : (UDP Offset: 0x30) USB Endpoint Control and Status Register -------- +#define AT91C_UDP_TXCOMP ((unsigned int) 0x1 << 0) // (UDP) Generates an IN packet with data previously written in the DPR +#define AT91C_UDP_RX_DATA_BK0 ((unsigned int) 0x1 << 1) // (UDP) Receive Data Bank 0 +#define AT91C_UDP_RXSETUP ((unsigned int) 0x1 << 2) // (UDP) Sends STALL to the Host (Control endpoints) +#define AT91C_UDP_ISOERROR ((unsigned int) 0x1 << 3) // (UDP) Isochronous error (Isochronous endpoints) +#define AT91C_UDP_TXPKTRDY ((unsigned int) 0x1 << 4) // (UDP) Transmit Packet Ready +#define AT91C_UDP_FORCESTALL ((unsigned int) 0x1 << 5) // (UDP) Force Stall (used by Control, Bulk and Isochronous endpoints). +#define AT91C_UDP_RX_DATA_BK1 ((unsigned int) 0x1 << 6) // (UDP) Receive Data Bank 1 (only used by endpoints with ping-pong attributes). +#define AT91C_UDP_DIR ((unsigned int) 0x1 << 7) // (UDP) Transfer Direction +#define AT91C_UDP_EPTYPE ((unsigned int) 0x7 << 8) // (UDP) Endpoint type +#define AT91C_UDP_EPTYPE_CTRL ((unsigned int) 0x0 << 8) // (UDP) Control +#define AT91C_UDP_EPTYPE_ISO_OUT ((unsigned int) 0x1 << 8) // (UDP) Isochronous OUT +#define AT91C_UDP_EPTYPE_BULK_OUT ((unsigned int) 0x2 << 8) // (UDP) Bulk OUT +#define AT91C_UDP_EPTYPE_INT_OUT ((unsigned int) 0x3 << 8) // (UDP) Interrupt OUT +#define AT91C_UDP_EPTYPE_ISO_IN ((unsigned int) 0x5 << 8) // (UDP) Isochronous IN +#define AT91C_UDP_EPTYPE_BULK_IN ((unsigned int) 0x6 << 8) // (UDP) Bulk IN +#define AT91C_UDP_EPTYPE_INT_IN ((unsigned int) 0x7 << 8) // (UDP) Interrupt IN +#define AT91C_UDP_DTGLE ((unsigned int) 0x1 << 11) // (UDP) Data Toggle +#define AT91C_UDP_EPEDS ((unsigned int) 0x1 << 15) // (UDP) Endpoint Enable Disable +#define AT91C_UDP_RXBYTECNT ((unsigned int) 0x7FF << 16) // (UDP) Number Of Bytes Available in the FIFO +// -------- UDP_TXVC : (UDP Offset: 0x74) Transceiver Control Register -------- +#define AT91C_UDP_TXVDIS ((unsigned int) 0x1 << 8) // (UDP) +#define AT91C_UDP_PUON ((unsigned int) 0x1 << 9) // (UDP) Pull-up ON + +// ***************************************************************************** +// REGISTER ADDRESS DEFINITION FOR AT91SAM7S256 +// ***************************************************************************** +// ========== Register definition for SYS peripheral ========== +// ========== Register definition for AIC peripheral ========== +#define AT91C_AIC_IVR ((AT91_REG *) 0xFFFFF100) // (AIC) IRQ Vector Register +#define AT91C_AIC_SMR ((AT91_REG *) 0xFFFFF000) // (AIC) Source Mode Register +#define AT91C_AIC_FVR ((AT91_REG *) 0xFFFFF104) // (AIC) FIQ Vector Register +#define AT91C_AIC_DCR ((AT91_REG *) 0xFFFFF138) // (AIC) Debug Control Register (Protect) +#define AT91C_AIC_EOICR ((AT91_REG *) 0xFFFFF130) // (AIC) End of Interrupt Command Register +#define AT91C_AIC_SVR ((AT91_REG *) 0xFFFFF080) // (AIC) Source Vector Register +#define AT91C_AIC_FFSR ((AT91_REG *) 0xFFFFF148) // (AIC) Fast Forcing Status Register +#define AT91C_AIC_ICCR ((AT91_REG *) 0xFFFFF128) // (AIC) Interrupt Clear Command Register +#define AT91C_AIC_ISR ((AT91_REG *) 0xFFFFF108) // (AIC) Interrupt Status Register +#define AT91C_AIC_IMR ((AT91_REG *) 0xFFFFF110) // (AIC) Interrupt Mask Register +#define AT91C_AIC_IPR ((AT91_REG *) 0xFFFFF10C) // (AIC) Interrupt Pending Register +#define AT91C_AIC_FFER ((AT91_REG *) 0xFFFFF140) // (AIC) Fast Forcing Enable Register +#define AT91C_AIC_IECR ((AT91_REG *) 0xFFFFF120) // (AIC) Interrupt Enable Command Register +#define AT91C_AIC_ISCR ((AT91_REG *) 0xFFFFF12C) // (AIC) Interrupt Set Command Register +#define AT91C_AIC_FFDR ((AT91_REG *) 0xFFFFF144) // (AIC) Fast Forcing Disable Register +#define AT91C_AIC_CISR ((AT91_REG *) 0xFFFFF114) // (AIC) Core Interrupt Status Register +#define AT91C_AIC_IDCR ((AT91_REG *) 0xFFFFF124) // (AIC) Interrupt Disable Command Register +#define AT91C_AIC_SPU ((AT91_REG *) 0xFFFFF134) // (AIC) Spurious Vector Register +// ========== Register definition for PDC_DBGU peripheral ========== +#define AT91C_DBGU_TCR ((AT91_REG *) 0xFFFFF30C) // (PDC_DBGU) Transmit Counter Register +#define AT91C_DBGU_RNPR ((AT91_REG *) 0xFFFFF310) // (PDC_DBGU) Receive Next Pointer Register +#define AT91C_DBGU_TNPR ((AT91_REG *) 0xFFFFF318) // (PDC_DBGU) Transmit Next Pointer Register +#define AT91C_DBGU_TPR ((AT91_REG *) 0xFFFFF308) // (PDC_DBGU) Transmit Pointer Register +#define AT91C_DBGU_RPR ((AT91_REG *) 0xFFFFF300) // (PDC_DBGU) Receive Pointer Register +#define AT91C_DBGU_RCR ((AT91_REG *) 0xFFFFF304) // (PDC_DBGU) Receive Counter Register +#define AT91C_DBGU_RNCR ((AT91_REG *) 0xFFFFF314) // (PDC_DBGU) Receive Next Counter Register +#define AT91C_DBGU_PTCR ((AT91_REG *) 0xFFFFF320) // (PDC_DBGU) PDC Transfer Control Register +#define AT91C_DBGU_PTSR ((AT91_REG *) 0xFFFFF324) // (PDC_DBGU) PDC Transfer Status Register +#define AT91C_DBGU_TNCR ((AT91_REG *) 0xFFFFF31C) // (PDC_DBGU) Transmit Next Counter Register +// ========== Register definition for DBGU peripheral ========== +#define AT91C_DBGU_EXID ((AT91_REG *) 0xFFFFF244) // (DBGU) Chip ID Extension Register +#define AT91C_DBGU_BRGR ((AT91_REG *) 0xFFFFF220) // (DBGU) Baud Rate Generator Register +#define AT91C_DBGU_IDR ((AT91_REG *) 0xFFFFF20C) // (DBGU) Interrupt Disable Register +#define AT91C_DBGU_CSR ((AT91_REG *) 0xFFFFF214) // (DBGU) Channel Status Register +#define AT91C_DBGU_CIDR ((AT91_REG *) 0xFFFFF240) // (DBGU) Chip ID Register +#define AT91C_DBGU_MR ((AT91_REG *) 0xFFFFF204) // (DBGU) Mode Register +#define AT91C_DBGU_IMR ((AT91_REG *) 0xFFFFF210) // (DBGU) Interrupt Mask Register +#define AT91C_DBGU_CR ((AT91_REG *) 0xFFFFF200) // (DBGU) Control Register +#define AT91C_DBGU_FNTR ((AT91_REG *) 0xFFFFF248) // (DBGU) Force NTRST Register +#define AT91C_DBGU_THR ((AT91_REG *) 0xFFFFF21C) // (DBGU) Transmitter Holding Register +#define AT91C_DBGU_RHR ((AT91_REG *) 0xFFFFF218) // (DBGU) Receiver Holding Register +#define AT91C_DBGU_IER ((AT91_REG *) 0xFFFFF208) // (DBGU) Interrupt Enable Register +// ========== Register definition for PIOA peripheral ========== +#define AT91C_PIOA_ODR ((AT91_REG *) 0xFFFFF414) // (PIOA) Output Disable Registerr +#define AT91C_PIOA_SODR ((AT91_REG *) 0xFFFFF430) // (PIOA) Set Output Data Register +#define AT91C_PIOA_ISR ((AT91_REG *) 0xFFFFF44C) // (PIOA) Interrupt Status Register +#define AT91C_PIOA_ABSR ((AT91_REG *) 0xFFFFF478) // (PIOA) AB Select Status Register +#define AT91C_PIOA_IER ((AT91_REG *) 0xFFFFF440) // (PIOA) Interrupt Enable Register +#define AT91C_PIOA_PPUDR ((AT91_REG *) 0xFFFFF460) // (PIOA) Pull-up Disable Register +#define AT91C_PIOA_IMR ((AT91_REG *) 0xFFFFF448) // (PIOA) Interrupt Mask Register +#define AT91C_PIOA_PER ((AT91_REG *) 0xFFFFF400) // (PIOA) PIO Enable Register +#define AT91C_PIOA_IFDR ((AT91_REG *) 0xFFFFF424) // (PIOA) Input Filter Disable Register +#define AT91C_PIOA_OWDR ((AT91_REG *) 0xFFFFF4A4) // (PIOA) Output Write Disable Register +#define AT91C_PIOA_MDSR ((AT91_REG *) 0xFFFFF458) // (PIOA) Multi-driver Status Register +#define AT91C_PIOA_IDR ((AT91_REG *) 0xFFFFF444) // (PIOA) Interrupt Disable Register +#define AT91C_PIOA_ODSR ((AT91_REG *) 0xFFFFF438) // (PIOA) Output Data Status Register +#define AT91C_PIOA_PPUSR ((AT91_REG *) 0xFFFFF468) // (PIOA) Pull-up Status Register +#define AT91C_PIOA_OWSR ((AT91_REG *) 0xFFFFF4A8) // (PIOA) Output Write Status Register +#define AT91C_PIOA_BSR ((AT91_REG *) 0xFFFFF474) // (PIOA) Select B Register +#define AT91C_PIOA_OWER ((AT91_REG *) 0xFFFFF4A0) // (PIOA) Output Write Enable Register +#define AT91C_PIOA_IFER ((AT91_REG *) 0xFFFFF420) // (PIOA) Input Filter Enable Register +#define AT91C_PIOA_PDSR ((AT91_REG *) 0xFFFFF43C) // (PIOA) Pin Data Status Register +#define AT91C_PIOA_PPUER ((AT91_REG *) 0xFFFFF464) // (PIOA) Pull-up Enable Register +#define AT91C_PIOA_OSR ((AT91_REG *) 0xFFFFF418) // (PIOA) Output Status Register +#define AT91C_PIOA_ASR ((AT91_REG *) 0xFFFFF470) // (PIOA) Select A Register +#define AT91C_PIOA_MDDR ((AT91_REG *) 0xFFFFF454) // (PIOA) Multi-driver Disable Register +#define AT91C_PIOA_CODR ((AT91_REG *) 0xFFFFF434) // (PIOA) Clear Output Data Register +#define AT91C_PIOA_MDER ((AT91_REG *) 0xFFFFF450) // (PIOA) Multi-driver Enable Register +#define AT91C_PIOA_PDR ((AT91_REG *) 0xFFFFF404) // (PIOA) PIO Disable Register +#define AT91C_PIOA_IFSR ((AT91_REG *) 0xFFFFF428) // (PIOA) Input Filter Status Register +#define AT91C_PIOA_OER ((AT91_REG *) 0xFFFFF410) // (PIOA) Output Enable Register +#define AT91C_PIOA_PSR ((AT91_REG *) 0xFFFFF408) // (PIOA) PIO Status Register +// ========== Register definition for CKGR peripheral ========== +#define AT91C_CKGR_MOR ((AT91_REG *) 0xFFFFFC20) // (CKGR) Main Oscillator Register +#define AT91C_CKGR_PLLR ((AT91_REG *) 0xFFFFFC2C) // (CKGR) PLL Register +#define AT91C_CKGR_MCFR ((AT91_REG *) 0xFFFFFC24) // (CKGR) Main Clock Frequency Register +// ========== Register definition for PMC peripheral ========== +#define AT91C_PMC_IDR ((AT91_REG *) 0xFFFFFC64) // (PMC) Interrupt Disable Register +#define AT91C_PMC_MOR ((AT91_REG *) 0xFFFFFC20) // (PMC) Main Oscillator Register +#define AT91C_PMC_PLLR ((AT91_REG *) 0xFFFFFC2C) // (PMC) PLL Register +#define AT91C_PMC_PCER ((AT91_REG *) 0xFFFFFC10) // (PMC) Peripheral Clock Enable Register +#define AT91C_PMC_PCKR ((AT91_REG *) 0xFFFFFC40) // (PMC) Programmable Clock Register +#define AT91C_PMC_MCKR ((AT91_REG *) 0xFFFFFC30) // (PMC) Master Clock Register +#define AT91C_PMC_SCDR ((AT91_REG *) 0xFFFFFC04) // (PMC) System Clock Disable Register +#define AT91C_PMC_PCDR ((AT91_REG *) 0xFFFFFC14) // (PMC) Peripheral Clock Disable Register +#define AT91C_PMC_SCSR ((AT91_REG *) 0xFFFFFC08) // (PMC) System Clock Status Register +#define AT91C_PMC_PCSR ((AT91_REG *) 0xFFFFFC18) // (PMC) Peripheral Clock Status Register +#define AT91C_PMC_MCFR ((AT91_REG *) 0xFFFFFC24) // (PMC) Main Clock Frequency Register +#define AT91C_PMC_SCER ((AT91_REG *) 0xFFFFFC00) // (PMC) System Clock Enable Register +#define AT91C_PMC_IMR ((AT91_REG *) 0xFFFFFC6C) // (PMC) Interrupt Mask Register +#define AT91C_PMC_IER ((AT91_REG *) 0xFFFFFC60) // (PMC) Interrupt Enable Register +#define AT91C_PMC_SR ((AT91_REG *) 0xFFFFFC68) // (PMC) Status Register +// ========== Register definition for RSTC peripheral ========== +#define AT91C_RSTC_RCR ((AT91_REG *) 0xFFFFFD00) // (RSTC) Reset Control Register +#define AT91C_RSTC_RMR ((AT91_REG *) 0xFFFFFD08) // (RSTC) Reset Mode Register +#define AT91C_RSTC_RSR ((AT91_REG *) 0xFFFFFD04) // (RSTC) Reset Status Register +// ========== Register definition for RTTC peripheral ========== +#define AT91C_RTTC_RTSR ((AT91_REG *) 0xFFFFFD2C) // (RTTC) Real-time Status Register +#define AT91C_RTTC_RTMR ((AT91_REG *) 0xFFFFFD20) // (RTTC) Real-time Mode Register +#define AT91C_RTTC_RTVR ((AT91_REG *) 0xFFFFFD28) // (RTTC) Real-time Value Register +#define AT91C_RTTC_RTAR ((AT91_REG *) 0xFFFFFD24) // (RTTC) Real-time Alarm Register +// ========== Register definition for PITC peripheral ========== +#define AT91C_PITC_PIVR ((AT91_REG *) 0xFFFFFD38) // (PITC) Period Interval Value Register +#define AT91C_PITC_PISR ((AT91_REG *) 0xFFFFFD34) // (PITC) Period Interval Status Register +#define AT91C_PITC_PIIR ((AT91_REG *) 0xFFFFFD3C) // (PITC) Period Interval Image Register +#define AT91C_PITC_PIMR ((AT91_REG *) 0xFFFFFD30) // (PITC) Period Interval Mode Register +// ========== Register definition for WDTC peripheral ========== +#define AT91C_WDTC_WDCR ((AT91_REG *) 0xFFFFFD40) // (WDTC) Watchdog Control Register +#define AT91C_WDTC_WDSR ((AT91_REG *) 0xFFFFFD48) // (WDTC) Watchdog Status Register +#define AT91C_WDTC_WDMR ((AT91_REG *) 0xFFFFFD44) // (WDTC) Watchdog Mode Register +// ========== Register definition for VREG peripheral ========== +#define AT91C_VREG_MR ((AT91_REG *) 0xFFFFFD60) // (VREG) Voltage Regulator Mode Register +// ========== Register definition for MC peripheral ========== +#define AT91C_MC_ASR ((AT91_REG *) 0xFFFFFF04) // (MC) MC Abort Status Register +#define AT91C_MC_RCR ((AT91_REG *) 0xFFFFFF00) // (MC) MC Remap Control Register +#define AT91C_MC_FCR ((AT91_REG *) 0xFFFFFF64) // (MC) MC Flash Command Register +#define AT91C_MC_AASR ((AT91_REG *) 0xFFFFFF08) // (MC) MC Abort Address Status Register +#define AT91C_MC_FSR ((AT91_REG *) 0xFFFFFF68) // (MC) MC Flash Status Register +#define AT91C_MC_FMR ((AT91_REG *) 0xFFFFFF60) // (MC) MC Flash Mode Register +// ========== Register definition for PDC_SPI peripheral ========== +#define AT91C_SPI_PTCR ((AT91_REG *) 0xFFFE0120) // (PDC_SPI) PDC Transfer Control Register +#define AT91C_SPI_TPR ((AT91_REG *) 0xFFFE0108) // (PDC_SPI) Transmit Pointer Register +#define AT91C_SPI_TCR ((AT91_REG *) 0xFFFE010C) // (PDC_SPI) Transmit Counter Register +#define AT91C_SPI_RCR ((AT91_REG *) 0xFFFE0104) // (PDC_SPI) Receive Counter Register +#define AT91C_SPI_PTSR ((AT91_REG *) 0xFFFE0124) // (PDC_SPI) PDC Transfer Status Register +#define AT91C_SPI_RNPR ((AT91_REG *) 0xFFFE0110) // (PDC_SPI) Receive Next Pointer Register +#define AT91C_SPI_RPR ((AT91_REG *) 0xFFFE0100) // (PDC_SPI) Receive Pointer Register +#define AT91C_SPI_TNCR ((AT91_REG *) 0xFFFE011C) // (PDC_SPI) Transmit Next Counter Register +#define AT91C_SPI_RNCR ((AT91_REG *) 0xFFFE0114) // (PDC_SPI) Receive Next Counter Register +#define AT91C_SPI_TNPR ((AT91_REG *) 0xFFFE0118) // (PDC_SPI) Transmit Next Pointer Register +// ========== Register definition for SPI peripheral ========== +#define AT91C_SPI_IER ((AT91_REG *) 0xFFFE0014) // (SPI) Interrupt Enable Register +#define AT91C_SPI_SR ((AT91_REG *) 0xFFFE0010) // (SPI) Status Register +#define AT91C_SPI_IDR ((AT91_REG *) 0xFFFE0018) // (SPI) Interrupt Disable Register +#define AT91C_SPI_CR ((AT91_REG *) 0xFFFE0000) // (SPI) Control Register +#define AT91C_SPI_MR ((AT91_REG *) 0xFFFE0004) // (SPI) Mode Register +#define AT91C_SPI_IMR ((AT91_REG *) 0xFFFE001C) // (SPI) Interrupt Mask Register +#define AT91C_SPI_TDR ((AT91_REG *) 0xFFFE000C) // (SPI) Transmit Data Register +#define AT91C_SPI_RDR ((AT91_REG *) 0xFFFE0008) // (SPI) Receive Data Register +#define AT91C_SPI_CSR ((AT91_REG *) 0xFFFE0030) // (SPI) Chip Select Register +// ========== Register definition for PDC_ADC peripheral ========== +#define AT91C_ADC_PTSR ((AT91_REG *) 0xFFFD8124) // (PDC_ADC) PDC Transfer Status Register +#define AT91C_ADC_PTCR ((AT91_REG *) 0xFFFD8120) // (PDC_ADC) PDC Transfer Control Register +#define AT91C_ADC_TNPR ((AT91_REG *) 0xFFFD8118) // (PDC_ADC) Transmit Next Pointer Register +#define AT91C_ADC_TNCR ((AT91_REG *) 0xFFFD811C) // (PDC_ADC) Transmit Next Counter Register +#define AT91C_ADC_RNPR ((AT91_REG *) 0xFFFD8110) // (PDC_ADC) Receive Next Pointer Register +#define AT91C_ADC_RNCR ((AT91_REG *) 0xFFFD8114) // (PDC_ADC) Receive Next Counter Register +#define AT91C_ADC_RPR ((AT91_REG *) 0xFFFD8100) // (PDC_ADC) Receive Pointer Register +#define AT91C_ADC_TCR ((AT91_REG *) 0xFFFD810C) // (PDC_ADC) Transmit Counter Register +#define AT91C_ADC_TPR ((AT91_REG *) 0xFFFD8108) // (PDC_ADC) Transmit Pointer Register +#define AT91C_ADC_RCR ((AT91_REG *) 0xFFFD8104) // (PDC_ADC) Receive Counter Register +// ========== Register definition for ADC peripheral ========== +#define AT91C_ADC_CDR2 ((AT91_REG *) 0xFFFD8038) // (ADC) ADC Channel Data Register 2 +#define AT91C_ADC_CDR3 ((AT91_REG *) 0xFFFD803C) // (ADC) ADC Channel Data Register 3 +#define AT91C_ADC_CDR0 ((AT91_REG *) 0xFFFD8030) // (ADC) ADC Channel Data Register 0 +#define AT91C_ADC_CDR5 ((AT91_REG *) 0xFFFD8044) // (ADC) ADC Channel Data Register 5 +#define AT91C_ADC_CHDR ((AT91_REG *) 0xFFFD8014) // (ADC) ADC Channel Disable Register +#define AT91C_ADC_SR ((AT91_REG *) 0xFFFD801C) // (ADC) ADC Status Register +#define AT91C_ADC_CDR4 ((AT91_REG *) 0xFFFD8040) // (ADC) ADC Channel Data Register 4 +#define AT91C_ADC_CDR1 ((AT91_REG *) 0xFFFD8034) // (ADC) ADC Channel Data Register 1 +#define AT91C_ADC_LCDR ((AT91_REG *) 0xFFFD8020) // (ADC) ADC Last Converted Data Register +#define AT91C_ADC_IDR ((AT91_REG *) 0xFFFD8028) // (ADC) ADC Interrupt Disable Register +#define AT91C_ADC_CR ((AT91_REG *) 0xFFFD8000) // (ADC) ADC Control Register +#define AT91C_ADC_CDR7 ((AT91_REG *) 0xFFFD804C) // (ADC) ADC Channel Data Register 7 +#define AT91C_ADC_CDR6 ((AT91_REG *) 0xFFFD8048) // (ADC) ADC Channel Data Register 6 +#define AT91C_ADC_IER ((AT91_REG *) 0xFFFD8024) // (ADC) ADC Interrupt Enable Register +#define AT91C_ADC_CHER ((AT91_REG *) 0xFFFD8010) // (ADC) ADC Channel Enable Register +#define AT91C_ADC_CHSR ((AT91_REG *) 0xFFFD8018) // (ADC) ADC Channel Status Register +#define AT91C_ADC_MR ((AT91_REG *) 0xFFFD8004) // (ADC) ADC Mode Register +#define AT91C_ADC_IMR ((AT91_REG *) 0xFFFD802C) // (ADC) ADC Interrupt Mask Register +// ========== Register definition for PDC_SSC peripheral ========== +#define AT91C_SSC_TNCR ((AT91_REG *) 0xFFFD411C) // (PDC_SSC) Transmit Next Counter Register +#define AT91C_SSC_RPR ((AT91_REG *) 0xFFFD4100) // (PDC_SSC) Receive Pointer Register +#define AT91C_SSC_RNCR ((AT91_REG *) 0xFFFD4114) // (PDC_SSC) Receive Next Counter Register +#define AT91C_SSC_TPR ((AT91_REG *) 0xFFFD4108) // (PDC_SSC) Transmit Pointer Register +#define AT91C_SSC_PTCR ((AT91_REG *) 0xFFFD4120) // (PDC_SSC) PDC Transfer Control Register +#define AT91C_SSC_TCR ((AT91_REG *) 0xFFFD410C) // (PDC_SSC) Transmit Counter Register +#define AT91C_SSC_RCR ((AT91_REG *) 0xFFFD4104) // (PDC_SSC) Receive Counter Register +#define AT91C_SSC_RNPR ((AT91_REG *) 0xFFFD4110) // (PDC_SSC) Receive Next Pointer Register +#define AT91C_SSC_TNPR ((AT91_REG *) 0xFFFD4118) // (PDC_SSC) Transmit Next Pointer Register +#define AT91C_SSC_PTSR ((AT91_REG *) 0xFFFD4124) // (PDC_SSC) PDC Transfer Status Register +// ========== Register definition for SSC peripheral ========== +#define AT91C_SSC_RHR ((AT91_REG *) 0xFFFD4020) // (SSC) Receive Holding Register +#define AT91C_SSC_RSHR ((AT91_REG *) 0xFFFD4030) // (SSC) Receive Sync Holding Register +#define AT91C_SSC_TFMR ((AT91_REG *) 0xFFFD401C) // (SSC) Transmit Frame Mode Register +#define AT91C_SSC_IDR ((AT91_REG *) 0xFFFD4048) // (SSC) Interrupt Disable Register +#define AT91C_SSC_THR ((AT91_REG *) 0xFFFD4024) // (SSC) Transmit Holding Register +#define AT91C_SSC_RCMR ((AT91_REG *) 0xFFFD4010) // (SSC) Receive Clock ModeRegister +#define AT91C_SSC_IER ((AT91_REG *) 0xFFFD4044) // (SSC) Interrupt Enable Register +#define AT91C_SSC_TSHR ((AT91_REG *) 0xFFFD4034) // (SSC) Transmit Sync Holding Register +#define AT91C_SSC_SR ((AT91_REG *) 0xFFFD4040) // (SSC) Status Register +#define AT91C_SSC_CMR ((AT91_REG *) 0xFFFD4004) // (SSC) Clock Mode Register +#define AT91C_SSC_TCMR ((AT91_REG *) 0xFFFD4018) // (SSC) Transmit Clock Mode Register +#define AT91C_SSC_CR ((AT91_REG *) 0xFFFD4000) // (SSC) Control Register +#define AT91C_SSC_IMR ((AT91_REG *) 0xFFFD404C) // (SSC) Interrupt Mask Register +#define AT91C_SSC_RFMR ((AT91_REG *) 0xFFFD4014) // (SSC) Receive Frame Mode Register +// ========== Register definition for PDC_US1 peripheral ========== +#define AT91C_US1_RNCR ((AT91_REG *) 0xFFFC4114) // (PDC_US1) Receive Next Counter Register +#define AT91C_US1_PTCR ((AT91_REG *) 0xFFFC4120) // (PDC_US1) PDC Transfer Control Register +#define AT91C_US1_TCR ((AT91_REG *) 0xFFFC410C) // (PDC_US1) Transmit Counter Register +#define AT91C_US1_PTSR ((AT91_REG *) 0xFFFC4124) // (PDC_US1) PDC Transfer Status Register +#define AT91C_US1_TNPR ((AT91_REG *) 0xFFFC4118) // (PDC_US1) Transmit Next Pointer Register +#define AT91C_US1_RCR ((AT91_REG *) 0xFFFC4104) // (PDC_US1) Receive Counter Register +#define AT91C_US1_RNPR ((AT91_REG *) 0xFFFC4110) // (PDC_US1) Receive Next Pointer Register +#define AT91C_US1_RPR ((AT91_REG *) 0xFFFC4100) // (PDC_US1) Receive Pointer Register +#define AT91C_US1_TNCR ((AT91_REG *) 0xFFFC411C) // (PDC_US1) Transmit Next Counter Register +#define AT91C_US1_TPR ((AT91_REG *) 0xFFFC4108) // (PDC_US1) Transmit Pointer Register +// ========== Register definition for US1 peripheral ========== +#define AT91C_US1_IF ((AT91_REG *) 0xFFFC404C) // (US1) IRDA_FILTER Register +#define AT91C_US1_NER ((AT91_REG *) 0xFFFC4044) // (US1) Nb Errors Register +#define AT91C_US1_RTOR ((AT91_REG *) 0xFFFC4024) // (US1) Receiver Time-out Register +#define AT91C_US1_CSR ((AT91_REG *) 0xFFFC4014) // (US1) Channel Status Register +#define AT91C_US1_IDR ((AT91_REG *) 0xFFFC400C) // (US1) Interrupt Disable Register +#define AT91C_US1_IER ((AT91_REG *) 0xFFFC4008) // (US1) Interrupt Enable Register +#define AT91C_US1_THR ((AT91_REG *) 0xFFFC401C) // (US1) Transmitter Holding Register +#define AT91C_US1_TTGR ((AT91_REG *) 0xFFFC4028) // (US1) Transmitter Time-guard Register +#define AT91C_US1_RHR ((AT91_REG *) 0xFFFC4018) // (US1) Receiver Holding Register +#define AT91C_US1_BRGR ((AT91_REG *) 0xFFFC4020) // (US1) Baud Rate Generator Register +#define AT91C_US1_IMR ((AT91_REG *) 0xFFFC4010) // (US1) Interrupt Mask Register +#define AT91C_US1_FIDI ((AT91_REG *) 0xFFFC4040) // (US1) FI_DI_Ratio Register +#define AT91C_US1_CR ((AT91_REG *) 0xFFFC4000) // (US1) Control Register +#define AT91C_US1_MR ((AT91_REG *) 0xFFFC4004) // (US1) Mode Register +// ========== Register definition for PDC_US0 peripheral ========== +#define AT91C_US0_TNPR ((AT91_REG *) 0xFFFC0118) // (PDC_US0) Transmit Next Pointer Register +#define AT91C_US0_RNPR ((AT91_REG *) 0xFFFC0110) // (PDC_US0) Receive Next Pointer Register +#define AT91C_US0_TCR ((AT91_REG *) 0xFFFC010C) // (PDC_US0) Transmit Counter Register +#define AT91C_US0_PTCR ((AT91_REG *) 0xFFFC0120) // (PDC_US0) PDC Transfer Control Register +#define AT91C_US0_PTSR ((AT91_REG *) 0xFFFC0124) // (PDC_US0) PDC Transfer Status Register +#define AT91C_US0_TNCR ((AT91_REG *) 0xFFFC011C) // (PDC_US0) Transmit Next Counter Register +#define AT91C_US0_TPR ((AT91_REG *) 0xFFFC0108) // (PDC_US0) Transmit Pointer Register +#define AT91C_US0_RCR ((AT91_REG *) 0xFFFC0104) // (PDC_US0) Receive Counter Register +#define AT91C_US0_RPR ((AT91_REG *) 0xFFFC0100) // (PDC_US0) Receive Pointer Register +#define AT91C_US0_RNCR ((AT91_REG *) 0xFFFC0114) // (PDC_US0) Receive Next Counter Register +// ========== Register definition for US0 peripheral ========== +#define AT91C_US0_BRGR ((AT91_REG *) 0xFFFC0020) // (US0) Baud Rate Generator Register +#define AT91C_US0_NER ((AT91_REG *) 0xFFFC0044) // (US0) Nb Errors Register +#define AT91C_US0_CR ((AT91_REG *) 0xFFFC0000) // (US0) Control Register +#define AT91C_US0_IMR ((AT91_REG *) 0xFFFC0010) // (US0) Interrupt Mask Register +#define AT91C_US0_FIDI ((AT91_REG *) 0xFFFC0040) // (US0) FI_DI_Ratio Register +#define AT91C_US0_TTGR ((AT91_REG *) 0xFFFC0028) // (US0) Transmitter Time-guard Register +#define AT91C_US0_MR ((AT91_REG *) 0xFFFC0004) // (US0) Mode Register +#define AT91C_US0_RTOR ((AT91_REG *) 0xFFFC0024) // (US0) Receiver Time-out Register +#define AT91C_US0_CSR ((AT91_REG *) 0xFFFC0014) // (US0) Channel Status Register +#define AT91C_US0_RHR ((AT91_REG *) 0xFFFC0018) // (US0) Receiver Holding Register +#define AT91C_US0_IDR ((AT91_REG *) 0xFFFC000C) // (US0) Interrupt Disable Register +#define AT91C_US0_THR ((AT91_REG *) 0xFFFC001C) // (US0) Transmitter Holding Register +#define AT91C_US0_IF ((AT91_REG *) 0xFFFC004C) // (US0) IRDA_FILTER Register +#define AT91C_US0_IER ((AT91_REG *) 0xFFFC0008) // (US0) Interrupt Enable Register +// ========== Register definition for TWI peripheral ========== +#define AT91C_TWI_IER ((AT91_REG *) 0xFFFB8024) // (TWI) Interrupt Enable Register +#define AT91C_TWI_CR ((AT91_REG *) 0xFFFB8000) // (TWI) Control Register +#define AT91C_TWI_SR ((AT91_REG *) 0xFFFB8020) // (TWI) Status Register +#define AT91C_TWI_IMR ((AT91_REG *) 0xFFFB802C) // (TWI) Interrupt Mask Register +#define AT91C_TWI_THR ((AT91_REG *) 0xFFFB8034) // (TWI) Transmit Holding Register +#define AT91C_TWI_IDR ((AT91_REG *) 0xFFFB8028) // (TWI) Interrupt Disable Register +#define AT91C_TWI_IADR ((AT91_REG *) 0xFFFB800C) // (TWI) Internal Address Register +#define AT91C_TWI_MMR ((AT91_REG *) 0xFFFB8004) // (TWI) Master Mode Register +#define AT91C_TWI_CWGR ((AT91_REG *) 0xFFFB8010) // (TWI) Clock Waveform Generator Register +#define AT91C_TWI_RHR ((AT91_REG *) 0xFFFB8030) // (TWI) Receive Holding Register +// ========== Register definition for TC0 peripheral ========== +#define AT91C_TC0_SR ((AT91_REG *) 0xFFFA0020) // (TC0) Status Register +#define AT91C_TC0_RC ((AT91_REG *) 0xFFFA001C) // (TC0) Register C +#define AT91C_TC0_RB ((AT91_REG *) 0xFFFA0018) // (TC0) Register B +#define AT91C_TC0_CCR ((AT91_REG *) 0xFFFA0000) // (TC0) Channel Control Register +#define AT91C_TC0_CMR ((AT91_REG *) 0xFFFA0004) // (TC0) Channel Mode Register (Capture Mode / Waveform Mode) +#define AT91C_TC0_IER ((AT91_REG *) 0xFFFA0024) // (TC0) Interrupt Enable Register +#define AT91C_TC0_RA ((AT91_REG *) 0xFFFA0014) // (TC0) Register A +#define AT91C_TC0_IDR ((AT91_REG *) 0xFFFA0028) // (TC0) Interrupt Disable Register +#define AT91C_TC0_CV ((AT91_REG *) 0xFFFA0010) // (TC0) Counter Value +#define AT91C_TC0_IMR ((AT91_REG *) 0xFFFA002C) // (TC0) Interrupt Mask Register +// ========== Register definition for TC1 peripheral ========== +#define AT91C_TC1_RB ((AT91_REG *) 0xFFFA0058) // (TC1) Register B +#define AT91C_TC1_CCR ((AT91_REG *) 0xFFFA0040) // (TC1) Channel Control Register +#define AT91C_TC1_IER ((AT91_REG *) 0xFFFA0064) // (TC1) Interrupt Enable Register +#define AT91C_TC1_IDR ((AT91_REG *) 0xFFFA0068) // (TC1) Interrupt Disable Register +#define AT91C_TC1_SR ((AT91_REG *) 0xFFFA0060) // (TC1) Status Register +#define AT91C_TC1_CMR ((AT91_REG *) 0xFFFA0044) // (TC1) Channel Mode Register (Capture Mode / Waveform Mode) +#define AT91C_TC1_RA ((AT91_REG *) 0xFFFA0054) // (TC1) Register A +#define AT91C_TC1_RC ((AT91_REG *) 0xFFFA005C) // (TC1) Register C +#define AT91C_TC1_IMR ((AT91_REG *) 0xFFFA006C) // (TC1) Interrupt Mask Register +#define AT91C_TC1_CV ((AT91_REG *) 0xFFFA0050) // (TC1) Counter Value +// ========== Register definition for TC2 peripheral ========== +#define AT91C_TC2_CMR ((AT91_REG *) 0xFFFA0084) // (TC2) Channel Mode Register (Capture Mode / Waveform Mode) +#define AT91C_TC2_CCR ((AT91_REG *) 0xFFFA0080) // (TC2) Channel Control Register +#define AT91C_TC2_CV ((AT91_REG *) 0xFFFA0090) // (TC2) Counter Value +#define AT91C_TC2_RA ((AT91_REG *) 0xFFFA0094) // (TC2) Register A +#define AT91C_TC2_RB ((AT91_REG *) 0xFFFA0098) // (TC2) Register B +#define AT91C_TC2_IDR ((AT91_REG *) 0xFFFA00A8) // (TC2) Interrupt Disable Register +#define AT91C_TC2_IMR ((AT91_REG *) 0xFFFA00AC) // (TC2) Interrupt Mask Register +#define AT91C_TC2_RC ((AT91_REG *) 0xFFFA009C) // (TC2) Register C +#define AT91C_TC2_IER ((AT91_REG *) 0xFFFA00A4) // (TC2) Interrupt Enable Register +#define AT91C_TC2_SR ((AT91_REG *) 0xFFFA00A0) // (TC2) Status Register +// ========== Register definition for TCB peripheral ========== +#define AT91C_TCB_BMR ((AT91_REG *) 0xFFFA00C4) // (TCB) TC Block Mode Register +#define AT91C_TCB_BCR ((AT91_REG *) 0xFFFA00C0) // (TCB) TC Block Control Register +// ========== Register definition for PWMC_CH3 peripheral ========== +#define AT91C_PWMC_CH3_CUPDR ((AT91_REG *) 0xFFFCC270) // (PWMC_CH3) Channel Update Register +#define AT91C_PWMC_CH3_Reserved ((AT91_REG *) 0xFFFCC274) // (PWMC_CH3) Reserved +#define AT91C_PWMC_CH3_CPRDR ((AT91_REG *) 0xFFFCC268) // (PWMC_CH3) Channel Period Register +#define AT91C_PWMC_CH3_CDTYR ((AT91_REG *) 0xFFFCC264) // (PWMC_CH3) Channel Duty Cycle Register +#define AT91C_PWMC_CH3_CCNTR ((AT91_REG *) 0xFFFCC26C) // (PWMC_CH3) Channel Counter Register +#define AT91C_PWMC_CH3_CMR ((AT91_REG *) 0xFFFCC260) // (PWMC_CH3) Channel Mode Register +// ========== Register definition for PWMC_CH2 peripheral ========== +#define AT91C_PWMC_CH2_Reserved ((AT91_REG *) 0xFFFCC254) // (PWMC_CH2) Reserved +#define AT91C_PWMC_CH2_CMR ((AT91_REG *) 0xFFFCC240) // (PWMC_CH2) Channel Mode Register +#define AT91C_PWMC_CH2_CCNTR ((AT91_REG *) 0xFFFCC24C) // (PWMC_CH2) Channel Counter Register +#define AT91C_PWMC_CH2_CPRDR ((AT91_REG *) 0xFFFCC248) // (PWMC_CH2) Channel Period Register +#define AT91C_PWMC_CH2_CUPDR ((AT91_REG *) 0xFFFCC250) // (PWMC_CH2) Channel Update Register +#define AT91C_PWMC_CH2_CDTYR ((AT91_REG *) 0xFFFCC244) // (PWMC_CH2) Channel Duty Cycle Register +// ========== Register definition for PWMC_CH1 peripheral ========== +#define AT91C_PWMC_CH1_Reserved ((AT91_REG *) 0xFFFCC234) // (PWMC_CH1) Reserved +#define AT91C_PWMC_CH1_CUPDR ((AT91_REG *) 0xFFFCC230) // (PWMC_CH1) Channel Update Register +#define AT91C_PWMC_CH1_CPRDR ((AT91_REG *) 0xFFFCC228) // (PWMC_CH1) Channel Period Register +#define AT91C_PWMC_CH1_CCNTR ((AT91_REG *) 0xFFFCC22C) // (PWMC_CH1) Channel Counter Register +#define AT91C_PWMC_CH1_CDTYR ((AT91_REG *) 0xFFFCC224) // (PWMC_CH1) Channel Duty Cycle Register +#define AT91C_PWMC_CH1_CMR ((AT91_REG *) 0xFFFCC220) // (PWMC_CH1) Channel Mode Register +// ========== Register definition for PWMC_CH0 peripheral ========== +#define AT91C_PWMC_CH0_Reserved ((AT91_REG *) 0xFFFCC214) // (PWMC_CH0) Reserved +#define AT91C_PWMC_CH0_CPRDR ((AT91_REG *) 0xFFFCC208) // (PWMC_CH0) Channel Period Register +#define AT91C_PWMC_CH0_CDTYR ((AT91_REG *) 0xFFFCC204) // (PWMC_CH0) Channel Duty Cycle Register +#define AT91C_PWMC_CH0_CMR ((AT91_REG *) 0xFFFCC200) // (PWMC_CH0) Channel Mode Register +#define AT91C_PWMC_CH0_CUPDR ((AT91_REG *) 0xFFFCC210) // (PWMC_CH0) Channel Update Register +#define AT91C_PWMC_CH0_CCNTR ((AT91_REG *) 0xFFFCC20C) // (PWMC_CH0) Channel Counter Register +// ========== Register definition for PWMC peripheral ========== +#define AT91C_PWMC_IDR ((AT91_REG *) 0xFFFCC014) // (PWMC) PWMC Interrupt Disable Register +#define AT91C_PWMC_DIS ((AT91_REG *) 0xFFFCC008) // (PWMC) PWMC Disable Register +#define AT91C_PWMC_IER ((AT91_REG *) 0xFFFCC010) // (PWMC) PWMC Interrupt Enable Register +#define AT91C_PWMC_VR ((AT91_REG *) 0xFFFCC0FC) // (PWMC) PWMC Version Register +#define AT91C_PWMC_ISR ((AT91_REG *) 0xFFFCC01C) // (PWMC) PWMC Interrupt Status Register +#define AT91C_PWMC_SR ((AT91_REG *) 0xFFFCC00C) // (PWMC) PWMC Status Register +#define AT91C_PWMC_IMR ((AT91_REG *) 0xFFFCC018) // (PWMC) PWMC Interrupt Mask Register +#define AT91C_PWMC_MR ((AT91_REG *) 0xFFFCC000) // (PWMC) PWMC Mode Register +#define AT91C_PWMC_ENA ((AT91_REG *) 0xFFFCC004) // (PWMC) PWMC Enable Register +// ========== Register definition for UDP peripheral ========== +#define AT91C_UDP_IMR ((AT91_REG *) 0xFFFB0018) // (UDP) Interrupt Mask Register +#define AT91C_UDP_FADDR ((AT91_REG *) 0xFFFB0008) // (UDP) Function Address Register +#define AT91C_UDP_NUM ((AT91_REG *) 0xFFFB0000) // (UDP) Frame Number Register +#define AT91C_UDP_FDR ((AT91_REG *) 0xFFFB0050) // (UDP) Endpoint FIFO Data Register +#define AT91C_UDP_ISR ((AT91_REG *) 0xFFFB001C) // (UDP) Interrupt Status Register +#define AT91C_UDP_CSR ((AT91_REG *) 0xFFFB0030) // (UDP) Endpoint Control and Status Register +#define AT91C_UDP_IDR ((AT91_REG *) 0xFFFB0014) // (UDP) Interrupt Disable Register +#define AT91C_UDP_ICR ((AT91_REG *) 0xFFFB0020) // (UDP) Interrupt Clear Register +#define AT91C_UDP_RSTEP ((AT91_REG *) 0xFFFB0028) // (UDP) Reset Endpoint Register +#define AT91C_UDP_TXVC ((AT91_REG *) 0xFFFB0074) // (UDP) Transceiver Control Register +#define AT91C_UDP_GLBSTATE ((AT91_REG *) 0xFFFB0004) // (UDP) Global State Register +#define AT91C_UDP_IER ((AT91_REG *) 0xFFFB0010) // (UDP) Interrupt Enable Register + +// ***************************************************************************** +// PIO DEFINITIONS FOR AT91SAM7S256 +// ***************************************************************************** +#define AT91C_PIO_PA0 ((unsigned int) 1 << 0) // Pin Controlled by PA0 +#define AT91C_PA0_PWM0 ((unsigned int) AT91C_PIO_PA0) // PWM Channel 0 +#define AT91C_PA0_TIOA0 ((unsigned int) AT91C_PIO_PA0) // Timer Counter 0 Multipurpose Timer I/O Pin A +#define AT91C_PIO_PA1 ((unsigned int) 1 << 1) // Pin Controlled by PA1 +#define AT91C_PA1_PWM1 ((unsigned int) AT91C_PIO_PA1) // PWM Channel 1 +#define AT91C_PA1_TIOB0 ((unsigned int) AT91C_PIO_PA1) // Timer Counter 0 Multipurpose Timer I/O Pin B +#define AT91C_PIO_PA10 ((unsigned int) 1 << 10) // Pin Controlled by PA10 +#define AT91C_PA10_DTXD ((unsigned int) AT91C_PIO_PA10) // DBGU Debug Transmit Data +#define AT91C_PA10_NPCS2 ((unsigned int) AT91C_PIO_PA10) // SPI Peripheral Chip Select 2 +#define AT91C_PIO_PA11 ((unsigned int) 1 << 11) // Pin Controlled by PA11 +#define AT91C_PA11_NPCS0 ((unsigned int) AT91C_PIO_PA11) // SPI Peripheral Chip Select 0 +#define AT91C_PA11_PWM0 ((unsigned int) AT91C_PIO_PA11) // PWM Channel 0 +#define AT91C_PIO_PA12 ((unsigned int) 1 << 12) // Pin Controlled by PA12 +#define AT91C_PA12_MISO ((unsigned int) AT91C_PIO_PA12) // SPI Master In Slave +#define AT91C_PA12_PWM1 ((unsigned int) AT91C_PIO_PA12) // PWM Channel 1 +#define AT91C_PIO_PA13 ((unsigned int) 1 << 13) // Pin Controlled by PA13 +#define AT91C_PA13_MOSI ((unsigned int) AT91C_PIO_PA13) // SPI Master Out Slave +#define AT91C_PA13_PWM2 ((unsigned int) AT91C_PIO_PA13) // PWM Channel 2 +#define AT91C_PIO_PA14 ((unsigned int) 1 << 14) // Pin Controlled by PA14 +#define AT91C_PA14_SPCK ((unsigned int) AT91C_PIO_PA14) // SPI Serial Clock +#define AT91C_PA14_PWM3 ((unsigned int) AT91C_PIO_PA14) // PWM Channel 3 +#define AT91C_PIO_PA15 ((unsigned int) 1 << 15) // Pin Controlled by PA15 +#define AT91C_PA15_TF ((unsigned int) AT91C_PIO_PA15) // SSC Transmit Frame Sync +#define AT91C_PA15_TIOA1 ((unsigned int) AT91C_PIO_PA15) // Timer Counter 1 Multipurpose Timer I/O Pin A +#define AT91C_PIO_PA16 ((unsigned int) 1 << 16) // Pin Controlled by PA16 +#define AT91C_PA16_TK ((unsigned int) AT91C_PIO_PA16) // SSC Transmit Clock +#define AT91C_PA16_TIOB1 ((unsigned int) AT91C_PIO_PA16) // Timer Counter 1 Multipurpose Timer I/O Pin B +#define AT91C_PIO_PA17 ((unsigned int) 1 << 17) // Pin Controlled by PA17 +#define AT91C_PA17_TD ((unsigned int) AT91C_PIO_PA17) // SSC Transmit data +#define AT91C_PA17_PCK1 ((unsigned int) AT91C_PIO_PA17) // PMC Programmable Clock Output 1 +#define AT91C_PIO_PA18 ((unsigned int) 1 << 18) // Pin Controlled by PA18 +#define AT91C_PA18_RD ((unsigned int) AT91C_PIO_PA18) // SSC Receive Data +#define AT91C_PA18_PCK2 ((unsigned int) AT91C_PIO_PA18) // PMC Programmable Clock Output 2 +#define AT91C_PIO_PA19 ((unsigned int) 1 << 19) // Pin Controlled by PA19 +#define AT91C_PA19_RK ((unsigned int) AT91C_PIO_PA19) // SSC Receive Clock +#define AT91C_PA19_FIQ ((unsigned int) AT91C_PIO_PA19) // AIC Fast Interrupt Input +#define AT91C_PIO_PA2 ((unsigned int) 1 << 2) // Pin Controlled by PA2 +#define AT91C_PA2_PWM2 ((unsigned int) AT91C_PIO_PA2) // PWM Channel 2 +#define AT91C_PA2_SCK0 ((unsigned int) AT91C_PIO_PA2) // USART 0 Serial Clock +#define AT91C_PIO_PA20 ((unsigned int) 1 << 20) // Pin Controlled by PA20 +#define AT91C_PA20_RF ((unsigned int) AT91C_PIO_PA20) // SSC Receive Frame Sync +#define AT91C_PA20_IRQ0 ((unsigned int) AT91C_PIO_PA20) // External Interrupt 0 +#define AT91C_PIO_PA21 ((unsigned int) 1 << 21) // Pin Controlled by PA21 +#define AT91C_PA21_RXD1 ((unsigned int) AT91C_PIO_PA21) // USART 1 Receive Data +#define AT91C_PA21_PCK1 ((unsigned int) AT91C_PIO_PA21) // PMC Programmable Clock Output 1 +#define AT91C_PIO_PA22 ((unsigned int) 1 << 22) // Pin Controlled by PA22 +#define AT91C_PA22_TXD1 ((unsigned int) AT91C_PIO_PA22) // USART 1 Transmit Data +#define AT91C_PA22_NPCS3 ((unsigned int) AT91C_PIO_PA22) // SPI Peripheral Chip Select 3 +#define AT91C_PIO_PA23 ((unsigned int) 1 << 23) // Pin Controlled by PA23 +#define AT91C_PA23_SCK1 ((unsigned int) AT91C_PIO_PA23) // USART 1 Serial Clock +#define AT91C_PA23_PWM0 ((unsigned int) AT91C_PIO_PA23) // PWM Channel 0 +#define AT91C_PIO_PA24 ((unsigned int) 1 << 24) // Pin Controlled by PA24 +#define AT91C_PA24_RTS1 ((unsigned int) AT91C_PIO_PA24) // USART 1 Ready To Send +#define AT91C_PA24_PWM1 ((unsigned int) AT91C_PIO_PA24) // PWM Channel 1 +#define AT91C_PIO_PA25 ((unsigned int) 1 << 25) // Pin Controlled by PA25 +#define AT91C_PA25_CTS1 ((unsigned int) AT91C_PIO_PA25) // USART 1 Clear To Send +#define AT91C_PA25_PWM2 ((unsigned int) AT91C_PIO_PA25) // PWM Channel 2 +#define AT91C_PIO_PA26 ((unsigned int) 1 << 26) // Pin Controlled by PA26 +#define AT91C_PA26_DCD1 ((unsigned int) AT91C_PIO_PA26) // USART 1 Data Carrier Detect +#define AT91C_PA26_TIOA2 ((unsigned int) AT91C_PIO_PA26) // Timer Counter 2 Multipurpose Timer I/O Pin A +#define AT91C_PIO_PA27 ((unsigned int) 1 << 27) // Pin Controlled by PA27 +#define AT91C_PA27_DTR1 ((unsigned int) AT91C_PIO_PA27) // USART 1 Data Terminal ready +#define AT91C_PA27_TIOB2 ((unsigned int) AT91C_PIO_PA27) // Timer Counter 2 Multipurpose Timer I/O Pin B +#define AT91C_PIO_PA28 ((unsigned int) 1 << 28) // Pin Controlled by PA28 +#define AT91C_PA28_DSR1 ((unsigned int) AT91C_PIO_PA28) // USART 1 Data Set ready +#define AT91C_PA28_TCLK1 ((unsigned int) AT91C_PIO_PA28) // Timer Counter 1 external clock input +#define AT91C_PIO_PA29 ((unsigned int) 1 << 29) // Pin Controlled by PA29 +#define AT91C_PA29_RI1 ((unsigned int) AT91C_PIO_PA29) // USART 1 Ring Indicator +#define AT91C_PA29_TCLK2 ((unsigned int) AT91C_PIO_PA29) // Timer Counter 2 external clock input +#define AT91C_PIO_PA3 ((unsigned int) 1 << 3) // Pin Controlled by PA3 +#define AT91C_PA3_TWD ((unsigned int) AT91C_PIO_PA3) // TWI Two-wire Serial Data +#define AT91C_PA3_NPCS3 ((unsigned int) AT91C_PIO_PA3) // SPI Peripheral Chip Select 3 +#define AT91C_PIO_PA30 ((unsigned int) 1 << 30) // Pin Controlled by PA30 +#define AT91C_PA30_IRQ1 ((unsigned int) AT91C_PIO_PA30) // External Interrupt 1 +#define AT91C_PA30_NPCS2 ((unsigned int) AT91C_PIO_PA30) // SPI Peripheral Chip Select 2 +#define AT91C_PIO_PA31 ((unsigned int) 1 << 31) // Pin Controlled by PA31 +#define AT91C_PA31_NPCS1 ((unsigned int) AT91C_PIO_PA31) // SPI Peripheral Chip Select 1 +#define AT91C_PA31_PCK2 ((unsigned int) AT91C_PIO_PA31) // PMC Programmable Clock Output 2 +#define AT91C_PIO_PA4 ((unsigned int) 1 << 4) // Pin Controlled by PA4 +#define AT91C_PA4_TWCK ((unsigned int) AT91C_PIO_PA4) // TWI Two-wire Serial Clock +#define AT91C_PA4_TCLK0 ((unsigned int) AT91C_PIO_PA4) // Timer Counter 0 external clock input +#define AT91C_PIO_PA5 ((unsigned int) 1 << 5) // Pin Controlled by PA5 +#define AT91C_PA5_RXD0 ((unsigned int) AT91C_PIO_PA5) // USART 0 Receive Data +#define AT91C_PA5_NPCS3 ((unsigned int) AT91C_PIO_PA5) // SPI Peripheral Chip Select 3 +#define AT91C_PIO_PA6 ((unsigned int) 1 << 6) // Pin Controlled by PA6 +#define AT91C_PA6_TXD0 ((unsigned int) AT91C_PIO_PA6) // USART 0 Transmit Data +#define AT91C_PA6_PCK0 ((unsigned int) AT91C_PIO_PA6) // PMC Programmable Clock Output 0 +#define AT91C_PIO_PA7 ((unsigned int) 1 << 7) // Pin Controlled by PA7 +#define AT91C_PA7_RTS0 ((unsigned int) AT91C_PIO_PA7) // USART 0 Ready To Send +#define AT91C_PA7_PWM3 ((unsigned int) AT91C_PIO_PA7) // PWM Channel 3 +#define AT91C_PIO_PA8 ((unsigned int) 1 << 8) // Pin Controlled by PA8 +#define AT91C_PA8_CTS0 ((unsigned int) AT91C_PIO_PA8) // USART 0 Clear To Send +#define AT91C_PA8_ADTRG ((unsigned int) AT91C_PIO_PA8) // ADC External Trigger +#define AT91C_PIO_PA9 ((unsigned int) 1 << 9) // Pin Controlled by PA9 +#define AT91C_PA9_DRXD ((unsigned int) AT91C_PIO_PA9) // DBGU Debug Receive Data +#define AT91C_PA9_NPCS1 ((unsigned int) AT91C_PIO_PA9) // SPI Peripheral Chip Select 1 + +// ***************************************************************************** +// PERIPHERAL ID DEFINITIONS FOR AT91SAM7S256 +// ***************************************************************************** +#define AT91C_ID_FIQ ((unsigned int) 0) // Advanced Interrupt Controller (FIQ) +#define AT91C_ID_SYS ((unsigned int) 1) // System Peripheral +#define AT91C_ID_PIOA ((unsigned int) 2) // Parallel IO Controller +#define AT91C_ID_3_Reserved ((unsigned int) 3) // Reserved +#define AT91C_ID_ADC ((unsigned int) 4) // Analog-to-Digital Converter +#define AT91C_ID_SPI ((unsigned int) 5) // Serial Peripheral Interface +#define AT91C_ID_US0 ((unsigned int) 6) // USART 0 +#define AT91C_ID_US1 ((unsigned int) 7) // USART 1 +#define AT91C_ID_SSC ((unsigned int) 8) // Serial Synchronous Controller +#define AT91C_ID_TWI ((unsigned int) 9) // Two-Wire Interface +#define AT91C_ID_PWMC ((unsigned int) 10) // PWM Controller +#define AT91C_ID_UDP ((unsigned int) 11) // USB Device Port +#define AT91C_ID_TC0 ((unsigned int) 12) // Timer Counter 0 +#define AT91C_ID_TC1 ((unsigned int) 13) // Timer Counter 1 +#define AT91C_ID_TC2 ((unsigned int) 14) // Timer Counter 2 +#define AT91C_ID_15_Reserved ((unsigned int) 15) // Reserved +#define AT91C_ID_16_Reserved ((unsigned int) 16) // Reserved +#define AT91C_ID_17_Reserved ((unsigned int) 17) // Reserved +#define AT91C_ID_18_Reserved ((unsigned int) 18) // Reserved +#define AT91C_ID_19_Reserved ((unsigned int) 19) // Reserved +#define AT91C_ID_20_Reserved ((unsigned int) 20) // Reserved +#define AT91C_ID_21_Reserved ((unsigned int) 21) // Reserved +#define AT91C_ID_22_Reserved ((unsigned int) 22) // Reserved +#define AT91C_ID_23_Reserved ((unsigned int) 23) // Reserved +#define AT91C_ID_24_Reserved ((unsigned int) 24) // Reserved +#define AT91C_ID_25_Reserved ((unsigned int) 25) // Reserved +#define AT91C_ID_26_Reserved ((unsigned int) 26) // Reserved +#define AT91C_ID_27_Reserved ((unsigned int) 27) // Reserved +#define AT91C_ID_28_Reserved ((unsigned int) 28) // Reserved +#define AT91C_ID_29_Reserved ((unsigned int) 29) // Reserved +#define AT91C_ID_IRQ0 ((unsigned int) 30) // Advanced Interrupt Controller (IRQ0) +#define AT91C_ID_IRQ1 ((unsigned int) 31) // Advanced Interrupt Controller (IRQ1) + +// ***************************************************************************** +// BASE ADDRESS DEFINITIONS FOR AT91SAM7S256 +// ***************************************************************************** +#define AT91C_BASE_SYS ((AT91PS_SYS) 0xFFFFF000) // (SYS) Base Address +#define AT91C_BASE_AIC ((AT91PS_AIC) 0xFFFFF000) // (AIC) Base Address +#define AT91C_BASE_PDC_DBGU ((AT91PS_PDC) 0xFFFFF300) // (PDC_DBGU) Base Address +#define AT91C_BASE_DBGU ((AT91PS_DBGU) 0xFFFFF200) // (DBGU) Base Address +#define AT91C_BASE_PIOA ((AT91PS_PIO) 0xFFFFF400) // (PIOA) Base Address +#define AT91C_BASE_CKGR ((AT91PS_CKGR) 0xFFFFFC20) // (CKGR) Base Address +#define AT91C_BASE_PMC ((AT91PS_PMC) 0xFFFFFC00) // (PMC) Base Address +#define AT91C_BASE_RSTC ((AT91PS_RSTC) 0xFFFFFD00) // (RSTC) Base Address +#define AT91C_BASE_RTTC ((AT91PS_RTTC) 0xFFFFFD20) // (RTTC) Base Address +#define AT91C_BASE_PITC ((AT91PS_PITC) 0xFFFFFD30) // (PITC) Base Address +#define AT91C_BASE_WDTC ((AT91PS_WDTC) 0xFFFFFD40) // (WDTC) Base Address +#define AT91C_BASE_VREG ((AT91PS_VREG) 0xFFFFFD60) // (VREG) Base Address +#define AT91C_BASE_MC ((AT91PS_MC) 0xFFFFFF00) // (MC) Base Address +#define AT91C_BASE_PDC_SPI ((AT91PS_PDC) 0xFFFE0100) // (PDC_SPI) Base Address +#define AT91C_BASE_SPI ((AT91PS_SPI) 0xFFFE0000) // (SPI) Base Address +#define AT91C_BASE_PDC_ADC ((AT91PS_PDC) 0xFFFD8100) // (PDC_ADC) Base Address +#define AT91C_BASE_ADC ((AT91PS_ADC) 0xFFFD8000) // (ADC) Base Address +#define AT91C_BASE_PDC_SSC ((AT91PS_PDC) 0xFFFD4100) // (PDC_SSC) Base Address +#define AT91C_BASE_SSC ((AT91PS_SSC) 0xFFFD4000) // (SSC) Base Address +#define AT91C_BASE_PDC_US1 ((AT91PS_PDC) 0xFFFC4100) // (PDC_US1) Base Address +#define AT91C_BASE_US1 ((AT91PS_USART) 0xFFFC4000) // (US1) Base Address +#define AT91C_BASE_PDC_US0 ((AT91PS_PDC) 0xFFFC0100) // (PDC_US0) Base Address +#define AT91C_BASE_US0 ((AT91PS_USART) 0xFFFC0000) // (US0) Base Address +#define AT91C_BASE_TWI ((AT91PS_TWI) 0xFFFB8000) // (TWI) Base Address +#define AT91C_BASE_TC0 ((AT91PS_TC) 0xFFFA0000) // (TC0) Base Address +#define AT91C_BASE_TC1 ((AT91PS_TC) 0xFFFA0040) // (TC1) Base Address +#define AT91C_BASE_TC2 ((AT91PS_TC) 0xFFFA0080) // (TC2) Base Address +#define AT91C_BASE_TCB ((AT91PS_TCB) 0xFFFA0000) // (TCB) Base Address +#define AT91C_BASE_PWMC_CH3 ((AT91PS_PWMC_CH) 0xFFFCC260) // (PWMC_CH3) Base Address +#define AT91C_BASE_PWMC_CH2 ((AT91PS_PWMC_CH) 0xFFFCC240) // (PWMC_CH2) Base Address +#define AT91C_BASE_PWMC_CH1 ((AT91PS_PWMC_CH) 0xFFFCC220) // (PWMC_CH1) Base Address +#define AT91C_BASE_PWMC_CH0 ((AT91PS_PWMC_CH) 0xFFFCC200) // (PWMC_CH0) Base Address +#define AT91C_BASE_PWMC ((AT91PS_PWMC) 0xFFFCC000) // (PWMC) Base Address +#define AT91C_BASE_UDP ((AT91PS_UDP) 0xFFFB0000) // (UDP) Base Address + +// ***************************************************************************** +// MEMORY MAPPING DEFINITIONS FOR AT91SAM7S256 +// ***************************************************************************** +#define AT91C_ISRAM ((char *) 0x00200000) // Internal SRAM base address +#define AT91C_ISRAM_SIZE ((unsigned int) 0x00010000) // Internal SRAM size in byte (64 Kbyte) +#define AT91C_IFLASH ((char *) 0x00100000) // Internal ROM base address +#define AT91C_IFLASH_SIZE ((unsigned int) 0x00040000) // Internal ROM size in byte (256 Kbyte) + +#endif diff --git a/lib/abort.c b/lib/abort.c new file mode 100644 index 0000000..26d47e7 --- /dev/null +++ b/lib/abort.c @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2011 Nicolas Schodet + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/* Provide an abort function, could be used by various library function. */ + +void +abort (void) +{ + /* Wait for ever, nothing better to do. */ + while (1) + ; +} + diff --git a/lib/errno.c b/lib/errno.c new file mode 100644 index 0000000..3eb52ac --- /dev/null +++ b/lib/errno.c @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2010 Nicolas Schodet + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/* This is needed for libm. Provide a non thread safe errno. */ + +static int __the_errno; + +int * +__errno (void) +{ + return &__the_errno; +} + diff --git a/lib/nxt.ld b/lib/nxt.ld new file mode 100644 index 0000000..e54bc5d --- /dev/null +++ b/lib/nxt.ld @@ -0,0 +1,167 @@ + +MEMORY +{ + CODE (rx) : ORIGIN = 0x00100000, LENGTH = 256k + DATA (rwx) : ORIGIN = 0x00200000, LENGTH = 64k +} + +__FIRST_IN_RAM = ORIGIN(DATA); +__TOP_STACK = ORIGIN(DATA) + LENGTH(DATA); + +/* Section Definitions */ + +SECTIONS +{ + /* first section is .text which is used for code */ + . = ORIGIN(CODE); + + .text : + { + KEEP(*(.vectorg)) + . = ALIGN(4); + KEEP(*(.init)) + *(.text .text.*) /* remaining code */ + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.gcc_except_table) + *(.rodata) /* read-only data (constants) */ + *(.rodata.*) + *(.gnu.linkonce.r.*) + . = ALIGN(4); + } >CODE + + . = ALIGN(4); + + /* .ctors .dtors are used for c++ constructors/destructors */ + + .ctors : + { + PROVIDE(__ctors_start__ = .); + KEEP(*(SORT(.ctors.*))) + KEEP(*(.ctors)) + PROVIDE(__ctors_end__ = .); + } >CODE + + .dtors : + { + PROVIDE(__dtors_start__ = .); + KEEP(*(SORT(.dtors.*))) + KEEP(*(.dtors)) + PROVIDE(__dtors_end__ = .); + } >CODE + + __exidx_start = . ; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } >CODE + __exidx_end = . ; + + . = ALIGN(4); + + _etext = . ; + PROVIDE (etext = .); + + /* .data section which is used for initialized data */ + .data : AT (_etext) + { + _data = . ; + KEEP(*(.vectmapped)) + . = ALIGN(4); + *(.fastrun .fastrun.*) + . = ALIGN(4); + SORT(CONSTRUCTORS) + . = ALIGN(4); + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(4); + } >DATA + + . = ALIGN(4); + + _edata = . ; + PROVIDE (edata = .); + + __STARTOFUSERFLASH_FROM_LINKER = + ALIGN (LOADADDR (.data) + SIZEOF (.data), 0x100); + + /* + * The various debugger stacks. + */ + .stack : ALIGN(8) { + /* abort stack */ + __abort_stack_bottom__ = . ; + KEEP(*(.stack.abort)) + __abort_stack__ = . ; + __abort_stack_top__ = . ; + + /* debugger state */ + __debugger_stack_bottom__ = . ; + KEEP(*(.stack.debugger)) + __debugger_stack__ = . ; + __debugger_stack_top__ = . ; + + /* breakpoints */ + __breakpoints_start__ = . ; + KEEP(*(.breakpoints)) + __breakpoints_end__ = . ; + } > DATA + + __breakpoints_num__ = (__breakpoints_end__ - __breakpoints_start__) / 8; + + /* .bss section which is used for uninitialized data */ + .bss (NOLOAD) : + { + __bss_start = . ; + __bss_start__ = . ; + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + } >DATA + + . = ALIGN(4); + + __bss_end__ = . ; + + _end = .; + PROVIDE (end = .); + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + +} diff --git a/lib/sbrk.c b/lib/sbrk.c new file mode 100644 index 0000000..317a94b --- /dev/null +++ b/lib/sbrk.c @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2010 Nicolas Schodet + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/* The newlib sprintf use dynamic allocation for floating point. Therefore, + * the sbrk syscall should be provided. + * + * This works by taking memory above BSS and below stack. There is no + * collision detection as it whould not known what to do then. */ + +extern char _end; + +void * +_sbrk (int incr) +{ + static char *heap = 0; + char *base; + /* Initialise if first call. */ + if (heap == 0) + heap = &_end; + /* Increment and return old heap base. */ + base = heap; + heap += incr; + return base; +} + diff --git a/lib/sscanf.c b/lib/sscanf.c new file mode 100644 index 0000000..a4f5e64 --- /dev/null +++ b/lib/sscanf.c @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2010 Nicolas Schodet + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/* NXT source code is using sscanf to parse a float. Newlib sscanf will pull + * too many code, so here is a stub which implement just what is used. */ +#include +#include +#include + +int +sscanf (const char *str, const char *fmt, ...) +{ + va_list ap; + float *f; + char *tailptr; + /* Only support use in NXT source code. */ + if (fmt[0] != '%' || fmt[1] != 'f' || fmt[2] != '\0') + return 0; + /* Retrieve float pointer. */ + va_start (ap, fmt); + f = va_arg (ap, float *); + va_end (ap); + /* Parse using the nice strtod. */ + *f = strtod (str, &tailptr); + if (str == tailptr) + return 0; + else + return 1; +} + diff --git a/lib/strtod.c b/lib/strtod.c new file mode 100644 index 0000000..49d02a2 --- /dev/null +++ b/lib/strtod.c @@ -0,0 +1,257 @@ +/* + * strtod.c -- + * + * Source code for the "strtod" library procedure. + * + * Copyright (c) 1988-1993 The Regents of the University of California. + * Copyright (c) 1994 Sun Microsystems, Inc. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies. The University of California + * makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without + * express or implied warranty. + */ + +#include +#include +#include + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif +#ifndef NULL +#define NULL 0 +#endif + +static int maxExponent = 511; /* Largest possible base 10 exponent. Any + * exponent larger than this will already + * produce underflow or overflow, so there's + * no need to worry about additional digits. + */ +static double powersOf10[] = { /* Table giving binary powers of 10. Entry */ + 10., /* is 10^2^i. Used to convert decimal */ + 100., /* exponents into floating-point numbers. */ + 1.0e4, + 1.0e8, + 1.0e16, + 1.0e32, + 1.0e64, + 1.0e128, + 1.0e256 +}; + +/* + *---------------------------------------------------------------------- + * + * strtod -- + * + * This procedure converts a floating-point number from an ASCII + * decimal representation to internal double-precision format. + * + * Results: + * The return value is the double-precision floating-point + * representation of the characters in string. If endPtr isn't + * NULL, then *endPtr is filled in with the address of the + * next character after the last one that was part of the + * floating-point number. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +double +strtod(string, endPtr) + const char *string; /* A decimal ASCII floating-point number, + * optionally preceded by white space. + * Must have form "-I.FE-X", where I is the + * integer part of the mantissa, F is the + * fractional part of the mantissa, and X + * is the exponent. Either of the signs + * may be "+", "-", or omitted. Either I + * or F may be omitted, or both. The decimal + * point isn't necessary unless F is present. + * The "E" may actually be an "e". E and X + * may both be omitted (but not just one). + */ + char **endPtr; /* If non-NULL, store terminating character's + * address here. */ +{ + int sign, expSign = FALSE; + double fraction, dblExp, *d; + register const char *p; + register int c; + int exp = 0; /* Exponent read from "EX" field. */ + int fracExp = 0; /* Exponent that derives from the fractional + * part. Under normal circumstatnces, it is + * the negative of the number of digits in F. + * However, if I is very long, the last digits + * of I get dropped (otherwise a long I with a + * large negative exponent could cause an + * unnecessary overflow on I alone). In this + * case, fracExp is incremented one for each + * dropped digit. */ + int mantSize; /* Number of digits in mantissa. */ + int decPt; /* Number of mantissa digits BEFORE decimal + * point. */ + const char *pExp; /* Temporarily holds location of exponent + * in string. */ + + /* + * Strip off leading blanks and check for a sign. + */ + + p = string; + while (isspace(*p)) { + p += 1; + } + if (*p == '-') { + sign = TRUE; + p += 1; + } else { + if (*p == '+') { + p += 1; + } + sign = FALSE; + } + + /* + * Count the number of digits in the mantissa (including the decimal + * point), and also locate the decimal point. + */ + + decPt = -1; + for (mantSize = 0; ; mantSize += 1) + { + c = *p; + if (!isdigit(c)) { + if ((c != '.') || (decPt >= 0)) { + break; + } + decPt = mantSize; + } + p += 1; + } + + /* + * Now suck up the digits in the mantissa. Use two integers to + * collect 9 digits each (this is faster than using floating-point). + * If the mantissa has more than 18 digits, ignore the extras, since + * they can't affect the value anyway. + */ + + pExp = p; + p -= mantSize; + if (decPt < 0) { + decPt = mantSize; + } else { + mantSize -= 1; /* One of the digits was the point. */ + } + if (mantSize > 18) { + fracExp = decPt - 18; + mantSize = 18; + } else { + fracExp = decPt - mantSize; + } + if (mantSize == 0) { + fraction = 0.0; + p = string; + goto done; + } else { + int frac1, frac2; + frac1 = 0; + for ( ; mantSize > 9; mantSize -= 1) + { + c = *p; + p += 1; + if (c == '.') { + c = *p; + p += 1; + } + frac1 = 10*frac1 + (c - '0'); + } + frac2 = 0; + for (; mantSize > 0; mantSize -= 1) + { + c = *p; + p += 1; + if (c == '.') { + c = *p; + p += 1; + } + frac2 = 10*frac2 + (c - '0'); + } + fraction = (1.0e9 * frac1) + frac2; + } + + /* + * Skim off the exponent. + */ + + p = pExp; + if ((*p == 'E') || (*p == 'e')) { + p += 1; + if (*p == '-') { + expSign = TRUE; + p += 1; + } else { + if (*p == '+') { + p += 1; + } + expSign = FALSE; + } + while (isdigit(*p)) { + exp = exp * 10 + (*p - '0'); + p += 1; + } + } + if (expSign) { + exp = fracExp - exp; + } else { + exp = fracExp + exp; + } + + /* + * Generate a floating-point number that represents the exponent. + * Do this by processing the exponent one bit at a time to combine + * many powers of 2 of 10. Then combine the exponent with the + * fraction. + */ + + if (exp < 0) { + expSign = TRUE; + exp = -exp; + } else { + expSign = FALSE; + } + if (exp > maxExponent) { + exp = maxExponent; + errno = ERANGE; + } + dblExp = 1.0; + for (d = powersOf10; exp != 0; exp >>= 1, d += 1) { + if (exp & 01) { + dblExp *= *d; + } + } + if (expSign) { + fraction /= dblExp; + } else { + fraction *= dblExp; + } + +done: + if (endPtr != NULL) { + *endPtr = (char *) p; + } + + if (sign) { + return -fraction; + } + return fraction; +} diff --git a/src/BtTest.inc b/src/BtTest.inc new file mode 100644 index 0000000..65575af --- /dev/null +++ b/src/BtTest.inc @@ -0,0 +1,1613 @@ +//******* TestPrg ************************************************************ + +//#define TESTPRG // If defined the test program will be included + +#ifndef BUILD_DATE +# define BUILD_DATE "" +#endif + +#ifdef TESTPRG +#include "Test1.txt" +#include "Test2.txt" +#endif + +extern void BtIo(void); + +void GetProtocolVersion(UBYTE *String) +{ + char Tmp[DISPLAYLINE_LENGTH + 1]; + snprintf(Tmp, sizeof(Tmp), "%d.%d.%d", (FIRMWAREVERSION >> 8) & 0xFF, FIRMWAREVERSION & 0xFF, FIRMWAREPATCH); + snprintf((char*)String, DISPLAYLINE_LENGTH + 1, "FWi %*s", DISPLAYLINE_LENGTH - 4, Tmp); +} + + +void GetARMBuild(UBYTE *String) +{ + snprintf((char*)String, DISPLAYLINE_LENGTH + 1, "%s", BUILD_DATE); +} + + +void GetBC4Build(UBYTE *String) +{ + sprintf((char*)String,"BC4 %2X.%02X",pMapComm->BrickData.BluecoreVersion[1],pMapComm->BrickData.BluecoreVersion[0]); +} + + +void GetAVRBuild(UBYTE *String) +{ + sprintf((char*)String,"AVR %1u.%02u",((IoFromAvr.Battery >> 13) & 3),((IoFromAvr.Battery >> 10) & 7)); +} + + +void GetBC4Address(UBYTE *String) +{ + UWORD Count; + UBYTE Tmp; + + Count = (UWORD)sprintf((char*)String,"ID "); + for (Tmp = 0;(Tmp < (SIZE_OF_BDADDR - 1)) && (Count <= (DISPLAYLINE_LENGTH - 2));Tmp++) + { + Count += (UWORD)sprintf((char*)&String[Count],"%02X",(UWORD)(pMapComm->BrickData.BdAddr[Tmp]) & 0xFF); + } +} + + +enum TSTPRG +{ + SYSTEM_INIT = 1, + SYSTEM_UNLOCK_INIT, + SYSTEM_UNLOCK, + SYSTEM_PAGE, + TIMER_INIT, + TIMER_SHOW, + TIMER_HOLD, + BT_PAGE, + BT_RESET, + BT_RESETTING, + BT_LIST_INIT, + BT_LIST, + BT_CONN_INIT, + BT_CONN, + BT_UPDATE_FW, + TSTPRG_INIT, + TSTPRG_SELECT_SUBTEST, + + TSTPRG_SENSOR_INIT, + TSTPRG_SELECT_SENSOR, + TSTPRG_TOUCH_SENSOR_INIT, + TSTPRG_TOUCH_SENSOR, + TSTPRG_SOUND_SENSOR_SELECT, + TSTPRG_SOUND_SENSOR_INIT, + TSTPRG_SOUND_SENSOR, + TSTPRG_LIGHT_SENSOR_SELECT, + TSTPRG_LIGHT_SENSOR_INIT, + TSTPRG_LIGHT_SENSOR, + TSTPRG_SKIP_SENSOR, + + TSTPRG_RCX_INIT, + TSTPRG_RCX_SELECT, + TSTPRG_RCX_DISPLAY_INIT, + TSTPRG_RCX_DISPLAY, + TSTPRG_RCX_INPUT_SELECT, + TSTPRG_RCX_INPUT_INIT, + TSTPRG_RCX_INPUT, + TSTPRG_RCX_DIGITAL_INIT, + TSTPRG_RCX_DIGITAL_OK, + TSTPRG_RCX_DIGITAL_FAIL, + TSTPRG_RCX_DIGITAL, + TSTPRG_RCX_MOTOR_INIT, + TSTPRG_RCX_MOTOR, + TSTPRG_SKIP_RCX_MOTOR, + TSTPRG_SKIP_RCX, + + TSTPRG_MOTOR_INIT, + TSTPRG_MOTOR, + TSTPRG_SKIP_MOTOR, + + TSTPRG_SKIP, + TSTPRG_WAIT +}; + +const UBYTE TXT_EMPTY[] = " "; +const UBYTE TXT_LINE[] = "----------------"; + +#ifdef TESTPRG + +const UBYTE TXT_TEST[] = "Timer Test Bt "; + +const UBYTE TXT_TIMER[] = "Reset Hold "; +const UBYTE TXT_TIMER_HOLD[] = " Continue "; + +const UBYTE TXT_LAST[] = "Last UI->BT Cmd."; +const UBYTE TXT_BT_PAGE[] = "Reset List BtIo"; + +const UBYTE TXT_RESETTING[] = " Resetting! "; + +const UBYTE TXT_BT_LIST[] = "Down ConTab Up "; +const UBYTE TXT_BT_CONN[] = "Down Update Up "; + +const UBYTE TXT_BTUPDATE[] = "BT update mode !"; +const UBYTE TXT_DONE[] = " When done "; +const UBYTE TXT_RESET[] = " activate reset "; +const UBYTE TXT_REBOOT[] = "button to reboot"; + +const UBYTE TXT_TESTPRG[] = " TestPrg V0.08 "; +const UBYTE TXT_SELECT[] = "Select sub test "; +const UBYTE TXT_SUBTEST[] = "Sens. RCX Motor"; + +const UBYTE TXT_SELECT_SENSOR[] = " Select sensor "; +const UBYTE TXT_SENSORS[] = "Touch Snd. Light"; + +const UBYTE TXT_SELECT_TYPE[] = " Select type "; +const UBYTE TXT_SOUND_SENSORS[] = " DB DBA "; +const UBYTE TXT_LIGHT_SENSORS[] = "Pasive Active"; + +const UBYTE TXT_SENSOR_TOUCH[] = "Touch Sensor Tst"; +const UBYTE TXT_SENSOR_SOUND_DB[] = "DB Sound Sens."; +const UBYTE TXT_SENSOR_SOUND_DBA[] = "DBA Sound Sens."; +const UBYTE TXT_SOUND_STOP[] = "440Hz Stop 4KHz"; +const UBYTE TXT_SENSOR_LIGHT_PASIVE[] = "Pas. Light Sens."; +const UBYTE TXT_SENSOR_LIGHT_ACTIVE[] = "Act. Light Sens."; + +const UBYTE TXT_SUBTEST_STOP[] = " Stop "; + +const UBYTE TXT_MOTOR[] = " Motor test "; +const UBYTE TXT_MOTOR_HEADER[] = "Outp Set Cnt"; +const UBYTE TXT_MOTOR_STOP[] = "Bwd Stop Fwd"; + +const UBYTE TXT_RCX[] = " RCX test "; +const UBYTE TXT_RCX_STOP[] = "Inp Disp Outp"; +const UBYTE TXT_RCX_INPUT_PASIVE[] = "Input pasive Tst"; +const UBYTE TXT_RCX_INPUT_ACTIVE[] = "Input active Tst"; +const UBYTE TXT_RCX_INPUT_SELECT[] = "Pas. Act. Dig."; +const UBYTE TXT_RCX_INPUT_DIGITAL[] = "Digital I/O Tst"; +const UBYTE TXT_RCX_DIGITAL_OK[] = " OK "; +const UBYTE TXT_RCX_DIGITAL_FAIL[] = " FAIL "; +const UBYTE TXT_MOTOR_NEXT[] = "Bwd Next Fwd"; + + +void TestPrgRunMotor(UBYTE No,SBYTE Speed) +{ + pMapOutPut->Outputs[No].Mode = MOTORON | BRAKE; + pMapOutPut->Outputs[No].Speed = Speed; + pMapOutPut->Outputs[No].TachoLimit = 0; + pMapOutPut->Outputs[No].RunState = MOTOR_RUN_STATE_RUNNING; + pMapOutPut->Outputs[No].Flags = UPDATE_MODE | UPDATE_SPEED | UPDATE_TACHO_LIMIT; +} + +void TestPrgFloatMotor(UBYTE No) +{ + pMapOutPut->Outputs[No].Mode = 0; + pMapOutPut->Outputs[No].Speed = 0; + pMapOutPut->Outputs[No].TachoLimit = 0; + pMapOutPut->Outputs[No].RunState = MOTOR_RUN_STATE_RUNNING; + pMapOutPut->Outputs[No].Flags = UPDATE_MODE | UPDATE_SPEED | UPDATE_TACHO_LIMIT; +} + +SBYTE TestPrgReadMotor(UBYTE No) +{ + return ((SBYTE)(pMapOutPut->Outputs[No].TachoCnt / 360)); +} + +#endif + + +UBYTE TestPrg(UBYTE Dummy) +{ + static UWORD Count; + static UBYTE TxtBuffer[TEXTLINES][DISPLAYLINE_LENGTH + 1]; + static UBYTE State = SYSTEM_INIT; +#ifdef TESTPRG + static UWORD Pointer; + static UWORD InputValues[NO_OF_INPUTS]; + static SWORD OutputValues[NO_OF_OUTPUTS]; + static UBYTE VolumeSave; + static UBYTE Timer; + static UBYTE SubState = 0; + UBYTE Tmp; +#endif + + Dummy = Dummy; + switch (State) + { + case SYSTEM_INIT : + { + GetProtocolVersion(TxtBuffer[0]); + GetARMBuild(TxtBuffer[1]); + GetAVRBuild(TxtBuffer[2]); + GetBC4Build(TxtBuffer[3]); + GetBC4Address(TxtBuffer[4]); + + pMapDisplay->pTextLines[TEXTLINE_3] = (UBYTE*)TxtBuffer[0]; + pMapDisplay->pTextLines[TEXTLINE_4] = (UBYTE*)TxtBuffer[1]; + pMapDisplay->pTextLines[TEXTLINE_5] = (UBYTE*)TxtBuffer[2]; + pMapDisplay->pTextLines[TEXTLINE_6] = (UBYTE*)TxtBuffer[3]; + pMapDisplay->pTextLines[TEXTLINE_7] = (UBYTE*)TxtBuffer[4]; + pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_EMPTY; + pMapDisplay->UpdateMask |= (TEXTLINE_BIT(TEXTLINE_3) | TEXTLINE_BIT(TEXTLINE_4) | TEXTLINE_BIT(TEXTLINE_5) | TEXTLINE_BIT(TEXTLINE_6) | TEXTLINE_BIT(TEXTLINE_7) | TEXTLINE_BIT(TEXTLINE_8)); + +#ifdef TESTPRG + SubState = 0; +#endif + State = SYSTEM_UNLOCK_INIT; + } + break; + +#ifndef TESTPRG + + case SYSTEM_UNLOCK_INIT : // ENTER * 1 + LEFT * 3 + RIGHT * 2 + ENTER * 1 = TEST MENU + { + if (cUiReadButtons() != BUTTON_NONE) + { + State = TSTPRG_SKIP; + } + } + break; + +#else + + case SYSTEM_UNLOCK_INIT : // ENTER * 1 + LEFT * 3 + RIGHT * 2 + ENTER * 1 = TEST MENU + { + Tmp = cUiReadButtons(); + switch (Tmp) + { + case BUTTON_ENTER : + { + switch (SubState) + { + case 0 : + { + SubState = 1; + Pointer = 0; + Count = 0; + } + break; + + case 3 : + { + State = SYSTEM_UNLOCK; + } + break; + + default : + { + Tmp = BUTTON_EXIT; + } + break; + + } + } + break; + + case BUTTON_NONE : + { + } + break; + + default : + { + switch (SubState) + { + case 0 : + { + Tmp = BUTTON_EXIT; + } + break; + + case 1 : + { + if (Tmp == BUTTON_LEFT) + { + if (++Count >= 3) + { + Count = 0; + SubState = 2; + } + Pointer = 0; + } + else + { + Tmp = BUTTON_EXIT; + } + } + break; + + case 2 : + { + if (Tmp == BUTTON_RIGHT) + { + if (++Count >= 2) + { + SubState = 3; + } + Pointer = 0; + } + else + { + Tmp = BUTTON_EXIT; + } + } + break; + + } + } + break; + + } + Pointer++; + if (((SubState) && (Pointer > 500)) || (Tmp == BUTTON_EXIT)) + { + State = TSTPRG_SKIP; + } + } + break; + + case SYSTEM_UNLOCK : + { + pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_TEST; + pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_8); + State = SYSTEM_PAGE; + } + break; + + case SYSTEM_PAGE : + { + switch (cUiReadButtons()) + { + case BUTTON_ENTER : + { + IOMapUi.Flags &= ~UI_ENABLE_STATUS_UPDATE; + pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_BACKGROUND); + State = TSTPRG_INIT; + } + break; + + case BUTTON_EXIT : + { + Count = 0; + State = TSTPRG_SKIP; + } + break; + + case BUTTON_LEFT : + { + IOMapUi.Flags &= ~UI_ENABLE_STATUS_UPDATE; + pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_BACKGROUND); + pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_2] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_3] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_4] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_5] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_6] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_7] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_TIMER; + pMapDisplay->EraseMask |= TEXTLINE_BITS; + pMapDisplay->UpdateMask |= TEXTLINE_BITS; + State = TIMER_INIT; + } + break; + + case BUTTON_RIGHT : + { + IOMapUi.Flags &= ~UI_ENABLE_STATUS_UPDATE; + pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_BACKGROUND); + pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_2] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_3] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_4] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_5] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_6] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_7] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_BT_PAGE; + if (DISPLAYLINE_LENGTH >= 16) + { + sprintf((char*)TxtBuffer[2],"Command %02X",(UWORD)VarsUi.BTCommand & 0xFF); + sprintf((char*)TxtBuffer[3],"Parameter 1 %02X",(UWORD)VarsUi.BTPar1 & 0xFF); + sprintf((char*)TxtBuffer[4],"Parameter 2 %02X",(UWORD)VarsUi.BTPar2 & 0xFF); + sprintf((char*)TxtBuffer[5],"Result %04X",(UWORD)VarsUi.BTResult); + pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_LAST; + pMapDisplay->pTextLines[TEXTLINE_2] = (UBYTE*)TXT_LINE; + pMapDisplay->pTextLines[TEXTLINE_3] = TxtBuffer[2]; + pMapDisplay->pTextLines[TEXTLINE_4] = TxtBuffer[3]; + pMapDisplay->pTextLines[TEXTLINE_5] = TxtBuffer[4]; + pMapDisplay->pTextLines[TEXTLINE_6] = TxtBuffer[5]; + } + pMapDisplay->EraseMask |= TEXTLINE_BITS; + pMapDisplay->UpdateMask |= TEXTLINE_BITS; + State = BT_PAGE; + } + break; + + } + } + break; + + case TIMER_INIT : + { + State = TIMER_SHOW; + } + break; + + case TIMER_SHOW : + { + sprintf((char*)TxtBuffer[2]," %10lu mS ",VarsUi.CRPasskey); + pMapDisplay->pTextLines[TEXTLINE_3] = TxtBuffer[2]; + pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3); + + switch (cUiReadButtons()) + { + case BUTTON_ENTER : + { + pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_TIMER_HOLD; + pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_8); + State = TIMER_HOLD; + } + break; + + case BUTTON_LEFT : + { + pMapDisplay->EraseMask |= TEXTLINE_BIT(TEXTLINE_3); + VarsUi.CRPasskey = 0L; + } + break; + + case BUTTON_EXIT : + { + State = TSTPRG_SKIP; + } + break; + + } + } + break; + + case TIMER_HOLD : + { + switch (cUiReadButtons()) + { + case BUTTON_ENTER : + { + pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_TIMER; + pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_8); + State = TIMER_SHOW; + } + break; + + case BUTTON_EXIT : + { + State = TSTPRG_SKIP; + } + break; + + } + } + break; + + case BT_PAGE : + { + switch (cUiReadButtons()) + { + case BUTTON_ENTER : + { + for (Count = 0;Count < TEXTLINES;Count++) + { + strcpy((char*)TxtBuffer[Count],(char*)TXT_EMPTY); + pMapDisplay->pTextLines[TEXTLINE_1 + Count] = TxtBuffer[Count]; + } + pMapDisplay->pTextLines[TEXTLINE_2] = (UBYTE*)TXT_LINE; + pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_BT_LIST; + pMapDisplay->EraseMask |= TEXTLINE_BITS; + pMapDisplay->UpdateMask |= TEXTLINE_BITS; + Pointer = 0; + State = BT_LIST_INIT; + } + break; + + case BUTTON_EXIT : + { + Count = 0; + State = TSTPRG_SKIP; + } + break; + + case BUTTON_LEFT : + { + State = BT_RESET; + } + break; + + case BUTTON_RIGHT : + { + pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_BTUPDATE; + pMapDisplay->pTextLines[TEXTLINE_2] = (UBYTE*)TXT_LINE; + pMapDisplay->pTextLines[TEXTLINE_3] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_4] = (UBYTE*)TXT_DONE; + pMapDisplay->pTextLines[TEXTLINE_5] = (UBYTE*)TXT_RESET; + pMapDisplay->pTextLines[TEXTLINE_6] = (UBYTE*)TXT_REBOOT; + pMapDisplay->pTextLines[TEXTLINE_7] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_EMPTY; + pMapDisplay->EraseMask |= TEXTLINE_BITS; + pMapDisplay->UpdateMask |= TEXTLINE_BITS; + Timer = 0; + State = BT_UPDATE_FW; + } + break; + + } + } + break; + + case BT_RESET : + { + VarsUi.BTCommand = (UBYTE)FACTORYRESET; + VarsUi.BTPar1 = (UBYTE)0; + VarsUi.BTPar2 = (UBYTE)0; + if (pMapComm->pFunc(VarsUi.BTCommand,VarsUi.BTPar1,VarsUi.BTPar2,0,NULL,&(VarsUi.BTResult)) == SUCCESS) + { + pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_2] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_3] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_4] = (UBYTE*)TXT_RESETTING; + pMapDisplay->pTextLines[TEXTLINE_5] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_6] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_7] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_EMPTY; + pMapDisplay->EraseMask |= TEXTLINE_BITS; + pMapDisplay->UpdateMask |= TEXTLINE_BITS; + State = BT_RESETTING; + } + else + { + State = TSTPRG_SKIP; + } + } + break; + + case BT_RESETTING : + { + if (VarsUi.BTResult != INPROGRESS) + { + State = TSTPRG_SKIP; + } + } + break; + + case BT_UPDATE_FW : + { + if (++Timer >= 100) + { + BtIo(); + } + } + break; + + case BT_LIST_INIT : + { + sprintf((char*)TxtBuffer[0],"DeviceTable No%2u",Pointer); + sprintf((char*)TxtBuffer[2],"%-*.*s",DISPLAYLINE_LENGTH,DISPLAYLINE_LENGTH,(char*)pMapComm->BtDeviceTable[Pointer].Name); + Count = (UWORD)sprintf((char*)TxtBuffer[3],"COD="); + for (Tmp = 0;(Tmp < SIZE_OF_CLASS_OF_DEVICE) && (Count < (DISPLAYLINE_LENGTH - 2));Tmp++) + { + Count += (UWORD)sprintf((char*)&TxtBuffer[3][Count],"%02X",(UWORD)(pMapComm->BtDeviceTable[Pointer].ClassOfDevice[Tmp]) & 0xFF); + } + Count = (UWORD)sprintf((char*)TxtBuffer[4],"A="); + for (Tmp = 0;(Tmp < SIZE_OF_BDADDR) && (Count <= (DISPLAYLINE_LENGTH - 2));Tmp++) + { + Count += (UWORD)sprintf((char*)&TxtBuffer[4][Count],"%02X",(UWORD)(pMapComm->BtDeviceTable[Pointer].BdAddr[Tmp]) & 0xFF); + } + sprintf((char*)TxtBuffer[5],"Status=%02X",(UWORD)(pMapComm->BtDeviceTable[Pointer].DeviceStatus) & 0xFF); + pMapDisplay->EraseMask |= TEXTLINE_BITS; + pMapDisplay->UpdateMask |= TEXTLINE_BITS; + State = BT_LIST; + } + break; + + case BT_LIST : + { + switch (cUiReadButtons()) + { + case BUTTON_ENTER : + { + for (Count = 0;Count < TEXTLINES;Count++) + { + strcpy((char*)TxtBuffer[Count],(char*)TXT_EMPTY); + pMapDisplay->pTextLines[TEXTLINE_1 + Count] = TxtBuffer[Count]; + } + pMapDisplay->pTextLines[TEXTLINE_2] = (UBYTE*)TXT_LINE; + pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_BT_CONN; + pMapDisplay->EraseMask |= TEXTLINE_BITS; + pMapDisplay->UpdateMask |= TEXTLINE_BITS; + Pointer = 0; + State = BT_CONN_INIT; + } + break; + + case BUTTON_EXIT : + { + State = SYSTEM_INIT; + } + break; + + case BUTTON_LEFT : + { + if (Pointer) + { + Pointer--; + } + else + { + Pointer = (SIZE_OF_BT_DEVICE_TABLE - 1); + } + State = BT_LIST_INIT; + } + break; + + case BUTTON_RIGHT : + { + if (Pointer < (SIZE_OF_BT_DEVICE_TABLE - 1)) + { + Pointer++; + } + else + { + Pointer = 0; + } + State = BT_LIST_INIT; + } + break; + + } + } + break; + + case BT_CONN_INIT : + { + sprintf((char*)TxtBuffer[0],"Conn. Table No%2u",Pointer); + sprintf((char*)TxtBuffer[2],"%-*.*s",DISPLAYLINE_LENGTH,DISPLAYLINE_LENGTH,(char*)pMapComm->BtConnectTable[Pointer].Name); + Count = (UWORD)sprintf((char*)TxtBuffer[3],"COD="); + for (Tmp = 0;(Tmp < SIZE_OF_CLASS_OF_DEVICE) && (Count < (DISPLAYLINE_LENGTH - 2));Tmp++) + { + Count += (UWORD)sprintf((char*)&TxtBuffer[3][Count],"%02X",(UWORD)(pMapComm->BtConnectTable[Pointer].ClassOfDevice[Tmp]) & 0xFF); + } + Count = (UWORD)sprintf((char*)TxtBuffer[4],"A="); + for (Tmp = 0;(Tmp < SIZE_OF_BDADDR) && (Count <= (DISPLAYLINE_LENGTH - 2));Tmp++) + { + Count += (UWORD)sprintf((char*)&TxtBuffer[4][Count],"%02X",(UWORD)(pMapComm->BtConnectTable[Pointer].BdAddr[Tmp]) & 0xFF); + } + sprintf((char*)TxtBuffer[5],"%-*.*s",DISPLAYLINE_LENGTH,DISPLAYLINE_LENGTH,(char*)pMapComm->BtConnectTable[Pointer].PinCode); + if (DISPLAYLINE_LENGTH >= 16) + { + sprintf((char*)TxtBuffer[6],"H=%02X S=%02X Q=%02X",(UWORD)(pMapComm->BtConnectTable[Pointer].HandleNr) & 0xFF,(UWORD)(pMapComm->BtConnectTable[Pointer].StreamStatus) & 0xFF,(UWORD)(pMapComm->BtConnectTable[Pointer].LinkQuality) & 0xFF); + } + pMapDisplay->EraseMask |= TEXTLINE_BITS; + pMapDisplay->UpdateMask |= TEXTLINE_BITS; + State = BT_CONN; + } + break; + + case BT_CONN : + { + switch (cUiReadButtons()) + { + case BUTTON_ENTER : + { + State = BT_CONN_INIT; + } + break; + + case BUTTON_EXIT : + { + State = SYSTEM_INIT; + } + break; + + case BUTTON_LEFT : + { + if (Pointer) + { + Pointer--; + } + else + { + Pointer = (SIZE_OF_BT_CONNECT_TABLE - 1); + } + State = BT_CONN_INIT; + } + break; + + case BUTTON_RIGHT : + { + if (Pointer < (SIZE_OF_BT_CONNECT_TABLE - 1)) + { + Pointer++; + } + else + { + Pointer = 0; + } + State = BT_CONN_INIT; + } + break; + + } + } + break; + + case TSTPRG_INIT : + { + IOMapUi.Flags &= ~UI_ENABLE_STATUS_UPDATE; + + pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_BACKGROUND); + + pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_TESTPRG; + pMapDisplay->pTextLines[TEXTLINE_2] = (UBYTE*)TXT_LINE; + pMapDisplay->pTextLines[TEXTLINE_3] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_4] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_5] = (UBYTE*)TXT_SELECT; + pMapDisplay->pTextLines[TEXTLINE_6] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_7] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_SUBTEST; + pMapDisplay->UpdateMask |= TEXTLINE_BITS; + + State = TSTPRG_SELECT_SUBTEST; + } + break; + + case TSTPRG_SELECT_SUBTEST : + { + switch (cUiReadButtons()) + { + case BUTTON_LEFT : + { + State = TSTPRG_SENSOR_INIT; + } + break; + + case BUTTON_RIGHT : + { + State = TSTPRG_MOTOR_INIT; + } + break; + + case BUTTON_ENTER : + { + State = TSTPRG_RCX_INIT; + } + break; + + case BUTTON_EXIT : + { + Count = 0; + State = TSTPRG_SKIP; + } + break; + + } + } + break; + + case TSTPRG_SENSOR_INIT : + { + pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_TESTPRG; + pMapDisplay->pTextLines[TEXTLINE_2] = (UBYTE*)TXT_LINE; + pMapDisplay->pTextLines[TEXTLINE_3] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_4] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_5] = (UBYTE*)TXT_SELECT_SENSOR; + pMapDisplay->pTextLines[TEXTLINE_6] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_7] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_SENSORS; + pMapDisplay->UpdateMask |= TEXTLINE_BITS; + + for (Count = 0;Count < NO_OF_INPUTS;Count++) + { + InputValues[Count] = 0x7FFF; + strcpy((char*)TxtBuffer[Count]," "); + } + + State = TSTPRG_SELECT_SENSOR; + } + break; + + case TSTPRG_SELECT_SENSOR : + { + switch (cUiReadButtons()) + { + case BUTTON_LEFT : + { + State = TSTPRG_TOUCH_SENSOR_INIT; + } + break; + + case BUTTON_ENTER : + { + pMapDisplay->pTextLines[TEXTLINE_5] = (UBYTE*)TXT_SELECT_TYPE; + pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_SOUND_SENSORS; + pMapDisplay->UpdateMask |= TEXTLINE_BITS; + State = TSTPRG_SOUND_SENSOR_SELECT; + } + break; + + case BUTTON_RIGHT : + { + pMapDisplay->pTextLines[TEXTLINE_5] = (UBYTE*)TXT_SELECT_TYPE; + pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_LIGHT_SENSORS; + pMapDisplay->UpdateMask |= TEXTLINE_BITS; + State = TSTPRG_LIGHT_SENSOR_SELECT; + } + break; + + case BUTTON_EXIT : + { + State = TSTPRG_INIT; + } + break; + + } + } + break; + + case TSTPRG_TOUCH_SENSOR_INIT : + { + for (Count = 0;Count < NO_OF_INPUTS;Count++) + { + pMapDisplay->pTextLines[TEXTLINE_3 + Count] = TxtBuffer[Count]; + } + pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_SENSOR_TOUCH; + pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_SUBTEST_STOP; + pMapDisplay->UpdateMask |= TEXTLINE_BITS; + for (Count = 0;Count < NO_OF_INPUTS;Count++) + { + pMapInput->Inputs[Count].SensorType = SWITCH; + } + State = TSTPRG_TOUCH_SENSOR; + } + break; + + case TSTPRG_TOUCH_SENSOR : + { + for (Count = 0;Count < NO_OF_INPUTS;Count++) + { + if (InputValues[Count] != pMapInput->Inputs[Count].ADRaw) + { + InputValues[Count] = pMapInput->Inputs[Count].ADRaw; + sprintf((char*)TxtBuffer[Count]," Input %u = %4u ",(UWORD)Count + 1,(UWORD)InputValues[Count]); + pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3 + Count); + } + } + if (cUiReadButtons() != BUTTON_NONE) + { + State = TSTPRG_SKIP_SENSOR; + } + } + break; + + case TSTPRG_SOUND_SENSOR_SELECT : + { + switch (cUiReadButtons()) + { + case BUTTON_LEFT : + { + pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_SENSOR_SOUND_DB; + for (Count = 0;Count < NO_OF_INPUTS;Count++) + { + pMapInput->Inputs[Count].SensorType = SOUND_DB; + } + State = TSTPRG_SOUND_SENSOR_INIT; + } + break; + + case BUTTON_ENTER : + { + State = TSTPRG_SKIP_SENSOR; + } + break; + + case BUTTON_EXIT : + { + State = TSTPRG_SKIP_SENSOR; + } + break; + + case BUTTON_RIGHT : + { + pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_SENSOR_SOUND_DBA; + for (Count = 0;Count < NO_OF_INPUTS;Count++) + { + pMapInput->Inputs[Count].SensorType = SOUND_DBA; + } + State = TSTPRG_SOUND_SENSOR_INIT; + } + break; + + } + } + break; + + case TSTPRG_SOUND_SENSOR_INIT : + { + VolumeSave = pMapSound->Volume; + pMapSound->Volume = MAX_VOLUME; + for (Count = 0;Count < NO_OF_INPUTS;Count++) + { + pMapDisplay->pTextLines[TEXTLINE_3 + Count] = TxtBuffer[Count]; + } + pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_SOUND_STOP; + pMapDisplay->UpdateMask |= TEXTLINE_BITS; + State = TSTPRG_SOUND_SENSOR; + } + break; + + case TSTPRG_SOUND_SENSOR : + { + for (Count = 0;Count < NO_OF_INPUTS;Count++) + { + if (InputValues[Count] != pMapInput->Inputs[Count].ADRaw) + { + InputValues[Count] = pMapInput->Inputs[Count].ADRaw; + sprintf((char*)TxtBuffer[Count]," Input %u = %4u ",(UWORD)Count + 1,(UWORD)InputValues[Count]); + pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3 + Count); + } + } + switch (cUiReadButtons()) + { + case BUTTON_LEFT : + { + pMapSound->Freq = 440; + pMapSound->Duration = 2000; + pMapSound->Mode = SOUND_TONE; + pMapSound->Flags |= SOUND_UPDATE; + } + break; + + case BUTTON_ENTER : + { + pMapSound->State = SOUND_STOP; + pMapSound->Volume = VolumeSave; + State = TSTPRG_SKIP_SENSOR; + } + break; + + case BUTTON_EXIT : + { + pMapSound->State = SOUND_STOP; + pMapSound->Volume = VolumeSave; + State = TSTPRG_SKIP_SENSOR; + } + break; + + case BUTTON_RIGHT : + { + pMapSound->Freq = 4000; + pMapSound->Duration = 2000; + pMapSound->Mode = SOUND_TONE; + pMapSound->Flags |= SOUND_UPDATE; + } + break; + + } + } + break; + + case TSTPRG_LIGHT_SENSOR_SELECT : + { + switch (cUiReadButtons()) + { + case BUTTON_LEFT : + { + pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_SENSOR_LIGHT_PASIVE; + for (Count = 0;Count < NO_OF_INPUTS;Count++) + { + pMapInput->Inputs[Count].SensorType = LIGHT_INACTIVE; + } + State = TSTPRG_LIGHT_SENSOR_INIT; + } + break; + + case BUTTON_ENTER : + { + State = TSTPRG_SKIP_SENSOR; + } + break; + + case BUTTON_EXIT : + { + State = TSTPRG_SKIP_SENSOR; + } + break; + + case BUTTON_RIGHT : + { + pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_SENSOR_LIGHT_ACTIVE; + for (Count = 0;Count < NO_OF_INPUTS;Count++) + { + pMapInput->Inputs[Count].SensorType = LIGHT_ACTIVE; + } + State = TSTPRG_LIGHT_SENSOR_INIT; + } + break; + + } + } + break; + + case TSTPRG_LIGHT_SENSOR_INIT : + { + for (Count = 0;Count < NO_OF_INPUTS;Count++) + { + pMapDisplay->pTextLines[TEXTLINE_3 + Count] = TxtBuffer[Count]; + } + pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_SUBTEST_STOP; + pMapDisplay->UpdateMask |= TEXTLINE_BITS; + State = TSTPRG_LIGHT_SENSOR; + } + break; + + case TSTPRG_LIGHT_SENSOR : + { + for (Count = 0;Count < NO_OF_INPUTS;Count++) + { + if (InputValues[Count] != pMapInput->Inputs[Count].ADRaw) + { + InputValues[Count] = pMapInput->Inputs[Count].ADRaw; + sprintf((char*)TxtBuffer[Count]," Input %u = %4u ",(UWORD)Count + 1,(UWORD)InputValues[Count]); + pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3 + Count); + } + } + if (cUiReadButtons() != BUTTON_NONE) + { + State = TSTPRG_SKIP_SENSOR; + } + } + break; + + case TSTPRG_SKIP_SENSOR : + { + for (Count = 0;Count < NO_OF_INPUTS;Count++) + { + pMapInput->Inputs[Count].SensorType = NO_SENSOR; + } + State = TSTPRG_SENSOR_INIT; + } + break; + + case TSTPRG_MOTOR_INIT : + { + pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_MOTOR; + pMapDisplay->pTextLines[TEXTLINE_2] = (UBYTE*)TXT_LINE; + pMapDisplay->pTextLines[TEXTLINE_3] = (UBYTE*)TXT_MOTOR_HEADER; + pMapDisplay->pTextLines[TEXTLINE_4] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_5] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_6] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_7] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_MOTOR_STOP; + + for (Count = 0;Count < NO_OF_OUTPUTS;Count++) + { + OutputValues[Count] = 0x7FFF; + TestPrgRunMotor(Count,0); + strcpy((char*)TxtBuffer[Count]," "); + pMapDisplay->pTextLines[TEXTLINE_4 + Count] = TxtBuffer[Count]; + } + + pMapDisplay->UpdateMask |= TEXTLINE_BITS; + State = TSTPRG_MOTOR; + } + break; + + case TSTPRG_MOTOR : + { + for (Count = 0;Count < NO_OF_OUTPUTS;Count++) + { + if (OutputValues[Count] != (SWORD)TestPrgReadMotor(Count)) + { + OutputValues[Count] = (SWORD)TestPrgReadMotor(Count); + sprintf((char*)TxtBuffer[Count]," %c %-4d %4d",(char)Count + 'A',(SWORD)pMapOutPut->Outputs[Count].Speed,OutputValues[Count]); + pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_4 + Count); + } + } + switch (cUiReadButtons()) + { + case BUTTON_LEFT : + { + for (Count = 0;Count < NO_OF_OUTPUTS;Count++) + { + OutputValues[Count] = 0x7FFF; + TestPrgRunMotor(Count,-50); + } + } + break; + + case BUTTON_ENTER : + { + for (Count = 0;Count < NO_OF_OUTPUTS;Count++) + { + OutputValues[Count] = 0x7FFF; + TestPrgRunMotor(Count,0); + } + } + break; + + case BUTTON_EXIT : + { + State = TSTPRG_SKIP_MOTOR; + } + break; + + case BUTTON_RIGHT : + { + for (Count = 0;Count < NO_OF_OUTPUTS;Count++) + { + OutputValues[Count] = 0x7FFF; + TestPrgRunMotor(Count,50); + } + } + break; + + } + } + break; + + case TSTPRG_SKIP_MOTOR : + { + for (Count = 0;Count < NO_OF_OUTPUTS;Count++) + { + TestPrgFloatMotor(Count); + } + State = TSTPRG_INIT; + } + break; + + case TSTPRG_RCX_INIT : + { + pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_RCX; + pMapDisplay->pTextLines[TEXTLINE_2] = (UBYTE*)TXT_LINE; + pMapDisplay->pTextLines[TEXTLINE_3] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_4] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_5] = (UBYTE*)TXT_SELECT; + pMapDisplay->pTextLines[TEXTLINE_6] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_7] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_RCX_STOP; + + pMapDisplay->UpdateMask |= TEXTLINE_BITS; + State = TSTPRG_RCX_SELECT; + } + break; + + case TSTPRG_RCX_SELECT : + { + switch (cUiReadButtons()) + { + case BUTTON_LEFT : + { + pMapDisplay->pTextLines[TEXTLINE_5] = (UBYTE*)TXT_SELECT_TYPE; + pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_RCX_INPUT_SELECT; + pMapDisplay->UpdateMask |= TEXTLINE_BITS; + for (Count = 0;Count < NO_OF_INPUTS;Count++) + { + InputValues[Count] = 0x7FFF; + strcpy((char*)TxtBuffer[Count]," "); + } + State = TSTPRG_RCX_INPUT_SELECT; + } + break; + + case BUTTON_ENTER : + { + State = TSTPRG_RCX_DISPLAY_INIT; + } + break; + + case BUTTON_RIGHT : + { + State = TSTPRG_RCX_MOTOR_INIT; + } + break; + + case BUTTON_EXIT : + { + State = TSTPRG_INIT; + } + break; + + } + } + break; + + case TSTPRG_RCX_DISPLAY_INIT : + { + Count = 0; + pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_BACKGROUND); + State = TSTPRG_RCX_DISPLAY; + } + break; + + case TSTPRG_RCX_DISPLAY : + { + if ((Count & 0x7FF) == 0x000) + { + pMapDisplay->pScreens[SCREEN_BACKGROUND] = (BMPMAP*)Test1; + pMapDisplay->UpdateMask |= SCREEN_BIT(SCREEN_BACKGROUND); + } + if ((Count & 0x7FF) == 0x3FF) + { + pMapDisplay->pScreens[SCREEN_BACKGROUND] = (BMPMAP*)Test2; + pMapDisplay->UpdateMask |= SCREEN_BIT(SCREEN_BACKGROUND); + } + Count++; + if (cUiReadButtons() != BUTTON_NONE) + { + State = TSTPRG_SKIP_RCX; + } + } + break; + + case TSTPRG_RCX_INPUT_SELECT : + { + switch (cUiReadButtons()) + { + case BUTTON_LEFT : + { + pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_RCX_INPUT_PASIVE; + for (Count = 0;Count < NO_OF_INPUTS;Count++) + { + pMapInput->Inputs[Count].SensorType = SWITCH; + } + State = TSTPRG_RCX_INPUT_INIT; + } + break; + + case BUTTON_ENTER : + { + pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_RCX_INPUT_ACTIVE; + for (Count = 0;Count < NO_OF_INPUTS;Count++) + { + pMapInput->Inputs[Count].SensorType = REFLECTION; + } + State = TSTPRG_RCX_INPUT_INIT; + } + break; + + case BUTTON_EXIT : + { + State = TSTPRG_SKIP_RCX; + } + break; + + case BUTTON_RIGHT : + { + pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_RCX_INPUT_DIGITAL; + pMapDisplay->pTextLines[TEXTLINE_2] = (UBYTE*)TXT_LINE; + pMapDisplay->pTextLines[TEXTLINE_3] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_4] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_5] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_6] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_7] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_SUBTEST_STOP; + pMapDisplay->UpdateMask |= TEXTLINE_BITS; + for (Count = 0;Count < NO_OF_INPUTS;Count++) + { + pMapInput->Inputs[Count].SensorType = CUSTOM; + } + SubState = 0; + Timer = 0; + State = TSTPRG_RCX_DIGITAL_INIT; + } + break; + + } + } + break; + + case TSTPRG_RCX_INPUT_INIT : + { + for (Count = 0;Count < NO_OF_INPUTS;Count++) + { + pMapDisplay->pTextLines[TEXTLINE_3 + Count] = TxtBuffer[Count]; + } + pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_SUBTEST_STOP; + pMapDisplay->UpdateMask |= TEXTLINE_BITS; + State = TSTPRG_RCX_INPUT; + Timer = 0; + } + break; + + case TSTPRG_RCX_INPUT : + { + if (++Timer >= 250) + { + Timer = 0; + for (Count = 0;Count < NO_OF_INPUTS;Count++) + { + if (InputValues[Count] != pMapInput->Inputs[Count].ADRaw) + { + InputValues[Count] = pMapInput->Inputs[Count].ADRaw; + sprintf((char*)TxtBuffer[Count]," Input %u = %4u ",(UWORD)Count + 1,(UWORD)InputValues[Count]); + pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3 + Count); + } + } + } + if (cUiReadButtons() != BUTTON_NONE) + { + State = TSTPRG_SKIP_RCX; + } + } + break; + + case TSTPRG_RCX_DIGITAL_INIT : + { + if (++Timer >= 20) + { + Timer = 0; + switch (SubState) + { + case 0 : + { + pMapInput->Inputs[0].DigiPinsDir |= DIGI0; // Digi 1-0 output -, + pMapInput->Inputs[0].DigiPinsDir &= ~DIGI1; // Digi 1-1 input -, | + pMapInput->Inputs[2].DigiPinsDir &= ~DIGI0; // Digi 3-0 input | -' + pMapInput->Inputs[2].DigiPinsDir |= DIGI1; // Digi 3-1 output -' + + pMapInput->Inputs[0].DigiPinsOut |= DIGI0; // Digi 1-0 output high + pMapInput->Inputs[2].DigiPinsOut &= ~DIGI1; // Digi 3-1 output low + + SubState++; + } + break; + + case 1 : + { + if ((pMapInput->Inputs[2].DigiPinsIn & DIGI0) && !(pMapInput->Inputs[0].DigiPinsIn & DIGI1)) + { + pMapInput->Inputs[0].DigiPinsOut &= ~DIGI0; // Digi 1-0 output low + pMapInput->Inputs[2].DigiPinsOut |= DIGI1; // Digi 3-1 output high + + SubState++; + } + else + { + State = TSTPRG_RCX_DIGITAL_FAIL; + } + } + break; + + case 2 : + { + if (!(pMapInput->Inputs[2].DigiPinsIn & DIGI0) && (pMapInput->Inputs[0].DigiPinsIn & DIGI1)) + { + pMapInput->Inputs[0].DigiPinsDir &= ~DIGI0; // Digi 1-0 input + pMapInput->Inputs[0].DigiPinsDir &= ~DIGI1; // Digi 1-1 input + pMapInput->Inputs[2].DigiPinsDir &= ~DIGI0; // Digi 3-0 input + pMapInput->Inputs[2].DigiPinsDir &= ~DIGI1; // Digi 3-1 input + + pMapInput->Inputs[1].DigiPinsDir |= DIGI0; // Digi 2-0 output -, + pMapInput->Inputs[1].DigiPinsDir &= ~DIGI1; // Digi 2-1 input -, | + pMapInput->Inputs[3].DigiPinsDir &= ~DIGI0; // Digi 4-0 input | -' + pMapInput->Inputs[3].DigiPinsDir |= DIGI1; // Digi 4-1 output -' + + pMapInput->Inputs[1].DigiPinsOut |= DIGI0; // Digi 2-0 output high + pMapInput->Inputs[3].DigiPinsOut &= ~DIGI1; // Digi 4-1 output low + + SubState++; + } + else + { + State = TSTPRG_RCX_DIGITAL_FAIL; + } + } + break; + + case 3 : + { + if ((pMapInput->Inputs[3].DigiPinsIn & DIGI0) && !(pMapInput->Inputs[1].DigiPinsIn & DIGI1)) + { + pMapInput->Inputs[1].DigiPinsOut &= ~DIGI0; // Digi 2-0 output low + pMapInput->Inputs[3].DigiPinsOut |= DIGI1; // Digi 4-1 output high + + SubState++; + } + else + { + State = TSTPRG_RCX_DIGITAL_FAIL; + } + } + break; + + case 4 : + { + if (!(pMapInput->Inputs[3].DigiPinsIn & DIGI0) && (pMapInput->Inputs[1].DigiPinsIn & DIGI1)) + { + pMapInput->Inputs[1].DigiPinsDir &= ~DIGI0; // Digi 2-0 input + pMapInput->Inputs[1].DigiPinsDir &= ~DIGI1; // Digi 2-1 input + pMapInput->Inputs[3].DigiPinsDir &= ~DIGI0; // Digi 4-0 input + pMapInput->Inputs[3].DigiPinsDir &= ~DIGI1; // Digi 4-1 input + + State = TSTPRG_RCX_DIGITAL_OK; + } + else + { + State = TSTPRG_RCX_DIGITAL_FAIL; + } + } + break; + + } + } + } + break; + + case TSTPRG_RCX_DIGITAL_OK : + { + pMapDisplay->pTextLines[TEXTLINE_5] = (UBYTE*)TXT_RCX_DIGITAL_OK; + pMapDisplay->UpdateMask |= TEXTLINE_BITS; + State = TSTPRG_RCX_DIGITAL; + } + break; + + case TSTPRG_RCX_DIGITAL_FAIL : + { + pMapDisplay->pTextLines[TEXTLINE_5] = (UBYTE*)TXT_RCX_DIGITAL_FAIL; + pMapDisplay->UpdateMask |= TEXTLINE_BITS; + State = TSTPRG_RCX_DIGITAL; + } + break; + + case TSTPRG_RCX_DIGITAL : + { + if (cUiReadButtons() != BUTTON_NONE) + { + State = TSTPRG_SKIP_RCX; + } + } + break; + + case TSTPRG_RCX_MOTOR_INIT : + { + pMapDisplay->pTextLines[TEXTLINE_1] = (UBYTE*)TXT_MOTOR; + pMapDisplay->pTextLines[TEXTLINE_2] = (UBYTE*)TXT_LINE; + pMapDisplay->pTextLines[TEXTLINE_3] = (UBYTE*)TXT_MOTOR_HEADER; + pMapDisplay->pTextLines[TEXTLINE_4] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_5] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_6] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_7] = (UBYTE*)TXT_EMPTY; + pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_MOTOR_NEXT; + + for (Count = 0;Count < NO_OF_OUTPUTS;Count++) + { + OutputValues[Count] = 0x7FFF; + TestPrgRunMotor(Count,0); + strcpy((char*)TxtBuffer[Count]," "); + pMapDisplay->pTextLines[TEXTLINE_4 + Count] = TxtBuffer[Count]; + } + + Pointer = 0; + pMapDisplay->UpdateMask |= TEXTLINE_BITS; + State = TSTPRG_RCX_MOTOR; + } + break; + + case TSTPRG_RCX_MOTOR : + { + for (Count = 0;Count < NO_OF_OUTPUTS;Count++) + { + if (OutputValues[Count] != (SWORD)TestPrgReadMotor(Count)) + { + OutputValues[Count] = (SWORD)TestPrgReadMotor(Count); + if (Pointer == Count) + { + sprintf((char*)TxtBuffer[Count],"> %c %-4d %4d",(char)Count + 'A',(SWORD)pMapOutPut->Outputs[Count].Speed,OutputValues[Count]); + } + else + { + sprintf((char*)TxtBuffer[Count]," %c %-4d %4d",(char)Count + 'A',(SWORD)pMapOutPut->Outputs[Count].Speed,OutputValues[Count]); + } + pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_4 + Count); + } + } + switch (cUiReadButtons()) + { + case BUTTON_LEFT : + { + for (Count = 0;Count < NO_OF_OUTPUTS;Count++) + { + OutputValues[Count] = 0x7FFF; + if (Pointer == Count) + { + TestPrgRunMotor(Count,-50); + } + else + { + TestPrgRunMotor(Count,0); + } + } + } + break; + + case BUTTON_ENTER : + { + for (Count = 0;Count < NO_OF_OUTPUTS;Count++) + { + OutputValues[Count] = 0x7FFF; + TestPrgRunMotor(Count,0); + } + if (++Pointer >= NO_OF_OUTPUTS) + { + State = TSTPRG_SKIP_RCX_MOTOR; + } + } + break; + + case BUTTON_EXIT : + { + State = TSTPRG_SKIP_RCX_MOTOR; + } + break; + + case BUTTON_RIGHT : + { + for (Count = 0;Count < NO_OF_OUTPUTS;Count++) + { + OutputValues[Count] = 0x7FFF; + if (Pointer == Count) + { + TestPrgRunMotor(Count,50); + } + else + { + TestPrgRunMotor(Count,0); + } + } + } + break; + + } + } + break; + + case TSTPRG_SKIP_RCX_MOTOR : + { + for (Count = 0;Count < NO_OF_OUTPUTS;Count++) + { + TestPrgFloatMotor(Count); + } + State = TSTPRG_RCX_INIT; + } + break; + + case TSTPRG_SKIP_RCX : + { + for (Count = 0;Count < NO_OF_INPUTS;Count++) + { + pMapInput->Inputs[Count].SensorType = NO_SENSOR; + } + pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_BACKGROUND); + State = TSTPRG_RCX_INIT; + } + break; + +#endif + + case TSTPRG_SKIP : + { + Count++; + if (Count == 100) + { + pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_BACKGROUND); + } + if (Count >= 200) + { + IOMapUi.Flags |= UI_REDRAW_STATUS; + State = 0; + } + } + break; + + default : + { + State = SYSTEM_INIT; + } + break; + + } + + return (State); +} diff --git a/src/Connections.txt b/src/Connections.txt new file mode 100644 index 0000000..3c20ed0 --- /dev/null +++ b/src/Connections.txt @@ -0,0 +1,23 @@ +DEFINE_DATA(ICON, Connections) = +{ + 0x04,0x00, // Graphics Format + 0x01,0x20, // Graphics DataSize + 0x01, // Graphics Count X + 0x04, // Graphics Count Y + 0x18, // Graphics Width + 0x18, // Graphics Height +BEGIN_DATA + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x00,0x40,0x40,0x00,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xDB,0x00,0x00,0x7E,0x81,0x81,0x7E,0x00,0x00,0xDB,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x00,0x02,0x02,0x00,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x00,0x40,0x40,0x00,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xDB,0x00,0x00,0x00,0x82,0xFF,0x80,0x00,0x00,0xDB,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x00,0x02,0x02,0x00,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x00,0x40,0x40,0x00,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xDB,0x00,0x00,0xE2,0x91,0x89,0x86,0x00,0x00,0xDB,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x00,0x02,0x02,0x00,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x00,0x40,0x40,0x00,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xDB,0x00,0x00,0x42,0x81,0x89,0x76,0x00,0x00,0xDB,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x00,0x02,0x02,0x00,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +END_DATA +}; diff --git a/src/Cursor.txt b/src/Cursor.txt new file mode 100644 index 0000000..69037cd --- /dev/null +++ b/src/Cursor.txt @@ -0,0 +1,13 @@ +#define sizeof_Cursor 15 +DEFINE_DATA(BMPMAP, Cursor) = +{ + 0x02,0x00, // Graphics Format + 0x00,0x08, // Graphics DataSize + 0x00, // Graphics Start X + 0x00, // Graphics Start Y + 0x07, // Graphics Width + 0x08, // Graphics Height +BEGIN_DATA + 0x21,0x31,0x39,0x3D,0x39,0x31,0x21 +END_DATA +}; diff --git a/src/Devices.txt b/src/Devices.txt new file mode 100644 index 0000000..cbfd564 --- /dev/null +++ b/src/Devices.txt @@ -0,0 +1,23 @@ +DEFINE_DATA(ICON, Devices) = +{ + 0x04,0x00, // Graphics Format + 0x01,0x20, // Graphics DataSize + 0x01, // Graphics Count X + 0x04, // Graphics Count Y + 0x18, // Graphics Width + 0x18, // Graphics Height +BEGIN_DATA + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x82,0x44,0x28,0xFF,0x11,0xAA,0x44,0x00,0x00,0x06,0x01,0x00,0x40,0x20,0x11,0x0E,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x48,0x48,0x78,0x48,0x48,0x78,0x48,0x48,0x78,0x48,0x48,0xF8,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x9E,0x91,0x51,0x51,0x51,0x91,0x9E,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x24,0x24,0x24,0x3C,0x25,0x25,0x25,0x3C,0x24,0x24,0x24,0x3F,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x70,0x08,0x30,0x40,0x40,0x40,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x4E,0x91,0x51,0x91,0x51,0x8E,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x10,0x11,0x12,0x11,0x12,0x11,0x12,0x10,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xBF,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xBF,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x06,0x07,0x05,0x06,0x05,0x06,0x05,0x06,0x05,0x06,0x05,0x06,0x05,0x07,0x06,0x00,0x00,0x00,0x00 +END_DATA +}; diff --git a/src/Display.txt b/src/Display.txt new file mode 100644 index 0000000..d1c2136 --- /dev/null +++ b/src/Display.txt @@ -0,0 +1,14 @@ +DEFINE_DATA(BMPMAP, Display) = +{ + 0x02,0x00, // Graphics Format + 0x00,0xD8, // Graphics DataSize + 0x0E, // Graphics Start X + 0x10, // Graphics Start Y + 0x48, // Graphics Width + 0x18, // Graphics Height +BEGIN_DATA + 0xF8,0xFC,0x0E,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0E,0xFC,0xF8,0xC0, + 0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF, + 0x0F,0x1F,0x38,0x30,0x30,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x78,0x7F,0x3F,0x1F +END_DATA +}; diff --git a/src/Fail.txt b/src/Fail.txt new file mode 100644 index 0000000..a213ec5 --- /dev/null +++ b/src/Fail.txt @@ -0,0 +1,14 @@ +DEFINE_DATA(BMPMAP, Fail) = +{ + 0x02,0x00, // Graphics Format + 0x00,0x48, // Graphics DataSize + 0x00, // Graphics Start X + 0x08, // Graphics Start Y + 0x18, // Graphics Width + 0x18, // Graphics Height +BEGIN_DATA + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x60,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x30,0x0C,0x03,0x00,0x7C,0x00,0x03,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x04,0x04,0x04,0x04,0x04,0x05,0x04,0x04,0x04,0x04,0x04,0x03,0x00,0x00,0x00,0x00,0x00 +END_DATA +}; diff --git a/src/Font.txt b/src/Font.txt new file mode 100644 index 0000000..0aa4303 --- /dev/null +++ b/src/Font.txt @@ -0,0 +1,17 @@ +DEFINE_DATA(ICON, Font) = +{ + 0x04,0x00, // Graphics Format + 0x02,0x40, // Graphics DataSize + 0x10, // Graphics Count X + 0x06, // Graphics Count Y + 0x06, // Graphics Width + 0x08, // Graphics Height +BEGIN_DATA + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x5F,0x06,0x00,0x00,0x07,0x03,0x00,0x07,0x03,0x00,0x24,0x7E,0x24,0x7E,0x24,0x00,0x24,0x2B,0x6A,0x12,0x00,0x00,0x63,0x13,0x08,0x64,0x63,0x00,0x30,0x4C,0x52,0x22,0x50,0x00,0x00,0x07,0x03,0x00,0x00,0x00,0x00,0x3E,0x41,0x00,0x00,0x00,0x00,0x41,0x3E,0x00,0x00,0x00,0x08,0x3E,0x1C,0x3E,0x08,0x00,0x08,0x08,0x3E,0x08,0x08,0x00,0x80,0x60,0x60,0x00,0x00,0x00,0x08,0x08,0x08,0x08,0x08,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x00, + 0x3E,0x51,0x49,0x45,0x3E,0x00,0x00,0x42,0x7F,0x40,0x00,0x00,0x62,0x51,0x49,0x49,0x46,0x00,0x22,0x49,0x49,0x49,0x36,0x00,0x18,0x14,0x12,0x7F,0x10,0x00,0x2F,0x49,0x49,0x49,0x31,0x00,0x3C,0x4A,0x49,0x49,0x30,0x00,0x01,0x71,0x09,0x05,0x03,0x00,0x36,0x49,0x49,0x49,0x36,0x00,0x06,0x49,0x49,0x29,0x1E,0x00,0x00,0x6C,0x6C,0x00,0x00,0x00,0x00,0xEC,0x6C,0x00,0x00,0x00,0x08,0x14,0x22,0x41,0x00,0x00,0x24,0x24,0x24,0x24,0x24,0x00,0x00,0x41,0x22,0x14,0x08,0x00,0x02,0x01,0x59,0x09,0x06,0x00, + 0x3E,0x41,0x5D,0x55,0x1E,0x00,0x7E,0x11,0x11,0x11,0x7E,0x00,0x7F,0x49,0x49,0x49,0x36,0x00,0x3E,0x41,0x41,0x41,0x22,0x00,0x7F,0x41,0x41,0x41,0x3E,0x00,0x7F,0x49,0x49,0x49,0x41,0x00,0x7F,0x09,0x09,0x09,0x01,0x00,0x3E,0x41,0x49,0x49,0x7A,0x00,0x7F,0x08,0x08,0x08,0x7F,0x00,0x00,0x41,0x7F,0x41,0x00,0x00,0x30,0x40,0x40,0x40,0x3F,0x00,0x7F,0x08,0x14,0x22,0x41,0x00,0x7F,0x40,0x40,0x40,0x40,0x00,0x7F,0x02,0x04,0x02,0x7F,0x00,0x7F,0x02,0x04,0x08,0x7F,0x00,0x3E,0x41,0x41,0x41,0x3E,0x00, + 0x7F,0x09,0x09,0x09,0x06,0x00,0x3E,0x41,0x51,0x21,0x5E,0x00,0x7F,0x09,0x09,0x19,0x66,0x00,0x26,0x49,0x49,0x49,0x32,0x00,0x01,0x01,0x7F,0x01,0x01,0x00,0x3F,0x40,0x40,0x40,0x3F,0x00,0x1F,0x20,0x40,0x20,0x1F,0x00,0x3F,0x40,0x3C,0x40,0x3F,0x00,0x63,0x14,0x08,0x14,0x63,0x00,0x07,0x08,0x70,0x08,0x07,0x00,0x71,0x49,0x45,0x43,0x00,0x00,0x00,0x7F,0x41,0x41,0x00,0x00,0x02,0x04,0x08,0x10,0x20,0x00,0x00,0x41,0x41,0x7F,0x00,0x00,0x04,0x02,0x01,0x02,0x04,0x00,0x80,0x80,0x80,0x80,0x80,0x00, + 0x00,0x02,0x05,0x02,0x00,0x00,0x20,0x54,0x54,0x54,0x78,0x00,0x7F,0x44,0x44,0x44,0x38,0x00,0x38,0x44,0x44,0x44,0x28,0x00,0x38,0x44,0x44,0x44,0x7F,0x00,0x38,0x54,0x54,0x54,0x08,0x00,0x08,0x7E,0x09,0x09,0x00,0x00,0x18,0x24,0xA4,0xA4,0xFC,0x00,0x7F,0x04,0x04,0x78,0x00,0x00,0x00,0x00,0x7D,0x40,0x00,0x00,0x40,0x80,0x84,0x7D,0x00,0x00,0x7F,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x7F,0x40,0x00,0x00,0x7C,0x04,0x18,0x04,0x78,0x00,0x7C,0x04,0x04,0x78,0x00,0x00,0x38,0x44,0x44,0x44,0x38,0x00, + 0xFC,0x44,0x44,0x44,0x38,0x00,0x38,0x44,0x44,0x44,0xFC,0x00,0x44,0x78,0x44,0x04,0x08,0x00,0x08,0x54,0x54,0x54,0x20,0x00,0x04,0x3E,0x44,0x24,0x00,0x00,0x3C,0x40,0x20,0x7C,0x00,0x00,0x1C,0x20,0x40,0x20,0x1C,0x00,0x3C,0x60,0x30,0x60,0x3C,0x00,0x6C,0x10,0x10,0x6C,0x00,0x00,0x9C,0xA0,0x60,0x3C,0x00,0x00,0x64,0x54,0x54,0x4C,0x00,0x00,0x08,0x3E,0x41,0x41,0x00,0x00,0x00,0x00,0x77,0x00,0x00,0x00,0x00,0x41,0x41,0x3E,0x08,0x00,0x02,0x01,0x02,0x01,0x00,0x00,0x10,0x20,0x40,0x38,0x07,0x00 +END_DATA +}; diff --git a/src/Functions.inl b/src/Functions.inl new file mode 100644 index 0000000..1424721 --- /dev/null +++ b/src/Functions.inl @@ -0,0 +1,4331 @@ +// +// Programmer +// +// Date init 26.04.2005 +// +// Reviser $Author:: Dktochpe $ +// +// Revision date $Date:: $ +// +// Filename $Workfile:: $ +// +// Version $Revision:: $ +// +// Archive $Archive:: $ +// +// Platform C +// + +//******* cUiBtTest ********************************************************** + +const UBYTE NONVOLATILE_NAME[] = UI_NONVOLATILE; // Non volatile filename without extention +const UBYTE DEFAULT_PROGRAM_NAME[] = UI_PROGRAM_DEFAULT; // On brick programming filename without extention +const UBYTE TEMP_PROGRAM_FILENAME[] = UI_PROGRAM_TEMP; // On brick programming tmp filename without extention +const UBYTE VM_PROGRAM_READER[] = UI_PROGRAM_READER; // On brick programming script reader filename without extention +const UBYTE TEMP_DATALOG_FILENAME[] = UI_DATALOG_TEMP; // On brick datalog tmp filename without extention +const UBYTE DEFAULT_DATALOG_NAME[] = UI_DATALOG_DEFAULT; // On brick datalog filename without extention +const UBYTE DEFAULT_PIN_CODE[] = UI_PINCODE_DEFAULT; // Default blue tooth pin code +const UBYTE TXT_INVALID_SENSOR[] = "??????????????"; // Display invalid sensor data + + +#define SENSORS (MENU_SENSOR_INVALID - MENU_SENSOR_EMPTY) + +const UBYTE SENSORTYPE[SENSORS] = // for view and datalog +{ + 0, // MENU_SENSOR_EMPTY + SOUND_DB, // MENU_SENSOR_SOUND_DB + SOUND_DBA, // MENU_SENSOR_SOUND_DBA + LIGHT_ACTIVE, // MENU_SENSOR_LIGHT + LIGHT_INACTIVE, // MENU_SENSOR_LIGHT_AMB + SWITCH, // MENU_SENSOR_TOUCH + 0, // MENU_SENSOR_MOTOR_DEG + 0, // MENU_SENSOR_MOTOR_ROT + LOWSPEED_9V, // MENU_SENSOR_ULTRASONIC_IN + LOWSPEED_9V, // MENU_SENSOR_ULTRASONIC_CM + LOWSPEED_9V, // MENU_SENSOR_IIC_TEMP_C + LOWSPEED_9V, // MENU_SENSOR_IIC_TEMP_F + COLORFULL // MENU_SENSOR_COLOR +}; + +const UBYTE SENSORMODE[SENSORS] = // for view and datalog +{ + 0, // MENU_SENSOR_EMPTY + PCTFULLSCALEMODE, // MENU_SENSOR_SOUND_DB + PCTFULLSCALEMODE, // MENU_SENSOR_SOUND_DBA + PCTFULLSCALEMODE, // MENU_SENSOR_LIGHT + PCTFULLSCALEMODE, // MENU_SENSOR_LIGHT_AMB + BOOLEANMODE, // MENU_SENSOR_TOUCH + 0, // MENU_SENSOR_MOTOR_DEG + 0, // MENU_SENSOR_MOTOR_ROT + 0, // MENU_SENSOR_ULTRASONIC_IN + 0, // MENU_SENSOR_ULTRASONIC_CM + 0, // MENU_SENSOR_IIC_TEMP_C + 0, // MENU_SENSOR_IIC_TEMP_F + 0 // MENU_SENSOR_COLOR +}; + +const UBYTE SENSORFORMAT[SENSORS][9] = +{ + "", // MENU_SENSOR_EMPTY + "%3.0f %%", // MENU_SENSOR_SOUND_DB + "%3.0f %%", // MENU_SENSOR_SOUND_DBA + "%3.0f %%", // MENU_SENSOR_LIGHT + "%3.0f %%", // MENU_SENSOR_LIGHT_AMB + "%1.0f", // MENU_SENSOR_TOUCH + "%8.0f `", // MENU_SENSOR_MOTOR_DEG + "%8.0f R", // MENU_SENSOR_MOTOR_ROT + "%3.0f In", // MENU_SENSOR_ULTRASONIC_IN + "%3.0f cm", // MENU_SENSOR_ULTRASONIC_CM + "%5.1f `C", // MENU_SENSOR_IIC_TEMP_C + "%5.1f `F", // MENU_SENSOR_IIC_TEMP_F + "%9.0f" // MENU_SENSOR_COLOR (no of characters) +}; + +const float SENSORDIVIDER[SENSORS] = +{ + 1.0f, // MENU_SENSOR_EMPTY + 1.0f, // MENU_SENSOR_SOUND_DB + 1.0f, // MENU_SENSOR_SOUND_DBA + 1.0f, // MENU_SENSOR_LIGHT + 1.0f, // MENU_SENSOR_LIGHT_AMB + 1.0f, // MENU_SENSOR_TOUCH + 1.0f, // MENU_SENSOR_MOTOR_DEG + 360.0f, // MENU_SENSOR_MOTOR_ROT + 2.54f, // MENU_SENSOR_ULTRASONIC_IN + 1.0f, // MENU_SENSOR_ULTRASONIC_CM + 10.0f, // MENU_SENSOR_IIC_TEMP_C + 10.0f, // MENU_SENSOR_IIC_TEMP_F + 1.0f // MENU_SENSOR_COLOR +}; + + +#define SENSORSYNCDATA "Sync data" +#define SENSORSDATA "Sdata" +#define SENSORTIME "Time" + + +const UBYTE SENSORDIRNAME[SENSORS - 1][19] = +{ + "Sound Sensor", // MENU_SENSOR_SOUND_DB + "Sound Sensor", // MENU_SENSOR_SOUND_DBA + "Light Sensor", // MENU_SENSOR_LIGHT + "Light Sensor", // MENU_SENSOR_LIGHT_AMB + "Bumper", // MENU_SENSOR_TOUCH + "FP Rotation Sensor", // MENU_SENSOR_MOTOR_DEG + "FP Rotation Sensor", // MENU_SENSOR_MOTOR_ROT + "Distance Sensor", // MENU_SENSOR_ULTRASONIC_IN + "Distance Sensor", // MENU_SENSOR_ULTRASONIC_CM + "NXT Temp Sensor", // MENU_SENSOR_IIC_TEMP_C + "NXT Temp Sensor", // MENU_SENSOR_IIC_TEMP_F + "Color Detector" // MENU_SENSOR_COLOR +}; + +const UBYTE SENSORUNITNAME[SENSORS - 1][5] = +{ + "_dB", // MENU_SENSOR_SOUND_DB + "_dBa", // MENU_SENSOR_SOUND_DBA + "_on", // MENU_SENSOR_LIGHT + "_off", // MENU_SENSOR_LIGHT_AMB + "", // MENU_SENSOR_TOUCH + "_deg", // MENU_SENSOR_MOTOR_DEG + "_rot", // MENU_SENSOR_MOTOR_ROT + "_in", // MENU_SENSOR_ULTRASONIC_IN + "_cm", // MENU_SENSOR_ULTRASONIC_CM + "_C", // MENU_SENSOR_IIC_TEMP_C + "_F", // MENU_SENSOR_IIC_TEMP_F + "_0", // MENU_SENSOR_COLOR +}; + +const UBYTE SENSORFORMAT2[SENSORS - 1][6] = +{ + "\t%.0f", // MENU_SENSOR_SOUND_DB + "\t%.0f", // MENU_SENSOR_SOUND_DBA + "\t%.0f", // MENU_SENSOR_LIGHT + "\t%.0f", // MENU_SENSOR_LIGHT_AMB + "\t%.0f", // MENU_SENSOR_TOUCH + "\t%.0f", // MENU_SENSOR_MOTOR_DEG + "\t%.0f", // MENU_SENSOR_MOTOR_ROT + "\t%.0f", // MENU_SENSOR_ULTRASONIC_IN + "\t%.0f", // MENU_SENSOR_ULTRASONIC_CM + "\t%.1f", // MENU_SENSOR_IIC_TEMP_C + "\t%.1f", // MENU_SENSOR_IIC_TEMP_F + "\t%.0f" // MENU_SENSOR_COLOR +}; + + +//******* cUiWriteLowspeed *************************************************** + +void cUiWriteLowspeed(UBYTE Port,UBYTE TxBytes,UBYTE *TxBuf,UBYTE RxBytes) +{ + Port -= MENU_PORT_1; + pMapLowSpeed->OutBuf[Port].InPtr = 0; + pMapLowSpeed->OutBuf[Port].OutPtr = 0; + + while (TxBytes) + { + pMapLowSpeed->OutBuf[Port].Buf[pMapLowSpeed->OutBuf[Port].InPtr] = *TxBuf; + pMapLowSpeed->OutBuf[Port].InPtr++; + TxBuf++; + TxBytes--; + } + pMapLowSpeed->InBuf[Port].BytesToRx = RxBytes; + pMapLowSpeed->ChannelState[Port] = LOWSPEED_INIT; + pMapLowSpeed->State |= (COM_CHANNEL_ONE_ACTIVE << Port); +} + + +//******* cUiReadLowspeed **************************************************** + +#define IIC_READY 0 +#define IIC_BUSY 1 +#define IIC_ERROR 2 + +UBYTE cUiReadLowspeed(UBYTE Port,UBYTE RxBytes,UWORD *Value) +{ + UBYTE Result; + + *Value = 0; + Port -= MENU_PORT_1; + if ((pMapLowSpeed->ChannelState[Port] == LOWSPEED_IDLE) || (pMapLowSpeed->ChannelState[Port] == LOWSPEED_DONE)) + { + while (RxBytes) + { + (*Value) <<= 8; + (*Value) |= (UWORD)(pMapLowSpeed->InBuf[Port].Buf[pMapLowSpeed->InBuf[Port].OutPtr]); + pMapLowSpeed->InBuf[Port].OutPtr++; + if (pMapLowSpeed->InBuf[Port].OutPtr >= SIZE_OF_LSBUF) + { + pMapLowSpeed->InBuf[Port].OutPtr = 0; + } + RxBytes--; + } + Result = IIC_READY; + } + else + { + if (pMapLowSpeed->ErrorType[Port] == LOWSPEED_CH_NOT_READY) + { + Result = IIC_ERROR; + } + else + { + Result = IIC_BUSY; + } + } + + return (Result); +} + + +//******* cUiUpdateSensor **************************************************** + +#define SENSOR_SETUP 0 +#define SENSOR_ACQUIRE 3 +#define SENSOR_READ 8 +#define SENSOR_STATES 10 + +void cUiUpdateSensor(SWORD Time) +{ + UBYTE Port; + UBYTE Sensor; + UBYTE Result; + SWORD Tmp; + + if (VarsUi.SensorReset == TRUE) + { + for (Port = MENU_PORT_1;Port < MENU_PORT_INVALID;Port++) + { + VarsUi.DatalogSampleValid[Port - MENU_PORT_1] = FALSE; + } + VarsUi.SensorTimer = (MIN_SENSOR_READ_TIME / SENSOR_STATES); + VarsUi.SensorState = SENSOR_SETUP; + } + + VarsUi.SensorTimer += Time; + if (VarsUi.SensorTimer >= (MIN_SENSOR_READ_TIME / SENSOR_STATES)) + { + VarsUi.SensorTimer -= (MIN_SENSOR_READ_TIME / SENSOR_STATES); + + for (Port = MENU_PORT_1;Port < MENU_PORT_INVALID;Port++) + { + Sensor = VarsUi.DatalogPort[Port - MENU_PORT_1]; + + if (Sensor != MENU_SENSOR_EMPTY) + { + if ((Sensor == MENU_SENSOR_MOTOR_DEG) || (Sensor == MENU_SENSOR_MOTOR_ROT)) + { + if (VarsUi.SensorReset == TRUE) + { + pMapOutPut->Outputs[Port - MENU_PORT_A].Mode &= ~(BRAKE | MOTORON); + pMapOutPut->Outputs[Port - MENU_PORT_A].Flags |= UPDATE_MODE | UPDATE_SPEED | UPDATE_RESET_COUNT; + pMapOutPut->Outputs[Port - MENU_PORT_A].TachoCnt = 0; + } + if (VarsUi.SensorState == SENSOR_READ) + { + VarsUi.DatalogSampleValue[Port - MENU_PORT_1] = pMapOutPut->Outputs[Port - MENU_PORT_A].TachoCnt; + VarsUi.DatalogSampleValid[Port - MENU_PORT_1] = TRUE; + } + } + else + { + pMapInput->Inputs[Port - MENU_PORT_1].SensorType = SENSORTYPE[Sensor - MENU_SENSOR_EMPTY]; + pMapInput->Inputs[Port - MENU_PORT_1].SensorMode = SENSORMODE[Sensor - MENU_SENSOR_EMPTY]; + if ((Sensor == MENU_SENSOR_ULTRASONIC_IN) || (Sensor == MENU_SENSOR_ULTRASONIC_CM)) + { + if (VarsUi.SensorReset == TRUE) + { + cUiWriteLowspeed(Port,3,"\x02\x41\x02",0); + } + if (VarsUi.SensorState == SENSOR_ACQUIRE) + { + cUiWriteLowspeed(Port,2,"\x02\x42",1); + } + if (VarsUi.SensorState == SENSOR_READ) + { + Result = cUiReadLowspeed(Port,1,(UWORD*)&Tmp); + if (Result == IIC_READY) + { + if ((UBYTE)Tmp != 0xFF) + { + VarsUi.DatalogSampleValue[Port - MENU_PORT_1] = (SLONG)Tmp; + VarsUi.DatalogSampleValid[Port - MENU_PORT_1] = TRUE; + } + else + { + VarsUi.DatalogSampleValid[Port - MENU_PORT_1] = FALSE; + } + } + else + { + VarsUi.DatalogSampleValid[Port - MENU_PORT_1] = FALSE; + } + } + } + else + { + if ((Sensor == MENU_SENSOR_IIC_TEMP_C) || (Sensor == MENU_SENSOR_IIC_TEMP_F)) + { + if (VarsUi.SensorState == SENSOR_SETUP) + { + cUiWriteLowspeed(Port,3,"\x98\x01\x60",0); + } + if (VarsUi.SensorState == SENSOR_ACQUIRE) + { + cUiWriteLowspeed(Port,2,"\x98\x00",2); + } + if (VarsUi.SensorState == SENSOR_READ) + { + Result = cUiReadLowspeed(Port,2,(UWORD*)&Tmp); + if (Result == IIC_READY) + { +// if (Tmp >= -14080) + { + if (Sensor == MENU_SENSOR_IIC_TEMP_F) + { + VarsUi.DatalogSampleValue[Port - MENU_PORT_1] = (SLONG)((float)(Tmp + 4544) / 14.2f); + } + else + { + VarsUi.DatalogSampleValue[Port - MENU_PORT_1] = (SLONG)((float)Tmp / 25.6f); + } + VarsUi.DatalogSampleValid[Port - MENU_PORT_1] = TRUE; + } + } + else + { + if (Result == IIC_ERROR) + { + VarsUi.DatalogSampleValid[Port - MENU_PORT_1] = FALSE; + } + } + } + } + else + { + if (VarsUi.SensorState == SENSOR_READ) + { + if (pMapInput->Inputs[Port - MENU_PORT_1].InvalidData != INVALID_DATA) + { + VarsUi.DatalogSampleValue[Port - MENU_PORT_1] = pMapInput->Inputs[Port - MENU_PORT_1].SensorValue; + VarsUi.DatalogSampleValid[Port - MENU_PORT_1] = TRUE; + } + else + { + VarsUi.DatalogSampleValid[Port - MENU_PORT_1] = FALSE; + } + } + } + } + } + } + } + + VarsUi.SensorState++; + if (VarsUi.SensorState >= SENSOR_STATES) + { + VarsUi.SensorState = SENSOR_SETUP; + } + + VarsUi.SensorReset = FALSE; + } +} + + +//******* cUiGetCustomPctFullScale ******************************************* + + +UBYTE cUiGetCustomPctFullScale(UBYTE Port,UBYTE Sensor) +{ + UBYTE Result = 0; + + if ((Sensor != MENU_SENSOR_MOTOR_DEG) && (Sensor != MENU_SENSOR_MOTOR_ROT)) + { + Result = (UBYTE)pMapInput->Inputs[Port - MENU_PORT_1].CustomPctFullScale; + } + + return (Result); +} + + + +//******* cUiGetCustomActiveStatus ******************************************* + + +UBYTE cUiGetCustomActiveStatus(UBYTE Port,UBYTE Sensor) +{ + UBYTE Result = 0; + + if ((Sensor != MENU_SENSOR_MOTOR_DEG) && (Sensor != MENU_SENSOR_MOTOR_ROT)) + { + Result = (UBYTE)pMapInput->Inputs[Port - MENU_PORT_1].CustomActiveStatus; + } + + return (Result); +} + + + +//******* cUiPrintSensorInDisplayBuffer ************************************** + +#define COLORNAMES 6 + +const UBYTE COLORNAME[COLORNAMES][10] = +{ + "1. Black ", + "2. Blue ", + "3. Green ", + "4. Yellow", + "5. Red ", + "6. White " +}; + + +void cUiPrintSensorInDisplayBuffer(UBYTE Port) +{ + UBYTE Sensor; + float Value; + SWORD Size; + SWORD Index; + + Port -= MENU_PORT_1; + Sensor = VarsUi.DatalogPort[Port] - MENU_SENSOR_EMPTY; + Value = (float)VarsUi.DatalogSampleValue[Port] / (float)SENSORDIVIDER[Sensor]; + Size = sprintf((char*)VarsUi.DisplayBuffer,(char*)SENSORFORMAT[Sensor],(float)0); + sprintf((char*)VarsUi.DisplayBuffer,"%*.*s",Size,Size,(char*)TXT_INVALID_SENSOR); + + if (VarsUi.DatalogSampleValid[Port] == TRUE) + { + if (Sensor == (MENU_SENSOR_COLOR - MENU_SENSOR_EMPTY)) + { + Index = (SWORD)Value - 1; + if ((Index >= 0) && (Index < COLORNAMES)) + { + sprintf((char*)VarsUi.DisplayBuffer,(char*)COLORNAME[Index]); + } + } + else + { + if (Size < sprintf((char*)VarsUi.DisplayBuffer,(char*)SENSORFORMAT[Sensor],Value)) + { + sprintf((char*)VarsUi.DisplayBuffer,"%*.*s",Size,Size,(char*)TXT_INVALID_SENSOR); + } + } + } +} + + +//******* cUiReleaseSensors ************************************************** + +void cUiReleaseSensors(void) +{ + UBYTE Tmp; + + for (Tmp = 0;Tmp < NO_OF_INPUTS;Tmp++) + { + pMapInput->Inputs[Tmp].SensorType = NO_SENSOR; + } +} + + + +//******* cUiBtCommand ******************************************************* + +enum +{ + UI_BT_CTRL, + + UI_BT_GET_DEVICES, // (UI_BT_GET_DEVICES,Known,*pDevices,NULL) [Known = 0,1] + UI_BT_GET_DEVICE_NAME, // (UI_BT_GET_DEVICE_NAME,Known,*pIndex,*pDeviceName) [Known = 0,1] + UI_BT_GET_DEVICE_TYPE, // (UI_BT_GET_DEVICE_TYPE,Known,*pIndex,*pDeviceType) [Known = 0,1] + + UI_BT_GET_CONNECTION_NAME, // (UI_BT_GET_CONNECTION_NAME,NULL,*pConnection,*pConnectionName) + UI_BT_GET_CONNECTION_TYPE, // (UI_BT_GET_CONNECTION_TYPE,NULL,*pConnection,*pConnectionType) + UI_BT_GET_CONNECTION_VALID, // (UI_BT_GET_CONNECTION_NAME,NULL,*pConnection,NULL) + + UI_BT_DUMMY +}; + + +#define UI_BT_FAILED 0x8200 // General command failed +#define UI_BT_SUCCES 0x0000 // Command executed succesfully + + +UBYTE cUiBTGetDeviceType(UBYTE *pCOD) +{ + ULONG COD; + UBYTE Result; + UBYTE Tmp; + + COD = 0; + for (Tmp = 0;Tmp < SIZE_OF_CLASS_OF_DEVICE;Tmp++) + { + COD <<= 8; + COD |= (ULONG)*pCOD; + pCOD++; + } + + Result = DEVICETYPE_UNKNOWN; + if ((COD & 0x00001FFF) == 0x00000804) + { + Result = DEVICETYPE_NXT; + } + if ((COD & 0x00001F00) == 0x00000200) + { + Result = DEVICETYPE_PHONE; + } + if ((COD & 0x00001F00) == 0x00000100) + { + Result = DEVICETYPE_PC; + } + + return (Result); +} + + +UBYTE cUiBTGetDeviceIndex(UBYTE Known,UBYTE No,UBYTE *pIndex) +{ + UBYTE Result = 0; + UBYTE Tmp; + + *pIndex = 0; + if (Known) + { + for (Tmp = 0;(Tmp < SIZE_OF_BT_DEVICE_TABLE) && (Result == 0);Tmp++) + { + if ((pMapComm->BtDeviceTable[Tmp].DeviceStatus & BT_DEVICE_KNOWN)) + { + if (No == *pIndex) + { + *pIndex = Tmp; + Result = ~0; + } + else + { + (*pIndex)++; + } + } + } + } + else + { + for (Tmp = 0;(Tmp < SIZE_OF_BT_DEVICE_TABLE) && (Result == 0);Tmp++) + { + if ((pMapComm->BtDeviceTable[Tmp].DeviceStatus & BT_DEVICE_UNKNOWN) || (pMapComm->BtDeviceTable[Tmp].DeviceStatus & BT_DEVICE_KNOWN)) + { + if (No == *pIndex) + { + *pIndex = Tmp; + Result = ~0; + } + else + { + (*pIndex)++; + } + } + } + } + + return (Result); +} + + +UWORD cUiBTCommand(UBYTE Cmd,UBYTE Flag,UBYTE *pParam1,UBYTE *pParam2) +{ + UWORD Result = UI_BT_FAILED; + + switch(Cmd) + { + case UI_BT_GET_DEVICES : + { + cUiBTGetDeviceIndex(Flag,SIZE_OF_BT_DEVICE_TABLE,pParam1); + Result = UI_BT_SUCCES; + } + break; + + case UI_BT_GET_DEVICE_NAME : + { + if ((*pParam1 < SIZE_OF_BT_DEVICE_TABLE) && (pParam2 != NULL)) + { + pParam2[0] = 0; + if (cUiBTGetDeviceIndex(Flag,*pParam1,&VarsUi.BTTmpIndex)) + { + sprintf((char*)pParam2,"%.*s",DISPLAYLINE_LENGTH,(char*)pMapComm->BtDeviceTable[VarsUi.BTTmpIndex].Name); + Result = UI_BT_SUCCES; + } + } + } + break; + + case UI_BT_GET_DEVICE_TYPE : + { + if ((*pParam1 < SIZE_OF_BT_DEVICE_TABLE) && (pParam2 != NULL)) + { + pParam2[0] = 0; + if (cUiBTGetDeviceIndex(Flag,*pParam1,&VarsUi.BTTmpIndex)) + { + pParam2[0] = cUiBTGetDeviceType(pMapComm->BtDeviceTable[VarsUi.BTTmpIndex].ClassOfDevice); + Result = UI_BT_SUCCES; + } + } + } + break; + + case UI_BT_GET_CONNECTION_NAME : + { + if (*pParam1 < SIZE_OF_BT_CONNECT_TABLE) + { + if (pMapComm->BtConnectTable[*pParam1].Name[0]) + { + if (pParam2 != NULL) + { + sprintf((char*)pParam2,"%.*s",DISPLAYLINE_LENGTH,(char*)pMapComm->BtConnectTable[*pParam1].Name); + } + Result = UI_BT_SUCCES; + } + else + { + if (pParam2 != NULL) + { + pParam2[0] = 0; + } + } + } + } + break; + + case UI_BT_GET_CONNECTION_TYPE : + { + if ((*pParam1 < SIZE_OF_BT_CONNECT_TABLE) && (pParam2 != NULL)) + { + pParam2[0] = 0; + if (pMapComm->BtConnectTable[*pParam1].Name[0]) + { + pParam2[0] = cUiBTGetDeviceType(pMapComm->BtConnectTable[*pParam1].ClassOfDevice); + Result = UI_BT_SUCCES; + } + } + } + break; + + case UI_BT_GET_CONNECTION_VALID : + { + if (*pParam1 < SIZE_OF_BT_CONNECT_TABLE) + { + if (pMapComm->BtConnectTable[*pParam1].Name[0]) + { + Result = UI_BT_SUCCES; + } + } + } + break; + + } + + return (Result); +} + + + +#include "BtTest.inc" + +//******* cUiNVxxxxx ********************************************************* + +void cUiNVWrite(void) +{ + sprintf((char*)VarsUi.NVFilename,"%s.%s",(char*)NONVOLATILE_NAME,(char*)TXT_SYS_EXT); + VarsUi.NVTmpHandle = pMapLoader->pFunc(FINDFIRST,VarsUi.NVFilename,VarsUi.SearchFilenameBuffer,&VarsUi.NVTmpLength); + if (!(VarsUi.NVTmpHandle & 0x8000)) + { + pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.NVTmpHandle,NULL,NULL); + pMapLoader->pFunc(DELETE,VarsUi.NVFilename,NULL,NULL); + } + VarsUi.NVTmpLength = sizeof(NVDATA); + VarsUi.NVTmpHandle = pMapLoader->pFunc(OPENWRITE,VarsUi.NVFilename,NULL,&VarsUi.NVTmpLength); + pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.NVTmpHandle,(UBYTE*)&VarsUi.NVData,&VarsUi.NVTmpLength); + pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.NVTmpHandle,NULL,NULL); +} + + +void cUiNVRead(void) +{ + VarsUi.NVData.CheckByte = 0; + sprintf((char*)VarsUi.NVFilename,"%s.%s",(char*)NONVOLATILE_NAME,(char*)TXT_SYS_EXT); + VarsUi.NVTmpHandle = pMapLoader->pFunc(OPENREAD,VarsUi.NVFilename,NULL,&VarsUi.NVTmpLength); + if (!(VarsUi.NVTmpHandle & 0x8000)) + { + VarsUi.NVTmpLength = sizeof(NVDATA); + pMapLoader->pFunc(READ,(UBYTE*)&VarsUi.NVTmpHandle,(UBYTE*)&VarsUi.NVData,&VarsUi.NVTmpLength); + pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.NVTmpHandle,NULL,NULL); + } + if (VarsUi.NVData.CheckByte != CHECKBYTE) + { + VarsUi.NVData.DatalogEnabled = DATALOGENABLED; + VarsUi.NVData.VolumeStep = MAX_VOLUME; + VarsUi.NVData.PowerdownCode = POWER_OFF_TIME_DEFAULT; + VarsUi.NVData.DatalogNumber = 0; + VarsUi.NVData.CheckByte = CHECKBYTE; + cUiNVWrite(); + } +} + + +//******* cUiFeedback ******************************************************** + +UBYTE cUiFeedback(BMPMAP *Bitmap,UBYTE TextNo1,UBYTE TextNo2,UWORD Time) // Show bimap and text +{ +// if ((VarsUi.FBState == 0) || ((pMapDisplay->Flags & DISPLAY_POPUP) == 0)) + { + switch (VarsUi.FBState) + { + case 0 : // Set busy + { + VarsUi.FBState++; + } + break; + + case 1 : // Clear line 2,3,4 + { + if (DISPLAY_IDLE) + { + pMapDisplay->EraseMask |= (TEXTLINE_BIT(TEXTLINE_2) | TEXTLINE_BIT(TEXTLINE_3) | TEXTLINE_BIT(TEXTLINE_4)); + VarsUi.FBState++; + } + } + break; + + case 2 : // Show bitmap if pressent + { + if (DISPLAY_IDLE) + { + if (Bitmap != NULL) + { + pMapDisplay->pBitmaps[BITMAP_1] = Bitmap; + pMapDisplay->UpdateMask |= BITMAP_BIT(BITMAP_1); + } + VarsUi.FBState++; + } + } + break; + + case 3 : // Get text string + { + if (DISPLAY_IDLE) + { + pMapDisplay->UpdateMask |= SPECIAL_BIT(TOPLINE); + VarsUi.FBText = cUiGetString(TextNo1); + VarsUi.FBPointer = 0; + if (TextNo2) + { + VarsUi.FBState = 5; + } + else + { + VarsUi.FBState++; + } + } + } + break; + + case 4 : // Show text string + { + if ((VarsUi.FBText[VarsUi.FBPointer]) && (VarsUi.FBPointer < NO_OF_FEEDBACK_CHARS)) + { + pMapDisplay->pFunc(DISPLAY_CHAR,TRUE,24 + VarsUi.FBPointer * 6,16,VarsUi.FBText[VarsUi.FBPointer],0); + VarsUi.FBPointer++; + } + else + { + VarsUi.FBTimer = 0; + VarsUi.FBState = 7; + } + } + break; + + case 5 : // Show text string + { + if ((VarsUi.FBText[VarsUi.FBPointer]) && (VarsUi.FBPointer < NO_OF_FEEDBACK_CHARS)) + { + pMapDisplay->pFunc(DISPLAY_CHAR,TRUE,24 + VarsUi.FBPointer * 6,12,VarsUi.FBText[VarsUi.FBPointer],0); + VarsUi.FBPointer++; + } + else + { + if (TextNo2 == 0xFF) + { + VarsUi.FBText = VarsUi.SelectedFilename; + } + else + { + VarsUi.FBText = cUiGetString(TextNo2); + } + VarsUi.FBPointer = 0; + VarsUi.FBState++; + } + } + break; + + case 6 : // Show text string + { + if ((VarsUi.FBText[VarsUi.FBPointer]) && (VarsUi.FBPointer < NO_OF_FEEDBACK_CHARS)) + { + pMapDisplay->pFunc(DISPLAY_CHAR,TRUE,24 + VarsUi.FBPointer * 6,20,VarsUi.FBText[VarsUi.FBPointer],0); + VarsUi.FBPointer++; + } + else + { + VarsUi.FBTimer = 0; + VarsUi.FBState++; + } + } + break; + + case 7 : // Wait if time provided + { + if (++VarsUi.FBTimer >= (Time + 100)) + { + VarsUi.FBState++; + } + } + break; + + default : // Exit + { + VarsUi.FBState = 0; + } + break; + + } + } + + return (VarsUi.FBState); +} + + + +//******* cUiFileList ******************************************************** + +UBYTE cUiFindNoOfFiles(UBYTE FileType,UBYTE *NoOfFiles) +{ + switch (VarsUi.FNOFState) + { + case 0 : + { + *NoOfFiles = 0; + + if (FileType >= FILETYPES) + { + FileType = FILETYPE_ALL; + } + sprintf((char*)VarsUi.FNOFSearchBuffer,"*.%s",TXT_FILE_EXT[FileType]); + + VarsUi.FNOFHandle = pMapLoader->pFunc(FINDFIRST,VarsUi.FNOFSearchBuffer,VarsUi.FNOFNameBuffer,&VarsUi.FNOFLength); + if (!(VarsUi.FNOFHandle & 0x8000)) + { + *NoOfFiles = 1; + VarsUi.FNOFState++; + } + } + break; + + case 1 : + { + VarsUi.FNOFHandle = pMapLoader->pFunc(FINDNEXT,(UBYTE*)&VarsUi.FNOFHandle,VarsUi.FNOFNameBuffer,&VarsUi.FNOFLength); + if (!(VarsUi.FNOFHandle & 0x8000)) + { + *NoOfFiles += 1; + } + else + { + pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.FNOFHandle,NULL,NULL); + VarsUi.FNOFState = 0; + } + } + break; + + } + + return (VarsUi.FNOFState); +} + + +UBYTE cUiFindNameForFileNo(UBYTE FileType,UBYTE FileNo,UBYTE *Name) +{ + switch (VarsUi.FNOFState) + { + case 0 : + { + Name[0] = 0; + + if (FileNo) + { + if (FileType >= FILETYPES) + { + FileType = FILETYPE_ALL; + } + sprintf((char*)VarsUi.FNOFSearchBuffer,"*.%s",TXT_FILE_EXT[FileType]); + + VarsUi.FNOFHandle = pMapLoader->pFunc(FINDFIRST,VarsUi.FNOFSearchBuffer,Name,&VarsUi.FNOFLength); + if (!(VarsUi.FNOFHandle & 0x8000)) + { + if (FileNo != 1) + { + VarsUi.FNOFFileNo = 1; + VarsUi.FNOFState++; + } + else + { + pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.FNOFHandle,NULL,NULL); + } + } + } + } + break; + + case 1 : + { + VarsUi.FNOFHandle = pMapLoader->pFunc(FINDNEXT,(UBYTE*)&VarsUi.FNOFHandle,Name,&VarsUi.FNOFLength); + if (!(VarsUi.FNOFHandle & 0x8000)) + { + VarsUi.FNOFFileNo++; + if (FileNo == VarsUi.FNOFFileNo) + { + pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.FNOFHandle,NULL,NULL); + VarsUi.FNOFState = 0; + } + } + else + { + pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.FNOFHandle,NULL,NULL); + VarsUi.FNOFState = 0; + } + } + break; + + } + + return (VarsUi.FNOFState); +} + + +UBYTE cUiFileList(UBYTE Action) // Show files and select +{ + switch (Action) + { + case MENU_INIT : + { + if (!VarsUi.State) + { + VarsUi.FileCenter = 1; + VarsUi.NextState = IOMapUi.State; + } + Action = MENU_DRAW; + } + break; + + case MENU_LEFT : + { + if (!VarsUi.State) + { + cUiListLeft(VarsUi.NoOfFiles,&VarsUi.FileCenter); + VarsUi.NextState = TEST_BUTTONS; + } + Action = MENU_DRAW; + } + break; + + case MENU_RIGHT : + { + if (!VarsUi.State) + { + cUiListRight(VarsUi.NoOfFiles,&VarsUi.FileCenter); + VarsUi.NextState = TEST_BUTTONS; + } + Action = MENU_DRAW; + } + break; + + case MENU_SELECT : + { + } + break; + + default : + { + if (Action < FILETYPES) + { + if (!VarsUi.State) + { + VarsUi.FileType = Action; + VarsUi.FileCenter = 1; + VarsUi.NextState = IOMapUi.State; + } + Action = MENU_DRAW; + } + else + { + IOMapUi.State = EXIT_PRESSED; + VarsUi.State = 0; + } + } + break; + + } + + if (Action == MENU_DRAW) + { + switch (VarsUi.State) + { + case 0 : + { + VarsUi.FNOFState = 0; + VarsUi.State++; + } + break; + + case 1 : + { + if (cUiFindNoOfFiles(VarsUi.FileType,&VarsUi.NoOfFiles) == 0) + { + if (VarsUi.NoOfFiles) + { + cUiListCalc(VarsUi.NoOfFiles,&VarsUi.FileCenter,&VarsUi.FileLeft,&VarsUi.FileRight); + VarsUi.State++; + } + else + { + VarsUi.State = 0; + IOMapUi.State = EXIT_PRESSED; + } + } + } + break; + + case 2 : + { + if (cUiFindNameForFileNo(VarsUi.FileType,VarsUi.FileCenter,VarsUi.SelectedFilename) == 0) + { + VarsUi.State++; + } + } + break; + + default : + { + pMapDisplay->pMenuIcons[MENUICON_LEFT] = NULL; + pMapDisplay->pMenuIcons[MENUICON_CENTER] = NULL; + pMapDisplay->pMenuIcons[MENUICON_RIGHT] = NULL; + + if (VarsUi.FileLeft) + { + pMapDisplay->pMenuIcons[MENUICON_LEFT] = (UBYTE*)&Icons->Data[(VarsUi.FileType + ALLFILES) * Icons->ItemPixelsX * (Icons->ItemPixelsY / 8)]; + pMapDisplay->UpdateMask |= MENUICON_BIT(MENUICON_LEFT); + } + if (VarsUi.FileCenter) + { + pMapDisplay->pMenuIcons[MENUICON_CENTER] = (UBYTE*)&Icons->Data[(VarsUi.FileType + ALLFILES) * Icons->ItemPixelsX * (Icons->ItemPixelsY / 8)]; + pMapDisplay->UpdateMask |= MENUICON_BIT(MENUICON_CENTER); + } + if (VarsUi.FileRight) + { + pMapDisplay->pMenuIcons[MENUICON_RIGHT] = (UBYTE*)&Icons->Data[(VarsUi.FileType + ALLFILES) * Icons->ItemPixelsX * (Icons->ItemPixelsY / 8)]; + pMapDisplay->UpdateMask |= MENUICON_BIT(MENUICON_RIGHT); + } + + pMapDisplay->EraseMask |= TEXTLINE_BIT(TEXTLINE_5); + + // Search forward for termination + VarsUi.Tmp = 0; + while ((VarsUi.SelectedFilename[VarsUi.Tmp]) && (VarsUi.Tmp < FILENAME_LENGTH)) + { + VarsUi.Tmp++; + } + + // Search backward for "." + while ((VarsUi.Tmp) && (VarsUi.SelectedFilename[VarsUi.Tmp] != '.')) + { + VarsUi.Tmp--; + } + + if (VarsUi.Tmp > DISPLAYLINE_LENGTH) + { + VarsUi.Tmp = DISPLAYLINE_LENGTH; + } + + VarsUi.DisplayBuffer[VarsUi.Tmp] = 0; + + // Copy only name not ext + while (VarsUi.Tmp) + { + VarsUi.Tmp--; + VarsUi.DisplayBuffer[VarsUi.Tmp] = VarsUi.SelectedFilename[VarsUi.Tmp]; + } + + pMapDisplay->pMenuText = VarsUi.DisplayBuffer; + pMapDisplay->EraseMask |= MENUICON_BITS; + pMapDisplay->UpdateMask |= (SPECIAL_BIT(FRAME_SELECT) | SPECIAL_BIT(MENUTEXT)); + + IOMapUi.State = VarsUi.NextState; + VarsUi.State = 0; + } + break; + + } + } + + return (VarsUi.State); +} + + + +//******* cUiVolume ********************************************************** + +UBYTE cUiVolume(UBYTE Action) // MENU_INIT,MENU_LEFT,MENU_RIGHT,MENU_EXIT +{ + switch (Action) + { + case MENU_INIT : // Init time counter and cursor bitmap + { + VarsUi.Counter = VarsUi.NVData.VolumeStep + 1; + + VarsUi.pTmp = (UBYTE*)Cursor; + for (VarsUi.Tmp = 0;(VarsUi.Tmp < SIZE_OF_CURSOR) && (VarsUi.Tmp < (UBYTE)SIZEOF_DATA(Cursor));VarsUi.Tmp++) + { + VarsUi.CursorTmp[VarsUi.Tmp] = *VarsUi.pTmp; + VarsUi.pTmp++; + } + Action = MENU_DRAW; + } + break; + + case MENU_LEFT : // Dec + { + cUiListLeft(MAX_VOLUME + 1,&VarsUi.Counter); + IOMapUi.Volume = VarsUi.Counter - 1; + Action = MENU_DRAW; + } + break; + + case MENU_RIGHT : // Inc + { + cUiListRight(MAX_VOLUME + 1,&VarsUi.Counter); + IOMapUi.Volume = VarsUi.Counter - 1; + Action = MENU_DRAW; + } + break; + + case MENU_ENTER : // Enter + { + VarsUi.NVData.VolumeStep = VarsUi.Counter - 1; + cUiNVWrite(); + IOMapUi.Volume = VarsUi.NVData.VolumeStep; + pMapSound->Volume = IOMapUi.Volume; + Action = MENU_EXIT; + } + break; + + case MENU_EXIT : // Leave + { + IOMapUi.Volume = VarsUi.NVData.VolumeStep; + } + break; + + } + if (Action == MENU_DRAW) + { + sprintf((char*)VarsUi.DisplayBuffer,"%u",(UWORD)VarsUi.Counter - 1); + pMapDisplay->pTextLines[TEXTLINE_3] = VarsUi.DisplayBuffer; + + pMapDisplay->pBitmaps[BITMAP_1] = (BMPMAP*)VarsUi.CursorTmp; + VarsUi.CursorTmp[4] = 46; + VarsUi.CursorTmp[5] = 24; + pMapDisplay->EraseMask |= (TEXTLINE_BIT(TEXTLINE_3) | TEXTLINE_BIT(TEXTLINE_4)); + pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_3); + pMapDisplay->UpdateMask |= (TEXTLINE_BIT(TEXTLINE_3) | BITMAP_BIT(BITMAP_1)); + } + if (Action == MENU_EXIT) + { + IOMapUi.State = EXIT_PRESSED; + } + + return (0); +} + + + +//******* cUiGetUserString *************************************************** + +#define STRINGTYPES 2 + +#define TOPTEXT_LINE TEXTLINE_3 +#define STRING_LINE TEXTLINE_5 + +typedef struct +{ + const UBYTE Text; + const UBYTE *Figures; + const UBYTE NoOfFigures; + const UBYTE MaxStringLength; + const UBYTE WindowSize; + const SBYTE DefaultPointer; +} +STRSETS; + +const UBYTE Figures[] = { "0987654321" "\x7F" "abcdefghijklmnopqrstuvwxyz " }; + +const STRSETS StrSets[STRINGTYPES] = +{ + { TXT_GETUSERSTRING_PIN, Figures, 37, SIZE_OF_BT_PINCODE - 1, 15, 10 }, + { TXT_GETUSERSTRING_FILENAME, Figures, 37, FILENAME_LENGTH - 4 , 15, 10 } +}; + + +UBYTE cUiGetUserString(UBYTE Type) // 0=Pincode, 1=filename +{ + UBYTE Tmp1; + SBYTE Tmp2; + + if (Type < STRINGTYPES) + { + switch (VarsUi.GUSState) + { + case 0 : // Init screen + { + // Disable update and prepare screen + pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_LARGE); + pMapDisplay->pBitmaps[BITMAP_1] = (BMPMAP*)Ok; + + // Set figure pointer to default + VarsUi.FigurePointer = (SBYTE)StrSets[Type].DefaultPointer; + + // Calculate cursor from default string + VarsUi.GUSCursor = 0; + while ((VarsUi.GUSCursor < DISPLAYLINE_LENGTH) && VarsUi.UserString[VarsUi.GUSCursor]) + { + VarsUi.GUSCursor++; + } + VarsUi.GUSNoname = TRUE; + + VarsUi.GUSState++; + } + break; + + case 1 : // Update user string + { + if (!(pMapDisplay->EraseMask & SCREEN_BIT(SCREEN_LARGE))) + { + // Display top text + pMapDisplay->pTextLines[TOPTEXT_LINE] = cUiGetString(StrSets[Type].Text); + pMapDisplay->UpdateMask |= TEXTLINE_BIT(TOPTEXT_LINE); + + Tmp1 = 0; + while (VarsUi.UserString[Tmp1] && (Tmp1 < StrSets[Type].MaxStringLength)) + { + VarsUi.DisplayText[Tmp1] = VarsUi.UserString[Tmp1]; + Tmp1++; + } + if (Tmp1 < StrSets[Type].MaxStringLength) + { + VarsUi.DisplayText[Tmp1] = '_'; + Tmp1++; + } + while (Tmp1 < StrSets[Type].MaxStringLength) + { + VarsUi.DisplayText[Tmp1] = ' '; + Tmp1++; + } + VarsUi.DisplayText[Tmp1] = 0; + + pMapDisplay->pTextLines[STRING_LINE] = VarsUi.DisplayText; + pMapDisplay->UpdateMask |= (TEXTLINE_BIT(STRING_LINE) | SPECIAL_BIT(TOPLINE)); + pMapDisplay->EraseMask |= BITMAP_BIT(BITMAP_1); + VarsUi.GUSState++; + } + } + break; + + case 2 : // Update figure string + { + if (!(pMapDisplay->EraseMask & BITMAP_BIT(BITMAP_1))) + { + Tmp2 = VarsUi.FigurePointer; + + for (Tmp1 = 0;Tmp1 < 3;Tmp1++) + { + if (Tmp2) + { + Tmp2--; + } + else + { + Tmp2 = StrSets[Type].NoOfFigures - 1; + } + } + for (Tmp1 = 0;Tmp1 < 7;Tmp1++) + { + if ((Tmp1 == 3) && (StrSets[Type].Figures[Tmp2] == 0x7F)) + { + pMapDisplay->UpdateMask |= BITMAP_BIT(BITMAP_1); + } + else + { + pMapDisplay->pFunc(DISPLAY_CHAR,TRUE,5 + Tmp1 * 14,52,StrSets[Type].Figures[Tmp2],0); + } + if (Tmp2 < (StrSets[Type].NoOfFigures - 1)) + { + Tmp2++; + } + else + { + Tmp2 = 0; + } + } + pMapDisplay->pFunc(DISPLAY_HORISONTAL_LINE,TRUE,42,47,57,0); + pMapDisplay->pFunc(DISPLAY_VERTICAL_LINE,TRUE,42,47,0,63); + pMapDisplay->pFunc(DISPLAY_VERTICAL_LINE,TRUE,57,47,0,63); + + VarsUi.GUSState++; + } + } + break; + + case 3 : // Get user input + { + if ((pMapButton->State[BTN4] & LONG_PRESSED_EV)) + { + if (VarsUi.GUSCursor) + { + if ((VarsUi.UserString[VarsUi.GUSCursor - 1] >= 'a') && (VarsUi.UserString[VarsUi.GUSCursor - 1] <= 'z')) + { + VarsUi.UserString[VarsUi.GUSCursor - 1] -= ' '; + VarsUi.GUSState -= 2; + } + } + } + + switch (cUiReadButtons()) + { + case BUTTON_LEFT : + { + if (VarsUi.FigurePointer) + { + VarsUi.FigurePointer--; + } + else + { + VarsUi.FigurePointer = StrSets[Type].NoOfFigures - 1; + } + pMapDisplay->EraseMask |= BITMAP_BIT(BITMAP_1); + VarsUi.GUSState -= 2; + } + break; + + case BUTTON_ENTER : + { + switch (StrSets[Type].Figures[VarsUi.FigurePointer]) + { + case 0x7F : + { + VarsUi.GUSState = 100; + } + break; + + default : + { + VarsUi.GUSNoname = FALSE; + if (VarsUi.GUSCursor < StrSets[Type].MaxStringLength) + { + VarsUi.UserString[VarsUi.GUSCursor] = StrSets[Type].Figures[VarsUi.FigurePointer]; + VarsUi.GUSCursor++; + VarsUi.UserString[VarsUi.GUSCursor] = 0; + VarsUi.GUSState -= 2; + } + } + break; + + } + } + break; + + case BUTTON_RIGHT : + { + if (VarsUi.FigurePointer < (StrSets[Type].NoOfFigures - 1)) + { + VarsUi.FigurePointer++; + } + else + { + VarsUi.FigurePointer = 0; + } + pMapDisplay->EraseMask |= BITMAP_BIT(BITMAP_1); + VarsUi.GUSState -= 2; + } + break; + + case BUTTON_EXIT : + { + if (VarsUi.GUSCursor) + { + if (VarsUi.GUSNoname == TRUE) + { + VarsUi.GUSNoname = FALSE; + while (VarsUi.GUSCursor) + { + VarsUi.UserString[VarsUi.GUSCursor] = 0; + VarsUi.GUSCursor--; + } + } + else + { + VarsUi.GUSCursor--; + } + VarsUi.UserString[VarsUi.GUSCursor] = 0; + VarsUi.GUSState -= 2; + } + else + { + VarsUi.UserString[0] = 0; + VarsUi.GUSState = 100; + } + } + break; + + } + } + break; + + default : // Clean up screen + { + pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_BACKGROUND); + pMapDisplay->UpdateMask = 0; + IOMapUi.Flags |= UI_REDRAW_STATUS; + VarsUi.GUSState = 0; + } + break; + } + } + + return (VarsUi.GUSState); +} + + + +//******* cUiDataLogging ***************************************************** + +void cUiDrawPortNo(UBYTE *Bitmap,UBYTE MenuIconNo,UBYTE PortNo) +{ + UBYTE Tmp; + + Bitmap[0] = (UBYTE)(FILEFORMAT_BITMAP >> 8); + Bitmap[1] = (UBYTE)(FILEFORMAT_BITMAP); + Bitmap[2] = (UBYTE)(SIZE_OF_PORTBITMAP >> 8); + Bitmap[3] = (UBYTE)(SIZE_OF_PORTBITMAP); + Bitmap[4] = DISPLAY_MENUICONS_X_OFFS + DISPLAY_MENUICONS_X_DIFF * MenuIconNo + 2; + Bitmap[5] = DISPLAY_MENUICONS_Y; + Bitmap[6] = Port[0].ItemPixelsX; + Bitmap[7] = Port[0].ItemPixelsY; + + Tmp = 0; + while (Tmp < Bitmap[6]) + { + Bitmap[Tmp + FILEHEADER_LENGTH] = Port[0].Data[Tmp + PortNo * Bitmap[6]]; + Tmp++; + } + +} + +UBYTE cUiDataLogging(UBYTE Action) +{ + SBYTE TmpBuffer[DATALOGBUFFERSIZE + 1]; + + switch (Action) + { + case MENU_INIT : // Initialize all ports to empty + { +// Show select + pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_VIEW_SELECT); + pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_3); + pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3); + pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_SMALL); + +// Init ports + for (VarsUi.Tmp = 0;VarsUi.Tmp < DATALOGPORTS;VarsUi.Tmp++) + { + VarsUi.DatalogPort[VarsUi.Tmp] = MENU_SENSOR_EMPTY; + } + } + break; + + case MENU_EXIT : // Initialize all ports to empty + { +// Show select + pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_VIEW_SELECT); + pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_3); + pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3); + pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_SMALL); + } + break; + + case MENU_TEXT : // Write text + { +// Init selected sensor and port to none + VarsUi.SelectedSensor = MENU_SENSOR_EMPTY; + VarsUi.SelectedPort = MENU_PORT_EMPTY; +// Count ports + VarsUi.Counter = 0; + for (VarsUi.Tmp = 0;VarsUi.Tmp < DATALOGPORTS;VarsUi.Tmp++) + { + if (MENU_SENSOR_EMPTY != VarsUi.DatalogPort[VarsUi.Tmp]) + { +// Find default port to view + if (VarsUi.SelectedPort == MENU_PORT_EMPTY) + { + VarsUi.SelectedPort = VarsUi.Tmp + MENU_PORT_1; + } + VarsUi.Counter++; + } + } + if (VarsUi.Counter) + { +// Display text + pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_DATALOGGING_PRESS_EXIT_TO); + pMapDisplay->pTextLines[TEXTLINE_4] = cUiGetString(TXT_DATALOGGING_STOP_DATALOGGING); + + pMapDisplay->TextLinesCenterFlags |= (TEXTLINE_BIT(TEXTLINE_3) | TEXTLINE_BIT(TEXTLINE_4)); + pMapDisplay->UpdateMask |= (TEXTLINE_BIT(TEXTLINE_3) | TEXTLINE_BIT(TEXTLINE_4)); + } + else + { + cUiMenuPrevFile(); + IOMapUi.State = NEXT_MENU; + VarsUi.State = 0; + } + } + break; + + case MENU_RUN : // Run data logging + { + switch (VarsUi.State) + { + case 0 : // Init log + { +// Save menu text + VarsUi.MenuIconTextSave = pMapDisplay->pMenuText; + +// Delete file if exist + sprintf((char*)VarsUi.FilenameBuffer,"%s.%s",(char*)TEMP_DATALOG_FILENAME,(char*)TXT_FILE_EXT[FILETYPE_DATALOG]); + VarsUi.TmpHandle = pMapLoader->pFunc(FINDFIRST,VarsUi.FilenameBuffer,VarsUi.SearchFilenameBuffer,&VarsUi.TmpLength); + if (!(VarsUi.TmpHandle & 0x8000)) + { + pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.TmpHandle,NULL,NULL); + pMapLoader->pFunc(DELETE,VarsUi.FilenameBuffer,NULL,NULL); + } + +// Open file + VarsUi.TmpLength = pMapLoader->FreeUserFlash; + sprintf((char*)VarsUi.FilenameBuffer,"%s.%s",(char*)TEMP_DATALOG_FILENAME,(char*)TXT_FILE_EXT[FILETYPE_DATALOG]); + VarsUi.TmpHandle = pMapLoader->pFunc(OPENWRITEDATA,VarsUi.FilenameBuffer,NULL,&VarsUi.TmpLength); + VarsUi.DatalogError = VarsUi.TmpHandle; + if (!(VarsUi.DatalogError & 0x8000)) + { + VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"%s\t%lu",SENSORSYNCDATA,pMapCmd->SyncTime); + VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); + + VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"\t%lu",pMapCmd->SyncTick); + VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); + + VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"\t%lu",pMapCmd->Tick); + VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); + + VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"\t%lu\t-1\r\n",DATALOG_DEFAULT_SAMPLE_TIME); + VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); + + VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"%s",SENSORSDATA); + VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); + for (VarsUi.Tmp = 0;(VarsUi.Tmp < DATALOGPORTS) && (!(VarsUi.DatalogError & 0x8000));VarsUi.Tmp++) + { + if (MENU_SENSOR_EMPTY != VarsUi.DatalogPort[VarsUi.Tmp]) + { + VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"\t%u_%s%s",(UWORD)(VarsUi.Tmp + 1),(char*)SENSORDIRNAME[(VarsUi.DatalogPort[VarsUi.Tmp] - MENU_SENSOR_EMPTY) - 1],(char*)SENSORUNITNAME[(VarsUi.DatalogPort[VarsUi.Tmp] - MENU_SENSOR_EMPTY) - 1]); + VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); + } + } + VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"\r\n"); + VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); + VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"%s",SENSORTIME); + VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); + for (VarsUi.Tmp = 0;(VarsUi.Tmp < DATALOGPORTS) && (!(VarsUi.DatalogError & 0x8000));VarsUi.Tmp++) + { + if (MENU_SENSOR_EMPTY != VarsUi.DatalogPort[VarsUi.Tmp]) + { + VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"\t%s",(char*)SENSORDIRNAME[(VarsUi.DatalogPort[VarsUi.Tmp] - MENU_SENSOR_EMPTY) - 1]); + VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); + } + } + VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"\r\n"); + VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); + if (!(VarsUi.DatalogError & 0x8000)) + { + VarsUi.DatalogTimer = 0; + VarsUi.DatalogSampleTime = DATALOG_DEFAULT_SAMPLE_TIME; + VarsUi.DatalogSampleTimer = 0; + VarsUi.Timer = 0; + VarsUi.Update = TRUE; + IOMapUi.Flags |= UI_BUSY; + VarsUi.DatalogOldTick = pMapCmd->Tick; + VarsUi.SensorReset = TRUE; + VarsUi.State++; + } + else + { + pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_SMALL); + pMapDisplay->pBitmaps[BITMAP_1] = NULL; + VarsUi.State = 4; + } + } + else + { +// File error + pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_SMALL); + pMapDisplay->pBitmaps[BITMAP_1] = NULL; + VarsUi.State = 3; + } + } + break; + + case 1 : + { +// Get real time since last + VarsUi.DatalogRTC = (pMapCmd->Tick - VarsUi.DatalogOldTick); + VarsUi.DatalogOldTick = pMapCmd->Tick; +// Update all timers + VarsUi.DatalogTimer += VarsUi.DatalogRTC; + VarsUi.DatalogSampleTimer += VarsUi.DatalogRTC; + VarsUi.ReadoutTimer += VarsUi.DatalogRTC; +// Update sensor values + cUiUpdateSensor((SWORD)VarsUi.DatalogRTC); +// Check for select change + if (VarsUi.Update == TRUE) + { + VarsUi.Update = FALSE; + VarsUi.SelectedSensor = VarsUi.DatalogPort[VarsUi.SelectedPort - MENU_PORT_1]; + pMapDisplay->pMenuIcons[MENUICON_CENTER] = cUiMenuGetIconImage(cUiMenuSearchSensorIcon(VarsUi.SelectedSensor)); + pMapDisplay->pMenuIcons[MENUICON_LEFT] = NULL; + pMapDisplay->pMenuIcons[MENUICON_RIGHT] = NULL; + + pMapDisplay->EraseMask = SCREEN_BIT(SCREEN_LARGE); + pMapDisplay->pBitmaps[BITMAP_1] = (BMPMAP*)Display; + pMapDisplay->UpdateMask = (BITMAP_BIT(BITMAP_1) | MENUICON_BITS | SPECIAL_BIT(TOPLINE) | SPECIAL_BIT(FRAME_SELECT)); + + pMapDisplay->pBitmaps[BITMAP_2] = (BMPMAP*)VarsUi.PortBitmapLeft; + pMapDisplay->pBitmaps[BITMAP_3] = (BMPMAP*)VarsUi.PortBitmapCenter; + pMapDisplay->pBitmaps[BITMAP_4] = (BMPMAP*)VarsUi.PortBitmapRight; + + cUiDrawPortNo(VarsUi.PortBitmapCenter,MENUICON_CENTER,VarsUi.SelectedPort - MENU_PORT_EMPTY); + pMapDisplay->UpdateMask |= BITMAP_BIT(BITMAP_3); + + + + if (VarsUi.Counter == 2) + { + VarsUi.Tmp = VarsUi.SelectedPort; + do + { + VarsUi.Tmp++; + if (VarsUi.Tmp >= MENU_PORT_INVALID) + { + VarsUi.Tmp = MENU_PORT_1; + } + } + while (VarsUi.DatalogPort[VarsUi.Tmp - MENU_PORT_1] == MENU_SENSOR_EMPTY); + if (VarsUi.Tmp > VarsUi.SelectedPort) + { + pMapDisplay->pMenuIcons[MENUICON_RIGHT] = cUiMenuGetIconImage(cUiMenuSearchSensorIcon(VarsUi.DatalogPort[VarsUi.Tmp - MENU_PORT_1])); + cUiDrawPortNo(VarsUi.PortBitmapRight,MENUICON_RIGHT,VarsUi.Tmp - MENU_PORT_EMPTY); + pMapDisplay->UpdateMask |= BITMAP_BIT(BITMAP_4); + } + else + { + pMapDisplay->pMenuIcons[MENUICON_LEFT] = cUiMenuGetIconImage(cUiMenuSearchSensorIcon(VarsUi.DatalogPort[VarsUi.Tmp - MENU_PORT_1])); + cUiDrawPortNo(VarsUi.PortBitmapLeft,MENUICON_LEFT,VarsUi.Tmp - MENU_PORT_EMPTY); + pMapDisplay->UpdateMask |= BITMAP_BIT(BITMAP_2); + } + } + if (VarsUi.Counter > 2) + { + VarsUi.Tmp = VarsUi.SelectedPort; + do + { + VarsUi.Tmp++; + if (VarsUi.Tmp >= MENU_PORT_INVALID) + { + VarsUi.Tmp = MENU_PORT_1; + } + } + while (VarsUi.DatalogPort[VarsUi.Tmp - MENU_PORT_1] == MENU_SENSOR_EMPTY); + pMapDisplay->pMenuIcons[MENUICON_RIGHT] = cUiMenuGetIconImage(cUiMenuSearchSensorIcon(VarsUi.DatalogPort[VarsUi.Tmp - MENU_PORT_1])); + cUiDrawPortNo(VarsUi.PortBitmapRight,MENUICON_RIGHT,VarsUi.Tmp - MENU_PORT_EMPTY); + pMapDisplay->UpdateMask |= BITMAP_BIT(BITMAP_4); + + VarsUi.Tmp = VarsUi.SelectedPort; + do + { + VarsUi.Tmp--; + if (VarsUi.Tmp <= MENU_PORT_EMPTY) + { + VarsUi.Tmp = MENU_PORT_INVALID - 1; + } + } + while (VarsUi.DatalogPort[VarsUi.Tmp - MENU_PORT_1] == MENU_SENSOR_EMPTY); + pMapDisplay->pMenuIcons[MENUICON_LEFT] = cUiMenuGetIconImage(cUiMenuSearchSensorIcon(VarsUi.DatalogPort[VarsUi.Tmp - MENU_PORT_1])); + cUiDrawPortNo(VarsUi.PortBitmapLeft,MENUICON_LEFT,VarsUi.Tmp - MENU_PORT_EMPTY); + pMapDisplay->UpdateMask |= BITMAP_BIT(BITMAP_2); + + + } + VarsUi.ReadoutTimer = DISPLAY_VIEW_UPDATE; + } +// Write sample if timeout + if (VarsUi.DatalogSampleTimer >= VarsUi.DatalogSampleTime) + { + VarsUi.DatalogSampleTimer -= VarsUi.DatalogSampleTime; + + VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"%lu",VarsUi.DatalogTimer - VarsUi.DatalogSampleTime); + VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); + for (VarsUi.Tmp = 0;(VarsUi.Tmp < DATALOGPORTS) && (!(VarsUi.DatalogError & 0x8000));VarsUi.Tmp++) + { + if (MENU_SENSOR_EMPTY != VarsUi.DatalogPort[VarsUi.Tmp]) + { + if (VarsUi.DatalogSampleValid[VarsUi.Tmp] == TRUE) + { + VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,(char*)SENSORFORMAT2[(VarsUi.DatalogPort[VarsUi.Tmp] - MENU_SENSOR_EMPTY) - 1],(float)VarsUi.DatalogSampleValue[VarsUi.Tmp] / SENSORDIVIDER[VarsUi.DatalogPort[VarsUi.Tmp] - MENU_SENSOR_EMPTY]); + VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); + } + else + { + VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"\t-"); + VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); + } + } + } + VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"\r\n"); + VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); + } +// Refresh display + if (++VarsUi.ReadoutTimer >= DISPLAY_VIEW_UPDATE) + { + VarsUi.ReadoutTimer = 0; + +// Display sensor value + cUiPrintSensorInDisplayBuffer(VarsUi.SelectedPort); + pMapDisplay->pTextLines[TEXTLINE_4] = VarsUi.DisplayBuffer; + pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_4); + pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_4); + } + +// Test for file error + if ((VarsUi.DatalogError & 0x8000)) + { + pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_SMALL); + pMapDisplay->pBitmaps[BITMAP_1] = NULL; + VarsUi.State = 4; + } + +// Test for break; + switch (cUiReadButtons()) + { + case BUTTON_EXIT : + { + VarsUi.State++; + } + break; + + case BUTTON_LEFT : + { + VarsUi.Tmp = VarsUi.SelectedPort; + do + { + VarsUi.Tmp--; + if (VarsUi.Tmp <= MENU_PORT_EMPTY) + { + VarsUi.Tmp = MENU_PORT_INVALID - 1; + } + } + while (VarsUi.DatalogPort[VarsUi.Tmp - MENU_PORT_1] == MENU_SENSOR_EMPTY); + if ((VarsUi.Counter > 2) || (VarsUi.Tmp < VarsUi.SelectedPort)) + { + VarsUi.SelectedPort = VarsUi.Tmp; + } + VarsUi.Update = TRUE; + } + break; + + case BUTTON_RIGHT : + { + VarsUi.Tmp = VarsUi.SelectedPort; + do + { + VarsUi.Tmp++; + if (VarsUi.Tmp >= MENU_PORT_INVALID) + { + VarsUi.Tmp = MENU_PORT_1; + } + } + while (VarsUi.DatalogPort[VarsUi.Tmp - MENU_PORT_1] == MENU_SENSOR_EMPTY); + if ((VarsUi.Counter > 2) || (VarsUi.Tmp > VarsUi.SelectedPort)) + { + VarsUi.SelectedPort = VarsUi.Tmp; + } + VarsUi.Update = TRUE; + } + break; + + } + IOMapUi.Flags |= UI_RESET_SLEEP_TIMER; + } + break; + + case 2 : + { +// Close file + pMapLoader->pFunc(CROPDATAFILE,(UBYTE*)&VarsUi.TmpHandle,NULL,NULL); + +// Clean up + pMapDisplay->pMenuText = VarsUi.MenuIconTextSave; + cUiReleaseSensors(); + + IOMapUi.Flags &= ~UI_BUSY; + IOMapUi.State = RIGHT_PRESSED; + VarsUi.State = 0; + } + break; + + case 3 : // Display memory full text + { + if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_DL_ERROR_MEMORY_FULL_1,TXT_FB_DL_ERROR_MEMORY_FULL_2,DISPLAY_SHOW_ERROR_TIME)) + { + cUiMenuPrevFile(); + IOMapUi.State = NEXT_MENU; + VarsUi.State = 0; + } + } + break; + + case 4 : // Display memory full text + { + if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_DL_ERROR_MEMORY_FULL_1,TXT_FB_DL_ERROR_MEMORY_FULL_2,DISPLAY_SHOW_ERROR_TIME)) + { + VarsUi.State = 2; + } + } + break; + + } + } + break; + + case MENU_SAVE : // Save datalog file + { + switch (VarsUi.State) + { + case 0 : + { + VarsUi.NVData.DatalogNumber++; + if (VarsUi.NVData.DatalogNumber > MAX_DATALOGS) + { + VarsUi.NVData.DatalogNumber = 1; + } + cUiNVWrite(); + sprintf((char*)VarsUi.SelectedFilename,"%s%u.%s",(char*)UI_DATALOG_FILENAME,VarsUi.NVData.DatalogNumber,TXT_FILE_EXT[FILETYPE_DATALOG]); + VarsUi.State++; + } + break; + + case 1 : + { +// Rename TEMP_DATALOG_FILENAME to VarsUi.SelectedFilename(user filename) + sprintf((char*)VarsUi.FilenameBuffer,"%s.%s",(char*)TEMP_DATALOG_FILENAME,(char*)TXT_FILE_EXT[FILETYPE_DATALOG]); + VarsUi.TmpHandle = pMapLoader->pFunc(RENAMEFILE,VarsUi.FilenameBuffer,VarsUi.SelectedFilename,&VarsUi.TmpLength); + VarsUi.State++; + } + break; + + case 2 : // Display saved text + { + if (!cUiFeedback((BMPMAP*)Info,TXT_FB_DL_FILE_SAVED_INFO,0xFF,DISPLAY_SHOW_FILENAME_TIME)) + { + VarsUi.State++; + } + } + break; + + default : + { + cUiMenuPrevFile(); + IOMapUi.State = NEXT_MENU; + VarsUi.State = 0; + } + break; + + } + } + break; + + case MENU_DELETE : // Delete datalog file + { + switch (VarsUi.State) + { + case 0 : + { +// Delete file if exist + sprintf((char*)VarsUi.FilenameBuffer,"%s.%s",(char*)TEMP_DATALOG_FILENAME,(char*)TXT_FILE_EXT[FILETYPE_DATALOG]); + pMapLoader->pFunc(DELETE,VarsUi.FilenameBuffer,NULL,NULL); + VarsUi.State++; + } + break; + + case 1 : + { + pMapDisplay->EraseMask |= (TEXTLINE_BIT(TEXTLINE_3) | TEXTLINE_BIT(TEXTLINE_4) | TEXTLINE_BIT(TEXTLINE_5) | MENUICON_BITS | SPECIAL_BIT(MENUTEXT)); + VarsUi.Timer = DISPLAY_SHOW_TIME; + VarsUi.State++; + } + break; + + case 2 : + { + if (++VarsUi.Timer >= DISPLAY_SHOW_TIME) + { + pMapDisplay->EraseMask |= TEXTLINE_BIT(TEXTLINE_3); + VarsUi.State++; + } + } + break; + + default : + { + VarsUi.State = 0; + } + break; + + } + } + break; + + case MENU_SELECT : // Save sensor + { + pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_VIEW_SELECT); + pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_3); + pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3); + + VarsUi.DatalogPort[VarsUi.SelectedPort - MENU_PORT_1] = VarsUi.SelectedSensor; + IOMapUi.State = EXIT_PRESSED; + } + break; + + default : + { + switch (VarsUi.State) + { + case 0 : + { + if ((Action > MENU_SENSOR_EMPTY) && (Action < MENU_SENSOR_INVALID)) + { + VarsUi.SelectedSensor = Action; + } + if ((Action > MENU_PORT_EMPTY) && (Action < MENU_PORT_INVALID)) + { + VarsUi.SelectedPort = Action; + if (VarsUi.DatalogPort[VarsUi.SelectedPort - MENU_PORT_1] != MENU_SENSOR_EMPTY) + { + + // Port occupied + pMapDisplay->pTextLines[TEXTLINE_4] = cUiGetString(TXT_DATALOGGING_PORT_OCCUPIED); + pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_4); + pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_4); + VarsUi.Timer = 0; + VarsUi.State++; + } + } + } + break; + + default : + { + if ((++VarsUi.Timer >= DISPLAY_SHOW_TIME) || (BUTTON_NONE != cUiReadButtons())) + { + pMapDisplay->EraseMask |= TEXTLINE_BIT(TEXTLINE_4); + cUiMenuPrev(); + IOMapUi.State = NEXT_MENU; + VarsUi.State = 0; + } + } + break; + + } + } + break; + + } + + return (VarsUi.State); +} + + +//******* cUiRunning ********************************************************** + +void cUiRunning(UBYTE Action) +{ + switch (Action) + { + case MENU_INIT : + { + VarsUi.RunIconSave = pMapDisplay->pMenuIcons[MENUICON_CENTER]; + VarsUi.RunBitmapPointer = 0; + VarsUi.RunTimer = 0; + pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_LARGE); + pMapDisplay->UpdateMask |= SPECIAL_BIT(TOPLINE); + } + break; + + case MENU_RUN : + { + if ((IOMapUi.Flags & UI_ENABLE_STATUS_UPDATE)) + { + if (++VarsUi.RunTimer >= RUN_BITMAP_CHANGE_TIME) + { + VarsUi.RunTimer = 0; + if (++VarsUi.RunBitmapPointer >= Running->ItemsY ) + { + VarsUi.RunBitmapPointer = 0; + } + pMapDisplay->pMenuIcons[MENUICON_CENTER] = (UBYTE*)&Running->Data[VarsUi.RunBitmapPointer * Running->ItemPixelsX * (Running->ItemPixelsY / 8)]; + pMapDisplay->EraseMask |= MENUICON_BIT(MENUICON_CENTER); + pMapDisplay->UpdateMask |= MENUICON_BIT(MENUICON_CENTER); + } + } + } + break; + + case MENU_UPDATE : + { + pMapDisplay->pMenuIcons[MENUICON_CENTER] = (UBYTE*)&Running->Data[VarsUi.RunBitmapPointer * Running->ItemPixelsX * (Running->ItemPixelsY / 8)]; + pMapDisplay->UpdateMask |= MENUICON_BIT(MENUICON_CENTER); + } + break; + + case MENU_EXIT : + { + pMapDisplay->pMenuIcons[MENUICON_CENTER] = VarsUi.RunIconSave; + pMapDisplay->UpdateMask = MENUICON_BITS | SPECIAL_BIT(MENUTEXT); + } + break; + + } +} + +//******* cUiOnBrickProgramming ********************************************** + +UBYTE cUiOnBrickProgramming(UBYTE Action) // On brick programming +{ + switch (Action) + { + case MENU_INIT : // Show motor / sensor text + { + pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_ONBRICKPROGRAMMING_PLEASE_USE_PORT); + pMapDisplay->pTextLines[TEXTLINE_4] = cUiGetString(TXT_ONBRICKPROGRAMMING_1_TOUCH_SENSOR); + pMapDisplay->pTextLines[TEXTLINE_5] = cUiGetString(TXT_ONBRICKPROGRAMMING_2_SOUND_SENSOR); + pMapDisplay->pTextLines[TEXTLINE_6] = cUiGetString(TXT_ONBRICKPROGRAMMING_3_LIGHT_SENSOR); + pMapDisplay->pTextLines[TEXTLINE_7] = cUiGetString(TXT_ONBRICKPROGRAMMING_4_ULTRA_SONIC); + pMapDisplay->pTextLines[TEXTLINE_8] = cUiGetString(TXT_ONBRICKPROGRAMMING_BC_LR_MOTORS); + pMapDisplay->EraseMask |= (TEXTLINE_BIT(TEXTLINE_3) | TEXTLINE_BIT(TEXTLINE_4) | TEXTLINE_BIT(TEXTLINE_5) | TEXTLINE_BIT(TEXTLINE_6) | TEXTLINE_BIT(TEXTLINE_7) | TEXTLINE_BIT(TEXTLINE_8)); + pMapDisplay->UpdateMask &= ~SPECIAL_BIT(FRAME_SELECT); + pMapDisplay->UpdateMask |= (TEXTLINE_BIT(TEXTLINE_3) | TEXTLINE_BIT(TEXTLINE_4) | TEXTLINE_BIT(TEXTLINE_5) | TEXTLINE_BIT(TEXTLINE_6) | TEXTLINE_BIT(TEXTLINE_7) | TEXTLINE_BIT(TEXTLINE_8) | SPECIAL_BIT(TOPLINE)); + pMapDisplay->TextLinesCenterFlags |= (TEXTLINE_BIT(TEXTLINE_3) | TEXTLINE_BIT(TEXTLINE_4) | TEXTLINE_BIT(TEXTLINE_5) | TEXTLINE_BIT(TEXTLINE_6) | TEXTLINE_BIT(TEXTLINE_7) | TEXTLINE_BIT(TEXTLINE_8)); + IOMapUi.State = TEST_BUTTONS; + } + break; + + case MENU_TEXT : // Show empty program steps + { + pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_LARGE); + + VarsUi.pTmp = (UBYTE*)Cursor; + for (VarsUi.Tmp = 0;(VarsUi.Tmp < SIZE_OF_CURSOR) && (VarsUi.Tmp < (UBYTE)SIZEOF_DATA(Cursor));VarsUi.Tmp++) + { + VarsUi.CursorTmp[VarsUi.Tmp] = *VarsUi.pTmp; + VarsUi.pTmp++; + } + + for (VarsUi.ProgramStepPointer = 0;VarsUi.ProgramStepPointer < ON_BRICK_PROGRAMSTEPS;VarsUi.ProgramStepPointer++) + { + VarsUi.ProgramSteps[VarsUi.ProgramStepPointer] = MENU_ACTION_EMPTY; + } + VarsUi.ProgramStepPointer = 0; + Action = MENU_DRAW; + } + break; + + case MENU_EXIT : // Delete one steps and exit at the end + { + if (VarsUi.ProgramStepPointer) + { + if (VarsUi.ProgramStepPointer < ON_BRICK_PROGRAMSTEPS) + { + VarsUi.ProgramSteps[VarsUi.ProgramStepPointer] = MENU_ACTION_EMPTY; + } + VarsUi.ProgramStepPointer--; + } + else + { + IOMapUi.State = NEXT_MENU; + } + Action = MENU_DRAW; + } + break; + + case MENU_RUN : // Run program steps until end or user press exit button + { + switch (VarsUi.State) + { + case 0 : + { + VarsUi.pTmp = (UBYTE*)Cursor; + for (VarsUi.Tmp = 0;(VarsUi.Tmp < SIZE_OF_CURSOR) && (VarsUi.Tmp < (UBYTE)SIZEOF_DATA(Cursor));VarsUi.Tmp++) + { + VarsUi.CursorTmp[VarsUi.Tmp] = *VarsUi.pTmp; + VarsUi.pTmp++; + } + pMapDisplay->pBitmaps[BITMAP_1] = (BMPMAP*)VarsUi.CursorTmp; + cUiRunning(MENU_INIT); + Action = MENU_DRAW; + VarsUi.State++; + } + break; + + case 1 : // If sound finished -> Init text and program pointer + { + if (SOUND_IDLE == pMapSound->State) + { + VarsUi.ProgramStepPointer = ON_BRICK_PROGRAMSTEPS; + VarsUi.MenuIconTextSave = pMapDisplay->pMenuText; + pMapDisplay->EraseMask |= SPECIAL_BIT(MENUTEXT); + VarsUi.State++; + } + } + break; + + case 2 : // load file to run + { + if (PROG_IDLE == pMapCmd->ProgStatus) + { + sprintf((char*)pMapCmd->FileName,"%s.%s",(char*)VM_PROGRAM_READER,(char*)TXT_SYS_EXT); + pMapCmd->ActivateFlag = TRUE; + VarsUi.State++; + } + } + break; + + case 3 : // Wait for end of file + { + if (PROG_RUNNING != pMapCmd->ProgStatus) + { + pMapCmd->ProgStatus = PROG_RESET; + VarsUi.State = 99; + VarsUi.ProgramStepPointer = ON_BRICK_PROGRAMSTEPS; + } + else + { + if (VarsUi.OBPTimer >= MIN_DISPLAY_UPDATE_TIME) + { + if (IOMapUi.OBPPointer != VarsUi.ProgramStepPointer) + { + VarsUi.ProgramStepPointer = IOMapUi.OBPPointer; + Action = MENU_DRAW; + } + } + } + } + break; + + default : // Program stopped + { + pMapDisplay->pMenuText = VarsUi.MenuIconTextSave; + pMapDisplay->UpdateMask |= SPECIAL_BIT(MENUTEXT); + Action = MENU_DRAW; + VarsUi.State = 0; + } + break; + + } + if (VarsUi.State) + { + cUiRunning(MENU_RUN); + } + else + { + cUiRunning(MENU_EXIT); + } + } + break; + + case MENU_LEFT : // NA + { + IOMapUi.State = TEST_BUTTONS; + } + break; + + case MENU_RIGHT : // NA + { + IOMapUi.State = TEST_BUTTONS; + } + break; + + case MENU_UPDATE : // NA + { + Action = MENU_DRAW; + } + break; + + case MENU_SAVE : // Save NXT program + { + switch (VarsUi.State) + { + case 0 : + { + // Suggest default filename to user + strcpy((char*)VarsUi.UserString,(char*)DEFAULT_PROGRAM_NAME); + VarsUi.State++; + } + break; + + case 1 : + { + if (!cUiGetUserString(1)) + { + if (VarsUi.UserString[0]) + { + sprintf((char*)VarsUi.SelectedFilename,"%s.%s",VarsUi.UserString,TXT_FILE_EXT[FILETYPE_NXT]); + + // If tmp file exist -> ask for overwrite + VarsUi.TmpHandle = pMapLoader->pFunc(FINDFIRST,(UBYTE*)VarsUi.SelectedFilename,VarsUi.FilenameBuffer,&VarsUi.TmpLength); + if (!(VarsUi.TmpHandle & 0x8000)) + { + pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.TmpHandle,NULL,NULL); + VarsUi.State++; + } + else + { + VarsUi.State += 2; + } + } + else + { + VarsUi.State = 99; + } + } + } + break; + + case 2 : + { + if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_OBP_FILE_EXIST_FAIL,TXT_FB_OBP_OVERWRITE_FAIL,0)) + { + VarsUi.State = 0; + } + } + break; + + case 3 : + { + // Rename TEMP_PROGRAM_FILENAME to VarsUi.SelectedFilename(user filename) + sprintf((char*)VarsUi.FilenameBuffer,"%s.%s",(char*)TEMP_PROGRAM_FILENAME,(char*)TXT_TMP_EXT); + VarsUi.TmpHandle = pMapLoader->pFunc(RENAMEFILE,VarsUi.FilenameBuffer,VarsUi.SelectedFilename,&VarsUi.TmpLength); + pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.TmpHandle,NULL,NULL); + VarsUi.State++; + } + break; + + case 4 : // Display saved text + { + if (!cUiFeedback((BMPMAP*)Info,TXT_FB_OBP_FILE_SAVED_INFO,0,DISPLAY_SHOW_TIME)) + { + VarsUi.State++; + } + } + break; + + default : + { + cUiMenuPrevFile(); + IOMapUi.State = NEXT_MENU; + VarsUi.State = 0; + } + break; + + } + } + break; + + case MENU_OVERWRITE : // Over write existing file + { + switch (VarsUi.State) + { + case 0 : + { + // Delete VarsUi.SelectedFilename(user filename) + VarsUi.TmpHandle = pMapLoader->pFunc(FINDFIRST,(UBYTE*)VarsUi.SelectedFilename,VarsUi.FilenameBuffer,&VarsUi.TmpLength); + if (!(VarsUi.TmpHandle & 0x8000)) + { + pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.TmpHandle,NULL,NULL); + pMapLoader->pFunc(DELETE,VarsUi.SelectedFilename,NULL,NULL); + } + + // Rename TEMP_PROGRAM_FILENAME to VarsUi.SelectedFilename(user filename) + sprintf((char*)VarsUi.FilenameBuffer,"%s.%s",(char*)TEMP_PROGRAM_FILENAME,(char*)TXT_TMP_EXT); + VarsUi.TmpHandle = pMapLoader->pFunc(RENAMEFILE,VarsUi.FilenameBuffer,VarsUi.SelectedFilename,&VarsUi.TmpLength); + pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.TmpHandle,NULL,NULL); + VarsUi.State++; + } + break; + + default : // Display saved text + { + if (!cUiFeedback((BMPMAP*)Info,TXT_FB_OBP_FILE_SAVED_INFO,0,DISPLAY_SHOW_TIME)) + { + VarsUi.State = 0; + } + } + break; + + } + + } + break; + + default : // Insert selected action/waitfor in program and save if finished + { + switch (VarsUi.State) + { + case 0 : + { + VarsUi.ProgramSteps[VarsUi.ProgramStepPointer] = Action; + if (VarsUi.ProgramStepPointer < ON_BRICK_PROGRAMSTEPS) + { + VarsUi.ProgramStepPointer++; + } + if (VarsUi.ProgramStepPointer == ON_BRICK_PROGRAMSTEPS) + { + // If tmp file exist -> delete it + sprintf((char*)VarsUi.FilenameBuffer,"%s.%s",(char*)TEMP_PROGRAM_FILENAME,(char*)TXT_TMP_EXT); + VarsUi.TmpHandle = pMapLoader->pFunc(FINDFIRST,VarsUi.FilenameBuffer,VarsUi.SearchFilenameBuffer,&VarsUi.TmpLength); + if (!(VarsUi.TmpHandle & 0x8000)) + { + pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.TmpHandle,NULL,NULL); + pMapLoader->pFunc(DELETE,VarsUi.FilenameBuffer,NULL,NULL); + } + + // Save program as tmp file + VarsUi.TmpLength = FILEHEADER_LENGTH + ON_BRICK_PROGRAMSTEPS; + VarsUi.TmpHandle = pMapLoader->pFunc(OPENWRITE,VarsUi.FilenameBuffer,NULL,&VarsUi.TmpLength); + if (!(VarsUi.TmpHandle & 0x8000)) + { + VarsUi.FileHeader[0] = (UBYTE)(FILEFORMAT_PROGRAM >> 8); + VarsUi.FileHeader[1] = (UBYTE)(FILEFORMAT_PROGRAM); + VarsUi.FileHeader[2] = (UBYTE)(ON_BRICK_PROGRAMSTEPS >> 8); + VarsUi.FileHeader[3] = (UBYTE)(ON_BRICK_PROGRAMSTEPS); + VarsUi.FileHeader[4] = (UBYTE)(ON_BRICK_PROGRAMSTEPS); + VarsUi.FileHeader[5] = (UBYTE)0; + VarsUi.FileHeader[6] = (UBYTE)0; + VarsUi.FileHeader[7] = (UBYTE)0; + VarsUi.TmpLength = FILEHEADER_LENGTH; + pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)VarsUi.FileHeader,&VarsUi.TmpLength); + VarsUi.TmpLength = ON_BRICK_PROGRAMSTEPS; + pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)VarsUi.ProgramSteps,&VarsUi.TmpLength); + pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.TmpHandle,NULL,NULL); + } + else + { + VarsUi.State++; + } + } + Action = MENU_DRAW; + } + break; + + default : // Display memory error text + { + if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_OBP_MEMORY_FULL_FAIL,0,DISPLAY_SHOW_ERROR_TIME)) + { + cUiMenuPrevFile(); + IOMapUi.State = NEXT_MENU; + VarsUi.State = 0; + } + } + break; + + } + } + break; + + } + + // Update display screen + if (Action == MENU_DRAW) + { + VarsUi.OBPTimer = 0; + + for (VarsUi.Pointer = 0;VarsUi.Pointer < ON_BRICK_PROGRAMSTEPS;VarsUi.Pointer++) + { + VarsUi.Tmp = VarsUi.ProgramSteps[VarsUi.Pointer]; + if ((VarsUi.Tmp >= MENU_ACTION_EMPTY) && (VarsUi.Tmp < MENU_ACTION_INVALID)) + { + VarsUi.Tmp -= MENU_ACTION_EMPTY; + pMapDisplay->StepIcons[VarsUi.Pointer] = VarsUi.Tmp + 1; + } + if ((VarsUi.Tmp >= MENU_WAIT_EMPTY) && (VarsUi.Tmp < MENU_WAIT_INVALID)) + { + VarsUi.Tmp -= MENU_WAIT_EMPTY; + pMapDisplay->StepIcons[VarsUi.Pointer] = VarsUi.Tmp + 1 + 16; + } + if (VarsUi.Tmp == MENU_LOOP) + { + pMapDisplay->StepIcons[VarsUi.Pointer] = 31; + } + if (VarsUi.Tmp == MENU_STOP) + { + pMapDisplay->StepIcons[VarsUi.Pointer] = 32; + } + pMapDisplay->UpdateMask |= STEPICON_BIT(STEPICON_1 + VarsUi.Pointer); + } + + // and cursor + pMapDisplay->pBitmaps[BITMAP_1] = (BMPMAP*)VarsUi.CursorTmp; + if (VarsUi.ProgramStepPointer < ON_BRICK_PROGRAMSTEPS) + { + VarsUi.CursorTmp[4] = 13 + (VarsUi.ProgramStepPointer * 17); + VarsUi.CursorTmp[5] = 24; + pMapDisplay->UpdateMask |= BITMAP_BIT(BITMAP_1); + } + if (PROG_RUNNING != pMapCmd->ProgStatus) + { + pMapDisplay->EraseMask |= (TEXTLINE_BIT(TEXTLINE_3) | TEXTLINE_BIT(TEXTLINE_2)); + } + pMapDisplay->EraseMask |= TEXTLINE_BIT(TEXTLINE_4); + pMapDisplay->UpdateMask |= (SPECIAL_BIT(STEPLINE) | SPECIAL_BIT(TOPLINE)); + } + + return (VarsUi.State); +} + + + +//******* cUiFileRun ********************************************************** + +UBYTE cUiFindFileType(UBYTE *Filename) // Find file type number +{ + UBYTE Ext[FILENAME_LENGTH + 1]; + UBYTE Result; + UBYTE Tmp1; + UBYTE Tmp2; + + Result = FILETYPE_ALL; + + Tmp1 = 0; + while ((Filename[Tmp1]) && (Tmp1 < FILENAME_LENGTH)) // Search forward for termination + { + Tmp1++; + } + + while ((Tmp1) && (Filename[Tmp1] != '.')) // Search backward for "." + { + Tmp1--; + } + + if (Filename[Tmp1] == '.') // If "." + { + Tmp1++; + Tmp2 = 0; + + while ((Filename[Tmp1]) && (Tmp1 < FILENAME_LENGTH)) // Convert to upper to Ext + { + Ext[Tmp2] = tolower(Filename[Tmp1]); + Tmp1++; + Tmp2++; + } + Ext[Tmp2] = 0; // Inser termination + + // Calculate type + for (Tmp1 = FILETYPE_ALL;(Tmp1 < FILETYPES) && (Result == FILETYPE_ALL);Tmp1++) + { + if (strcmp((char*)TXT_FILE_EXT[Tmp1],(char*)Ext) == 0) + { + Result = Tmp1; + } + } + } + + return (Result); +} + + +#define FILERUN_FILENAMELINE TEXTLINE_4 +#define FILERUN_TEXTLINE TEXTLINE_5 + +UBYTE cUiFileRun(UBYTE Action) // Run selected file +{ + switch (Action) + { + + case MENU_INIT : + { + VarsUi.Tmp = 0; + while ((VarsUi.SelectedFilename[VarsUi.Tmp]) && (VarsUi.Tmp < FILENAME_LENGTH)) // Search forward for termination + { + VarsUi.Tmp++; + } + + while ((VarsUi.Tmp) && (VarsUi.SelectedFilename[VarsUi.Tmp] != '.')) // Search backward for "." + { + VarsUi.Tmp--; + } + + if (VarsUi.Tmp > DISPLAYLINE_LENGTH) + { + VarsUi.Tmp = DISPLAYLINE_LENGTH; + } + + VarsUi.DisplayBuffer[VarsUi.Tmp] = 0; + + while (VarsUi.Tmp) // Copy only name not ext + { + VarsUi.Tmp--; + VarsUi.DisplayBuffer[VarsUi.Tmp] = VarsUi.SelectedFilename[VarsUi.Tmp]; + } + + pMapDisplay->pTextLines[FILERUN_FILENAMELINE] = (UBYTE*)VarsUi.DisplayBuffer; + pMapDisplay->TextLinesCenterFlags = TEXTLINE_BIT(FILERUN_FILENAMELINE); + pMapDisplay->UpdateMask = TEXTLINE_BIT(FILERUN_FILENAMELINE); + } + break; + + case MENU_RUN : + { + if (VarsUi.Timer < DISPLAY_SHOW_TIME) + { + VarsUi.Timer++; + } + + switch (VarsUi.State) + { + case 0 : + { + IOMapUi.Flags |= UI_BUSY; + VarsUi.State++; + } + break; + + case 1 : // Set state from extention when sound is ready + { + if (SOUND_IDLE == pMapSound->State) + { + pMapDisplay->pTextLines[FILERUN_TEXTLINE] = cUiGetString(TXT_FILERUN_RUNNING); + pMapDisplay->UpdateMask = (TEXTLINE_BIT(FILERUN_TEXTLINE) | TEXTLINE_BIT(FILERUN_FILENAMELINE)); + pMapDisplay->TextLinesCenterFlags = (TEXTLINE_BIT(FILERUN_TEXTLINE) | TEXTLINE_BIT(FILERUN_FILENAMELINE)); + cUiRunning(MENU_INIT); + VarsUi.State++; + } + } + break; + + case 2 : + { + if ((!pMapDisplay->EraseMask) && (!pMapDisplay->UpdateMask)) + { + VarsUi.State = 10 * cUiFindFileType(VarsUi.SelectedFilename); + if (VarsUi.State == (FILETYPE_TRYME * 10)) + { + VarsUi.State = FILETYPE_LMS * 10; + } + } + } + break; + + case (FILETYPE_SOUND * 10 + 0) : // Start sound file (*.snd, *.rso) Wait for sound idle + { + strcpy((char*)pMapSound->SoundFilename,(char*)VarsUi.SelectedFilename); + pMapSound->Volume = IOMapUi.Volume; + pMapSound->Mode = SOUND_ONCE; + pMapSound->Flags |= SOUND_UPDATE; + VarsUi.State++; + } + break; + + case (FILETYPE_SOUND * 10 + 1) : // Wait for stop or user break + { + cUiRunning(MENU_RUN); + + if (SOUND_IDLE == pMapSound->State) + { + pMapDisplay->pTextLines[FILERUN_TEXTLINE] = cUiGetString(TXT_FILERUN_ENDED); + VarsUi.State = 99; + } + if (BUTTON_EXIT == cUiReadButtons()) + { + pMapSound->Flags &= ~SOUND_UPDATE; + pMapSound->State = SOUND_STOP; + pMapDisplay->pTextLines[FILERUN_TEXTLINE] = cUiGetString(TXT_FILERUN_ABORTED); + VarsUi.State = 99; + } + } + break; + + case (FILETYPE_LMS * 10 + 0) : // Start LMS file (*.rxe) + { + if ((!pMapDisplay->EraseMask) && (pMapCmd->ProgStatus == PROG_IDLE) && (!pMapButton->State[BTN4])) + { + strcpy((char*)pMapCmd->FileName,(char*)VarsUi.SelectedFilename); + pMapCmd->ActivateFlag = TRUE; + VarsUi.State++; + } + } + break; + + case (FILETYPE_LMS * 10 + 1) : // Wait for program stop or user break + { + cUiRunning(MENU_RUN); + + if ((IOMapUi.Flags & UI_REDRAW_STATUS) && (IOMapUi.Flags & UI_ENABLE_STATUS_UPDATE)) + { + pMapDisplay->pTextLines[FILERUN_FILENAMELINE] = (UBYTE*)VarsUi.DisplayBuffer; + pMapDisplay->TextLinesCenterFlags = TEXTLINE_BIT(FILERUN_FILENAMELINE); + pMapDisplay->UpdateMask = TEXTLINE_BIT(FILERUN_FILENAMELINE); + pMapDisplay->pTextLines[FILERUN_TEXTLINE] = cUiGetString(TXT_FILERUN_RUNNING); + pMapDisplay->UpdateMask = (TEXTLINE_BIT(FILERUN_TEXTLINE) | TEXTLINE_BIT(FILERUN_FILENAMELINE)); + pMapDisplay->TextLinesCenterFlags = (TEXTLINE_BIT(FILERUN_TEXTLINE) | TEXTLINE_BIT(FILERUN_FILENAMELINE)); + } + + switch (pMapCmd->ProgStatus) + { + case PROG_RUNNING : + { + } + break; + + case PROG_OK : + { + pMapDisplay->pTextLines[FILERUN_TEXTLINE] = cUiGetString(TXT_FILERUN_ENDED); + VarsUi.State = 99; + } + break; + + case PROG_ABORT : + { + pMapDisplay->pTextLines[FILERUN_TEXTLINE] = cUiGetString(TXT_FILERUN_ABORTED); + VarsUi.State = 99; + } + break; + + default : + { + pMapDisplay->pTextLines[FILERUN_TEXTLINE] = cUiGetString(TXT_FILERUN_FILE_ERROR); + VarsUi.State = 99; + } + break; + + } + } + break; + + case (FILETYPE_NXT * 10 + 0) :// Start Program file (*.prg) + { + VarsUi.TmpHandle = pMapLoader->pFunc(OPENREAD,VarsUi.SelectedFilename,NULL,&VarsUi.TmpLength); + if (!(VarsUi.TmpHandle & 0x8000)) + { + VarsUi.TmpLength = FILEHEADER_LENGTH; + pMapLoader->pFunc(READ,(UBYTE*)&VarsUi.TmpHandle,VarsUi.FileHeader,&VarsUi.TmpLength); + VarsUi.TmpLength = ON_BRICK_PROGRAMSTEPS; + pMapLoader->pFunc(READ,(UBYTE*)&VarsUi.TmpHandle,VarsUi.ProgramSteps,&VarsUi.TmpLength); + pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.TmpHandle,NULL,NULL); + } + if ((ON_BRICK_PROGRAMSTEPS == VarsUi.TmpLength) && (VarsUi.FileHeader[0] == (UBYTE)(FILEFORMAT_PROGRAM >> 8)) && (VarsUi.FileHeader[1] == (UBYTE)(FILEFORMAT_PROGRAM))) + { + // If tmp file exist -> delete it + sprintf((char*)VarsUi.FilenameBuffer,"%s.%s",(char*)TEMP_PROGRAM_FILENAME,(char*)TXT_TMP_EXT); + VarsUi.TmpHandle = pMapLoader->pFunc(FINDFIRST,VarsUi.FilenameBuffer,VarsUi.SearchFilenameBuffer,&VarsUi.TmpLength); + if (!(VarsUi.TmpHandle & 0x8000)) + { + pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.TmpHandle,NULL,NULL); + pMapLoader->pFunc(DELETE,VarsUi.FilenameBuffer,NULL,NULL); + } + + // Save program as tmp file + VarsUi.TmpLength = FILEHEADER_LENGTH + ON_BRICK_PROGRAMSTEPS; + VarsUi.TmpHandle = pMapLoader->pFunc(OPENWRITE,VarsUi.FilenameBuffer,NULL,&VarsUi.TmpLength); + if (!(VarsUi.TmpHandle & 0x8000)) + { + VarsUi.TmpLength = FILEHEADER_LENGTH; + pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)VarsUi.FileHeader,&VarsUi.TmpLength); + VarsUi.TmpLength = ON_BRICK_PROGRAMSTEPS; + pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)VarsUi.ProgramSteps,&VarsUi.TmpLength); + pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.TmpHandle,NULL,NULL); + } + + pMapDisplay->UpdateMask &= ~TEXTLINE_BIT(FILERUN_FILENAMELINE); + pMapDisplay->EraseMask |= TEXTLINE_BIT(FILERUN_FILENAMELINE); + VarsUi.State++; + } + else + { + pMapDisplay->pTextLines[FILERUN_TEXTLINE] = cUiGetString(TXT_FILERUN_FILE_ERROR); + VarsUi.State = 99; + } + VarsUi.GUSState = 0; + } + break; + + case (FILETYPE_NXT * 10 + 1) : // Wait for program stop or user break + { + VarsUi.State = VarsUi.GUSState; + cUiOnBrickProgramming(MENU_RUN); + VarsUi.GUSState = VarsUi.State; + if (VarsUi.State) + { + VarsUi.State = (FILETYPE_NXT * 10 + 1); + } + else + { + pMapDisplay->pTextLines[FILERUN_TEXTLINE] = cUiGetString(TXT_FILERUN_ENDED); + VarsUi.State = 99; + } + } + break; + + case 99 : // Wait for display show time or user action + { + pMapDisplay->EraseMask = SCREEN_BIT(SCREEN_LARGE); + pMapDisplay->UpdateMask = (TEXTLINE_BIT(FILERUN_TEXTLINE) | TEXTLINE_BIT(FILERUN_FILENAMELINE)); + pMapDisplay->TextLinesCenterFlags = (TEXTLINE_BIT(FILERUN_TEXTLINE) | TEXTLINE_BIT(FILERUN_FILENAMELINE)); + IOMapUi.Flags |= UI_REDRAW_STATUS | UI_ENABLE_STATUS_UPDATE; + cUiRunning(MENU_UPDATE); + VarsUi.Timer = 0; + VarsUi.State++; + } + break; + + default : + { + if ((++VarsUi.Timer >= DISPLAY_SHOW_TIME) || (BUTTON_NONE != cUiReadButtons())) + { + if (pMapCmd->ProgStatus != PROG_IDLE) + pMapCmd->ProgStatus = PROG_RESET; + pMapDisplay->UpdateMask = 0; + pMapDisplay->TextLinesCenterFlags = 0; + cUiRunning(MENU_EXIT); + pMapDisplay->EraseMask = TEXTLINE_BIT(FILERUN_TEXTLINE); + pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(FILERUN_FILENAMELINE); + pMapDisplay->UpdateMask |= TEXTLINE_BIT(FILERUN_FILENAMELINE); + IOMapUi.Flags &= ~UI_BUSY; + VarsUi.State = 0; + } + } + break; + + } + } + break; + + } + + return (VarsUi.State); +} + + + +//******* cUiFileDelete ******************************************************* + +UBYTE cUiFileDelete(UBYTE Action) +{ + if (MENU_INIT == Action) + { + switch (VarsUi.State) + { + case 0 : + { + VarsUi.State++; + } + break; + + case 1 : + { + if (SOUND_IDLE == pMapSound->State) + { + VarsUi.State++; + } + } + break; + + case 2 : + { + pMapLoader->pFunc(DELETE,VarsUi.SelectedFilename,NULL,NULL); + VarsUi.State++; + } + break; + + default : // Display deleted text + { + if (!cUiFeedback((BMPMAP*)Info,TXT_FB_FD_FILE_DELETED_INFO,0,DISPLAY_SHOW_TIME)) + { + IOMapUi.State = EXIT_PRESSED; + VarsUi.State = 0; + } + } + break; + + } + } + + return (VarsUi.State); +} + + +//******* cUiView ************************************************************ + +UBYTE cUiView(UBYTE Action) // MENU_INIT +{ + switch (VarsUi.State) + { + case 0 : + { + switch (Action) + { + case MENU_INIT : // Init + { + pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_VIEW_SELECT); + pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_3); + pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3); + pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_SMALL); +// Init ports + for (VarsUi.Tmp = 0;VarsUi.Tmp < DATALOGPORTS;VarsUi.Tmp++) + { + VarsUi.DatalogPort[VarsUi.Tmp] = MENU_SENSOR_EMPTY; + } + } + break; + + default : + { + if ((Action > MENU_SENSOR_EMPTY) && (Action < MENU_SENSOR_INVALID)) + { + VarsUi.SelectedSensor = Action; + } + if ((Action >= MENU_PORT_1) && (Action <= MENU_PORT_C)) + { + VarsUi.SelectedPort = Action; + + VarsUi.DatalogPort[VarsUi.SelectedPort - MENU_PORT_1] = VarsUi.SelectedSensor; + + IOMapUi.Flags |= UI_BUSY; + pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_LARGE); + pMapDisplay->pBitmaps[BITMAP_1] = (BMPMAP*)Display; + pMapDisplay->UpdateMask = BITMAP_BIT(BITMAP_1); + IOMapUi.Flags |= UI_REDRAW_STATUS; + VarsUi.ReadoutTimer = 0;; + VarsUi.State++; + + VarsUi.SensorReset = TRUE; + } + } + break; + + } + } + break; + + case 1 : + { + VarsUi.ReadoutTimer++; + cUiUpdateSensor(1); + if (VarsUi.ReadoutTimer >= DISPLAY_VIEW_UPDATE) + { + VarsUi.ReadoutTimer = 0; + cUiPrintSensorInDisplayBuffer(VarsUi.SelectedPort); + pMapDisplay->pTextLines[TEXTLINE_4] = VarsUi.DisplayBuffer; + pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_4); + pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_4); + } + + VarsUi.Tmp = cUiReadButtons(); + if (VarsUi.Tmp == BUTTON_EXIT) + { + pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_VIEW_SELECT); + pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_3); + pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3); + pMapDisplay->UpdateMask &= ~TEXTLINE_BIT(TEXTLINE_4); + pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_SMALL); + VarsUi.State++; + } + if (VarsUi.Tmp == BUTTON_ENTER) + { + VarsUi.SensorReset = TRUE; + } + } + break; + + default : + { + cUiReleaseSensors(); + IOMapUi.Flags &= ~UI_BUSY; + VarsUi.State = 0; + IOMapUi.State = EXIT_PRESSED; + } + break; + + } + + return (VarsUi.State); +} + + + +//******* cUiBtOn ************************************************************ + +UBYTE cUiBtOn(UBYTE Action) +{ + switch (Action) + { + case MENU_ON : + { + switch (VarsUi.State) + { + case 0 : // Turn BT on + { + VarsUi.BTCommand = (UBYTE)BTON; + VarsUi.BTPar1 = (UBYTE)0; + VarsUi.BTPar2 = (UBYTE)0; + if (pMapComm->pFunc(VarsUi.BTCommand,VarsUi.BTPar1,VarsUi.BTPar2,0,NULL,&(VarsUi.BTResult)) == SUCCESS) + { + VarsUi.State++; + } + else + { + VarsUi.State = 99; + } + } + break; + + case 1 : // Display turning on text + { + if (!cUiFeedback((BMPMAP*)Wait,TXT_FB_BT_TURNING_ON_WAIT,0,0)) + { + VarsUi.State++; + } + } + break; + + case 2 : // Check result + { + if (VarsUi.BTResult != INPROGRESS) + { + if (VarsUi.BTResult == SUCCESS) + { + Action = MENU_EXIT; + } + else + { + VarsUi.State++; + } + } + } + break; + + default : // Display fail text + { + if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_BT_TURNING_ON_FAIL,0,DISPLAY_SHOW_ERROR_TIME)) + { + Action = MENU_EXIT; + } + } + break; + + } + } + break; + + case MENU_OFF : + { + switch (VarsUi.State) + { + case 0 : // Turn BT off + { + VarsUi.BTCommand = (UBYTE)BTOFF; + VarsUi.BTPar1 = (UBYTE)0; + VarsUi.BTPar2 = (UBYTE)0; + if (pMapComm->pFunc(VarsUi.BTCommand,VarsUi.BTPar1,VarsUi.BTPar2,0,NULL,&(VarsUi.BTResult)) == SUCCESS) + { + VarsUi.State++; + } + else + { + VarsUi.State = 99; + } + } + break; + + case 1 : // Display turning off text + { + if (!cUiFeedback((BMPMAP*)Wait,TXT_FB_BT_TURNING_OFF_WAIT,0,0)) + { + VarsUi.State++; + } + } + break; + + case 2 : // Check result + { + if (VarsUi.BTResult != INPROGRESS) + { + if (VarsUi.BTResult == SUCCESS) + { + Action = MENU_EXIT; + } + else + { + VarsUi.State++; + } + } + } + break; + + default : // Display fail text + { + if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_BT_TURNING_OFF_FAIL,0,DISPLAY_SHOW_ERROR_TIME)) + { + Action = MENU_EXIT; + } + } + break; + + } + } + break; + + } + if (Action == MENU_EXIT) + { + VarsUi.State = 0; + IOMapUi.State = EXIT_PRESSED; + } + + return (VarsUi.State); +} + + + +//******* cUiBtVisiability *************************************************** + +UBYTE cUiBtVisiability(UBYTE Action) // Visibility on/off +{ + switch (Action) + { + case MENU_ON : // Set visible + { + switch (VarsUi.State) + { + case 0 : + { + VarsUi.BTCommand = (UBYTE)VISIBILITY; + VarsUi.BTPar1 = (UBYTE)1; + VarsUi.BTPar2 = (UBYTE)0; + if (pMapComm->pFunc(VarsUi.BTCommand,VarsUi.BTPar1,VarsUi.BTPar2,0,NULL,&(VarsUi.BTResult)) == SUCCESS) + { + VarsUi.State++; + } + else + { + Action = MENU_EXIT; + } + } + break; + + default : + { + if (VarsUi.BTResult != INPROGRESS) + { + Action = MENU_EXIT; + } + } + break; + + } + } + break; + + case MENU_OFF : // Set invisible + { + switch (VarsUi.State) + { + case 0 : + { + VarsUi.BTCommand = (UBYTE)VISIBILITY; + VarsUi.BTPar1 = (UBYTE)0; + VarsUi.BTPar2 = (UBYTE)0; + if (pMapComm->pFunc(VarsUi.BTCommand,VarsUi.BTPar1,VarsUi.BTPar2,0,NULL,&(VarsUi.BTResult)) == SUCCESS) + { + VarsUi.State++; + } + else + { + Action = MENU_EXIT; + } + } + break; + + default : + { + if (VarsUi.BTResult != INPROGRESS) + { + Action = MENU_EXIT; + } + } + break; + + } + } + break; + + } + if (Action == MENU_EXIT) + { + VarsUi.State = 0; + IOMapUi.State = EXIT_PRESSED; + } + + return (VarsUi.State); +} + + + +//******* cUiBtSearch ******************************************************** + +UBYTE cUiBtSearch(UBYTE Action) // Search for devices +{ + if (Action == MENU_INIT) // Init + { + switch (VarsUi.State) + { + case 0 : // Show three menu icons + { + pMapDisplay->pMenuIcons[MENUICON_LEFT] = pMapDisplay->pMenuIcons[MENUICON_CENTER]; + pMapDisplay->pMenuIcons[MENUICON_RIGHT] = pMapDisplay->pMenuIcons[MENUICON_CENTER]; + pMapDisplay->UpdateMask |= MENUICON_BITS; + VarsUi.State++; + } + break; + + case 1 : // Display wait text and start search + { + if (!cUiFeedback((BMPMAP*)Wait,TXT_FB_BT_SEARCHING_WAIT,0,0)) + { + VarsUi.BTCommand = (UBYTE)SEARCH; + VarsUi.BTPar1 = (UBYTE)1; + VarsUi.BTPar2 = (UBYTE)0; + if (pMapComm->pFunc(VarsUi.BTCommand,VarsUi.BTPar1,VarsUi.BTPar2,0,NULL,&(VarsUi.BTResult)) == SUCCESS) + { + VarsUi.DisplayBuffer[0] = 0; + pMapDisplay->pMenuText = VarsUi.DisplayBuffer; + pMapDisplay->UpdateMask |= SPECIAL_BIT(MENUTEXT); + VarsUi.NoOfNames = 0; + VarsUi.NoOfDevices = 0; + VarsUi.State++; + } + else + { + VarsUi.State = 99; + } + } + } + break; + + case 2 : // Wait for search finished + { + if (VarsUi.NoOfNames != pMapComm->BtDeviceNameCnt) + { + VarsUi.NoOfNames = pMapComm->BtDeviceNameCnt; + + if ((VarsUi.NoOfNames) && (VarsUi.NoOfNames <= DISPLAYLINE_LENGTH)) + { + sprintf((char*)VarsUi.DisplayBuffer,"%.*s",VarsUi.NoOfNames,"****************"); + pMapDisplay->pMenuText = VarsUi.DisplayBuffer; + pMapDisplay->UpdateMask |= SPECIAL_BIT(MENUTEXT); + } + } + if (VarsUi.NoOfDevices != pMapComm->BtDeviceCnt) + { + VarsUi.NoOfDevices = pMapComm->BtDeviceCnt; + + if ((VarsUi.NoOfDevices) && (VarsUi.NoOfDevices <= DISPLAYLINE_LENGTH)) + { + sprintf((char*)VarsUi.DisplayBuffer,"%.*s",VarsUi.NoOfDevices,"????????????????"); + pMapDisplay->pMenuText = VarsUi.DisplayBuffer; + pMapDisplay->UpdateMask |= SPECIAL_BIT(MENUTEXT); + } + } + + if (VarsUi.BTResult != INPROGRESS) + { + cUiBTCommand(UI_BT_GET_DEVICES,0,&VarsUi.Devices,NULL); + if (VarsUi.Devices) + { + VarsUi.State++; + } + else + { + VarsUi.State = 99; + } + } + + if (cUiReadButtons() == BUTTON_EXIT) + { + VarsUi.BTCommand = (UBYTE)STOPSEARCH; + VarsUi.BTPar1 = (UBYTE)0; + VarsUi.BTPar2 = (UBYTE)0; + pMapComm->pFunc(VarsUi.BTCommand,VarsUi.BTPar1,VarsUi.BTPar2,0,NULL,&(VarsUi.BTResult)); + VarsUi.State = 4; + } + } + break; + + case 3 : // Auto enter to next menu + { + IOMapUi.State = ENTER_PRESSED; + VarsUi.State = 0; + } + break; + + case 4 : // Display info text + { + if (!cUiFeedback((BMPMAP*)Info,TXT_FB_BT_SEARCH_ABORTED_INFO,0,DISPLAY_SHOW_TIME)) + { + VarsUi.State++; + } + } + break; + + case 5 : // Wait for abort + { + if (VarsUi.BTResult != INPROGRESS) + { + cUiBTCommand(UI_BT_GET_DEVICES,0,&VarsUi.Devices,NULL); + if (VarsUi.Devices) + { + VarsUi.State++; + } + else + { + VarsUi.State = 99; + } + } + } + break; + + case 6 : // Auto enter to next menu + { + IOMapUi.State = ENTER_PRESSED; + VarsUi.State = 0; + } + break; + + default : // Display fail text + { + if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_BT_SEARCHING_FAIL,0,DISPLAY_SHOW_ERROR_TIME)) + { + VarsUi.State = 0; + IOMapUi.State = EXIT_PRESSED; + } + } + break; + + } + } + + return (VarsUi.State); +} + + + +//******* cUiBtDeviceList **************************************************** + +UBYTE cUiBtDeviceList(UBYTE Action) // Show devices +{ + switch (Action) + { + case MENU_INIT : // Init "Search" list + { + VarsUi.SelectedDevice = 0; + VarsUi.DevicesKnown = 0; + cUiBTCommand(UI_BT_GET_DEVICES,VarsUi.DevicesKnown,&VarsUi.Devices,NULL); + if (VarsUi.Devices) + { + pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_BTDEVICELIST_SELECT); + pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_3); + pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3); + VarsUi.MenuIconTextSave = pMapDisplay->pMenuText; + VarsUi.DeviceCenter = 1; + Action = MENU_DRAW; + IOMapUi.State = TEST_BUTTONS; + } + else + { + Action = MENU_EXIT; + } + } + break; + + case MENU_INIT_ALTERNATIVE : // Init only "My contacts" + { + VarsUi.SelectedDevice = 0; + VarsUi.DevicesKnown = 1; + cUiBTCommand(UI_BT_GET_DEVICES,VarsUi.DevicesKnown,&VarsUi.Devices,NULL); + if (VarsUi.Devices) + { + pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_BTDEVICELIST_SELECT); + pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_3); + pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3); + VarsUi.MenuIconTextSave = pMapDisplay->pMenuText; + VarsUi.DeviceCenter = 1; + Action = MENU_DRAW; + IOMapUi.State = TEST_BUTTONS; + } + else + { + Action = MENU_EXIT; + } + } + break; + + case MENU_LEFT : // Left button + { + cUiListLeft(VarsUi.Devices,&VarsUi.DeviceCenter); + Action = MENU_DRAW; + IOMapUi.State = TEST_BUTTONS; + } + break; + + case MENU_RIGHT : // Right button + { + cUiListRight(VarsUi.Devices,&VarsUi.DeviceCenter); + Action = MENU_DRAW; + IOMapUi.State = TEST_BUTTONS; + } + break; + + case MENU_SELECT : // Select for connection + { + VarsUi.SelectedDevice = VarsUi.DeviceCenter; + pMapDisplay->pMenuText = VarsUi.MenuIconTextSave; + IOMapUi.State = NEXT_MENU; + } + break; + + case MENU_DELETE : // Remove device from "My contacts" + { + switch (VarsUi.State) + { + case 0 : + { + if (VarsUi.SelectedDevice) + { + if (cUiBTGetDeviceIndex(VarsUi.DevicesKnown,VarsUi.SelectedDevice - 1,&VarsUi.BTIndex)) + { + VarsUi.BTCommand = (UBYTE)REMOVEDEVICE; + VarsUi.BTPar1 = (UBYTE)VarsUi.BTIndex; + VarsUi.BTPar2 = (UBYTE)0; + if (pMapComm->pFunc(VarsUi.BTCommand,VarsUi.BTPar1,VarsUi.BTPar2,0,NULL,&(VarsUi.BTResult)) == SUCCESS) + { + VarsUi.State++; + } + else + { + VarsUi.State = 99; + } + } + else + { + Action = MENU_EXIT; + } + VarsUi.SelectedDevice = 0; + } + else + { + Action = MENU_EXIT; + } + } + break; + + case 1 : + { + if (VarsUi.BTResult != INPROGRESS) + { + if (VarsUi.BTResult == SUCCESS) + { + Action = MENU_EXIT; + } + else + { + VarsUi.State = 99; + } + } + } + break; + + default : // Display fail text + { + if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_BT_REMOVE_FAIL,0,DISPLAY_SHOW_ERROR_TIME)) + { + Action = MENU_EXIT; + } + } + break; + + } + } + break; + + } + + if (Action == MENU_DRAW) + { + cUiListCalc(VarsUi.Devices,&VarsUi.DeviceCenter,&VarsUi.DeviceLeft,&VarsUi.DeviceRight); + + pMapDisplay->pMenuIcons[MENUICON_LEFT] = NULL; + pMapDisplay->pMenuIcons[MENUICON_CENTER] = NULL; + pMapDisplay->pMenuIcons[MENUICON_RIGHT] = NULL; + + if (VarsUi.DeviceLeft) + { + VarsUi.Tmp = VarsUi.DeviceLeft - 1; + cUiBTCommand(UI_BT_GET_DEVICE_TYPE,VarsUi.DevicesKnown,&VarsUi.Tmp,&VarsUi.DeviceType); + pMapDisplay->pMenuIcons[MENUICON_LEFT] = (UBYTE*)&Devices->Data[VarsUi.DeviceType * Devices->ItemPixelsX * (Devices->ItemPixelsY / 8)]; + pMapDisplay->UpdateMask |= MENUICON_BIT(MENUICON_LEFT); + } + if (VarsUi.DeviceCenter) + { + VarsUi.Tmp = VarsUi.DeviceCenter - 1; + cUiBTCommand(UI_BT_GET_DEVICE_TYPE,VarsUi.DevicesKnown,&VarsUi.Tmp,&VarsUi.DeviceType); + pMapDisplay->pMenuIcons[MENUICON_CENTER] = (UBYTE*)&Devices->Data[VarsUi.DeviceType * Devices->ItemPixelsX * (Devices->ItemPixelsY / 8)]; + pMapDisplay->UpdateMask |= MENUICON_BIT(MENUICON_CENTER); + } + if (VarsUi.DeviceRight) + { + VarsUi.Tmp = VarsUi.DeviceRight - 1; + cUiBTCommand(UI_BT_GET_DEVICE_TYPE,VarsUi.DevicesKnown,&VarsUi.Tmp,&VarsUi.DeviceType); + pMapDisplay->pMenuIcons[MENUICON_RIGHT] = (UBYTE*)&Devices->Data[VarsUi.DeviceType * Devices->ItemPixelsX * (Devices->ItemPixelsY / 8)]; + pMapDisplay->UpdateMask |= MENUICON_BIT(MENUICON_RIGHT); + } + + pMapDisplay->EraseMask |= TEXTLINE_BIT(TEXTLINE_5); + + VarsUi.Tmp = VarsUi.DeviceCenter - 1; + cUiBTCommand(UI_BT_GET_DEVICE_NAME,VarsUi.DevicesKnown,&VarsUi.Tmp,VarsUi.DisplayBuffer); + + pMapDisplay->pMenuText = VarsUi.DisplayBuffer; + pMapDisplay->EraseMask |= MENUICON_BITS; + pMapDisplay->UpdateMask |= (SPECIAL_BIT(FRAME_SELECT) | SPECIAL_BIT(MENUTEXT)); + } + if (Action == MENU_EXIT) + { + VarsUi.State = 0; + IOMapUi.State = EXIT_PRESSED; + } + + return (VarsUi.State); +} + + +//******* cUiBtConnectList *************************************************** + +UBYTE cUiBtConnectList(UBYTE Action) // Show connections and maybe disconnect +{ + switch (Action) + { + case MENU_INIT : // Init + { + VarsUi.Slots = SIZE_OF_BT_CONNECT_TABLE; + VarsUi.SlotCenter = 2; + Action = MENU_DRAW; + IOMapUi.State = TEST_BUTTONS; + } + break; + + case MENU_LEFT : // Left button + { + cUiListLeft(VarsUi.Slots,&VarsUi.SlotCenter); + Action = MENU_DRAW; + IOMapUi.State = TEST_BUTTONS; + } + break; + + case MENU_RIGHT : // Right button + { + cUiListRight(VarsUi.Slots,&VarsUi.SlotCenter); + Action = MENU_DRAW; + IOMapUi.State = TEST_BUTTONS; + } + break; + + case MENU_UPDATE : // Check connection valid + { + VarsUi.Tmp = VarsUi.SlotCenter - 1; + if (cUiBTCommand(UI_BT_GET_CONNECTION_VALID,NULL,&VarsUi.Tmp,NULL) != UI_BT_SUCCES) + { + Action = MENU_EXIT; + } + } + break; + + case MENU_DISCONNECT : // Disconnect + { + switch (VarsUi.State) + { + case 0 : + { + VarsUi.SelectedSlot = VarsUi.SlotCenter - 1; + VarsUi.BTCommand = (UBYTE)DISCONNECT; + VarsUi.BTPar1 = (UBYTE)VarsUi.SelectedSlot; + VarsUi.BTPar2 = (UBYTE)0; + if (pMapComm->pFunc(VarsUi.BTCommand,VarsUi.BTPar1,VarsUi.BTPar2,0,NULL,&(VarsUi.BTResult)) == SUCCESS) + { + VarsUi.State++; + } + else + { + VarsUi.State = 99; + } + } + break; + + case 1 : + { + if (VarsUi.BTResult != INPROGRESS) + { + if (VarsUi.BTResult == SUCCESS) + { + Action = MENU_EXIT; + } + else + { + VarsUi.State = 99; + } + } + } + break; + + default : // Display fail text + { + if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_BT_DISCONNECT_FAIL,0,DISPLAY_SHOW_ERROR_TIME)) + { + Action = MENU_EXIT; + } + } + break; + + } + } + break; + + } + if (Action == MENU_DRAW) + { + cUiListCalc(VarsUi.Slots,&VarsUi.SlotCenter,&VarsUi.SlotLeft,&VarsUi.SlotRight); + + pMapDisplay->pBitmaps[BITMAP_2] = (BMPMAP*)VarsUi.PortBitmapLeft; + pMapDisplay->pBitmaps[BITMAP_3] = (BMPMAP*)VarsUi.PortBitmapCenter; + pMapDisplay->pBitmaps[BITMAP_4] = (BMPMAP*)VarsUi.PortBitmapRight; + + VarsUi.Tmp = VarsUi.SlotLeft - 1; + if (cUiBTCommand(UI_BT_GET_CONNECTION_VALID,NULL,&VarsUi.Tmp,NULL) == UI_BT_SUCCES) + { + cUiBTCommand(UI_BT_GET_CONNECTION_TYPE,NULL,&VarsUi.Tmp,&VarsUi.DeviceType); + pMapDisplay->pMenuIcons[MENUICON_LEFT] = (UBYTE*)&Devices->Data[VarsUi.DeviceType * Devices->ItemPixelsX * (Devices->ItemPixelsY / 8)]; + cUiDrawPortNo(VarsUi.PortBitmapLeft,MENUICON_LEFT,VarsUi.Tmp); + pMapDisplay->UpdateMask |= BITMAP_BIT(BITMAP_2); + } + else + { + pMapDisplay->pMenuIcons[MENUICON_LEFT] = (UBYTE*)&Connections->Data[VarsUi.Tmp * Connections->ItemPixelsX * (Connections->ItemPixelsY / 8)]; + } + + VarsUi.Tmp = VarsUi.SlotCenter - 1; + cUiBTCommand(UI_BT_GET_CONNECTION_NAME,NULL,&VarsUi.Tmp,VarsUi.DisplayBuffer); + pMapDisplay->EraseMask |= TEXTLINE_BIT(TEXTLINE_5); + pMapDisplay->pMenuText = VarsUi.DisplayBuffer; + + if (cUiBTCommand(UI_BT_GET_CONNECTION_VALID,NULL,&VarsUi.Tmp,NULL) == UI_BT_SUCCES) + { + cUiBTCommand(UI_BT_GET_CONNECTION_TYPE,NULL,&VarsUi.Tmp,&VarsUi.DeviceType); + pMapDisplay->pMenuIcons[MENUICON_CENTER] = (UBYTE*)&Devices->Data[VarsUi.DeviceType * Devices->ItemPixelsX * (Devices->ItemPixelsY / 8)]; + cUiDrawPortNo(VarsUi.PortBitmapCenter,MENUICON_CENTER,VarsUi.Tmp); + pMapDisplay->UpdateMask |= BITMAP_BIT(BITMAP_3); + } + else + { + pMapDisplay->pMenuIcons[MENUICON_CENTER] = (UBYTE*)&Connections->Data[VarsUi.Tmp * Connections->ItemPixelsX * (Connections->ItemPixelsY / 8)]; + } + VarsUi.Tmp = VarsUi.SlotRight - 1; + if (cUiBTCommand(UI_BT_GET_CONNECTION_VALID,NULL,&VarsUi.Tmp,NULL) == UI_BT_SUCCES) + { + cUiBTCommand(UI_BT_GET_CONNECTION_TYPE,NULL,&VarsUi.Tmp,&VarsUi.DeviceType); + pMapDisplay->pMenuIcons[MENUICON_RIGHT] = (UBYTE*)&Devices->Data[VarsUi.DeviceType * Devices->ItemPixelsX * (Devices->ItemPixelsY / 8)]; + cUiDrawPortNo(VarsUi.PortBitmapRight,MENUICON_RIGHT,VarsUi.Tmp); + pMapDisplay->UpdateMask |= BITMAP_BIT(BITMAP_4); + } + else + { + pMapDisplay->pMenuIcons[MENUICON_RIGHT] = (UBYTE*)&Connections->Data[VarsUi.Tmp * Connections->ItemPixelsX * (Connections->ItemPixelsY / 8)]; + } + pMapDisplay->EraseMask &= ~SCREEN_BIT(SCREEN_LARGE); + pMapDisplay->EraseMask |= MENUICON_BITS; + pMapDisplay->UpdateMask |= (MENUICON_BITS | SPECIAL_BIT(FRAME_SELECT) | SPECIAL_BIT(MENUTEXT)); + } + if (Action == MENU_EXIT) + { + VarsUi.State = 0; + IOMapUi.State = EXIT_PRESSED; + } + + + return (VarsUi.State); +} + + +UBYTE cUiBtConnect(UBYTE Action) // Select connection no and insert device +{ + switch (Action) + { + case MENU_INIT : // Init + { + VarsUi.Slots = SIZE_OF_BT_CONNECT_TABLE - 1; + VarsUi.SlotCenter = 1; + Action = MENU_DRAW; + IOMapUi.State = TEST_BUTTONS; + } + break; + + case MENU_LEFT : // Left button + { + cUiListLeft(VarsUi.Slots,&VarsUi.SlotCenter); + Action = MENU_DRAW; + IOMapUi.State = TEST_BUTTONS; + } + break; + + case MENU_RIGHT : // Right button + { + cUiListRight(VarsUi.Slots,&VarsUi.SlotCenter); + Action = MENU_DRAW; + IOMapUi.State = TEST_BUTTONS; + } + break; + + case MENU_CONNECT : // Insert device + { + switch (VarsUi.State) + { + case 0 : // Check selected device + { + VarsUi.SelectedSlot = (UBYTE)VarsUi.SlotCenter; + if (VarsUi.SelectedDevice) + { + VarsUi.State++; + } + else + { + Action = MENU_EXIT; + } + } + break; + + case 1 : // Display wait text + { + if (!cUiFeedback((BMPMAP*)Wait,TXT_FB_BT_CONNECTING_WAIT,0,0)) + { + if (cUiBTGetDeviceIndex(VarsUi.DevicesKnown,VarsUi.SelectedDevice - 1,&VarsUi.BTIndex)) + { + VarsUi.BTCommand = (UBYTE)CONNECT; + VarsUi.BTPar1 = (UBYTE)VarsUi.BTIndex; + VarsUi.BTPar2 = (UBYTE)VarsUi.SelectedSlot; + if (pMapComm->pFunc(VarsUi.BTCommand,VarsUi.BTPar1,VarsUi.BTPar2,0,NULL,&(VarsUi.BTResult)) == SUCCESS) + { + VarsUi.State++; + } + else + { + VarsUi.State = 99; + } + } + else + { + VarsUi.State = 99; + } + } + } + break; + + case 2 : // Wait for result + { + if (VarsUi.BTResult != INPROGRESS) + { + if (VarsUi.BTResult == SUCCESS) + { + Action = MENU_EXIT; + } + else + { + if (VarsUi.BTResult == REQPIN) + { + sprintf((char*)pMapSound->SoundFilename,"%s.%s",(char*)UI_ATTENTION_SOUND,(char*)TXT_FILE_EXT[FILETYPE_SOUND]); + pMapSound->Volume = IOMapUi.Volume; + pMapSound->Mode = SOUND_ONCE; + pMapSound->Flags |= SOUND_UPDATE; + strcpy((char*)VarsUi.UserString,(char*)DEFAULT_PIN_CODE); + VarsUi.State++; + } + else + { + VarsUi.State = 6; + } + } + } + } + break; + + case 3 : // Get pincode and send + { + if (!cUiGetUserString(0)) + { + if (VarsUi.UserString[0] == 0) + { + sprintf((char*)VarsUi.UserString,"%08lX",VarsUi.CRPasskey); + Action = MENU_EXIT; + } + else + { + VarsUi.State++; + } + pMapComm->pFunc2(VarsUi.UserString); + } + } + break; + + case 4 : // Display wait text + { + if (!cUiFeedback((BMPMAP*)Wait,TXT_FB_BT_CONNECTING_WAIT,0,0)) + { + VarsUi.State++; + } + } + break; + + case 5 : // Wait for result + { + if (VarsUi.BTResult != INPROGRESS) + { + if (VarsUi.BTResult == SUCCESS) + { + Action = MENU_EXIT; + } + else + { + VarsUi.State = 6; + } + } + } + break; + + case 6 : // Display busy text + { + if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_BT_CONNECT_BUSY_FAIL,0,DISPLAY_SHOW_ERROR_TIME)) + { + Action = MENU_EXIT; + } + } + break; + + default : // Display fail text + { + if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_BT_CONNECTING_FAIL,0,DISPLAY_SHOW_ERROR_TIME)) + { + Action = MENU_EXIT; + } + } + break; + + } + } + break; + + case MENU_SEND : + { + switch (VarsUi.State) + { + case 0 : // Check connection + { + VarsUi.SelectedSlot = (UBYTE)VarsUi.SlotCenter; + if (VarsUi.SelectedFilename[0] && (cUiBTCommand(UI_BT_GET_CONNECTION_NAME,NULL,&VarsUi.SelectedSlot,NULL) == UI_BT_SUCCES)) + { + VarsUi.State += 2; + } + else + { + VarsUi.State++; + } + } + break; + + case 1 : // Display fail text + { + if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_BT_SENDING_NO_CONN_FAIL,0,DISPLAY_SHOW_ERROR_TIME)) + { + Action = MENU_EXIT; + } + } + break; + + case 2 : // Display wait text and send file + { + if (!cUiFeedback((BMPMAP*)Wait,TXT_FB_BT_SENDING_WAIT,0,0)) + { + VarsUi.BTCommand = (UBYTE)SENDFILE; + VarsUi.BTPar1 = (UBYTE)VarsUi.SelectedSlot; + VarsUi.BTPar2 = (UBYTE)0; + if (pMapComm->pFunc(VarsUi.BTCommand,VarsUi.BTPar1,VarsUi.BTPar2,0,VarsUi.SelectedFilename,&(VarsUi.BTResult)) == SUCCESS) + { + VarsUi.Timer = 0; + VarsUi.State++; + } + else + { + VarsUi.State = 4; + } + } + } + break; + + case 3 : // Wait for result + { + if (VarsUi.BTResult != INPROGRESS) + { + if (VarsUi.BTResult == SUCCESS) + { + VarsUi.State += 2; + } + else + { + VarsUi.State++; + } + } + VarsUi.Timer++; + } + break; + + case 4 : // Display fail text + { + if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_BT_SENDING_FAIL,0,DISPLAY_SHOW_ERROR_TIME)) + { + Action = MENU_EXIT; + } + } + break; + + case 5 : // Wait min. "DISPLAY_SHOW_TIME" to show "TXT_FB_BT_SENDING_WAIT" + { + if (++VarsUi.Timer >= DISPLAY_SHOW_TIME) + { + Action = MENU_EXIT; + } + } + break; + + } + } + break; + + } + if (Action == MENU_DRAW) // Update display + { + cUiListCalc(VarsUi.Slots,&VarsUi.SlotCenter,&VarsUi.SlotLeft,&VarsUi.SlotRight); + + pMapDisplay->pBitmaps[BITMAP_2] = (BMPMAP*)VarsUi.PortBitmapLeft; + pMapDisplay->pBitmaps[BITMAP_3] = (BMPMAP*)VarsUi.PortBitmapCenter; + pMapDisplay->pBitmaps[BITMAP_4] = (BMPMAP*)VarsUi.PortBitmapRight; + + VarsUi.Tmp = VarsUi.SlotLeft; + if (cUiBTCommand(UI_BT_GET_CONNECTION_VALID,NULL,&VarsUi.Tmp,NULL) == UI_BT_SUCCES) + { + cUiBTCommand(UI_BT_GET_CONNECTION_TYPE,NULL,&VarsUi.Tmp,&VarsUi.DeviceType); + pMapDisplay->pMenuIcons[MENUICON_LEFT] = (UBYTE*)&Devices->Data[VarsUi.DeviceType * Devices->ItemPixelsX * (Devices->ItemPixelsY / 8)]; + cUiDrawPortNo(VarsUi.PortBitmapLeft,MENUICON_LEFT,VarsUi.Tmp); + pMapDisplay->UpdateMask |= BITMAP_BIT(BITMAP_2); + } + else + { + pMapDisplay->pMenuIcons[MENUICON_LEFT] = (UBYTE*)&Connections->Data[VarsUi.Tmp * Connections->ItemPixelsX * (Connections->ItemPixelsY / 8)]; + } + + VarsUi.Tmp = VarsUi.SlotCenter; + cUiBTCommand(UI_BT_GET_CONNECTION_NAME,NULL,&VarsUi.Tmp,VarsUi.DisplayBuffer); + pMapDisplay->EraseMask |= TEXTLINE_BIT(TEXTLINE_5); + pMapDisplay->pMenuText = VarsUi.DisplayBuffer; + + if (cUiBTCommand(UI_BT_GET_CONNECTION_VALID,NULL,&VarsUi.Tmp,NULL) == UI_BT_SUCCES) + { + cUiBTCommand(UI_BT_GET_CONNECTION_TYPE,NULL,&VarsUi.Tmp,&VarsUi.DeviceType); + pMapDisplay->pMenuIcons[MENUICON_CENTER] = (UBYTE*)&Devices->Data[VarsUi.DeviceType * Devices->ItemPixelsX * (Devices->ItemPixelsY / 8)]; + cUiDrawPortNo(VarsUi.PortBitmapCenter,MENUICON_CENTER,VarsUi.Tmp); + pMapDisplay->UpdateMask |= BITMAP_BIT(BITMAP_3); + } + else + { + pMapDisplay->pMenuIcons[MENUICON_CENTER] = (UBYTE*)&Connections->Data[VarsUi.Tmp * Connections->ItemPixelsX * (Connections->ItemPixelsY / 8)]; + } + VarsUi.Tmp = VarsUi.SlotRight; + if (cUiBTCommand(UI_BT_GET_CONNECTION_VALID,NULL,&VarsUi.Tmp,NULL) == UI_BT_SUCCES) + { + cUiBTCommand(UI_BT_GET_CONNECTION_TYPE,NULL,&VarsUi.Tmp,&VarsUi.DeviceType); + pMapDisplay->pMenuIcons[MENUICON_RIGHT] = (UBYTE*)&Devices->Data[VarsUi.DeviceType * Devices->ItemPixelsX * (Devices->ItemPixelsY / 8)]; + cUiDrawPortNo(VarsUi.PortBitmapRight,MENUICON_RIGHT,VarsUi.Tmp); + pMapDisplay->UpdateMask |= BITMAP_BIT(BITMAP_4); + } + else + { + pMapDisplay->pMenuIcons[MENUICON_RIGHT] = (UBYTE*)&Connections->Data[VarsUi.Tmp * Connections->ItemPixelsX * (Connections->ItemPixelsY / 8)]; + } + pMapDisplay->EraseMask &= ~SCREEN_BIT(SCREEN_LARGE); + pMapDisplay->EraseMask |= MENUICON_BITS; + pMapDisplay->UpdateMask |= (MENUICON_BITS | SPECIAL_BIT(FRAME_SELECT) | SPECIAL_BIT(MENUTEXT)); + } + if (Action == MENU_EXIT) + { + IOMapUi.State = EXIT_PRESSED; + VarsUi.State = 0; + } + + return (VarsUi.State); +} + + + +//******* cUiPowerOffTime **************************************************** + +UBYTE cUiPowerOffTime(UBYTE Action) // MENU_INIT,MENU_LEFT,MENU_RIGHT,MENU_EXIT +{ + switch (Action) + { + case MENU_INIT : // Init time counter and cursor bitmap + { + VarsUi.Counter = VarsUi.NVData.PowerdownCode + 1; + + VarsUi.pTmp = (UBYTE*)Cursor; + for (VarsUi.Tmp = 0;(VarsUi.Tmp < SIZE_OF_CURSOR) && (VarsUi.Tmp < (UBYTE)SIZEOF_DATA(Cursor));VarsUi.Tmp++) + { + VarsUi.CursorTmp[VarsUi.Tmp] = *VarsUi.pTmp; + VarsUi.pTmp++; + } + Action = MENU_DRAW; + } + break; + + case MENU_LEFT : // Dec + { + cUiListLeft(POWER_OFF_TIME_STEPS,&VarsUi.Counter); + Action = MENU_DRAW; + } + break; + + case MENU_RIGHT : // Inc + { + cUiListRight(POWER_OFF_TIME_STEPS,&VarsUi.Counter); + Action = MENU_DRAW; + } + break; + + case MENU_ENTER : // Enter + { + VarsUi.NVData.PowerdownCode = VarsUi.Counter - 1; + cUiNVWrite(); + IOMapUi.SleepTimeout = PowerOffTimeSteps[VarsUi.NVData.PowerdownCode]; + Action = MENU_EXIT; + } + break; + + } + + if (Action == MENU_DRAW) + { + if (VarsUi.Counter > 1) + { + sprintf((char*)VarsUi.DisplayBuffer,"%u",(UWORD)PowerOffTimeSteps[VarsUi.Counter - 1]); + } + else + { + sprintf((char*)VarsUi.DisplayBuffer,(char*)cUiGetString(TXT_POWEROFFTIME_NEVER)); + } + pMapDisplay->pTextLines[TEXTLINE_3] = VarsUi.DisplayBuffer; + + pMapDisplay->pBitmaps[BITMAP_1] = (BMPMAP*)VarsUi.CursorTmp; + VarsUi.CursorTmp[4] = 46; + VarsUi.CursorTmp[5] = 24; + pMapDisplay->EraseMask |= (TEXTLINE_BIT(TEXTLINE_3) | TEXTLINE_BIT(TEXTLINE_4)); + pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_3); + pMapDisplay->UpdateMask |= (TEXTLINE_BIT(TEXTLINE_3) | BITMAP_BIT(BITMAP_1)); + } + if (Action == MENU_EXIT) + { + IOMapUi.State = EXIT_PRESSED; + } + + return (0); +} + + + +//******* cUiBTConnectRequest ************************************************ + +UBYTE cUiBTConnectRequest(UBYTE Action) +{ + switch (Action) + { + case MENU_INIT : + { + switch (VarsUi.CRState) + { + case 0 : + { + sprintf((char*)pMapSound->SoundFilename,"%s.%s",(char*)UI_ATTENTION_SOUND,(char*)TXT_FILE_EXT[FILETYPE_SOUND]); + pMapSound->Volume = IOMapUi.Volume; + pMapSound->Mode = SOUND_ONCE; + pMapSound->Flags |= SOUND_UPDATE; + VarsUi.CRState++; + } + break; + + case 1 : + { + if (DISPLAY_IDLE) + { + pMapDisplay->Flags |= DISPLAY_POPUP; + VarsUi.CRState++; + } + } + break; + + case 2 : + { + strcpy((char*)VarsUi.UserString,(char*)DEFAULT_PIN_CODE); + IOMapUi.Flags |= UI_REDRAW_STATUS; + VarsUi.CRState++; + } + break; + + case 3 : // Get pincode and send + { + if (!cUiGetUserString(0)) + { + if (VarsUi.UserString[0] == 0) + { + sprintf((char*)VarsUi.UserString,"%08lX",VarsUi.CRPasskey); + } + pMapComm->pFunc2(VarsUi.UserString); + VarsUi.CRState++; + } + } + break; + + case 4 : + { + if (DISPLAY_IDLE) + { + pMapDisplay->Flags &= ~DISPLAY_POPUP; + VarsUi.CRState = 0; + } + } + break; + + } + } + break; + + } + + return (VarsUi.CRState); +} + + + +//******* cUiFilesDelete ***************************************************** + +UBYTE cUiFilesDelete(UBYTE Action) +{ + switch (Action) + { + case MENU_INIT : + { + pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_FILESDELETE_DELETING_ALL); + pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_3); + pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3); + sprintf((char*)VarsUi.DisplayBuffer,(char*)cUiGetString(TXT_FILESDELETE_S_FILES),(char*)cUiGetString(TXT_FILETYPE[VarsUi.SelectedType])); + pMapDisplay->pTextLines[TEXTLINE_4] = VarsUi.DisplayBuffer; + pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_4); + pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_4); + IOMapUi.State = TEST_BUTTONS; + } + break; + + case MENU_DELETE : + { + switch (VarsUi.State) + { + case 0 : + { + if (VarsUi.SelectedType < FILETYPES) + { + sprintf((char*)VarsUi.FilenameBuffer,"*.%s",TXT_FILE_EXT[VarsUi.SelectedType]); + } + else + { + sprintf((char*)VarsUi.FilenameBuffer,"*.*"); + } + VarsUi.State++; + } + break; + + case 1 : + { + if (SOUND_IDLE == pMapSound->State) + { + VarsUi.State++; + } + } + break; + + case 2 : // Delete files + { + VarsUi.TmpHandle = pMapLoader->pFunc(FINDFIRST,VarsUi.FilenameBuffer,VarsUi.SelectedFilename,&VarsUi.TmpLength); + if (!(VarsUi.TmpHandle & 0x8000)) + { + pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.TmpHandle,NULL,NULL); + pMapLoader->pFunc(DELETE,VarsUi.SelectedFilename,NULL,NULL); + } + else + { + pMapDisplay->EraseMask |= MENUICON_BITS; + pMapDisplay->EraseMask |= SPECIAL_BIT(MENUTEXT); + VarsUi.State++; + } + } + break; + + default : // Display Files deleted text + { + if (!cUiFeedback((BMPMAP*)Info,TXT_FB_FD_FILES_INFO,TXT_FB_FD_DELETED_INFO,DISPLAY_SHOW_TIME)) + { + IOMapUi.State = EXIT_PRESSED; + VarsUi.State = 0; + } + } + break; + + } + } + break; + + default : + { + if (Action < FILETYPES) + { + VarsUi.SelectedType = Action; + } + else + { + VarsUi.SelectedType = FILETYPE_ALL; + } + } + break; + + } + + return (VarsUi.State); +} + + +//******* cUiOff ************************************************************* + +UBYTE cUiOff(UBYTE Action) // Tell AVR to turn off ARM +{ + if (Action == MENU_INIT) + { + switch (VarsUi.State) + { + case 0 : // Stop VM if running + { + if (pMapCmd->ProgStatus == PROG_RUNNING) + { + pMapCmd->DeactivateFlag = TRUE; + } + VarsUi.State++; + } + break; + + case 1 : // When VM is stopped -> Display off and close all connections + { + if (pMapCmd->ProgStatus != PROG_RUNNING) + { + pMapDisplay->Flags &= ~DISPLAY_ON; + VarsUi.BTCommand = (UBYTE)DISCONNECTALL; + VarsUi.BTPar1 = (UBYTE)0; + VarsUi.BTPar2 = (UBYTE)0; + pMapComm->pFunc(VarsUi.BTCommand,VarsUi.BTPar1,VarsUi.BTPar2,0,NULL,&(VarsUi.BTResult)); + VarsUi.State++; + } + } + break; + + case 2 : // Send off command to AVR + { + if (VarsUi.BTResult != INPROGRESS) + { + pMapIoCtrl->PowerOn = POWERDOWN; + VarsUi.Timer = 0; + VarsUi.State++; + } + } + break; + + case 3 : // Wait for power off + { + if (++VarsUi.Timer >= ARM_WAIT_FOR_POWER_OFF) + { + VarsUi.State++; + } + } + break; + + case 4 : // Vitual off state (if still power) wait for on button + { + pMapIoCtrl->PowerOn = 0; + if (BUTTON_ENTER == cUiReadButtons()) + { + VarsUi.State++; + } + } + break; + + default : // Turn on again + { + IOMapUi.State = INIT_DISPLAY; + VarsUi.State = 0; + } + break; + + } + } + + return (VarsUi.State); +} + + + +//******* FUNCTIONS ********************************************************** + +enum FUNC_NO // Must reffer to entry in Functions +{ // used in Menus to repressent function + FUNC_NO_NOT_USED = 0x00, + FUNC_NO_TEST_PROGRAM = 0x01, + FUNC_NO_OFF = 0x02, + FUNC_NO_BT_ON = 0x03, + FUNC_NO_POWER_OFF_TIME = 0x04, + FUNC_NO_FILES_DELETE = 0x05, + FUNC_NO_FILE_LIST = 0x06, + FUNC_NO_VOLUME = 0x07, + FUNC_NO_FILE_RUN = 0x08, + FUNC_NO_FILE_DELETE = 0x09, + FUNC_NO_FREE1 = 0x0A, + FUNC_NO_ON_BRICK_PROGRAMMING = 0x0B, + FUNC_NO_FREE2 = 0x0C, + FUNC_NO_BT_CONNECT_REQUEST = 0x0D, + FUNC_NO_VIEW = 0x0E, + FUNC_NO_GET_USER_STRING = 0x0F, + FUNC_NO_BT_CONNECT = 0x10, + FUNC_NO_BT_VISIABILITY = 0x11, + FUNC_NO_BT_SEARCH = 0x12, + FUNC_NO_BT_DEVICE_LIST = 0x13, + FUNC_NO_BT_CONNECT_LIST = 0x14, + FUNC_NO_MAX +}; + +FUNCTION Functions[] = // Use same index as FUNC_NO +{ + 0, + TestPrg, + cUiOff, + cUiBtOn, + cUiPowerOffTime, + cUiFilesDelete, + cUiFileList, + cUiVolume, + cUiFileRun, + cUiFileDelete, + cUiDataLogging, + cUiOnBrickProgramming, + 0, + cUiBTConnectRequest, + cUiView, + cUiGetUserString, + cUiBtConnect, + cUiBtVisiability, + cUiBtSearch, + cUiBtDeviceList, + cUiBtConnectList +}; + + diff --git a/src/Icons.txt b/src/Icons.txt new file mode 100644 index 0000000..459b078 --- /dev/null +++ b/src/Icons.txt @@ -0,0 +1,293 @@ +DEFINE_DATA(ICON, Icons) = +{ + 0x04,0x00, // Graphics Format + 0x1A,0x70, // Graphics DataSize + 0x01, // Graphics Count X + 0x5E, // Graphics Count Y + 0x18, // Graphics Width + 0x18, // Graphics Height +BEGIN_DATA + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xA0,0x50,0xB0,0x50,0xB0,0x50,0xA0,0xC0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x20,0x10,0x88,0x47,0x2F,0x1F,0x1E,0x1F,0x1E,0x1D,0x0E,0x07,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x06,0x09,0x08,0x04,0x02,0x01,0x08,0x14,0x1F,0x00,0x1F,0x15,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xA0,0x50,0xB0,0x50,0xB0,0x50,0xA0,0xC0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x20,0x10,0x88,0x47,0x2F,0x1F,0x1E,0x1F,0x1E,0x1D,0x0E,0x07,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x06,0x09,0x08,0x04,0x02,0x01,0x08,0x14,0x1F,0x00,0x1F,0x15,0x0A,0x00,0x1E,0x09,0x1E,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x40,0x40,0x20,0x20,0x20,0x40,0x40,0x98,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x02,0x42,0x20,0x07,0x18,0x60,0x80,0x00,0x00,0x00,0x80,0x60,0x18,0x07,0x00,0x10,0x22,0x02,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x15,0x35,0x25,0x35,0x15,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0xC0,0x60,0xA0,0x60,0xC0,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x1A,0x75,0xAA,0x55,0xAA,0x55,0xAA,0x75,0x1A,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x15,0x35,0x25,0x35,0x15,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xFE,0x02,0xC3,0xC2,0xC2,0x02,0xC3,0x42,0xC2,0x03,0x02,0x02,0x02,0x03,0x02,0xFE,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x1F,0x1C,0x1D,0x1D,0x1D,0x1C,0x1D,0x1D,0x1D,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1F,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00, + 0x00,0x00,0x08,0x04,0x04,0x02,0x09,0x09,0x4C,0x4E,0xCB,0xC8,0xC8,0xC8,0xC8,0x70,0x00,0x00,0xF8,0x04,0xFF,0x00,0x00,0x00, + 0x00,0x00,0x18,0x18,0x30,0x30,0x30,0x34,0x35,0x1D,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x0F,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x80,0xC0,0x80,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x10,0xBA,0xC6,0x01,0x11,0x38,0x6C,0x38,0x11,0x01,0xC6,0xBA,0x10,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x01,0x02,0x06,0x02,0x01,0x03,0x00,0x00,0x1E,0x12,0x0C,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x80,0xC0,0x80,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x10,0xBA,0xC6,0x01,0x11,0x38,0x6C,0x38,0x11,0x01,0xC6,0xBA,0x10,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x01,0x02,0x06,0x02,0x01,0x03,0x00,0x00,0x1E,0x0A,0x14,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xF8,0x06,0x01,0x01,0x00,0x03,0x01,0x00,0x00,0x01,0x01,0x06,0xF8,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x04,0x04,0x08,0x08,0x08,0x08,0x08,0x04,0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x20,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xE0,0x3C,0xC3,0x00,0x00,0x00,0xFF,0x10,0x10,0x82,0x6C,0x10,0x01,0xC6,0x38,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x01,0x02,0x04,0x07,0x00,0x00,0x1C,0x00,0x1C,0x05,0x08,0x1C,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x20,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xE0,0x3C,0xC3,0x00,0x00,0x00,0xFF,0x10,0x10,0x82,0x6C,0x10,0x01,0xC6,0x38,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x01,0x02,0x04,0x07,0x00,0x1C,0x14,0x00,0x1C,0x05,0x08,0x04,0x1C,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x30,0x48,0x48,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xC0,0x40,0x40,0x40,0x4F,0xD0,0x50,0x50,0x49,0x40,0xFC,0x04,0x07,0x05,0x05,0x05,0x07,0x04,0x04,0x07,0x00,0x00, + 0x00,0x00,0x07,0x06,0x06,0x06,0x06,0x07,0x04,0x04,0x04,0x04,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x30,0x48,0x48,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xC0,0x40,0x40,0x40,0x5F,0xC4,0x44,0x40,0x40,0x40,0xFC,0x04,0x07,0x05,0x05,0x05,0x07,0x04,0x04,0x07,0x00,0x00, + 0x00,0x00,0x07,0x06,0x06,0x06,0x06,0x07,0x04,0x04,0x04,0x04,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x08,0xF0,0x00,0x00,0x00,0x00,0x60,0x90,0x90,0x60,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x7F,0x04,0x7F,0x80,0x00,0x00,0x00,0xC0,0x20,0x20,0x40,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x08,0x10,0x10,0x10,0x08,0x07,0x00,0x00,0x03,0x04,0x04,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x08,0xF0,0x00,0x00,0x00,0x00,0x60,0x90,0x90,0x60,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x7F,0x04,0x7F,0x80,0x00,0x00,0x00,0xE0,0x20,0x20,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x08,0x10,0x10,0x10,0x08,0x07,0x00,0x00,0x07,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x40,0xA0,0x60,0xA0,0x40,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xC0,0x30,0x18,0x0F,0x0A,0x0D,0x1A,0x35,0xEA,0xF5,0xFA,0xFF,0xF8,0xF8,0xF0,0xE0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x06,0x04,0x08,0x08,0x08,0x04,0x06,0x01,0x03,0x07,0x07,0x07,0x07,0x03,0x01,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x48,0x48,0x78,0x48,0x48,0x78,0x48,0x48,0x78,0x48,0x48,0xF8,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x9E,0x91,0x51,0x51,0x51,0x91,0x9E,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3C,0x3C,0x3C,0x24,0x25,0x3D,0x25,0x24,0x3C,0x24,0x24,0x3F,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x48,0x48,0x78,0x48,0x48,0x78,0x48,0x48,0x78,0x48,0x48,0xF8,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x9E,0x91,0x51,0x51,0x51,0x91,0x9E,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x24,0x24,0x3C,0x3C,0x3D,0x3D,0x25,0x24,0x3C,0x24,0x24,0x3F,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x48,0x48,0x78,0x48,0x48,0x78,0x48,0x48,0x78,0x48,0x48,0xF8,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x9E,0x91,0x51,0x51,0x51,0x91,0x9E,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x24,0x24,0x3C,0x24,0x25,0x3D,0x3D,0x3C,0x3C,0x24,0x24,0x3F,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x48,0x48,0x78,0x48,0x48,0x78,0x48,0x48,0x78,0x48,0x48,0xF8,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x9E,0x91,0x51,0x51,0x51,0x91,0x9E,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x24,0x24,0x3C,0x24,0x25,0x3D,0x25,0x24,0x3C,0x3C,0x3C,0x3F,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x78,0x78,0x78,0x48,0x48,0x78,0x48,0x48,0x78,0x48,0x48,0xF8,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x9E,0x91,0x51,0x51,0x51,0x91,0x9E,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x24,0x24,0x3C,0x24,0x25,0x3D,0x25,0x24,0x3C,0x24,0x24,0x3F,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x48,0x48,0x78,0x78,0x78,0x78,0x48,0x48,0x78,0x48,0x48,0xF8,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x9E,0x91,0x51,0x51,0x51,0x91,0x9E,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x24,0x24,0x3C,0x24,0x25,0x3D,0x25,0x24,0x3C,0x24,0x24,0x3F,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x48,0x48,0x78,0x48,0x48,0x78,0x78,0x78,0x78,0x48,0x48,0xF8,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x9E,0x91,0x51,0x51,0x51,0x91,0x9E,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x24,0x24,0x3C,0x24,0x25,0x3D,0x25,0x24,0x3C,0x24,0x24,0x3F,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xF0,0x10,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xF0,0x10,0xF0,0x00,0x00,0x00, + 0x00,0x00,0x00,0xFF,0x00,0x1F,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x1F,0x00,0xFF,0x00,0x00,0x00, + 0x00,0x00,0x00,0x07,0x08,0x10,0x10,0x10,0x10,0x1F,0x11,0x1D,0x1D,0x11,0x11,0x11,0x1F,0x10,0x10,0x10,0x0F,0x00,0x00,0x00, + 0x00,0x00,0x00,0xF0,0x10,0xF0,0x10,0x10,0x10,0x10,0x90,0x90,0x50,0x50,0xD0,0x10,0x10,0x10,0xF0,0x10,0xF0,0x00,0x00,0x00, + 0x00,0x00,0x00,0xFF,0x00,0x1F,0x20,0x20,0x20,0x2C,0x2F,0x20,0x20,0x26,0x27,0x20,0x20,0x20,0x1F,0x00,0xFF,0x00,0x00,0x00, + 0x00,0x00,0x00,0x07,0x08,0x10,0x10,0x10,0x10,0x1F,0x11,0x1D,0x1D,0x11,0x11,0x11,0x1F,0x10,0x10,0x10,0x0F,0x00,0x00,0x00, + 0x00,0x00,0x00,0xF0,0x10,0xF0,0x10,0x10,0x10,0xD0,0x50,0x50,0x50,0x50,0xD0,0x10,0x10,0x10,0xF0,0x10,0xF0,0x00,0x00,0x00, + 0x00,0x00,0x00,0xFF,0x00,0x1F,0x20,0x20,0x20,0x2F,0x28,0x23,0x23,0x28,0x2F,0x20,0x20,0x20,0x1F,0x00,0xFF,0x00,0x00,0x00, + 0x00,0x00,0x00,0x07,0x08,0x10,0x10,0x10,0x10,0x1F,0x11,0x1D,0x1D,0x11,0x11,0x11,0x1F,0x10,0x10,0x10,0x0F,0x00,0x00,0x00, + 0x00,0x00,0x00,0xF0,0x10,0xF0,0x10,0xD0,0x50,0xD0,0x90,0x50,0x50,0x90,0xD0,0x50,0xD0,0x10,0xF0,0x10,0xF0,0x00,0x00,0x00, + 0x00,0x00,0x00,0xFF,0x00,0x3F,0x40,0x41,0x41,0x41,0x40,0x41,0x41,0x40,0x41,0x41,0x41,0x40,0x3F,0x00,0xFF,0x00,0x00,0x00, + 0x00,0x00,0x00,0x07,0x08,0x10,0x10,0x10,0x10,0x1F,0x11,0x1D,0x1D,0x11,0x11,0x11,0x1F,0x10,0x10,0x10,0x0F,0x00,0x00,0x00, + 0x00,0x00,0x00,0xF0,0x10,0xF0,0x10,0x10,0x10,0x90,0x50,0x70,0x50,0x70,0x50,0x90,0x10,0x10,0xF0,0x10,0xF0,0x00,0x00,0x00, + 0x00,0x00,0x00,0xFF,0x00,0x1F,0x20,0x20,0x20,0x2F,0x30,0x25,0x28,0x25,0x30,0x2F,0x20,0x20,0x1F,0x00,0xFF,0x00,0x00,0x00, + 0x00,0x00,0x00,0x07,0x08,0x10,0x10,0x10,0x10,0x1F,0x11,0x1D,0x1D,0x11,0x11,0x11,0x1F,0x10,0x10,0x10,0x0F,0x00,0x00,0x00, + 0x00,0x00,0x00,0xF0,0x10,0xF0,0x90,0xD0,0x90,0x10,0x10,0x10,0x10,0x10,0x50,0x10,0x10,0x10,0xF0,0x10,0xF0,0x00,0x00,0x00, + 0x00,0x00,0x00,0xFF,0x00,0x3F,0x40,0x5F,0x50,0x54,0x50,0x52,0x50,0x51,0x50,0x78,0x50,0x40,0x3F,0x00,0xFF,0x00,0x00,0x00, + 0x00,0x00,0x00,0x07,0x08,0x10,0x10,0x10,0x10,0x1F,0x11,0x1D,0x1D,0x11,0x11,0x11,0x1F,0x10,0x10,0x10,0x0F,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x06,0xFD,0x00,0x00,0x00,0x00,0xFD,0x06,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x10,0x10,0x10,0x10,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x40,0x80,0x00,0x00,0x00,0x58,0x68,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x06,0xFD,0x00,0x00,0x00,0x00,0xFD,0x06,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x10,0x10,0x10,0x10,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x20,0x20,0x20,0x20,0xE0,0x00,0x68,0x58,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x60,0x90,0x08,0x04,0x0E,0x08,0x08,0x0F,0x00,0x00,0x00,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x07,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0xE0,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x06,0x09,0x10,0x20,0x70,0x10,0x10,0xF0,0x00,0x00,0x00,0x01,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x04,0x04,0x04,0x04,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0xE0,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x68,0x58,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x06,0x09,0x10,0x20,0x70,0x10,0x10,0xF0,0x00,0x00,0x00,0x01,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x04,0x04,0x04,0x04,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x20,0x20,0x20,0x20,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x00,0x00,0x00,0x0F,0x08,0x08,0x0E,0x04,0x08,0x90,0x60,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x07,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0xE0,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x01,0x00,0x00,0x00,0xF0,0x10,0x10,0x70,0x20,0x10,0x09,0x06,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x04,0x04,0x04,0x04,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x68,0x58,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0xE0,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x01,0x00,0x00,0x00,0xF0,0x10,0x10,0x70,0x20,0x10,0x09,0x06,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x04,0x04,0x04,0x04,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x20,0x20,0x20,0x20,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x60,0x90,0x08,0x04,0x0E,0x08,0x08,0x0F,0x00,0x00,0x00,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x07,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x03,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0x40,0x40,0x00,0x00,0x00,0xC0,0x60,0x20,0x20,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x7F,0x00,0x00,0x80,0xC0,0xC0,0xC0,0xBF,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x03,0x03,0x01,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x40,0x40,0x40,0x40,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x05,0x08,0x10,0x10,0x08,0x05,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x40,0x40,0x40,0x40,0xC0,0x00,0x00,0x58,0x68,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x05,0x08,0x10,0x10,0x08,0x05,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x68,0x58,0x00,0xE0,0x20,0x20,0x20,0x20,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x00,0x00,0x00,0x0F,0x08,0x08,0x0E,0x04,0x08,0x90,0x60,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x07,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x40,0xA0,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x20,0x10,0xA0,0x40,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x82,0x44,0x28,0x11,0x82,0x44,0x82,0x11,0x28,0x44,0x82,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x04,0x0A,0x11,0x08,0x04,0x02,0x01,0x00,0x00,0x00,0x01,0x02,0x04,0x08,0x11,0x0A,0x04,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x10,0x90,0x60,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xC0,0x20,0x20,0x40,0x40,0x80,0x80,0x80,0x60,0x18,0x86,0x61,0x18,0x06,0x01,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x03,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x18,0x06,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xE0,0xF0,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x38,0xF0,0xE0,0x00,0x00,0x00, + 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, + 0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00, + 0x00,0x00,0x00,0xA8,0xA8,0x54,0x54,0x2A,0x2A,0x00,0x3F,0x21,0x32,0x2C,0x24,0x24,0x24,0x2C,0x32,0x21,0x3F,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x40,0x40,0x60,0x60,0x60,0x40,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x08,0x0F,0x08,0x0F,0x08,0x0F,0x08,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x01,0x01,0x02,0x02,0x04,0x04,0x88,0x88,0x50,0x50,0x20,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x08,0x04,0x04,0x02,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x20,0x50,0x50,0x88,0x88,0x04,0x04,0x02,0x02,0x01,0x01,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x04,0x04,0x08,0x0F,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xFF,0x01,0x01,0x01,0x01,0x7F,0x40,0x48,0x4C,0x7A,0x01,0x00,0x00,0x01,0xFA,0x0C,0x08,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x03,0x04,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x04,0x03,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0xC0,0xC0,0xC0,0xC0,0xC0,0x80,0x80,0x60,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xF8,0xFE,0x07,0x21,0x21,0x20,0x20,0xE0,0x00,0x00,0x01,0x01,0x07,0xFE,0xF9,0x01,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x03,0x07,0x0C,0x0C,0x18,0x18,0x1B,0x18,0x18,0x0C,0x0C,0x07,0x03,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x80,0x00,0x20,0xC0,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x78,0x48,0x48,0x84,0x02,0x01,0xFF,0x00,0x00,0x86,0x78,0x01,0x86,0x78,0x01,0x86,0x78,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x07,0x00,0x00,0x01,0x00,0x06,0x01,0x10,0x0E,0x01,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0xE0,0xE0,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x78,0xFE,0x87,0x01,0x01,0x00,0x07,0x07,0x00,0x01,0x01,0x87,0xFE,0x78,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x06,0x06,0x0C,0x0C,0x0C,0x0C,0x06,0x06,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xF8,0x08,0xF8,0x48,0xC8,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x78,0x48,0xF8,0x40,0xC0,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x02,0xFE,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x03,0x02,0xFF,0x02,0xFE,0x00,0x00,0x00, + 0x00,0x00,0x00,0x01,0x07,0x08,0x3F,0x40,0x80,0x81,0xF9,0x89,0xE9,0x89,0x89,0x89,0xF9,0x81,0x80,0x80,0x7F,0x00,0x00,0x00, + 0x00,0x00,0x00,0xE0,0x20,0x20,0x20,0xE0,0x80,0x80,0xE0,0x20,0x20,0x20,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x03,0x02,0x02,0x02,0x03,0x00,0x00,0x03,0x02,0x82,0xCA,0xFB,0x78,0x78,0xF8,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x7C,0x44,0x44,0x44,0x7C,0x00,0x03,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x08,0xFC,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x06,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x1F,0x10,0x10,0x13,0x13,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x10,0x00,0x00, + 0x00,0x00,0x00,0xE0,0x30,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x30,0xE0,0x00,0x00,0x00, + 0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x80,0xC0,0xA0,0x90,0x08,0x08,0x90,0xA0,0xC0,0x80,0x00,0x00,0x00,0xFF,0x00,0x00,0x00, + 0x00,0x00,0x00,0x01,0x03,0x02,0x02,0x02,0x02,0x02,0x1F,0x10,0x10,0x1F,0x02,0x02,0x02,0x02,0x02,0x03,0x01,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xFE,0xFF,0xFF,0xE3,0xE1,0xE0,0xF0,0x78,0x38,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x1C,0x1E,0x1F,0x0F,0x07,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0xE0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xFE,0x01,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x01,0xFE,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x0F,0x10,0x20,0x20,0x20,0x22,0x24,0x24,0x24,0x24,0x22,0x20,0x20,0x20,0x10,0x0F,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xF8,0x06,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0xF8,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x03,0x04,0x08,0x08,0x10,0x10,0x10,0x10,0x10,0x08,0x08,0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x20,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xE0,0x3C,0xC3,0x00,0x00,0x00,0xFF,0x10,0x10,0x82,0x6C,0x10,0x01,0xC6,0x38,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x01,0x02,0x04,0x07,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xA0,0x50,0xB0,0x50,0xB0,0x50,0xA0,0xC0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x20,0x10,0x88,0x47,0x2F,0x1F,0x1F,0x1F,0x1E,0x1F,0x0E,0x07,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x06,0x09,0x08,0x04,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00, + 0x00,0x00,0x08,0x04,0x04,0x02,0x09,0x09,0x4C,0x4E,0xCB,0xC8,0xC8,0xC8,0xC8,0x70,0x00,0x00,0xF8,0x04,0xFF,0x00,0x00,0x00, + 0x00,0x00,0x18,0x18,0x30,0x30,0x30,0x34,0x35,0x1D,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x0F,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x38,0xC8,0x08,0x08,0x08,0x08,0xA8,0x68,0x08,0x08,0x08,0x08,0xC8,0x38,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x42,0x24,0x98,0x85,0x85,0x98,0x24,0x42,0x81,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x1C,0x13,0x14,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x14,0x13,0x1C,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x38,0xC8,0x08,0x08,0x08,0x08,0x68,0xA8,0x08,0x08,0x08,0x08,0xC8,0x38,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x42,0x24,0x18,0x05,0x05,0x18,0x24,0x42,0x81,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x1C,0x13,0x14,0x16,0x17,0x17,0x17,0x17,0x17,0x17,0x16,0x14,0x13,0x1C,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x38,0xC8,0x08,0x08,0x48,0xE8,0x08,0xC8,0x28,0xC8,0x08,0x08,0xC8,0x38,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x42,0x24,0x19,0x04,0x04,0x19,0x24,0x42,0x81,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x1C,0x13,0x18,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x18,0x13,0x1C,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xF8,0x06,0xF9,0x56,0xAA,0x55,0xAB,0x55,0xAB,0x55,0xAA,0x56,0xF9,0x06,0xF8,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x03,0x04,0x0B,0x0A,0x15,0x16,0x15,0x16,0x15,0x0A,0x0B,0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xFF,0x00,0x5C,0x74,0x00,0x04,0x7C,0x04,0x00,0x38,0x44,0x38,0x00,0x7C,0x14,0x08,0x00,0xFF,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x08,0x04,0x02,0x01,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x40,0x40,0x60,0xFC,0xF8,0xF0,0x60,0x00,0x00,0x40,0x40,0x80,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xFC,0x03,0x00,0x00,0x00,0x00,0x00,0x03,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x81,0x7E,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x03,0x04,0x04,0x00,0x00,0x0C,0x1E,0x3F,0x7F,0x04,0x04,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x48,0x48,0x78,0x48,0x48,0x78,0x48,0x48,0x78,0x48,0x48,0xF8,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x9E,0x91,0x51,0x51,0x51,0x91,0x9E,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x24,0x24,0x24,0x3C,0x25,0x25,0x25,0x3C,0x24,0x24,0x24,0x3F,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0x60,0x30,0x10,0x10,0x90,0x10,0x10,0x30,0x60,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x82,0x44,0x28,0xFF,0x11,0xAA,0x44,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x03,0x06,0x0C,0x18,0x10,0x10,0x13,0x11,0x10,0x18,0x0C,0x06,0x03,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xE0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x40,0xC0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xE0,0x00,0x00,0x00, + 0x00,0x00,0x00,0xFF,0x00,0x55,0x00,0x55,0x55,0x55,0x00,0x55,0xFF,0x00,0x01,0x00,0x01,0x01,0x01,0x00,0xFF,0x00,0x00,0x00, + 0x00,0x00,0x00,0x0F,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x12,0x15,0x17,0x12,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0F,0x00,0x00,0x00, + 0x00,0x00,0x80,0x80,0x80,0x80,0x40,0x40,0x40,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x04,0x04,0x02,0x42,0xC6,0x88,0x10,0x60,0xC0,0x01,0x81,0x81,0x81,0x00,0x00, + 0x00,0x00,0x01,0x01,0x01,0x02,0x04,0x08,0x0A,0x0C,0x09,0x0B,0x0E,0x0C,0x05,0x07,0x02,0x03,0x01,0x01,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0x60,0xE2,0xB2,0xF6,0xF6,0x76,0x2C,0x6C,0xDC,0x9C,0x38,0x30,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x04,0x05,0x05,0x05,0x04,0x02,0x02,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0xE0,0xE0,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x78,0x86,0x01,0x00,0x88,0x50,0xFD,0xA9,0x50,0x00,0x00,0x01,0x86,0x78,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x04,0x04,0x08,0x09,0x08,0x08,0x04,0x04,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xC0,0xE0,0x70,0x38,0x98,0x18,0xD8,0x98,0x18,0x38,0x70,0xE0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x1F,0x3F,0x70,0xE0,0xC8,0xC5,0xDF,0xCA,0xC5,0x60,0x70,0xFF,0xCF,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x07,0x0E,0x1C,0x18,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x82,0x44,0x28,0xFF,0x11,0xAA,0x44,0x00,0x00,0x06,0x01,0x00,0x40,0x20,0x11,0x0E,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x82,0x44,0x28,0xFF,0x11,0xAA,0x44,0x00,0x00,0x00,0x00,0x01,0x82,0x44,0x28,0x10,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x83,0xC6,0x6C,0xFF,0x39,0xBA,0x6C,0xC6,0x83,0x01,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x03,0x01,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0x60,0xE2,0xB2,0xF6,0xF6,0x76,0x2C,0x6C,0xDC,0x9C,0x38,0x30,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x04,0x05,0x05,0x05,0x04,0x02,0x02,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xC0,0xE0,0x80,0x00,0x02,0x02,0x06,0x06,0x06,0x0C,0x0C,0x9C,0xDC,0xB8,0x30,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x03,0x02,0x02,0x02,0x02,0x02,0x03,0x03,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0xE0,0xE0,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x78,0x86,0x01,0x00,0x88,0x50,0xFD,0xA9,0x50,0x00,0x00,0x01,0x86,0x78,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x04,0x04,0x08,0x09,0x08,0x08,0x04,0x04,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x80,0x40,0x20,0x10,0x20,0x40,0x80,0xE0,0xE0,0x00,0x80,0x40,0x20,0x10,0x20,0x40,0x80,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x79,0x86,0x44,0x28,0x10,0x00,0x01,0x83,0x01,0x00,0x10,0x28,0x44,0xFA,0x01,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x02,0x05,0x08,0x10,0x08,0x04,0x0A,0x09,0x08,0x09,0x06,0x04,0x08,0x10,0x08,0x05,0x02,0x00,0x00,0x00 +END_DATA +}; diff --git a/src/Info.txt b/src/Info.txt new file mode 100644 index 0000000..7e2b639 --- /dev/null +++ b/src/Info.txt @@ -0,0 +1,14 @@ +DEFINE_DATA(BMPMAP, Info) = +{ + 0x02,0x00, // Graphics Format + 0x00,0x48, // Graphics DataSize + 0x00, // Graphics Start X + 0x08, // Graphics Start Y + 0x18, // Graphics Width + 0x18, // Graphics Height +BEGIN_DATA + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x40,0xA0,0x90,0x20,0x20,0x40,0x40,0x30,0x8C,0x73,0x0C,0x03,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x02,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +END_DATA +}; diff --git a/src/LowBattery.txt b/src/LowBattery.txt new file mode 100644 index 0000000..51b8ddb --- /dev/null +++ b/src/LowBattery.txt @@ -0,0 +1,18 @@ +DEFINE_DATA(BMPMAP, LowBattery) = +{ + 0x02,0x00, // Graphics Format + 0x02,0xA0, // Graphics DataSize + 0x02, // Graphics Start X + 0x08, // Graphics Start Y + 0x60, // Graphics Width + 0x38, // Graphics Height +BEGIN_DATA + 0x02,0xF2,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0xF2,0x82,0x02, + 0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x20,0x18,0x04,0x02,0x02,0x01,0x01,0x01,0x00,0xF0,0xF8,0xFC,0xFC,0xF8,0xF0,0x00,0x01,0x01,0x01,0x02,0x02,0x04,0x18,0x20,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00, + 0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x7F,0xFF,0xFF,0x7F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00, + 0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x0E,0x10,0x60,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xF0,0xF0,0xF0,0xF0,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x10,0x0E,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00, + 0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x00,0xE0,0x10,0x10,0x10,0xE0,0x00,0xF0,0x00,0xC0,0x00,0xF0,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0xF2,0x92,0x92,0x94,0x64,0x04,0xE4,0x14,0x14,0x14,0xE4,0x02,0x12,0x12,0xF1,0x11,0x10,0x00,0x10,0x10,0xF0,0x10,0x10,0x00,0xF0,0x90,0x90,0x90,0x10,0x00,0xF0,0x90,0x90,0x90,0x60,0x00,0x70,0x80,0x00,0x80,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00, + 0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x04,0x04,0x04,0x04,0x00,0x03,0x04,0x04,0x04,0x03,0x00,0x03,0x04,0x03,0x04,0x03,0x00,0x00,0x00,0x00,0xC0,0x40,0xF0,0x17,0x14,0x14,0x14,0x13,0x10,0x17,0x11,0x11,0x11,0x17,0x10,0x10,0xD0,0xD7,0x10,0xF0,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x04,0x04,0x04,0x04,0x00,0x07,0x00,0x00,0x01,0x06,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00, + 0x00,0x3F,0x20,0x20,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x63,0x62,0x6F,0x68,0x68,0x68,0x68,0x68,0x68,0x68,0x68,0x68,0x68,0x68,0x68,0x68,0x6B,0x6B,0x68,0x6F,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x7F,0x7F,0x00 +END_DATA +}; diff --git a/src/Mainmenu.rms b/src/Mainmenu.rms new file mode 100644 index 0000000..2e014fb --- /dev/null +++ b/src/Mainmenu.rms @@ -0,0 +1,72 @@ +const UBYTE MAINMENU[] = +{ + 0x07,0x00, // Menu Format + 0x01,0x05, // Menu DataSize + 0x1D, // Menu item size + 0x09, // Menu items + 0x18, // Menu icon Width + 0x18, // Menu icon Height + + // Turn_off? + 0x00,0x00,0x00,0x01, // 0x00000001 + 0x10,0x20,0x04,0x01, // 0x10200401 + 0x02,0x00,0x00,0x01, // 2 ,0 ,0 ,1 + 0x54,0x75,0x72,0x6E,0x20,0x6F,0x66,0x66,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x31, // 31 + + // Turn_off? + 0x00,0x00,0x00,0x02, // 0x00000002 + 0x10,0x20,0x00,0x01, // 0x10200001 + 0x00,0x00,0x00,0x01, // 0 ,0 ,0 ,1 + 0x54,0x75,0x72,0x6E,0x20,0x6F,0x66,0x66,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x30, // 30 + + // My_Files + 0x00,0x00,0x00,0x11, // 0x00000011 + 0x01,0x04,0x00,0x00, // 0x01040000 + 0x00,0x00,0x01,0x01, // 0 ,0 ,1 ,1 + 0x4D,0x79,0x20,0x46,0x69,0x6C,0x65,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x3B, // 3B + + // NXT_Program + 0x00,0x00,0x00,0x21, // 0x00000021 + 0x01,0x04,0x00,0x00, // 0x01040000 + 0x00,0x00,0x02,0x01, // 0 ,0 ,2 ,1 + 0x4E,0x58,0x54,0x20,0x50,0x72,0x6F,0x67,0x72,0x61,0x6D,0x00,0x00,0x00,0x00,0x00, + 0x3C, // 3C + + // NXT_Datalog + 0x00,0x00,0x00,0x31, // 0x00000031 + 0x01,0x84,0x00,0x00, // 0x01840000 + 0x0A,0x00,0x03,0x01, // 10 ,0 ,3 ,1 + 0x4E,0x58,0x54,0x20,0x44,0x61,0x74,0x61,0x6C,0x6F,0x67,0x00,0x00,0x00,0x00,0x00, + 0x3D, // 3D + + // View + 0x00,0x00,0x00,0x41, // 0x00000041 + 0x01,0x04,0x00,0x00, // 0x01040000 + 0x0E,0x00,0x04,0x01, // 14 ,0 ,4 ,1 + 0x56,0x69,0x65,0x77,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x3E, // 3E + + // Bluetooth + 0x00,0x00,0x00,0x51, // 0x00000051 + 0x01,0x04,0x00,0x00, // 0x01040000 + 0x00,0x00,0x07,0x02, // 0 ,0 ,7 ,2 + 0x42,0x6C,0x75,0x65,0x74,0x6F,0x6F,0x74,0x68,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x51, // 51 + + // Settings + 0x00,0x00,0x00,0x61, // 0x00000061 + 0x01,0x04,0x00,0x00, // 0x01040000 + 0x00,0x00,0x05,0x01, // 0 ,0 ,5 ,1 + 0x53,0x65,0x74,0x74,0x69,0x6E,0x67,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x3F, // 3F + + // Try_Me + 0x00,0x00,0x00,0x71, // 0x00000071 + 0x01,0x04,0x00,0x00, // 0x01040000 + 0x00,0x00,0x06,0x01, // 0 ,0 ,6 ,1 + 0x54,0x72,0x79,0x20,0x4D,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x40, // 40 +}; diff --git a/src/Ok.txt b/src/Ok.txt new file mode 100644 index 0000000..32bad41 --- /dev/null +++ b/src/Ok.txt @@ -0,0 +1,13 @@ +DEFINE_DATA(BMPMAP, Ok) = +{ + 0x02,0x00, // Graphics Format + 0x00,0x20, // Graphics DataSize + 0x2A, // Graphics Start X + 0x30, // Graphics Start Y + 0x10, // Graphics Width + 0x10, // Graphics Height +BEGIN_DATA + 0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x38,0xC4,0x34,0x08,0x00,0xFF, + 0xFF,0x04,0x0A,0x19,0x12,0x22,0x24,0x24,0x23,0x18,0x07,0x00,0x00,0x00,0x00,0xFF +END_DATA +}; diff --git a/src/Port.txt b/src/Port.txt new file mode 100644 index 0000000..292fccc --- /dev/null +++ b/src/Port.txt @@ -0,0 +1,12 @@ +DEFINE_DATA(ICON, Port) = +{ + 0x04,0x00, // Graphics Format + 0x00,0x18, // Graphics DataSize + 0x08, // Graphics Count X + 0x01, // Graphics Count Y + 0x03, // Graphics Width + 0x08, // Graphics Height +BEGIN_DATA + 0x70,0x88,0x70,0x90,0xF8,0x80,0xC8,0xA8,0x90,0x88,0xA8,0x50,0x38,0x20,0xF8,0xF0,0x28,0xF0,0xF8,0xA8,0x50,0x70,0x88,0x50 +END_DATA +}; diff --git a/src/RCXintro_1.txt b/src/RCXintro_1.txt new file mode 100644 index 0000000..456a63d --- /dev/null +++ b/src/RCXintro_1.txt @@ -0,0 +1,19 @@ +DEFINE_DATA(BMPMAP, RCXintro_1) = +{ + 0x02,0x00, // Graphics Format + 0x02,0x00, // Graphics DataSize + 0x10, // Graphics Start X + 0x00, // Graphics Start Y + 0x40, // Graphics Width + 0x40, // Graphics Height +BEGIN_DATA + 0xFF,0x01,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0x01,0xFF, + 0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0xFF, + 0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x1F,0x8F,0xC7,0xE7,0x67,0x33,0x33,0x33,0x67,0xE7,0x8F,0xCF,0xE7,0x67,0x63,0x33,0x33,0x33,0x33,0x33,0x27,0x67,0xCF,0xCF,0xE7,0x67,0x63,0x33,0x33,0x33,0x33,0x33,0x63,0x67,0xC7,0x8F,0x8F,0xCF,0x67,0x67,0x23,0x33,0x33,0x33,0x33,0x63,0x67,0xC7,0x8F,0x1F,0x33,0xF3,0xFF,0x00,0xFF, + 0xFF,0x00,0xFF,0xFF,0x7F,0x0F,0x83,0xE0,0x78,0x1E,0x07,0x01,0x00,0x00,0x80,0xE0,0xF8,0x7E,0x1F,0x07,0x01,0x00,0x00,0x00,0x18,0x18,0x18,0xF8,0xF8,0x1C,0x06,0x03,0x00,0x00,0xC0,0x70,0x3C,0x3C,0x30,0x20,0x20,0xE0,0xF0,0x3D,0x0F,0x03,0x00,0x00,0xC0,0xF0,0xFC,0x3C,0x00,0x00,0x00,0x00,0xC0,0xFF,0x1E,0x00,0xC0,0xFF,0x00,0xFF, + 0xFF,0x00,0xFF,0x01,0x00,0xFC,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x0E,0x0F,0xFF,0xC7,0x00,0x00,0x00,0x00,0x00,0x0E,0x0E,0x0E,0x0E,0xFE,0xC7,0x80,0x00,0x00,0x00,0x00,0x1F,0x1F,0x0E,0x00,0x00,0x80,0xC0,0xF0,0xFF,0x83,0x00,0x00,0x00,0x1C,0x1F,0x0F,0x03,0x00,0x80,0xC0,0xE0,0x78,0x1E,0x87,0xC1,0xF0,0xFE,0xFF,0xFF,0x00,0xFF, + 0xFF,0x00,0xFF,0xFE,0xFC,0xF8,0xF3,0xF3,0xE6,0xE6,0xE6,0xE6,0xE6,0xF2,0xF3,0xF9,0xF9,0xF3,0xF6,0xE6,0xE6,0xE6,0xE6,0xE6,0xF3,0xF3,0xF9,0xF9,0xF3,0xF3,0xE6,0xE6,0xE6,0xE6,0xE6,0xE6,0xF3,0xF3,0xF9,0xFC,0xFC,0xF9,0xF3,0xF3,0xE6,0xE6,0xE6,0xE6,0xE6,0xE6,0xF3,0xF3,0xF9,0xF8,0xFC,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0xFF, + 0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0xFF, + 0xFF,0x80,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0x80,0xFF +END_DATA +}; diff --git a/src/RCXintro_10.txt b/src/RCXintro_10.txt new file mode 100644 index 0000000..5f98538 --- /dev/null +++ b/src/RCXintro_10.txt @@ -0,0 +1,13 @@ +DEFINE_DATA(BMPMAP, RCXintro_10) = +{ + 0x02,0x00, // Graphics Format + 0x00,0x20, // Graphics DataSize + 0x38, // Graphics Start X + 0x20, // Graphics Start Y + 0x0A, // Graphics Width + 0x10, // Graphics Height +BEGIN_DATA + 0xFE,0xFE,0x06,0x06,0x66,0x66,0x06,0x06,0xFE,0xFE, + 0x07,0x07,0x06,0x06,0x00,0x00,0x06,0x06,0x07,0x07 +END_DATA +}; diff --git a/src/RCXintro_11.txt b/src/RCXintro_11.txt new file mode 100644 index 0000000..6afaabd --- /dev/null +++ b/src/RCXintro_11.txt @@ -0,0 +1,13 @@ +DEFINE_DATA(BMPMAP, RCXintro_11) = +{ + 0x02,0x00, // Graphics Format + 0x00,0x10, // Graphics DataSize + 0x3A, // Graphics Start X + 0x20, // Graphics Start Y + 0x08, // Graphics Width + 0x10, // Graphics Height +BEGIN_DATA + 0xF8,0xF8,0x18,0xD8,0xD8,0x18,0xF8,0xF8, + 0x07,0x07,0x06,0x00,0x00,0x06,0x07,0x07 +END_DATA +}; diff --git a/src/RCXintro_12.txt b/src/RCXintro_12.txt new file mode 100644 index 0000000..b89f65c --- /dev/null +++ b/src/RCXintro_12.txt @@ -0,0 +1,13 @@ +DEFINE_DATA(BMPMAP, RCXintro_12) = +{ + 0x02,0x00, // Graphics Format + 0x00,0xC0, // Graphics DataSize + 0x03, // Graphics Start X + 0x20, // Graphics Start Y + 0x5E, // Graphics Width + 0x10, // Graphics Height +BEGIN_DATA + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xF8,0x18,0xD8,0xD8,0x18,0xF8,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x06,0x06,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x06,0x00,0x00,0x06,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x06,0x06,0x00,0x00,0x00,0x07,0x07 +END_DATA +}; diff --git a/src/RCXintro_13.txt b/src/RCXintro_13.txt new file mode 100644 index 0000000..ee512ea --- /dev/null +++ b/src/RCXintro_13.txt @@ -0,0 +1,13 @@ +DEFINE_DATA(BMPMAP, RCXintro_13) = +{ + 0x02,0x00, // Graphics Format + 0x00,0xC0, // Graphics DataSize + 0x03, // Graphics Start X + 0x20, // Graphics Start Y + 0x5E, // Graphics Width + 0x10, // Graphics Height +BEGIN_DATA + 0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x00,0x00,0x00,0x00,0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x00,0x00,0x00,0x00,0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0xF8,0xF8,0x18,0xD8,0xD8,0x18,0xF8,0xF8,0x00,0x00,0xE0,0xE0,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x00,0x00,0x00,0xC0,0xC0, + 0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x06,0x06,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x06,0x00,0x00,0x06,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x06,0x06,0x00,0x00,0x00,0x07,0x07 +END_DATA +}; diff --git a/src/RCXintro_14.txt b/src/RCXintro_14.txt new file mode 100644 index 0000000..feb4cd7 --- /dev/null +++ b/src/RCXintro_14.txt @@ -0,0 +1,13 @@ +DEFINE_DATA(BMPMAP, RCXintro_14) = +{ + 0x02,0x00, // Graphics Format + 0x00,0xC0, // Graphics DataSize + 0x03, // Graphics Start X + 0x20, // Graphics Start Y + 0x5E, // Graphics Width + 0x10, // Graphics Height +BEGIN_DATA + 0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x00,0x00,0x00,0x00,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x00,0x00,0x00,0x00,0xFE,0xFE,0x00,0x00,0xF8,0xF8,0x00,0x00,0x00,0xD8,0xD8,0x00,0x00,0x00,0x00,0x00,0xF8,0xF8,0x00,0x00,0x00,0x00,0x00,0xF8,0xF8,0x18,0xD8,0xD8,0x18,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x00,0x00,0x00,0x00,0x38,0x38,0x00,0x00,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x00,0x00,0x00,0xD8,0xD8, + 0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x06,0x06,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x06,0x00,0x00,0x06,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x06,0x06,0x00,0x00,0x00,0x07,0x07 +END_DATA +}; diff --git a/src/RCXintro_15.txt b/src/RCXintro_15.txt new file mode 100644 index 0000000..71f51e0 --- /dev/null +++ b/src/RCXintro_15.txt @@ -0,0 +1,13 @@ +DEFINE_DATA(BMPMAP, RCXintro_15) = +{ + 0x02,0x00, // Graphics Format + 0x00,0xC0, // Graphics DataSize + 0x03, // Graphics Start X + 0x20, // Graphics Start Y + 0x5E, // Graphics Width + 0x10, // Graphics Height +BEGIN_DATA + 0xF8,0xF8,0x18,0x00,0xF8,0xF8,0x18,0x00,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x18,0x18,0x00,0x00,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x18,0x18,0x00,0x00,0xFE,0xFE,0x00,0x00,0xF8,0xF8,0x18,0x00,0xC0,0xD8,0xD8,0x00,0x00,0x18,0x18,0x00,0xF8,0xF8,0x18,0x00,0x00,0x00,0x00,0xF8,0xF8,0x18,0xD8,0xD8,0x18,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x18,0x00,0x00,0x18,0x38,0x38,0x00,0x00,0xF8,0xF8,0x18,0x00,0xF8,0xF8,0x18,0x00,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x18,0x00,0xC0,0xD8,0xD8, + 0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x06,0x06,0x07,0x07,0x00,0x00,0x06,0x06,0x06,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x06,0x00,0x00,0x06,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x06,0x06,0x06,0x00,0x00,0x07,0x07 +END_DATA +}; diff --git a/src/RCXintro_16.txt b/src/RCXintro_16.txt new file mode 100644 index 0000000..9cf470c --- /dev/null +++ b/src/RCXintro_16.txt @@ -0,0 +1,13 @@ +DEFINE_DATA(BMPMAP, RCXintro_16) = +{ + 0x02,0x00, // Graphics Format + 0x00,0xC0, // Graphics DataSize + 0x03, // Graphics Start X + 0x20, // Graphics Start Y + 0x5E, // Graphics Width + 0x10, // Graphics Height +BEGIN_DATA + 0xF8,0xF8,0x18,0x18,0xF8,0xF8,0x18,0x18,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x18,0x18,0x18,0x18,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x18,0x18,0x18,0x18,0xFE,0xFE,0x00,0x00,0xF8,0xF8,0xD8,0xD8,0xD8,0xD8,0xD8,0x00,0x00,0x18,0x18,0x18,0xF8,0xF8,0x18,0x18,0x18,0x00,0x00,0xF8,0xF8,0x18,0xD8,0xD8,0x18,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0x18,0x18,0x18,0x18,0x38,0x38,0x00,0x00,0xF8,0xF8,0x18,0x18,0xF8,0xF8,0x18,0x18,0xF8,0xF8,0x00,0x00,0xF8,0xF8,0xD8,0xD8,0xD8,0xD8,0xD8, + 0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x06,0x06,0x06,0x06,0x07,0x07,0x00,0x00,0x06,0x06,0x06,0x06,0x06,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x06,0x00,0x00,0x06,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x06,0x06,0x06,0x06,0x06,0x07,0x07 +END_DATA +}; diff --git a/src/RCXintro_2.txt b/src/RCXintro_2.txt new file mode 100644 index 0000000..addecb2 --- /dev/null +++ b/src/RCXintro_2.txt @@ -0,0 +1,19 @@ +DEFINE_DATA(BMPMAP, RCXintro_2) = +{ + 0x02,0x00, // Graphics Format + 0x02,0x00, // Graphics DataSize + 0x10, // Graphics Start X + 0x00, // Graphics Start Y + 0x40, // Graphics Width + 0x40, // Graphics Height +BEGIN_DATA + 0xFC,0x02,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0x02,0xFC, + 0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x3F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x3F,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0xFF, + 0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x1F,0x8F,0xC7,0xE7,0x67,0x30,0x30,0x30,0x60,0xE0,0x80,0xC0,0xE0,0x60,0x60,0x30,0x30,0x30,0x30,0x30,0x20,0x60,0xC0,0xC0,0xE0,0x60,0x60,0x30,0x30,0x30,0x30,0x30,0x60,0x60,0xC0,0x80,0x80,0xC0,0x60,0x60,0x20,0x33,0x33,0x33,0x33,0x63,0x67,0xC7,0x8F,0x1F,0x33,0xF3,0xFF,0x00,0xFF, + 0xFF,0x00,0xFF,0xFF,0x7F,0x0F,0x83,0xE0,0x78,0x1E,0x07,0x01,0x00,0x00,0x80,0xE0,0xF8,0x7E,0x1F,0x07,0x01,0x00,0x00,0x00,0x18,0x18,0x18,0xF8,0xF8,0x1C,0x06,0x03,0x00,0x00,0xC0,0x70,0x3C,0x3C,0x30,0x20,0x20,0xE0,0xF0,0x3D,0x0F,0x03,0x00,0x00,0xC0,0xF0,0xFC,0x3C,0x00,0x00,0x00,0x00,0xC0,0xFF,0x1E,0x00,0xC0,0xFF,0x00,0xFF, + 0xFF,0x00,0xFF,0x01,0x00,0xFC,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x0E,0x0F,0xFF,0xC7,0x00,0x00,0x00,0x00,0x00,0x0E,0x0E,0x0E,0x0E,0xFE,0xC7,0x80,0x00,0x00,0x00,0x00,0x1F,0x1F,0x0E,0x00,0x00,0x80,0xC0,0xF0,0xFF,0x83,0x00,0x00,0x00,0x1C,0x1F,0x0F,0x03,0x00,0x80,0xC0,0xE0,0x78,0x1E,0xC7,0xE1,0xF8,0xFF,0xFF,0xFF,0x00,0xFF, + 0xFF,0x00,0xFF,0xFE,0xFE,0xFC,0xF3,0xF3,0xE6,0xE6,0xE6,0xE6,0xE6,0xF2,0x83,0x01,0x01,0x03,0x06,0x06,0x06,0x06,0x06,0x06,0x03,0x03,0x01,0x01,0x03,0x03,0x06,0x06,0x06,0x06,0x06,0x06,0x03,0x03,0x01,0x00,0x00,0x01,0x03,0x03,0x06,0x06,0x06,0x06,0x06,0x86,0xF3,0xFB,0xF9,0xFC,0xFE,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0xFF, + 0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFC,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0xFF, + 0x3F,0x40,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0x40,0x3F +END_DATA +}; diff --git a/src/RCXintro_3.txt b/src/RCXintro_3.txt new file mode 100644 index 0000000..eba6710 --- /dev/null +++ b/src/RCXintro_3.txt @@ -0,0 +1,19 @@ +DEFINE_DATA(BMPMAP, RCXintro_3) = +{ + 0x02,0x00, // Graphics Format + 0x02,0x00, // Graphics DataSize + 0x10, // Graphics Start X + 0x00, // Graphics Start Y + 0x40, // Graphics Width + 0x40, // Graphics Height +BEGIN_DATA + 0xFC,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFC, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x3F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x3F,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x1F,0x07,0x07,0xC3,0xF1,0x79,0x1F,0x00,0x00,0x00,0x00,0xF8,0x7E,0x07,0x03,0x19,0x18,0xF8,0xFC,0xFC,0xFC,0xFF,0xFF,0xFF,0xFF,0xFD,0xFD,0xFC,0xF8,0x31,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x30,0x0C,0x07,0x81,0xE0,0x3C,0x01,0x01,0xC3,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC3,0x80,0x80,0x80,0x80,0x8F,0xDF,0x70,0x00,0x00,0x00,0x00,0x00,0x7F,0xC0,0x80,0x80,0xCE,0xCE,0x5F,0x7F,0xFF,0xFF,0xBF,0xBF,0x3F,0x3F,0x3F,0x3F,0xBF,0xDF,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x63,0xC0,0x80,0xC6,0xE3,0xC0,0xE0,0xF8,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFC,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xFC,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0x3F,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x3F +END_DATA +}; diff --git a/src/RCXintro_4.txt b/src/RCXintro_4.txt new file mode 100644 index 0000000..dc15847 --- /dev/null +++ b/src/RCXintro_4.txt @@ -0,0 +1,19 @@ +DEFINE_DATA(BMPMAP, RCXintro_4) = +{ + 0x02,0x00, // Graphics Format + 0x02,0x00, // Graphics DataSize + 0x10, // Graphics Start X + 0x00, // Graphics Start Y + 0x40, // Graphics Width + 0x40, // Graphics Height +BEGIN_DATA + 0xFC,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFC, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x3F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x3F,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFC,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xFC,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0x3F,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x3F +END_DATA +}; diff --git a/src/RCXintro_5.txt b/src/RCXintro_5.txt new file mode 100644 index 0000000..efd3cb9 --- /dev/null +++ b/src/RCXintro_5.txt @@ -0,0 +1,19 @@ +DEFINE_DATA(BMPMAP, RCXintro_5) = +{ + 0x02,0x00, // Graphics Format + 0x01,0xC0, // Graphics DataSize + 0x17, // Graphics Start X + 0x00, // Graphics Start Y + 0x34, // Graphics Width + 0x40, // Graphics Height +BEGIN_DATA + 0x80,0xC0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xC0,0x80, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF0,0xE0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xE0,0xF0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F, + 0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00 +END_DATA +}; diff --git a/src/RCXintro_6.txt b/src/RCXintro_6.txt new file mode 100644 index 0000000..4ab152a --- /dev/null +++ b/src/RCXintro_6.txt @@ -0,0 +1,17 @@ +DEFINE_DATA(BMPMAP, RCXintro_6) = +{ + 0x02,0x00, // Graphics Format + 0x01,0x20, // Graphics DataSize + 0x1C, // Graphics Start X + 0x08, // Graphics Start Y + 0x2C, // Graphics Width + 0x30, // Graphics Height +BEGIN_DATA + 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x07,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x03,0x07,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x03,0x03,0x03,0x03,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFC,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xFC,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0x07,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x07 +END_DATA +}; diff --git a/src/RCXintro_7.txt b/src/RCXintro_7.txt new file mode 100644 index 0000000..cabcc7b --- /dev/null +++ b/src/RCXintro_7.txt @@ -0,0 +1,16 @@ +DEFINE_DATA(BMPMAP, RCXintro_7) = +{ + 0x02,0x00, // Graphics Format + 0x00,0xC8, // Graphics DataSize + 0x23, // Graphics Start X + 0x10, // Graphics Start Y + 0x22, // Graphics Width + 0x28, // Graphics Height +BEGIN_DATA + 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xC0,0xC0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x0F,0x0F,0x0F,0x0F,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,0xF8,0xF8,0xF8,0xF8,0xF8,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xF8,0xF8,0xF8,0xF8,0xF8,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0x01,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x01 +END_DATA +}; diff --git a/src/RCXintro_8.txt b/src/RCXintro_8.txt new file mode 100644 index 0000000..d062714 --- /dev/null +++ b/src/RCXintro_8.txt @@ -0,0 +1,14 @@ +DEFINE_DATA(BMPMAP, RCXintro_8) = +{ + 0x02,0x00, // Graphics Format + 0x00,0x48, // Graphics DataSize + 0x2C, // Graphics Start X + 0x18, // Graphics Start Y + 0x16, // Graphics Width + 0x18, // Graphics Height +BEGIN_DATA + 0xFE,0xFF,0xFF,0xFF,0x1F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x1F,0xFF,0xFF,0xFF,0xFE, + 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x1E,0x1E,0x1E,0x1E,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF, + 0x1F,0x3F,0x3F,0x3F,0x3E,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x3E,0x3F,0x3F,0x3F,0x1F +END_DATA +}; diff --git a/src/RCXintro_9.txt b/src/RCXintro_9.txt new file mode 100644 index 0000000..3952437 --- /dev/null +++ b/src/RCXintro_9.txt @@ -0,0 +1,14 @@ +DEFINE_DATA(BMPMAP, RCXintro_9) = +{ + 0x02,0x00, // Graphics Format + 0x00,0x30, // Graphics DataSize + 0x34, // Graphics Start X + 0x18, // Graphics Start Y + 0x0E, // Graphics Width + 0x18, // Graphics Height +BEGIN_DATA + 0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0, + 0xFF,0xFF,0xFF,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0xFF,0xFF,0xFF, + 0x07,0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x07 +END_DATA +}; diff --git a/src/Running.txt b/src/Running.txt new file mode 100644 index 0000000..6bea492 --- /dev/null +++ b/src/Running.txt @@ -0,0 +1,59 @@ +DEFINE_DATA(ICON, Running) = +{ + 0x04,0x00, // Graphics Format + 0x04,0x80, // Graphics DataSize + 0x01, // Graphics Count X + 0x10, // Graphics Count Y + 0x18, // Graphics Width + 0x18, // Graphics Height +BEGIN_DATA + 0x00,0x00,0x00,0xE0,0xF0,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x38,0xF0,0xE0,0x00,0x00,0x00, + 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, + 0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,0x00,0x00, + 0x00,0x00,0x00,0xE0,0xF0,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x38,0xF0,0xE0,0x00,0x00,0x00, + 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, + 0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,0x00,0x00, + 0x00,0x00,0x00,0xE0,0xF0,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x38,0xF0,0xE0,0x00,0x00,0x00, + 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, + 0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,0x00,0x00, + 0x00,0x00,0x00,0xE0,0xF0,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x38,0xF0,0xE0,0x00,0x00,0x00, + 0x00,0x00,0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, + 0x00,0x00,0x00,0x06,0x0E,0x1C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,0x00,0x00, + 0x00,0x00,0x00,0xE0,0xF0,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x38,0xF0,0xE0,0x00,0x00,0x00, + 0x00,0x00,0x00,0xC3,0xC3,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, + 0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,0x00,0x00, + 0x00,0x00,0x00,0x60,0x70,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x38,0xF0,0xE0,0x00,0x00,0x00, + 0x00,0x00,0x00,0xF8,0xF8,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, + 0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,0x00,0x00, + 0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x38,0xF0,0xE0,0x00,0x00,0x00, + 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, + 0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,0x00,0x00, + 0x00,0x00,0x00,0xE0,0xF0,0x38,0x18,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x38,0xF0,0xE0,0x00,0x00,0x00, + 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, + 0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,0x00,0x00, + 0x00,0x00,0x00,0xE0,0xF0,0x38,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x38,0xF0,0xE0,0x00,0x00,0x00, + 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, + 0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,0x00,0x00, + 0x00,0x00,0x00,0xE0,0xF0,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x18,0x38,0xF0,0xE0,0x00,0x00,0x00, + 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, + 0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,0x00,0x00, + 0x00,0x00,0x00,0xE0,0xF0,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x80,0x80,0x00,0x00,0x00, + 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, + 0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,0x00,0x00, + 0x00,0x00,0x00,0xE0,0xF0,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x38,0x70,0x60,0x00,0x00,0x00, + 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0xF8,0xF8,0x00,0x00,0x00, + 0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,0x00,0x00, + 0x00,0x00,0x00,0xE0,0xF0,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x38,0xF0,0xE0,0x00,0x00,0x00, + 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0xC3,0xC3,0x00,0x00,0x00, + 0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,0x00,0x00, + 0x00,0x00,0x00,0xE0,0xF0,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x38,0xF0,0xE0,0x00,0x00,0x00, + 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0x1F,0x1F,0x00,0x00,0x00, + 0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1C,0x0E,0x06,0x00,0x00,0x00, + 0x00,0x00,0x00,0xE0,0xF0,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x38,0xF0,0xE0,0x00,0x00,0x00, + 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, + 0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x01,0x01,0x00,0x00,0x00, + 0x00,0x00,0x00,0xE0,0xF0,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x38,0xF0,0xE0,0x00,0x00,0x00, + 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, + 0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x18,0x1C,0x0F,0x07,0x00,0x00,0x00 +END_DATA +}; diff --git a/src/Status.txt b/src/Status.txt new file mode 100644 index 0000000..6d1d5bd --- /dev/null +++ b/src/Status.txt @@ -0,0 +1,17 @@ +DEFINE_DATA(ICON, Status) = +{ + 0x04,0x00, // Graphics Format + 0x01,0xB0, // Graphics DataSize + 0x06, // Graphics Count X + 0x06, // Graphics Count Y + 0x0C, // Graphics Width + 0x08, // Graphics Height +BEGIN_DATA + 0x00,0x00,0x7E,0x81,0x81,0x19,0x19,0x81,0x81,0x7E,0x00,0x00,0x00,0x00,0x7E,0x01,0x01,0x99,0x99,0x81,0x81,0x7E,0x00,0x00,0x00,0x00,0x1E,0x81,0x81,0x99,0x99,0x81,0x81,0x7E,0x00,0x00,0x00,0x00,0x66,0x81,0x81,0x99,0x99,0x81,0x81,0x7E,0x00,0x00,0x00,0x00,0x78,0x81,0x81,0x99,0x99,0x81,0x81,0x7E,0x00,0x00,0x00,0x00,0x7E,0x80,0x80,0x99,0x99,0x81,0x81,0x7E,0x00,0x00, + 0x00,0x00,0x7E,0x81,0x81,0x98,0x98,0x81,0x81,0x7E,0x00,0x00,0x00,0x00,0x7E,0x81,0x81,0x99,0x99,0x80,0x80,0x7E,0x00,0x00,0x00,0x00,0x7E,0x81,0x81,0x99,0x99,0x81,0x81,0x78,0x00,0x00,0x00,0x00,0x7E,0x81,0x81,0x99,0x99,0x81,0x81,0x66,0x00,0x00,0x00,0x00,0x7E,0x81,0x81,0x99,0x99,0x81,0x81,0x1E,0x00,0x00,0x00,0x00,0x7E,0x81,0x81,0x99,0x99,0x01,0x01,0x7E,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x24,0x24,0x24,0x24,0x24,0x3C,0x3C,0x00,0x00,0x00,0x00,0x18,0x24,0x24,0x24,0x24,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x18,0x24,0x24,0x3C,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x18,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x24,0x24,0x24,0x24,0x24,0x3C,0x3C,0x00,0x00,0x00,0x00,0x18,0x24,0x24,0x24,0x24,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x18,0x24,0x24,0x3C,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x18,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x22,0x14,0x7F,0x2A,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x22,0x14,0x7F,0x2A,0x14,0x00,0x08,0x14,0x22,0x00,0x00,0x00,0x22,0x14,0x7F,0x2A,0x14,0x00,0x00,0x00,0x22,0x14,0x08,0x00,0x22,0x14,0x7F,0x2A,0x14,0x00,0x08,0x14,0x22,0x14,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x22,0x1C,0x00,0x3E,0x0A,0x02,0x00,0x3E,0x20,0x3E,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x14,0x1C,0x08,0x08,0x08,0x08,0x08,0x1C,0x14,0x14,0x00,0x3E,0x20,0x3E,0x00,0x2E,0x2A,0x3A,0x00,0x3E,0x2A,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +END_DATA +}; diff --git a/src/Step.txt b/src/Step.txt new file mode 100644 index 0000000..cba0c0d --- /dev/null +++ b/src/Step.txt @@ -0,0 +1,19 @@ +DEFINE_DATA(ICON, Step) = +{ + 0x04,0x00, // Graphics Format + 0x02,0xC0, // Graphics DataSize + 0x08, // Graphics Count X + 0x04, // Graphics Count Y + 0x0B, // Graphics Width + 0x10, // Graphics Height +BEGIN_DATA + 0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0xFF,0x01,0x01,0x11,0x19,0x7D,0x19,0x11,0x01,0x01,0xFF,0xFF,0x01,0x01,0x11,0x19,0x7D,0x19,0x11,0x05,0x01,0xFF,0xFF,0x01,0x11,0x39,0x7D,0x11,0x1D,0x01,0x05,0x01,0xFF,0xFF,0x01,0x11,0x39,0x7D,0x11,0x71,0x01,0x01,0x01,0xFF,0xFF,0x01,0x11,0x39,0x7D,0x11,0x71,0x01,0x05,0x01,0xFF,0xFF,0x01,0x01,0x01,0x1D,0x11,0x7D,0x39,0x11,0x01,0xFF,0xFF,0x01,0x01,0x01,0x71,0x11,0x7D,0x39,0x11,0x01,0xFF, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0xFF,0x01,0x05,0x01,0x71,0x11,0x7D,0x39,0x11,0x01,0xFF,0xFF,0x01,0x11,0x39,0x7D,0x11,0x1D,0x01,0x01,0x01,0xFF,0xFF,0x01,0x01,0x21,0x71,0x71,0x3D,0x01,0x01,0x01,0xFF,0xFF,0x01,0x01,0x21,0x71,0x71,0x3D,0x01,0x01,0x01,0xFF,0xFF,0x01,0x01,0x11,0x31,0x7D,0x31,0x11,0x01,0x01,0xFF,0xFF,0x01,0x01,0x11,0x31,0x7D,0x31,0x11,0x05,0x01,0xFF,0xFF,0x01,0x05,0x01,0x1D,0x11,0x7D,0x39,0x11,0x01,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0xFF,0x01,0x01,0x39,0x45,0x45,0x45,0x39,0x01,0x01,0xFF,0xFF,0x01,0xF1,0x39,0x45,0xFF,0x11,0x45,0x39,0x01,0xFF,0xFF,0x01,0x39,0x29,0x29,0x39,0x45,0x45,0x39,0x01,0xFF,0xFF,0x01,0x01,0x01,0x01,0x01,0x39,0x45,0xFF,0x01,0xFF,0xFF,0x01,0x01,0xC7,0xAB,0x93,0xAB,0xC7,0x01,0x01,0xFF,0xFF,0x01,0x01,0xC7,0xAB,0x93,0xAB,0xC7,0x01,0x01,0xFF,0xFF,0x01,0x01,0xC7,0xAB,0x93,0xAB,0xC7,0x01,0x01,0xFF, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0xFF,0x01,0x01,0x39,0x7D,0x7D,0x7D,0x39,0x01,0x01,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x01,0x39,0x41,0x45,0x4F,0x45,0x39,0x01,0x01,0xFF,0xFF,0x01,0x49,0x55,0x25,0x01,0x05,0x7D,0x05,0x01,0xFF, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 +END_DATA +}; diff --git a/src/Submenu01.rms b/src/Submenu01.rms new file mode 100644 index 0000000..aadf93d --- /dev/null +++ b/src/Submenu01.rms @@ -0,0 +1,128 @@ +const UBYTE SUBMENU01[] = +{ + 0x07,0x00, // Menu Format + 0x01,0xED, // Menu DataSize + 0x1D, // Menu item size + 0x11, // Menu items + 0x18, // Menu icon Width + 0x18, // Menu icon Height + + // Software_files + 0x00,0x00,0x00,0x01, // 0x00000001 + 0x10,0x00,0x80,0x01, // 0x10008001 + 0x06,0x02,0x00,0x01, // 6 ,2 ,0 ,1 + 0x53,0x6F,0x66,0x74,0x77,0x61,0x72,0x65,0x20,0x66,0x69,0x6C,0x65,0x73,0x00,0x00, + 0x1C, // 1C + + // NXT_files + 0x00,0x00,0x00,0x02, // 0x00000002 + 0x10,0x00,0x80,0x01, // 0x10008001 + 0x06,0x03,0x00,0x01, // 6 ,3 ,0 ,1 + 0x4E,0x58,0x54,0x20,0x66,0x69,0x6C,0x65,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x1D, // 1D + + // Sound_files + 0x00,0x00,0x00,0x03, // 0x00000003 + 0x10,0x00,0x80,0x01, // 0x10008001 + 0x06,0x01,0x00,0x01, // 6 ,1 ,0 ,1 + 0x53,0x6F,0x75,0x6E,0x64,0x20,0x66,0x69,0x6C,0x65,0x73,0x00,0x00,0x00,0x00,0x00, + 0x1B, // 1B + + // Datalog_files + 0x00,0x00,0x00,0x04, // 0x00000004 + 0x00,0x80,0x80,0x00, // 0x00808000 + 0x06,0x05,0x00,0x02, // 6 ,5 ,0 ,2 + 0x44,0x61,0x74,0x61,0x6C,0x6F,0x67,0x20,0x66,0x69,0x6C,0x65,0x73,0x00,0x00,0x00, + 0x1F, // 1F + + // _ + 0x00,0x00,0x00,0x11, // 0x00000011 + 0x00,0x00,0x03,0x00, // 0x00000300 + 0x06,0xF2,0x00,0x01, // 6 ,242,0 ,1 + 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00, // 00 + + // _ + 0x00,0x00,0x00,0x14, // 0x00000014 + 0x00,0x00,0x03,0x00, // 0x00000300 + 0x06,0xF2,0x00,0x01, // 6 ,242,0 ,1 + 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00, // 00 + + // Run + 0x00,0x00,0x01,0x11, // 0x00000111 + 0x00,0x00,0x01,0x20, // 0x00000120 + 0x08,0xF8,0x00,0x00, // 8 ,248,0 ,0 + 0x52,0x75,0x6E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x32, // 32 + + // Send + 0x00,0x00,0x02,0x11, // 0x00000211 + 0x00,0x40,0x00,0x00, // 0x00400000 + 0x00,0x00,0x00,0x01, // 0 ,0 ,0 ,1 + 0x53,0x65,0x6E,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x33, // 33 + + // Delete + 0x00,0x00,0x03,0x11, // 0x00000311 + 0x00,0x00,0x00,0x00, // 0x00000000 + 0x00,0x00,0x00,0x02, // 0 ,0 ,0 ,2 + 0x44,0x65,0x6C,0x65,0x74,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x34, // 34 + + // Delete + 0x00,0x00,0x01,0x14, // 0x00000114 + 0x00,0x00,0x00,0x00, // 0x00000000 + 0x00,0x00,0x00,0x02, // 0 ,0 ,0 ,2 + 0x44,0x65,0x6C,0x65,0x74,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x34, // 34 + + // Send + 0x00,0x00,0x02,0x14, // 0x00000214 + 0x00,0x40,0x00,0x00, // 0x00400000 + 0x00,0x00,0x00,0x01, // 0 ,0 ,0 ,1 + 0x53,0x65,0x6E,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x33, // 33 + + // _ + 0x00,0x00,0x12,0x11, // 0x00001211 + 0x00,0x00,0x03,0x00, // 0x00000300 + 0x10,0xF9,0x00,0x00, // 16 ,249,0 ,0 + 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00, // 00 + + // Are_you_sure? + 0x00,0x00,0x13,0x11, // 0x00001311 + 0x00,0x00,0x00,0x08, // 0x00000008 + 0x09,0x00,0x00,0x00, // 9 ,0 ,0 ,0 + 0x41,0x72,0x65,0x20,0x79,0x6F,0x75,0x20,0x73,0x75,0x72,0x65,0x3F,0x00,0x00,0x00, + 0x31, // 31 + + // Are_you_sure? + 0x00,0x00,0x23,0x11, // 0x00002311 + 0x00,0x00,0x00,0x04, // 0x00000004 + 0x00,0x00,0x00,0x00, // 0 ,0 ,0 ,0 + 0x41,0x72,0x65,0x20,0x79,0x6F,0x75,0x20,0x73,0x75,0x72,0x65,0x3F,0x00,0x00,0x00, + 0x30, // 30 + + // Are_you_sure? + 0x00,0x00,0x11,0x14, // 0x00001114 + 0x00,0x00,0x00,0x08, // 0x00000008 + 0x09,0x00,0x00,0x00, // 9 ,0 ,0 ,0 + 0x41,0x72,0x65,0x20,0x79,0x6F,0x75,0x20,0x73,0x75,0x72,0x65,0x3F,0x00,0x00,0x00, + 0x31, // 31 + + // Are_you_sure? + 0x00,0x00,0x21,0x14, // 0x00002114 + 0x00,0x00,0x00,0x04, // 0x00000004 + 0x00,0x00,0x00,0x00, // 0 ,0 ,0 ,0 + 0x41,0x72,0x65,0x20,0x79,0x6F,0x75,0x20,0x73,0x75,0x72,0x65,0x3F,0x00,0x00,0x00, + 0x30, // 30 + + // _ + 0x00,0x00,0x12,0x14, // 0x00001214 + 0x00,0x00,0x03,0x00, // 0x00000300 + 0x10,0xF9,0x00,0x00, // 16 ,249,0 ,0 + 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00, // 00 +}; diff --git a/src/Submenu02.rms b/src/Submenu02.rms new file mode 100644 index 0000000..a30478f --- /dev/null +++ b/src/Submenu02.rms @@ -0,0 +1,401 @@ +const UBYTE SUBMENU02[] = +{ + 0x07,0x00, // Menu Format + 0x06,0x58, // Menu DataSize + 0x1D, // Menu item size + 0x38, // Menu items + 0x18, // Menu icon Width + 0x18, // Menu icon Height + + // _ + 0x00,0x00,0x00,0x01, // 0x00000001 + 0x00,0x00,0x03,0x00, // 0x00000300 + 0x0B,0xF7,0x00,0x01, // 11 ,247,0 ,1 + 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00, // 00 + + // Forward_5 + 0x00,0x00,0x00,0x11, // 0x00000011 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x23,0x00,0x01, // 11 ,35 ,0 ,1 + 0x46,0x6F,0x72,0x77,0x61,0x72,0x64,0x20,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x23, // 23 + + // Forward + 0x00,0x00,0x00,0x21, // 0x00000021 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x22,0x00,0x01, // 11 ,34 ,0 ,1 + 0x46,0x6F,0x72,0x77,0x61,0x72,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x22, // 22 + + // Turn_right_2 + 0x00,0x00,0x00,0x31, // 0x00000031 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x29,0x00,0x01, // 11 ,41 ,0 ,1 + 0x54,0x75,0x72,0x6E,0x20,0x72,0x69,0x67,0x68,0x74,0x20,0x32,0x00,0x00,0x00,0x00, + 0x29, // 29 + + // Turn_right + 0x00,0x00,0x00,0x41, // 0x00000041 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x28,0x00,0x01, // 11 ,40 ,0 ,1 + 0x54,0x75,0x72,0x6E,0x20,0x72,0x69,0x67,0x68,0x74,0x00,0x00,0x00,0x00,0x00,0x00, + 0x28, // 28 + + // Back_right_2 + 0x00,0x00,0x00,0x51, // 0x00000051 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x2F,0x00,0x01, // 11 ,47 ,0 ,1 + 0x42,0x61,0x63,0x6B,0x20,0x72,0x69,0x67,0x68,0x74,0x20,0x32,0x00,0x00,0x00,0x00, + 0x2F, // 2F + + // Back_right + 0x00,0x00,0x00,0x61, // 0x00000061 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x27,0x00,0x01, // 11 ,39 ,0 ,1 + 0x42,0x61,0x63,0x6B,0x20,0x72,0x69,0x67,0x68,0x74,0x00,0x00,0x00,0x00,0x00,0x00, + 0x27, // 27 + + // Tone_1 + 0x00,0x00,0x00,0x71, // 0x00000071 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x2B,0x00,0x01, // 11 ,43 ,0 ,1 + 0x54,0x6F,0x6E,0x65,0x20,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x2B, // 2B + + // Tone_2 + 0x00,0x00,0x00,0x81, // 0x00000081 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x2C,0x00,0x01, // 11 ,44 ,0 ,1 + 0x54,0x6F,0x6E,0x65,0x20,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x2C, // 2C + + // Back_left_2 + 0x00,0x00,0x00,0x91, // 0x00000091 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x24,0x00,0x01, // 11 ,36 ,0 ,1 + 0x42,0x61,0x63,0x6B,0x20,0x6C,0x65,0x66,0x74,0x20,0x32,0x00,0x00,0x00,0x00,0x00, + 0x24, // 24 + + // Back_left + 0x00,0x00,0x00,0xA1, // 0x000000A1 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x2A,0x00,0x01, // 11 ,42 ,0 ,1 + 0x42,0x61,0x63,0x6B,0x20,0x6C,0x65,0x66,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x2A, // 2A + + // Turn_left + 0x00,0x00,0x00,0xB1, // 0x000000B1 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x25,0x00,0x01, // 11 ,37 ,0 ,1 + 0x54,0x75,0x72,0x6E,0x20,0x6C,0x65,0x66,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x25, // 25 + + // Turn_left_2 + 0x00,0x00,0x00,0xC1, // 0x000000C1 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x26,0x00,0x01, // 11 ,38 ,0 ,1 + 0x54,0x75,0x72,0x6E,0x20,0x6C,0x65,0x66,0x74,0x20,0x32,0x00,0x00,0x00,0x00,0x00, + 0x26, // 26 + + // Empty + 0x00,0x00,0x00,0xD1, // 0x000000D1 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x21,0x00,0x01, // 11 ,33 ,0 ,1 + 0x45,0x6D,0x70,0x74,0x79,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x21, // 21 + + // Backward + 0x00,0x00,0x00,0xE1, // 0x000000E1 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x2D,0x00,0x01, // 11 ,45 ,0 ,1 + 0x42,0x61,0x63,0x6B,0x77,0x61,0x72,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x2D, // 2D + + // Backward_5 + 0x00,0x00,0x00,0xF1, // 0x000000F1 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x2E,0x00,0x01, // 11 ,46 ,0 ,1 + 0x42,0x61,0x63,0x6B,0x77,0x61,0x72,0x64,0x20,0x35,0x00,0x00,0x00,0x00,0x00,0x00, + 0x2E, // 2E + + // Empty + 0x00,0x00,0x01,0x11, // 0x00000111 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x41,0x00,0x01, // 11 ,65 ,0 ,1 + 0x45,0x6D,0x70,0x74,0x79,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x21, // 21 + + // Wait_2 + 0x00,0x00,0x02,0x11, // 0x00000211 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x46,0x00,0x01, // 11 ,70 ,0 ,1 + 0x57,0x61,0x69,0x74,0x20,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x46, // 46 + + // Wait_5 + 0x00,0x00,0x03,0x11, // 0x00000311 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x47,0x00,0x01, // 11 ,71 ,0 ,1 + 0x57,0x61,0x69,0x74,0x20,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x47, // 47 + + // Wait_10 + 0x00,0x00,0x04,0x11, // 0x00000411 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x48,0x00,0x01, // 11 ,72 ,0 ,1 + 0x57,0x61,0x69,0x74,0x20,0x31,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x48, // 48 + + // Object + 0x00,0x00,0x05,0x11, // 0x00000511 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x43,0x00,0x01, // 11 ,67 ,0 ,1 + 0x4F,0x62,0x6A,0x65,0x63,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x43, // 43 + + // Sound + 0x00,0x00,0x06,0x11, // 0x00000611 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x44,0x00,0x01, // 11 ,68 ,0 ,1 + 0x53,0x6F,0x75,0x6E,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x44, // 44 + + // Light + 0x00,0x00,0x07,0x11, // 0x00000711 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x42,0x00,0x01, // 11 ,66 ,0 ,1 + 0x4C,0x69,0x67,0x68,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x42, // 42 + + // Dark + 0x00,0x00,0x08,0x11, // 0x00000811 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x49,0x00,0x01, // 11 ,73 ,0 ,1 + 0x44,0x61,0x72,0x6B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x49, // 49 + + // Touch + 0x00,0x00,0x09,0x11, // 0x00000911 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x45,0x00,0x01, // 11 ,69 ,0 ,1 + 0x54,0x6F,0x75,0x63,0x68,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x45, // 45 + + // Forward_5 + 0x00,0x00,0x11,0x11, // 0x00001111 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x23,0x00,0x01, // 11 ,35 ,0 ,1 + 0x46,0x6F,0x72,0x77,0x61,0x72,0x64,0x20,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x23, // 23 + + // Forward + 0x00,0x00,0x21,0x11, // 0x00002111 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x22,0x00,0x01, // 11 ,34 ,0 ,1 + 0x46,0x6F,0x72,0x77,0x61,0x72,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x22, // 22 + + // Turn_right_2 + 0x00,0x00,0x31,0x11, // 0x00003111 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x29,0x00,0x01, // 11 ,41 ,0 ,1 + 0x54,0x75,0x72,0x6E,0x20,0x72,0x69,0x67,0x68,0x74,0x20,0x32,0x00,0x00,0x00,0x00, + 0x29, // 29 + + // Turn_right + 0x00,0x00,0x41,0x11, // 0x00004111 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x28,0x00,0x01, // 11 ,40 ,0 ,1 + 0x54,0x75,0x72,0x6E,0x20,0x72,0x69,0x67,0x68,0x74,0x00,0x00,0x00,0x00,0x00,0x00, + 0x28, // 28 + + // Back_right_2 + 0x00,0x00,0x51,0x11, // 0x00005111 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x2F,0x00,0x01, // 11 ,47 ,0 ,1 + 0x42,0x61,0x63,0x6B,0x20,0x72,0x69,0x67,0x68,0x74,0x20,0x32,0x00,0x00,0x00,0x00, + 0x2F, // 2F + + // Back_right + 0x00,0x00,0x61,0x11, // 0x00006111 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x27,0x00,0x01, // 11 ,39 ,0 ,1 + 0x42,0x61,0x63,0x6B,0x20,0x72,0x69,0x67,0x68,0x74,0x00,0x00,0x00,0x00,0x00,0x00, + 0x27, // 27 + + // Tone_1 + 0x00,0x00,0x71,0x11, // 0x00007111 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x2B,0x00,0x01, // 11 ,43 ,0 ,1 + 0x54,0x6F,0x6E,0x65,0x20,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x2B, // 2B + + // Tone_2 + 0x00,0x00,0x81,0x11, // 0x00008111 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x2C,0x00,0x01, // 11 ,44 ,0 ,1 + 0x54,0x6F,0x6E,0x65,0x20,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x2C, // 2C + + // Back_left_2 + 0x00,0x00,0x91,0x11, // 0x00009111 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x24,0x00,0x01, // 11 ,36 ,0 ,1 + 0x42,0x61,0x63,0x6B,0x20,0x6C,0x65,0x66,0x74,0x20,0x32,0x00,0x00,0x00,0x00,0x00, + 0x24, // 24 + + // Back_left + 0x00,0x00,0xA1,0x11, // 0x0000A111 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x2A,0x00,0x01, // 11 ,42 ,0 ,1 + 0x42,0x61,0x63,0x6B,0x20,0x6C,0x65,0x66,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x2A, // 2A + + // Turn_left + 0x00,0x00,0xB1,0x11, // 0x0000B111 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x25,0x00,0x01, // 11 ,37 ,0 ,1 + 0x54,0x75,0x72,0x6E,0x20,0x6C,0x65,0x66,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x25, // 25 + + // Turn_left_2 + 0x00,0x00,0xC1,0x11, // 0x0000C111 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x26,0x00,0x01, // 11 ,38 ,0 ,1 + 0x54,0x75,0x72,0x6E,0x20,0x6C,0x65,0x66,0x74,0x20,0x32,0x00,0x00,0x00,0x00,0x00, + 0x26, // 26 + + // Empty + 0x00,0x00,0xD1,0x11, // 0x0000D111 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x21,0x00,0x01, // 11 ,33 ,0 ,1 + 0x45,0x6D,0x70,0x74,0x79,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x21, // 21 + + // Backward + 0x00,0x00,0xE1,0x11, // 0x0000E111 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x2D,0x00,0x01, // 11 ,45 ,0 ,1 + 0x42,0x61,0x63,0x6B,0x77,0x61,0x72,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x2D, // 2D + + // Backward_5 + 0x00,0x00,0xF1,0x11, // 0x0000F111 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x2E,0x00,0x01, // 11 ,46 ,0 ,1 + 0x42,0x61,0x63,0x6B,0x77,0x61,0x72,0x64,0x20,0x35,0x00,0x00,0x00,0x00,0x00,0x00, + 0x2E, // 2E + + // Empty + 0x00,0x01,0x11,0x11, // 0x00011111 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x41,0x00,0x01, // 11 ,65 ,0 ,1 + 0x45,0x6D,0x70,0x74,0x79,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x21, // 21 + + // Wait_2 + 0x00,0x02,0x11,0x11, // 0x00021111 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x46,0x00,0x01, // 11 ,70 ,0 ,1 + 0x57,0x61,0x69,0x74,0x20,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x46, // 46 + + // Wait_5 + 0x00,0x03,0x11,0x11, // 0x00031111 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x47,0x00,0x01, // 11 ,71 ,0 ,1 + 0x57,0x61,0x69,0x74,0x20,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x47, // 47 + + // Wait_10 + 0x00,0x04,0x11,0x11, // 0x00041111 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x48,0x00,0x01, // 11 ,72 ,0 ,1 + 0x57,0x61,0x69,0x74,0x20,0x31,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x48, // 48 + + // Object + 0x00,0x05,0x11,0x11, // 0x00051111 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x43,0x00,0x01, // 11 ,67 ,0 ,1 + 0x4F,0x62,0x6A,0x65,0x63,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x43, // 43 + + // Sound + 0x00,0x06,0x11,0x11, // 0x00061111 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x44,0x00,0x01, // 11 ,68 ,0 ,1 + 0x53,0x6F,0x75,0x6E,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x44, // 44 + + // Light + 0x00,0x07,0x11,0x11, // 0x00071111 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x42,0x00,0x01, // 11 ,66 ,0 ,1 + 0x4C,0x69,0x67,0x68,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x42, // 42 + + // Dark + 0x00,0x08,0x11,0x11, // 0x00081111 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x49,0x00,0x01, // 11 ,73 ,0 ,1 + 0x44,0x61,0x72,0x6B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x49, // 49 + + // Touch + 0x00,0x09,0x11,0x11, // 0x00091111 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0x45,0x00,0x01, // 11 ,69 ,0 ,1 + 0x54,0x6F,0x75,0x63,0x68,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x45, // 45 + + // Stop + 0x00,0x11,0x11,0x11, // 0x00111111 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0xFB,0x00,0x01, // 11 ,251,0 ,1 + 0x53,0x74,0x6F,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x4D, // 4D + + // Loop + 0x00,0x21,0x11,0x11, // 0x00211111 + 0x10,0x00,0x00,0x61, // 0x10000061 + 0x0B,0xFC,0x00,0x01, // 11 ,252,0 ,1 + 0x4C,0x6F,0x6F,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x4E, // 4E + + // Run + 0x01,0x11,0x11,0x11, // 0x01111111 + 0x00,0x00,0x00,0x60, // 0x00000060 + 0x0B,0xF8,0x00,0x00, // 11 ,248,0 ,0 + 0x52,0x75,0x6E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x32, // 32 + + // Main_menu + 0x02,0x11,0x11,0x11, // 0x02111111 + 0x00,0x00,0x20,0x60, // 0x00002060 + 0x00,0x00,0x00,0x00, // 0 ,0 ,0 ,0 + 0x4D,0x61,0x69,0x6E,0x20,0x6D,0x65,0x6E,0x75,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x37, // 37 + + // Save + 0x04,0x11,0x11,0x11, // 0x04111111 + 0x00,0x00,0x00,0x60, // 0x00000060 + 0x0B,0xFA,0x00,0x02, // 11 ,250,0 ,2 + 0x53,0x61,0x76,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x1D, // 1D + + // Yes + 0x14,0x11,0x11,0x11, // 0x14111111 + 0x00,0x00,0x20,0x20, // 0x00002020 + 0x0B,0xED,0x00,0x00, // 11 ,237,0 ,0 + 0x59,0x65,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x31, // 31 + + // No + 0x24,0x11,0x11,0x11, // 0x24111111 + 0x00,0x08,0x00,0x24, // 0x00080024 + 0x0B,0xF6,0x00,0x00, // 11 ,246,0 ,0 + 0x4E,0x6F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x30, // 30 +}; diff --git a/src/Submenu03.rms b/src/Submenu03.rms new file mode 100644 index 0000000..cb7830b --- /dev/null +++ b/src/Submenu03.rms @@ -0,0 +1,233 @@ +const UBYTE SUBMENU03[] = +{ + 0x07,0x00, // Menu Format + 0x03,0xA0, // Menu DataSize + 0x1D, // Menu item size + 0x20, // Menu items + 0x18, // Menu icon Width + 0x18, // Menu icon Height + + // Temperature_`C + 0x00,0x00,0x00,0x01, // 0x00000001 + 0x10,0x00,0x00,0x21, // 0x10000021 + 0x0A,0x0B,0x00,0x01, // 10 ,11 ,0 ,1 + 0x54,0x65,0x6D,0x70,0x65,0x72,0x61,0x74,0x75,0x72,0x65,0x20,0x60,0x43,0x00,0x00, + 0x0F, // 0F + + // Temperature_`F + 0x00,0x00,0x00,0x02, // 0x00000002 + 0x10,0x00,0x00,0x21, // 0x10000021 + 0x0A,0x0C,0x00,0x01, // 10 ,12 ,0 ,1 + 0x54,0x65,0x6D,0x70,0x65,0x72,0x61,0x74,0x75,0x72,0x65,0x20,0x60,0x46,0x00,0x00, + 0x10, // 10 + + // Sound_dB + 0x00,0x00,0x00,0x03, // 0x00000003 + 0x10,0x00,0x00,0x21, // 0x10000021 + 0x0A,0x02,0x00,0x01, // 10 ,2 ,0 ,1 + 0x53,0x6F,0x75,0x6E,0x64,0x20,0x64,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x02, // 02 + + // Sound_dBA + 0x00,0x00,0x00,0x04, // 0x00000004 + 0x10,0x00,0x00,0x21, // 0x10000021 + 0x0A,0x03,0x00,0x01, // 10 ,3 ,0 ,1 + 0x53,0x6F,0x75,0x6E,0x64,0x20,0x64,0x42,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x03, // 03 + + // Reflected_light + 0x00,0x00,0x00,0x05, // 0x00000005 + 0x10,0x00,0x00,0x21, // 0x10000021 + 0x0A,0x04,0x00,0x01, // 10 ,4 ,0 ,1 + 0x52,0x65,0x66,0x6C,0x65,0x63,0x74,0x65,0x64,0x20,0x6C,0x69,0x67,0x68,0x74,0x00, + 0x04, // 04 + + // Ambient_light + 0x00,0x00,0x00,0x06, // 0x00000006 + 0x10,0x00,0x00,0x21, // 0x10000021 + 0x0A,0x05,0x00,0x01, // 10 ,5 ,0 ,1 + 0x41,0x6D,0x62,0x69,0x65,0x6E,0x74,0x20,0x6C,0x69,0x67,0x68,0x74,0x00,0x00,0x00, + 0x05, // 05 + + // Motor_Rotations + 0x00,0x00,0x00,0x07, // 0x00000007 + 0x00,0x00,0x00,0x20, // 0x00000020 + 0x0A,0x08,0x00,0x01, // 10 ,8 ,0 ,1 + 0x4D,0x6F,0x74,0x6F,0x72,0x20,0x52,0x6F,0x74,0x61,0x74,0x69,0x6F,0x6E,0x73,0x00, + 0x09, // 09 + + // Motor_Degrees + 0x00,0x00,0x00,0x08, // 0x00000008 + 0x00,0x00,0x00,0x20, // 0x00000020 + 0x0A,0x07,0x00,0x01, // 10 ,7 ,0 ,1 + 0x4D,0x6F,0x74,0x6F,0x72,0x20,0x44,0x65,0x67,0x72,0x65,0x65,0x73,0x00,0x00,0x00, + 0x08, // 08 + + // Touch + 0x00,0x00,0x00,0x09, // 0x00000009 + 0x10,0x00,0x00,0x21, // 0x10000021 + 0x0A,0x06,0x00,0x01, // 10 ,6 ,0 ,1 + 0x54,0x6F,0x75,0x63,0x68,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x07, // 07 + + // UltraSonic_inch + 0x00,0x00,0x00,0x0A, // 0x0000000A + 0x10,0x00,0x00,0x21, // 0x10000021 + 0x0A,0x09,0x00,0x01, // 10 ,9 ,0 ,1 + 0x55,0x6C,0x74,0x72,0x61,0x53,0x6F,0x6E,0x69,0x63,0x20,0x69,0x6E,0x63,0x68,0x00, + 0x0B, // 0B + + // UltraSonic_cm + 0x00,0x00,0x00,0x0B, // 0x0000000B + 0x10,0x00,0x00,0x21, // 0x10000021 + 0x0A,0x0A,0x00,0x01, // 10 ,10 ,0 ,1 + 0x55,0x6C,0x74,0x72,0x61,0x53,0x6F,0x6E,0x69,0x63,0x20,0x63,0x6D,0x00,0x00,0x00, + 0x0C, // 0C + + // Color + 0x00,0x00,0x00,0x0C, // 0x0000000C + 0x10,0x00,0x00,0x21, // 0x10000021 + 0x0A,0x0D,0x00,0x01, // 10 ,13 ,0 ,1 + 0x43,0x6F,0x6C,0x6F,0x72,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x11, // 11 + + // Done + 0x00,0x00,0x00,0x0D, // 0x0000000D + 0x00,0x00,0x00,0x20, // 0x00000020 + 0x0A,0xEE,0x00,0x01, // 10 ,238,0 ,1 + 0x44,0x6F,0x6E,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x31, // 31 + + // Port_1 + 0x00,0x00,0x00,0x11, // 0x00000011 + 0x10,0x00,0x00,0x21, // 0x10000021 + 0x0A,0x12,0x00,0x01, // 10 ,18 ,0 ,1 + 0x50,0x6F,0x72,0x74,0x20,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x12, // 12 + + // Port_2 + 0x00,0x00,0x00,0x21, // 0x00000021 + 0x10,0x00,0x00,0x21, // 0x10000021 + 0x0A,0x13,0x00,0x01, // 10 ,19 ,0 ,1 + 0x50,0x6F,0x72,0x74,0x20,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x13, // 13 + + // Port_3 + 0x00,0x00,0x00,0x31, // 0x00000031 + 0x10,0x00,0x00,0x21, // 0x10000021 + 0x0A,0x14,0x00,0x01, // 10 ,20 ,0 ,1 + 0x50,0x6F,0x72,0x74,0x20,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x14, // 14 + + // Port_4 + 0x00,0x00,0x00,0x41, // 0x00000041 + 0x10,0x00,0x00,0x21, // 0x10000021 + 0x0A,0x15,0x00,0x01, // 10 ,21 ,0 ,1 + 0x50,0x6F,0x72,0x74,0x20,0x34,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x15, // 15 + + // Port_A + 0x00,0x00,0x00,0x17, // 0x00000017 + 0x10,0x00,0x00,0x21, // 0x10000021 + 0x0A,0x16,0x00,0x01, // 10 ,22 ,0 ,1 + 0x50,0x6F,0x72,0x74,0x20,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x16, // 16 + + // Port_B + 0x00,0x00,0x00,0x27, // 0x00000027 + 0x10,0x00,0x00,0x21, // 0x10000021 + 0x0A,0x17,0x00,0x01, // 10 ,23 ,0 ,1 + 0x50,0x6F,0x72,0x74,0x20,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x17, // 17 + + // Port_C + 0x00,0x00,0x00,0x37, // 0x00000037 + 0x10,0x00,0x00,0x21, // 0x10000021 + 0x0A,0x18,0x00,0x01, // 10 ,24 ,0 ,1 + 0x50,0x6F,0x72,0x74,0x20,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x18, // 18 + + // Port_A + 0x00,0x00,0x00,0x18, // 0x00000018 + 0x10,0x00,0x00,0x21, // 0x10000021 + 0x0A,0x16,0x00,0x01, // 10 ,22 ,0 ,1 + 0x50,0x6F,0x72,0x74,0x20,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x16, // 16 + + // Port_B + 0x00,0x00,0x00,0x28, // 0x00000028 + 0x10,0x00,0x00,0x21, // 0x10000021 + 0x0A,0x17,0x00,0x01, // 10 ,23 ,0 ,1 + 0x50,0x6F,0x72,0x74,0x20,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x17, // 17 + + // Port_C + 0x00,0x00,0x00,0x38, // 0x00000038 + 0x10,0x00,0x00,0x21, // 0x10000021 + 0x0A,0x18,0x00,0x01, // 10 ,24 ,0 ,1 + 0x50,0x6F,0x72,0x74,0x20,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x17, // 17 + + // _ + 0x00,0x00,0x00,0x1D, // 0x0000001D + 0x00,0x00,0x10,0x00, // 0x00001000 + 0x0A,0xF7,0x00,0x01, // 10 ,247,0 ,1 + 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00, // 00 + + // _ + 0x00,0x00,0x01,0x11, // 0x00000111 + 0x0D,0x05,0x10,0x00, // 0x0D051000 + 0x0A,0xF2,0x00,0x00, // 10 ,242,0 ,0 + 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00, // 00 + + // _ + 0x00,0x00,0x01,0x17, // 0x00000117 + 0x0D,0x05,0x10,0x00, // 0x0D051000 + 0x0A,0xF2,0x00,0x00, // 10 ,242,0 ,0 + 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00, // 00 + + // _ + 0x00,0x00,0x01,0x18, // 0x00000118 + 0x0D,0x05,0x10,0x00, // 0x0D051000 + 0x0A,0xF2,0x00,0x00, // 10 ,242,0 ,0 + 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00, // 00 + + // Run + 0x00,0x00,0x01,0x1D, // 0x0000011D + 0x00,0x00,0x00,0x68, // 0x00000068 + 0x0A,0xF8,0x00,0x02, // 10 ,248,0 ,2 + 0x52,0x75,0x6E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x32, // 32 + + // Main_menu + 0x00,0x00,0x11,0x1D, // 0x0000111D + 0x00,0x02,0x20,0x00, // 0x00022000 + 0x0A,0xF1,0x00,0x00, // 10 ,241,0 ,0 + 0x4D,0x61,0x69,0x6E,0x20,0x6D,0x65,0x6E,0x75,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x37, // 37 + + // Save + 0x00,0x00,0x21,0x1D, // 0x0000211D + 0x00,0x02,0x00,0x00, // 0x00020000 + 0x0A,0xFA,0x00,0x02, // 10 ,250,0 ,2 + 0x53,0x61,0x76,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x1F, // 1F + + // Yes + 0x00,0x01,0x21,0x1D, // 0x0001211D + 0x00,0x00,0x20,0x20, // 0x00002020 + 0x0A,0xED,0x00,0x00, // 10 ,237,0 ,0 + 0x59,0x65,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x31, // 31 + + // No + 0x00,0x02,0x21,0x1D, // 0x0002211D + 0x00,0x08,0x00,0x24, // 0x00080024 + 0x00,0x00,0x00,0x00, // 0 ,0 ,0 ,0 + 0x4E,0x6F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x30, // 30 +}; diff --git a/src/Submenu04.rms b/src/Submenu04.rms new file mode 100644 index 0000000..273e456 --- /dev/null +++ b/src/Submenu04.rms @@ -0,0 +1,163 @@ +const UBYTE SUBMENU04[] = +{ + 0x07,0x00, // Menu Format + 0x02,0x7E, // Menu DataSize + 0x1D, // Menu item size + 0x16, // Menu items + 0x18, // Menu icon Width + 0x18, // Menu icon Height + + // Sound_dB + 0x00,0x00,0x00,0x01, // 0x00000001 + 0x10,0x00,0x00,0x21, // 0x10000021 + 0x0E,0x02,0x00,0x01, // 14 ,2 ,0 ,1 + 0x53,0x6F,0x75,0x6E,0x64,0x20,0x64,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x02, // 02 + + // Sound_dBA + 0x00,0x00,0x00,0x02, // 0x00000002 + 0x10,0x00,0x00,0x21, // 0x10000021 + 0x0E,0x03,0x00,0x01, // 14 ,3 ,0 ,1 + 0x53,0x6F,0x75,0x6E,0x64,0x20,0x64,0x42,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x03, // 03 + + // Reflected_light + 0x00,0x00,0x00,0x03, // 0x00000003 + 0x10,0x00,0x00,0x21, // 0x10000021 + 0x0E,0x04,0x00,0x01, // 14 ,4 ,0 ,1 + 0x52,0x65,0x66,0x6C,0x65,0x63,0x74,0x65,0x64,0x20,0x6C,0x69,0x67,0x68,0x74,0x00, + 0x04, // 04 + + // Ambient_light + 0x00,0x00,0x00,0x04, // 0x00000004 + 0x10,0x00,0x00,0x21, // 0x10000021 + 0x0E,0x05,0x00,0x01, // 14 ,5 ,0 ,1 + 0x41,0x6D,0x62,0x69,0x65,0x6E,0x74,0x20,0x6C,0x69,0x67,0x68,0x74,0x00,0x00,0x00, + 0x05, // 05 + + // Temperature_`C + 0x00,0x00,0x00,0x05, // 0x00000005 + 0x10,0x00,0x01,0x21, // 0x10000121 + 0x0E,0x0B,0x00,0x01, // 14 ,11 ,0 ,1 + 0x54,0x65,0x6D,0x70,0x65,0x72,0x61,0x74,0x75,0x72,0x65,0x20,0x60,0x43,0x00,0x00, + 0x0F, // 0F + + // Temperature_`F + 0x00,0x00,0x00,0x06, // 0x00000006 + 0x10,0x00,0x00,0x21, // 0x10000021 + 0x0E,0x0C,0x00,0x01, // 14 ,12 ,0 ,1 + 0x54,0x65,0x6D,0x70,0x65,0x72,0x61,0x74,0x75,0x72,0x65,0x20,0x60,0x46,0x00,0x00, + 0x10, // 10 + + // Motor_rotations + 0x00,0x00,0x00,0x07, // 0x00000007 + 0x00,0x00,0x00,0x20, // 0x00000020 + 0x0E,0x08,0x00,0x01, // 14 ,8 ,0 ,1 + 0x4D,0x6F,0x74,0x6F,0x72,0x20,0x72,0x6F,0x74,0x61,0x74,0x69,0x6F,0x6E,0x73,0x00, + 0x09, // 09 + + // Motor_degrees + 0x00,0x00,0x00,0x08, // 0x00000008 + 0x00,0x00,0x00,0x20, // 0x00000020 + 0x0E,0x07,0x00,0x01, // 14 ,7 ,0 ,1 + 0x4D,0x6F,0x74,0x6F,0x72,0x20,0x64,0x65,0x67,0x72,0x65,0x65,0x73,0x00,0x00,0x00, + 0x08, // 08 + + // Touch + 0x00,0x00,0x00,0x09, // 0x00000009 + 0x10,0x00,0x00,0x21, // 0x10000021 + 0x0E,0x06,0x00,0x01, // 14 ,6 ,0 ,1 + 0x54,0x6F,0x75,0x63,0x68,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x07, // 07 + + // Ultrasonic_inch + 0x00,0x00,0x00,0x0A, // 0x0000000A + 0x10,0x00,0x00,0x21, // 0x10000021 + 0x0E,0x09,0x00,0x01, // 14 ,9 ,0 ,1 + 0x55,0x6C,0x74,0x72,0x61,0x73,0x6F,0x6E,0x69,0x63,0x20,0x69,0x6E,0x63,0x68,0x00, + 0x0B, // 0B + + // Ultrasonic_cm + 0x00,0x00,0x00,0x0B, // 0x0000000B + 0x10,0x00,0x00,0x21, // 0x10000021 + 0x0E,0x0A,0x00,0x01, // 14 ,10 ,0 ,1 + 0x55,0x6C,0x74,0x72,0x61,0x73,0x6F,0x6E,0x69,0x63,0x20,0x63,0x6D,0x00,0x00,0x00, + 0x0C, // 0C + + // Color + 0x00,0x00,0x00,0x0C, // 0x0000000C + 0x10,0x00,0x00,0x21, // 0x10000021 + 0x0E,0x0D,0x00,0x01, // 14 ,13 ,0 ,1 + 0x43,0x6F,0x6C,0x6F,0x72,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x11, // 11 + + // Port_1 + 0x00,0x00,0x00,0x11, // 0x00000011 + 0x00,0x00,0x00,0x20, // 0x00000020 + 0x0E,0x12,0x00,0x00, // 14 ,18 ,0 ,0 + 0x50,0x6F,0x72,0x74,0x20,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x12, // 12 + + // Port_2 + 0x00,0x00,0x00,0x21, // 0x00000021 + 0x00,0x00,0x00,0x20, // 0x00000020 + 0x0E,0x13,0x00,0x00, // 14 ,19 ,0 ,0 + 0x50,0x6F,0x72,0x74,0x20,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x13, // 13 + + // Port_3 + 0x00,0x00,0x00,0x31, // 0x00000031 + 0x00,0x00,0x00,0x20, // 0x00000020 + 0x0E,0x14,0x00,0x00, // 14 ,20 ,0 ,0 + 0x50,0x6F,0x72,0x74,0x20,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x14, // 14 + + // Port_4 + 0x00,0x00,0x00,0x41, // 0x00000041 + 0x00,0x00,0x00,0x20, // 0x00000020 + 0x0E,0x15,0x00,0x00, // 14 ,21 ,0 ,0 + 0x50,0x6F,0x72,0x74,0x20,0x34,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x15, // 15 + + // Port_A + 0x00,0x00,0x00,0x17, // 0x00000017 + 0x00,0x00,0x00,0x20, // 0x00000020 + 0x0E,0x16,0x00,0x00, // 14 ,22 ,0 ,0 + 0x50,0x6F,0x72,0x74,0x20,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x16, // 16 + + // Port_B + 0x00,0x00,0x00,0x27, // 0x00000027 + 0x00,0x00,0x00,0x20, // 0x00000020 + 0x0E,0x17,0x00,0x00, // 14 ,23 ,0 ,0 + 0x50,0x6F,0x72,0x74,0x20,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x17, // 17 + + // Port_C + 0x00,0x00,0x00,0x37, // 0x00000037 + 0x00,0x00,0x00,0x20, // 0x00000020 + 0x0E,0x18,0x00,0x00, // 14 ,24 ,0 ,0 + 0x50,0x6F,0x72,0x74,0x20,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x18, // 18 + + // Port_A + 0x00,0x00,0x00,0x18, // 0x00000018 + 0x00,0x00,0x00,0x20, // 0x00000020 + 0x0E,0x16,0x00,0x00, // 14 ,22 ,0 ,0 + 0x50,0x6F,0x72,0x74,0x20,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x16, // 16 + + // Port_B + 0x00,0x00,0x00,0x28, // 0x00000028 + 0x00,0x00,0x00,0x20, // 0x00000020 + 0x0E,0x17,0x00,0x00, // 14 ,23 ,0 ,0 + 0x50,0x6F,0x72,0x74,0x20,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x17, // 17 + + // Port_C + 0x00,0x00,0x00,0x38, // 0x00000038 + 0x00,0x00,0x00,0x20, // 0x00000020 + 0x0E,0x18,0x00,0x00, // 14 ,24 ,0 ,0 + 0x50,0x6F,0x72,0x74,0x20,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x18, // 18 +}; diff --git a/src/Submenu05.rms b/src/Submenu05.rms new file mode 100644 index 0000000..5e03396 --- /dev/null +++ b/src/Submenu05.rms @@ -0,0 +1,128 @@ +const UBYTE SUBMENU05[] = +{ + 0x07,0x00, // Menu Format + 0x01,0xED, // Menu DataSize + 0x1D, // Menu item size + 0x11, // Menu items + 0x18, // Menu icon Width + 0x18, // Menu icon Height + + // Volume + 0x00,0x00,0x00,0x01, // 0x00000001 + 0x00,0x00,0x80,0x00, // 0x00008000 + 0x00,0x00,0x00,0x01, // 0 ,0 ,0 ,1 + 0x56,0x6F,0x6C,0x75,0x6D,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x39, // 39 + + // Sleep + 0x00,0x00,0x00,0x02, // 0x00000002 + 0x00,0x00,0x80,0x00, // 0x00008000 + 0x00,0x00,0x00,0x01, // 0 ,0 ,0 ,1 + 0x53,0x6C,0x65,0x65,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x3A, // 3A + + // NXT_Version + 0x00,0x00,0x00,0x03, // 0x00000003 + 0x00,0x00,0x00,0x00, // 0x00000000 + 0x01,0x00,0x00,0x00, // 1 ,0 ,0 ,0 + 0x4E,0x58,0x54,0x20,0x56,0x65,0x72,0x73,0x69,0x6F,0x6E,0x00,0x00,0x00,0x00,0x00, + 0x4F, // 4F + + // Delete_files + 0x00,0x00,0x00,0x04, // 0x00000004 + 0x00,0x00,0x80,0x00, // 0x00008000 + 0x00,0x00,0x00,0x01, // 0 ,0 ,0 ,1 + 0x44,0x65,0x6C,0x65,0x74,0x65,0x20,0x66,0x69,0x6C,0x65,0x73,0x00,0x00,0x00,0x00, + 0x34, // 34 + + // _ + 0x00,0x00,0x00,0x11, // 0x00000011 + 0x00,0x00,0x03,0x60, // 0x00000360 + 0x07,0xEF,0x00,0x00, // 7 ,239,0 ,0 + 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x39, // 39 + + // _ + 0x00,0x00,0x00,0x21, // 0x00000021 + 0x00,0x00,0x00,0x00, // 0x00000000 + 0x00,0x00,0x00,0x00, // 0 ,0 ,0 ,0 + 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x35, // 35 + + // _ + 0x00,0x00,0x00,0x31, // 0x00000031 + 0x00,0x00,0x00,0x00, // 0x00000000 + 0x00,0x00,0x00,0x00, // 0 ,0 ,0 ,0 + 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x36, // 36 + + // _ + 0x00,0x00,0x00,0x12, // 0x00000012 + 0x00,0x00,0x03,0x20, // 0x00000320 + 0x04,0xEF,0x00,0x00, // 4 ,239,0 ,0 + 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x3A, // 3A + + // _ + 0x00,0x00,0x00,0x22, // 0x00000022 + 0x00,0x00,0x00,0x00, // 0x00000000 + 0x00,0x00,0x00,0x00, // 0 ,0 ,0 ,0 + 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x35, // 35 + + // _ + 0x00,0x00,0x00,0x32, // 0x00000032 + 0x00,0x00,0x00,0x00, // 0x00000000 + 0x00,0x00,0x00,0x00, // 0 ,0 ,0 ,0 + 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x36, // 36 + + // Software_files + 0x00,0x00,0x00,0x14, // 0x00000014 + 0x10,0x00,0x00,0x01, // 0x10000001 + 0x05,0x02,0x00,0x02, // 5 ,2 ,0 ,2 + 0x53,0x6F,0x66,0x74,0x77,0x61,0x72,0x65,0x20,0x66,0x69,0x6C,0x65,0x73,0x00,0x00, + 0x1C, // 1C + + // NXT_files + 0x00,0x00,0x00,0x24, // 0x00000024 + 0x10,0x00,0x00,0x01, // 0x10000001 + 0x05,0x03,0x00,0x02, // 5 ,3 ,0 ,2 + 0x4E,0x58,0x54,0x20,0x66,0x69,0x6C,0x65,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x1D, // 1D + + // Sound_files + 0x00,0x00,0x00,0x34, // 0x00000034 + 0x10,0x00,0x00,0x01, // 0x10000001 + 0x05,0x01,0x00,0x02, // 5 ,1 ,0 ,2 + 0x53,0x6F,0x75,0x6E,0x64,0x20,0x66,0x69,0x6C,0x65,0x73,0x00,0x00,0x00,0x00,0x00, + 0x1B, // 1B + + // Datalog_files + 0x00,0x00,0x00,0x44, // 0x00000044 + 0x10,0x80,0x00,0x01, // 0x10800001 + 0x05,0x05,0x00,0x02, // 5 ,5 ,0 ,2 + 0x44,0x61,0x74,0x61,0x6C,0x6F,0x67,0x20,0x66,0x69,0x6C,0x65,0x73,0x00,0x00,0x00, + 0x1F, // 1F + + // Try_me_files + 0x00,0x00,0x00,0x54, // 0x00000054 + 0x10,0x00,0x00,0x01, // 0x10000001 + 0x05,0x04,0x00,0x02, // 5 ,4 ,0 ,2 + 0x54,0x72,0x79,0x20,0x6D,0x65,0x20,0x66,0x69,0x6C,0x65,0x73,0x00,0x00,0x00,0x00, + 0x1E, // 1E + + // Are_you_sure? + 0x00,0x00,0x01,0x14, // 0x00000114 + 0x00,0x00,0x01,0x08, // 0x00000108 + 0x05,0xF1,0x00,0x00, // 5 ,241,0 ,0 + 0x41,0x72,0x65,0x20,0x79,0x6F,0x75,0x20,0x73,0x75,0x72,0x65,0x3F,0x00,0x00,0x00, + 0x31, // 31 + + // Are_you_sure? + 0x00,0x00,0x02,0x14, // 0x00000214 + 0x00,0x00,0x01,0x04, // 0x00000104 + 0x05,0x00,0x00,0x00, // 5 ,0 ,0 ,0 + 0x41,0x72,0x65,0x20,0x79,0x6F,0x75,0x20,0x73,0x75,0x72,0x65,0x3F,0x00,0x00,0x00, + 0x30, // 30 +}; diff --git a/src/Submenu06.rms b/src/Submenu06.rms new file mode 100644 index 0000000..5cd1b06 --- /dev/null +++ b/src/Submenu06.rms @@ -0,0 +1,51 @@ +const UBYTE SUBMENU06[] = +{ + 0x07,0x00, // Menu Format + 0x00,0xAE, // Menu DataSize + 0x1D, // Menu item size + 0x06, // Menu items + 0x18, // Menu icon Width + 0x18, // Menu icon Height + + // _ + 0x00,0x00,0x00,0x01, // 0x00000001 + 0x00,0x00,0x10,0x00, // 0x00001000 + 0x06,0x04,0x00,0x01, // 6 ,4 ,0 ,1 + 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x1E, // 1E + + // _ + 0x00,0x00,0x00,0x11, // 0x00000011 + 0x00,0x00,0x03,0x80, // 0x00000380 + 0x06,0xF2,0x00,0x02, // 6 ,242,0 ,2 + 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x1E, // 1E + + // Delete + 0x00,0x00,0x01,0x11, // 0x00000111 + 0x00,0x00,0x00,0x00, // 0x00000000 + 0x00,0x00,0x00,0x02, // 0 ,0 ,0 ,2 + 0x44,0x65,0x6C,0x65,0x74,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x34, // 34 + + // Run + 0x00,0x00,0x02,0x11, // 0x00000211 + 0x00,0x00,0x01,0x20, // 0x00000120 + 0x08,0xF8,0x00,0x00, // 8 ,248,0 ,0 + 0x52,0x75,0x6E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x32, // 32 + + // Are_you_sure? + 0x00,0x00,0x11,0x11, // 0x00001111 + 0x00,0x00,0x00,0x08, // 0x00000008 + 0x09,0x00,0x00,0x00, // 9 ,0 ,0 ,0 + 0x41,0x72,0x65,0x20,0x79,0x6F,0x75,0x20,0x73,0x75,0x72,0x65,0x3F,0x00,0x00,0x00, + 0x31, // 31 + + // Are_you_sure? + 0x00,0x00,0x21,0x11, // 0x00002111 + 0x00,0x00,0x00,0x04, // 0x00000004 + 0x00,0x00,0x00,0x00, // 0 ,0 ,0 ,0 + 0x41,0x72,0x65,0x20,0x79,0x6F,0x75,0x20,0x73,0x75,0x72,0x65,0x3F,0x00,0x00,0x00, + 0x30, // 30 +}; diff --git a/src/Submenu07.rms b/src/Submenu07.rms new file mode 100644 index 0000000..43c292e --- /dev/null +++ b/src/Submenu07.rms @@ -0,0 +1,142 @@ +const UBYTE SUBMENU07[] = +{ + 0x07,0x00, // Menu Format + 0x02,0x27, // Menu DataSize + 0x1D, // Menu item size + 0x13, // Menu items + 0x18, // Menu icon Width + 0x18, // Menu icon Height + + // Search + 0x00,0x00,0x00,0x01, // 0x00000001 + 0x00,0x40,0x80,0x00, // 0x00408000 + 0x00,0x00,0x00,0x01, // 0 ,0 ,0 ,1 + 0x53,0x65,0x61,0x72,0x63,0x68,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x56, // 56 + + // My_contacts + 0x00,0x00,0x00,0x02, // 0x00000002 + 0x00,0x40,0x80,0x00, // 0x00408000 + 0x00,0x00,0x00,0x01, // 0 ,0 ,0 ,1 + 0x4D,0x79,0x20,0x63,0x6F,0x6E,0x74,0x61,0x63,0x74,0x73,0x00,0x00,0x00,0x00,0x00, + 0x52, // 52 + + // Connections + 0x00,0x00,0x00,0x03, // 0x00000003 + 0x00,0x40,0x80,0x00, // 0x00408000 + 0x00,0x00,0x00,0x01, // 0 ,0 ,0 ,1 + 0x43,0x6F,0x6E,0x6E,0x65,0x63,0x74,0x69,0x6F,0x6E,0x73,0x00,0x00,0x00,0x00,0x00, + 0x53, // 53 + + // Visibility + 0x00,0x00,0x00,0x04, // 0x00000004 + 0x00,0x40,0x80,0x00, // 0x00408000 + 0x00,0x00,0x00,0x01, // 0 ,0 ,0 ,1 + 0x56,0x69,0x73,0x69,0x62,0x69,0x6C,0x69,0x74,0x79,0x00,0x00,0x00,0x00,0x00,0x00, + 0x54, // 54 + + // On/Off + 0x00,0x00,0x00,0x05, // 0x00000005 + 0x00,0x00,0x80,0x00, // 0x00008000 + 0x00,0x00,0x00,0x01, // 0 ,0 ,0 ,1 + 0x4F,0x6E,0x2F,0x4F,0x66,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x55, // 55 + + // _ + 0x00,0x00,0x00,0x11, // 0x00000011 + 0x00,0x00,0x03,0x00, // 0x00000300 + 0x12,0xFF,0x00,0x01, // 18 ,255,0 ,1 + 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x57, // 57 + + // _ + 0x00,0x00,0x00,0x12, // 0x00000012 + 0x00,0x00,0x10,0x00, // 0x00001000 + 0x00,0x00,0x00,0x01, // 0 ,0 ,0 ,1 + 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x57, // 57 + + // _ + 0x00,0x00,0x00,0x13, // 0x00000013 + 0x00,0x00,0x03,0x00, // 0x00000300 + 0x14,0xF6,0x00,0x01, // 20 ,246,0 ,1 + 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x57, // 57 + + // Visible + 0x00,0x00,0x00,0x14, // 0x00000014 + 0x00,0x00,0x00,0x00, // 0x00000000 + 0x11,0xEB,0x00,0x00, // 17 ,235,0 ,0 + 0x56,0x69,0x73,0x69,0x62,0x6C,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x5A, // 5A + + // Invisible + 0x00,0x00,0x00,0x24, // 0x00000024 + 0x00,0x00,0x00,0x00, // 0x00000000 + 0x11,0xEA,0x00,0x00, // 17 ,234,0 ,0 + 0x49,0x6E,0x76,0x69,0x73,0x69,0x62,0x6C,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x5B, // 5B + + // On + 0x00,0x00,0x00,0x15, // 0x00000015 + 0x00,0x00,0x00,0x80, // 0x00000080 + 0x03,0xEB,0x00,0x00, // 3 ,235,0 ,0 + 0x4F,0x6E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x5C, // 5C + + // Off + 0x00,0x00,0x00,0x25, // 0x00000025 + 0x00,0x40,0x00,0x80, // 0x00400080 + 0x03,0xEA,0x00,0x00, // 3 ,234,0 ,0 + 0x4F,0x66,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x5D, // 5D + + // _ + 0x00,0x00,0x01,0x11, // 0x00000111 + 0x00,0x00,0x03,0x08, // 0x00000308 + 0x13,0xF2,0x00,0x01, // 19 ,242,0 ,1 + 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x57, // 57 + + // _ + 0x00,0x00,0x01,0x12, // 0x00000112 + 0x00,0x10,0x02,0x08, // 0x00100208 + 0x13,0xF2,0x00,0x02, // 19 ,242,0 ,2 + 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x57, // 57 + + // Disconnect + 0x00,0x00,0x01,0x13, // 0x00000113 + 0x00,0x00,0x00,0x00, // 0x00000000 + 0x14,0xF0,0x00,0x00, // 20 ,240,0 ,0 + 0x44,0x69,0x73,0x63,0x6F,0x6E,0x6E,0x65,0x63,0x74,0x00,0x00,0x00,0x00,0x00,0x00, + 0x59, // 59 + + // _ + 0x00,0x00,0x11,0x11, // 0x00001111 + 0x00,0x00,0x03,0x00, // 0x00000300 + 0x10,0xF5,0x00,0x00, // 16 ,245,0 ,0 + 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x57, // 57 + + // Delete + 0x00,0x00,0x11,0x12, // 0x00001112 + 0x00,0x00,0x00,0x00, // 0x00000000 + 0x13,0xF1,0x00,0x00, // 19 ,241,0 ,0 + 0x44,0x65,0x6C,0x65,0x74,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x34, // 34 + + // Connect + 0x00,0x00,0x21,0x12, // 0x00002112 + 0x00,0x00,0x00,0x00, // 0x00000000 + 0x00,0x00,0x00,0x01, // 0 ,0 ,0 ,1 + 0x43,0x6F,0x6E,0x6E,0x65,0x63,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x58, // 58 + + // _ + 0x00,0x01,0x21,0x12, // 0x00012112 + 0x00,0x00,0x03,0x08, // 0x00000308 + 0x10,0xF5,0x00,0x00, // 16 ,245,0 ,0 + 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x57, // 57 +}; diff --git a/src/Test1.txt b/src/Test1.txt new file mode 100644 index 0000000..018d27d --- /dev/null +++ b/src/Test1.txt @@ -0,0 +1,19 @@ +DEFINE_DATA(BMPMAP, Test1) = +{ + 0x02,0x00, // Graphics Format + 0x04,0x00, // Graphics DataSize + 0x00, // Graphics Start X + 0x00, // Graphics Start Y + 0x80, // Graphics Width + 0x40, // Graphics Height +BEGIN_DATA + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +END_DATA +}; diff --git a/src/Test2.txt b/src/Test2.txt new file mode 100644 index 0000000..2553335 --- /dev/null +++ b/src/Test2.txt @@ -0,0 +1,19 @@ +DEFINE_DATA(BMPMAP, Test2) = +{ + 0x02,0x00, // Graphics Format + 0x04,0x00, // Graphics DataSize + 0x00, // Graphics Start X + 0x00, // Graphics Start Y + 0x80, // Graphics Width + 0x40, // Graphics Height +BEGIN_DATA + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +END_DATA +}; diff --git a/src/Ui.txt b/src/Ui.txt new file mode 100644 index 0000000..2cf47aa --- /dev/null +++ b/src/Ui.txt @@ -0,0 +1,72 @@ +DEFINE_DATA(TXT, Ui) = +{ + 0x05,0x00, // Text Format + 0x04,0x0D, // Text DataSize + 0x01, // ItemsX + 0x3D, // ItemsY + 0x11, // ItemCharsX + 0x01, // ItemCharsY +BEGIN_DATA + 'C','o','n','n','e','c','t','i','n','g', 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'L','i','n','e',' ','i','s',' ','b','u','s','y', 0 , 0 , 0 , 0 , 0 , + 'F','a','i','l','e','d','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'C','o','n','n','e','c','t','i','o','n','?', 0 , 0 , 0 , 0 , 0 , 0 , + 'S','e','n','d','i','n','g',' ','f','i','l','e', 0 , 0 , 0 , 0 , 0 , + 'F','a','i','l','e','d','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'T','u','r','n','i','n','g',' ','o','n', 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'F','a','i','l','e','d','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'T','u','r','n','i','n','g',' ','o','f','f', 0 , 0 , 0 , 0 , 0 , 0 , + 'F','a','i','l','e','d','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'S','e','a','r','c','h','i','n','g', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'A','b','o','r','t','e','d','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'F','a','i','l','e','d','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'F','a','i','l','e','d','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'F','a','i','l','e','d','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'M','e','m','o','r','y',' ','f','u','l','l','!', 0 , 0 , 0 , 0 , 0 , + 'F','i','l','e',' ','s','a','v','e','d', 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'F','i','l','e',' ','e','x','i','s','t','s', 0 , 0 , 0 , 0 , 0 , 0 , + 'o','v','e','r','w','r','i','t','e','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'S','a','v','e','d',' ','a','s', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'F','i','l','e',' ','e','x','i','s','t', 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'o','v','e','r','w','r','i','t','e','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'F','i','l','e',' ','d','e','l','e','t','e','d', 0 , 0 , 0 , 0 , 0 , + 'F','i','l','e','s', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'd','e','l','e','t','e','d', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'R','u','n','n','i','n','g', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'A','b','o','r','t','e','d','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'D','o','n','e', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'F','i','l','e',' ','e','r','r','o','r','!', 0 , 0 , 0 , 0 , 0 , 0 , + 'D','e','l','e','t','i','n','g',' ','a','l','l', 0 , 0 , 0 , 0 , 0 , + '%','s',' ','f','i','l','e','s','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'P','r','e','s','s',' ','C','l','e','a','r',' ','t','o', 0 , 0 , 0 , + 's','t','o','p',' ','D','a','t','a','L','o','g','g','i','n','g', 0 , + 'P','o','r','t',' ','o','c','c','u','p','i','e','d','!', 0 , 0 , 0 , + 'H',':','M','M',':','S','S',':','0','0', 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'H','H',':','M','M',':','S','S', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'S','o','u','n','d', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'S','o','f','t','w','a','r','e', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'N','X','T', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'T','r','y',' ','M','e', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'D','a','t','a','l','o','g', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'P','a','s','s','k','e','y',':', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'F','i','l','e',' ','n','a','m','e',':', 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'P','l','e','a','s','e',' ','u','s','e',' ','p','o','r','t',':', 0 , + '1',' ','-',' ','T','o','u','c','h',' ','S','e','n','s','o','r', 0 , + '2',' ','-',' ','S','o','u','n','d',' ','S','e','n','s','o','r', 0 , + '3',' ','-',' ','L','i','g','h','t',' ','S','e','n','s','o','r', 0 , + '4',' ','-',' ','U','l','t','r','a','s','o','n','i','c',' ',' ', 0 , + 'B','/','C',' ','-',' ','L','/','R',' ','m','o','t','o','r','s', 0 , + 'S','e','l','e','c','t', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'S','e','l','e','c','t', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'S','e','l','e','c','t', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'B','T',' ','s','a','v','e',' ','d','a','t','a', 0 , 0 , 0 , 0 , 0 , + 'e','r','r','o','r','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'B','T',' ','s','t','o','r','e',' ','i','s', 0 , 0 , 0 , 0 , 0 , 0 , + 'f','u','l','l',' ','e','r','r','o','r','!', 0 , 0 , 0 , 0 , 0 , 0 , + 'B','T',' ','u','n','k','n','o','w','n', 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'a','d','d','r','.',' ','e','r','r','o','r','!', 0 , 0 , 0 , 0 , 0 , + 'M','e','m','o','r','y',' ','i','s', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'f','u','l','l','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'N','e','v','e','r', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 +END_DATA +}; diff --git a/src/Wait.txt b/src/Wait.txt new file mode 100644 index 0000000..abdbd43 --- /dev/null +++ b/src/Wait.txt @@ -0,0 +1,14 @@ +DEFINE_DATA(BMPMAP, Wait) = +{ + 0x02,0x00, // Graphics Format + 0x00,0x48, // Graphics DataSize + 0x00, // Graphics Start X + 0x08, // Graphics Start Y + 0x18, // Graphics Width + 0x18, // Graphics Height +BEGIN_DATA + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC3,0x24,0x98,0xC2,0x98,0x24,0xC3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +END_DATA +}; diff --git a/src/c_button.c b/src/c_button.c new file mode 100644 index 0000000..3145d8f --- /dev/null +++ b/src/c_button.c @@ -0,0 +1,134 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: c_button.c $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_butt $ +// +// Platform C +// + +#include "stdconst.h" +#include "modules.h" +#include "c_button.h" +#include "c_button.iom" +#include "c_button.h" +#include "d_button.h" + +#define BTN_PRESCALER 2 + +enum +{ + LONG_TIME = (2000/BTN_PRESCALER) +}; + +static IOMAPBUTTON IOMapButton; +static VARSBUTTON VarsButton; +static UBYTE BtnCnt; + +const HEADER cButton = +{ + 0x00040001L, + "Button", + cButtonInit, + cButtonCtrl, + cButtonExit, + (void *)&IOMapButton, + (void *)&VarsButton, + (UWORD)sizeof(IOMapButton), + (UWORD)sizeof(VarsButton), + 0x0000 //Code size - not used so far +}; + + +void cButtonInit(void* pHeader) +{ + UBYTE Tmp; + + for (Tmp = 0; Tmp < NO_OF_BTNS; Tmp++) + { + IOMapButton.State[Tmp] = 0; + IOMapButton.BtnCnt[Tmp].PressedCnt = 0; + IOMapButton.BtnCnt[Tmp].LongPressCnt = 0; + IOMapButton.BtnCnt[Tmp].ShortRelCnt = 0; + IOMapButton.BtnCnt[Tmp].LongRelCnt = 0; + VarsButton.Cnt[Tmp] = 0; + } + VarsButton.OldState = 0; + BtnCnt = 0; + dButtonInit(BTN_PRESCALER); +} + +void cButtonCtrl(void) +{ + UBYTE ButtonState, Tmp, ButtonNo; + + for (Tmp = 0; Tmp < NO_OF_BTNS; Tmp++) + { + IOMapButton.State[Tmp] &= ~PRESSED_EV; + } + if (++BtnCnt >= BTN_PRESCALER) + { + BtnCnt = 0; + dButtonRead(&ButtonState); + + ButtonNo = 0x01; + for (Tmp = 0; Tmp < NO_OF_BTNS; Tmp++) + { + if (ButtonState & ButtonNo) + { + if (LONG_TIME >= (VarsButton.Cnt[Tmp])) + { + (VarsButton.Cnt[Tmp])++; + } + IOMapButton.State[Tmp] = PRESSED_STATE; + if (!((VarsButton.OldState) & ButtonNo)) + { + + /* Button just pressed */ + (IOMapButton.State[Tmp]) |= PRESSED_EV; + (IOMapButton.BtnCnt[Tmp].PressedCnt)++; + VarsButton.Cnt[Tmp] = 0; + } + else + { + if (LONG_TIME == VarsButton.Cnt[Tmp]) + { + IOMapButton.State[Tmp] |= LONG_PRESSED_EV; + (IOMapButton.BtnCnt[Tmp].LongPressCnt)++; + } + } + } + else + { + IOMapButton.State[Tmp] = 0x00; + if ((VarsButton.OldState) & ButtonNo) + { + if (VarsButton.Cnt[Tmp] > LONG_TIME) + { + IOMapButton.State[Tmp] = LONG_RELEASED_EV; + (IOMapButton.BtnCnt[Tmp].LongRelCnt)++; + + } + else + { + IOMapButton.State[Tmp] = SHORT_RELEASED_EV; + (IOMapButton.BtnCnt[Tmp].ShortRelCnt)++; + } + } + } + ButtonNo <<= 1; + IOMapButton.BtnCnt[Tmp].RelCnt = ((IOMapButton.BtnCnt[Tmp].ShortRelCnt) + (IOMapButton.BtnCnt[Tmp].LongRelCnt)); + } + VarsButton.OldState = ButtonState; + } +} + +void cButtonExit(void) +{ + dButtonExit(); +} diff --git a/src/c_button.h b/src/c_button.h new file mode 100644 index 0000000..c33b24d --- /dev/null +++ b/src/c_button.h @@ -0,0 +1,37 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: c_button.h $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_butt $ +// +// Platform C +// + +#ifndef C_BUTTON +#define C_BUTTON + +#ifdef INCLUDE_OS +extern const HEADER cButton; +#endif + +#include "c_button.iom" + + +typedef struct +{ + UWORD Cnt[NO_OF_BTNS]; + UBYTE OldState; +}VARSBUTTON; + +void cButtonInit(void* pHeader); +void cButtonCtrl(void); +void cButtonExit(void); + +extern const HEADER cButton; + +#endif diff --git a/src/c_button.iom b/src/c_button.iom new file mode 100644 index 0000000..640a7cd --- /dev/null +++ b/src/c_button.iom @@ -0,0 +1,61 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: c_button.iom $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_butt $ +// +// Platform C +// + +#ifndef CBUTTON_IOM +#define CBUTTON_IOM + +#define pMapButton ((IOMAPBUTTON*)(pHeaders[ENTRY_BUTTON]->pIOMap)) + +enum +{ + BTN1, + BTN2, + BTN3, + BTN4, + NO_OF_BTNS +}; + +/* Costants related to State */ +enum +{ + PRESSED_EV = 0x01, + SHORT_RELEASED_EV = 0x02, + LONG_PRESSED_EV = 0x04, + LONG_RELEASED_EV = 0x08, + PRESSED_STATE = 0x80 +}; + +typedef struct +{ + UBYTE PressedCnt; + UBYTE LongPressCnt; + UBYTE ShortRelCnt; + UBYTE LongRelCnt; + UBYTE RelCnt; + UBYTE SpareOne; + UBYTE SpareTwo; + UBYTE SpareThree; +}BTNCNT; + +typedef struct +{ + BTNCNT BtnCnt[NO_OF_BTNS]; + UBYTE State[NO_OF_BTNS]; +}IOMAPBUTTON; + + +#endif + + + diff --git a/src/c_cmd.c b/src/c_cmd.c new file mode 100644 index 0000000..87b3e24 --- /dev/null +++ b/src/c_cmd.c @@ -0,0 +1,8020 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date: 24-06-09 8:53 $ +// +// Filename $Workfile:: c_cmd.c $ +// +// Version $Revision: 14 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_cmd. $ +// +// Platform C +// + +// +// File Description: +// This file contains the virtual machine implementation to run bytecode +// programs compatible with LEGO MINDSTORMS NXT Software 2.0. +// +// This module (c_cmd) is also responsible for reading the system timer +// (d_timer) and returning on 1 ms timer boundaries. +// + +#include "stdconst.h" +#include "modules.h" + +#include "c_cmd.iom" +#include "c_output.iom" +#include "c_input.iom" +#include "c_loader.iom" +#include "c_ui.iom" +#include "c_sound.iom" +#include "c_button.iom" +#include "c_display.iom" +#include "c_comm.iom" +#include "c_lowspeed.iom" +#include "m_sched.h" + +#include "c_cmd.h" +#include "c_cmd_bytecodes.h" +#include "d_timer.h" +#include +#include +#include +#include // for sqrt, abs, and trig stuff + +#define VMProfilingCode 0 + +static IOMAPCMD IOMapCmd; +static VARSCMD VarsCmd; +static HEADER **pHeaders; +static ULONG gInstrsToExecute; +static SLONG gPCDelta; +#define NUM_INTERP_FUNCS 16 +#define NUM_SHORT_INTERP_FUNCS 8 +#define VAR_INSTR_SIZE 0xE +// important to cast since most args are assigned from signed value, and locals may be ULONG +#define GetDataArg(arg) ((UWORD)(arg)) +#if VMProfilingCode +static ULONG ExecutedInstrs= 0, CmdCtrlTime= 0, OverheadTime= 0, CmdCtrlCalls= 0, LeaveTime= 0, NotFirstCall= 0, LastAvgCount= 0; +static ULONG CmdCtrlClumpTime[256]; +typedef struct { + ULONG Time; + ULONG Count; + ULONG Avg; + ULONG Max; +} VMInstrProfileInfo; +static VMInstrProfileInfo InstrProfile[OPCODE_COUNT]; +static VMInstrProfileInfo SysCallProfile[SYSCALL_COUNT]; +static VMInstrProfileInfo InterpFuncProfile[NUM_INTERP_FUNCS]; +static VMInstrProfileInfo ShortInstrProfile[NUM_SHORT_OPCODE_COUNT]; +#endif + +#define cCmdDSType(Arg) (VarsCmd.pDataspaceTOC[(Arg)].TypeCode) +#define cCmdDSScalarPtr(DSElementID, Offset) (VarsCmd.pDataspace + VarsCmd.pDataspaceTOC[DSElementID].DSOffset + Offset) +#define cCmdSizeOf(TC) (TC_Size_Table[(TC)]) + +#define scalarBinopDispatchMask 0x1 +#define scalarUnop2DispatchMask 0x2 + +const HEADER cCmd = +{ + 0x00010001L, + "Command", + cCmdInit, + cCmdCtrl, + cCmdExit, + (void *)&IOMapCmd, + (void *)&VarsCmd, + (UWORD)sizeof(IOMapCmd), + (UWORD)sizeof(VarsCmd), + 0x0000 //Code size - not used so far +}; + +#if ENABLE_VM + +// c_cmd_drawing.inc is just another C source file +// (the graphics implementation was split off for practical file management reasons) +#include "c_cmd_drawing.inc" + +// +//Function pointers to sub-interpreters +//This table is indexed by instr size +//Unary operations can have arity of 1 or 2 (some need a destination) +//All instructions taking 4 or more operands are handled as "Other" +// Table uses NoArg for illegal instr sizes such as zero and odd sizes +// +static pInterp InterpFuncs[NUM_INTERP_FUNCS] = +{ + cCmdInterpNoArg, + cCmdInterpNoArg, + cCmdInterpNoArg, // size 2 + cCmdInterpNoArg, + cCmdInterpUnop1, // size 4 + cCmdInterpNoArg, + cCmdInterpUnop2, // size 6 general poly is cCmdInterpUnop2, scalar is cCmdInterpScalarUnop2 + cCmdInterpNoArg, + cCmdInterpBinop, // size 8, general poly is cCmdInterpBinop, scalar is cCmdInterpScalarBinop + cCmdInterpNoArg, + cCmdInterpOther, // size 10 + cCmdInterpNoArg, + cCmdInterpOther, // size 12 + cCmdInterpNoArg, + cCmdInterpOther, // size 14 + cCmdInterpNoArg +}; + +static pInterpShort ShortInterpFuncs[NUM_SHORT_INTERP_FUNCS] = +{ + cCmdInterpShortMove, + cCmdInterpShortAcquire, + cCmdInterpShortRelease, + cCmdInterpShortSubCall, + cCmdInterpShortError, + cCmdInterpShortError, + cCmdInterpShortError, + cCmdInterpShortError +}; + +ULONG TC_Size_Table[]= { + 0, // void + SIZE_UBYTE, + SIZE_SBYTE, + SIZE_UWORD, + SIZE_SWORD, + SIZE_ULONG, + SIZE_SLONG, + SIZE_UWORD, // array + 0, // cluster + SIZE_MUTEX, + SIZE_FLOAT +}; + + +// +//Function pointers to SysCall implementations +//See interpreter for OP_SYSCALL +// +static pSysCall SysCallFuncs[SYSCALL_COUNT] = +{ + cCmdWrapFileOpenRead, + cCmdWrapFileOpenWrite, + cCmdWrapFileOpenAppend, + cCmdWrapFileRead, + cCmdWrapFileWrite, + cCmdWrapFileClose, // 5 + cCmdWrapFileResolveHandle, + cCmdWrapFileRename, + cCmdWrapFileDelete, + cCmdWrapSoundPlayFile, + cCmdWrapSoundPlayTone, // 10 + cCmdWrapSoundGetState, + cCmdWrapSoundSetState, + cCmdWrapDrawText, + cCmdWrapDrawPoint, + cCmdWrapDrawLine, // 15 + cCmdWrapDrawCircle, + cCmdWrapDrawRect, + cCmdWrapDrawPicture, + cCmdWrapSetScreenMode, + cCmdWrapReadButton, // 20 + cCmdWrapCommLSWrite, + cCmdWrapCommLSRead, + cCmdWrapCommLSCheckStatus, + cCmdWrapRandomNumber, + cCmdWrapGetStartTick, // 25 + cCmdWrapMessageWrite, + cCmdWrapMessageRead, + cCmdWrapCommBTCheckStatus, + cCmdWrapCommBTWrite, + cCmdWrapCommBTRead, // 30 + cCmdWrapKeepAlive, + cCmdWrapIOMapRead, + cCmdWrapIOMapWrite, + cCmdWrapColorSensorRead, + cCmdWrapCommBTOnOff, // 35 + cCmdWrapCommBTConnection, + cCmdWrapCommHSWrite, + cCmdWrapCommHSRead, + cCmdWrapCommHSCheckStatus, + cCmdWrapReadSemData, //40 + cCmdWrapWriteSemData, + cCmdWrapComputeCalibValue, + cCmdWrapUpdateCalibCacheInfo, + cCmdWrapDatalogWrite, + cCmdWrapDatalogGetTimes, //45 + cCmdWrapSetSleepTimeout, + cCmdWrapListFiles //47 + + // don't forget to update SYSCALL_COUNT in c_cmd.h +}; + +// +//Next set of arrays are lookup tables for IOM access bytecodes +// +TYPE_CODE IO_TYPES_IN[IO_IN_FIELD_COUNT] = +{ + //IO_IN0 + TC_UBYTE, //IO_IN_TYPE + TC_UBYTE, //IO_IN_MODE + TC_UWORD, //IO_IN_ADRAW + TC_UWORD, //IO_IN_NORMRAW + TC_SWORD, //IO_IN_SCALED_VAL + TC_UBYTE, //IO_IN_INVALID_DATA + + //IO_IN1 + TC_UBYTE, //IO_IN_TYPE + TC_UBYTE, //IO_IN_MODE + TC_UWORD, //IO_IN_ADRAW + TC_UWORD, //IO_IN_NORMRAW + TC_SWORD, //IO_IN_SCALED_VAL + TC_UBYTE, //IO_IN_INVALID_DATA + + //IO_IN2 + TC_UBYTE, //IO_IN_TYPE + TC_UBYTE, //IO_IN_MODE + TC_UWORD, //IO_IN_ADRAW + TC_UWORD, //IO_IN_NORMRAW + TC_SWORD, //IO_IN_SCALED_VAL + TC_UBYTE, //IO_IN_INVALID_DATA + + //IO_IN3 + TC_UBYTE, //IO_IN_TYPE + TC_UBYTE, //IO_IN_MODE + TC_UWORD, //IO_IN_ADRAW + TC_UWORD, //IO_IN_NORMRAW + TC_SWORD, //IO_IN_SCALED_VAL + TC_UBYTE, //IO_IN_INVALID_DATA +}; + +TYPE_CODE IO_TYPES_OUT[IO_OUT_FIELD_COUNT] = +{ + //IO_OUT0 + TC_UBYTE, //IO_OUT_FLAGS + TC_UBYTE, //IO_OUT_MODE + TC_SBYTE, //IO_OUT_SPEED + TC_SBYTE, //IO_OUT_ACTUAL_SPEED + TC_SLONG, //IO_OUT_TACH_COUNT + TC_ULONG, //IO_OUT_TACH_LIMIT + TC_UBYTE, //IO_OUT_RUN_STATE + TC_SBYTE, //IO_OUT_TURN_RATIO + TC_UBYTE, //IO_OUT_REG_MODE + TC_UBYTE, //IO_OUT_OVERLOAD + TC_UBYTE, //IO_OUT_REG_P_VAL + TC_UBYTE, //IO_OUT_REG_I_VAL + TC_UBYTE, //IO_OUT_REG_D_VAL + TC_SLONG, //IO_OUT_BLOCK_TACH_COUNT + TC_SLONG, //IO_OUT_ROTATION_COUNT + TC_UBYTE, //IO_OUT_OPTIONS + TC_SBYTE, //IO_OUT_MAX_SPEED + TC_SBYTE, //IO_OUT_MAX_ACCELERATION + + //IO_OUT1 + TC_UBYTE, //IO_OUT_FLAGS + TC_UBYTE, //IO_OUT_MODE + TC_SBYTE, //IO_OUT_SPEED + TC_SBYTE, //IO_OUT_ACTUAL_SPEED + TC_SLONG, //IO_OUT_TACH_COUNT + TC_ULONG, //IO_OUT_TACH_LIMIT + TC_UBYTE, //IO_OUT_RUN_STATE + TC_SBYTE, //IO_OUT_TURN_RATIO + TC_UBYTE, //IO_OUT_REG_MODE + TC_UBYTE, //IO_OUT_OVERLOAD + TC_UBYTE, //IO_OUT_REG_P_VAL + TC_UBYTE, //IO_OUT_REG_I_VAL + TC_UBYTE, //IO_OUT_REG_D_VAL + TC_SLONG, //IO_OUT_BLOCK_TACH_COUNT + TC_SLONG, //IO_OUT_ROTATION_COUNT + TC_UBYTE, //IO_OUT_OPTIONS + TC_SBYTE, //IO_OUT_MAX_SPEED + TC_SBYTE, //IO_OUT_MAX_ACCELERATION + + //IO_OUT2 + TC_UBYTE, //IO_OUT_FLAGS + TC_UBYTE, //IO_OUT_MODE + TC_SBYTE, //IO_OUT_SPEED + TC_SBYTE, //IO_OUT_ACTUAL_SPEED + TC_SLONG, //IO_OUT_TACH_COUNT + TC_ULONG, //IO_OUT_TACH_LIMIT + TC_UBYTE, //IO_OUT_RUN_STATE + TC_SBYTE, //IO_OUT_TURN_RATIO + TC_UBYTE, //IO_OUT_REG_MODE + TC_UBYTE, //IO_OUT_OVERLOAD + TC_UBYTE, //IO_OUT_REG_P_VAL + TC_UBYTE, //IO_OUT_REG_I_VAL + TC_UBYTE, //IO_OUT_REG_D_VAL + TC_SLONG, //IO_OUT_BLOCK_TACH_COUNT + TC_SLONG, //IO_OUT_ROTATION_COUNT + TC_UBYTE, //IO_OUT_OPTIONS + TC_SBYTE, //IO_OUT_MAX_SPEED + TC_SBYTE, //IO_OUT_MAX_ACCELERATION +}; + + +TYPE_CODE * IO_TYPES[2] = +{ + IO_TYPES_IN, + IO_TYPES_OUT +}; + +//Actual pointers filled in during cCmdInit() +void * IO_PTRS_IN[IO_IN_FIELD_COUNT]; +void * IO_PTRS_OUT[IO_OUT_FIELD_COUNT]; + +void ** IO_PTRS[2] = +{ + IO_PTRS_IN, + IO_PTRS_OUT +}; + +// Data used to indicate usage of motor ports, or usage requests +UBYTE gUsageSemData, gRequestSemData; + +UBYTE cCmdBTGetDeviceType(UBYTE *pCOD) +{ + ULONG COD; + UBYTE Result; + UBYTE Tmp; + + COD = 0; + for (Tmp = 0;Tmp < SIZE_OF_CLASS_OF_DEVICE;Tmp++) + { + COD <<= 8; + COD |= (ULONG)*pCOD; + pCOD++; + } + + Result = DEVICETYPE_UNKNOWN; + if ((COD & 0x00001FFF) == 0x00000804) + { + Result = DEVICETYPE_NXT; + } + if ((COD & 0x00001F00) == 0x00000200) + { + Result = DEVICETYPE_PHONE; + } + if ((COD & 0x00001F00) == 0x00000100) + { + Result = DEVICETYPE_PC; + } + + return (Result); +} + +//cCmdHandleRemoteCommands is the registered handler for "direct" command protocol packets +//It is only intended to be called via c_comm's main protocol handler +UWORD cCmdHandleRemoteCommands(UBYTE * pInBuf, UBYTE * pOutBuf, UBYTE * pLen) +{ + NXT_STATUS RCStatus = NO_ERR; + //Response packet length. Always includes RCStatus byte. + ULONG ResponseLen = 1; + //Boolean flag to send a response. TRUE unless overridden below. + ULONG SendResponse = TRUE; + //Boolean flag if we are handling a reply telegram. FALSE unless overridden. + ULONG IncomingReply = FALSE; + ULONG i, FirstPort, LastPort; + UWORD LStatus; + UWORD Count, QueueID; + UBYTE * pData; + + //Illegal call, give up + if (pInBuf == NULL || pLen == NULL) + { + NXT_BREAK; + return (0xFFFF); + } + + //No output buffer provided, so skip any work related to returning a response + if (pOutBuf == NULL) + SendResponse = FALSE; + + //If first byte identifies this as a reply telegram, we have different work to do. + if (pInBuf[0] == 0x02) + { + IncomingReply = TRUE; + //Reply telegrams never get responses, even if caller provided a buffer. + SendResponse = FALSE; + } + + //Advance pInBuf past command type byte + pInBuf++; + + if (!IncomingReply) + { + switch(pInBuf[0]) + { + case RC_START_PROGRAM: + { + //Check that file exists. If not, return error + //!!! Should return standard loader file error in cases like this?? + //!!! Proper solution would also check file mode to avoid confusing errors + if (LOADER_ERR(LStatus = pMapLoader->pFunc(FINDFIRST, (&pInBuf[1]), NULL, NULL)) != SUCCESS) + { + RCStatus = ERR_RC_ILLEGAL_VAL; + break; + } + + //Close file handle returned by FINDFIRST + pMapLoader->pFunc(CLOSE, LOADER_HANDLE_P(LStatus), NULL, NULL); + + //File must exist, so inform UI to attempt execution in the usual way (enables consistent feedback) + pMapUi->Flags |= UI_EXECUTE_LMS_FILE; + strncpy((PSZ)(pMapUi->LMSfilename), (PSZ)(&pInBuf[1]), FILENAME_LENGTH + 1); + } + break; + + case RC_STOP_PROGRAM: + { + if (VarsCmd.ActiveProgHandle == NOT_A_HANDLE) + { + RCStatus = ERR_NO_PROG; + break; + } + + IOMapCmd.DeactivateFlag = TRUE; + } + break; + + case RC_PLAY_SOUND_FILE: + { + if (LOADER_ERR(LStatus = pMapLoader->pFunc(FINDFIRST, (&pInBuf[2]), NULL, NULL)) != SUCCESS) + { + RCStatus = ERR_RC_ILLEGAL_VAL; + break; + } + + //Close file handle returned by FINDFIRST + pMapLoader->pFunc(CLOSE, LOADER_HANDLE_P(LStatus), NULL, NULL); + + if (pInBuf[1] == FALSE) + pMapSound->Mode = SOUND_ONCE; + else //Any non-zero value treated as TRUE + pMapSound->Mode = SOUND_LOOP; + + strncpy((PSZ)pMapSound->SoundFilename, (PSZ)(&pInBuf[2]), FILENAME_LENGTH + 1); + pMapSound->Flags |= SOUND_UPDATE; + } + break; + + case RC_PLAY_TONE: + { + pMapSound->Mode = SOUND_TONE; + //!!! Range check valid values? + memcpy((PSZ)(&(pMapSound->Freq)), (PSZ)(&pInBuf[1]), 2); + memcpy((PSZ)(&(pMapSound->Duration)), (PSZ)(&pInBuf[3]), 2); + + pMapSound->Flags |= SOUND_UPDATE; + } + break; + + case RC_SET_OUT_STATE: + { + UBYTE Port = pInBuf[1]; + //Don't do anything if illegal port specification is made + if (Port >= NO_OF_OUTPUTS && Port != 0xFF) + { + RCStatus = ERR_RC_ILLEGAL_VAL; + break; + } + + //0xFF is protocol defined to mean "all ports". + if (Port == 0xFF) + { + FirstPort = 0; + LastPort = NO_OF_OUTPUTS - 1; + } + else + FirstPort = LastPort = Port; + + for (i = FirstPort; i <= LastPort; i++) + { + OUTPUT * pOut = &(pMapOutPut->Outputs[i]); + pOut->Speed = pInBuf[2]; + pOut->Mode = pInBuf[3]; + pOut->RegMode = pInBuf[4]; + pOut->SyncTurnParameter = pInBuf[5]; + pOut->RunState = pInBuf[6]; + pOut->Options = pOut->Mode & REG_METHOD; + memcpy((PSZ)(&(pOut->TachoLimit)), (PSZ)(&pInBuf[7]), 4); + + pOut->Flags |= UPDATE_MODE | UPDATE_SPEED | UPDATE_TACHO_LIMIT; + } + } + break; + + case RC_SET_IN_MODE: + { + i = pInBuf[1]; + + //Don't do anything if illegal port specification is made + //!!! Should check against legal Types and Modes? (bitmask for Modes?) + if (i >= NO_OF_INPUTS) + { + RCStatus = ERR_RC_ILLEGAL_VAL; + break; + } + INPUTSTRUCT * pIn = &(pMapInput->Inputs[i]); + + pIn->SensorType = pInBuf[2]; + pIn->SensorMode = pInBuf[3]; + + //Set InvalidData flag automatically since type may have changed + pIn->InvalidData = TRUE; + } + break; + + case RC_GET_OUT_STATE: + { + if (SendResponse == TRUE) + { + i = pInBuf[1]; + + //Return error and all zeros if illegal port specification is made + if (i >= NO_OF_OUTPUTS) + { + RCStatus = ERR_RC_ILLEGAL_VAL; + memset(&(pOutBuf[ResponseLen]), 0, 22); + ResponseLen += 22; + break; + } + OUTPUT * pOut = &(pMapOutPut->Outputs[i]); + + //Echo port + pOutBuf[ResponseLen] = i; + ResponseLen++; + + //Power + pOutBuf[ResponseLen] = pOut->Speed; + ResponseLen++; + + //Mode + pOutBuf[ResponseLen] = pOut->Mode; + ResponseLen++; + + //RegMode + pOutBuf[ResponseLen] = pOut->RegMode; + ResponseLen++; + + //TurnRatio + pOutBuf[ResponseLen] = pOut->SyncTurnParameter; + ResponseLen++; + + //RunState + pOutBuf[ResponseLen] = pOut->RunState; + ResponseLen++; + + //TachoLimit ULONG + memcpy((PSZ)&(pOutBuf[ResponseLen]), (PSZ)(&(pOut->TachoLimit)), 4); + ResponseLen += 4; + + //TachoCount SLONG + memcpy((PSZ)&(pOutBuf[ResponseLen]), (PSZ)(&(pOut->TachoCnt)), 4); + ResponseLen += 4; + + //BlockTachoCount SLONG + memcpy((PSZ)&(pOutBuf[ResponseLen]), (PSZ)(&(pOut->BlockTachoCount)), 4); + ResponseLen += 4; + + //RotationCount SLONG + memcpy((PSZ)&(pOutBuf[ResponseLen]), (PSZ)(&(pOut->RotationCount)), 4); + ResponseLen += 4; + + NXT_ASSERT(ResponseLen == 23); + } + } + break; + + case RC_GET_IN_VALS: + { + if (SendResponse == TRUE) + { + i = pInBuf[1]; + + //Return error and all zeros if illegal port specification is made + if (i >= NO_OF_INPUTS) + { + RCStatus = ERR_RC_ILLEGAL_VAL; + memset(&(pOutBuf[ResponseLen]), 0, 13); + ResponseLen += 13; + break; + } + + //Echo port + pOutBuf[ResponseLen] = i; + ResponseLen++; + + INPUTSTRUCT * pIn = &(pMapInput->Inputs[i]); + + //Set "Valid?" boolean + if (pIn->InvalidData) + pOutBuf[ResponseLen] = FALSE; + else + pOutBuf[ResponseLen] = TRUE; + + ResponseLen++; + + //Set "Calibrated?" boolean + //!!! "Calibrated?" is a placeholder in the protocol. Always FALSE for now. + pOutBuf[ResponseLen] = FALSE; + ResponseLen++; + + pOutBuf[ResponseLen] = pIn->SensorType; + ResponseLen++; + + pOutBuf[ResponseLen] = pIn->SensorMode; + ResponseLen++; + + //Set Raw, Normalized, and Scaled values + memcpy((PSZ)&(pOutBuf[ResponseLen]), (PSZ)(&(pIn->ADRaw)), 2); + ResponseLen += 2; + + memcpy((PSZ)&(pOutBuf[ResponseLen]), (PSZ)(&(pIn->SensorRaw)), 2); + ResponseLen += 2; + + memcpy((PSZ)&(pOutBuf[ResponseLen]), (PSZ)(&(pIn->SensorValue)), 2); + ResponseLen += 2; + + //!!! Return normalized raw value in place of calibrated value for now -- see comment above + memcpy((PSZ)&(pOutBuf[ResponseLen]), (PSZ)(&(pIn->SensorRaw)), 2); + ResponseLen += 2; + + NXT_ASSERT(ResponseLen == 14); + } + } + break; + + case RC_RESET_IN_VAL: + { + i = pInBuf[1]; + + //Don't do anything if illegal port specification is made + if (i >= NO_OF_INPUTS) + { + RCStatus = ERR_RC_ILLEGAL_VAL; + break; + } + + //Clear SensorValue to zero. Leave Raw and Normalized as-is, since they never accumulate running values. + pMapInput->Inputs[i].SensorValue = 0; + } + break; + + case RC_MESSAGE_WRITE: + { + QueueID = pInBuf[1]; + Count = pInBuf[2]; + pData = &(pInBuf[3]); + + //If Count is illegal or MsgData is not null-terminated, + // we can't accept it as a valid string + if (Count == 0 || Count > MAX_MESSAGE_SIZE || pData[Count - 1] != 0x00) + { + RCStatus = ERR_RC_ILLEGAL_VAL; + break; + } + + RCStatus = cCmdMessageWrite(QueueID, pData, Count); + + //ERR_MEM here means we must compact the dataspace and retry message write + if (RCStatus == ERR_MEM) + { + cCmdDSCompact(); + RCStatus = cCmdMessageWrite(QueueID, pData, Count); + } + } + break; + + case RC_RESET_POSITION: + { + i = pInBuf[1]; + + //Don't do anything if illegal port specification is made + if (i >= NO_OF_OUTPUTS) + { + RCStatus = ERR_RC_ILLEGAL_VAL; + break; + } + + //pInBuf[2] is a selector + //FALSE: Position relative to start of last program + //TRUE: Position relative to start of last motor control block + pMapOutPut->Outputs[i].Flags |= (pInBuf[2] ? UPDATE_RESET_BLOCK_COUNT : UPDATE_RESET_ROTATION_COUNT); + } + break; + + case RC_GET_BATT_LVL: + { + if (SendResponse == TRUE) + { + //Return BatteryVoltage directly from IOMapUI, in mV + memcpy((PSZ)&(pOutBuf[ResponseLen]), (PSZ)&(pMapUi->BatteryVoltage), 2); + ResponseLen += 2; + } + } + break; + + case RC_STOP_SOUND: + { + //Tell sound module to stop playback, no questions asked + pMapSound->State = SOUND_STOP; + } + break; + + case RC_KEEP_ALIVE: + { + pMapUi->Flags |= UI_RESET_SLEEP_TIMER; + + if (SendResponse == TRUE) + { + //Convert to milliseconds to match external conventions + i = (pMapUi->SleepTimeout * 60 * 1000); + memcpy((PSZ)&(pOutBuf[ResponseLen]), (PSZ)&i, 4); + ResponseLen += 4; + } + } + break; + + case RC_LS_GET_STATUS: + { + if (SendResponse == TRUE) + { + i = pInBuf[1]; + + //Don't do anything if illegal port specification is made + if (i >= NO_OF_LOWSPEED_COM_CHANNEL) + { + RCStatus = ERR_RC_ILLEGAL_VAL; + break; + } + + RCStatus = cCmdLSCheckStatus(i); + + pOutBuf[ResponseLen] = cCmdLSCalcBytesReady(i); + ResponseLen++; + } + } + break; + + case RC_LS_WRITE: + { + i = pInBuf[1]; + Count = pInBuf[2]; + + //Don't do anything if illegal port specification is made + if (i >= NO_OF_LOWSPEED_COM_CHANNEL) + { + RCStatus = ERR_RC_ILLEGAL_VAL; + break; + } + + RCStatus = cCmdLSWrite(i, Count, &(pInBuf[4]), pInBuf[3]); + } + break; + + case RC_LS_READ: + { + if (SendResponse == TRUE) + { + i = pInBuf[1]; + + //Don't do anything if illegal port specification is made + if (i >= NO_OF_LOWSPEED_COM_CHANNEL) + { + RCStatus = ERR_RC_ILLEGAL_VAL; + break; + } + + //Get channel status and number of bytes available to read + RCStatus = cCmdLSCheckStatus(i); + Count = cCmdLSCalcBytesReady(i); + + pOutBuf[ResponseLen] = (UBYTE)Count; + ResponseLen++; + + //If channel is ready and has data ready for us, put the data into outgoing buffer + if (!IS_ERR(RCStatus) && Count > 0) + { + RCStatus = cCmdLSRead(i, (UBYTE)Count, &(pOutBuf[ResponseLen])); + ResponseLen += Count; + } + + //Pad remaining data bytes with zeroes + Count = 16 - Count; + memset(&(pOutBuf[ResponseLen]), 0, Count); + ResponseLen += Count; + } + } + break; + + case RC_GET_CURR_PROGRAM: + { + if (SendResponse == TRUE) + { + //If there's no active program, return error and empty name buffer + if (VarsCmd.ActiveProgHandle == NOT_A_HANDLE) + { + RCStatus = ERR_NO_PROG; + memset(&(pOutBuf[ResponseLen]), 0, FILENAME_LENGTH + 1); + } + //Else, copy out stashed program name + else + { + strncpy((PSZ)(&(pOutBuf[ResponseLen])), (PSZ)(VarsCmd.ActiveProgName), FILENAME_LENGTH + 1); + } + + //Regardless, we've copied out a filename's worth of bytes... + ResponseLen += FILENAME_LENGTH + 1; + } + } + break; + + case RC_MESSAGE_READ: + { + if (SendResponse == TRUE) + { + QueueID = pInBuf[1]; + + //Fill in response with remote mailbox number so remote device knows where to store this message. + pOutBuf[ResponseLen] = pInBuf[2]; + ResponseLen++; + + RCStatus = cCmdMessageGetSize(QueueID, &Count); + pOutBuf[ResponseLen] = Count; + ResponseLen++; + + if (!IS_ERR(RCStatus) && Count > 0) + { + pData = &(pOutBuf[ResponseLen]); + RCStatus = cCmdMessageRead(QueueID, pData, Count, (pInBuf[3])); + //If cCmdMessageRead encountered an error, there is no real data in the buffer, so clear it out (below) + if (IS_ERR(RCStatus)) + Count = 0; + else + ResponseLen += Count; + } + + //Pad remaining data bytes with zeroes + Count = MAX_MESSAGE_SIZE - Count; + memset(&(pOutBuf[ResponseLen]), 0, Count); + ResponseLen += Count; + } + } + break; + + // remote-only command to read from datalog buffer + // pInBuf[1] = Remove? (bool) + case RC_DATALOG_READ: + { + if (SendResponse == TRUE) + { + RCStatus = cCmdDatalogGetSize(&Count); + pOutBuf[ResponseLen] = Count; + ResponseLen++; + + if (!IS_ERR(RCStatus) && Count > 0) + { + pData = &(pOutBuf[ResponseLen]); + RCStatus = cCmdDatalogRead(pData, Count, (pInBuf[1])); + //If cCmdDatalogRead encountered an error, there is no real data in the buffer, so clear it out (below) + if (IS_ERR(RCStatus)) + Count = 0; + else + ResponseLen += Count; + } + + //Pad remaining data bytes with zeroes + Count = MAX_DATALOG_SIZE - Count; + memset(&(pOutBuf[ResponseLen]), 0, Count); + ResponseLen += Count; + } + } + break; + case RC_DATALOG_SET_TIMES: + { + //SyncTime SLONG + memcpy((PSZ)&IOMapCmd.SyncTime, (PSZ)&(pInBuf[1]), 4); + IOMapCmd.SyncTick= dTimerReadNoPoll(); + } + break; + + case RC_BT_GET_CONN_COUNT: + if (SendResponse == TRUE) { + pOutBuf[ResponseLen]= SIZE_OF_BT_CONNECT_TABLE; + ResponseLen++; + } + break; + case RC_BT_GET_CONN_NAME: // param in is index, param out is name + if (SendResponse == TRUE) { // get index from inbuf + i = pInBuf[1]; + if(i < SIZE_OF_BT_CONNECT_TABLE) { // unsigned, so guaranteed >= 0 + pOutBuf[ResponseLen] = cCmdBTGetDeviceType(pMapComm->BtConnectTable[i].ClassOfDevice); + memcpy((PSZ)(&(pOutBuf[ResponseLen+1])), (PSZ)(pMapComm->BtConnectTable[i].Name), SIZE_OF_BT_NAME + 1); + ResponseLen += SIZE_OF_BT_NAME + 2; + } + else { + pOutBuf[ResponseLen] = 0; + ResponseLen += SIZE_OF_BT_NAME + 2; + } + } + break; + case RC_BT_GET_CONTACT_COUNT: + if (SendResponse == TRUE) { + pOutBuf[ResponseLen]= SIZE_OF_BT_DEVICE_TABLE; + ResponseLen++; + } + break; + case RC_BT_GET_CONTACT_NAME: + if (SendResponse == TRUE) { // get index from inbuf + i = pInBuf[1]; + if(i < SIZE_OF_BT_DEVICE_TABLE && (pMapComm->BtDeviceTable[i].DeviceStatus & BT_DEVICE_KNOWN)) { // unsigned, so guaranteed >= 0 + (pOutBuf[ResponseLen])= cCmdBTGetDeviceType(pMapComm->BtDeviceTable[i].ClassOfDevice); + memcpy((PSZ)(&(pOutBuf[ResponseLen+1])), (PSZ)(pMapComm->BtDeviceTable[i].Name), SIZE_OF_BT_NAME + 1); + ResponseLen += SIZE_OF_BT_NAME + 2; + } + else + { + pOutBuf[ResponseLen] = 0; + memset((PSZ)(&(pOutBuf[ResponseLen+1])), 0, SIZE_OF_BT_NAME + 1); + ResponseLen += SIZE_OF_BT_NAME + 2; + } + } + break; + case RC_SET_PROPERTY: // label/value pairs + i = pInBuf[1]; + switch(i) { + case RC_PROP_BTONOFF: { + UWORD retVal, status; + if(pInBuf[2]) + status= pMapComm->pFunc(BTON, 0, 0, 0, NULL, &retVal); + else + status= pMapComm->pFunc(BTOFF, 0, 0, 0, NULL, &retVal); + + RCStatus= (status == SUCCESS) ? retVal : status; + } + break; + case RC_PROP_SOUND_LEVEL: { + UBYTE volume= pInBuf[2]; + if(volume > 4) + volume= 4; + pMapSound->Volume= volume; // apparently stored in two places + pMapUi->Volume= volume; + } + break; + case RC_PROP_SLEEP_TIMEOUT: { // ulong millisecs to sleep + ULONG value; + memcpy((PSZ)&value, (PSZ)&(pInBuf[2]), 4); + pMapUi->SleepTimeout= value / 60000; + } + break; + default: + //Unknown property -- still inform client to not expect any response bytes + NXT_BREAK; + RCStatus = ERR_RC_UNKNOWN_CMD; + break; + } + break; + case RC_GET_PROPERTY: // label/value pairs + if (SendResponse == TRUE) { // get index from inbuf + i = pInBuf[1]; + switch(i) { + case RC_PROP_BTONOFF: + pOutBuf[ResponseLen]= pMapUi->BluetoothState != BT_STATE_OFF; + ResponseLen++; + break; + case RC_PROP_SOUND_LEVEL: { + pOutBuf[ResponseLen]= pMapSound->Volume; + ResponseLen++; + } + break; + case RC_PROP_SLEEP_TIMEOUT: { + ULONG value= (pMapUi->SleepTimeout * 60 * 1000); + memcpy((PSZ)&(pOutBuf[ResponseLen]), (PSZ)&value, 4); + ResponseLen += 4; + } + break; + default: + //Unknown property -- still inform client to not expect any response bytes + NXT_BREAK; + RCStatus = ERR_RC_UNKNOWN_CMD; + break; + } + } + break; + case RC_UPDATE_RESET_COUNT: + { + i = pInBuf[1]; + + //Don't do anything if illegal port specification is made + if (i >= NO_OF_OUTPUTS) + { + RCStatus = ERR_RC_ILLEGAL_VAL; + break; + } + + pMapOutPut->Outputs[i].Flags |= UPDATE_RESET_COUNT; + } + break; + default: + { + //Unknown remote command -- still inform client to not expect any response bytes + NXT_BREAK; + RCStatus = ERR_RC_UNKNOWN_CMD; + } + break; + }; + } + //Handle reply telegrams + else + { + switch(pInBuf[0]) + { + case RC_MESSAGE_READ: + { + QueueID = pInBuf[2]; + Count = pInBuf[3]; + pData = &(pInBuf[4]); + + //This is a response to our request to read a message from a remote mailbox. + //If telegram looks valid, write the resulting message into our local mailbox. + //(If MsgData is not null-terminated, we can't accept it as a valid string.) + if (!IS_ERR((SBYTE)(pInBuf[1])) + && Count > 0 + && Count <= MAX_MESSAGE_SIZE + && pData[Count - 1] == 0x00) + { + RCStatus = cCmdMessageWrite(QueueID, pData, Count); + + //ERR_MEM here means we must compact the dataspace + if (RCStatus == ERR_MEM) + { + cCmdDSCompact(); + RCStatus = cCmdMessageWrite(QueueID, pData, Count); + } + } + + //If telegram doesn't check out, do nothing. No errors are ever returned for reply telegrams. + } + break; + + default: + { + //Unhandled reply telegram. Do nothing. + //!!! Could/should stash unhandled/all replies somewhere so a syscall could read them + } + break; + }; + } + + if (SendResponse == TRUE) + { + //Return response length (pointer checked above) + *pLen = (UBYTE)ResponseLen; + //Fill in status byte + pOutBuf[0] = (UBYTE)(RCStatus); + } + else + *pLen = 0; + + return (0); +} + + +// +// Standard interface functions +// + +void cCmdInit(void* pHeader) +{ + ULONG i; + + pHeaders = pHeader; + + IOMapCmd.pRCHandler = &cCmdHandleRemoteCommands; + +#if defined(ARM_DEBUG) + //Init run-time assert tracking variables + VarsCmd.AssertFlag = FALSE; + VarsCmd.AssertLine = 0; +#endif + + //Initialize IO_PTRS_OUT + for (i = 0; i < NO_OF_OUTPUTS; i++) + { + OUTPUT * pOut = &(pMapOutPut->Outputs[i]); + IO_PTRS_OUT[IO_OUT_FLAGS + i * IO_OUT_FPP] = (void*)&(pOut->Flags); + IO_PTRS_OUT[IO_OUT_MODE + i * IO_OUT_FPP] = (void*)&(pOut->Mode); + IO_PTRS_OUT[IO_OUT_SPEED + i * IO_OUT_FPP] = (void*)&(pOut->Speed); + IO_PTRS_OUT[IO_OUT_ACTUAL_SPEED + i * IO_OUT_FPP] = (void*)&(pOut->ActualSpeed); + IO_PTRS_OUT[IO_OUT_TACH_COUNT + i * IO_OUT_FPP] = (void*)&(pOut->TachoCnt); + IO_PTRS_OUT[IO_OUT_TACH_LIMIT + i * IO_OUT_FPP] = (void*)&(pOut->TachoLimit); + IO_PTRS_OUT[IO_OUT_RUN_STATE + i * IO_OUT_FPP] = (void*)&(pOut->RunState); + IO_PTRS_OUT[IO_OUT_TURN_RATIO + i * IO_OUT_FPP] = (void*)&(pOut->SyncTurnParameter); + IO_PTRS_OUT[IO_OUT_REG_MODE + i * IO_OUT_FPP] = (void*)&(pOut->RegMode); + IO_PTRS_OUT[IO_OUT_OVERLOAD + i * IO_OUT_FPP] = (void*)&(pOut->Overloaded); + IO_PTRS_OUT[IO_OUT_REG_P_VAL + i * IO_OUT_FPP] = (void*)&(pOut->RegPParameter); + IO_PTRS_OUT[IO_OUT_REG_I_VAL + i * IO_OUT_FPP] = (void*)&(pOut->RegIParameter); + IO_PTRS_OUT[IO_OUT_REG_D_VAL + i * IO_OUT_FPP] = (void*)&(pOut->RegDParameter); + IO_PTRS_OUT[IO_OUT_BLOCK_TACH_COUNT + i * IO_OUT_FPP] = (void*)&(pOut->BlockTachoCount); + IO_PTRS_OUT[IO_OUT_ROTATION_COUNT + i * IO_OUT_FPP] = (void*)&(pOut->RotationCount); + IO_PTRS_OUT[IO_OUT_OPTIONS + i * IO_OUT_FPP] = (void*)&(pOut->Options); + IO_PTRS_OUT[IO_OUT_MAX_SPEED + i * IO_OUT_FPP] = (void*)&(pOut->MaxSpeed); + IO_PTRS_OUT[IO_OUT_MAX_ACCELERATION + i * IO_OUT_FPP] = (void*)&(pOut->MaxAcceleration); + } + + //Initialize IO_PTRS_IN + for (i = 0; i < NO_OF_INPUTS; i++) + { + INPUTSTRUCT * pIn = &(pMapInput->Inputs[i]); + IO_PTRS_IN[IO_IN_TYPE + i * IO_IN_FPP] = (void*)&(pIn->SensorType); + IO_PTRS_IN[IO_IN_MODE + i * IO_IN_FPP] = (void*)&(pIn->SensorMode); + IO_PTRS_IN[IO_IN_ADRAW + i * IO_IN_FPP] = (void*)&(pIn->ADRaw); + IO_PTRS_IN[IO_IN_NORMRAW + i * IO_IN_FPP] = (void*)&(pIn->SensorRaw); + IO_PTRS_IN[IO_IN_SCALEDVAL + i * IO_IN_FPP] = (void*)&(pIn->SensorValue); + IO_PTRS_IN[IO_IN_INVALID_DATA + i * IO_IN_FPP] = (void*)&(pIn->InvalidData); + } + + //Clear memory pool and initialize VarsCmd (cCmdDeactivateProgram effectively re-inits VarsCmd) + cCmdInitPool(); + cCmdDeactivateProgram(); + + //Global state variables for BlueTooth communication. + VarsCmd.CommStat = (SWORD)SUCCESS; + VarsCmd.CommStatReset = (SWORD)BTBUSY; + VarsCmd.CommCurrConnection = 1; + + //Global flags for various reset and bookkeeping scenarios + VarsCmd.DirtyComm = FALSE; + VarsCmd.DirtyDisplay = FALSE; + + VarsCmd.VMState = VM_IDLE; + +#if defined (ARM_NXT) + //Make sure Pool is long-aligned + NXT_ASSERT(!((ULONG)(POOL_START) % SIZE_SLONG)); +#endif + + IOMapCmd.ProgStatus = PROG_IDLE; + IOMapCmd.ActivateFlag = FALSE; + IOMapCmd.Awake = TRUE; + + //Default offsets explicitly chosen to cause an error if used with IOMAPREAD/IOMAPWRITE + //Real values will be set when programs run and/or the DS is re-arranged. + IOMapCmd.OffsetDVA = 0xFFFF; + IOMapCmd.OffsetDS = 0xFFFF; + + //Initialize format string and clear out FileName string + strncpy((PSZ)(IOMapCmd.FormatString), VM_FORMAT_STRING, VM_FORMAT_STRING_SIZE); + memset(IOMapCmd.FileName, 0, sizeof(IOMapCmd.FileName)); + + dTimerInit(); + IOMapCmd.Tick = dTimerRead(); + IOMapCmd.SyncTime= 0; + IOMapCmd.SyncTick= 0; + + return; +} + + +void cCmdCtrl(void) +{ + NXT_STATUS Status = NO_ERR; + + switch (VarsCmd.VMState) + { + case VM_RUN_FREE: + case VM_RUN_SINGLE: + { + #if VMProfilingCode + ULONG EnterTime= dTimerReadHiRes(), FinishTime; + CmdCtrlCalls ++; +#endif + ULONG Continue; + +#if VM_BENCHMARK + //IOMapCmd.Tick currently holds the tick from the end of last cCmdCtrl call. + //If we don't come back here before dTimerRead() increments, the m_sched loop has taken *at least* 1 ms. + if (IOMapCmd.Tick != dTimerRead()) + { + VarsCmd.OverTimeCount++; + //Record maximum magnitude of schedule loop overage, in millisecs + if (dTimerRead() - IOMapCmd.Tick > VarsCmd.MaxOverTimeLength) + VarsCmd.MaxOverTimeLength = dTimerRead() - IOMapCmd.Tick; + } + VarsCmd.CmdCtrlCount++; +#endif + //Abort current program if cancel button is pressed + if (IOMapCmd.DeactivateFlag == TRUE || pMapButton->State[BTN1] & PRESSED_EV) + { + IOMapCmd.DeactivateFlag = FALSE; + + //Clear pressed event so it doesn't get double-counted by UI + pMapButton->State[BTN1] &= ~PRESSED_EV; + + //Go to VM_RESET1 state and report abort + VarsCmd.VMState = VM_RESET1; + IOMapCmd.ProgStatus = PROG_ABORT; + break; + } + + //Assert that we have an active program + NXT_ASSERT(VarsCmd.ActiveProgHandle != NOT_A_HANDLE); + + //Handle any resting clumps that are ready to awaken + cCmdCheckRestQ(IOMapCmd.Tick); // not using result, yet + //Execute from at least one clump + do + { + //Execute instructions from a clump up to INSTR_MAX, to end of millisec, + //Finishing/suspending a clump, BREAKOUT_REQ, or any errors will cause a return +#if VMProfilingCode + ULONG ClumpEnterTime= dTimerReadHiRes(); + CLUMP_ID clump= VarsCmd.RunQ.Head; +#endif + Status = cCmdInterpFromClump(); +#if VMProfilingCode + CmdCtrlClumpTime[clump] += dTimerReadHiRes() - ClumpEnterTime; +#endif + + //If RunQ and RestQ are empty, program is done, or wacko + if (!cCmdIsClumpIDSane(VarsCmd.RunQ.Head)) { + Continue = FALSE; + if(!cCmdIsClumpIDSane(VarsCmd.RestQ.Head)) { + VarsCmd.VMState = VM_RESET1; + IOMapCmd.ProgStatus = PROG_OK; + } + } + else if (Status == CLUMP_SUSPEND || Status == CLUMP_DONE) + Continue = TRUE; // queue isn't empty, didn't timeout + //Only rotate RunQ on a "normal" finish, i.e. no error, clump end, or breakout request + else if (Status == ROTATE_QUEUE) { // done and suspend do their own + cCmdRotateQ(); + Continue= TRUE; + } + else if (Status == TIMES_UP) { + cCmdRotateQ(); + Continue = FALSE; + } + else if (IS_ERR(Status)) // mem error is handled in InterpFromClump if possible + { + Continue = FALSE; + VarsCmd.VMState = VM_RESET1; + IOMapCmd.ProgStatus = PROG_ERROR; + } + else if (Status == STOP_REQ) + { + Continue = FALSE; + VarsCmd.VMState = VM_RESET1; + IOMapCmd.ProgStatus = PROG_OK; + } + else if (Status == BREAKOUT_REQ) + { + Continue = FALSE; + } + } while (Continue == TRUE); +#if VMProfilingCode + FinishTime= dTimerReadHiRes(); + if(NotFirstCall) + OverheadTime += EnterTime - LeaveTime; + else + NotFirstCall= 1; + CmdCtrlTime += FinishTime - EnterTime; + LeaveTime= FinishTime; +#endif + // May busy wait to postpone to 1ms schedule + while (IOMapCmd.Tick == dTimerRead()); + } + break; + case VM_IDLE: + { + //If there's a new program to activate... + if (IOMapCmd.ActivateFlag == TRUE) + { + //Clear flag so we only activate once per new file + IOMapCmd.ActivateFlag = FALSE; + + Status = cCmdActivateProgram(IOMapCmd.FileName); + + //If we hit an activation error: + //1. Set PROG_ERROR status + //2. Proceed to VM_RESET1 (some unneeded work, yes, but preserves contract with UI + if (IS_ERR(Status)) + { + IOMapCmd.ProgStatus = PROG_ERROR; + VarsCmd.VMState = VM_RESET1; + } + //Else start running program + else + { + VarsCmd.VMState = VM_RUN_FREE; + IOMapCmd.ProgStatus = PROG_RUNNING; + VarsCmd.StartTick = IOMapCmd.Tick; + if(VarsCmd.VMState == VM_RUN_FREE) + gInstrsToExecute = 20; + else + gInstrsToExecute= 1; + +#if VM_BENCHMARK + //Re-init benchmark + VarsCmd.InstrCount = 0; + VarsCmd.Average = 0; + VarsCmd.OverTimeCount = 0; + VarsCmd.MaxOverTimeLength = 0; + VarsCmd.CmdCtrlCount = 0; + VarsCmd.CompactionCount = 0; + VarsCmd.LastCompactionTick = 0; + VarsCmd.MaxCompactionTime = 0; + memset(VarsCmd.OpcodeBenchmarks, 0, sizeof(VarsCmd.OpcodeBenchmarks)); + memset(VarsCmd.SyscallBenchmarks, 0, sizeof(VarsCmd.SyscallBenchmarks)); +#endif + //Reset devices to a known state before we begin running + cCmdResetDevices(); + + pMapUi->Flags |= (UI_DISABLE_LEFT_RIGHT_ENTER | UI_DISABLE_EXIT); + } + } + while (IOMapCmd.Tick == dTimerRead()); // delay until scheduled time + } + break; + + //Initialize VM internal state data and devices which must respond immediately to program ending + case VM_RESET1: + { + //If we aborted a program, reset devices (specifically, motors) immediately + //Otherwise, wait for UI to put us into PROG_RESET (gives motors a chance to brake before setting to coast) + //!!! This means cCmdResetDevices will get called twice on abort. Should not be a big deal. + if (IOMapCmd.ProgStatus == PROG_ABORT) + cCmdResetDevices(); + + //Reenable UI access to buttons + pMapUi->Flags &= ~(UI_DISABLE_LEFT_RIGHT_ENTER | UI_DISABLE_EXIT); + +#if VM_BENCHMARK + if (IOMapCmd.Tick != VarsCmd.StartTick) + VarsCmd.Average = VarsCmd.InstrCount / (IOMapCmd.Tick - VarsCmd.StartTick); + else + //It appears that we finished in 0 milliseconds. Very unlikely on ARM, so set a flag value. + VarsCmd.Average = 0xFFFFFFFF; + + cCmdWriteBenchmarkFile(); +#endif + + //Re-initialize program state data (contents of memory pool preserved) + //!!! Skip this step in simulator builds so helper access methods still work +#ifndef SIM_NXT + cCmdDeactivateProgram(); +#endif //SIM_NXT + + //If this program has taken over the display, reset it for the UI + cCmdRestoreDefaultScreen(); + + //Stop any currently playing sound and re-init volume according to UI prefs + pMapSound->State = SOUND_STOP; + pMapSound->Volume = pMapUi->Volume; + + //Artificially set CommStatReset to BTBUSY to force at least one SETCMDMODE call (see VM_RESET2 case) + VarsCmd.CommStatReset = (SWORD)BTBUSY; + + VarsCmd.VMState = VM_RESET2; + while (IOMapCmd.Tick == dTimerRead()); // delay until scheduled time + } + break; + + case VM_RESET2: + { + //Reset BlueCore into "command mode" (close any open streams) + //Since SETCMDMODE subject to BTBUSY, we may need to make multiple calls + //Any CommStatReset value other than BTBUSY means our request was accepted + //Assumptions: + //Process should never take longer than UI timeout (see below), but if it does, + // we could be left with the stream open to an NXT peer and block out the PC. + //Also assuming that once SETCMDMODE request is accepted, it never fails. + if (VarsCmd.CommStatReset == (SWORD)BTBUSY && VarsCmd.DirtyComm == TRUE) + pMapComm->pFunc(SETCMDMODE, 0, 0, 0, NULL, (UWORD*)&(VarsCmd.CommStatReset)); + + //If UI is done displaying ending program status, move on. + if (IOMapCmd.ProgStatus == PROG_RESET) + { + //Reset devices whenever a program ends for any reason + cCmdResetDevices(); + + VarsCmd.DirtyComm = FALSE; + + //Go to VM_IDLE state + VarsCmd.VMState = VM_IDLE; + IOMapCmd.ProgStatus = PROG_IDLE; + } + while (IOMapCmd.Tick == dTimerRead()); // delay until scheduled time + } + break; + }//END state machine switch + + //Set tick to new value for next time 'round + IOMapCmd.Tick = dTimerReadNoPoll(); + + return; +} + + +void cCmdExit(void) +{ + dTimerExit(); + + return; +} + + +NXT_STATUS cCmdReadFileHeader(UBYTE* pData, ULONG DataSize, + PROG_FILE_OFFSETS* pFileOffsets) +{ + ULONG i; + UBYTE * pCursor; + UWORD CurrOffset = 0; + UBYTE DepCount; + UWORD DopeVectorOffset; + UWORD FileClumpCount; + UBYTE FileMajor, FileMinor, + CompatibleMinor, CompatibleMajor, + CurrentMajor; + + NXT_ASSERT(pData != NULL); + + if (strncmp((PSZ)pData, "NXTBINARY", VM_FORMAT_STRING_SIZE) == 0) + { + ULONG NativeOffset; + pCursor = (pData + 12); + NativeOffset = (ULONG)(*pCursor); + void (*native)(ULONG, ULONG) = (void (*)())(pData + NativeOffset); + (*native)((ULONG)pData, DataSize); + NXT_BREAK; + return (ERR_VER); + } + //Assign pCursor to point to version word inside file header + pCursor = (pData + VM_FORMAT_STRING_SIZE - 2); + + //Decode version numbers into comparable bytes + FileMajor = *pCursor; + FileMinor = *(pCursor + 1); + CompatibleMajor = (UBYTE)(VM_OLDEST_COMPATIBLE_VERSION >> 8); + CompatibleMinor = (UBYTE)(VM_OLDEST_COMPATIBLE_VERSION); + CurrentMajor = (UBYTE)(FIRMWAREVERSION >> 8); + //CurrentMinor = (UBYTE)(FIRMWAREVERSION); + + //Return ERR_VER if file lacks proper format string or version number + //!!! Only checking major version recommended for future development + if (strncmp((PSZ)pData, VM_FORMAT_STRING, VM_FORMAT_STRING_SIZE) + || FileMajor < CompatibleMajor || FileMinor < CompatibleMinor + || FileMajor > CurrentMajor) + { + NXT_BREAK; + return (ERR_VER); + } + + //Advance CurrOffset past header information + CurrOffset += VM_FORMAT_STRING_SIZE; + + // + //Initialize bookkeeping variables + // + VarsCmd.DataspaceCount = *((UWORD*)(pData + CurrOffset)); + CurrOffset += 2; + + VarsCmd.DataspaceSize = *((UWORD*)(pData + CurrOffset)); + CurrOffset += 2; + + VarsCmd.DSStaticSize = *((UWORD*)(pData + CurrOffset)); + CurrOffset += 2; + + pFileOffsets->DSDefaultsSize = *((UWORD*)(pData + CurrOffset)); + CurrOffset += 2; + + pFileOffsets->DynamicDefaults = *((UWORD*)(pData + CurrOffset)); + CurrOffset += 2; + + pFileOffsets->DynamicDefaultsSize = *((UWORD*)(pData + CurrOffset)); + CurrOffset += 2; + + VarsCmd.MemMgr.Head = *((UWORD*)(pData + CurrOffset)); + CurrOffset += 2; + + VarsCmd.MemMgr.Tail = *((UWORD*)(pData + CurrOffset)); + CurrOffset += 2; + + DopeVectorOffset = *((UWORD*)(pData + CurrOffset)); + CurrOffset += 2; + + //!!! Odd code here to deal with type mismatch between file format and CLUMP_ID typedef. + //Neither is trivial to change, so it's best to just check the data for consistency here. + FileClumpCount = *((UWORD*)(pData + CurrOffset)); + CurrOffset += 2; + + //Must have at least one clump and count can't exceed the NOT_A_CLUMP sentinel + if (FileClumpCount == 0 || FileClumpCount >= NOT_A_CLUMP) + return (ERR_FILE); + else + VarsCmd.AllClumpsCount = (CLUMP_ID)FileClumpCount; + + VarsCmd.CodespaceCount = *((UWORD*)(pData + CurrOffset)); + CurrOffset += 2; + + //Can't have a valid program with no code + if (VarsCmd.CodespaceCount == 0) + return (ERR_FILE); + + // + // Now, calculate offsets for each data segment in the file + // + + CurrOffset += CurrOffset % 2; + pFileOffsets->DSTOC = CurrOffset; + CurrOffset += VarsCmd.DataspaceCount * sizeof(DS_TOC_ENTRY); + + CurrOffset += CurrOffset % 2; + pFileOffsets->DSDefaults = CurrOffset; + CurrOffset += pFileOffsets->DSDefaultsSize; + + //ClumpRecs must be aligned on even boundaries + CurrOffset += CurrOffset % 2; + pFileOffsets->Clumps = CurrOffset; + + //Set cursor to start of clump records + pCursor = pData + CurrOffset; + + //Set CurrOffset to start of dependent lists + CurrOffset += VarsCmd.AllClumpsCount * VM_FILE_CLUMP_REC_SIZE; + + //Read dependent count from each clump record, advancing CurrOffset accordingly + for (i = 0; i < VarsCmd.AllClumpsCount; i++) + { + DepCount = *(pCursor + 1); + CurrOffset += DepCount; + pCursor += VM_FILE_CLUMP_REC_SIZE; + } + + //Codespace must be aligned on even boundary + CurrOffset += CurrOffset % 2; + pFileOffsets->Codespace = CurrOffset; + + //No need to read through codespace, but make sure CurrOffset ended up sane + //If not, something went wrong reading the header information + if (CurrOffset != (DataSize - VarsCmd.CodespaceCount * 2)) + { + NXT_BREAK; + return (ERR_FILE); + } + + // + // Finally, update VarsCmd fields + // + + VarsCmd.RunQ.Head = NOT_A_CLUMP; + VarsCmd.RunQ.Tail = NOT_A_CLUMP; + VarsCmd.RestQ.Head = NOT_A_CLUMP; + VarsCmd.RestQ.Tail = NOT_A_CLUMP; + + //Reset codespace pointer + VarsCmd.pCodespace = (CODE_WORD*)(pData + pFileOffsets->Codespace); + + //...placing clump records first... + VarsCmd.pAllClumps = (CLUMP_REC*)(VarsCmd.Pool + VarsCmd.PoolSize); + VarsCmd.PoolSize += VarsCmd.AllClumpsCount * sizeof(CLUMP_REC); + + //...then DSTOC... + VarsCmd.pDataspaceTOC = (DS_TOC_ENTRY*)(pData + pFileOffsets->DSTOC); + + //...then the dataspace itself + ALIGN_TO_MOD(VarsCmd.PoolSize, POOL_ALIGN); + VarsCmd.pDataspace = (VarsCmd.Pool + VarsCmd.PoolSize); + IOMapCmd.OffsetDS = (UWORD)((ULONG)(VarsCmd.pDataspace) - (ULONG)&(IOMapCmd)); + VarsCmd.PoolSize += VarsCmd.DataspaceSize; + + //init rest of MemMgr + VarsCmd.MemMgr.pDopeVectorArray = (DOPE_VECTOR *)(VarsCmd.pDataspace + DopeVectorOffset); + IOMapCmd.OffsetDVA = (UWORD)((ULONG)(VarsCmd.MemMgr.pDopeVectorArray) - (ULONG)&(IOMapCmd)); + VarsCmd.MemMgr.FreeHead = NOT_A_DS_ID; + + + if (VarsCmd.PoolSize > POOL_MAX_SIZE) + { + NXT_BREAK; + return (ERR_FILE); + } + + return (NO_ERR); +} + + +//!!! Recursive function +NXT_STATUS cCmdInflateDSDefaults(UBYTE* pDSDefaults, UWORD *pDefaultsOffset, DS_ELEMENT_ID DSElementID) +{ + NXT_STATUS Status = NO_ERR; + TYPE_CODE TypeCode; + UWORD i, Count; + UBYTE *pVal; + + NXT_ASSERT(cCmdIsDSElementIDSane(DSElementID)); + + TypeCode = cCmdDSType(DSElementID); + + if (TypeCode > TC_LAST_VALID) + return ERR_INSTR; + else if (TypeCode == TC_CLUSTER) + { + Count = cCmdClusterCount(DSElementID); + //Advance DSElementID to sub-type + DSElementID = INC_ID(DSElementID); + //Loop through sub-types, inflate recursively + for (i = 0; i < Count; i++) + { + Status = cCmdInflateDSDefaults(pDSDefaults, pDefaultsOffset, DSElementID); + if (IS_ERR(Status)) + return Status; + DSElementID = cCmdNextDSElement(DSElementID); + } + } + else + { + if (TypeCode == TC_ARRAY) + { + //Resolve pointer to DVIndex + pVal = VarsCmd.pDataspace + VarsCmd.pDataspaceTOC[DSElementID].DSOffset; + } + else + { + pVal = cCmdResolveDataArg(DSElementID, 0, NULL); + } + + //Check if the element has the "default default" + if (VarsCmd.pDataspaceTOC[DSElementID].Flags & DS_DEFAULT_DEFAULT) + { + //Fill element with the "default default" of zero + memset(pVal, 0, cCmdSizeOf(TypeCode)); + } + else + { + //Get default from stream + memmove(pVal, pDSDefaults + *pDefaultsOffset, cCmdSizeOf(TypeCode)); + *pDefaultsOffset += cCmdSizeOf(TypeCode); + } + } + + //!!! Currently will always return NO_ERR + return Status; +} + +void cCmdRefreshActiveClump(CLUMP_ID CurrID) +{ + CLUMP_REC * clumpRecPtr= &(VarsCmd.pAllClumps[CurrID]); + + if(clumpRecPtr->clumpScalarDispatchHints & scalarBinopDispatchMask) + InterpFuncs[8]= cCmdInterpScalarBinop; + else + InterpFuncs[8]= cCmdInterpBinop; + if(clumpRecPtr->clumpScalarDispatchHints & scalarUnop2DispatchMask) + InterpFuncs[6]= cCmdInterpScalarUnop2; + else + InterpFuncs[6]= cCmdInterpUnop2; +} + +NXT_STATUS cCmdActivateProgram(UBYTE * pFileName) +{ + UWORD i, j; + UBYTE * pCursor; + + NXT_STATUS Status = NO_ERR; + PROG_FILE_OFFSETS FileOffsets; + + LOADER_STATUS LStatus; + ULONG DataSize; + UBYTE * pData; + ULONG pDataHolder; + UWORD DefaultsOffset; + + LStatus = pMapLoader->pFunc(OPENREADLINEAR, pFileName, (UBYTE*)(&pDataHolder), &DataSize); + pData = (UBYTE*)(pDataHolder); + + //If Loader returned error or bad file pointer, bail out + if (LOADER_ERR(LStatus) != SUCCESS || pData == NULL || DataSize == 0) + return (ERR_FILE); + + //Deactivate current program and re-initialize memory pool + cCmdDeactivateProgram(); + cCmdInitPool(); + + //Stash this program's handle since we hold it open while running + VarsCmd.ActiveProgHandle = LOADER_HANDLE(LStatus); + + //Stash this program's name for easy reference later + strncpy((PSZ)(VarsCmd.ActiveProgName), (PSZ)(pFileName), FILENAME_LENGTH + 1); + + //Consume activation record data stream. + //See TargettingVIs/NXT.PackAR.vi for data stream packing details + + //Read header portion of the file, calculating offsets and initializing VarsCmd + Status = cCmdReadFileHeader(pData, DataSize, &FileOffsets); + if (IS_ERR(Status)) + return Status; + + //Do some spot checks to make sure bad file contents didn't leave us with obviously insane VarsCmd contents + //!!! Should add alignment checks on these pointers to avoid data abort exceptions later + if (((UBYTE*)(VarsCmd.pCodespace) < pData) + || ((UBYTE*)(VarsCmd.pCodespace) >= (pData + DataSize)) + || ((UBYTE*)(VarsCmd.pAllClumps) < POOL_START) + || ((UBYTE*)(VarsCmd.pAllClumps) >= POOL_SENTINEL) + || ((UBYTE*)(VarsCmd.pDataspace) < POOL_START) + || ((UBYTE*)(VarsCmd.pDataspace) >= POOL_SENTINEL) + || (VarsCmd.DataspaceSize == 0) ) + { + NXT_BREAK; + return ERR_FILE; + } + + //Initialize CLUMP_RECs as contiguous list in RAM + pCursor = (pData + FileOffsets.Clumps); + for (i = 0; i < VarsCmd.AllClumpsCount; i++) + { + CLUMP_REC *clumpPtr= &VarsCmd.pAllClumps[i]; + clumpPtr->InitFireCount = *(UBYTE*)(pCursor + i * VM_FILE_CLUMP_REC_SIZE); + clumpPtr->DependentCount = *(UBYTE*)(pCursor + (i * VM_FILE_CLUMP_REC_SIZE) + 1); + clumpPtr->CodeStart = *(UWORD*)(pCursor + (i * VM_FILE_CLUMP_REC_SIZE) + 2) + VarsCmd.pCodespace; + + //Initialize remaining CLUMP_REC fields + clumpPtr->PC = clumpPtr->CodeStart; + clumpPtr->Link = NOT_A_CLUMP; + + //Activate any clumps with CurrFireCount of 0 + clumpPtr->CurrFireCount = clumpPtr->InitFireCount; + if (clumpPtr->CurrFireCount == 0) + cCmdEnQClump(&(VarsCmd.RunQ), (CLUMP_ID)i); + } + + //Patch up dependents in separate pass (reuse of pCursor) + pCursor += VarsCmd.AllClumpsCount * VM_FILE_CLUMP_REC_SIZE; + for (i = 0; i < VarsCmd.AllClumpsCount; i++) + { + CLUMP_REC *clumpPtr= &VarsCmd.pAllClumps[i]; + if (clumpPtr->DependentCount > 0) + { + clumpPtr->pDependents = (CLUMP_ID*)(pCursor); + + pCursor += (clumpPtr->DependentCount * sizeof(CLUMP_ID)); + } + else + clumpPtr->pDependents = NULL; + + //Patch up CodeEnd value based on CodeStart of next clump or last overall codeword + if (i < (VarsCmd.AllClumpsCount - 1)) + clumpPtr->CodeEnd = (clumpPtr+1)->CodeStart - 1; + else + clumpPtr->CodeEnd = VarsCmd.CodespaceCount - 1 + VarsCmd.pCodespace; + + //Test for empty/insane clump code definitions + NXT_ASSERT(clumpPtr->CodeStart < clumpPtr->CodeEnd); + } + + // Check if the instructions within a clump are polymorphic and mark which table to dispatch from + for (i = 0; i < VarsCmd.AllClumpsCount; i++) + { // Check type on Boolean, math, ArrInit and ArrIndex, ingore GetSet I/O as these are always scalar + // do we need to check for DataArg encodings to I/O map??? GM + // Get Opcode and size of each instr, if ^^, check Arg types for Array or Cluster + CLUMP_REC *clumpPtr= &VarsCmd.pAllClumps[i]; + CODE_WORD *pInstr = clumpPtr->CodeStart, *lastPC = clumpPtr->CodeEnd; + ULONG InstrSize, opCode, shortOp, isT2Agg, isT3Agg, isScalarBinop= TRUE, isScalarUnop2= TRUE; + TYPE_CODE t1, t2, t3; + ULONG instrWord; + do + { + instrWord= *(UWORD*)pInstr; + opCode= OP_CODE(pInstr); + shortOp= (instrWord>>8) & 0x0F; + InstrSize = INSTR_SIZE(instrWord); + if (InstrSize == VAR_INSTR_SIZE) + InstrSize = ((UWORD*)pInstr)[1]; + if(shortOp <= 7) // no shorts are binOps + { + t2= cCmdDSType(pInstr[2]); + isT2Agg= IS_AGGREGATE_TYPE(t2); + if(InstrSize == 8) { + t3= cCmdDSType(pInstr[3]); + isT3Agg= IS_AGGREGATE_TYPE(t3); + if(isT2Agg || isT3Agg) { + if(opCode == OP_CMP) { + UBYTE isString2, isString3; + isString2= (t2 == TC_ARRAY) && cCmdDSType(INC_ID(pInstr[2])) == TC_UBYTE; + isString3= (t3 == TC_ARRAY) && cCmdDSType(INC_ID(pInstr[3])) == TC_UBYTE; + t1= cCmdDSType(pInstr[1]); + if((!isString2 || !isString3) || t1 == TC_ARRAY) // allow strings to go scalar, don't let through element compares of bytes or Bools + isScalarBinop= FALSE; + } + else if(opCode == OP_BRCMP) + isScalarBinop= FALSE; + } + } + else if(InstrSize == 6 && isT2Agg && (opCode == OP_NOT || opCode == OP_BRTST)) + isScalarUnop2= FALSE; + } + pInstr += InstrSize/2; + } while((isScalarBinop || isScalarUnop2) && pInstr < lastPC); + if(isScalarBinop) + clumpPtr->clumpScalarDispatchHints |= scalarBinopDispatchMask; + else + clumpPtr->clumpScalarDispatchHints &= ~scalarBinopDispatchMask; + + if(isScalarUnop2) + clumpPtr->clumpScalarDispatchHints |= scalarUnop2DispatchMask; + else + clumpPtr->clumpScalarDispatchHints &= ~scalarUnop2DispatchMask; + + } + //Programs with no active clumps constitutes an activation error + if (VarsCmd.RunQ.Head == NOT_A_CLUMP) + return (ERR_FILE); + else + { + // now that we know which clumps are scalar and poly, refresh dispatch table to match head + cCmdRefreshActiveClump(VarsCmd.RunQ.Head); + + } + + //Initialize dataspace with default values from file + //!!! This would be a good place to enforce check against potentially + // unsafe nested types (deeply nested types mean deep recursive calls) + DefaultsOffset = 0; + for (i = 0; i != NOT_A_DS_ID; i = cCmdNextDSElement(i)) + { + + Status = cCmdInflateDSDefaults(pData + FileOffsets.DSDefaults, &DefaultsOffset, i); + if (IS_ERR(Status)) + return Status; + } + + if ((DefaultsOffset != FileOffsets.DynamicDefaults) + || (DefaultsOffset + FileOffsets.DynamicDefaultsSize != FileOffsets.DSDefaultsSize)) + { + NXT_BREAK; + return (ERR_FILE); + } + + //Copy Dynamic defaults from file + memmove(VarsCmd.pDataspace + VarsCmd.DSStaticSize, pData + FileOffsets.DSDefaults + FileOffsets.DynamicDefaults, FileOffsets.DynamicDefaultsSize); + + // fix memmgr links. old files contain unused backPtrs, we now use these to store backLink + DV_INDEX prev= NOT_A_DS_ID; + for (i = VarsCmd.MemMgr.Head; i != NOT_A_DS_ID; i = DV_ARRAY[i].Link) { + DV_ARRAY[i].BackLink= prev; + prev= i; + } + + //Verify the MemMgr ended up where we said it would + if ((UBYTE *)VarsCmd.MemMgr.pDopeVectorArray != VarsCmd.pDataspace + DV_ARRAY[0].Offset) + { + NXT_BREAK; + return (ERR_FILE); + } + + //Initialize message queues + for (i = 0; i < MESSAGE_QUEUE_COUNT; i++) + { + VarsCmd.MessageQueues[i].ReadIndex = 0; + VarsCmd.MessageQueues[i].WriteIndex = 0; + + for (j = 0; j < MESSAGES_PER_QUEUE; j++) + { + VarsCmd.MessageQueues[i].Messages[j] = NOT_A_DS_ID; + } + } + + //Initialize datalog queue + VarsCmd.DatalogBuffer.ReadIndex = 0; + VarsCmd.DatalogBuffer.WriteIndex = 0; + for (j = 0; j < DATALOG_QUEUE_DEPTH; j++) + { + VarsCmd.DatalogBuffer.Datalogs[j] = NOT_A_DS_ID; + } + + // now that we've loaded program, prime memmgr dopevectors based upon number of handles in ds. + ULONG numHandles= DV_ARRAY[0].Count/2; + if(numHandles > 200) + numHandles= 200; + Status = cCmdGrowDopeVectorArray(numHandles); + + if (cCmdVerifyMemMgr() != TRUE) + return (ERR_FILE); + + gUsageSemData= 0; + gRequestSemData= 0; + // preload all calibration coefficients into mem + cCmdLoadCalibrationFiles(); + return (Status); +} + + +void cCmdDeactivateProgram() +{ + UBYTE i, tmp; + + //Wipe away all references into the pool and clear all run-time data + VarsCmd.pCodespace = NULL; + VarsCmd.CodespaceCount = 0; + + VarsCmd.pAllClumps = NULL; + VarsCmd.AllClumpsCount = 0; + + VarsCmd.DataspaceCount = 0; + VarsCmd.pDataspaceTOC = NULL; + VarsCmd.pDataspace = NULL; + VarsCmd.DataspaceSize = 0; + VarsCmd.DSStaticSize = 0; + + VarsCmd.MemMgr.Head = NOT_A_DS_ID; + VarsCmd.MemMgr.Tail = NOT_A_DS_ID; + VarsCmd.MemMgr.FreeHead = NOT_A_DS_ID; + VarsCmd.MemMgr.pDopeVectorArray = NULL; + + VarsCmd.RunQ.Head = NOT_A_CLUMP; + VarsCmd.RunQ.Tail = NOT_A_CLUMP; + + if (VarsCmd.ActiveProgHandle != NOT_A_HANDLE) + { + //Close handle that we've kept open for this program + pMapLoader->pFunc(CLOSE, &(VarsCmd.ActiveProgHandle), NULL, NULL); + VarsCmd.ActiveProgHandle = NOT_A_HANDLE; + + //Clear internal stashed name + memset(VarsCmd.ActiveProgName, 0, FILENAME_LENGTH + 1); + } + + //Close any files we had opened programatically + for (i = 0; i < MAX_HANDLES; i++) + { + //Copy i to tmp, because we pass a pointer to it to pFunc + tmp = i; + //Close file + if (*(VarsCmd.FileHandleTable[i]) != 0) + pMapLoader->pFunc(CROPDATAFILE, &tmp, NULL, NULL); + } + + //Clear FileHandleTable + memset(VarsCmd.FileHandleTable, 0, sizeof(VarsCmd.FileHandleTable)); + + return; +} + + +void cCmdResetDevices(void) +{ + UBYTE i; + + //Clear NXT button counts so 'bumped' will work on first run + for (i = 0; i < NO_OF_BTNS; i++) + { + pMapButton->BtnCnt[i].RelCnt = 0; + //Need to clear short and long counts too, because RelCnt depends on them. No known side effects. + pMapButton->BtnCnt[i].ShortRelCnt = 0; + pMapButton->BtnCnt[i].LongRelCnt = 0; + } + + for (i = 0; i < NO_OF_INPUTS; i++) + { + INPUTSTRUCT * pIn = &(pMapInput->Inputs[i]); + //Clear type and mode to defaults + pIn->SensorType = NO_SENSOR; + pIn->SensorMode = RAWMODE; + + //Reset input values to 0 prior to running (clear things like stale rotation counts) + pIn->ADRaw = 0; + pIn->SensorRaw = 0; + pIn->SensorValue = 0; + + //Assert invalid data flag so future code is aware of these changes + pIn->InvalidData = TRUE; + } + + for (i = 0; i < NO_OF_OUTPUTS; i++) + { + //Coast and reset all motor parameters + OUTPUT * pOut = &(pMapOutPut->Outputs[i]); + pOut->Mode = 0; + pOut->RegMode = REGULATION_MODE_IDLE; + pOut->RunState = MOTOR_RUN_STATE_IDLE; + pOut->Speed = 0; + pOut->TachoLimit = 0; + pOut->SyncTurnParameter = 0; + pOut->Flags = UPDATE_MODE | UPDATE_SPEED | UPDATE_TACHO_LIMIT | UPDATE_RESET_COUNT | UPDATE_RESET_BLOCK_COUNT | UPDATE_RESET_ROTATION_COUNT; + } + + //Lowspeed init, INSERT CODE !!! + for (i = 0; i < NO_OF_LOWSPEED_COM_CHANNEL; i++) + { + pMapLowSpeed->InBuf[i].InPtr = 0; + pMapLowSpeed->InBuf[i].OutPtr = 0; + pMapLowSpeed->InBuf[i].BytesToRx = 0; + pMapLowSpeed->OutBuf[i].InPtr = 0; + pMapLowSpeed->OutBuf[i].OutPtr = 0; + if (pMapLowSpeed->ChannelState[i] != LOWSPEED_IDLE) + { + pMapLowSpeed->ChannelState[i] = LOWSPEED_DONE; + pMapLowSpeed->State |= (0x01<Head == NOT_A_CLUMP) + { + NXT_ASSERT(Queue->Tail == NOT_A_CLUMP); + + Queue->Head = NewClump; + Queue->Tail = NewClump; + if(Queue == &(VarsCmd.RunQ)) + cCmdRefreshActiveClump(NewClump); + } + //Otherwise, tack onto the end + else + { + VarsCmd.pAllClumps[Queue->Tail].Link = NewClump; + Queue->Tail = NewClump; + } + + return; +} + +//Dequeue specified clump +//Normal usage is to dequeue only from the head (i.e. pass Queue.Head as arg) +void cCmdDeQClump(CLUMP_Q * Queue, CLUMP_ID Clump) +{ + CLUMP_ID CurrID, LinkID; + + //Make sure Clump's ID is valid and is already on Queue + NXT_ASSERT(cCmdIsClumpIDSane(Clump)); + NXT_ASSERT(cCmdIsQSane(Queue) == TRUE); + NXT_ASSERT(cCmdIsClumpOnQ(Queue, Clump)); + + CurrID = Queue->Head; + + //If our clump is the head, move up the next and disconnect + if (CurrID == Clump) + { + Queue->Head = VarsCmd.pAllClumps[Clump].Link; + VarsCmd.pAllClumps[Clump].Link = NOT_A_CLUMP; + + //If we just removed the last clump, patch up the queue's tail + if (Queue->Head == NOT_A_CLUMP) + Queue->Tail = NOT_A_CLUMP; + else if(Queue == &(VarsCmd.RunQ)) + cCmdRefreshActiveClump(Queue->Head); + } + //Else, look through rest of list looking for a link to our clump + else + { + do + { + CLUMP_REC *clumpPtr= &VarsCmd.pAllClumps[CurrID]; + LinkID = clumpPtr->Link; + + //If we find a link to our clump, patch up predecessor's link + if (clumpPtr->Link == Clump) + { + clumpPtr->Link = VarsCmd.pAllClumps[Clump].Link; + VarsCmd.pAllClumps[Clump].Link = NOT_A_CLUMP; + + //If we just removed the tail, patch tail + if (Clump == Queue->Tail) + Queue->Tail = CurrID; + } + + CurrID = LinkID; + } while (CurrID != NOT_A_CLUMP); + } + + return; +} + + +//Rotate head to tail and advance head for given Queue +void cCmdRotateQ() +{ + CLUMP_ID CurrID; + CLUMP_REC * pClumpRec; + CLUMP_Q * Queue = &VarsCmd.RunQ; + + //Make sure Queue is sane + NXT_ASSERT(cCmdIsQSane(Queue) == TRUE); + + //If queue has at least two clumps + if (Queue->Head != Queue->Tail) + { + CurrID = Queue->Head; + pClumpRec = &(VarsCmd.pAllClumps[CurrID]); + + //Disconnect head + Queue->Head = pClumpRec->Link; + pClumpRec->Link = NOT_A_CLUMP; + + //Reconnect head as tail + pClumpRec = &(VarsCmd.pAllClumps[Queue->Tail]); + pClumpRec->Link = CurrID; + Queue->Tail = CurrID; + + // reinit clump info + CurrID= Queue->Head; + cCmdRefreshActiveClump(Queue->Head); + + //Make sure we didn't make any really stupid mistakes + NXT_ASSERT(cCmdIsQSane(Queue) == TRUE); + } + + return; +} + + +UBYTE cCmdIsClumpOnQ(CLUMP_Q * Queue, CLUMP_ID Clump) +{ + CLUMP_ID CurrID; + + //Make sure Clump's ID is valid and is already on Queue + NXT_ASSERT(cCmdIsClumpIDSane(Clump)); + NXT_ASSERT(cCmdIsQSane(Queue) == TRUE); + + CurrID = Queue->Head; + + while (CurrID != NOT_A_CLUMP) + { + if (CurrID == Clump) + return TRUE; + + CurrID = VarsCmd.pAllClumps[CurrID].Link; + } + + return FALSE; +} + + +UBYTE cCmdIsQSane(CLUMP_Q * Queue) +{ + CLUMP_ID Head, Tail; + CLUMP_REC * pHead; + + if (Queue == NULL) + { + NXT_BREAK; + return FALSE; + } + + Head = Queue->Head; + Tail = Queue->Tail; + + if (Head == NOT_A_CLUMP && cCmdIsClumpIDSane(Tail)) + return FALSE; + + if (cCmdIsClumpIDSane(Head) && Tail == NOT_A_CLUMP) + return FALSE; + + if (cCmdIsClumpIDSane(Head) && cCmdIsClumpIDSane(Tail)) + { + pHead = &(VarsCmd.pAllClumps[Head]); + + //!!! More comprehensive queue tests could go here + + //Check for mislinked head if there are at least two queue members + if (Head != Tail && pHead->Link == NOT_A_CLUMP) + return FALSE; + } + + return TRUE; +} + +// +// Mutex queuing functions +// + +NXT_STATUS cCmdAcquireMutex(MUTEX_Q * Mutex) +{ + NXT_STATUS Status = NO_ERR; + CLUMP_ID Clump= VarsCmd.RunQ.Head; // save off before queue changes below + + NXT_ASSERT(Mutex != NULL && cCmdIsClumpIDSane(Clump)); + + if (Mutex->Owner == NOT_A_CLUMP) + { + //Mutex is open, so just take it + Mutex->Owner = Clump; + + NXT_ASSERT(Mutex->WaitQ.Head == NOT_A_CLUMP && Mutex->WaitQ.Tail == NOT_A_CLUMP); + } + else + { + //Mutex is reserved by someone else, take self off RunQ and add to WaitQ + cCmdDeQClump(&(VarsCmd.RunQ), Clump); + cCmdEnQClump(&(Mutex->WaitQ), Clump); + Status = CLUMP_SUSPEND; + } + + NXT_ASSERT(cCmdIsQSane(&(Mutex->WaitQ))); + + return (Status); +} + + +NXT_STATUS cCmdReleaseMutex(MUTEX_Q * Mutex) +{ +#if WIN_DEBUG || defined(ARM_DEBUG) + CLUMP_ID Clump= VarsCmd.RunQ.Head; +#endif + NXT_ASSERT(Mutex != NULL); + //!!! don't actually need to pass in Owner clump, but provides nice error checking for now + // Might want to return an error/warning if we see a Release on an free mutex, though... + NXT_ASSERT(Clump != NOT_A_CLUMP && Mutex->Owner == Clump); + + //Always set new Owner to WaitQ's Head, since NOT_A_CLUMP means mutex is free + Mutex->Owner = Mutex->WaitQ.Head; + + if (Mutex->Owner != NOT_A_CLUMP) + { + cCmdDeQClump(&(Mutex->WaitQ), Mutex->Owner); + cCmdEnQClump(&(VarsCmd.RunQ), Mutex->Owner); + } + + NXT_ASSERT(cCmdIsQSane(&(Mutex->WaitQ))); + NXT_ASSERT(cCmdIsQSane(&(VarsCmd.RunQ))); + + return (NO_ERR); +} + +// No instruction to do this yet, but put current clump to sleep until awakeTime occurs +NXT_STATUS cCmdSleepClump(ULONG time) +{ + CLUMP_ID Clump= VarsCmd.RunQ.Head; // save off before queue changes below + CLUMP_REC * pClump = &(VarsCmd.pAllClumps[Clump]); + cCmdDeQClump(&(VarsCmd.RunQ), Clump); + cCmdEnQClump(&(VarsCmd.RestQ), Clump); + pClump->awakenTime= time; + return CLUMP_SUSPEND; +} + +UBYTE cCmdCheckRestQ(ULONG currTime) +{ + UBYTE awakened= FALSE; + CLUMP_ID curr, next; + CLUMP_REC * pClump; + curr= VarsCmd.RestQ.Head; + while(curr != NOT_A_CLUMP) { + pClump= &(VarsCmd.pAllClumps[curr]); + next= pClump->Link; + if(pClump->awakenTime <= currTime) { + pClump->awakenTime= 0; // not necessary, but for debugging identification + cCmdDeQClump(&(VarsCmd.RestQ), curr); + cCmdEnQClump(&(VarsCmd.RunQ), curr); + awakened= TRUE; + } + curr= next; + } + return awakened; +} + +NXT_STATUS cCmdSchedDependents(CLUMP_ID Clump, SWORD Begin, SWORD End) +{ + CLUMP_ID CurrDepClumpID; + SWORD i; + + //Begin and End specify range of CLUMP_IDs in dependent list to schedule + //If either equals -1, both should equal -1, and no dependents will be scheduled + //Else schedule specified subset offset from pDependents + + //Check for valid args + NXT_ASSERT(cCmdIsClumpIDSane(Clump)); + NXT_ASSERT((Begin >= 0 && End >= 0 && End < VarsCmd.pAllClumps[Clump].DependentCount) + || (Begin == -1 && End == -1)); + + //If non-empty range + if (Begin != -1 || End != -1) + { + //update dependents, scheduling if their CurrFireCount reaches 0 + for (i = Begin; i <= End; i++) + { + CurrDepClumpID = VarsCmd.pAllClumps[Clump].pDependents[i]; + + NXT_ASSERT(cCmdIsClumpIDSane(CurrDepClumpID)); + + VarsCmd.pAllClumps[CurrDepClumpID].CurrFireCount--; + + if (VarsCmd.pAllClumps[CurrDepClumpID].CurrFireCount == 0) + cCmdEnQClump(&(VarsCmd.RunQ), CurrDepClumpID); + } + } + + return (NO_ERR); +} + + +NXT_STATUS cCmdSchedDependent(CLUMP_ID Clump, CLUMP_ID TargetClump) +{ + //TargetClump specifies the clump number of the target to schedule explicitly. + + //Check for valid args + NXT_ASSERT(cCmdIsClumpIDSane(Clump)); + NXT_ASSERT(cCmdIsClumpIDSane(TargetClump)); + + CLUMP_REC *clumpPtr= &VarsCmd.pAllClumps[TargetClump]; + clumpPtr->CurrFireCount--; + if (clumpPtr->CurrFireCount == 0) + cCmdEnQClump(&(VarsCmd.RunQ), TargetClump); + + return (NO_ERR); +} + + +UBYTE cCmdIsClumpIDSane(CLUMP_ID Clump) +{ + if (Clump < VarsCmd.AllClumpsCount) + return TRUE; + else + return FALSE; +} + + +// +// Memory pool management functions +// +void cCmdInitPool(void) +{ + ULONG i; + ULONG *poolPtr; + + //VarsCmd.Pool is a UBYTE pointer to ULONG array + //This was done to enforce portable alignment. + VarsCmd.Pool = (UBYTE*)(IOMapCmd.MemoryPool); + + for (i = (POOL_MAX_SIZE / 4), poolPtr= (ULONG*)&(POOL_START)[0]; i>0; i--, poolPtr++) + *poolPtr = 0xDEADBEEF; + + VarsCmd.PoolSize = 0; +} + + +#if VMProfilingCode +ULONG memMgrTime= 0; +#endif +NXT_STATUS cCmdDSArrayAlloc(DS_ELEMENT_ID DSElementID, UWORD Offset, UWORD NewCount) +{ + NXT_STATUS Status = NO_ERR; + UWORD DVIndex; + UWORD OldCount; + UWORD i; +#if VMProfilingCode + ULONG enterTime= dTimerReadHiRes(); +#endif + NXT_ASSERT(cCmdIsDSElementIDSane(DSElementID)); + + //Only arrays are valid here + //!!! Recommended to upgrade NXT_ASSERT to ERR_INSTR return + NXT_ASSERT(cCmdDSType(DSElementID) == TC_ARRAY); + + DVIndex = cCmdGetDVIndex(DSElementID, Offset); + OldCount = DV_ARRAY[DVIndex].Count; + + if(OldCount == NewCount) + goto allocExit; + Status = cCmdDVArrayAlloc(DVIndex, NewCount); + + if (Status < NO_ERR) + goto allocExit; + + if(!IS_AGGREGATE_TYPE(cCmdDSType(INC_ID(DSElementID)))) + goto allocExit; + + if (OldCount > NewCount) + { + //Free dope vectors for sub-arrays. + for (i = NewCount; i < OldCount; i++) + { + Status = cCmdFreeSubArrayDopeVectors(INC_ID(DSElementID), ARRAY_ELEM_OFFSET(DVIndex, i)); + if (IS_ERR(Status)) + goto allocExit; + } + } + else if (OldCount < NewCount) + { + //Alloc dope vectors for sub-arrays. Set up DVIndexes + for (i = OldCount; i < NewCount; i++) + { + Status = cCmdAllocSubArrayDopeVectors(INC_ID(DSElementID), ARRAY_ELEM_OFFSET(DVIndex, i)); + if (IS_ERR(Status)) + goto allocExit; + } + } + + NXT_ASSERT(cCmdVerifyMemMgr()); +allocExit: +#if VMProfilingCode + memMgrTime += dTimerReadHiRes() - enterTime; +#endif + return Status; +} + +NXT_STATUS cCmdDVArrayAlloc(DV_INDEX DVIndex, UWORD NewCount) +{ + NXT_STATUS Status = NO_ERR; + UBYTE *pData; + UWORD ArraySize, InplaceSize; + UWORD NextDVIndex; + UWORD OldCount; + + OldCount = DV_ARRAY[DVIndex].Count; + + if (OldCount == NewCount) + { + //Nothing to alloc. Return. + return Status; + } + else if (OldCount > NewCount) + { + //Already have the space. Shrink inplace. + DV_ARRAY[DVIndex].Count = NewCount; + return Status; + } + else // need to grow array + { + //Calculate new array size + ArraySize = NewCount * DV_ARRAY[DVIndex].ElemSize; + + //Try growing inplace + // If the Offset == NOT_AN_OFFSET then the array has never been allocated and can't grow inplace. + if (DV_ARRAY[DVIndex].Offset != NOT_AN_OFFSET) + { + //Get pointer to next dope vector in dataspace + if (DV_ARRAY[DVIndex].Link != NOT_A_DS_ID) + { + NextDVIndex = DV_ARRAY[DVIndex].Link; + InplaceSize = DV_ARRAY[NextDVIndex].Offset - DV_ARRAY[DVIndex].Offset; + } + else + { + //Last element in dataspace. + NXT_ASSERT(DVIndex == VarsCmd.MemMgr.Tail); + InplaceSize = VarsCmd.DataspaceSize - DV_ARRAY[DVIndex].Offset; + } + + if (ArraySize <= InplaceSize) + { + DV_ARRAY[DVIndex].Count = NewCount; + return Status; + } + } + + //Can't grow inplace, have to allocate new space + + //Make sure we properly align for type + //!!! This could also overflow memory (make PoolSize > POOL_MAX_SIZE) if we're within 3 bytes of the end. + // I don't think it matters because if it does happend, we'll trigger the ERR_MEM below and compact. + // During compaction, we'll reclaim these unused bytes. + //!!! Aligning beginning of ALL arrays to 4 byte address + ALIGN_TO_MOD(VarsCmd.PoolSize, SIZE_ULONG); + ALIGN_TO_MOD(VarsCmd.DataspaceSize, SIZE_ULONG); + + if (VarsCmd.PoolSize + ArraySize >= POOL_MAX_SIZE) + { + //Not enough memory available + return ERR_MEM; + } + + //Get data from end of pool + pData = VarsCmd.Pool + VarsCmd.PoolSize; + //Grow pool and dataspace + VarsCmd.PoolSize += ArraySize; + VarsCmd.DataspaceSize += ArraySize; + + //Move old Array Data to new allocation + if(OldCount) + memmove(pData, VarsCmd.pDataspace + DV_ARRAY[DVIndex].Offset, (UWORD)(DV_ARRAY[DVIndex].ElemSize * OldCount)); + //!!! Clear mem so old mem doesn't contain stale data. Not strictly needed. +#if WIN_DEBUG || defined(ARM_DEBUG) + memset(VarsCmd.pDataspace + DV_ARRAY[DVIndex].Offset, 0xFF, (UWORD)(DV_ARRAY[DVIndex].ElemSize * OldCount)); +#endif + //Update dope vector + DV_ARRAY[DVIndex].Offset = pData - VarsCmd.pDataspace; + DV_ARRAY[DVIndex].Count = NewCount; + + //Move dope vector to end of MemMgr list + Status = cCmdMemMgrMoveToTail(DVIndex); + if (IS_ERR(Status)) + return Status; + + NXT_ASSERT(cCmdVerifyMemMgr()); + } + + return Status; +} + + +//!!! Recursive function +NXT_STATUS cCmdAllocSubArrayDopeVectors(DS_ELEMENT_ID DSElementID, UWORD Offset) +{ + // Walks a single array element to see if it contains arrays + // For any array it finds, a dope vector is allocated and the DVIndex is placed in the dataspace for the parent array. + // This is a non-recursive function. It only walks the immediate array element. + // DSElementID - ID of array sub-entry + // Offset - offset to array element in dataspace + NXT_STATUS Status = NO_ERR; + TYPE_CODE TypeCode; + DV_INDEX DVIndex; + UWORD i; + UWORD DVIndexOffset; //Offset to DVIndex field that points to the DopeVector from pDataspace + UWORD LoopCount = 1; + UWORD ElemSize; + + for (i = 0; i < LoopCount; i++) + { + TypeCode = cCmdDSType((DS_ELEMENT_ID)(DSElementID + i)); + if (TypeCode == TC_CLUSTER) + { + LoopCount += cCmdClusterCount(DSElementID); + } + else if (TypeCode == TC_ARRAY) + { + //!!! ElemSize is a static value, but we don't have anywhere we put it (another TOC sub-entry?) + // It'd be nice to not have to recalculate it. + ElemSize = cCmdCalcArrayElemSize((DS_ELEMENT_ID)(DSElementID + i)); + DVIndexOffset = VarsCmd.pDataspaceTOC[DSElementID + i].DSOffset + Offset; + Status = cCmdAllocDopeVector(&DVIndex, ElemSize); + if (IS_ERR(Status)) + return Status; + + *((UWORD *)(VarsCmd.pDataspace + DVIndexOffset)) = DVIndex; + } + } + + return Status; +} + + +//!!! Recursive function +NXT_STATUS cCmdFreeSubArrayDopeVectors(DS_ELEMENT_ID DSElementID, UWORD Offset) +{ + // Walks a single array element to see if it contains arrays + // Frees all dope vectors associated with the array element. + // Recursively deletes sub-arrays. + // DSElementID - ID of array sub-entry + // Offset - offset to array element in dataspace + NXT_STATUS Status = NO_ERR; + TYPE_CODE TypeCode; + DV_INDEX DVIndex; + UWORD i, Count; + + TypeCode = cCmdDSType(DSElementID); + + if (TypeCode == TC_ARRAY) + { + DVIndex = cCmdGetDVIndex(DSElementID, Offset); + + NXT_ASSERT(DVIndex < DV_ARRAY[0].Count); + + Count = DV_ARRAY[DVIndex].Count; + //Recur on sub-elements + for (i = 0; i < Count; i++) + { + Status = cCmdFreeSubArrayDopeVectors(INC_ID(DSElementID), ARRAY_ELEM_OFFSET(DVIndex, i)); + if (IS_ERR(Status)) + return Status; + } + + //Free Dope Vector + Status = cCmdFreeDopeVector(DVIndex); + } + else if (TypeCode == TC_CLUSTER) + { + Count = cCmdClusterCount(DSElementID); + DSElementID = INC_ID(DSElementID); + //Recur on sub-elements + for (i = 0; i < Count; i++) + { + Status = cCmdFreeSubArrayDopeVectors((DS_ELEMENT_ID)(DSElementID + i), Offset); + if (IS_ERR(Status)) + return Status; + } + } + + return Status; +} + + +NXT_STATUS cCmdAllocDopeVector(DV_INDEX *pIndex, UWORD ElemSize) +{ + NXT_STATUS Status = NO_ERR; + + if (VarsCmd.MemMgr.FreeHead == NOT_A_DS_ID) + { + //No free DVs. Need to grow DopeVector array. + Status = cCmdGrowDopeVectorArray(DV_ARRAY_GROWTH_COUNT); + if (IS_ERR(Status)) + return Status; + } + + if(VarsCmd.MemMgr.FreeHead == NOT_A_DS_ID) + return ERR_MEM; + + //Remove DV from free list + *pIndex = VarsCmd.MemMgr.FreeHead; + VarsCmd.MemMgr.FreeHead = DV_ARRAY[*pIndex].Link; + if(VarsCmd.MemMgr.FreeHead != NOT_A_DS_ID) + DV_ARRAY[VarsCmd.MemMgr.FreeHead].BackLink= NOT_A_DS_ID; + //Add DV to tail of MemMgr list + Status = cCmdMemMgrInsertAtTail(*pIndex); + + //Initialize values + DV_ARRAY[*pIndex].Offset = NOT_AN_OFFSET; + DV_ARRAY[*pIndex].ElemSize = ElemSize; + DV_ARRAY[*pIndex].Count = 0; + + NXT_ASSERT(cCmdVerifyMemMgr()); + + return Status; +} + +// +//cCmdFreeDopeVector() - Open up a spot in the DopeVectorArray for future use +// The DopeVectorArray doesn't shrink when arrays (and their dope vectors) are deleted. +// Instead they're pushed on the free list and the array stays the same size. +// Future allocations check the free list before resorting to cCmdGrowDopeVectorArray() +// +NXT_STATUS cCmdFreeDopeVector(DV_INDEX DVIndex) +{ + NXT_STATUS Status = NO_ERR; + DV_INDEX prev, post; + + //Bounds check + NXT_ASSERT(DVIndex < DV_ARRAY[0].Count); + + //Reset dope vector fields + DV_ARRAY[DVIndex].Count = 0; + DV_ARRAY[DVIndex].ElemSize = 0; + DV_ARRAY[DVIndex].Offset = NOT_AN_OFFSET; + + //Remove from MemMgr list + if (DVIndex == VarsCmd.MemMgr.Head) + { + VarsCmd.MemMgr.Head = DV_ARRAY[DVIndex].Link; + if(VarsCmd.MemMgr.Head != NOT_A_DS_ID) + DV_ARRAY[VarsCmd.MemMgr.Head].BackLink= NOT_A_DS_ID; + } + else + { + // patchup middle or end of list. + prev= DV_ARRAY[DVIndex].BackLink; + post= DV_ARRAY[DVIndex].Link; + NXT_ASSERT(prev != NOT_A_DS_ID); + + DV_ARRAY[prev].Link = post; + if(post != NOT_A_DS_ID) + DV_ARRAY[post].BackLink= prev; + if (DVIndex == VarsCmd.MemMgr.Tail) + VarsCmd.MemMgr.Tail = prev; + //Make sure we found the previous DV, otherwise this DV was not in the the list (already freed?) + } + + //Push onto free list + DV_ARRAY[DVIndex].Link = VarsCmd.MemMgr.FreeHead; + DV_ARRAY[DVIndex].BackLink = NOT_A_DS_ID; + DV_ARRAY[VarsCmd.MemMgr.FreeHead].BackLink= DVIndex; + VarsCmd.MemMgr.FreeHead = DVIndex; + + NXT_ASSERT(cCmdVerifyMemMgr()); + + return Status; +} + +// +//cCmdGrowDopeVectorArray() - expand DopeVectorArray to be able to track more dataspace arrays +// +NXT_STATUS cCmdGrowDopeVectorArray(UWORD NewNodesCount) +{ + NXT_STATUS Status = NO_ERR; + UWORD ArraySize; + UWORD OldCount, NewCount, i; + UBYTE * pData; + + NXT_ASSERT(cCmdVerifyMemMgr()); + + OldCount = DV_ARRAY[0].Count; + NewCount = OldCount + NewNodesCount; + NXT_ASSERT(NewCount > OldCount); + + ArraySize = DV_ARRAY[0].ElemSize * NewCount; + + //!!! Aligning beginning of ALL arrays to 4 byte address + ALIGN_TO_MOD(VarsCmd.PoolSize, SIZE_ULONG); + ALIGN_TO_MOD(VarsCmd.DataspaceSize, SIZE_ULONG); + + if (VarsCmd.PoolSize + ArraySize >= POOL_MAX_SIZE) + { + //Not enough memory available + return ERR_MEM; + } + + //Get data from end of pool + pData = VarsCmd.Pool + VarsCmd.PoolSize; + //Grow pool and dataspace + VarsCmd.PoolSize += ArraySize; + VarsCmd.DataspaceSize += ArraySize; + + //Move DopeVector Array + memmove(pData, (UBYTE *)VarsCmd.MemMgr.pDopeVectorArray, (UWORD)(DV_ARRAY[0].ElemSize * DV_ARRAY[0].Count)); + + //Update MemMgr pointer + VarsCmd.MemMgr.pDopeVectorArray = (DOPE_VECTOR *)pData; + IOMapCmd.OffsetDVA = (UWORD)((ULONG)(VarsCmd.MemMgr.pDopeVectorArray) - (ULONG)&(IOMapCmd)); + + //Update dope vector + DV_ARRAY[0].Offset = pData - VarsCmd.pDataspace; + DV_ARRAY[0].Count = NewCount; + + //Add new DopeVectors to free list + //Push in reverse order so they get popped in order (mostly for ease of debugging) + for (i = NewCount - 1; i >= OldCount; i--) + { + DV_ARRAY[i].Offset = 0xFFFF; + DV_ARRAY[i].ElemSize = 0; + DV_ARRAY[i].Count = 0; + DV_ARRAY[i].BackLink = NOT_A_DS_ID; + if(VarsCmd.MemMgr.FreeHead != NOT_A_DS_ID) + DV_ARRAY[VarsCmd.MemMgr.FreeHead].BackLink = i; + DV_ARRAY[i].Link = VarsCmd.MemMgr.FreeHead; + VarsCmd.MemMgr.FreeHead = i; + } + + //Move dope vector to end of MemMgr list + Status = cCmdMemMgrMoveToTail(0); + + NXT_ASSERT(cCmdVerifyMemMgr()); + + return Status; +} + + +UWORD cCmdCalcArrayElemSize(DS_ELEMENT_ID DSElementID) +{ + TYPE_CODE TypeCode; + UWORD SizeOfType; + UWORD i; + UWORD LoopCount = 1; + UWORD Size = 0; + UWORD Alignment = 0; + + NXT_ASSERT(cCmdDSType(DSElementID) == TC_ARRAY); + + DSElementID = INC_ID(DSElementID); + for (i = 0; i < LoopCount; i++) + { + TypeCode = cCmdDSType((DS_ELEMENT_ID)(DSElementID + i)); + if (TypeCode == TC_CLUSTER) + { + LoopCount += cCmdClusterCount((DS_ELEMENT_ID)(DSElementID + i)); + } + else + { + SizeOfType = cCmdSizeOf(TypeCode); + ALIGN_TO_MOD(Size, SizeOfType); + Size += SizeOfType; + if (SizeOfType > Alignment) + Alignment = SizeOfType; + } + } + ALIGN_TO_MOD(Size, Alignment); + + return Size; +} + + +NXT_STATUS cCmdMemMgrMoveToTail(DV_INDEX DVIndex) +{ + DV_INDEX prev, post; + + //Bounds check + NXT_ASSERT(DVIndex < DV_ARRAY[0].Count); + + //Short circut if its already at the tail + if (DVIndex == VarsCmd.MemMgr.Tail) + return NO_ERR; + + if (DVIndex == VarsCmd.MemMgr.Head) { + VarsCmd.MemMgr.Head = DV_ARRAY[DVIndex].Link; + DV_ARRAY[VarsCmd.MemMgr.Head].BackLink= NOT_A_DS_ID; + } + else + { + // connect to middle or end of list. + prev= DV_ARRAY[DVIndex].BackLink; + post= DV_ARRAY[DVIndex].Link; + NXT_ASSERT(prev != NOT_A_DS_ID); + DV_ARRAY[prev].Link = post; + if(post != NOT_A_DS_ID) + DV_ARRAY[post].BackLink= prev; + } + + DV_ARRAY[DVIndex].Link = NOT_A_DS_ID; + DV_ARRAY[DVIndex].BackLink = VarsCmd.MemMgr.Tail; + if(VarsCmd.MemMgr.Tail != NOT_A_DS_ID) + DV_ARRAY[VarsCmd.MemMgr.Tail].Link = DVIndex; + VarsCmd.MemMgr.Tail = DVIndex; + + NXT_ASSERT(cCmdVerifyMemMgr()); + + return NO_ERR; +} + + +NXT_STATUS cCmdMemMgrInsertAtTail(DV_INDEX DVIndex) +{ + //Bounds check + NXT_ASSERT(DVIndex < DV_ARRAY[0].Count); + + DV_ARRAY[VarsCmd.MemMgr.Tail].Link = DVIndex; + DV_ARRAY[DVIndex].BackLink= VarsCmd.MemMgr.Tail; + DV_ARRAY[DVIndex].Link = NOT_A_DS_ID; + VarsCmd.MemMgr.Tail = DVIndex; + + NXT_ASSERT(cCmdVerifyMemMgr()); + + return NO_ERR; +} + + +UBYTE cCmdVerifyMemMgr() +{ + DV_INDEX i, prev, post; + UWORD CurrOffset = 0; + UWORD PrevOffset = 0; + UWORD DVCount = 0; + + //Make sure the MemMgr list is properly sorted in ascending offset order + for (i = VarsCmd.MemMgr.Head; i != NOT_A_DS_ID; i = DV_ARRAY[i].Link) + { + CurrOffset = DV_ARRAY[i].Offset; + + if (CurrOffset != 0xFFFF) + { + if (PrevOffset > CurrOffset) + return FALSE; + + PrevOffset = CurrOffset; + } + + prev= DV_ARRAY[i].BackLink; + post= DV_ARRAY[i].Link; + if (post == NOT_A_DS_ID && i != VarsCmd.MemMgr.Tail) + return FALSE; + else if(prev == NOT_A_DS_ID && i != VarsCmd.MemMgr.Head) + return FALSE; + else if(prev != NOT_A_DS_ID && DV_ARRAY[prev].Link != i) + return FALSE; + else if(post != NOT_A_DS_ID && DV_ARRAY[post].BackLink != i) + return FALSE; + + DVCount++; + } + + // could check link and backlinks too + for (i = VarsCmd.MemMgr.FreeHead; i != NOT_A_DS_ID; i = DV_ARRAY[i].Link) + { + DVCount++; + } + + //Make sure the # of dope vectors = # used + # free + if (DVCount != DV_ARRAY[0].Count) + return FALSE; + + return TRUE; +} + + +NXT_STATUS cCmdDSCompact(void) +{ + NXT_STATUS Status = NO_ERR; + + DV_INDEX CurrIndex; + UWORD NewOffset; + UWORD CurrOffset; + UWORD Size; + UWORD DeltaDSSize; + UWORD TempOffset, TempSize; + +#if VM_BENCHMARK + ULONG StartTime, TotalTime; + + VarsCmd.CompactionCount++; + VarsCmd.LastCompactionTick = IOMapCmd.Tick - VarsCmd.StartTick; + + StartTime = dTimerRead(); +#endif + + NXT_ASSERT(cCmdVerifyMemMgr()); + + NewOffset = VarsCmd.DSStaticSize; + for (CurrIndex = VarsCmd.MemMgr.Head; CurrIndex != NOT_A_DS_ID; CurrIndex = DV_ARRAY[CurrIndex].Link) + { + //Align NewOffset for array to 4 byte address. + ALIGN_TO_MOD(NewOffset, SIZE_ULONG); + + CurrOffset = DV_ARRAY[CurrIndex].Offset; + if (CurrOffset != NOT_AN_OFFSET) + { + Size = DV_ARRAY[CurrIndex].ElemSize * DV_ARRAY[CurrIndex].Count; + if (CurrOffset != NewOffset) + { + NXT_ASSERT(NewOffset < CurrOffset); + memmove(VarsCmd.pDataspace + NewOffset, VarsCmd.pDataspace + CurrOffset, Size); + + // Clear mem to make stale data references more obvious while debugging. + // Correct for overlapping memory regions (make sure we don't clear what we just moved). + //!!! Clearing step not strictly necessary, so it could be optimized out + if (NewOffset + Size > CurrOffset) + { + TempOffset = NewOffset + Size; + TempSize = Size - (TempOffset - CurrOffset); + } + else + { + TempOffset = CurrOffset; + TempSize = Size; + } + memset(VarsCmd.pDataspace + TempOffset, 0xFF, TempSize); + + //Update pDopeVectorArray if we move the dope vector array + if (CurrIndex == 0) + { + VarsCmd.MemMgr.pDopeVectorArray = (DOPE_VECTOR *)(VarsCmd.pDataspace + NewOffset); + IOMapCmd.OffsetDVA = (UWORD)((ULONG)(VarsCmd.MemMgr.pDopeVectorArray) - (ULONG)&(IOMapCmd)); + } + + //Update offset in DV Array + DV_ARRAY[CurrIndex].Offset = NewOffset; + } + + NewOffset += Size; + } + } + + DeltaDSSize = VarsCmd.DataspaceSize - NewOffset; + + VarsCmd.PoolSize -= DeltaDSSize; + VarsCmd.DataspaceSize -= DeltaDSSize; + + NXT_ASSERT(cCmdVerifyMemMgr()); + +#if VM_BENCHMARK + TotalTime = dTimerRead() - StartTime; + + if (TotalTime > VarsCmd.MaxCompactionTime) + VarsCmd.MaxCompactionTime = TotalTime; +#endif + + return Status; +} + + +// +// Message Queue functions +// + +NXT_STATUS cCmdMessageWrite(UWORD QueueID, UBYTE * pData, UWORD Length) +{ + NXT_STATUS Status = NO_ERR; + + if (pData == NULL) + return ERR_ARG; + + if (QueueID >= MESSAGE_QUEUE_COUNT) + return ERR_INVALID_QUEUE; + + if (VarsCmd.ActiveProgHandle == NOT_A_HANDLE) + return ERR_NO_PROG; + + //Can't accept oversize messages because we treat them as strings (truncation would remove null termination) + if (Length > MAX_MESSAGE_SIZE) + return ERR_INVALID_SIZE; + + if (IS_DV_INDEX_SANE(GET_WRITE_MSG(QueueID))) + { + //A message is already there, the queue is full + NXT_ASSERT(VarsCmd.MessageQueues[QueueID].WriteIndex == VarsCmd.MessageQueues[QueueID].ReadIndex); + + //Bump read index, drop existing message to make room for our new incoming message + VarsCmd.MessageQueues[QueueID].ReadIndex = (VarsCmd.MessageQueues[QueueID].ReadIndex + 1) % MESSAGES_PER_QUEUE; + } + else + { + //Allocate dope vector for message + Status = cCmdAllocDopeVector(&GET_WRITE_MSG(QueueID), 1); + if (IS_ERR(Status)) + return Status; + } + + //Allocate storage for message + Status = cCmdDVArrayAlloc(GET_WRITE_MSG(QueueID), Length); + if (IS_ERR(Status)) + { + //Clear the dope vector for the message, since we're unable to put a message there. + cCmdFreeDopeVector(GET_WRITE_MSG(QueueID)); + SET_WRITE_MSG(QueueID, NOT_A_DS_ID); + return Status; + } + + //Copy message + memmove(cCmdDVPtr(GET_WRITE_MSG(QueueID)), pData, Length); + + //Advance write index + VarsCmd.MessageQueues[QueueID].WriteIndex = (VarsCmd.MessageQueues[QueueID].WriteIndex + 1) % MESSAGES_PER_QUEUE; + + return Status; +} + + +NXT_STATUS cCmdMessageGetSize(UWORD QueueID, UWORD * Size) +{ + DV_INDEX ReadDVIndex; + + if (Size == NULL) + return (ERR_ARG); + + if (VarsCmd.ActiveProgHandle == NOT_A_HANDLE) + { + *Size = 0; + return (ERR_NO_PROG); + } + + if (QueueID >= MESSAGE_QUEUE_COUNT) + { + *Size = 0; + return (ERR_INVALID_QUEUE); + } + + ReadDVIndex = GET_READ_MSG(QueueID); + + if (IS_DV_INDEX_SANE(ReadDVIndex)) + { + *Size = (DV_ARRAY[ReadDVIndex].Count); + return (NO_ERR); + } + else + { + *Size = 0; + return (STAT_MSG_EMPTY_MAILBOX); + } +} + + +NXT_STATUS cCmdMessageRead(UWORD QueueID, UBYTE * pBuffer, UWORD Length, UBYTE Remove) +{ + NXT_STATUS Status = NO_ERR; + DV_INDEX ReadDVIndex; + + if (pBuffer == NULL) + return (ERR_ARG); + + if (VarsCmd.ActiveProgHandle == NOT_A_HANDLE) + return (ERR_NO_PROG); + + if (QueueID >= MESSAGE_QUEUE_COUNT) + return (ERR_INVALID_QUEUE); + + ReadDVIndex = GET_READ_MSG(QueueID); + + if (IS_DV_INDEX_SANE(ReadDVIndex)) + { + //If Buffer doesn't have room for the entire message, + //don't risk incomplete string floating around + if (Length < DV_ARRAY[ReadDVIndex].Count) + return (ERR_INVALID_SIZE); + + //Copy message + memmove(pBuffer, cCmdDVPtr(ReadDVIndex), DV_ARRAY[ReadDVIndex].Count); + + if (Remove) + { + //Free memory used by message + Status = cCmdFreeDopeVector(ReadDVIndex); + if (IS_ERR(Status)) + return Status; + + SET_READ_MSG(QueueID, NOT_A_DS_ID); + + //Advance read index + VarsCmd.MessageQueues[QueueID].ReadIndex = (VarsCmd.MessageQueues[QueueID].ReadIndex + 1) % MESSAGES_PER_QUEUE; + } + } + else + { + //No message to read, message Queue is empty + NXT_ASSERT(VarsCmd.MessageQueues[QueueID].ReadIndex == VarsCmd.MessageQueues[QueueID].WriteIndex); + + return (STAT_MSG_EMPTY_MAILBOX); + } + + return Status; +} + +// +// Datalog Queue function(s) +// + +NXT_STATUS cCmdDatalogWrite(UBYTE * pData, UWORD Length) +{ + NXT_STATUS Status = NO_ERR; + + if (pData == NULL) + return ERR_ARG; + + if (VarsCmd.ActiveProgHandle == NOT_A_HANDLE) + return (ERR_NO_PROG); + + //Can't accept oversize messages because we treat them as strings (truncation would remove null termination) + if (Length > MAX_DATALOG_SIZE) + return ERR_INVALID_SIZE; + + if (IS_DV_INDEX_SANE(GET_WRITE_DTLG())) + { + //A message is already there, the queue is full + NXT_ASSERT(VarsCmd.DatalogBuffer.WriteIndex == VarsCmd.DatalogBuffer.ReadIndex); + Status = STAT_MSG_BUFFERWRAP; + //Bump read index, drop existing message to make room for our newly acquired datalog + VarsCmd.DatalogBuffer.ReadIndex = (VarsCmd.DatalogBuffer.ReadIndex + 1) % DATALOG_QUEUE_DEPTH; + } + else + { + //Allocate dope vector for message + Status = cCmdAllocDopeVector(&GET_WRITE_DTLG(), 1); + if (IS_ERR(Status)) + return Status; + } + + //Allocate storage for message + Status |= cCmdDVArrayAlloc(GET_WRITE_DTLG(), Length); + if (IS_ERR(Status)) + { + //Clear the dope vector for the message, since we're unable to put a message there. + cCmdFreeDopeVector(GET_WRITE_DTLG()); + SET_WRITE_DTLG(NOT_A_DS_ID); + return Status; + } + + //Copy message + memmove(cCmdDVPtr(GET_WRITE_DTLG()), pData, Length); + + //Advance write index + VarsCmd.DatalogBuffer.WriteIndex = (VarsCmd.DatalogBuffer.WriteIndex + 1) % DATALOG_QUEUE_DEPTH; + + return Status; +} + +NXT_STATUS cCmdDatalogGetSize(UWORD * Size) +{ + DV_INDEX ReadDVIndex; + + if (Size == NULL) + return (ERR_ARG); + + if (VarsCmd.ActiveProgHandle == NOT_A_HANDLE) + { + *Size = 0; + return (ERR_NO_PROG); + } + + ReadDVIndex = GET_READ_DTLG(); + + if (IS_DV_INDEX_SANE(ReadDVIndex)) + { + *Size = (DV_ARRAY[ReadDVIndex].Count); + return (NO_ERR); + } + else + { + *Size = 0; + return (STAT_MSG_EMPTY_MAILBOX); + } +} + +NXT_STATUS cCmdDatalogRead(UBYTE * pBuffer, UWORD Length, UBYTE Remove) +{ + NXT_STATUS Status = NO_ERR; + DV_INDEX ReadDVIndex; + + if (pBuffer == NULL) + return (ERR_ARG); + + if (VarsCmd.ActiveProgHandle == NOT_A_HANDLE) + return (ERR_NO_PROG); + + ReadDVIndex = GET_READ_DTLG(); + + if (IS_DV_INDEX_SANE(ReadDVIndex)) + { + //If Buffer doesn't have room for the entire message, + //don't risk incomplete string floating around + if (Length < DV_ARRAY[ReadDVIndex].Count) + return (ERR_INVALID_SIZE); + + //Copy message + memmove(pBuffer, cCmdDVPtr(ReadDVIndex), DV_ARRAY[ReadDVIndex].Count); + + if (Remove) + { + //Free memory used by message + Status = cCmdFreeDopeVector(ReadDVIndex); + if (IS_ERR(Status)) + return Status; + + SET_READ_DTLG(NOT_A_DS_ID); + + //Advance read index + VarsCmd.DatalogBuffer.ReadIndex = (VarsCmd.DatalogBuffer.ReadIndex + 1) % DATALOG_QUEUE_DEPTH; + } + } + else + { + //No message to read, datalog Queue is empty + NXT_ASSERT(VarsCmd.DatalogBuffer.ReadIndex == VarsCmd.DatalogBuffer.WriteIndex); + + return (STAT_MSG_EMPTY_MAILBOX); + } + + return Status; +} + + +// +// Color Sensor Functions +// +NXT_STATUS cCmdColorSensorRead (UBYTE Port, SWORD * SensorValue, UWORD * RawArray, UWORD * NormalizedArray, + SWORD * ScaledArray, UBYTE * InvalidData) +{ + ULONG i; + //Make sure Port is valid for Color Sensor + INPUTSTRUCT * pIn = &(pMapInput->Inputs[Port]); + UBYTE sType = pIn->SensorType; + if (!(sType == COLORFULL || sType == COLORRED || sType == COLORGREEN || + sType == COLORBLUE || sType == COLORNONE)) + { + return (ERR_COMM_CHAN_NOT_READY); //TODO - is this the right error? + } + //Copy Detected Color + *SensorValue = pIn->SensorValue; + + //Copy all raw, normalized and scaled data from I/O Map + for (i=0; iColors[Port]); + RawArray[i] = pColor->ADRaw[i]; + NormalizedArray[i] = pColor->SensorRaw[i]; + ScaledArray[i] = pColor->SensorValue[i]; + } + //Copy the Invalid Data Flag + *InvalidData = pIn->InvalidData; + + return NO_ERR; + +} + + +// +// Dataspace Support functions +// + +UBYTE cCmdIsDSElementIDSane(DS_ELEMENT_ID Index) +{ + if (Index < VarsCmd.DataspaceCount) + return TRUE; + else + return FALSE; +} + +void * cCmdResolveDataArg(DATA_ARG DataArg, UWORD Offset, TYPE_CODE * TypeCode) +{ + void * ret_val = NULL; + + //!!! DATA_ARG masking system only for internal c_cmd use! + // All normal bytecode arguments should go through top if() block. + + NXT_ASSERT(cCmdIsDSElementIDSane(DataArg)); + ret_val = cCmdDSPtr(DataArg, Offset); + if (TypeCode) + *TypeCode = VarsCmd.pDataspaceTOC[DataArg].TypeCode; + + //!!! Caller beware! If DataArg isn't sane, ret_val may be out of range or NULL! + return ret_val; +} + +// normal Resolve handles both, but this is specific to I/O args +void * cCmdResolveIODataArg(DATA_ARG DataArg, ULONG Offset, TYPE_CODE * TypeCode) + { + void * ret_val = NULL; + + ULONG ModuleID; + ULONG FieldID; + //DataArg refers to a field in the IO map + // ModuleID = ((DataArg >> 9) & 0x1F); + ModuleID = ((DataArg & 0x3FFF) >> 9); + FieldID = (DataArg & 0x01FF); + + //!!! Preliminary bounds check -- still could allow invalid combos through + if (ModuleID > MOD_OUTPUT || FieldID >= IO_OUT_FIELD_COUNT) + { + NXT_BREAK; + return NULL; + } + + ret_val = IO_PTRS[ModuleID][FieldID]; + if (TypeCode) + *TypeCode = IO_TYPES[ModuleID][FieldID]; + return ret_val; +} + +void cCmdSetValFlt(void * pVal, TYPE_CODE TypeCode, float NewVal) +{ + + if (pVal) + { + switch (TypeCode) + { + case TC_ULONG: + case TC_SLONG: + { + *(ULONG*)pVal = NewVal; + } + break; + + case TC_UWORD: + case TC_SWORD: + { + *(UWORD*)pVal = (UWORD)NewVal; + } + break; + + case TC_UBYTE: + case TC_SBYTE: + { + *(UBYTE*)pVal = (UBYTE)NewVal; + } + break; + + case TC_FLOAT: + { + *(float*)pVal = (float)NewVal; + } + break; + } + } + + return; +} + +ULONG cCmdGetUByte(void * pVal); +ULONG cCmdGetSByte(void * pVal); +ULONG cCmdGetUWord(void * pVal); +ULONG cCmdGetSWord(void * pVal); +ULONG cCmdGetULong(void * pVal); +ULONG cCmdGetSLong(void * pVal); +ULONG cCmdGetError(void * pVal); +ULONG cCmdGetFloat(void * pVal); + +void cCmdSetByte(void * pVal, ULONG NewVal); +void cCmdSetWord(void * pVal, ULONG NewVal); +void cCmdSetLong(void * pVal, ULONG NewVal); +void cCmdSetError(void * pVal, ULONG NewVal); + + +typedef ULONG (*pGetOperand)(void *); +static pGetOperand GetProcArray[11]= {cCmdGetUByte, cCmdGetUByte, cCmdGetSByte, cCmdGetUWord, cCmdGetSWord, cCmdGetULong, cCmdGetSLong, cCmdGetError, cCmdGetError, cCmdGetError, cCmdGetFloat}; // dup UByte to line up + +typedef void (*pSetOperand)(void *, ULONG); +static pSetOperand SetProcArray[9]= {cCmdSetByte, cCmdSetByte, cCmdSetByte, cCmdSetWord, cCmdSetWord, cCmdSetLong, cCmdSetLong, cCmdSetError, cCmdSetError}; // dup UByte to line up + +void cCmdSetError(void * pVal, ULONG NewVal) { + NXT_BREAK; +} + +void cCmdSetLong(void * pVal, ULONG NewVal) { + *(ULONG*)pVal = NewVal; +} + +void cCmdSetWord(void * pVal, ULONG NewVal) { + *(UWORD*)pVal = (UWORD)NewVal; +} + +void cCmdSetByte(void * pVal, ULONG NewVal) { + *(UBYTE*)pVal = (UBYTE)NewVal; +} + +// only works on simple types, equivalent to resolve and get, but faster +ULONG cCmdGetScalarValFromDataArg(DATA_ARG DataArg, UWORD Offset) +{ + DS_TOC_ENTRY *dsTOCPtr= &VarsCmd.pDataspaceTOC[DataArg]; + return GetProcArray[dsTOCPtr->TypeCode](VarsCmd.pDataspace + dsTOCPtr->DSOffset + Offset); +} + + +ULONG cCmdGetError(void * pVal) { + NXT_BREAK; + return 0; +} + +ULONG cCmdGetULong(void * pVal) { + return (ULONG)(*(ULONG*)pVal); +} + +ULONG cCmdGetSLong(void * pVal) { + return (SLONG)(*(SLONG*)pVal); +} + +ULONG cCmdGetUWord(void * pVal) { + return (UWORD)(*(UWORD*)pVal); +} + +ULONG cCmdGetSWord(void * pVal) { + return (SWORD)(*(SWORD*)pVal); +} + +ULONG cCmdGetUByte(void * pVal) { + return (UBYTE)(*(UBYTE*)pVal); +} + +ULONG cCmdGetSByte(void * pVal) { + return (SBYTE)(*(SBYTE*)pVal); +} + +ULONG cCmdGetFloat(void * pVal) { + float tempVal = *(float*)pVal; + if (tempVal >= 0.0f) { + tempVal += 0.5f; + } + else { + tempVal -= 0.5f; + } + return (ULONG)tempVal; +} + +ULONG cCmdGetVal(void * pVal, TYPE_CODE TypeCode) +{ + if (pVal) + return GetProcArray[TypeCode](pVal); + else + //!!! Default return value places responsibility on caller to use this function wisely + return 0; +} + + +float cCmdGetValFlt(void * pVal, TYPE_CODE TypeCode) +{ + if (pVal) + { + switch (TypeCode) + { + case TC_ULONG: + { + return (ULONG)(*(ULONG*)pVal); + } + + case TC_SLONG: + { + return (SLONG)(*(SLONG*)pVal); + } + + case TC_UWORD: + { + return (UWORD)(*(UWORD*)pVal); + } + + case TC_SWORD: + { + return (SWORD)(*(SWORD*)pVal); + } + + case TC_UBYTE: + { + return (UBYTE)(*(UBYTE*)pVal); + } + + case TC_SBYTE: + { + return (SBYTE)(*(SBYTE*)pVal); + } + + case TC_FLOAT: + { + return (float)(*(float*)pVal); + } + + default: + break; + } + } + + //!!! Default return value places responsibility on caller to use this function wisely + return 0; +} + + + +// Only for scalar types and no offset +void cCmdSetScalarValFromDataArg(DATA_ARG DataArg, ULONG NewVal) +{ + DS_TOC_ENTRY *dsTOCPtr= &VarsCmd.pDataspaceTOC[DataArg]; + SetProcArray[dsTOCPtr->TypeCode](VarsCmd.pDataspace + dsTOCPtr->DSOffset, NewVal); +} + +void cCmdSetVal(void * pVal, TYPE_CODE TypeCode, ULONG NewVal) +{ + if (pVal) + SetProcArray[TypeCode](pVal, NewVal); +} + +void* cCmdDSPtr(DS_ELEMENT_ID DSElementID, UWORD Offset) +{ + void * pDSItem; + DV_INDEX DVIndex; + TYPE_CODE TypeCode; + + NXT_ASSERT(cCmdIsDSElementIDSane(DSElementID)); + + TypeCode = cCmdDSType(DSElementID); + if (TypeCode == TC_ARRAY) + { + //!!! Empty arrays return NULL. + if (cCmdArrayCount(DSElementID, Offset) == 0) + pDSItem = NULL; + else + { + DVIndex = cCmdGetDVIndex(DSElementID, Offset); + pDSItem = (VarsCmd.pDataspace + DV_ARRAY[DVIndex].Offset); + } + } + else if (TypeCode == TC_CLUSTER) + { + NXT_ASSERT(cCmdClusterCount(DSElementID) != 0) + + //Returning pointer to the first element in the cluster + pDSItem = cCmdDSPtr(INC_ID(DSElementID), Offset); + } + else + pDSItem = (VarsCmd.pDataspace + VarsCmd.pDataspaceTOC[DSElementID].DSOffset + Offset); + + NXT_ASSERT((UBYTE*)pDSItem < POOL_SENTINEL); + + return pDSItem; +} + +void* cCmdDVPtr(DV_INDEX DVIndex) +{ + NXT_ASSERT(IS_DV_INDEX_SANE(DVIndex)); + return (VarsCmd.pDataspace + DV_ARRAY[DVIndex].Offset); +} + + +//!!! Recursive function +DS_ELEMENT_ID cCmdNextDSElement(DS_ELEMENT_ID CurrID) +{ + DS_ELEMENT_ID NextID; + TYPE_CODE CurrType; + UWORD ClusterCount, i; + + NXT_ASSERT(cCmdIsDSElementIDSane(CurrID)); + + NextID = CurrID + 1; + + if (!cCmdIsDSElementIDSane(NextID)) + return NOT_A_DS_ID; + + CurrType = cCmdDSType(CurrID); + + if (CurrType == TC_ARRAY) + { + //Arrays contain two elements. Advance past the second one. + NextID = cCmdNextDSElement(NextID); + } + else if (CurrType == TC_CLUSTER) + { + ClusterCount = cCmdClusterCount(CurrID); + for (i = 0; i < ClusterCount; i++) + { + NextID = cCmdNextDSElement(NextID); + } + } + + return NextID; +} + + +//!!! Recursive function +UBYTE cCmdCompareDSType(DS_ELEMENT_ID DSElementID1, DS_ELEMENT_ID DSElementID2) +{ + TYPE_CODE Type1, Type2; + UWORD i, Count1, Count2; + + Type1 = cCmdDSType(DSElementID1); + Type2 = cCmdDSType(DSElementID2); + + if (Type1 != Type2) + return FALSE; + + if (Type1 == TC_CLUSTER) + { + Count1 = cCmdClusterCount(DSElementID1); + Count2 = cCmdClusterCount(DSElementID2); + + if(Count1 != Count2) + return FALSE; + + DSElementID1 = INC_ID(DSElementID1); + DSElementID2 = INC_ID(DSElementID2); + + for (i = 0; i < Count1; i++) + { + if (!cCmdCompareDSType(DSElementID1, DSElementID2)) + return FALSE; + + DSElementID1 = cCmdNextDSElement(DSElementID1); + DSElementID2 = cCmdNextDSElement(DSElementID2); + } + } + else if (Type1 == TC_ARRAY) + { + if (!cCmdCompareDSType(INC_ID(DSElementID1), INC_ID(DSElementID2))) + return FALSE; + } + + return TRUE; +} + + +//!!! Recursive function +UWORD cCmdCalcFlattenedSize(DS_ELEMENT_ID DSElementID, UWORD Offset) +{ + UWORD Size = 0; + TYPE_CODE TypeCode; + DV_INDEX DVIndex; + UWORD i; + UWORD Count; + + TypeCode = cCmdDSType(DSElementID); + + if (TypeCode == TC_ARRAY) + { + DVIndex = cCmdGetDVIndex(DSElementID, Offset); + + DSElementID = INC_ID(DSElementID); + TypeCode = cCmdDSType(DSElementID); + + if (!IS_AGGREGATE_TYPE(TypeCode)) + { + //Short circuit recursive calculation if our array sub-type is a scalar + Size += DV_ARRAY[DVIndex].ElemSize * DV_ARRAY[DVIndex].Count; + } + else + { + //If the sub type is an aggregate type, then it can contain arrays, so we have to recur + for (i = 0; i < DV_ARRAY[DVIndex].Count; i++) + { + Size += cCmdCalcFlattenedSize(DSElementID, ARRAY_ELEM_OFFSET(DVIndex, i)); + } + } + } + else if (TypeCode == TC_CLUSTER) + { + Count = cCmdClusterCount(DSElementID); + + DSElementID = INC_ID(DSElementID); + for (i = 0; i < Count; i++) + { + Size += cCmdCalcFlattenedSize(DSElementID, Offset); + DSElementID = cCmdNextDSElement(DSElementID); + } + } + else //Scalar + { + Size += cCmdSizeOf(TypeCode); + } + return Size; +} + + +//!!! Recursive function +NXT_STATUS cCmdFlattenToByteArray(UBYTE * pByteArray, UWORD * pByteOffset, DS_ELEMENT_ID DSElementID, UWORD Offset) +{ + NXT_STATUS Status = NO_ERR; + TYPE_CODE TypeCode; + DV_INDEX DVIndex; + UWORD i; + UWORD Count; + UBYTE *pVal; + + TypeCode = cCmdDSType(DSElementID); + + if (TypeCode == TC_ARRAY) + { + DVIndex = cCmdGetDVIndex(DSElementID, Offset); + Count = DV_ARRAY[DVIndex].Count; + + DSElementID = INC_ID(DSElementID); + TypeCode = cCmdDSType(DSElementID); + if (!IS_AGGREGATE_TYPE(TypeCode)) + { + //Short circuit recursive calculation if our array sub-type is a scalar + Count = DV_ARRAY[DVIndex].ElemSize * DV_ARRAY[DVIndex].Count; + memmove((pByteArray + *pByteOffset), (VarsCmd.pDataspace + DV_ARRAY[DVIndex].Offset), Count); + *pByteOffset += Count; + } + else + { + //If the sub type is an aggregate type, then it can contain arrays, so we have to recur + for (i = 0; i < Count; i++) + { + cCmdFlattenToByteArray(pByteArray, pByteOffset, DSElementID, ARRAY_ELEM_OFFSET(DVIndex, i)); + } + } + } + else if (TypeCode == TC_CLUSTER) + { + Count = cCmdClusterCount(DSElementID); + + DSElementID = INC_ID(DSElementID); + for (i = 0; i < Count; i++) + { + cCmdFlattenToByteArray(pByteArray, pByteOffset, DSElementID, Offset); + DSElementID = cCmdNextDSElement(DSElementID); + } + } + else //Scalar + { + pVal = cCmdResolveDataArg(DSElementID, Offset, NULL); + Count = cCmdSizeOf(TypeCode); + + memmove((pByteArray + *pByteOffset), pVal, Count); + *pByteOffset += Count; + } + + return Status; +} + +NXT_STATUS cCmdUnflattenFromByteArray(UBYTE * pByteArray, UWORD * pByteOffset, DS_ELEMENT_ID DSElementID, UWORD Offset) +{ + NXT_STATUS Status = NO_ERR; + TYPE_CODE TypeCode; + DV_INDEX DVIndex; + UWORD i; + UWORD Count; + UBYTE *pVal; + + TypeCode = cCmdDSType(DSElementID); + + if (TypeCode == TC_ARRAY) + { + DVIndex = cCmdGetDVIndex(DSElementID, Offset); + Count = DV_ARRAY[DVIndex].Count; + + DSElementID = INC_ID(DSElementID); + TypeCode = cCmdDSType(DSElementID); + if (!IS_AGGREGATE_TYPE(TypeCode)) + { + //Short circuit recursive calculation if our array sub-type is a scalar + Count = DV_ARRAY[DVIndex].ElemSize * DV_ARRAY[DVIndex].Count; + memmove((VarsCmd.pDataspace + DV_ARRAY[DVIndex].Offset), (pByteArray + *pByteOffset), Count); + *pByteOffset += Count; + } + else + { + //If the sub type is an aggregate type, then it can contain arrays, so we have to recur + for (i = 0; i < Count; i++) + { + cCmdUnflattenFromByteArray(pByteArray, pByteOffset, DSElementID, ARRAY_ELEM_OFFSET(DVIndex, i)); + } + } + } + else if (TypeCode == TC_CLUSTER) + { + Count = cCmdClusterCount(DSElementID); + + DSElementID = INC_ID(DSElementID); + for (i = 0; i < Count; i++) + { + cCmdUnflattenFromByteArray(pByteArray, pByteOffset, DSElementID, Offset); + DSElementID = cCmdNextDSElement(DSElementID); + } + } + else //Scalar + { + pVal = cCmdResolveDataArg(DSElementID, Offset, NULL); + Count = cCmdSizeOf(TypeCode); + + memmove(pVal, (pByteArray + *pByteOffset), Count); + *pByteOffset += Count; + } + + return Status; +} + + +UWORD cCmdClusterCount(DS_ELEMENT_ID DSElementID) +{ + UWORD ClusterCount; + + NXT_ASSERT(cCmdIsDSElementIDSane(DSElementID)); + NXT_ASSERT(cCmdDSType(DSElementID) == TC_CLUSTER); + + ClusterCount = VarsCmd.pDataspaceTOC[DSElementID].DSOffset; + + return ClusterCount; +} + + +UWORD cCmdGetDVIndex(DS_ELEMENT_ID DSElementID, UWORD Offset) +{ + UWORD DVIndex; + + NXT_ASSERT(cCmdDSType(DSElementID) == TC_ARRAY); + + DVIndex = *(UWORD *)(VarsCmd.pDataspace + VarsCmd.pDataspaceTOC[DSElementID].DSOffset + Offset); + + //Make sure we're returning a valid DVIndex + NXT_ASSERT(DVIndex != 0 && DVIndex < DV_ARRAY[0].Count); + + return DVIndex; +} + + +UWORD cCmdArrayCount(DS_ELEMENT_ID DSElementID, UWORD Offset) +{ + DV_INDEX DVIndex; + + NXT_ASSERT(cCmdIsDSElementIDSane(DSElementID)); + NXT_ASSERT(cCmdDSType(DSElementID) == TC_ARRAY); + + DVIndex = cCmdGetDVIndex(DSElementID, Offset); + return DV_ARRAY[DVIndex].Count; +} + +TYPE_CODE cCmdArrayType(DS_ELEMENT_ID DSElementID) +{ + TYPE_CODE TypeCode; + + NXT_ASSERT(cCmdIsDSElementIDSane(DSElementID)); + NXT_ASSERT(cCmdIsDSElementIDSane(INC_ID(DSElementID))); + NXT_ASSERT(cCmdDSType(DSElementID) == TC_ARRAY); + + TypeCode = VarsCmd.pDataspaceTOC[DSElementID + 1].TypeCode; + + return TypeCode; +} + + +DS_ELEMENT_ID cCmdGetDataspaceCount(void) +{ + return (VarsCmd.DataspaceCount); +} + + +UBYTE cCmdCompare(UBYTE CompCode, ULONG Val1, ULONG Val2, TYPE_CODE TypeCode1, TYPE_CODE TypeCode2) +{ + SLONG SVal1, SVal2; + if (QUICK_UNSIGNED_TEST(TypeCode1) || QUICK_UNSIGNED_TEST(TypeCode2)) + { + return ((CompCode == OPCC1_LT && Val1 < Val2) + || (CompCode == OPCC1_GT && Val1 > Val2) + || (CompCode == OPCC1_LTEQ && Val1 <= Val2) + || (CompCode == OPCC1_GTEQ && Val1 >= Val2) + || (CompCode == OPCC1_EQ && Val1 == Val2) + || (CompCode == OPCC1_NEQ && Val1 != Val2)); + } + else + { + SVal1 = (SLONG)Val1; + SVal2 = (SLONG)Val2; + return ((CompCode == OPCC1_LT && SVal1 < SVal2) + || (CompCode == OPCC1_GT && SVal1 > SVal2) + || (CompCode == OPCC1_LTEQ && SVal1 <= SVal2) + || (CompCode == OPCC1_GTEQ && SVal1 >= SVal2) + || (CompCode == OPCC1_EQ && SVal1 == SVal2) + || (CompCode == OPCC1_NEQ && SVal1 != SVal2)); + } +} + +UBYTE cCmdCompareFlt(UBYTE CompCode, float Val1, float Val2, TYPE_CODE TypeCode1, TYPE_CODE TypeCode2) +{ + //!!! add threshold to equality comparisons + return ((CompCode == OPCC1_LT && Val1 < Val2) + || (CompCode == OPCC1_GT && Val1 > Val2) + || (CompCode == OPCC1_LTEQ && Val1 <= Val2) + || (CompCode == OPCC1_GTEQ && Val1 >= Val2) + || (CompCode == OPCC1_EQ && Val1 == Val2) + || (CompCode == OPCC1_NEQ && Val1 != Val2)); +} + + +NXT_STATUS cCmdCompareAggregates(UBYTE CompCode, UBYTE *ReturnBool, DATA_ARG Arg2, UWORD Offset2, DATA_ARG Arg3, UWORD Offset3) +{ + NXT_STATUS Status = NO_ERR; + UBYTE Finished; + + Finished = FALSE; + Status = cCmdRecursiveCompareAggregates(CompCode, ReturnBool, &Finished, Arg2, Offset2, Arg3, Offset3); + if (Finished == FALSE) + { + //If Finished has not been set to TRUE, it means that it was unable to find an inequality, thereby ending the comparison. + //Both elements are equal. Assign the proper value to ReturnBool + *ReturnBool = (CompCode == OPCC1_EQ || CompCode == OPCC1_GTEQ || CompCode == OPCC1_LTEQ); + } + + return Status; +} + + +//!!! Recursive function +NXT_STATUS cCmdRecursiveCompareAggregates(UBYTE CompCode, UBYTE *ReturnBool, UBYTE *Finished, DATA_ARG Arg2, UWORD Offset2, DATA_ARG Arg3, UWORD Offset3) +{ + //The value of Finished must be set to FALSE before calling this function. + //We are able to determine the result of the comparison once we find an inequality. + //Once an inequality is found, Finished is set to TRUE and ReturnBool is set based on the CompCode. + //A call to this function will return with Finished still equal to FALSE if both elements are equal in value and count. + //It is the caller of this function's job to set ReturnBool if this function returns with Finished == FALSE. + + NXT_STATUS Status = NO_ERR; + TYPE_CODE TypeCode2, TypeCode3; + DV_INDEX DVIndex2, DVIndex3; + ULONG ArgVal2, ArgVal3; + UWORD Count2, Count3, MinCount; + UWORD i; + + TypeCode2 = cCmdDSType(Arg2); + TypeCode3 = cCmdDSType(Arg3); + + //Make sure the two things we're comparing are the same type + if (IS_AGGREGATE_TYPE(TypeCode2) && (TypeCode2 != TypeCode3)) + { + NXT_BREAK; + return ERR_ARG; + } + + //Simple case, both args are scalars. Solve and return. + if (!IS_AGGREGATE_TYPE(TypeCode2)) + { + ArgVal2 = cCmdGetScalarValFromDataArg(Arg2, Offset2); + ArgVal3 = cCmdGetScalarValFromDataArg(Arg3, Offset3); + + //Once we find an inequality, we can determine the result of the comparison + *Finished = cCmdCompare(OPCC1_NEQ, ArgVal2, ArgVal3, TypeCode2, TypeCode3); + + if (*Finished) + *ReturnBool = cCmdCompare(CompCode, ArgVal2, ArgVal3, TypeCode2, TypeCode3); + + return Status; + } + + // Initialize local variables for each argument + + if (TypeCode2 == TC_ARRAY) + { + Count2 = cCmdArrayCount(Arg2, Offset2); + DVIndex2 = cCmdGetDVIndex(Arg2, Offset2); + Offset2 = DV_ARRAY[DVIndex2].Offset; + + Count3 = cCmdArrayCount(Arg3, Offset3); + DVIndex3 = cCmdGetDVIndex(Arg3, Offset3); + Offset3 = DV_ARRAY[DVIndex3].Offset; + } + else if (TypeCode2 == TC_CLUSTER) + { + Count2 = cCmdClusterCount(Arg2); + Count3 = cCmdClusterCount(Arg3); + } + + //Short circuit evaluation of EQ and NEQ if counts are different + if (Count2 != Count3) + { + if ((CompCode == OPCC1_EQ) || (CompCode == OPCC1_NEQ)) + { + *Finished = TRUE; + *ReturnBool = (CompCode == OPCC1_NEQ); + return Status; + } + } + + MinCount = (Count2 < Count3) ? Count2 : Count3; + + //Advance aggregate args to first sub-element for next call + Arg2 = INC_ID(Arg2); + Arg3 = INC_ID(Arg3); + + // + // Loop through the sub-elements of aggregate arguments. + // Call cCmdRecursiveCompareAggregates recursively with simpler type. + // + + for (i = 0; i < MinCount; i++) + { + Status = cCmdRecursiveCompareAggregates(CompCode, ReturnBool, Finished, Arg2, Offset2, Arg3, Offset3); + if (*Finished || IS_ERR(Status)) + return Status; + + //Advance aggregate args to next sub-element + if (TypeCode2 == TC_ARRAY) + { + Offset2 += DV_ARRAY[DVIndex2].ElemSize; + Offset3 += DV_ARRAY[DVIndex3].ElemSize; + } + else if (TypeCode2 == TC_CLUSTER) + { + Arg2 = cCmdNextDSElement(Arg2); + Arg3 = cCmdNextDSElement(Arg3); + } + } + + //All elements in aggregates type up to MinCount are equal. Count discrepancy determines comparison outcome. + if (Count2 != Count3) + { + *Finished = TRUE; + *ReturnBool = cCmdCompare(CompCode, Count2, Count3, TC_UWORD, TC_UWORD); + } + //Else, no size discrepancy. Elements are equal. Comparison still not resolved, + //so return !Finished and status back up the call chain for further comparison + + return Status; +} + +ULONG gClearProfileInfo= 0, bigExecTime= 0; +#if VMProfilingCode +void UpdateProfileInfo(ULONG shortOp, CODE_WORD *pInstr, ULONG execTime, ULONG InstrSize) +{ + ULONG j; + ULONG opCode; + + if(execTime > 500 && shortOp == 8) + bigExecTime= shortOp; + if(gClearProfileInfo) { + ExecutedInstrs= 0; + CmdCtrlTime= 0; + OverheadTime= 0; + CmdCtrlCalls= 0; + LastAvgCount= 0; + for(j= 0; j < 255; j++) + CmdCtrlClumpTime[j]= 0; + for(j= 0; j < OPCODE_COUNT; j++) { + InstrProfile[j].Avg= 0; + InstrProfile[j].Time= 0; + InstrProfile[j].Count= 0; + InstrProfile[j].Max= 0; + } + for(j= 0; j < SYSCALL_COUNT; j++) { + SysCallProfile[j].Avg= 0; + SysCallProfile[j].Time= 0; + SysCallProfile[j].Count= 0; + SysCallProfile[j].Max= 0; + } + for(j= 0; j < NUM_SHORT_OPCODE_COUNT; j++) { + ShortInstrProfile[j].Avg= 0; + ShortInstrProfile[j].Time= 0; + ShortInstrProfile[j].Count= 0; + ShortInstrProfile[j].Max= 0; + } + for(j= 0; j < NUM_INTERP_FUNCS; j++) { + InterpFuncProfile[j].Avg= 0; + InterpFuncProfile[j].Time= 0; + InterpFuncProfile[j].Count= 0; + InterpFuncProfile[j].Max= 0; + } + gClearProfileInfo= FALSE; + } + ExecutedInstrs ++; + if(shortOp > 7) // shortop bit set + { + ShortInstrProfile[shortOp-8].Time += execTime; + ShortInstrProfile[shortOp-8].Count++; + if(execTime > ShortInstrProfile[shortOp-8].Max) + ShortInstrProfile[shortOp-8].Max= execTime; + } + else + { + opCode = OP_CODE(pInstr); + InstrProfile[opCode].Time += execTime; + InstrProfile[opCode].Count++; + if(execTime > InstrProfile[opCode].Max) + InstrProfile[opCode].Max= execTime; + if(opCode == OP_SYSCALL) + { + SysCallProfile[GetDataArg(pInstr[1])].Time += execTime; + SysCallProfile[GetDataArg(pInstr[1])].Count++; + if(execTime > SysCallProfile[GetDataArg(pInstr[1])].Max) + SysCallProfile[GetDataArg(pInstr[1])].Max= execTime; + } + + InterpFuncProfile[InstrSize].Time += execTime; + InterpFuncProfile[InstrSize].Count++; + if(execTime > InterpFuncProfile[InstrSize].Max) + InterpFuncProfile[InstrSize].Max= execTime; + } + if(ExecutedInstrs - LastAvgCount > 999) // every N instrs, update avgs + { + for(j= 0; j < OPCODE_COUNT; j++) + if(InstrProfile[j].Count) + InstrProfile[j].Avg= InstrProfile[j].Time/InstrProfile[j].Count; + for(j= 0; j < SYSCALL_COUNT; j++) + if(SysCallProfile[j].Count) + SysCallProfile[j].Avg= SysCallProfile[j].Time/SysCallProfile[j].Count; + for(j= 0; j < NUM_SHORT_OPCODE_COUNT; j++) + if(ShortInstrProfile[j].Count) + ShortInstrProfile[j].Avg= ShortInstrProfile[j].Time/ShortInstrProfile[j].Count; + for(j= 0; j < NUM_INTERP_FUNCS; j++) + if(InterpFuncProfile[j].Count) + InterpFuncProfile[j].Avg= InterpFuncProfile[j].Time/InterpFuncProfile[j].Count; + LastAvgCount= ExecutedInstrs; + } +} +#endif + + +// +// Interpreter Functions +// + +NXT_STATUS cCmdInterpFromClump() +{ + CLUMP_ID Clump= VarsCmd.RunQ.Head; + NXT_STATUS Status = NO_ERR; + CLUMP_REC * pClumpRec; + CODE_WORD * pInstr, *lastClumpInstr; + UBYTE InstrSize; + ULONG shortOp, nextMSTick; + SLONG i; +#if VM_BENCHMARK + ULONG InstrTime = dTimerRead(); +#endif + + if (!cCmdIsClumpIDSane(Clump)) // this means all clumps are asleep + return TIMES_UP; + + //Resolve clump record structure and current instruction pointer + pClumpRec = &(VarsCmd.pAllClumps[Clump]); + pInstr = pClumpRec->PC; // abs + lastClumpInstr= pClumpRec->CodeEnd; // abs + + i= gInstrsToExecute; + nextMSTick= dTimerGetNextMSTickCnt(); + do + { +#if VMProfilingCode + ULONG instrStartTime; + instrStartTime= dTimerReadHiRes(); +#endif + + ULONG instrWord= *(UWORD*)pInstr; + shortOp= (instrWord>>8) & 0x0F; + if(shortOp > 7) // shortop bit set + Status= ShortInterpFuncs[shortOp - 8](pInstr); + else + { // we know this is a long instr, dispatch on num params, which correlates to size + InstrSize = INSTR_SIZE(instrWord); // keep in a local for profiling + Status = (*InterpFuncs[InstrSize])(pInstr); + } + +#if VMProfilingCode + UpdateProfileInfo(shortOp, pInstr, dTimerReadHiRes() - instrStartTime, InstrSize); +#endif + +afterCompaction: + if (Status == NO_ERR) + pInstr += gPCDelta; + else if (Status == CLUMP_DONE) // already requeued + { + pClumpRec->PC = pClumpRec->CodeStart; + pClumpRec->CurrFireCount = pClumpRec->InitFireCount; + return Status; + } + else if (Status == CLUMP_SUSPEND || Status == BREAKOUT_REQ || Status == ROTATE_QUEUE) // already requeued + { + pClumpRec->PC = pInstr + gPCDelta; + //Throw error if we ever advance beyond the clump's codespace + if (pInstr > lastClumpInstr) + { + NXT_BREAK; + Status = ERR_INSTR; + } + return Status; + } + else if (Status == ERR_MEM) + { + //Memory is full. Compact dataspace and try the instruction again. + //!!! Could compact DopeVectorArray here + cCmdDSCompact(); + if(shortOp > 7) // shortop bit set + Status= ShortInterpFuncs[shortOp - 8](pInstr); + else + Status = (*InterpFuncs[InstrSize])(pInstr); + if(Status == ERR_MEM) + return Status; + else + goto afterCompaction; + } + else // other errors, breakout, stop + return Status; + + //Throw error if we ever advance beyond the clump's codespace + if (pInstr > lastClumpInstr) + { + NXT_BREAK; + Status = ERR_INSTR; + } + +#if VM_BENCHMARK + //Increment opcode count + VarsCmd.OpcodeBenchmarks[OP_CODE(pInstr)][0]++; + + InstrTime = dTimerRead() - InstrTime; + if (InstrTime > 1) + { + VarsCmd.OpcodeBenchmarks[OP_CODE(pInstr)][1]++; + if (InstrTime > VarsCmd.OpcodeBenchmarks[OP_CODE(pInstr)][2]) + VarsCmd.OpcodeBenchmarks[OP_CODE(pInstr)][2] = InstrTime; + } + VarsCmd.InstrCount++; +#endif + + //Count one more instruction for this pass + if ((SLONG)(nextMSTick - dTimerReadTicks()) <= 0) // HWTimer has passed ms tick limit + Status= TIMES_UP; + else if(--i <= 0) + Status= ROTATE_QUEUE; + } while (!Status); + pClumpRec->PC= pInstr; + return (Status); +} + + +NXT_STATUS cCmdInterpUnop1(CODE_WORD * const pCode) +{ + NXT_STATUS Status = NO_ERR; + UBYTE opCode; + DATA_ARG Arg1; + + NXT_ASSERT(pCode != NULL); + + gPCDelta= 2; + opCode = OP_CODE(pCode); + Arg1 = pCode[1]; + + switch (opCode) + { + case OP_JMP: + { + gPCDelta= (SWORD)Arg1; + Status = NO_ERR; + } + break; + + case OP_ACQUIRE: + { + NXT_ASSERT(cCmdIsDSElementIDSane(Arg1)); + NXT_ASSERT(VarsCmd.pDataspaceTOC[Arg1].TypeCode == TC_MUTEX); + + Status = cCmdAcquireMutex((MUTEX_Q *)cCmdDSScalarPtr(Arg1, 0)); + } + break; + + case OP_RELEASE: + { + NXT_ASSERT(cCmdIsDSElementIDSane(Arg1)); + NXT_ASSERT(VarsCmd.pDataspaceTOC[Arg1].TypeCode == TC_MUTEX); + + Status = cCmdReleaseMutex((MUTEX_Q *)cCmdDSScalarPtr(Arg1, 0)); + } + break; + + case OP_SUBRET: + { + NXT_ASSERT(cCmdIsDSElementIDSane(Arg1)); + + //Take Subroutine off RunQ + //Add Subroutine's caller to RunQ + cCmdDeQClump(&(VarsCmd.RunQ), VarsCmd.RunQ.Head); + cCmdEnQClump(&(VarsCmd.RunQ), *((CLUMP_ID *)cCmdDSScalarPtr(Arg1, 0))); + + Status = CLUMP_DONE; + } + break; + + case OP_FINCLUMPIMMED: + { + CLUMP_ID Clump= VarsCmd.RunQ.Head; // DeQ changes Head, use local val + cCmdDeQClump(&(VarsCmd.RunQ), Clump); //Dequeue finalized clump + cCmdSchedDependent(Clump, (CLUMP_ID)Arg1); // Use immediate form + + Status = CLUMP_DONE; + } + break; + + case OP_GETTICK: + { + cCmdSetScalarValFromDataArg(Arg1, dTimerReadNoPoll()); + } + break; + + case OP_STOP: + { + //Unwired Arg1 means always stop + if (Arg1 == NOT_A_DS_ID) + Status = STOP_REQ; + else if (cCmdGetScalarValFromDataArg(Arg1, 0) > 0) + Status = STOP_REQ; + } + break; + + default: + { + //Fatal error: Unrecognized instruction + NXT_BREAK; + Status = ERR_INSTR; + } + break; + } + + return (Status); +} + +ULONG scalarNots= 0, scalarBrtst= 0, scalarUn2Other= 0, scalarUn2Dispatch= 0, polyUn2Dispatch= 0; +NXT_STATUS cCmdInterpScalarUnop2(CODE_WORD * const pCode) +{ + NXT_STATUS Status; + UBYTE opCode; + + NXT_ASSERT(pCode != NULL); + opCode = OP_CODE(pCode); + DATA_ARG Arg1, Arg2; + + scalarUn2Dispatch ++; + if(opCode == OP_NOT) // t2 && t3 guaranteed scalar + { + gPCDelta= 3; + Arg1 = pCode[1]; + Arg2 = pCode[2]; + ULONG ArgVal1, ArgVal2; + + ArgVal2= cCmdGetScalarValFromDataArg(Arg2, 0); + //!!! OP_NOT is logical, *not* bit-wise. + //This differs from the other logical ops because we don't distinguish booleans from UBYTEs. + ArgVal1= (!ArgVal2); + cCmdSetScalarValFromDataArg(Arg1, ArgVal1); + Status = NO_ERR; + scalarNots ++; + } + else if(opCode == OP_BRTST) + { + ULONG Branch, compare= COMP_CODE(pCode); + ULONG TypeCode; + + Arg1 = pCode[1]; + Arg2 = pCode[2]; + TypeCode = cCmdDSType(Arg2); + + if(Arg2 == NOT_A_DS_ID) + { + Branch= ((compare == OPCC1_EQ) + || (compare == OPCC1_LTEQ) + || (compare == OPCC1_GTEQ)); + } + else + { + if(compare == OPCC1_EQ && TypeCode == TC_UBYTE) // very common for loops + { + UBYTE *pBRVal = (VarsCmd.pDataspace + VarsCmd.pDataspaceTOC[Arg2].DSOffset); + Branch= *pBRVal == 0; + } + else + { + SLONG SVal1 = (SLONG)cCmdGetScalarValFromDataArg(Arg2, 0); + Branch= ((compare == OPCC1_EQ && SVal1 == 0) + || (compare == OPCC1_NEQ && SVal1 != 0) + || (compare == OPCC1_GT && SVal1 > 0) + || (compare == OPCC1_LT && SVal1 < 0) + || (compare == OPCC1_LTEQ && SVal1 <= 0) + || (compare == OPCC1_GTEQ && SVal1 >= 0)); + } + } + if (Branch) + gPCDelta = (SWORD)Arg1; + else + gPCDelta= 3; + Status = NO_ERR; + scalarBrtst ++; + } + else { + Status= cCmdInterpUnop2(pCode); + scalarUn2Other ++; + } + return Status; +} + +NXT_STATUS cCmdInterpUnop2(CODE_WORD * const pCode) +{ + NXT_STATUS Status = NO_ERR; + UBYTE opCode; + DATA_ARG Arg1; + DATA_ARG Arg2; + void *pArg1 = NULL, *pArg2 = NULL; + TYPE_CODE TypeCode1, TypeCode2; + + ULONG i; + UWORD ArgC; + static UBYTE * ArgV[MAX_CALL_ARGS + 1]; + + polyUn2Dispatch ++; + UWORD Count; + UWORD Offset; + SLONG TmpSLong; + ULONG TmpULong; + ULONG ArgVal2; + float FltArgVal2; + char Buffer[30]; + char FormatString[5]; + UBYTE CheckTrailingZeros = 0; + + NXT_ASSERT(pCode != NULL); + + gPCDelta= 3; + opCode = OP_CODE(pCode); + Arg1 = pCode[1]; + Arg2 = pCode[2]; + + if (opCode == OP_NEG || opCode == OP_NOT || opCode == OP_TST || opCode == OP_SQRT || opCode == OP_ABS) + { + return cCmdInterpPolyUnop2(*pCode, Arg1, 0, Arg2, 0); + } + + switch (opCode) + { + case OP_MOV: + { + Status= cCmdMove(Arg1, Arg2); + } + break; + + case OP_SET: + { + //!!! Should throw error if TypeCode1 is non-scalar + // Accepting non-scalar destinations could have unpredictable results! + cCmdSetScalarValFromDataArg(Arg1, Arg2); + } + break; + + case OP_BRTST: + { + //!!!BDUGGAN BRTST w/ Float? + ULONG Branch, compare= COMP_CODE(pCode); + ULONG TypeCode = cCmdDSType(Arg2); + if(compare == OPCC1_EQ && TypeCode == TC_UBYTE) // very common for loops + { + UBYTE *pBRVal = (VarsCmd.pDataspace + VarsCmd.pDataspaceTOC[Arg2].DSOffset); + Branch= *pBRVal == 0; + } + else + { + SLONG SVal1 = (SLONG)cCmdGetScalarValFromDataArg(Arg2, 0); + Branch= ((compare == OPCC1_EQ && SVal1 == 0) + || (compare == OPCC1_NEQ && SVal1 != 0) + || (compare == OPCC1_GT && SVal1 > 0) + || (compare == OPCC1_LT && SVal1 < 0) + || (compare == OPCC1_LTEQ && SVal1 <= 0) + || (compare == OPCC1_GTEQ && SVal1 >= 0)); + } + if (Branch) + + { + gPCDelta = (SWORD)Arg1; + Status = NO_ERR; + } + } + break; + + case OP_FINCLUMP: + { + CLUMP_ID Clump= VarsCmd.RunQ.Head; // DeQ changes Head, use local val + cCmdDeQClump(&(VarsCmd.RunQ), Clump); //Dequeue finalized clump + cCmdSchedDependents(Clump, (SWORD)Arg1, (SWORD)Arg2); + Status = CLUMP_DONE; + } + break; + + case OP_SUBCALL: + { + NXT_ASSERT(cCmdIsClumpIDSane((CLUMP_ID)Arg1)); + NXT_ASSERT(!cCmdIsClumpOnQ(&(VarsCmd.RunQ), (CLUMP_ID)Arg1)); + + NXT_ASSERT(cCmdIsDSElementIDSane(Arg2)); + + *((CLUMP_ID *)(cCmdDSScalarPtr(Arg2, 0))) = VarsCmd.RunQ.Head; + + cCmdDeQClump(&(VarsCmd.RunQ), VarsCmd.RunQ.Head); //Take caller off RunQ + cCmdEnQClump(&(VarsCmd.RunQ), (CLUMP_ID)Arg1); //Add callee to RunQ + + Status = CLUMP_SUSPEND; + } + break; + + case OP_ARRSIZE: + { + cCmdSetScalarValFromDataArg(Arg1, cCmdArrayCount(Arg2, 0)); + } + break; + + case OP_SYSCALL: + { + if (Arg1 >= SYSCALL_COUNT) + { + NXT_BREAK; + Status = ERR_INSTR; + break; + } + + ArgC = cCmdClusterCount(Arg2); + + if (ArgC > MAX_CALL_ARGS) + { + NXT_BREAK; + Status = ERR_INSTR; + break; + } + + if (ArgC > 0) + { + Arg2 = INC_ID(Arg2); + + for (i = 0; i < ArgC; i++) + { + if (cCmdDSType(Arg2) == TC_ARRAY) + { + //Storing pointer to array's DV_INDEX + //!!! This resolve is different than cCmdDSPtr + // since SysCalls may need the DVIndex to re-alloc arrays + ArgV[i] = VarsCmd.pDataspace + VarsCmd.pDataspaceTOC[Arg2].DSOffset; + } + else + { + ArgV[i] = cCmdDSPtr(Arg2, 0); + } + + //If any argument fails to resolve, return a fatal error. + if (ArgV[i] == NULL) + { + Status = ERR_BAD_PTR; + break; + } + + Arg2 = cCmdNextDSElement(Arg2); + } + } + else + { + i = 0; + } + + //ArgV list is null terminated + ArgV[i] = NULL; + + Status = (*SysCallFuncs[Arg1])(ArgV); + } + break; + + case OP_FLATTEN: + { + //Flatten Arg2 to a NULL terminated string + + //Assert that the destination is a string (array of bytes) + NXT_ASSERT(cCmdDSType(Arg1) == TC_ARRAY); + NXT_ASSERT(cCmdDSType(INC_ID(Arg1)) == TC_UBYTE); + + Count = cCmdCalcFlattenedSize(Arg2, 0); + //Add room for NULL terminator + Count++; + Status = cCmdDSArrayAlloc(Arg1, 0, Count); + if (IS_ERR(Status)) + return Status; + + pArg1 = cCmdResolveDataArg(Arg1, 0, NULL); + Offset = 0; + + Status = cCmdFlattenToByteArray(pArg1, &Offset, Arg2, 0); + //Append NULL terminator + *((UBYTE *)pArg1 + Offset) = 0; + Offset++; + NXT_ASSERT(Offset == Count); + } + break; + + case OP_NUMTOSTRING: + { + //Assert that the destination is a string (array of bytes) + NXT_ASSERT(cCmdDSType(Arg1) == TC_ARRAY); + NXT_ASSERT(cCmdDSType(INC_ID(Arg1)) == TC_UBYTE); + + //Make sure we're trying to convert a scalar to a string + TypeCode2= cCmdDSType(Arg2); + NXT_ASSERT(!IS_AGGREGATE_TYPE(TypeCode2)); + + if (TypeCode2 == TC_FLOAT) + { + pArg2 = cCmdResolveDataArg(Arg2, 0, NULL); + FltArgVal2 = cCmdGetValFlt(pArg2, TypeCode2); + // is number too big for display? then format differently and don't bother with trailing zeros + if ((FltArgVal2 > 9999999999999.99f)||(FltArgVal2 < -999999999999.99f)){ // these are the widest %.2f numbers that will fit on display + strcpy (FormatString, "%.6g"); + } + else{ + strcpy (FormatString, "%.2f"); + CheckTrailingZeros = 1; + } + Count = sprintf(Buffer, FormatString, FltArgVal2); + Count++; //add room for null terminator + + if (CheckTrailingZeros){ + // Determine if the trailing digits are zeros. If so, drop them + if (Buffer[Count-2] == 0x30) { // NOTE: 0x30 is ASCII 0 + if (Buffer[Count-3] == 0x30){ + strcpy (FormatString, "%.0f"); // the last two digits = 0, copy as integer + Count = Count - 3; // don't need memory for decimal and 2 ascii characters + } + else { + strcpy (FormatString, "%.1f"); // only the 2nd digit = 0 so drop it, but keep the tenths place + Count = Count - 1; // don't need memory for 2nd ascii character + } + } + } + } + else + { + ArgVal2 = cCmdGetScalarValFromDataArg(Arg2, 0); + //Calculate size of array + if (ArgVal2 == 0) + Count = 1; + else { + Count = 0; + SLONG digits= 0; + ULONG Tmp= 1; + if (TypeCode2 == TC_SLONG || TypeCode2 == TC_SWORD || TypeCode2 == TC_SBYTE) + { + TmpSLong = (SLONG)ArgVal2; + //Add room for negative sign + if (TmpSLong < 0) { + Count++; + TmpULong= -TmpSLong; + } + else + TmpULong= ArgVal2; + } + else + TmpULong= ArgVal2; + + while (Tmp <= TmpULong && digits < 10) { // maxint is ten digits, max + Tmp *= 10; + digits++; + } + Count += digits; + } + //add room for NULL terminator + Count++; + } + + //Allocate array + Status = cCmdDSArrayAlloc(Arg1, 0, Count); + if (IS_ERR(Status)) + return Status; + + pArg1 = cCmdResolveDataArg(Arg1, 0, &TypeCode1); + + //Populate array + if (TypeCode2 == TC_FLOAT) + { + sprintf(pArg1, FormatString, FltArgVal2); + } + else if (TypeCode2 == TC_SLONG || TypeCode2 == TC_SWORD || TypeCode2 == TC_SBYTE) + { + sprintf(pArg1, "%d", (SLONG)ArgVal2); + } + else + { + sprintf(pArg1, "%u", ArgVal2); + } + } + break; + + case OP_STRTOBYTEARR: + { + NXT_ASSERT((cCmdDSType(Arg1) == TC_ARRAY) && (cCmdDSType(INC_ID(Arg1)) == TC_UBYTE)); + NXT_ASSERT((cCmdDSType(Arg2) == TC_ARRAY) && (cCmdDSType(INC_ID(Arg2)) == TC_UBYTE)); + + Count = cCmdArrayCount(Arg2, 0); + + if (Count > 0) + { + Status = cCmdDSArrayAlloc(Arg1, 0, (UWORD)(Count - 1)); + if (IS_ERR(Status)) + return Status; + + pArg1 = cCmdResolveDataArg(Arg1, 0, NULL); + pArg2 = cCmdResolveDataArg(Arg2, 0, NULL); + + memmove(pArg1, pArg2, Count - 1); + } + } + break; + + case OP_BYTEARRTOSTR: + { + NXT_ASSERT((cCmdDSType(Arg1) == TC_ARRAY) && (cCmdDSType(INC_ID(Arg1)) == TC_UBYTE)); + NXT_ASSERT((cCmdDSType(Arg2) == TC_ARRAY) && (cCmdDSType(INC_ID(Arg2)) == TC_UBYTE)); + + Count = cCmdArrayCount(Arg2, 0); + + Status = cCmdDSArrayAlloc(Arg1, 0, (UWORD)(Count + 1)); + if (IS_ERR(Status)) + return Status; + + pArg1 = cCmdResolveDataArg(Arg1, 0, NULL); + pArg2 = cCmdResolveDataArg(Arg2, 0, NULL); + + memmove(pArg1, pArg2, Count); + *((UBYTE *)pArg1 + Count) = '\0'; + } + break; + + case OP_WAIT: + { + ULONG wait= 0; + //Unwired Arg2 defaults to wait 0, which rotates queue + if (Arg2 != NOT_A_DS_ID) + wait= cCmdGetScalarValFromDataArg(Arg2, 0); + if(wait == 0) + Status= ROTATE_QUEUE; + else + Status = cCmdSleepClump(wait + IOMapCmd.Tick); // put to sleep, to wake up wait ms in future + if(Arg1 != NOT_A_DS_ID) + cCmdSetScalarValFromDataArg(Arg1, dTimerReadNoPoll()); + } + break; + + default: + { + //Fatal error: Unrecognized instruction + NXT_BREAK; + Status = ERR_INSTR; + } + break; + } + + return (Status); +} + + +NXT_STATUS cCmdInterpPolyUnop2(CODE_WORD const Code, DATA_ARG Arg1, UWORD Offset1Param, DATA_ARG Arg2, UWORD Offset2Param) +{ + NXT_STATUS Status = NO_ERR; + TYPE_CODE TypeCode1, TypeCode2; + DV_INDEX DVIndex1, DVIndex2; + ULONG ArgVal1, ArgVal2; + float FltArgVal1, FltArgVal2; + UWORD Count1, Count2, Offset1= Offset1Param, Offset2= Offset2Param; + UWORD MinArrayCount; + UWORD i; + //!!! AdvCluster is intended to catch the case where sources are Cluster and an Array of Clusters. + // In practice, the logic it uses is broken, leading to some source cluster elements being ignored. + UBYTE AdvCluster; + + void * pArg1 = NULL, + *pArg2 = NULL; + + TypeCode1 = cCmdDSType(Arg1); + TypeCode2 = cCmdDSType(Arg2); + + //Simple case, scalar. Solve and return. + if (!IS_AGGREGATE_TYPE(TypeCode2)) + { + NXT_ASSERT(!IS_AGGREGATE_TYPE(TypeCode1)); + + pArg1 = cCmdResolveDataArg(Arg1, Offset1, &TypeCode1); + + if (TypeCode1 == TC_FLOAT || TypeCode2 == TC_FLOAT) + { + pArg2 = cCmdResolveDataArg(Arg2, Offset2, &TypeCode2); + FltArgVal2 = cCmdGetValFlt(pArg2, TypeCode2); + FltArgVal1 = cCmdUnop2Flt(Code, FltArgVal2, TypeCode2); + cCmdSetValFlt(pArg1, TypeCode1, FltArgVal1); + } + else + { + ArgVal2= cCmdGetScalarValFromDataArg(Arg2, Offset2); + if(OP_CODE(&Code) == OP_MOV) + ArgVal1= ArgVal2; + else + ArgVal1 = cCmdUnop2(Code, ArgVal2, TypeCode2); + cCmdSetVal(pArg1, TypeCode1, ArgVal1); + } + return Status; + } + + //At least one of the args is an aggregate type + + if(TypeCode1 == TC_ARRAY && TypeCode2 == TC_ARRAY) { + TYPE_CODE tc1, tc2; + tc1= cCmdDSType(INC_ID(Arg1)); + tc2= cCmdDSType(INC_ID(Arg2)); + if(tc1 <= TC_LAST_INT_SCALAR && tc1 == tc2) { + void *pArg1, *pArg2; + ULONG Count = cCmdArrayCount(Arg2, Offset2); + Status = cCmdDSArrayAlloc(Arg1, Offset1, Count); + if (IS_ERR(Status)) + return Status; + pArg1 = cCmdResolveDataArg(Arg1, Offset1, NULL); + pArg2 = cCmdResolveDataArg(Arg2, Offset2, NULL); + memmove(pArg1, pArg2, Count * cCmdSizeOf(tc1)); + return Status; + } + } + + + // + // Initialize Count and ArrayType local variables for each argument + // + + if (TypeCode2 == TC_ARRAY) + { + Count2 = cCmdArrayCount(Arg2, Offset2); + DVIndex2 = cCmdGetDVIndex(Arg2, Offset2); + Offset2 = DV_ARRAY[DVIndex2].Offset; + } + else if (TypeCode2 == TC_CLUSTER) + { + Count2 = cCmdClusterCount(Arg2); + } + + if (TypeCode1 == TC_ARRAY) + { + if (TypeCode2 != TC_ARRAY) + { + //If output is an array, but source is not an array, that's a fatal error! + NXT_BREAK; + return (ERR_ARG); + } + if(Count2 == 0) { // both arrays, input is empty, is output already empty? + Count1= cCmdArrayCount(Arg1, Offset1); + if(Count1 == 0) + return NO_ERR; + } + + MinArrayCount = Count2; + + //Make sure the destination array is the proper size to hold the result + Status = cCmdDSArrayAlloc(Arg1, Offset1, MinArrayCount); + if (IS_ERR(Status)) + return Status; + + if(MinArrayCount == 0) // if we emptied array, nothing else to do. + return NO_ERR; + Count1 = MinArrayCount; + DVIndex1 = cCmdGetDVIndex(Arg1, Offset1); + Offset1 = DV_ARRAY[DVIndex1].Offset; + AdvCluster = FALSE; + } + else if (TypeCode1 == TC_CLUSTER) + { + Count1 = cCmdClusterCount(Arg1); + AdvCluster = TRUE; + } + + //Advance aggregate args to first sub-element for next call + if (IS_AGGREGATE_TYPE(TypeCode1)) + Arg1 = INC_ID(Arg1); + if (IS_AGGREGATE_TYPE(TypeCode2)) + Arg2 = INC_ID(Arg2); + + // + // Loop through the sub-elements of aggregate arguments. + // Call cCmdInterpPolyUnop2 recursively with simpler type. + // + for (i = 0; i < Count1; i++) + { + Status = cCmdInterpPolyUnop2(Code, Arg1, Offset1, Arg2, Offset2); + if (IS_ERR(Status)) + return Status; + + //Advance aggregate args to next sub-element + if (TypeCode1 == TC_ARRAY) + Offset1 += DV_ARRAY[DVIndex1].ElemSize; + else if ((TypeCode1 == TC_CLUSTER) && AdvCluster) + Arg1 = cCmdNextDSElement(Arg1); + + if (TypeCode2 == TC_ARRAY) + Offset2 += DV_ARRAY[DVIndex2].ElemSize; + else if ((TypeCode2 == TC_CLUSTER) && AdvCluster) + Arg2 = cCmdNextDSElement(Arg2); + } + return Status; +} + + +ULONG cCmdUnop2(CODE_WORD const Code, ULONG Operand, TYPE_CODE TypeCode) +{ + UBYTE opCode; + + opCode = OP_CODE((&Code)); + if(opCode == OP_MOV) + return Operand; + else if(opCode == OP_NEG) + return (-((SLONG)Operand)); + else if(opCode == OP_NOT) + //!!! OP_NOT is logical, *not* bit-wise. + //This differs from the other logical ops because we don't distinguish booleans from UBYTEs. + return (!Operand); + else if(opCode == OP_TST) + return cCmdCompare(COMP_CODE((&Code)), Operand, 0, TypeCode, TypeCode); + else if(opCode == OP_ABS) + return abs(Operand); + else + { + //Unrecognized instruction, NXT_BREAK for easy debugging (ERR_INSTR handled in caller) + NXT_BREAK; + return 0; + } +} + +float cCmdUnop2Flt(CODE_WORD const Code, float Operand, TYPE_CODE TypeCode) +{ + UBYTE opCode; + + opCode = OP_CODE((&Code)); + if(opCode == OP_MOV) + return Operand; + else if(opCode == OP_NEG) + return (-(Operand)); + else if(opCode == OP_NOT) + //!!! OP_NOT is logical, *not* bit-wise. + //This differs from the other logical ops because we don't distinguish booleans from UBYTEs. + return (!Operand); + else if(opCode == OP_TST) + return cCmdCompareFlt(COMP_CODE((&Code)), Operand, 0, TypeCode, TypeCode); + else if(opCode == OP_ABS) + return fabsf(Operand); + else if(opCode == OP_SQRT) + return sqrtf(Operand); +#if 0 + else if(opCode == OP_SIN) + return sinf(Operand); + else if(opCode == OP_COS) + return cosf(Operand); + else if(opCode == OP_TAN) + return tanf(Operand); + else if(opCode == OP_ASIN) + return asinf(Operand); + else if(opCode == OP_ACOS) + return acosf(Operand); + else if(opCode == OP_ATAN) + return atanf(Operand); +#endif + else + { + //Unrecognized instruction, NXT_BREAK for easy debugging (ERR_INSTR handled in caller) + NXT_BREAK; + return 0; + } +} + +NXT_STATUS cCmdIOGetSet(ULONG opCode, DATA_ARG Arg1, DATA_ARG Arg2, DATA_ARG Arg3) +{ + ULONG ArgVal1, ArgVal2; + TYPE_CODE TypeCode2; + void *pArg2 = NULL; + switch(opCode) + { + case OP_GETOUT: + { + ArgVal2 = cCmdGetScalarValFromDataArg(Arg2, 0); + Arg2 = (UWORD)(0x200 | (Arg3 + ArgVal2 * IO_OUT_FPP)); + pArg2 = cCmdResolveIODataArg(Arg2, 0, &TypeCode2); + cCmdSetScalarValFromDataArg(Arg1, cCmdGetVal(pArg2, TypeCode2)); + } + break; + //!!! All IO map access commands should screen illegal port values! + // Right now, cCmdResolveIODataArg's implementation allows SETIN/GETIN to access arbitrary RAM! + case OP_SETIN: + { + ArgVal2 = cCmdGetScalarValFromDataArg(Arg2, 0); + Arg2 = (UWORD)(Arg3 + ArgVal2 * IO_IN_FPP); + pArg2 = cCmdResolveIODataArg(Arg2, 0, &TypeCode2); + ArgVal1 = cCmdGetScalarValFromDataArg(Arg1, 0); + cCmdSetVal(pArg2, TypeCode2, ArgVal1); + } + break; + case OP_GETIN: + { + TYPE_CODE TypeCode1; + void * pArg1; + ArgVal2 = cCmdGetScalarValFromDataArg(Arg2, 0); + Arg2 = (UWORD)(Arg3 + ArgVal2 * IO_IN_FPP); + pArg2 = cCmdResolveIODataArg(Arg2, 0, &TypeCode2); + TypeCode1= cCmdDSType(Arg1); + pArg1= cCmdDSScalarPtr(Arg1, 0); + if(TypeCode1 <= TC_SBYTE && TypeCode1 <= TC_SBYTE) // seems really common + *(UBYTE*)pArg1= *(UBYTE*)pArg2; + else + cCmdSetVal(pArg1, TypeCode1, cCmdGetVal(pArg2, TypeCode2)); + } + break; + } + return NO_ERR; +} + +ULONG scalarCmp= 0, scalarFloatCmp= 0, recursiveCmp= 0, PolyScalarCmp= 0, polyPolyCmp= 0, scalarOther= 0, scalarBinopDispatch= 0, polyBinopDispatch= 0; +NXT_STATUS cCmdInterpScalarBinop(CODE_WORD * const pCode) +{ + NXT_STATUS Status; + UBYTE opCode; + UBYTE CmpBool; + + NXT_ASSERT(pCode != NULL); + opCode = OP_CODE(pCode); + DATA_ARG Arg1, Arg2, Arg3; + + scalarBinopDispatch ++; + if(opCode == OP_CMP) // t2 && t3 guaranteed scalar or string + { + gPCDelta= 4; + Arg1 = pCode[1]; + Arg2 = pCode[2]; + Arg3 = pCode[3]; + ULONG ArgVal1, ArgVal2, ArgVal3; + TYPE_CODE TypeCode2, TypeCode3; + DS_TOC_ENTRY *dsTOC2Ptr= &VarsCmd.pDataspaceTOC[Arg2]; + DS_TOC_ENTRY *dsTOC3Ptr= &VarsCmd.pDataspaceTOC[Arg3]; + + TypeCode2 = dsTOC2Ptr->TypeCode; + TypeCode3 = dsTOC3Ptr->TypeCode; + if(TypeCode2 <= TC_LAST_INT_SCALAR && TypeCode3 <= TC_LAST_INT_SCALAR) { + ArgVal2= GetProcArray[TypeCode2](VarsCmd.pDataspace + dsTOC2Ptr->DSOffset); + ArgVal3= GetProcArray[TypeCode3](VarsCmd.pDataspace + dsTOC3Ptr->DSOffset); + ArgVal1= cCmdCompare(COMP_CODE(pCode), ArgVal2, ArgVal3, TypeCode2, TypeCode3); + DS_TOC_ENTRY *dsTOC1Ptr= &VarsCmd.pDataspaceTOC[Arg1]; + SetProcArray[dsTOC1Ptr->TypeCode](VarsCmd.pDataspace + dsTOC1Ptr->DSOffset, ArgVal1); + scalarCmp++; + Status = NO_ERR; + } + else if (TypeCode2 == TC_ARRAY) // two strings + { + // memcmp(); here or in compareagg, could use memcmp to speed up string compares ??? + Status = cCmdCompareAggregates(COMP_CODE(pCode), &CmpBool, Arg2, 0, Arg3, 0); + cCmdSetScalarValFromDataArg(Arg1, CmpBool); + recursiveCmp++; + } + else { // floats + Status = cCmdInterpPolyBinop(*pCode, Arg1, 0, Arg2, 0, Arg3, 0); + scalarFloatCmp++; + } + } + else if(opCode == OP_BRCMP) { // t2 and t3 guaranteed scalar + TYPE_CODE TypeCode2, TypeCode3; + ULONG ArgVal2, ArgVal3; + + Arg1 = pCode[1]; + Arg2 = pCode[2]; + Arg3 = pCode[3]; + TypeCode2= cCmdDSType(Arg2); + TypeCode3= cCmdDSType(Arg3); + ArgVal2= cCmdGetScalarValFromDataArg(Arg2, 0); + ArgVal3= cCmdGetScalarValFromDataArg(Arg3, 0); + CmpBool= cCmdCompare(COMP_CODE(pCode), ArgVal2, ArgVal3, TypeCode2, TypeCode3); + + if (CmpBool) + gPCDelta = (SWORD)Arg1; + else + gPCDelta= 4; + Status= NO_ERR; + } + else if(opCode >= OP_SETIN && opCode <= OP_GETOUT) { + Arg1 = pCode[1]; + Arg2 = pCode[2]; + Arg3 = pCode[3]; + Status= cCmdIOGetSet(opCode, Arg1, Arg2, Arg3); + gPCDelta= 4; + } + else { + scalarOther ++; + Status= cCmdInterpBinop(pCode); + } + return Status; +} + + +NXT_STATUS cCmdInterpBinop(CODE_WORD * const pCode) +{ + NXT_STATUS Status = NO_ERR; + UBYTE opCode; + DATA_ARG Arg1, Arg2, Arg3; + ULONG ArgVal3; + UBYTE CmpBool; + DV_INDEX DVIndex1, DVIndex2; + UWORD i; + + polyBinopDispatch ++; + gPCDelta= 4; + + NXT_ASSERT(pCode != NULL); + opCode = OP_CODE(pCode); + Arg1 = pCode[1]; + Arg2 = pCode[2]; + Arg3 = pCode[3]; + + if (opCode <= OP_XOR) // && ! OP_NEG, can't happen since it is unop + Status= cCmdInterpPolyBinop(opCode, Arg1, 0, Arg2, 0, Arg3, 0); + else if(opCode >= OP_SETIN && opCode <= OP_GETOUT) + Status= cCmdIOGetSet(opCode, Arg1, Arg2, Arg3); + else { + switch (opCode) + { + case OP_CMP: + { + TYPE_CODE TypeCode2= cCmdDSType(Arg2), TypeCode3= cCmdDSType(Arg3); + if(TypeCode2 <= TC_LAST_INT_SCALAR && TypeCode3 <= TC_LAST_INT_SCALAR) { + ULONG ArgVal1, ArgVal2, ArgVal3; + ArgVal2= cCmdGetScalarValFromDataArg(Arg2, 0); + ArgVal3= cCmdGetScalarValFromDataArg(Arg3, 0); + ArgVal1= cCmdCompare(COMP_CODE(pCode), ArgVal2, ArgVal3, TypeCode2, TypeCode3); + cCmdSetScalarValFromDataArg(Arg1, ArgVal1); + PolyScalarCmp++; + } + else if (IS_AGGREGATE_TYPE(TypeCode2) && IS_AGGREGATE_TYPE(TypeCode3) && !IS_AGGREGATE_TYPE(cCmdDSType(Arg1))) + { + //Compare Aggregates + Status = cCmdCompareAggregates(COMP_CODE(pCode), &CmpBool, Arg2, 0, Arg3, 0); + cCmdSetScalarValFromDataArg(Arg1, CmpBool); + recursiveCmp++; + } + else + { + //Compare Elements + Status = cCmdInterpPolyBinop(*pCode, Arg1, 0, Arg2, 0, Arg3, 0); + polyPolyCmp++; + } + } + break; + + case OP_BRCMP: + { + TYPE_CODE TypeCode2= cCmdDSType(Arg2), TypeCode3= cCmdDSType(Arg3); + if(TypeCode2 <= TC_LAST_INT_SCALAR && TypeCode3 <= TC_LAST_INT_SCALAR) { + ULONG ArgVal2, ArgVal3; + ArgVal2= cCmdGetScalarValFromDataArg(Arg2, 0); + ArgVal3= cCmdGetScalarValFromDataArg(Arg3, 0); + CmpBool= cCmdCompare(COMP_CODE(pCode), ArgVal2, ArgVal3, TypeCode2, TypeCode3); + } + else //Compare Aggregates + Status = cCmdCompareAggregates(COMP_CODE(pCode), &CmpBool, Arg2, 0, Arg3, 0); + + if (CmpBool) + gPCDelta = (SWORD)Arg1; + } + break; + + case OP_INDEX: + { + ArgVal3 = (Arg3 != NOT_A_DS_ID) ? cCmdGetScalarValFromDataArg(Arg3, 0) : 0; + + DVIndex2 = cCmdGetDVIndex(Arg2, 0); + if (ArgVal3 >= DV_ARRAY[DVIndex2].Count) + return (ERR_ARG); + + Status = cCmdInterpPolyUnop2(OP_MOV, Arg1, 0, INC_ID(Arg2), ARRAY_ELEM_OFFSET(DVIndex2, ArgVal3)); + } + break; + + case OP_ARRINIT: + { + //Arg1 - Dst, Arg2 - element type/default val, Arg3 - length + + NXT_ASSERT(cCmdDSType(Arg1) == TC_ARRAY); + + ArgVal3 = (Arg3 != NOT_A_DS_ID) ? cCmdGetScalarValFromDataArg(Arg3, 0) : 0; + + Status = cCmdDSArrayAlloc(Arg1, 0, (UWORD)ArgVal3); + if (!IS_ERR(Status)) + { + DVIndex1 = cCmdGetDVIndex(Arg1, 0); + if(cCmdDSType(Arg2) <= TC_LAST_INT_SCALAR) + { + ULONG val= cCmdGetScalarValFromDataArg(Arg2, 0); + TYPE_CODE TypeCode= cCmdDSType(INC_ID(Arg1)); + for (i = 0; i < ArgVal3; i++) // could init ptr and incr by offset GM??? + { + //copy Arg2 into each element of Arg1 + cCmdSetVal(VarsCmd.pDataspace + ARRAY_ELEM_OFFSET(DVIndex1, i), TypeCode, val); + } + } + else + for (i = 0; i < ArgVal3; i++) //copy Arg2 into each element of Arg1 + Status = cCmdInterpPolyUnop2(OP_MOV, INC_ID(Arg1), ARRAY_ELEM_OFFSET(DVIndex1, i), Arg2, 0); + } + } + break; + + default: + { + //Fatal error: Unrecognized instruction + NXT_BREAK; + Status = ERR_INSTR; + } + break; + } + } + return (Status); +} + + +NXT_STATUS cCmdInterpPolyBinop(CODE_WORD const Code, DATA_ARG Arg1, UWORD Offset1, DATA_ARG Arg2, UWORD Offset2, DATA_ARG Arg3, UWORD Offset3) +{ + NXT_STATUS Status = NO_ERR; + TYPE_CODE TypeCode1, TypeCode2, TypeCode3; + DV_INDEX DVIndex1, DVIndex2, DVIndex3; + ULONG ArgVal1, ArgVal2, ArgVal3; + float FltArgVal1, FltArgVal2, FltArgVal3; + UWORD Count1, Count2, Count3; + UWORD MinArrayCount; + UWORD i; + //!!! AdvCluster is intended to catch the case where sources are Cluster and an Array of Clusters. + // In practice, the logic it uses is broken, leading to some source cluster elements being ignored. + UBYTE AdvCluster; + + void * pArg1 = NULL, + *pArg2 = NULL, + *pArg3 = NULL; + + TypeCode1 = cCmdDSType(Arg1); + TypeCode2 = cCmdDSType(Arg2); + TypeCode3 = cCmdDSType(Arg3); + + //Simple case, both args are scalars. Solve and return. + if ((!IS_AGGREGATE_TYPE(TypeCode2)) && (!IS_AGGREGATE_TYPE(TypeCode3))) + { + NXT_ASSERT(!IS_AGGREGATE_TYPE(TypeCode1)); + + pArg1 = cCmdResolveDataArg(Arg1, Offset1, NULL); + + if (TypeCode1 == TC_FLOAT || TypeCode2 == TC_FLOAT || TypeCode3 == TC_FLOAT){ + pArg2 = cCmdResolveDataArg(Arg2, Offset2, NULL); + pArg3 = cCmdResolveDataArg(Arg3, Offset3, NULL); + FltArgVal2 = cCmdGetValFlt(pArg2, TypeCode2); + FltArgVal3 = cCmdGetValFlt(pArg3, TypeCode3); + FltArgVal1 = cCmdBinopFlt(Code, FltArgVal2, FltArgVal3, TypeCode2, TypeCode3); + cCmdSetValFlt(pArg1, TypeCode1, FltArgVal1); + } + else + { + ArgVal2 = cCmdGetScalarValFromDataArg(Arg2, Offset2); + ArgVal3 = cCmdGetScalarValFromDataArg(Arg3, Offset3); + ArgVal1 = cCmdBinop(Code, ArgVal2, ArgVal3, TypeCode2, TypeCode3); + cCmdSetVal(pArg1, TypeCode1, ArgVal1); + } + return Status; + } + + //At least one of the args is an aggregate type + + // + // Initialize Count and ArrayType local variables for each argument + // + + if (TypeCode2 == TC_ARRAY) + { + Count2 = cCmdArrayCount(Arg2, Offset2); + DVIndex2 = cCmdGetDVIndex(Arg2, Offset2); + Offset2 = DV_ARRAY[DVIndex2].Offset; + } + else if (TypeCode2 == TC_CLUSTER) + { + Count2 = cCmdClusterCount(Arg2); + } + + if (TypeCode3 == TC_ARRAY) + { + Count3 = cCmdArrayCount(Arg3, Offset3); + DVIndex3 = cCmdGetDVIndex(Arg3, Offset3); + Offset3 = DV_ARRAY[DVIndex3].Offset; + } + else if (TypeCode3 == TC_CLUSTER) + { + Count3 = cCmdClusterCount(Arg3); + } + + + if (TypeCode1 == TC_ARRAY) + { + //If the destination is an array, make sure it has enough memory to hold the result + if ((TypeCode2 == TC_ARRAY) && (TypeCode3 == TC_ARRAY)) + { + if (Count2 < Count3) + MinArrayCount = Count2; + else + MinArrayCount = Count3; + } + else if (TypeCode2 == TC_ARRAY) + MinArrayCount = Count2; + else if (TypeCode3 == TC_ARRAY) + MinArrayCount = Count3; + else + { + //If output is an array, but no sources are arrays, that's a fatal error! + NXT_BREAK; + return (ERR_ARG); + } + + //Make sure the destination array is the proper size to hold the result + Status = cCmdDSArrayAlloc(Arg1, Offset1, MinArrayCount); + if (IS_ERR(Status)) + return Status; + + Count1 = MinArrayCount; + DVIndex1 = cCmdGetDVIndex(Arg1, Offset1); + Offset1 = DV_ARRAY[DVIndex1].Offset; + AdvCluster = FALSE; + } + else if (TypeCode1 == TC_CLUSTER) + { + Count1 = cCmdClusterCount(Arg1); + AdvCluster = TRUE; + } + + //Advance aggregate args to first sub-element for next call + if (IS_AGGREGATE_TYPE(TypeCode1)) + Arg1 = INC_ID(Arg1); + if (IS_AGGREGATE_TYPE(TypeCode2)) + Arg2 = INC_ID(Arg2); + if (IS_AGGREGATE_TYPE(TypeCode3)) + Arg3 = INC_ID(Arg3); + + // + // Loop through the sub-elements of aggregate arguments. + // Call cCmdInterpPolyBinop recursively with simpler type. + // + + for (i = 0; i < Count1; i++) + { + Status = cCmdInterpPolyBinop(Code, Arg1, Offset1, Arg2, Offset2, Arg3, Offset3); + if (IS_ERR(Status)) + return Status; + + //Advance aggregate args to next sub-element + if (TypeCode1 == TC_ARRAY) + Offset1 += DV_ARRAY[DVIndex1].ElemSize; + else if ((TypeCode1 == TC_CLUSTER) && AdvCluster) + Arg1 = cCmdNextDSElement(Arg1); + + if (TypeCode2 == TC_ARRAY) + Offset2 += DV_ARRAY[DVIndex2].ElemSize; + else if ((TypeCode2 == TC_CLUSTER) && AdvCluster) + Arg2 = cCmdNextDSElement(Arg2); + + if (TypeCode3 == TC_ARRAY) + Offset3 += DV_ARRAY[DVIndex3].ElemSize; + else if ((TypeCode3 == TC_CLUSTER) && AdvCluster) + Arg3 = cCmdNextDSElement(Arg3); + } + + return Status; +} + + +ULONG cCmdBinop(CODE_WORD const Code, ULONG LeftOp, ULONG RightOp, TYPE_CODE LeftType, TYPE_CODE RightType) +{ + UBYTE opCode; + + opCode = OP_CODE((&Code)); + + switch (opCode) + { + case OP_ADD: + { + return LeftOp + RightOp; + } + + case OP_SUB: + { + return LeftOp - RightOp; + } + + case OP_MUL: + { + return LeftOp * RightOp; + } + + case OP_DIV: + { + //Catch divide-by-zero for a portable, well-defined result. + //(x / 0) = 0. Thus Spake LOTHAR!! (It's technical.) + if (RightOp == 0) + return 0; + + if (IS_SIGNED_TYPE(LeftType) && IS_SIGNED_TYPE(RightType)) + return ((SLONG)LeftOp) / ((SLONG)RightOp); + else if (IS_SIGNED_TYPE(LeftType)) + return ((SLONG)LeftOp) / RightOp; + else if (IS_SIGNED_TYPE(RightType)) + return LeftOp / ((SLONG)RightOp); + else + return LeftOp / RightOp; + } + + case OP_MOD: + { + //As with OP_DIV, make sure (x % 0) = x is well-defined + if (RightOp == 0) + return (LeftOp); + + if (IS_SIGNED_TYPE(LeftType) && IS_SIGNED_TYPE(RightType)) + return ((SLONG)LeftOp) % ((SLONG)RightOp); + else if (IS_SIGNED_TYPE(LeftType)) + return ((SLONG)LeftOp) % RightOp; + else if (IS_SIGNED_TYPE(RightType)) + return LeftOp % ((SLONG)RightOp); + else + return LeftOp % RightOp; + } + + case OP_AND: + { + return (LeftOp & RightOp); + } + + case OP_OR: + { + return (LeftOp | RightOp); + } + + case OP_XOR: + { + return ((LeftOp | RightOp) & (~(LeftOp & RightOp))); + } + + case OP_CMP: + { + return cCmdCompare(COMP_CODE((&Code)), LeftOp, RightOp, LeftType, RightType); + } + + default: + { + //Unrecognized instruction, NXT_BREAK for easy debugging (ERR_INSTR handled in caller) + NXT_BREAK; + return 0; + } + } +} + + +float cCmdBinopFlt(CODE_WORD const Code, float LeftOp, float RightOp, TYPE_CODE LeftType, TYPE_CODE RightType) +{ + UBYTE opCode; + + opCode = OP_CODE((&Code)); + + switch (opCode) + { + case OP_ADD: + { + return LeftOp + RightOp; + } + + case OP_SUB: + { + return LeftOp - RightOp; + } + + case OP_MUL: + { + return LeftOp * RightOp; + } + + case OP_DIV: + { + //Catch divide-by-zero for a portable, well-defined result. + //(x / 0) = 0. Thus Spake LOTHAR!! (It's technical.) + if (RightOp == 0) + return 0; + + return LeftOp / RightOp; + } + + case OP_MOD: + { + //As with OP_DIV, make sure (x % 0) = x is well-defined + if (RightOp == 0) + return (LeftOp); + + return (SLONG)LeftOp % (SLONG)RightOp; + } + + case OP_AND: + { + return ((SLONG)LeftOp & (SLONG)RightOp); + } + + case OP_OR: + { + return ((SLONG)LeftOp | (SLONG)RightOp); + } + + case OP_XOR: + { + return (((SLONG)LeftOp | (SLONG)RightOp) & (~((SLONG)LeftOp & (SLONG)RightOp))); + } + + case OP_CMP: + { + return cCmdCompareFlt(COMP_CODE((&Code)), LeftOp, RightOp, LeftType, RightType); + } + + default: + { + //Unrecognized instruction, NXT_BREAK for easy debugging (ERR_INSTR handled in caller) + NXT_BREAK; + return 0; + } + } +} + +NXT_STATUS cCmdInterpNoArg(CODE_WORD * const pCode) +{ + //Fatal error: Unrecognized instruction (no current opcodes have zero instructions) + NXT_BREAK; + return (ERR_INSTR); +} + +NXT_STATUS cCmdInterpShortError(CODE_WORD * const pCode) +{ + //Fatal error: Unrecognized instruction (no current opcodes have zero instructions) + NXT_BREAK; + return (ERR_INSTR); +} + +NXT_STATUS cCmdInterpShortSubCall(CODE_WORD * const pCode) +{ + NXT_STATUS Status; + DATA_ARG Arg1, Arg2; + + gPCDelta= 2; + Arg1 = GetDataArg(SHORT_ARG(pCode) + pCode[1]); + Arg2 = GetDataArg(pCode[1]); + NXT_ASSERT(cCmdIsClumpIDSane((CLUMP_ID)Arg1)); + NXT_ASSERT(!cCmdIsClumpOnQ(&(VarsCmd.RunQ), (CLUMP_ID)Arg1)); + + NXT_ASSERT(cCmdIsDSElementIDSane(Arg2)); + + *((CLUMP_ID *)(cCmdDSScalarPtr(Arg2, 0))) = VarsCmd.RunQ.Head; + + cCmdDeQClump(&(VarsCmd.RunQ), VarsCmd.RunQ.Head); //Take caller off RunQ + cCmdEnQClump(&(VarsCmd.RunQ), (CLUMP_ID)Arg1); //Add callee to RunQ + + Status = CLUMP_SUSPEND; + + return Status; +} + +ULONG moveSameInt= 0, moveDiffInt= 0, moveFloat= 0, moveArrInt= 0, moveOther= 0; +NXT_STATUS cCmdMove(DATA_ARG Arg1, DATA_ARG Arg2) +{ + NXT_STATUS Status; + DS_TOC_ENTRY *TOC1Ptr= &VarsCmd.pDataspaceTOC[Arg1], + *TOC2Ptr= &VarsCmd.pDataspaceTOC[Arg2]; + TYPE_CODE tc1= TOC1Ptr->TypeCode, tc2= TOC2Ptr->TypeCode; + void *pArg1, *pArg2; + + if(tc1 <= TC_LAST_INT_SCALAR && tc2 <= TC_LAST_INT_SCALAR) + { + // if tc1 == tc2, do long, byte, then word assignment + if(tc1 == tc2) + { + moveSameInt++; + pArg1= VarsCmd.pDataspace + TOC1Ptr->DSOffset; + pArg2= VarsCmd.pDataspace + TOC2Ptr->DSOffset; + if(tc1 >= TC_ULONG) + *(ULONG*)pArg1= *(ULONG*)pArg2; + else if(tc1 <= TC_SBYTE) + *(UBYTE*)pArg1= *(UBYTE*)pArg2; + else + *(UWORD*)pArg1= *(UWORD*)pArg2; + Status= NO_ERR; + } + else + { + moveDiffInt++; + ULONG val= cCmdGetScalarValFromDataArg(Arg2, 0); + cCmdSetScalarValFromDataArg(Arg1, val); + Status= NO_ERR; + } + } + else if(tc1 == TC_FLOAT && tc2 == TC_FLOAT) { // may also need to speed up float to int and int to float conversions + moveFloat++; + pArg1= VarsCmd.pDataspace + TOC1Ptr->DSOffset; + pArg2= VarsCmd.pDataspace + TOC2Ptr->DSOffset; + *(float*)pArg1= *(float*)pArg2; + Status= NO_ERR; + } + //!!! Optimized move for arrays of ints. + else if ((tc1 == TC_ARRAY) && (tc2 == TC_ARRAY) + && ((TOC1Ptr+1)->TypeCode <= TC_LAST_INT_SCALAR) + && ((TOC1Ptr+1)->TypeCode == (TOC2Ptr+1)->TypeCode)) + { + ULONG Count; + moveArrInt++; + Count = cCmdArrayCount(Arg2, 0); + Status = cCmdDSArrayAlloc(Arg1, 0, Count); + if (IS_ERR(Status)) + return Status; + + pArg1 = cCmdResolveDataArg(Arg1, 0, NULL); + pArg2 = cCmdResolveDataArg(Arg2, 0, NULL); + + memmove(pArg1, pArg2, Count * cCmdSizeOf((TOC1Ptr+1)->TypeCode)); + } + else { // if ((tc1 == TC_CLUSTER) && (tc2 == TC_CLUSTER)) + moveOther++; + Status = cCmdInterpPolyUnop2(OP_MOV, Arg1, 0, Arg2, 0); + } + return Status; +} + + +NXT_STATUS cCmdInterpShortMove(CODE_WORD * const pCode) +{ + NXT_STATUS Status; + DATA_ARG Arg1, Arg2; + + Arg1 = GetDataArg(SHORT_ARG(pCode) + pCode[1]); + Arg2 = GetDataArg(pCode[1]); + Status= cCmdMove(Arg1, Arg2); + + gPCDelta= 2; + return Status; +} + +NXT_STATUS cCmdInterpShortAcquire(CODE_WORD * const pCode) +{ + NXT_STATUS Status; + DATA_ARG Arg1; + + gPCDelta= 1; + Arg1 = GetDataArg(SHORT_ARG(pCode)); + NXT_ASSERT(cCmdIsDSElementIDSane(Arg1)); + NXT_ASSERT(cCmdDSType(Arg1) == TC_MUTEX); + + Status = cCmdAcquireMutex((MUTEX_Q *)cCmdDSScalarPtr(Arg1, 0)); + + return Status; +} + +NXT_STATUS cCmdInterpShortRelease(CODE_WORD * const pCode) +{ + NXT_STATUS Status; + DATA_ARG Arg1; + + gPCDelta= 1; + Arg1 = GetDataArg(SHORT_ARG(pCode)); + NXT_ASSERT(cCmdIsDSElementIDSane(Arg1)); + NXT_ASSERT(cCmdDSType(Arg1) == TC_MUTEX); + + Status = cCmdReleaseMutex((MUTEX_Q *)cCmdDSScalarPtr(Arg1, 0)); + + return Status; +} + + +//OP_SETOUT gets it's own interpreter function because it is relatively complex +// (called from cCmdInterpOther()) +//This also serves as a convenient breakpoint stop for investigating output module behavior +NXT_STATUS cCmdExecuteSetOut(CODE_WORD * const pCode) +{ + TYPE_CODE TypeCodeField, TypeCodeSrc, TypeCodePortArg; + void *pField = NULL, + *pSrc = NULL, + *pPort = NULL; + DS_ELEMENT_ID PortArg; + UWORD PortCount, InstrSize; + ULONG Port, FieldTableIndex, i, j; + DV_INDEX DVIndex; + + //Arg1 = InstrSize + //Arg2 = port number or list of ports + //Arg3 and beyond = FieldID, src DSID tuples + + //Calculate number of tuples + //!!! Might want to throw ERR_INSTR if instrSize and tuples don't check out + InstrSize = (pCode[1] / 2); + + //Second argument may specify a single port or an array list. + //Figure out which and resolve accordingly. + PortArg = pCode[2]; + TypeCodePortArg = cCmdDSType(PortArg); + + if (TypeCodePortArg == TC_ARRAY) + { + DVIndex = cCmdGetDVIndex(PortArg, 0); + PortCount = cCmdArrayCount(PortArg, 0); + } + else + PortCount = 1; + + //For each port, process all the tuples + for (i = 0; i < PortCount; i++) + { + if (TypeCodePortArg == TC_ARRAY) + { + pPort = (UBYTE*)cCmdResolveDataArg(INC_ID(PortArg), ARRAY_ELEM_OFFSET(DVIndex, i), NULL); + Port = cCmdGetVal(pPort, cCmdDSType(INC_ID(PortArg))); + } + else + { + Port = cCmdGetScalarValFromDataArg(PortArg, 0); + } + + //If user specified a valid port, process the tuples. Else, this port is a no-op + if (Port < NO_OF_OUTPUTS) + { + for (j = 3; j < InstrSize; j += 2) + { + FieldTableIndex = (Port * IO_OUT_FPP) + pCode[j]; + pSrc = cCmdResolveDataArg(pCode[j + 1], 0, &TypeCodeSrc); + + //If FieldTableIndex is valid, go ahead and set the value + if (FieldTableIndex < IO_OUT_FIELD_COUNT) + { + pField = IO_PTRS[MOD_OUTPUT][FieldTableIndex]; + TypeCodeField = IO_TYPES[MOD_OUTPUT][FieldTableIndex]; + cCmdSetVal(pField, TypeCodeField, cCmdGetVal(pSrc, TypeCodeSrc)); + } + //Else, compiler is nutso! Return fatal error. + else + return (ERR_INSTR); + } + } + } + + return (NO_ERR); +} + + +NXT_STATUS cCmdInterpOther(CODE_WORD * const pCode) +{ + NXT_STATUS Status = NO_ERR; + UBYTE opCode; + DATA_ARG Arg1, Arg2, Arg3, Arg4, Arg5; + TYPE_CODE TypeCode1, TypeCode2, TypeCode3, TypeCode5; + ULONG ArgVal2, ArgVal3, ArgVal4, ArgVal5; + UWORD ArrayCount1, ArrayCount2, ArrayCount3, ArrayCount4; + UWORD MinCount; + UWORD i,j; + DV_INDEX DVIndex1, DVIndex2, DVIndex4,TmpDVIndex; + UWORD SrcCount; + DS_ELEMENT_ID TmpDSID; + UWORD DstIndex; + UWORD Size; + UWORD Offset; + + void *pArg1 = NULL; + void *pArg2 = NULL; + void *pArg3 = NULL; + void *pArg5 = NULL; + + NXT_ASSERT(pCode != NULL); + + ULONG sz= INSTR_SIZE(*(UWORD*)pCode); + if (sz == VAR_INSTR_SIZE) + sz = ((UWORD*)pCode)[1]; + gPCDelta= sz/2; // advance words, sz is in bytes + + opCode = OP_CODE(pCode); + + switch (opCode) + { + + case OP_REPLACE: + { + //Arg1 - Dst + //Arg2 - Src + //Arg3 - Index + //Arg4 - New val / array of vals + + Arg1 = pCode[1]; + Arg2 = pCode[2]; + Arg3 = pCode[3]; + Arg4 = pCode[4]; + + NXT_ASSERT(cCmdDSType(Arg1) == TC_ARRAY); + NXT_ASSERT(cCmdDSType(Arg2) == TC_ARRAY); + + //Copy Src to Dst + //!!! Could avoid full data copy if we knew which portion to overwrite + if (Arg1 != Arg2) + { + Status= cCmdMove(Arg1, Arg2); + if (IS_ERR(Status)) + return Status; + } + + DVIndex1 = cCmdGetDVIndex(Arg1, 0); + //Copy new val to Dst + if (Arg3 != NOT_A_DS_ID) + { + pArg3 = cCmdResolveDataArg(Arg3, 0, &TypeCode3); + ArgVal3 = cCmdGetVal(pArg3, TypeCode3); + } + else + { + //Index input unwired + ArgVal3 = 0; + } + + ArrayCount1 = cCmdArrayCount(Arg1, 0); + //Bounds check + //If array index (ArgVal3) is out of range, just pass out the copy of Src (effectively no-op) + if (ArgVal3 >= ArrayCount1) + return (NO_ERR); + + if (cCmdDSType(Arg4) != TC_ARRAY) + { + Status = cCmdInterpPolyUnop2(OP_MOV, INC_ID(Arg1), ARRAY_ELEM_OFFSET(DVIndex1, ArgVal3), Arg4, 0); + if (IS_ERR(Status)) + return Status; + } + else + { + DVIndex4 = cCmdGetDVIndex(Arg4, 0); + + ArrayCount4 = cCmdArrayCount(Arg4, 0); + if (ArrayCount1 - ArgVal3 < ArrayCount4) + MinCount = (UWORD)(ArrayCount1 - ArgVal3); + else + MinCount = ArrayCount4; + + for (i = 0; i < MinCount; i++) + { + Status = cCmdInterpPolyUnop2(OP_MOV, INC_ID(Arg1), ARRAY_ELEM_OFFSET(DVIndex1, ArgVal3 + i), INC_ID(Arg4), ARRAY_ELEM_OFFSET(DVIndex4, i)); + if (IS_ERR(Status)) + return Status; + } + } + } + break; + + case OP_ARRSUBSET: + { + //Arg1 - Dst + //Arg2 - Src + //Arg3 - Index + //Arg4 - Length + + Arg1 = pCode[1]; + Arg2 = pCode[2]; + Arg3 = pCode[3]; + Arg4 = pCode[4]; + + NXT_ASSERT(cCmdDSType(Arg1) == TC_ARRAY); + NXT_ASSERT(cCmdDSType(Arg2) == TC_ARRAY); + + ArrayCount2 = cCmdArrayCount(Arg2, 0); + + if (Arg3 != NOT_A_DS_ID) + ArgVal3 = cCmdGetScalarValFromDataArg(Arg3, 0); + else //Index input unwired + ArgVal3 = 0; + + if (Arg4 != NOT_A_DS_ID) + ArgVal4 = cCmdGetScalarValFromDataArg(Arg4, 0); + else //Length input unwired, set to "rest" + ArgVal4 = (UWORD)(ArrayCount2 - ArgVal3); + + //Bounds check + if (ArgVal3 > ArrayCount2) + { + //Illegal range - return empty subset + Status = cCmdDSArrayAlloc(Arg1, 0, 0); + return Status; + } + + //Set MinCount to "rest" + MinCount = (UWORD)(ArrayCount2 - ArgVal3); + + // Copy "Length" if it is less than "rest" + if (ArgVal4 < (ULONG)MinCount) + MinCount = (UWORD)ArgVal4; + + //Allocate Dst array + Status = cCmdDSArrayAlloc(Arg1, 0, MinCount); + if (IS_ERR(Status)) + return Status; + + DVIndex1 = cCmdGetDVIndex(Arg1, 0); + DVIndex2 = cCmdGetDVIndex(Arg2, 0); + + //Move src subset to dst + for (i = 0; i < MinCount; i++) + { + Status = cCmdInterpPolyUnop2(OP_MOV, INC_ID(Arg1), ARRAY_ELEM_OFFSET(DVIndex1, i), INC_ID(Arg2), ARRAY_ELEM_OFFSET(DVIndex2, ArgVal3 + i)); + if (IS_ERR(Status)) + return Status; + } + } + break; + + case OP_STRSUBSET: + { + //Arg1 - Dst + //Arg2 - Src + //Arg3 - Index + //Arg4 - Length + + Arg1 = pCode[1]; + Arg2 = pCode[2]; + Arg3 = pCode[3]; + Arg4 = pCode[4]; + + NXT_ASSERT(cCmdDSType(Arg1) == TC_ARRAY); + NXT_ASSERT(cCmdDSType(INC_ID(Arg1)) == TC_UBYTE); + NXT_ASSERT(cCmdDSType(Arg2) == TC_ARRAY); + NXT_ASSERT(cCmdDSType(INC_ID(Arg2)) == TC_UBYTE); + + ArrayCount2 = cCmdArrayCount(Arg2, 0); + + //Remove NULL from Count + ArrayCount2--; + + if (Arg3 != NOT_A_DS_ID) + ArgVal3 = cCmdGetScalarValFromDataArg(Arg3, 0); + else //Index input unwired + ArgVal3 = 0; + + if (Arg4 != NOT_A_DS_ID) + ArgVal4 = cCmdGetScalarValFromDataArg(Arg4, 0); + else //Length input unwired, set to "rest" + ArgVal4 = (UWORD)(ArrayCount2 - ArgVal3); + + //Bounds check + if (ArgVal3 > ArrayCount2) + { + //Illegal range - return empty string + Status = cCmdDSArrayAlloc(Arg1, 0, 1); + if (!IS_ERR(Status)) + { + pArg1 = cCmdResolveDataArg(Arg1, 0, NULL); + *((UBYTE *)pArg1) = '\0'; + } + return Status; + } + + //Set MinCount to "rest" + MinCount = (UWORD)(ArrayCount2 - ArgVal3); + + // Copy "Length" if it is less than "rest" + if (ArgVal4 < (ArrayCount2 - ArgVal3)) + MinCount = (UWORD)ArgVal4; + + //Allocate Dst array + Status = cCmdDSArrayAlloc(Arg1, 0, (UWORD)(MinCount + 1)); + if (IS_ERR(Status)) + return Status; + + pArg1 = cCmdResolveDataArg(Arg1, 0, NULL); + pArg2 = cCmdResolveDataArg(Arg2, 0, NULL); + + //Move src subset to dst + memmove((UBYTE *)pArg1, (UBYTE *)pArg2 + ArgVal3, MinCount); + + //Append NULL terminator to Dst + *((UBYTE *)pArg1 + MinCount) = '\0'; + + } + break; + + case OP_SETOUT: + { + Status = cCmdExecuteSetOut(pCode); + } + break; + + case OP_ARRBUILD: + { + // Arg1 - Instruction Size in bytes + // Arg2 - Dst + // Arg3-N - Srcs + + Arg2 = pCode[2]; + + NXT_ASSERT(cCmdDSType(Arg2) == TC_ARRAY); + + //Number of Srcs = total code words - 3 (account for opcode word, size, and Dst) + //!!! Argument access like this is potentially unsafe. + //A function/macro which checks proper encoding would be better + SrcCount = (pCode[1] / 2) - 3; + + //Calculate Dst array count + ArrayCount2 = 0; + for (i = 0; i < SrcCount; i++) + { + TmpDSID = pCode[3 + i]; + NXT_ASSERT(cCmdIsDSElementIDSane(TmpDSID)); + + //If the type descriptors are the same, then the input is an array, not a single element + if (cCmdCompareDSType(Arg2, TmpDSID)) + { + NXT_ASSERT(cCmdDSType(TmpDSID) == TC_ARRAY); + ArrayCount2 += cCmdArrayCount(TmpDSID, 0); + } + else + { + //Assert that the output is an array of this input type + NXT_ASSERT(cCmdCompareDSType(INC_ID(Arg2), TmpDSID)); + ArrayCount2++; + } + } + + //Allocate Dst array + Status = cCmdDSArrayAlloc(Arg2, 0, ArrayCount2); + if (IS_ERR(Status)) + return Status; + + DVIndex2 = cCmdGetDVIndex(Arg2, 0); + + //Move Src(s) to Dst + DstIndex = 0; + for (i = 0; i < SrcCount; i++) + { + TmpDSID = pCode[3 + i]; + + //If the type descriptors are the same, then the input is an array, not a single element + if (cCmdCompareDSType(Arg2, TmpDSID)) + { + NXT_ASSERT(cCmdDSType(TmpDSID) == TC_ARRAY); + TmpDVIndex = cCmdGetDVIndex(TmpDSID, 0); + // if flat, use memmove, otherwise this stuff + if(cCmdDSType(INC_ID(TmpDSID)) <= TC_LAST_INT_SCALAR) + { + memmove(VarsCmd.pDataspace + ARRAY_ELEM_OFFSET(DVIndex2, DstIndex), VarsCmd.pDataspace + DV_ARRAY[TmpDVIndex].Offset, (UWORD)(DV_ARRAY[TmpDVIndex].ElemSize * DV_ARRAY[TmpDVIndex].Count)); + DstIndex += DV_ARRAY[TmpDVIndex].Count; + } + else + for (j = 0; j < DV_ARRAY[TmpDVIndex].Count; j++) + { + Status = cCmdInterpPolyUnop2(OP_MOV, INC_ID(Arg2), ARRAY_ELEM_OFFSET(DVIndex2, DstIndex), INC_ID(TmpDSID), ARRAY_ELEM_OFFSET(TmpDVIndex, j)); + if (IS_ERR(Status)) + return Status; + DstIndex++; + } + } + else + { + //Assert that the output is an array of this input type + NXT_ASSERT(cCmdCompareDSType(INC_ID(Arg2), TmpDSID)); + Status = cCmdInterpPolyUnop2(OP_MOV, INC_ID(Arg2), ARRAY_ELEM_OFFSET(DVIndex2, DstIndex), TmpDSID, 0); + if (IS_ERR(Status)) + return Status; + DstIndex++; + } + } + + NXT_ASSERT(DstIndex == ArrayCount2); + } + break; + + case OP_STRCAT: + { + // Arg1 - Instruction Size in bytes + // Arg2 - Dst + // Arg3-N - Srcs + + Arg2 = pCode[2]; + + //Make sure Dst arg is a string + NXT_ASSERT(cCmdDSType(Arg2) == TC_ARRAY); + NXT_ASSERT(cCmdDSType(INC_ID(Arg2)) == TC_UBYTE); + + //Number of Srcs = total code words - 3 (account for opcode word, size, and Dst) + //!!! Argument access like this is potentially unsafe. + //A function/macro which checks proper encoding would be better + SrcCount = (pCode[1] / 2) - 3; + + //Calculate Dst array count + ArrayCount2 = 0; + for (i = 0; i < SrcCount; i++) + { + TmpDSID = pCode[3 + i]; + NXT_ASSERT(cCmdIsDSElementIDSane(TmpDSID)); + + //Make sure Src arg is a string + //!!! Type checks here should be richer to allow array of strings as input (match LabVIEW behavior) + NXT_ASSERT(cCmdDSType(TmpDSID) == TC_ARRAY); + + if (cCmdDSType(INC_ID(TmpDSID)) != TC_UBYTE) + { + NXT_BREAK; + return ERR_ARG; + } + + ArrayCount3 = cCmdArrayCount(TmpDSID, 0); + NXT_ASSERT(ArrayCount3 > 0); + //Subtract NULL terminator from Src array count + ArrayCount3--; + + //Increase Dst array count by Src array count + ArrayCount2 += ArrayCount3; + } + + //Add room for NULL terminator + ArrayCount2++; + + //Allocate Dst array + Status = cCmdDSArrayAlloc(Arg2, 0, ArrayCount2); + if (IS_ERR(Status)) + return Status; + + //Move Src(s) to Dst + DstIndex = 0; + pArg2 = cCmdResolveDataArg(Arg2, 0, NULL); + for (i = 0; i < SrcCount; i++) + { + TmpDSID = pCode[3 + i]; + + pArg3 = cCmdResolveDataArg(TmpDSID, 0, NULL); + + ArrayCount3 = cCmdArrayCount(TmpDSID, 0); + NXT_ASSERT(ArrayCount3 > 0); + //Subtract NULL terminator from Src array count + ArrayCount3--; + + memmove((UBYTE *)pArg2 + DstIndex, pArg3, ArrayCount3); + DstIndex += ArrayCount3; + } + + //Append NULL terminator to Dst + *((UBYTE *)pArg2 + DstIndex) = '\0'; + DstIndex++; + + NXT_ASSERT(DstIndex == ArrayCount2); + } + break; + + case OP_UNFLATTEN: + { + //Arg1 - Dst + //Arg2 - Err (output) + //Arg3 - Src (byte stream) + //Arg4 - Type + + //The Type arg is a preallocated structure of the exact size you + //want to unflatten into. This allows us to support unflattening arbitrary types. + + //!!! Currently, both outputs must have valid destinations. + // It would be trivial to handle NOT_A_DS_ID to avoid dummy + // allocations when outputs are unused. + + Arg1 = pCode[1]; + Arg2 = pCode[2]; + Arg3 = pCode[3]; + Arg4 = pCode[4]; + + //Move Type template to Dst + //This provides a default value for Dst and makes sure Dst is properly sized + Status= cCmdMove(Arg1, Arg4); + if (IS_ERR(Status)) + return Status; + + //Resolve error data pointer + pArg2 = cCmdResolveDataArg(Arg2, 0, &TypeCode2); + + //Make sure Arg3 is a String + NXT_ASSERT(cCmdDSType(Arg3) == TC_ARRAY); + NXT_ASSERT(cCmdDSType(INC_ID(Arg3)) == TC_UBYTE); + + ArrayCount3 = cCmdArrayCount(Arg3, 0); + //Take NULL terminator out of count + ArrayCount3--; + + Size = cCmdCalcFlattenedSize(Arg4, 0); + + //Check that we have a proper type template to unflatten into + if (ArrayCount3 == Size) + { + pArg3 = cCmdResolveDataArg(Arg3, 0, NULL); + Offset = 0; + Status = cCmdUnflattenFromByteArray(pArg3, &Offset, Arg1, 0); + + //!!! Status ignored from cCmdUnflattenFromByteArray + // If future revisions of this function provide better error checking, + // Err arg should be conditionally set based on the result. + //Unflatten succeeded; set Err arg to FALSE + cCmdSetVal(pArg2, TypeCode2, FALSE); + + NXT_ASSERT(Offset == Size); + } + else + { + //Unflatten failed; set Err arg to TRUE + cCmdSetVal(pArg2, TypeCode2, TRUE); + } + } + break; + + case OP_STRINGTONUM: + { + float ArgValF; + SLONG decimals= 0; + UBYTE cont= TRUE; + // Arg1 - Dst number (output) + // Arg2 - Offset past match (output) + // Arg3 - Src string + // Arg4 - Offset + // Arg5 - Default (type/value) + + //!!! Currently, both outputs must have valid destinations. + // It would be trivial to handle NOT_A_DS_ID to avoid dummy + // allocations when outputs are unused. + + Arg1 = pCode[1]; + Arg2 = pCode[2]; + Arg3 = pCode[3]; + Arg4 = pCode[4]; + Arg5 = pCode[5]; + + pArg1 = cCmdResolveDataArg(Arg1, 0, &TypeCode1); + pArg3 = cCmdResolveDataArg(Arg3, 0, &TypeCode3); + + if (Arg4 != NOT_A_DS_ID) + ArgVal4 = cCmdGetScalarValFromDataArg(Arg4, 0); + else //Offset input unwired + ArgVal4 = 0; + + if (Arg5 != NOT_A_DS_ID) + { + pArg5 = cCmdResolveDataArg(Arg5, 0, &TypeCode5); + ArgVal5 = cCmdGetVal(pArg5, TypeCode5); + } + else //Default input unwired + { + ArgVal5 = 0; + } + + //Read number from string + if (sscanf(((PSZ)pArg3 + ArgVal4), "%f", &ArgValF) == 1) + { + i = (UWORD)ArgVal4; + //Scan until we see the number, consumes negative sign too + while ((((UBYTE *)pArg3)[i] < '0') || (((UBYTE *)pArg3)[i] > '9')) + i++; + + //Scan until we get past the number and no more than one decimal + while (cont) { + if ((((UBYTE *)pArg3)[i] >= '0') && (((UBYTE *)pArg3)[i] <= '9')) + i++; + else if(((UBYTE *)pArg3)[i] == '.' && !decimals) { + i++; + decimals++; + } + else + cont= FALSE; + } + ArgVal2 = i; + } + else + { + //Number wasn't found in string, use defaults + ArgValF = ArgVal5; + ArgVal2 = 0; + } + + //Set outputs + cCmdSetValFlt(pArg1, TypeCode1, ArgValF); + cCmdSetScalarValFromDataArg(Arg2, ArgVal2); + } + break; + + default: + { + //Fatal error: Unrecognized instruction + NXT_BREAK; + Status = ERR_INSTR; + } + break; + } + + return (Status); +} + + +// +//Support functions for lowspeed (I2C devices, i.e. ultrasonic sensor) communications +// + +//Simple lookup table for pMapLowSpeed->ChannelState[Port] values +//This is used to keep VM status code handling consistent +//...and ChannelState gives us too much information, anyway... +static const NXT_STATUS MapLStoVMStat[6] = +{ + NO_ERR, //LOWSPEED_IDLE, + STAT_COMM_PENDING, //LOWSPEED_INIT, + STAT_COMM_PENDING, //LOWSPEED_LOAD_BUFFER, + STAT_COMM_PENDING, //LOWSPEED_COMMUNICATING, + ERR_COMM_BUS_ERR, //LOWSPEED_ERROR, + STAT_COMM_PENDING, //LOWSPEED_DONE (really means c_lowspeed state machine is resetting) +}; + + +//cCmdLSCheckStatus +//Check lowspeed port status, optionally returning bytes available in the buffer for reading +NXT_STATUS cCmdLSCheckStatus(UBYTE Port) +{ + if (Port >= NO_OF_LOWSPEED_COM_CHANNEL) + { + return (ERR_COMM_CHAN_INVALID); + } + + INPUTSTRUCT * pInput = &(pMapInput->Inputs[Port]); + + //If port is not configured properly ahead of time, report that error + //!!! This seems like the right policy, but may restrict otherwise valid read operations... + if (!(pInput->SensorType == LOWSPEED_9V || pInput->SensorType == LOWSPEED) + || !(pInput->InvalidData == FALSE)) + { + return (ERR_COMM_CHAN_NOT_READY); + } + + return (MapLStoVMStat[pMapLowSpeed->ChannelState[Port]]); +} + +//cCmdLSCalcBytesReady +//Calculate true number of bytes available in the inbound LS buffer +UBYTE cCmdLSCalcBytesReady(UBYTE Port) +{ + SLONG Tmp; + + //Expect callers to validate Port, but short circuit here to be safe. + if (Port >= NO_OF_LOWSPEED_COM_CHANNEL) + return 0; + + LSBUF * pInBuf = &(pMapLowSpeed->InBuf[Port]); + + //Normally, bytes available is a simple difference. + Tmp = pInBuf->InPtr - pInBuf->OutPtr; + + //If InPtr is actually behind OutPtr, circular buffer has wrapped. Account for wrappage... + if (Tmp < 0) + Tmp = (pInBuf->InPtr + (SIZE_OF_LSBUF - pInBuf->OutPtr)); + + return (UBYTE)(Tmp); +} + +//cCmdLSWrite +//Write BufLength bytes into specified port's lowspeed buffer and kick off comm process to device +NXT_STATUS cCmdLSWrite(UBYTE Port, UBYTE BufLength, UBYTE *pBuf, UBYTE ResponseLength) +{ + if (Port >= NO_OF_LOWSPEED_COM_CHANNEL) + { + return (ERR_COMM_CHAN_INVALID); + } + + if (BufLength > SIZE_OF_LSBUF || ResponseLength > SIZE_OF_LSBUF) + { + return (ERR_INVALID_SIZE); + } + + INPUTSTRUCT * pInput = &(pMapInput->Inputs[Port]); + UBYTE * pChState = &(pMapLowSpeed->ChannelState[Port]); + LSBUF * pOutBuf = &(pMapLowSpeed->OutBuf[Port]); + + //Only start writing process if port is properly configured and c_lowspeed module is ready + if ((pInput->SensorType == LOWSPEED_9V || pInput->SensorType == LOWSPEED) + && (pInput->InvalidData == FALSE) + && (*pChState == LOWSPEED_IDLE) || (*pChState == LOWSPEED_ERROR)) + { + pOutBuf->InPtr = 0; + pOutBuf->OutPtr = 0; + + memcpy(pOutBuf->Buf, pBuf, BufLength); + pOutBuf->InPtr = (UBYTE)BufLength; + + pMapLowSpeed->InBuf[Port].BytesToRx = ResponseLength; + + *pChState = LOWSPEED_INIT; + pMapLowSpeed->State |= (COM_CHANNEL_ONE_ACTIVE << Port); + + return (NO_ERR); + } + else + { + //!!! Would be more consistent to return STAT_COMM_PENDING if c_lowspeed is busy + return (ERR_COMM_CHAN_NOT_READY); + } +} + + +//cCmdLSRead +//Read BufLength bytes from specified port's lowspeed buffer +NXT_STATUS cCmdLSRead(UBYTE Port, UBYTE BufLength, UBYTE * pBuf) +{ + UBYTE BytesReady, BytesToRead; + + if (Port >= NO_OF_LOWSPEED_COM_CHANNEL) + { + return (ERR_COMM_CHAN_INVALID); + } + + if (BufLength > SIZE_OF_LSBUF) + { + return (ERR_INVALID_SIZE); + } + + BytesReady = cCmdLSCalcBytesReady(Port); + + if (BufLength > BytesReady) + { + return (ERR_COMM_CHAN_NOT_READY); + } + + BytesToRead = BufLength; + + LSBUF * pInBuf = &(pMapLowSpeed->InBuf[Port]); + + //If the bytes we want to read wrap around the end, we must first read the end, then reset back to the beginning + if (pInBuf->OutPtr + BytesToRead >= SIZE_OF_LSBUF) + { + BytesToRead = SIZE_OF_LSBUF - pInBuf->OutPtr; + memcpy(pBuf, pInBuf->Buf + pInBuf->OutPtr, BytesToRead); + pInBuf->OutPtr = 0; + pBuf += BytesToRead; + BytesToRead = BufLength - BytesToRead; + } + + memcpy(pBuf, pInBuf->Buf + pInBuf->OutPtr, BytesToRead); + pInBuf->OutPtr += BytesToRead; + + return (NO_ERR); +} + + +// +//Wrappers for OP_SYSCALL +// + +// +//cCmdWrapFileOpenRead +//ArgV[0]: (Function return) Loader status, U16 return +//ArgV[1]: File Handle, U8 return +//ArgV[2]: Filename, CStr +//ArgV[3]: Length, U32 return +NXT_STATUS cCmdWrapFileOpenRead(UBYTE * ArgV[]) +{ + LOADER_STATUS LStatus; + DV_INDEX DVIndex; + + //Resolve array argument + DVIndex = *(DV_INDEX *)(ArgV[2]); + ArgV[2] = cCmdDVPtr(DVIndex); + + LStatus = pMapLoader->pFunc(OPENREAD, ArgV[2], NULL, (ULONG *)ArgV[3]); + + //Add entry into FileHandleTable + if (LOADER_ERR(LStatus) == SUCCESS) + { + VarsCmd.FileHandleTable[LOADER_HANDLE(LStatus)][0] = 'r'; + strcpy((PSZ)(VarsCmd.FileHandleTable[LOADER_HANDLE(LStatus)] + 1), (PSZ)(ArgV[2])); + } + + //Status code in high byte of LStatus + *((UWORD *)ArgV[0]) = LOADER_ERR(LStatus); + //File handle in low byte of LStatus + *(ArgV[1]) = LOADER_HANDLE(LStatus); + + return NO_ERR; +} + +//cCmdWrapFileOpenWrite +//ArgV[0]: (Function return) Loader status, U16 return +//ArgV[1]: File Handle, U8 return +//ArgV[2]: Filename, CStr +//ArgV[3]: Length, U32 return +NXT_STATUS cCmdWrapFileOpenWrite(UBYTE * ArgV[]) +{ + LOADER_STATUS LStatus; + DV_INDEX DVIndex; + + //Resolve array argument + DVIndex = *(DV_INDEX *)(ArgV[2]); + ArgV[2] = cCmdDVPtr(DVIndex); + + LStatus = pMapLoader->pFunc(OPENWRITEDATA, ArgV[2], NULL, (ULONG *)ArgV[3]); + + //Add entry into FileHandleTable + if (LOADER_ERR(LStatus) == SUCCESS) + { + VarsCmd.FileHandleTable[LOADER_HANDLE(LStatus)][0] = 'w'; + strcpy((PSZ)(VarsCmd.FileHandleTable[LOADER_HANDLE(LStatus)] + 1), (PSZ)(ArgV[2])); + } + + //Status code in high byte of LStatus + *((UWORD *)ArgV[0]) = LOADER_ERR(LStatus); + //File handle in low byte of LStatus + *(ArgV[1]) = LOADER_HANDLE(LStatus); + + return NO_ERR; +} + +//cCmdWrapFileOpenAppend +//ArgV[0]: (Function return) Loader status, U16 return +//ArgV[1]: File Handle, U8 return +//ArgV[2]: Filename, CStr +//ArgV[3]: Length Remaining, U32 return +NXT_STATUS cCmdWrapFileOpenAppend(UBYTE * ArgV[]) +{ + LOADER_STATUS LStatus; + DV_INDEX DVIndex; + + //Resolve array argument + DVIndex = *(DV_INDEX *)(ArgV[2]); + ArgV[2] = cCmdDVPtr(DVIndex); + + LStatus = pMapLoader->pFunc(OPENAPPENDDATA, ArgV[2], NULL, (ULONG *)ArgV[3]); + + //Add entry into FileHandleTable + if (LOADER_ERR(LStatus) == SUCCESS) + { + VarsCmd.FileHandleTable[LOADER_HANDLE(LStatus)][0] = 'w'; + strcpy((PSZ)(VarsCmd.FileHandleTable[LOADER_HANDLE(LStatus)] + 1), (PSZ)(ArgV[2])); + } + + //Status code in high byte of LStatus + *((UWORD *)ArgV[0]) = LOADER_ERR(LStatus); + //File handle in low byte of LStatus + *(ArgV[1]) = LOADER_HANDLE(LStatus); + + return NO_ERR; +} + +//cCmdWrapFileRead +//ArgV[0]: (Function return) Loader status, U16 return +//ArgV[1]: File Handle, U8 in/out +//ArgV[2]: Buffer, CStr out +//ArgV[3]: Length, U32 in/out +NXT_STATUS cCmdWrapFileRead(UBYTE * ArgV[]) +{ + NXT_STATUS Status = NO_ERR; + LOADER_STATUS LStatus; + DV_INDEX DVIndex; + + //Resolve array argument + DVIndex = *(DV_INDEX *)(ArgV[2]); + //Size Buffer to Length + //Add room for null terminator to length + Status = cCmdDVArrayAlloc(DVIndex, (UWORD)(*(ULONG *)ArgV[3] + 1)); + if (IS_ERR(Status)) + return Status; + + ArgV[2] = cCmdDVPtr(DVIndex); + LStatus = pMapLoader->pFunc(READ, ArgV[1], ArgV[2], (ULONG *)ArgV[3]); + + //Tack on NULL terminator + //Note that loader code may have adjusted length (*ArgV[3]) if all requested data was not available + //!!! Better solution would be to resize buffer to new length + 1, + // but then you must also be wary of side effects if resize allocation fails! + *(ArgV[2] + *(ULONG *)ArgV[3]) = '\0'; + + //Status code in high byte of LStatus + *((UWORD *)ArgV[0]) = LOADER_ERR(LStatus); + //File handle in low byte of LStatus + *(ArgV[1]) = LOADER_HANDLE(LStatus); + + return Status; +} + +//cCmdWrapFileWrite +//ArgV[0]: (Function return) Loader status, U16 return +//ArgV[1]: File Handle, U8 in/out +//ArgV[2]: Buffer, CStr +//ArgV[3]: Length, U32 return +NXT_STATUS cCmdWrapFileWrite(UBYTE * ArgV[]) +{ + LOADER_STATUS LStatus; + DV_INDEX DVIndex; + + //Resolve array argument + DVIndex = *(DV_INDEX *)(ArgV[2]); + ArgV[2] = cCmdDVPtr(DVIndex); + + LStatus = pMapLoader->pFunc(WRITE, ArgV[1], ArgV[2], (ULONG *)ArgV[3]); + + //Status code in high byte of LStatus + *((UWORD *)ArgV[0]) = LOADER_ERR(LStatus); + //File handle in low byte of LStatus + *(ArgV[1]) = LOADER_HANDLE(LStatus); + + return NO_ERR; +} + +//cCmdWrapFileClose +//ArgV[0]: (Function return) Loader status, U16 return +//ArgV[1]: File Handle, U8 +NXT_STATUS cCmdWrapFileClose(UBYTE * ArgV[]) +{ + LOADER_STATUS LStatus; + + //!!! This bounds check also exists in dLoaderCloseHandle(), but we provide an explicit error code + if (*(ArgV[1]) >= MAX_HANDLES) + { + *((UWORD *)ArgV[0]) = ILLEGALHANDLE; + return NO_ERR; + } + + LStatus = pMapLoader->pFunc(CLOSE, ArgV[1], NULL, NULL); + + //Clear entry in FileHandleTable + memset(VarsCmd.FileHandleTable[*(ArgV[1])], 0, FILENAME_LENGTH + 2); + + //Status code in high byte of LStatus + *((UWORD *)ArgV[0]) = LOADER_ERR(LStatus); + + return NO_ERR; +} + +//cCmdWrapFileResolveHandle +//ArgV[0]: (Function return) Loader status, U16 return +//ArgV[1]: File Handle, U8 return +//ArgV[2]: Write Handle?, Bool return +//ArgV[3]: Filename, CStr +NXT_STATUS cCmdWrapFileResolveHandle (UBYTE * ArgV[]) +{ + UBYTE i; + DV_INDEX DVIndex; + + //Resolve array argument + DVIndex = *(DV_INDEX *)(ArgV[3]); + ArgV[3] = cCmdDVPtr(DVIndex); + + for (i = 0; i < MAX_HANDLES; i++) + { + if (strcmp((PSZ)(ArgV[3]), (PSZ)(VarsCmd.FileHandleTable[i] + 1)) == 0) + { + *(ArgV[2]) = (VarsCmd.FileHandleTable[i][0] == 'w'); + break; + } + } + + if (i == MAX_HANDLES) + { + i = NOT_A_HANDLE; + *((UWORD *)ArgV[0]) = HANDLEALREADYCLOSED; + } + else + { + *((UWORD *)ArgV[0]) = SUCCESS; + } + + *(ArgV[1]) = i; + + return NO_ERR; +} + + +//cCmdWrapFileRename +//ArgV[0]: (Function return) Loader status, U16 return +//ArgV[1]: Old Filename, CStr +//ArgV[2]: New Filename, CStr +NXT_STATUS cCmdWrapFileRename (UBYTE * ArgV[]) +{ + LOADER_STATUS LStatus; + ULONG Tmp; + DV_INDEX DVIndex; + + //Resolve array arguments + DVIndex = *(DV_INDEX *)(ArgV[1]); + ArgV[1] = cCmdDVPtr(DVIndex); + DVIndex = *(DV_INDEX *)(ArgV[2]); + ArgV[2] = cCmdDVPtr(DVIndex); + + //!!! Tmp placeholder passed into loader code to avoid illegal dereferencing. + LStatus = pMapLoader->pFunc(RENAMEFILE, ArgV[1], ArgV[2], &Tmp); + + //Status code in high byte of LStatus + *((UWORD *)ArgV[0]) = LOADER_ERR(LStatus); + + return NO_ERR; +} + + +//cCmdWrapFileDelete +//ArgV[0]: (Function return) Loader status, U16 return +//ArgV[1]: Filename, CStr +NXT_STATUS cCmdWrapFileDelete (UBYTE * ArgV[]) +{ + LOADER_STATUS LStatus; + DV_INDEX DVIndex; + + //Resolve array arguments + DVIndex = *(DV_INDEX *)(ArgV[1]); + ArgV[1] = cCmdDVPtr(DVIndex); + + LStatus = pMapLoader->pFunc(DELETE, ArgV[1], NULL, NULL); + + //Status code in high byte of LStatus + *((UWORD *)ArgV[0]) = LOADER_ERR(LStatus); + + return NO_ERR; +} + +// +//cCmdWrapSoundPlayFile +//ArgV[0]: (Return value) Status code, SBYTE +//ArgV[1]: Filename, CStr +//ArgV[2]: Loop?, UBYTE (bool) +//ArgV[3]: Volume, UBYTE +// +NXT_STATUS cCmdWrapSoundPlayFile(UBYTE * ArgV[]) +{ + DV_INDEX DVIndex; + + //Resolve array arguments + DVIndex = *(DV_INDEX *)(ArgV[1]); + UBYTE sndVol= *(ArgV[3]); + ArgV[1] = cCmdDVPtr(DVIndex); + + //!!! Should check filename and/or existence and return error before proceeding + strncpy((PSZ)(pMapSound->SoundFilename), (PSZ)(ArgV[1]), FILENAME_LENGTH); + + if (*(ArgV[2]) == TRUE) + pMapSound->Mode = SOUND_LOOP; + else + pMapSound->Mode = SOUND_ONCE; + + if(sndVol > 4) + sndVol= 4; + pMapSound->Volume = sndVol; + //SampleRate of '0' means "let file specify SampleRate" + pMapSound->SampleRate = 0; + pMapSound->Flags |= SOUND_UPDATE; + + *((SBYTE*)(ArgV[0])) = (NO_ERR); + + return (NO_ERR); +} + +// +//cCmdWrapSoundPlayTone +//ArgV[0]: (Return value) Status code, SBYTE +//ArgV[1]: Frequency, UWORD +//ArgV[2]: Duration, UWORD +//ArgV[3]: Loop?, UBYTE (Boolean) +//ArgV[4]: Volume, UBYTE +// +NXT_STATUS cCmdWrapSoundPlayTone(UBYTE * ArgV[]) +{ + UBYTE sndVol= *(ArgV[4]); + pMapSound->Freq = *(UWORD*)(ArgV[1]); + pMapSound->Duration = *(UWORD*)(ArgV[2]); + if(sndVol > 4) + sndVol= 4; + pMapSound->Volume = sndVol; + pMapSound->Flags |= SOUND_UPDATE; + + if (*(ArgV[3]) == TRUE) + pMapSound->Mode = SOUND_TONE | SOUND_LOOP; + else + pMapSound->Mode = SOUND_TONE; + + *((SBYTE*)(ArgV[0])) = (NO_ERR); + + return (NO_ERR); +} + +// +//cCmdWrapSoundGetState +//ArgV[0]: (Return value) sound module state, UBYTE +//ArgV[1]: Flags, UBYTE +// +NXT_STATUS cCmdWrapSoundGetState(UBYTE * ArgV[]) +{ + *(ArgV[0]) = pMapSound->State; + *(ArgV[1]) = pMapSound->Flags; + return (NO_ERR); +} + +// +//cCmdWrapSoundSetState +//ArgV[0]: (Return value) sound module state, UBYTE +//ArgV[1]: State, UBYTE +//ArgV[2]: Flags, UBYTE +// +NXT_STATUS cCmdWrapSoundSetState(UBYTE * ArgV[]) +{ + pMapSound->State = *(ArgV[1]); + //Return same state we just set, mostly for interface consistency + *(ArgV[0]) = pMapSound->State; + + //OR in provided flags (usually 0) + pMapSound->Flags |= *(ArgV[2]); + + return (NO_ERR); +} + +// +//cCmdWrapReadButton +//ArgV[0]: (Function return) Status code, SBYTE +//ArgV[1]: Index (U8) +//ArgV[2]: Pressed (bool) +//ArgV[3]: Count (U8) (count of press-then-release cycles) +//ArgV[4]: ResetCount? (bool in) +// +NXT_STATUS cCmdWrapReadButton(UBYTE * ArgV[]) +{ + UBYTE btnIndex; + + btnIndex = *((UBYTE*)(ArgV[1])); + + if (btnIndex < NO_OF_BTNS) + { + //Set pressed boolean output + if (pMapButton->State[btnIndex] & PRESSED_STATE) + *(ArgV[2]) = TRUE; + else + *(ArgV[2]) = FALSE; + + //Set count output + *(ArgV[3]) = (UBYTE)(pMapButton->BtnCnt[btnIndex].RelCnt); + + //Optionally reset internal count + if (*(ArgV[4]) != 0) + { + pMapButton->BtnCnt[btnIndex].RelCnt = 0; + //Need to clear short and long counts too, because RelCnt depends on them. No known side effects. + pMapButton->BtnCnt[btnIndex].ShortRelCnt = 0; + pMapButton->BtnCnt[btnIndex].LongRelCnt = 0; + } + + // Set status code 'OK' + *((SBYTE*)(ArgV[0])) = NO_ERR; + } + else + { + //Bad button index specified, return error and default outputs + *((SBYTE*)(ArgV[0])) = ERR_INVALID_PORT; + *(ArgV[2]) = FALSE; + *(ArgV[3]) = 0; + } + + return (NO_ERR); +} + +// +//cCmdWrapCommLSWrite +//ArgV[0]: (return) Status code, SBYTE +//ArgV[1]: Port specifier, UBYTE +//ArgV[2]: Buffer to send, UBYTE array, only SIZE_OF_LSBUF bytes will be used +//ArgV[3]: ResponseLength, UBYTE, specifies expected bytes back from slave device +// +NXT_STATUS cCmdWrapCommLSWrite(UBYTE * ArgV[]) +{ + SBYTE * pReturnVal = (SBYTE*)(ArgV[0]); + UBYTE Port = *(ArgV[1]); + UBYTE * pBuf; + UWORD BufLength; + UBYTE ResponseLength = *(ArgV[3]); + DV_INDEX DVIndex; + + //Resolve array arguments + DVIndex = *(DV_INDEX *)(ArgV[2]); + pBuf = cCmdDVPtr(DVIndex); + BufLength = DV_ARRAY[DVIndex].Count; + + *pReturnVal = cCmdLSWrite(Port, (UBYTE)BufLength, pBuf, ResponseLength); + + return (NO_ERR); +} + +// +//cCmdWrapCommLSCheckStatus +//ArgV[0]: (return) Status code, SBYTE +//ArgV[1]: Port specifier, UBYTE +//ArgV[2]: BytesReady, UBYTE +// +NXT_STATUS cCmdWrapCommLSCheckStatus(UBYTE * ArgV[]) +{ + UBYTE Port = *(ArgV[1]); + + *((SBYTE*)(ArgV[0])) = cCmdLSCheckStatus(Port); + *((UBYTE*)(ArgV[2])) = cCmdLSCalcBytesReady(Port); + + return (NO_ERR); +} + +// +//cCmdWrapCommLSRead +//ArgV[0]: (return) Status code, SBYTE +//ArgV[1]: Port specifier, UBYTE +//ArgV[2]: Buffer for data, UBYTE array, max SIZE_OF_LSBUF bytes will be written +//ArgV[3]: BufferLength, UBYTE, specifies size of buffer requested +// +NXT_STATUS cCmdWrapCommLSRead(UBYTE * ArgV[]) +{ + SBYTE * pReturnVal = (SBYTE*)(ArgV[0]); + UBYTE Port = *(ArgV[1]); + UBYTE * pBuf; + UBYTE BufLength = *(ArgV[3]); + UBYTE BytesToRead; + DV_INDEX DVIndex = *(DV_INDEX *)(ArgV[2]); + NXT_STATUS AllocStatus; + + *pReturnVal = cCmdLSCheckStatus(Port); + BytesToRead = cCmdLSCalcBytesReady(Port); + + //If channel is OK and has data ready for us, put the data into outgoing buffer + if (!IS_ERR(*pReturnVal) && BytesToRead > 0) + { + //Limit buffer to available data + if (BufLength > BytesToRead) + BufLength = BytesToRead; + + AllocStatus = cCmdDVArrayAlloc(DVIndex, BufLength); + if (IS_ERR(AllocStatus)) + return (AllocStatus); + + pBuf = cCmdDVPtr(DVIndex); + *pReturnVal = cCmdLSRead(Port, BufLength, pBuf); + } + //Else, the channel has an error and/or there's no data to read; clear the output array + else + { + AllocStatus = cCmdDVArrayAlloc(DVIndex, 0); + if (IS_ERR(AllocStatus)) + return (AllocStatus); + } + + return (NO_ERR); +} + +// +//cCmdWrapRandomNumber +//ArgV[0]: (return) Random number, SWORD +// +NXT_STATUS cCmdWrapRandomNumber(UBYTE * ArgV[]) +{ + static UBYTE count = 0; + SWORD random; + + if (count == 0) + srand(dTimerRead()); + + if (count > 20) + count = 0; + else + count++; + + //!!! IAR's implementation of the rand() library function returns signed values, and we want it that way. + //Some stdlib implementations may return only positive numbers, so be wary if this code is ported. + random = rand(); + + *((SWORD *)ArgV[0]) = random; + + return NO_ERR; +} + +// +//cCmdWrapGetStartTick +//ArgV[0]: (return) Start Tick, ULONG +// +NXT_STATUS cCmdWrapGetStartTick(UBYTE * ArgV[]) +{ + *((ULONG *)ArgV[0]) = VarsCmd.StartTick; + return NO_ERR; +} + +// +//cCmdWrapMessageWrite +//ArgV[0]: (return) Error Code, SBYTE (NXT_STATUS) +//ArgV[1]: QueueID, UBYTE +//ArgV[2]: Message, CStr +// +NXT_STATUS cCmdWrapMessageWrite(UBYTE * ArgV[]) +{ + NXT_STATUS Status = NO_ERR; + DV_INDEX DVIndex; + + //Resolve array arguments + DVIndex = *(DV_INDEX *)(ArgV[2]); + ArgV[2] = cCmdDVPtr(DVIndex); + + Status = cCmdMessageWrite(*(UBYTE *)(ArgV[1]), ArgV[2], DV_ARRAY[DVIndex].Count); + + *(SBYTE *)(ArgV[0]) = Status; + + if (IS_FATAL(Status)) + return Status; + else + return (NO_ERR); +} + + + +// +//cCmdWrapColorSensorRead +//ArgV[0]: (return) Error code, SBYTE +//ArgV[1]: Port, UBYTE +//ArgV[2]: SensorValue, SWORD +//ArgV[3]: RawArray, UWORD[NO_OF_COLORS] +//ArgV[4]: NormalizedArray, UWORD[NO_OF_COLORS] +//ArgV[5]: ScaledArray, SWORD[NO_OF_COLORS] +//ArgV[6]: InvalidData, UBYTE +// +NXT_STATUS cCmdWrapColorSensorRead (UBYTE * ArgV[]) +{ + DV_INDEX DVIndex; + NXT_STATUS Status = NO_ERR; + //Resolve return val arguments + SBYTE * pReturnVal = (SBYTE*)(ArgV[0]); + //Resolve Port argument + UBYTE Port = *(UBYTE*)(ArgV[1]); + //Resolve SensorValue + SWORD SensorValue = *(SWORD*)(ArgV[2]); + //Resolve RawArray as array + DVIndex = *(DV_INDEX*)(ArgV[3]); + NXT_ASSERT(IS_DV_INDEX_SANE(DestDVIndex)); + Status= cCmdDVArrayAlloc(DVIndex, NO_OF_COLORS); + if (IS_ERR(Status)) + return (Status); + ArgV[3] = cCmdDVPtr (DVIndex); + //Resolve NormalizedArray as array + DVIndex = *(DV_INDEX*)(ArgV[4]); + NXT_ASSERT(IS_DV_INDEX_SANE(DestDVIndex)); + Status= cCmdDVArrayAlloc(DVIndex, NO_OF_COLORS); + if (IS_ERR(Status)) + return (Status); + ArgV[4] = cCmdDVPtr (DVIndex); + //Resolve ScaledArray as array + DVIndex = *(DV_INDEX*)(ArgV[5]); + NXT_ASSERT(IS_DV_INDEX_SANE(DestDVIndex)); + Status= cCmdDVArrayAlloc(DVIndex, NO_OF_COLORS); + if (IS_ERR(Status)) + return (Status); + ArgV[5] = cCmdDVPtr (DVIndex); + //Resolve InvalidData + UBYTE InvalidData = *(UBYTE*)(ArgV[6]); + + //call implementation with unwrapped parameters + *pReturnVal = cCmdColorSensorRead (Port, &SensorValue, (UWORD*)ArgV[3], (UWORD*)ArgV[4], (SWORD*)ArgV[5], &InvalidData); + + *(ArgV[2]) = SensorValue; + *(ArgV[6]) = InvalidData; + + if (IS_ERR(*pReturnVal)){ + return (*pReturnVal); + } + return NO_ERR; +} + + +#define UNPACK_STATUS(StatusWord) ((SBYTE)(StatusWord)) + +NXT_STATUS cCmdBTCheckStatus(UBYTE Connection) +{ + //If specified connection is invalid, return error code to the user. + if (Connection >= SIZE_OF_BT_CONNECT_TABLE) + { + return (ERR_INVALID_PORT); + } + + //INPROGRESS means a request is currently pending completion by the comm module + if (VarsCmd.CommStat == INPROGRESS) + { + return (STAT_COMM_PENDING); + } + //Translate BTBUSY to ERR_COMM_CHAN_NOT_READY + //And check if specified connection is indeed configured + else if (VarsCmd.CommStat == (SWORD)BTBUSY + || (pMapComm->BtConnectTable[Connection].Name[0]) == '\0') + { + return (ERR_COMM_CHAN_NOT_READY); + } + else + { + return (UNPACK_STATUS(VarsCmd.CommStat)); + } +} + +//Default packet to send for a remote MESSAGE_READ command. +//3rd byte must be replaced with remote mailbox (QueueID) +//4th byte must be replaced with local mailbox +static UBYTE RemoteMsgReadPacket[5] = {0x00, 0x13, 0xFF, 0xFF, 0x01}; + +// +//cCmdWrapMessageRead +//ArgV[0]: (return) Error Code, SBYTE (NXT_STATUS) +//ArgV[1]: QueueID, UBYTE +//ArgV[2]: Remove, UBYTE +//ArgV[3]: (return) Message, CStr +// +NXT_STATUS cCmdWrapMessageRead(UBYTE * ArgV[]) +{ + NXT_STATUS Status = NO_ERR; + NXT_STATUS AllocStatus = NO_ERR; + UBYTE QueueID = *(UBYTE *)(ArgV[1]); + DV_INDEX DestDVIndex = *(DV_INDEX *)(ArgV[3]); + UWORD MessageSize; + UBYTE i; + + NXT_ASSERT(IS_DV_INDEX_SANE(DestDVIndex)); + + //Check Next Message's size + Status = cCmdMessageGetSize(QueueID, &MessageSize); + + //If there is a valid message in local mailbox, read it + if (!IS_ERR(Status) && MessageSize > 0 ) + { + //!!! Also check for EMPTY_MAILBOX status? + //Size destination string + AllocStatus = cCmdDVArrayAlloc(DestDVIndex, MessageSize); + if (IS_ERR(AllocStatus)) + return AllocStatus; + + //Get Message + //!!! Should more aggressively enforce null termination before blindly copying to dataspace + Status = cCmdMessageRead(QueueID, cCmdDVPtr(DestDVIndex), MessageSize, *(ArgV[2])); + } + else + { + //Clear destination string + AllocStatus = cCmdDVArrayAlloc(DestDVIndex, 1); + if (IS_ERR(AllocStatus)) + return AllocStatus; + + //Successful allocation, make sure first byte is null terminator + *(UBYTE*)(cCmdDVPtr(DestDVIndex)) = '\0'; + } + + //If there were no local messages, see if there are any waiting in our slaves' outboxes + if (Status == STAT_MSG_EMPTY_MAILBOX && QueueID < INCOMING_QUEUE_COUNT) + { + //If there's an old error code hanging around, clear it before proceeding. + //!!! Clearing error here means bytecode status checking loops could get false SUCCESS results? + if (VarsCmd.CommStat < 0) + VarsCmd.CommStat = SUCCESS; + + //Search through possible slaves, looking for valid connection + for (i = 0; i < SIZE_OF_BT_CONNECT_TABLE - 1; i++) + { + //Advance CommCurrConnection and limit to 1, 2, or 3 (only slave connection slots are checked) + VarsCmd.CommCurrConnection++; + if (VarsCmd.CommCurrConnection == SIZE_OF_BT_CONNECT_TABLE) + VarsCmd.CommCurrConnection = 1; + + if (cCmdBTCheckStatus(VarsCmd.CommCurrConnection) == NO_ERR) + break; + } + + //If there is at least one configured slave connection, make a remote read request + if (i < SIZE_OF_BT_CONNECT_TABLE - 1) + { + //Outgoing QueueID on slave device is the local QueueID + INCOMING_QUEUE_COUNT + RemoteMsgReadPacket[2] = QueueID + INCOMING_QUEUE_COUNT; + RemoteMsgReadPacket[3] = QueueID; + + //Request comm module to send assembled packet and not go idle until response comes back (or error) + pMapComm->pFunc(SENDDATA, sizeof(RemoteMsgReadPacket), VarsCmd.CommCurrConnection, TRUE, RemoteMsgReadPacket, (UWORD*)&(VarsCmd.CommStat)); + + //Read status back after SENDDATA call so bytecode gets STAT_COMM_PENDING or error + Status = cCmdBTCheckStatus(VarsCmd.CommCurrConnection); + + //If our request was accepted, set the DirtyComm flag so stream will get cleaned up later + if (Status == STAT_COMM_PENDING) + VarsCmd.DirtyComm = TRUE; + } + } + + *(SBYTE *)(ArgV[0]) = Status; + if (IS_FATAL(Status)) + return Status; + else + return (NO_ERR); +} + + +// +//cCmdWrapCommBTCheckStatus +//ArgV[0]: (return) Status byte, SBYTE +//ArgV[1]: Connection index, 0-3 +// +NXT_STATUS cCmdWrapCommBTCheckStatus(UBYTE * ArgV[]) +{ + *((SBYTE*)(ArgV[0])) = cCmdBTCheckStatus(*(ArgV[1])); + + return (NO_ERR); +} + +// +//cCmdWrapCommBTWrite +//ArgV[0]: (return) Status byte, SBYTE +//ArgV[1]: Connection index, 0-3 +//ArgV[2]: Buffer +// +NXT_STATUS cCmdWrapCommBTWrite(UBYTE * ArgV[]) +{ + SBYTE * pReturnVal = (SBYTE*)(ArgV[0]); + UBYTE Connection = *(ArgV[1]); + UBYTE * pBuf; + UWORD BufLength; + DV_INDEX DVIndex; + + //Resolve array arguments + DVIndex = *(DV_INDEX *)(ArgV[2]); + pBuf = cCmdDVPtr(DVIndex); + + BufLength = DV_ARRAY[DVIndex].Count; + + //If there's an old error code hanging around, clear it before proceeding. + if (VarsCmd.CommStat < 0) + VarsCmd.CommStat = SUCCESS; + + //!!! Only first 256 bytes could possibly make it through! Should return error on longer input? + //!!! Not requesting a wait-for-response because only known use doesn't read responses. + pMapComm->pFunc(SENDDATA, (UBYTE)BufLength, Connection, FALSE, pBuf, (UWORD*)&(VarsCmd.CommStat)); + + //!!! Reasonable to wrap below code in cCmdCommBTCheckStatus? + //INPROGRESS means our request was accepted by His Funkiness of pFunc + if (VarsCmd.CommStat == (SWORD)INPROGRESS) + { + *pReturnVal = STAT_COMM_PENDING; + + //Set DirtyComm flag so stream is reset after program ends + VarsCmd.DirtyComm = TRUE; + } + //Translate BTBUSY to ERR_COMM_CHAN_NOT_READY + else if (VarsCmd.CommStat == (SWORD)BTBUSY) + { + *pReturnVal = ERR_COMM_CHAN_NOT_READY; + } + else + { + *pReturnVal = UNPACK_STATUS(VarsCmd.CommStat); + } + + return (NO_ERR); +} + +// +//cCmdWrapCommBTRead +//ArgV[0]: (return) Status byte, SBYTE +//ArgV[1]: Count to read +//ArgV[2]: Buffer +// +NXT_STATUS cCmdWrapCommBTRead(UBYTE * ArgV[]) +{ + //SBYTE * pReturnVal = (SBYTE*)(ArgV[0]); + //UBYTE * pBuf = (ArgV[2]); + //!!! should provide length and/or connection to read? + + //!!! This syscall is not implemented; return fatal error. + return (ERR_INSTR); +} + +// +//cCmdWrapKeepAlive +//ArgV[0]: (return) Current timer limit in ms, ULONG +// +NXT_STATUS cCmdWrapKeepAlive(UBYTE * ArgV[]) +{ + pMapUi->Flags |= UI_RESET_SLEEP_TIMER; + + //Convert UI's minute-based timeout value to millisecs + //Milliseconds are the "natural" time unit in user-land. + *(ULONG*)(ArgV[0]) = (pMapUi->SleepTimeout * 60 * 1000); + + return (NO_ERR); +} + + + +#define MAX_IOM_BUFFER_SIZE 64 +// +//cCmdWrapIOMapRead +//ArgV[0]: (return) Status byte, SBYTE +//ArgV[1]: Module name, CStr +//ArgV[2]: Offset, UWORD +//ArgV[3]: Count, UWORD +//ArgV[4]: Buffer, UBYTE array +// +NXT_STATUS cCmdWrapIOMapRead(UBYTE * ArgV[]) +{ + UWORD LStatus; + NXT_STATUS Status; + + SBYTE * pReturnVal = (SBYTE*)(ArgV[0]); + UWORD Offset = *(UWORD*)(ArgV[2]); + //Our copy of 'Count' must be a ULONG to match the loader interface + ULONG Count = *(UWORD*)(ArgV[3]); + + DV_INDEX DVIndex; + + //Buffer for return of FINDFIRSTMODULE call, structure defined in protocol doc + //We need it to transfer the ModuleID to the IOMAPREAD call + UBYTE FindBuffer[FILENAME_LENGTH + 10]; + //Buffer to store data and offset in for IOMAPREAD call + //!!! Constant size means only limited reads and writes + UBYTE DataBuffer[MAX_IOM_BUFFER_SIZE + 2]; + + if (Count > MAX_IOM_BUFFER_SIZE) + { + //Request to read too much data at once; clear buffer, return error. + DVIndex = *(DV_INDEX *)(ArgV[4]); + *pReturnVal = cCmdDVArrayAlloc(DVIndex, 0); + if (IS_ERR(*pReturnVal)) + return (*pReturnVal); + + *pReturnVal = ERR_INVALID_SIZE; + return (NO_ERR); + } + + //Resolve module name + DVIndex = *(DV_INDEX *)(ArgV[1]); + ArgV[1] = cCmdDVPtr(DVIndex); + + //Find module by name. Note that wildcards are accepted, but only first match matters. + LStatus = pMapLoader->pFunc(FINDFIRSTMODULE, ArgV[1], FindBuffer, NULL); + + if (LOADER_ERR(LStatus) == SUCCESS) + { + //Module was found, transfer Offset into first two bytes of DataBuffer and attempt to read + *(UWORD*)(DataBuffer) = Offset; + LStatus = pMapLoader->pFunc(IOMAPREAD, &(FindBuffer[FILENAME_LENGTH + 1]), DataBuffer, &Count); + + if (LOADER_ERR(LStatus) == SUCCESS) + { + //No error from IOMAPREAD, so copy the data into VM's dataspace + //Size destination array + DVIndex = *(DV_INDEX *)(ArgV[4]); + Status = cCmdDVArrayAlloc(DVIndex, (UWORD)Count); + if (IS_ERR(Status)) + { + //Alloc failed, so close handle and return + pMapLoader->pFunc(CLOSEMODHANDLE, NULL, NULL, NULL); + return (Status); + } + + //Alloc succeeded, so resolve and copy away + ArgV[4] = cCmdDVPtr(DVIndex); + memcpy(ArgV[4], &(DataBuffer[2]), Count); + } + } + + *pReturnVal = LOADER_ERR_BYTE(LStatus); + + pMapLoader->pFunc(CLOSEMODHANDLE, NULL, NULL, NULL); + return (NO_ERR); +} + +// +//cCmdWrapIOMapWrite +//ArgV[0]: (return) Status byte, SBYTE +//ArgV[1]: Module name, CStr +//ArgV[2]: Offset, UWORD +//ArgV[3]: Buffer, UBYTE array +// +NXT_STATUS cCmdWrapIOMapWrite(UBYTE * ArgV[]) +{ + UWORD LStatus; + + SBYTE * pReturnVal = (SBYTE*)(ArgV[0]); + UWORD Offset = *(UWORD*)(ArgV[2]); + + //Our copy of 'Count' must be a ULONG to match the loader interface + ULONG Count; + DV_INDEX DVIndex; + + //Buffer for return of FINDFIRSTMODULE call, structure defined in protocol doc + //We need it to transfer the ModuleID to the IOMAPREAD call + UBYTE FindBuffer[FILENAME_LENGTH + 10]; + //Buffer to store data and offset in for IOMAPREAD call + //!!! Constant size means only limited reads and writes + UBYTE DataBuffer[MAX_IOM_BUFFER_SIZE + 2]; + + //Resolve module name and buffer + DVIndex = *(DV_INDEX *)(ArgV[1]); + ArgV[1] = cCmdDVPtr(DVIndex); + + DVIndex = *(DV_INDEX *)(ArgV[3]); + ArgV[3] = cCmdDVPtr(DVIndex); + Count = DV_ARRAY[DVIndex].Count; + + if (Count > MAX_IOM_BUFFER_SIZE) + { + //Request to read too much data at once; return error and give up + *pReturnVal = ERR_INVALID_SIZE; + return (NO_ERR); + } + + LStatus = pMapLoader->pFunc(FINDFIRSTMODULE, ArgV[1], FindBuffer, NULL); + + if (LOADER_ERR(LStatus) == SUCCESS) + { + //Module was found, transfer Offset into first two bytes of DataBuffer, copy data into rest of buffer, then write + *(UWORD*)(DataBuffer) = Offset; + memcpy(&(DataBuffer[2]), ArgV[3], Count); + LStatus = pMapLoader->pFunc(IOMAPWRITE, &(FindBuffer[FILENAME_LENGTH + 1]), DataBuffer, &Count); + } + + *pReturnVal = LOADER_ERR_BYTE(LStatus); + + pMapLoader->pFunc(CLOSEMODHANDLE, NULL, NULL, NULL); + return (NO_ERR); +} + +#if VM_BENCHMARK +void cCmdWriteBenchmarkFile() +{ + LOADER_STATUS LStatus; + UBYTE Handle; + ULONG BenchFileSize; + ULONG i, Length; + UBYTE Buffer[256]; + + //Remove old benchmark file, create a new one + strcpy((char *)Buffer, "benchmark.txt"); + pMapLoader->pFunc(DELETE, Buffer, NULL, NULL); + BenchFileSize = 2048; + LStatus = pMapLoader->pFunc(OPENWRITEDATA, Buffer, NULL, &BenchFileSize); + + if (!LOADER_ERR(LStatus)) + { + //Write Benchmark file + Handle = LOADER_HANDLE(LStatus); + + //Header + sprintf((char *)Buffer, "Program Name: %s\r\n", VarsCmd.ActiveProgName); + Length = strlen((char *)Buffer); + LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length); + + sprintf((char *)Buffer, "InstrCount: %d\r\n", VarsCmd.InstrCount); + Length = strlen((char *)Buffer); + LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length); + + sprintf((char *)Buffer, "Time: %d\r\n", IOMapCmd.Tick - VarsCmd.StartTick); + Length = strlen((char *)Buffer); + LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length); + + sprintf((char *)Buffer, "Instr/Tick: %d\r\n", VarsCmd.Average); + Length = strlen((char *)Buffer); + LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length); + + sprintf((char *)Buffer, "CmdCtrl Calls: %d\r\n", VarsCmd.CmdCtrlCount); + Length = strlen((char *)Buffer); + LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length); + + sprintf((char *)Buffer, "OverTime Rounds: %d\r\n", VarsCmd.OverTimeCount); + Length = strlen((char *)Buffer); + LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length); + + sprintf((char *)Buffer, "Max OverTime Length: %d\r\n", VarsCmd.MaxOverTimeLength); + Length = strlen((char *)Buffer); + LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length); + + sprintf((char *)Buffer, "CompactionCount: %d\r\n", VarsCmd.CompactionCount); + Length = strlen((char *)Buffer); + LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length); + + sprintf((char *)Buffer, "LastCompactionTick: %d\r\n", VarsCmd.LastCompactionTick); + Length = strlen((char *)Buffer); + LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length); + + sprintf((char *)Buffer, "MaxCompactionTime: %d\r\n", VarsCmd.MaxCompactionTime); + Length = strlen((char *)Buffer); + LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length); + + //opcode benchmarks + sprintf((char *)Buffer, "Op\tCnt\tOver\tMax\r\n"); + Length = strlen((char *)Buffer); + LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length); + for (i = 0; i < OPCODE_COUNT; i++) + { + sprintf((char *)Buffer, "%x\t%d\t%d\t%d\t%d\r\n", i, VarsCmd.OpcodeBenchmarks[i][0], VarsCmd.OpcodeBenchmarks[i][1], VarsCmd.OpcodeBenchmarks[i][2], VarsCmd.OpcodeBenchmarks[i][3]); + Length = strlen((char *)Buffer); + LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length); + } + //close file + LStatus = pMapLoader->pFunc(CLOSE, &Handle, NULL, NULL); + } +} +#endif + + +///////////////////////////////////////////////////////////// +// Dymanic syscall implementations +//////////////////////////////////////////////////////////// + +// +//cCmdWrapDatalogWrite +//ArgV[0]: (return) Error Code, SBYTE (NXT_STATUS) +//ArgV[1]: Message, CStr +// +NXT_STATUS cCmdWrapDatalogWrite(UBYTE * ArgV[]) +{ + NXT_STATUS Status = NO_ERR; + DV_INDEX DVIndex; + + //Resolve array arguments + DVIndex = *(DV_INDEX *)(ArgV[1]); + ArgV[1] = cCmdDVPtr(DVIndex); + + Status = cCmdDatalogWrite(ArgV[1], DV_ARRAY[DVIndex].Count); + + *(SBYTE *)(ArgV[0]) = Status; + + if (IS_FATAL(Status)) + return Status; + else + return (NO_ERR); +} + +// +//cCmdWrapDatalogGetTimes +//ArgV[0]: SyncTime, U32 +//ArgV[1]: SyncTick, U32 +// +NXT_STATUS cCmdWrapDatalogGetTimes(UBYTE * ArgV[]) +{ + *((ULONG *)ArgV[1]) = IOMapCmd.SyncTime; + *((ULONG *)ArgV[2]) = IOMapCmd.SyncTick; + return (NO_ERR); +} + +// +//cCmdWrapSetSleepTimeout +//ArgV[0]: (return) Status byte, SBYTE +//ArgV[1]: desired timer limit in ms, ULONG +// +NXT_STATUS cCmdWrapSetSleepTimeout(UBYTE * ArgV[]) +{ + ULONG value = *(ULONG*)(ArgV[1]); + if(value==0) + { + pMapUi->SleepTimeout=0; + } + else if(value < 60000) + { + pMapUi->SleepTimeout=1; //integer math would've made this zero + } + else + { + pMapUi->SleepTimeout= value / 60000; + } + return (NO_ERR); +} + +// currently copied from LS, not finished. +// +//cCmdWrapCommHSWrite +//ArgV[0]: (return) Status code, SBYTE +//ArgV[1]: Port specifier, UBYTE +//ArgV[2]: Buffer to send, UBYTE array, only SIZE_OF_LSBUF bytes will be used +//ArgV[3]: ResponseLength, UBYTE, specifies expected bytes back from slave device +// +NXT_STATUS cCmdWrapCommHSWrite(UBYTE * ArgV[]) +{ + SBYTE * pReturnVal = (SBYTE*)(ArgV[0]); + UBYTE Port = *(ArgV[1]); + UBYTE * pBuf; + UWORD BufLength; + UBYTE ResponseLength = *(ArgV[3]); + DV_INDEX DVIndex; + + //Resolve array arguments + DVIndex = *(DV_INDEX *)(ArgV[2]); + pBuf = cCmdDVPtr(DVIndex); + BufLength = DV_ARRAY[DVIndex].Count; + + *pReturnVal = cCmdLSWrite(Port, (UBYTE)BufLength, pBuf, ResponseLength); + + return (NO_ERR); +} + +// +//cCmdWrapCommHSCheckStatus +//ArgV[0]: (return) Status code, SBYTE +//ArgV[1]: Port specifier, UBYTE +//ArgV[2]: BytesReady, UBYTE +// +NXT_STATUS cCmdWrapCommHSCheckStatus(UBYTE * ArgV[]) +{ + UBYTE Port = *(ArgV[1]); + + *((SBYTE*)(ArgV[0])) = cCmdLSCheckStatus(Port); + *((UBYTE*)(ArgV[2])) = cCmdLSCalcBytesReady(Port); + + return (NO_ERR); +} + +// +//cCmdWrapCommHSRead +//ArgV[0]: (return) Status code, SBYTE +//ArgV[1]: Port specifier, UBYTE +//ArgV[2]: Buffer for data, UBYTE array, max SIZE_OF_LSBUF bytes will be written +//ArgV[3]: BufferLength, UBYTE, specifies size of buffer requested +// +NXT_STATUS cCmdWrapCommHSRead(UBYTE * ArgV[]) +{ + SBYTE * pReturnVal = (SBYTE*)(ArgV[0]); + UBYTE Port = *(ArgV[1]); + UBYTE * pBuf; + UBYTE BufLength = *(ArgV[3]); + UBYTE BytesToRead; + DV_INDEX DVIndex = *(DV_INDEX *)(ArgV[2]); + NXT_STATUS AllocStatus; + + *pReturnVal = cCmdLSCheckStatus(Port); + BytesToRead = cCmdLSCalcBytesReady(Port); + + //If channel is OK and has data ready for us, put the data into outgoing buffer + if (!IS_ERR(*pReturnVal) && BytesToRead > 0) + { + //Limit buffer to available data + if (BufLength > BytesToRead) + BufLength = BytesToRead; + + AllocStatus = cCmdDVArrayAlloc(DVIndex, BufLength); + if (IS_ERR(AllocStatus)) + return (AllocStatus); + + pBuf = cCmdDVPtr(DVIndex); + *pReturnVal = cCmdLSRead(Port, BufLength, pBuf); + } + //Else, the channel has an error and/or there's no data to read; clear the output array + else + { + AllocStatus = cCmdDVArrayAlloc(DVIndex, 0); + if (IS_ERR(AllocStatus)) + return (AllocStatus); + } + + return (NO_ERR); +} + +// +//cCmdWrapCommBTOnOff +//ArgV[0]: (return) Status byte, SBYTE +//ArgV[1]: Power State, 0-1 +// +NXT_STATUS cCmdWrapCommBTOnOff(UBYTE * ArgV[]) +{ + UWORD retVal; + NXT_STATUS status; + SBYTE * pReturnVal = (SBYTE*)(ArgV[0]); + + UBYTE powerState = *(ArgV[1]); + if(powerState) + status= pMapComm->pFunc(BTON, 0, 0, 0, NULL, &retVal); + else + status= pMapComm->pFunc(BTOFF, 0, 0, 0, NULL, &retVal); + + *pReturnVal= (status == SUCCESS) ? retVal : status; + return (NO_ERR); +} + +// +//cCmdWrapCommBTConnection +//ArgV[0]: (return) Status byte, SBYTE +//ArgV[1]: Action, UBYTE +//ArgV[2]: name, UBYTE array CStr +//ArgV[3]: connection slot, UBYTE +// +NXT_STATUS cCmdWrapCommBTConnection(UBYTE * ArgV[]) +{ + UWORD retVal; + NXT_STATUS status; + SBYTE * pReturnVal = (SBYTE*)(ArgV[0]); + UBYTE *nmPtr; + + UBYTE action = *(ArgV[1]); + UBYTE connection = *(ArgV[3]); + nmPtr = cCmdDVPtr(*(DV_INDEX *)(ArgV[2])); + + if(action) // Init + status= pMapComm->pFunc(CONNECTBYNAME, 0, connection, 0, nmPtr, &retVal); + else // Close + status= pMapComm->pFunc(DISCONNECT, connection, 0, 0, NULL, &retVal); + + *pReturnVal= (status == SUCCESS) ? retVal : status; + return (NO_ERR); +} + + +// +//cCmdWrapReadSemData +//ArgV[0]: return data, U8 +//ArgV[1]: which (0=used, 1=request), U8 +// +NXT_STATUS cCmdWrapReadSemData(UBYTE * ArgV[]) +{ + if(!(*((UBYTE *)ArgV[1]))) + *((UBYTE *)ArgV[0])= gUsageSemData; + else + *((UBYTE *)ArgV[0])= gRequestSemData; + return (NO_ERR); +} + +// +//cCmdWrapWriteSemData +//ArgV[0]: return data, U8 +//ArgV[1]: which (0=used, 1=request), U8 +//ArgV[2]: newValue, U8 +//ArgV[3]: action (0= OR, 1= AND), U8 +// +NXT_STATUS cCmdWrapWriteSemData(UBYTE * ArgV[]) +{ + UBYTE curVal, newVal, which= (*((UBYTE *)ArgV[1])); + if(!which) + curVal= gUsageSemData; + else + curVal= gRequestSemData; + + newVal= *((UBYTE *)ArgV[2]); + + if(*((UBYTE *)ArgV[3])) + curVal &= ~newVal; + else + curVal |= newVal; + + if(!which) + gUsageSemData= curVal; + else + gRequestSemData= curVal; + *((UBYTE *)ArgV[0])= curVal; + return (NO_ERR); +} + + +// +//cCmdWrapUpdateCalibCacheInfo +//ArgV[0]: return data, U8 +//ArgV[1]: nm, UBYTE array CStr +//ArgV[2]: min, U16 +//ArgV[3]: max , U16 +// +NXT_STATUS cCmdWrapUpdateCalibCacheInfo(UBYTE * ArgV[]) +{ + UBYTE *nm= cCmdDVPtr(*(DV_INDEX *)(ArgV[1])); + SWORD min= (*((SWORD *)ArgV[2])); + SWORD max= (*((SWORD *)ArgV[3])); + + cCmdUpdateCalibrationCache(nm, min, max); + *((UBYTE *)ArgV[0])= SUCCESS; + return (NO_ERR); +} + +// +//cCmdWrapComputeCalibValue +//ArgV[0]: return data, U8 +//ArgV[1]: nm, UBYTE array CStr +//ArgV[2]: raw, U16 ref in out +NXT_STATUS cCmdWrapComputeCalibValue (UBYTE * ArgV[]) +{ + UBYTE *nm= cCmdDVPtr(*(DV_INDEX *)(ArgV[1])); + SWORD raw= (*((SWORD *)ArgV[2])); + + *((UBYTE *)ArgV[0])= cCmdComputeCalibratedValue(nm, &raw); + (*((SWORD *)ArgV[2]))= raw; + return (NO_ERR); +} + +typedef struct { + SWORD min, max; + UBYTE nm[FILENAME_LENGTH + 1]; +} CalibCacheType; + +SBYTE gCalibCacheCnt= 0; +DV_INDEX gCalibCacheArrayDVIdx= NOT_A_DS_ID; +CalibCacheType *gCalibCacheArray= NULL; + +SWORD cCmdGetCalibrationIndex(UBYTE *nm) { + SBYTE i; + for(i= 0; i < gCalibCacheCnt; i++) + if(!strcmp((PSZ)nm, (PSZ)gCalibCacheArray[i].nm)) + break; + return i; +} + +NXT_STATUS cCmdComputeCalibratedValue(UBYTE *nm, SWORD *pRaw) { + SBYTE i= cCmdGetCalibrationIndex(nm); + NXT_STATUS status= ERR_RC_ILLEGAL_VAL; + SLONG raw= *pRaw, range; + if(i < gCalibCacheCnt) { + status= SUCCESS; + raw -= gCalibCacheArray[i].min; + range= (gCalibCacheArray[i].max - gCalibCacheArray[i].min); + } + else + range= 1023; + raw *= 100; + raw /= range; + if(raw < 0) raw= 0; + else if(raw > 100) raw= 100; + *pRaw= raw; + return status; +} + + +NXT_STATUS ResizeCalibCache(ULONG elements) { // alloc dv if needed, grow if needed. dv never freed. on boot, set to NOT_A_DS_ID. use cnt for valid elements. + NXT_STATUS Status = NO_ERR; + + if(gCalibCacheArrayDVIdx == NOT_A_DS_ID) + Status = cCmdAllocDopeVector(&gCalibCacheArrayDVIdx, sizeof(CalibCacheType)); + if(!IS_ERR(Status) && DV_ARRAY[gCalibCacheArrayDVIdx].Count < elements) //Allocate storage for cache element + Status = cCmdDVArrayAlloc(gCalibCacheArrayDVIdx, elements); + if(!IS_ERR(Status)) + gCalibCacheArray= cCmdDVPtr(gCalibCacheArrayDVIdx); + // on error, does old DVIdx still point to array, or should we null out array??? + return Status; +} + +// called to update min/max on existing cache element, and to add new named element +void cCmdUpdateCalibrationCache(UBYTE *nm, SWORD min, SWORD max) { + SWORD i= cCmdGetCalibrationIndex(nm); + NXT_STATUS Status = NO_ERR; + + if(i == gCalibCacheCnt) { // sensor wasn't found, insert into cache + Status= ResizeCalibCache(gCalibCacheCnt+1); + if(!IS_ERR(Status)) { + gCalibCacheCnt++; + strcpy((PSZ)gCalibCacheArray[i].nm, (PSZ)nm); + } + } + if(!IS_ERR(Status)) { + gCalibCacheArray[i].min= min; + gCalibCacheArray[i].max= max; + } +} + +void cCmdLoadCalibrationFiles(void) { + ULONG cnt, DataSize; + UBYTE nm[FILENAME_LENGTH + 1], nmLen; + SWORD Handle, HandleSearch; + gCalibCacheCnt= 0; + gCalibCacheArrayDVIdx= NOT_A_DS_ID; + // file I/O to load all .cal files into cached globals used by scaling syscall + HandleSearch = pMapLoader->pFunc(FINDFIRST, "*.cal", nm, &cnt); // returns total files and nm of first one + while (LOADER_ERR(HandleSearch) == SUCCESS) { // if we have a file, process it by closing and opening + SWORD min= 0, max= 0, tmp; + ULONG length; + pMapLoader->pFunc(CLOSE, LOADER_HANDLE_P(HandleSearch), NULL, NULL); + Handle = pMapLoader->pFunc(OPENREAD, nm, NULL, &DataSize); + if (LOADER_ERR(Handle) == SUCCESS && DataSize == 4) { + // access data, two bytes for min and two for max + length= 2; + pMapLoader->pFunc(READ,LOADER_HANDLE_P(Handle),(UBYTE*)&tmp,&length); + if (length == 2) + min= tmp; + length= 2; + pMapLoader->pFunc(READ,LOADER_HANDLE_P(Handle),(UBYTE*)&tmp,&length); + if (length == 2) + max= tmp; + } + pMapLoader->pFunc(CLOSE, LOADER_HANDLE_P(Handle), NULL, NULL); + // update calibration cache with nm, min, and max + nmLen= strlen((PSZ)nm) - 4; // chop off .cal extension + nm[nmLen]= 0; + cCmdUpdateCalibrationCache(nm, min, max); + + HandleSearch = pMapLoader->pFunc(FINDNEXT, LOADER_HANDLE_P(HandleSearch), nm, &cnt); + } + pMapLoader->pFunc(CLOSE, LOADER_HANDLE_P(HandleSearch), NULL, NULL); +} + +// +//cCmdWrapListFiles +//ArgV[0]: return data, SBYTE +//ArgV[1]: pattern, UBYTE array CStr +//ArgV[2]: list, UBYTE array CStr array ref in out +NXT_STATUS cCmdWrapListFiles (UBYTE * ArgV[]) +{ + ULONG fileSize, matchCount=0, i=0, oldCount; + SWORD HandleSearch; + NXT_STATUS Status = NO_ERR; + DV_INDEX listIdx, *list; + UBYTE *strTemp, *pattern; + UBYTE name[FILENAME_LENGTH + 1]; + + //Resolve array arguments + pattern = cCmdDVPtr(*(DV_INDEX *)(ArgV[1])); + listIdx = *(DV_INDEX *)(ArgV[2]); + + HandleSearch = pMapLoader->pFunc(FINDFIRST, pattern, name, &fileSize); // returns first file matching pattern + + //Count how many files we're going to have + while (LOADER_ERR(HandleSearch) == SUCCESS) + { + matchCount++; + pMapLoader->pFunc(CLOSE, LOADER_HANDLE_P(HandleSearch), NULL, NULL); + HandleSearch = pMapLoader->pFunc(FINDNEXT, LOADER_HANDLE_P(HandleSearch), name, &fileSize); + } + + HandleSearch = pMapLoader->pFunc(FINDFIRST, pattern, name, &fileSize); // returns first file matching pattern + + oldCount = DV_ARRAY[listIdx].Count; // Check to see how many dope vectors are already in the array (if they passed us a non-blank array of strings) + + Status = cCmdDVArrayAlloc(listIdx, matchCount); // Size the top-level array + if(IS_ERR(Status)) + return Status; + + list = (DV_INDEX*)(VarsCmd.pDataspace + DV_ARRAY[listIdx].Offset); // Get a pointer into the dataspace for the array of DV_INDEXes + + while (LOADER_ERR(HandleSearch) == SUCCESS && !IS_ERR(Status)) + { + pMapLoader->pFunc(CLOSE, LOADER_HANDLE_P(HandleSearch), NULL, NULL); // Close the handle that we automatically opened above + // Allocate a new dope vector if one doesn't already exist + if(i >= oldCount) + Status = cCmdAllocDopeVector(&(list[i]), sizeof(char)); + + // Allocate the string buffer for output array[i] + if(!IS_ERR(Status)) + Status = cCmdDVArrayAlloc(list[i], strlen((PSZ)name) + 1); + + if(!IS_ERR(Status)) + { + strTemp = VarsCmd.pDataspace + DV_ARRAY[list[i]].Offset; // Get a pointer into the dataspace for this string + strcpy((PSZ)strTemp, (PSZ)name); + } + i++; + + HandleSearch = pMapLoader->pFunc(FINDNEXT, LOADER_HANDLE_P(HandleSearch), name, &fileSize); + } + + *(SBYTE *)(ArgV[0]) = Status; + + return Status; +} + +#ifdef SIM_NXT +// Accessors for simulator library code +SWORD cCmdGetCodeWord(CLUMP_ID Clump, CODE_INDEX Index) +{ + if (Clump == NOT_A_CLUMP) + { + NXT_ASSERT(Index < VarsCmd.CodespaceCount); + return (VarsCmd.pCodespace[Index]); + } + else + { + NXT_ASSERT(cCmdIsClumpIDSane(Clump)); +#error // CodeStart is now absolute, but not sure how to fix + return (((SWORD)VarsCmd.pCodespace[VarsCmd.pAllClumps[Clump].CodeStart + Index])); + } +} + + +UBYTE * cCmdGetDataspace(UWORD *DataspaceSize) +{ + if (DataspaceSize) + *DataspaceSize = VarsCmd.DataspaceSize; + return (VarsCmd.pDataspace); +} + + +DOPE_VECTOR * cCmdGetDopeVectorPtr() +{ + return VarsCmd.MemMgr.pDopeVectorArray; +} + + +MEM_MGR cCmdGetMemMgr(void) +{ + return VarsCmd.MemMgr; +} + + +ULONG cCmdGetPoolSize() +{ + return VarsCmd.PoolSize; +} +#endif + +#else //!ENABLE_VM +// +//Implementations of standard interface if VM is disabled. +//Place low-level test code here if VM is causing issues. +//Test code must implement cCmdInit(), cCmdCtrl(), and cCmdExit() at a minimum. +//Recommend using a pattern like #include "c_cmd_alternate.c" +// + +//!!! !ENABLE_VM implementations really should provide a placeholder function for this pointer +//IOMapCmd.pRCHandler = &cCmdHandleRemoteCommands; +#include "c_cmd_alternate.c" + +#endif //ENABLE_VM diff --git a/src/c_cmd.h b/src/c_cmd.h new file mode 100644 index 0000000..c6e5267 --- /dev/null +++ b/src/c_cmd.h @@ -0,0 +1,885 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date: 10-07-08 13:22 $ +// +// Filename $Workfile:: c_cmd.h $ +// +// Version $Revision: 8 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_cmd. $ +// +// Platform C +// + +// +// File Description: +// This file contains definitions and prototypes for the VM which runs bytecode +// programs compatible with LEGO MINDSTORMS NXT Software 1.0. +// + +#ifndef C_CMD +#define C_CMD + +//!!! MAX_HANDLES also defined in m_sched.h +#ifndef MAX_HANDLES +#define MAX_HANDLES 16 +#endif + +#include "c_cmd_bytecodes.h" +#define SYSCALL_COUNT 48 + +extern const HEADER cCmd; + +// +//Standard interface to other modules +// +void cCmdInit(void* pHeader); +void cCmdCtrl(void); +void cCmdExit(void); + +// +//ARM_NXT vs SIM_NXT +//These definitions are set up to allow compiling this code for use in a simulated (non-ARM7) environment. +//If your toolchain doesn't automatically use the __ICCARM__ or __arm__ token, define it to ensure normal compilation. +// +#if defined (__ICCARM__) || (defined (__GNUC__) && defined (__arm__)) +#define ARM_NXT +#else +#define SIM_NXT +#endif + +// +//ENABLE_VM toggles compilation the main body of VM code. +//Define it as 0 to compile alternate implementation for testing (see bottom of c_cmd.c) +// +#define ENABLE_VM 1 +#undef ARM_DEBUG +// +//VM_BENCHMARK enables extra instrumentation code to measure VM performance. +//When enabled, a file named "benchmark.txt" is produced every time a program completes. +// +#define VM_BENCHMARK (ENABLE_VM && 0) //<-- Toggle to turn on benchmark calculations + +#if VM_BENCHMARK +//Prototype for benchmark recording function +void cCmdWriteBenchmarkFile(); +#endif + +// +//Run-time assert macros +//Use these to test for unexpected conditions +//If expr evaluates as false while running under a debugger, +// a software breakpoint exception is thrown. +//NXT_BREAK is just a shortcut for unconditional break. +// +//Assert definitions behind WIN_DEBUG only make sense when compiling SIM_NXT +// under an x86 Windows debugger. +// +#if defined WIN_DEBUG +//"int 3" is a break exception on x86 +#define NXT_ASSERT(expr) if (expr) {} else { __asm {int 3} } +#define NXT_BREAK NXT_ASSERT(0) +// +//Assert definitions behind ARM_DEBUG aren't quite as handy as WIN_DEBUG, +// but they do record the code line causing the last assert failure. +// +#elif defined(ARM_DEBUG) +#define NXT_ASSERT(expr) if (expr) {}\ + else\ + {\ + VarsCmd.AssertFlag = TRUE;\ + VarsCmd.AssertLine = __LINE__;\ + } +#define NXT_BREAK NXT_ASSERT(0); +#else +//Not debugging, so #defined as nothing +//!!! Note that these definitions means all usages of NXT_ASSERT and NXT_BREAK +// get stripped out of an unmodified ARM7 build. +//Unless ARM_DEBUG is enabled, treat them as documentation of expected values. +#define NXT_ASSERT(expr) +#define NXT_BREAK +#endif + +// +//Status byte used to return requests for further action or errors +//Valid codes #defined in c_cmd.iom +//!!!JLOFTUS Replace with NXT_STATUS? Same for ASSERTS? Others? Risk factors? +// +typedef SBYTE NXT_STATUS; + +#if ENABLE_VM + +//Intial values for clump records are packed into 4 bytes in the file format. +#define VM_FILE_CLUMP_REC_SIZE 4 + +// +// Definitions for dataspace management, IO Map (IOM) access, and bytecode instruction structure +// + +//Type codes for use in the dataspace table-of-contents (DSTOC) +typedef UBYTE TYPE_CODE; + +enum +{ + //VOID type for unused DS elements; never valid to address them from bytecode + TC_VOID, + + //Simple scalar integers, equivalent to matching basic types from stdconst.h + TC_UBYTE, + TC_SBYTE, + TC_UWORD, + TC_SWORD, + TC_ULONG, + TC_SLONG, TC_LAST_INT_SCALAR= TC_SLONG, + + //Aggregate types containing one or more scalar + TC_ARRAY, + TC_CLUSTER, + + //Mutex tracks current holder and any waiting clumps + TC_MUTEX, + TC_FLOAT, TC_LAST_VALID= TC_FLOAT +}; + +//Sizes (in bytes) of each scalar type +#define SIZE_UBYTE 1 +#define SIZE_SBYTE 1 +#define SIZE_UWORD 2 +#define SIZE_SWORD 2 +#define SIZE_ULONG 4 +#define SIZE_SLONG 4 +#define SIZE_FLOAT 4 + +//MUTEX record is a struct containing 3 8-bit CLUMP_IDs, packed into 32-bit word +//See MUTEX_Q typedef +#define SIZE_MUTEX 4 + +//Module IDs for IO map addressing +enum +{ + MOD_INPUT, + MOD_OUTPUT +}; + +//Field IDs for input IOM +enum +{ + IO_IN_TYPE, + IO_IN_MODE, + IO_IN_ADRAW, + IO_IN_NORMRAW, + IO_IN_SCALEDVAL, + IO_IN_INVALID_DATA +}; + +//FPP = Fields Per Port +#define IO_IN_FPP 6 +#define IO_IN_FIELD_COUNT (IO_IN_FPP * NO_OF_INPUTS) + +//Field IDs for input IOM +enum +{ + IO_OUT_FLAGS, + IO_OUT_MODE, + IO_OUT_SPEED, //AKA "Power" + IO_OUT_ACTUAL_SPEED, + IO_OUT_TACH_COUNT, + IO_OUT_TACH_LIMIT, + IO_OUT_RUN_STATE, + IO_OUT_TURN_RATIO, + IO_OUT_REG_MODE, + IO_OUT_OVERLOAD, + IO_OUT_REG_P_VAL, + IO_OUT_REG_I_VAL, + IO_OUT_REG_D_VAL, + IO_OUT_BLOCK_TACH_COUNT, + IO_OUT_ROTATION_COUNT, + IO_OUT_OPTIONS, + IO_OUT_MAX_SPEED, + IO_OUT_MAX_ACCELERATION, +}; + +#define IO_OUT_FPP 18 +#define IO_OUT_FIELD_COUNT (IO_OUT_FPP * NO_OF_OUTPUTS) + +// +//DS_TOC_ENTRY is a record in the dataspace table of contents +//The TypeCode describes the data which is stored at Dataspace[DSOffset] +// +typedef struct +{ + TYPE_CODE TypeCode; + UBYTE Flags; + SWORD DSOffset; +} DS_TOC_ENTRY; + +//DS_TOC_ENTRY Flags +//!!! Yes, there's only one flag defined for an 8-bit field. +//ARM7 alignment rules means those bits would otherwise just be padding, anyway. +#define DS_DEFAULT_DEFAULT 1 //This entry has no default value in file; fill with zero at activation time + +//DS_ELEMENT_ID (AKA "DS item ID") indexes DataspaceTOC +typedef UWORD DS_ELEMENT_ID; + +//Special flag value used for opcode-specific default behavior when real dataspace argument is not provided +#define NOT_A_DS_ID 0xFFFF + +//Macro to bump DS_ELEMENT_IDs +1 with a cast (mostly to quash annoying warnings) +#define INC_ID(X) ((DS_ELEMENT_ID)(X + 1)) + +//DATA_ARG may contain a DS_ELEMENT_ID or encoded IO map address +typedef UWORD DATA_ARG; + +//CODE_WORD is a single indexable element of the codespace +typedef SWORD CODE_WORD; + +//CODE_INDEX indexes codespaces for opcodes and args +//!!! UWORD CODE_INDEX currently limits programs to 128KB code +// Yes, this is "plenty", but noted here to make sure we think about it +// when considering code size changes +typedef UWORD CODE_INDEX; + +//Typedef and define to hold and check for valid file handles +typedef UBYTE FILE_HANDLE; + +#define NOT_A_HANDLE 0xFF + +// +// Dynamic Memory Manager +// + +typedef UWORD DV_INDEX; //Dope Vector Index: Index into the DopeVectorArray + +//DOPE_VECTOR struct: One instance exists in the DopeVectorArray for every array in the dataspace. +typedef struct +{ + UWORD Offset; + UWORD ElemSize; + UWORD Count; + DV_INDEX BackLink; // points to previous DV + DV_INDEX Link; // points to next DV +} DOPE_VECTOR; + +// +//MEM_MGR struct +//Head and Tail keep track of the main linked-list of dope vectors, +// which must be maintained in ascending order according to Offset +//FreeHead is the head DV of the list of allocated but unused DVs +//pDopeVectorArray is initialized at activation-time to point to the master DVA +// +typedef struct +{ + DV_INDEX Head; + DV_INDEX Tail; + DV_INDEX FreeHead; + DOPE_VECTOR * pDopeVectorArray; +} MEM_MGR; + +//Macro to shorten common DVA access code +#define DV_ARRAY VarsCmd.MemMgr.pDopeVectorArray +//# of nodes to alloc when the Dope Vector Array is full +#define DV_ARRAY_GROWTH_COUNT 25 +//Flag value for invalid Offset fields in DVs +#define NOT_AN_OFFSET 0xFFFF +//Check for legal index into DVA +#define IS_DV_INDEX_SANE(X) (((X) > 0) && ((X) < DV_ARRAY[0].Count)) + +// +// Message Queuing +// + +// +//There are 10 incoming and 10 outgoing message queues, each 5 messages deep +//A "message" is defined as a null-terminated string under MAX_MESSAGE_SIZE +// +#define MESSAGES_PER_QUEUE 5 +#define MESSAGE_QUEUE_COUNT 20 +#define INCOMING_QUEUE_COUNT ((MESSAGE_QUEUE_COUNT)/2) +#define NOT_A_QUEUE 0xFF + +// +//MAX_MESSAGE_SIZE including null-terminator +//!!! Capped at 59 unless USB protocol assumptions are changed! +// +#define MAX_MESSAGE_SIZE 59 + +//A MESSAGE is a dynamically sized string, so we use a DV_INDEX to get to its information +typedef DV_INDEX MESSAGE; + +// +//MESSAGE_QUEUE keeps track of last messages read and written (acts as a circular buffer) +// +typedef struct +{ + UWORD ReadIndex; + UWORD WriteIndex; + MESSAGE Messages[MESSAGES_PER_QUEUE]; +} MESSAGE_QUEUE; + +//Handy macros for accessing MESSAGE_QUEUEs +#define GET_WRITE_MSG(QueueID) (VarsCmd.MessageQueues[(QueueID)].Messages[VarsCmd.MessageQueues[(QueueID)].WriteIndex]) +#define GET_READ_MSG(QueueID) (VarsCmd.MessageQueues[(QueueID)].Messages[VarsCmd.MessageQueues[(QueueID)].ReadIndex]) +#define SET_WRITE_MSG(QueueID, DVIndex) (VarsCmd.MessageQueues[(QueueID)].Messages[VarsCmd.MessageQueues[(QueueID)].WriteIndex] = (DVIndex)) +#define SET_READ_MSG(QueueID, DVIndex) (VarsCmd.MessageQueues[(QueueID)].Messages[VarsCmd.MessageQueues[(QueueID)].ReadIndex] = (DVIndex)) + +// +// Datalog Queuing +// +// The datalog queue is loosely modeled around the message queue except that there is only one queue, not an array of them. +// + +// A datalog has one less byte of 'header' info so different max size +#define MAX_DATALOG_SIZE 60 + +// The number of datalog messages to buffer +#define DATALOG_QUEUE_DEPTH 30 + +// A DATALOG_MESSAGE is a dynamically sized string, so we use a DV_INDEX to get to its information +typedef DV_INDEX DATALOG_MESSAGE; + +// +// DATALOG_QUEUE keeps track of last messages read and written (acts as a circular buffer) +typedef struct +{ + UWORD ReadIndex; + UWORD WriteIndex; + DATALOG_MESSAGE Datalogs[DATALOG_QUEUE_DEPTH]; +} DATALOG_QUEUE; + +//Handy macros for accessing the DATALOG_QUEUE +#define GET_WRITE_DTLG() (VarsCmd.DatalogBuffer.Datalogs[VarsCmd.DatalogBuffer.WriteIndex]) +#define GET_READ_DTLG() (VarsCmd.DatalogBuffer.Datalogs[VarsCmd.DatalogBuffer.ReadIndex]) +#define SET_WRITE_DTLG(DVIndex) (VarsCmd.DatalogBuffer.Datalogs[VarsCmd.DatalogBuffer.WriteIndex] = (DVIndex)) +#define SET_READ_DTLG(DVIndex) (VarsCmd.DatalogBuffer.Datalogs[VarsCmd.DatalogBuffer.ReadIndex] = (DVIndex)) + + +// +//Definitions related to dataflow scheduling +// + +//CLUMP_IDs are used to index list at pAllClumps +typedef UBYTE CLUMP_ID; + +// +//The last value in CLUMP_ID's range is reserved as NOT_A_CLUMP +//This is useful as a queue terminator and general placeholder +// +#define NOT_A_CLUMP 0xFF +#define MAX_CLUMPS 255 +#define INSTR_MAX_COUNT 20 + +//CLUMP_Q struct for tracking head and tail of a queue of clumps +typedef struct +{ + CLUMP_ID Head; + CLUMP_ID Tail; +} CLUMP_Q; + +// +//MUTEX_Q is a struct to be stashed in the dataspace to track state of a mutex +//If mutex is free, Owner field is NOT_A_CLUMP and WaitQ is empty. +//The mutex is acquired by stashing a new owner's ID. +//If others attempt to acquire, they will be put on the WaitQ +// +typedef struct +{ + CLUMP_ID Owner; + CLUMP_Q WaitQ; +} MUTEX_Q; + +// +// Clump Record, run-time book-keeping for each clump +// +// CodeStart: Start of this clump's bytecodes, absolute address +// CodeEnd: End of this clump's bytecodes, absolute address +// PC: "program counter" -- current offset into codespace relative to CodeStart +// InitFireCount: Initial count of upstream dependencies +// CurrFireCount: Run-time count of unsatisfied dependencies +// Link: ID of next clump in the queue. NOT_A_CLUMP denotes end or bad link. +// +// clumpScalarDispatchHints: this clump only uses scalar data args, can be interpretted with faster dispatch tables +// +// pDependents: pointer to list of downstream dependents' ClumpIDs +// awakenTime: If a clump is on rest queue for sleep, this is the time at which it will return to runQueue +// DependentCount: Count of downstream dependents +// +typedef struct +{ + CODE_WORD* CodeStart; + CODE_WORD* CodeEnd; + CODE_WORD* PC; + UBYTE InitFireCount; + UBYTE CurrFireCount; //AKA ShortCount + CLUMP_ID Link; + + UBYTE clumpScalarDispatchHints; + + CLUMP_ID* pDependents; + ULONG awakenTime; + UBYTE DependentCount; +} CLUMP_REC; + +// +//Definitions for memory pool management +// + +//First valid pointer into the memory pool +#define POOL_START ((UBYTE*)(VarsCmd.Pool)) + +//Sentinel points one byte *past* the pool -- i.e. first bad pool pointer +#define POOL_SENTINEL ((UBYTE*)(VarsCmd.Pool + VarsCmd.PoolSize)) + +//Alignment mod for Pool and all sub-fields of the Pool +#define POOL_ALIGN SIZE_SLONG + +#define ALIGN_TO_MOD(val,mod) if ((val) % (mod) != 0) { (val) += (mod) - ((val) % (mod)); } else {} + +// +//Internal states of the VM +//VM_IDLE: Just sitting around. Request to run program will lead to ONE of the VM_RUN* states. +//VM_RUN_FREE: Attempt to run as many instructions as possible within our timeslice +//VM_RUN_SINGLE: Run exactly one instruction per timeslice +//VM_RUN_PAUSE: Program still "active", but someone has asked us to pause +//VM_RESET2: Final clean up and return to IDLE +//VM_RESET1: Initialize state variables and some I/O devices -- executed when programs end +// +typedef enum +{ + VM_IDLE, + VM_RUN_FREE, + VM_RUN_SINGLE, + VM_RUN_PAUSE, + VM_RESET1, + VM_RESET2, +} VM_STATE; + +// +// VARSCMD: Private state data for active program and VM system +// +//pCodespace: pointer for flat codespace (stored in flash, includes all clumps) +//CodespaceCount: count of code words +// +//pAllClumps: Pointer to list of CLUMP_RECs +//AllClumpsCount: Count of CLUMP_RECs in list +// +//RunQ: Head and tail of run queue (elements in-place in AllClumps list) +// +//pDataspaceTOC: Pointer to DSTOC entries (stored in flash) +//DataspaceCount: Count of entries in DSTOC +//pDataspace: Base pointer of actual dataspace +//DataspaceSize: Size, in bytes, of dataspace +//DSStaticSize: Size, in bytes, of static portion of the dataspace (used as an offset to the dynamic dataspace) +// +//VMState: Internal state of VM's loader/scheduler (cCmdCtrl()) +// +//MemMgr: Contains data to manage dynamic arrays +// +//PoolSize: Current size of main memory pool, in bytes. +//Pool: Static pool of bytes for stashing all program run-time data +// +//ActiveProgHandle: Handle of the program that is currently running +//ActiveProgName: Stashed name of currently running program, if any +// +//FileHandleTable: Table of file names opened by program while running. +// First byte of each record is 'r' or 'w' (read or write). +// +//MessageQueues: Message buffer tracking data +// +//CommStat, CommStatReset, CommCurrConnection, DirtyComm: Helper data for interfacing to c_comm module +// +//DirtyDisplay: Boolean reminding us to re-initialize the display if program used it +// +//StartTick: MS tick stashed when program started. Used for relative time measurements. +// +//Further notes on the memory pool: +// The main memory pool is used for all clump records, dataspace tracking data, +// and the dataspace itself. In other words, pAllClumps and +// pDataspace must all point to memory within the pool. Watch for NXT_ASSERTs +// to enforce safe indexing into the pool. +// +typedef struct +{ + CODE_WORD* pCodespace; + CLUMP_REC* pAllClumps; + DS_TOC_ENTRY* pDataspaceTOC; + UBYTE* pDataspace; + UBYTE* Pool; + + ULONG PoolSize; + UWORD CodespaceCount; + CLUMP_ID AllClumpsCount; + UWORD DataspaceCount; + UWORD DataspaceSize; + UWORD DSStaticSize; + + VM_STATE VMState; + + MEM_MGR MemMgr; + + CLUMP_Q RunQ; + CLUMP_Q RestQ; + + UBYTE ActiveProgHandle; + UBYTE ActiveProgName[FILENAME_LENGTH + 1]; + + UBYTE FileHandleTable[MAX_HANDLES][FILENAME_LENGTH + 2]; + + MESSAGE_QUEUE MessageQueues[MESSAGE_QUEUE_COUNT]; + + SWORD CommStat; + SWORD CommStatReset; + UBYTE CommCurrConnection; + + UBYTE DirtyComm; + UBYTE DirtyDisplay; + + ULONG StartTick; + + DATALOG_QUEUE DatalogBuffer; + +#if VM_BENCHMARK + ULONG InstrCount; + ULONG Average; + ULONG OverTimeCount; + ULONG MaxOverTimeLength; + ULONG CmdCtrlCount; + ULONG CompactionCount; + ULONG LastCompactionTick; + ULONG MaxCompactionTime; + ULONG OpcodeBenchmarks[OPCODE_COUNT][4]; + ULONG SyscallBenchmarks[SYSCALL_COUNT][4]; + UBYTE Buffer[256]; +#endif + +#if defined ARM_DEBUG + UBYTE AssertFlag; + ULONG AssertLine; +#endif +} VARSCMD; + +// +//Activation +// + +//Activate new program by filename (open file and inflate run-time data) +NXT_STATUS cCmdActivateProgram(UBYTE * pFileName); + +//Deactivate currently active program (re-init run-time data and close file) +void cCmdDeactivateProgram(); + +//Reset various device state variables +void cCmdResetDevices(void); + +//Parse activation record file header information +typedef struct +{ + UWORD DSTOC; + UWORD DSDefaults; + UWORD DSDefaultsSize; + UWORD DynamicDefaults; + UWORD DynamicDefaultsSize; + UWORD Clumps; + UWORD Codespace; +} PROG_FILE_OFFSETS; + +NXT_STATUS cCmdReadFileHeader(UBYTE* pData, ULONG DataSize, + PROG_FILE_OFFSETS* pFileOffsets); + +NXT_STATUS cCmdInflateDSDefaults(UBYTE* pDSDefaults, UWORD *pDefaultsOffset, DS_ELEMENT_ID DSElementID); + + +// +//Clump management +// + +//Clump queuing +void cCmdEnQClump(CLUMP_Q * Queue, CLUMP_ID NewClump); +void cCmdDeQClump(CLUMP_Q * Queue, CLUMP_ID Clump); +void cCmdRotateQ(); +UBYTE cCmdIsClumpOnQ(CLUMP_Q * Queue, CLUMP_ID Clump); +UBYTE cCmdIsQSane(CLUMP_Q * Queue); + +// Rest queue functions +NXT_STATUS cCmdSleepClump(ULONG time); +UBYTE cCmdCheckRestQ(ULONG currTime); + +//Mutex queuing +NXT_STATUS cCmdAcquireMutex(MUTEX_Q * Mutex); +NXT_STATUS cCmdReleaseMutex(MUTEX_Q * Mutex); + +//Conditionally schedule dependents of given clump (Begin and End specify subset of list) +NXT_STATUS cCmdSchedDependents(CLUMP_ID Clump, SWORD Begin, SWORD End); + +//Conditionally schedule TargetClump +NXT_STATUS cCmdSchedDependent(CLUMP_ID Clump, CLUMP_ID TargetClump); + +//Test if ClumpID is sane at run-time (valid for indexing AllClumps) +UBYTE cCmdIsClumpIDSane(CLUMP_ID Clump); + +// +//Code stream management +// + +//Instruction masking macros -- get the interesting bits out of an encoded instruction word +#define COMP_CODE(pInstr) ((UBYTE)((((pInstr)[0]) & 0x0700) >> 8)) +#define INSTR_SIZE(wd) ((wd) >> 12) & 0x0F; + +#define IS_SHORT_OP(pInstr) ((UBYTE)((((pInstr)[0]) & 0x0800) >> 8) == 8) +#define SHORT_OP_CODE(pInstr) COMP_CODE(pInstr) +#define SHORT_ARG(pInstr) ((SBYTE) (((pInstr)[0]) & 0x00FF)) +//ShortOpMap defined in c_cmd_bytecodes.h +#define OP_CODE(pInstr) (UBYTE) (((pInstr)[0]) & 0x00FF) + +// +//Memory pool management +// + +//Initialize entire memory pool with default value +void cCmdInitPool(void); + +//Resize dataspace array specified by DSElementID and Offset. +NXT_STATUS cCmdDSArrayAlloc(DS_ELEMENT_ID DSElementID, UWORD Offset, UWORD NewCount); +//Resize dataspace array specified by DVIndex. In most cases, call higher-level cCmdDSArrayAlloc instead. +NXT_STATUS cCmdDVArrayAlloc(DV_INDEX DVIndex, UWORD NewCount); + +NXT_STATUS cCmdAllocSubArrayDopeVectors(DS_ELEMENT_ID DSElementID, UWORD Offset); +NXT_STATUS cCmdFreeSubArrayDopeVectors(DS_ELEMENT_ID DSElementID, UWORD Offset); +NXT_STATUS cCmdAllocDopeVector(DV_INDEX *pIndex, UWORD ElemSize); +NXT_STATUS cCmdFreeDopeVector(DV_INDEX DVIndex); +NXT_STATUS cCmdGrowDopeVectorArray(UWORD NewCount); + +UWORD cCmdCalcArrayElemSize(DS_ELEMENT_ID DSElementID); + +NXT_STATUS cCmdMemMgrMoveToTail(DV_INDEX DVIndex); +NXT_STATUS cCmdMemMgrInsertAtTail(DV_INDEX DVIndex); + +//Utility function to check sanity of MemMgr data structure. Boolean result. +UBYTE cCmdVerifyMemMgr(); + +NXT_STATUS cCmdDSCompact(void); + +// +// Message Queue management +// + +NXT_STATUS cCmdMessageWrite(UWORD QueueID, UBYTE * pData, UWORD Length); +NXT_STATUS cCmdMessageRead(UWORD QueueID, UBYTE * pData, UWORD Length, UBYTE Remove); +NXT_STATUS cCmdMessageGetSize(UWORD QueueID, UWORD * Size); + +// +// Datalog Queue management +// + +NXT_STATUS cCmdDatalogWrite(UBYTE * pData, UWORD Length); +NXT_STATUS cCmdDatalogRead(UBYTE * pData, UWORD Length, UBYTE Remove); +NXT_STATUS cCmdDatalogGetSize(UWORD * Size); + +// +// Color Sensor +// + +NXT_STATUS cCmdColorSensorRead (UBYTE Port, SWORD* SensorValue, UWORD* RawArray, UWORD* NormalizedArray, + SWORD* ScaledArray, UBYTE* InvalidData); + +// +//Dataspace management +// + +#define IS_AGGREGATE_TYPE(TypeCode) ((TypeCode == TC_ARRAY) || (TypeCode == TC_CLUSTER)) +// use carefully, only where tc will be a scalar int +#define QUICK_UNSIGNED_TEST(TypeCode) ((TypeCode) & 0x1) +#define IS_SIGNED_TYPE(TypeCode) (((TypeCode) == TC_SBYTE) || ((TypeCode) == TC_SWORD) || ((TypeCode) == TC_SLONG)) +//!!!BDUGGAN add TC_FLOAT? + +//Test if DS_ELEMENT_ID is sane at run-time (valid for indexing DS TOC) +UBYTE cCmdIsDSElementIDSane(DS_ELEMENT_ID Index); + +DS_ELEMENT_ID cCmdGetDataspaceCount(void); + +//Pointer accessors to resolve actual data locations in RAM +void* cCmdDSPtr(DS_ELEMENT_ID DSElementID, UWORD Offset); +void* cCmdDVPtr(DV_INDEX DVIndex); + +//Helper to walk the DSTOC to the next entry at the same aggregate nesting level as CurrID +DS_ELEMENT_ID cCmdNextDSElement(DS_ELEMENT_ID CurrID); + +//Recursively compare two complete data type descriptors +UBYTE cCmdCompareDSType(DS_ELEMENT_ID DSElementID1, DS_ELEMENT_ID DSElementID2); + +//Functions for managing data flattened to byte arrays +UWORD cCmdCalcFlattenedSize(DS_ELEMENT_ID DSElementID, UWORD Offset); +NXT_STATUS cCmdFlattenToByteArray(UBYTE * pByteArray, UWORD * pByteOffset, DS_ELEMENT_ID DSElementID, UWORD Offset); +NXT_STATUS cCmdUnflattenFromByteArray(UBYTE * pByteArray, UWORD * pByteOffset, DS_ELEMENT_ID DSElementID, UWORD Offset); + +//Comparison evaluation. Comparison codes defined in c_cmd_bytecodes.h. +//cCmdCompare operates on scalars passed as ULONGs -- type-specific comparisons done inside function. +UBYTE cCmdCompare(UBYTE CompCode, ULONG Val1, ULONG Val2, TYPE_CODE TypeCode1, TYPE_CODE TypeCode2); +UBYTE cCmdCompareFlt(UBYTE CompCode, float Val1, float Val2, TYPE_CODE TypeCode1, TYPE_CODE TypeCode2); +//cCmdCompareAggregates does polymorphic comparisons (with recursive helper function). +NXT_STATUS cCmdCompareAggregates(UBYTE CompCode, UBYTE *ReturnBool, DATA_ARG Arg2, UWORD Offset2, DATA_ARG Arg3, UWORD Offset3); +NXT_STATUS cCmdRecursiveCompareAggregates(UBYTE CompCode, UBYTE *ReturnBool, UBYTE *Finished, DATA_ARG Arg2, UWORD Offset2, DATA_ARG Arg3, UWORD Offset3); + +//Cluster functions +UWORD cCmdClusterCount(DS_ELEMENT_ID DSElementID); + +//Array functions +#define ARRAY_ELEM_OFFSET(DVIndex, Index) ((UWORD)(DV_ARRAY[(DVIndex)].Offset + DV_ARRAY[(DVIndex)].ElemSize * (Index))) +UWORD cCmdGetDVIndex(DS_ELEMENT_ID DSElementID, UWORD Offset); +UWORD cCmdArrayCount(DS_ELEMENT_ID DSElementID, UWORD Offset); +TYPE_CODE cCmdArrayType(DS_ELEMENT_ID DSElementID); + +//!!! DATA_ARG masks are for internal use only! (Bytecode programs should never contain them) +// See cCmdResolveDataArg() calls in the interpreter code for OP_GETOUT, OP_SETIN, and OP_GETIN. +#define DATA_ARG_ADDR_MASK 0x3FFF +#define DATA_ARG_IMM_MASK 0x7FFF + +//General data accessors (DS and IO Map) +void * cCmdResolveDataArg(DATA_ARG DataArg, UWORD Offset, TYPE_CODE * TypeCode); +void * cCmdResolveIODataArg(DATA_ARG DataArg, ULONG Offset, TYPE_CODE * TypeCode); +ULONG cCmdGetVal(void * pVal, TYPE_CODE TypeCode); +void cCmdSetVal(void * pVal, TYPE_CODE TypeCode, ULONG NewVal); + +// Calibration routines +void cCmdLoadCalibrationFiles(void); +NXT_STATUS cCmdComputeCalibratedValue(UBYTE *nm, SWORD *raw); +void cCmdUpdateCalibrationCache(UBYTE *nm, SWORD min, SWORD max); + +// +//Interpreter functions +// + +//Clump-based "master" interpreter +NXT_STATUS cCmdInterpFromClump(); + +//Function pointer typedef for sub-interpreters +typedef NXT_STATUS (*pInterp)(CODE_WORD * const); +typedef NXT_STATUS (*pInterpShort)(CODE_WORD * const); + +//Sub-interpreter dispatch functions +NXT_STATUS cCmdInterpNoArg(CODE_WORD * const pCode); +NXT_STATUS cCmdInterpUnop1(CODE_WORD * const pCode); +NXT_STATUS cCmdInterpUnop2(CODE_WORD * const pCode); +NXT_STATUS cCmdInterpScalarUnop2(CODE_WORD * const pCode); +NXT_STATUS cCmdInterpBinop(CODE_WORD * const pCode); +NXT_STATUS cCmdInterpScalarBinop(CODE_WORD * const pCode); +NXT_STATUS cCmdInterpOther(CODE_WORD * const pCode); + +NXT_STATUS cCmdInterpShortError(CODE_WORD * const pCode); +NXT_STATUS cCmdInterpShortSubCall(CODE_WORD * const pCode); +NXT_STATUS cCmdInterpShortMove(CODE_WORD * const pCode); +NXT_STATUS cCmdInterpShortAcquire(CODE_WORD * const pCode); +NXT_STATUS cCmdInterpShortRelease(CODE_WORD * const pCode); + +NXT_STATUS cCmdMove(DATA_ARG Arg1, DATA_ARG Arg2); + +//Polymorphic interpreter functions +NXT_STATUS cCmdInterpPolyUnop2(CODE_WORD const Code, DATA_ARG Arg1, UWORD Offset1, DATA_ARG Arg2, UWORD Offset2); +ULONG cCmdUnop2(CODE_WORD const Code, ULONG Operand, TYPE_CODE TypeCode); +float cCmdUnop2Flt(CODE_WORD const Code, float Operand, TYPE_CODE TypeCode); + +NXT_STATUS cCmdInterpPolyBinop(CODE_WORD const Code, DATA_ARG Arg1, UWORD Offset1, DATA_ARG Arg2, UWORD Offset2, DATA_ARG Arg3, UWORD Offset3); +ULONG cCmdBinop(CODE_WORD const Code, ULONG LeftOp, ULONG RightOp, TYPE_CODE LeftType, TYPE_CODE RightType); +float cCmdBinopFlt(CODE_WORD const Code, float LeftOp, float RightOp, TYPE_CODE LeftType, TYPE_CODE RightType); +void cCmdSetValFlt(void * pVal, TYPE_CODE TypeCode, float NewVal); +float cCmdGetValFlt(void * pVal, TYPE_CODE TypeCode); +// +//Support functions for lowspeed (I2C devices, i.e. ultrasonic sensor) communications +// + +NXT_STATUS cCmdLSCheckStatus(UBYTE Port); +UBYTE cCmdLSCalcBytesReady(UBYTE Port); +NXT_STATUS cCmdLSWrite(UBYTE Port, UBYTE BufLength, UBYTE *pBuf, UBYTE ResponseLength); +NXT_STATUS cCmdLSRead(UBYTE Port, UBYTE BufLength, UBYTE * pBuf); + +// +//Support for OP_SYSCALL +// + +// +//Each cCmdWrap funtion below implements one system call. +//The OP_SYSCALL interpreter wrangles the argument vector, ArgV, +// then calls the appropriate wrapper function according to the SysCallID. +//Wrapper functions write directly back into the dataspace via ArgV. +// +#define MAX_CALL_ARGS 16 + +typedef NXT_STATUS (*pSysCall)(UBYTE * ArgV[]); + +NXT_STATUS cCmdWrapFileOpenRead(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapFileOpenWrite(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapFileOpenAppend(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapFileRead(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapFileWrite(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapFileClose(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapFileResolveHandle (UBYTE * ArgV[]); +NXT_STATUS cCmdWrapFileRename (UBYTE * ArgV[]); +NXT_STATUS cCmdWrapFileDelete (UBYTE * ArgV[]); +NXT_STATUS cCmdWrapSoundPlayFile(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapSoundPlayTone(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapSoundGetState(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapSoundSetState(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapDrawText(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapDrawPoint(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapDrawLine(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapDrawCircle(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapDrawRect(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapDrawPicture(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapSetScreenMode(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapReadButton(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapCommLSWrite(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapCommLSRead(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapCommLSCheckStatus(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapRandomNumber(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapGetStartTick(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapMessageWrite(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapMessageRead(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapDatalogWrite(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapCommBTCheckStatus(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapCommBTWrite(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapCommBTRead(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapKeepAlive(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapIOMapRead(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapIOMapWrite(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapColorSensorRead (UBYTE * ArgV[]); +NXT_STATUS cCmdWrapDatalogGetTimes(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapSetSleepTimeout(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapListFiles(UBYTE * ArgV[]); + +// Handlers for dynamically added syscalls +NXT_STATUS cCmdWrapCommHSWrite(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapCommHSRead(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapCommHSCheckStatus(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapCommBTOnOff(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapCommBTConnection(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapReadSemData(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapWriteSemData(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapUpdateCalibCacheInfo(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapComputeCalibValue(UBYTE * ArgV[]); + + +//Handler for remote control protocol packets -- called from comm module via IO map function pointer +UWORD cCmdHandleRemoteCommands(UBYTE * pInBuf, UBYTE * pOutBuf, UBYTE * pLen); + +#ifdef SIM_NXT +// +// Helper functions to provide simulator library access to VM internals +// +SWORD cCmdGetCodeWord(CLUMP_ID Clump, CODE_INDEX Index); +UBYTE * cCmdGetDataspace(UWORD *DataspaceSize); +DOPE_VECTOR * cCmdGetDopeVectorPtr(void); +ULONG cCmdGetPoolSize(void); +MEM_MGR cCmdGetMemMgr(void); +#endif + +#else //!ENABLE_VM + +//Placeholder VARSCMD for alternate implementation (see bottom of c_cmd.c for usage notes) +typedef struct +{ + UBYTE Tmp; +} VARSCMD; + +#endif //ENABLE_VM + +#endif //C_CMD diff --git a/src/c_cmd.iom b/src/c_cmd.iom new file mode 100644 index 0000000..7c5906c --- /dev/null +++ b/src/c_cmd.iom @@ -0,0 +1,202 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date: 3-02-09 9:28 $ +// +// Filename $Workfile:: c_cmd.iom $ +// +// Version $Revision: 5 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_cmd. $ +// +// Platform C +// + +#ifndef CCMD_IOM +#define CCMD_IOM + +#include "modules.h" + +#define pMapCmd ((IOMAPCMD*)(pHeaders[ENTRY_CMD]->pIOMap)) + +// +// Status/error codes for the VM internal code and bytecodes, loosely categorized +// Positive values are used for non-error status codes; commonly used by bytecode handlers +// to affect future execution. +// Negative values are run-time errors, and the first group is considered "fatal" in that +// program execution cannot continue when these errors are encountered. +// + +#define STAT_MSG_EMPTY_MAILBOX 64 //0x40 Specified mailbox contains no new messages +#define STAT_MSG_BUFFERWRAP 16 //0x10 Datalog buffer not being read fast enough +#define STAT_COMM_PENDING 32 //0x20 Pending setup operation in progress + +#define TIMES_UP 6 //0x06 Return to let drivers run +#define ROTATE_QUEUE 5 //0x05 Give a slice to another queue +#define STOP_REQ 4 //0x04 Abort current program +#define BREAKOUT_REQ 3 //0x03 Break multi-instruction interpreter loop; give I/O a chance to run +#define CLUMP_SUSPEND 2 //0x02 Place clump in stasis; execute others until this one returns to RunQ +#define CLUMP_DONE 1 //0x01 Finish and reset this clump; execute others until this one is rescheduled + +#define NO_ERR 0 + +//Fatal errors +#define ERR_ARG -1 //0xFF Bad arguments +#define ERR_INSTR -2 //0xFE Illegal bytecode instruction +#define ERR_FILE -3 //0xFD Mal-formed file contents +#define ERR_VER -4 //0xFC Version mismatch between firmware and compiler +#define ERR_MEM -5 //0xFB Insufficient memory available +#define ERR_BAD_PTR -6 //0xFA Someone passed us a bad pointer! + +//General errors +#define ERR_INVALID_PORT -16 //0xF0 Bad input or output port specified +#define ERR_INVALID_FIELD -17 //0xEF Attempted to access invalid field of a structure +#define ERR_INVALID_QUEUE -18 //0xEE Illegal queue ID specified +#define ERR_INVALID_SIZE -19 //0xED Illegal size specified +#define ERR_NO_PROG -20 //0xEC No active program + +//Communications specific errors +#define ERR_COMM_CHAN_NOT_READY -32 //0xE0 Specified channel/connection not configured or busy +#define ERR_COMM_CHAN_INVALID -33 //0xDF Specified channel/connection is not valid +#define ERR_COMM_BUFFER_FULL -34 //0xDE No room in comm buffer +#define ERR_COMM_BUS_ERR -35 //0xDD Something went wrong on the communications bus + +//Remote control ("direct commands") errors +#define ERR_RC_ILLEGAL_VAL -64 //0xC0 Data contains out-of-range values +#define ERR_RC_BAD_PACKET -65 //0xBF Clearly insane packet +#define ERR_RC_UNKNOWN_CMD -66 //0xBE Unknown command opcode +#define ERR_RC_FAILED -67 //0xBD Request failed (i.e. specified file not found) + +//NB: Error codes -96 through -128 (0xA0 through 0x80) reserved for loader (file system) errors +//This whole range isn't actually used by current loader code, but it's a reasonable range to reserve + +#define IS_ERR(Status) ((Status) < NO_ERR) + +//Errors are considered fatal if they are something we'd consider halting the VM for. +#define IS_FATAL(Status) ((Status) < NO_ERR && (Status) >= ERR_BAD_PTR) + +//Direct command protocol opcodes +//!!! These MUST be mutually exclusive with c_comm's protocol opcodes. +// Since all of c_comm's protocol opcodes are above 0x80, we're safe for now. +enum +{ + RC_START_PROGRAM, + RC_STOP_PROGRAM, + RC_PLAY_SOUND_FILE, + RC_PLAY_TONE, + RC_SET_OUT_STATE, + RC_SET_IN_MODE, + RC_GET_OUT_STATE, + RC_GET_IN_VALS, + RC_RESET_IN_VAL, + RC_MESSAGE_WRITE, + RC_RESET_POSITION, + RC_GET_BATT_LVL, + RC_STOP_SOUND, + RC_KEEP_ALIVE, + RC_LS_GET_STATUS, + RC_LS_WRITE, + RC_LS_READ, + RC_GET_CURR_PROGRAM, + RC_GET_BUTTON_STATE, + RC_MESSAGE_READ, + RC_RESERVED1, + RC_RESERVED2, + RC_RESERVED3, + RC_RESERVED4, + RC_RESERVED5, + RC_DATALOG_READ, + RC_DATALOG_SET_TIMES, + RC_BT_GET_CONTACT_COUNT, + RC_BT_GET_CONTACT_NAME, + RC_BT_GET_CONN_COUNT, + RC_BT_GET_CONN_NAME, + RC_SET_PROPERTY, + RC_GET_PROPERTY, + RC_UPDATE_RESET_COUNT, + + NUM_RC_OPCODES +}; + +// selectors for RC Get and Set properties +enum { +RC_PROP_BTONOFF, +RC_PROP_SOUND_LEVEL, +RC_PROP_SLEEP_TIMEOUT +}; + +// +//Published status of last program to be activated +//This value is published so outside parties (like the UI) can check if a program is running, +//and if not, how the last program ended. Initial value is "PROG_OK". +//PROG_OK: Last program finished normally. +//PROG_RUNNING: Program currently running +//PROG_ERROR: Last program ended because of an error +//PROG_ABORT: Last program ended because of (user) abort +// +typedef enum +{ + PROG_IDLE, + PROG_OK, + PROG_RUNNING, + PROG_ERROR, + PROG_ABORT, + PROG_RESET +} PROGRAM_STATUS; + +//Maximum size of memory pool, in bytes +//!!! Code assumes this value is evenly divisible by 4! +#define POOL_MAX_SIZE 32768 + +//Versioning information +//Format string must exist verbatim in the header of a valid program file. +//Also included in IOMAPCMD for remote identification of the VM +#define VM_FORMAT_STRING "MindstormsNXT" +//Size of format string above, plus version number packed in the last two bytes. +#define VM_FORMAT_STRING_SIZE 16 +//Current firmware version defined in c_loader.iom as FIRMWAREVERSION +//This is the oldest compatible version in the same system +#define VM_OLDEST_COMPATIBLE_VERSION 0x0004 +// +//IO Map for Command Module +// pRCHandler: Function pointer to handler for remote control protocol +// Tick: Latest value from 1 ms system timer + +//!!! Two offset values below are useful for external debugging. They are only valid after a program has started! +// OffsetDS: Offset to the dataspace (inside MemoryPool); relative to first byte of IOMapCmd +// OffsetDVA: Offset to the DopeVectorArray (inside MemoryPool); relative to first byte of IOMapCmd + +// ProgStatus: Published status of last program to be activated +// Awake: Boolean is only true after initialization + +// ActivateFlag: Set this flag to notify cCmdCtrl to activate new file +// DeactivateFlag: Set this flag to notify cCmdCtrl to deactivate current program + +// FileName[]: Fill in this buffer when using ActivateFlag +// MemoryPool[]: Main memory pool for program data. +// (Declared as ULONG for portable alignment; used internally via a byte pointer.) +// +typedef struct +{ + UBYTE FormatString[VM_FORMAT_STRING_SIZE]; + UWORD (*pRCHandler)(UBYTE *, UBYTE *, UBYTE *); + ULONG Tick; + + UWORD OffsetDS; + UWORD OffsetDVA; + + PROGRAM_STATUS ProgStatus; + + UBYTE Awake; + + UBYTE ActivateFlag; + UBYTE DeactivateFlag; + UBYTE FileName[FILENAME_LENGTH + 1]; + + ULONG MemoryPool[POOL_MAX_SIZE / 4]; + + ULONG SyncTime; + ULONG SyncTick; +} IOMAPCMD; + +#endif //CCMD_IOM diff --git a/src/c_cmd_bytecodes.h b/src/c_cmd_bytecodes.h new file mode 100644 index 0000000..5cd9dfd --- /dev/null +++ b/src/c_cmd_bytecodes.h @@ -0,0 +1,119 @@ +#ifndef C_CMD_BYTECODES +#define C_CMD_BYTECODES +// +// opcode definitions +// symbol, bits, arg format +// +#define OPCODE_COUNT 0x38 + +//Family: Math +#define OP_ADD 0x00 // dest, src1, src2 +#define OP_SUB 0x01 // dest, src1, src2 +#define OP_NEG 0x02 // dest, src +#define OP_MUL 0x03 // dest, src1, src2 +#define OP_DIV 0x04 // dest, src1, src2 +#define OP_MOD 0x05 // dest, src1, src2 + +//Family: Logic +#define OP_AND 0x06 // dest, src1, src2 +#define OP_OR 0x07 // dest, src1, src2 +#define OP_XOR 0x08 // dest, src1, src2 +#define OP_NOT 0x09 // dest, src + +//Family: Bit manipulation +#define OP_CMNT 0x0A // dest, src +#define OP_LSL 0x0B // dest, src +#define OP_LSR 0x0C // dest, src +#define OP_ASL 0x0D // dest, src +#define OP_ASR 0x0E // dest, src +#define OP_ROTL 0x0F // dest, src +#define OP_ROTR 0x10 // dest, src + +//Family: Comparison +#define OP_CMP 0x11 // dest, src1, src2 +#define OP_TST 0x12 // dest, src +#define OP_CMPSET 0x13 // dest, src, testsrc, testsrc +#define OP_TSTSET 0x14 // dest, src, testsrc + +//Family: Array ops +#define OP_INDEX 0x15 // dest, src, index +#define OP_REPLACE 0x16 // dest, src, index, val +#define OP_ARRSIZE 0x17 // dest, src +#define OP_ARRBUILD 0x18 // instrsize, dest, src1, src2, … +#define OP_ARRSUBSET 0x19 // dest, src, index, length +#define OP_ARRINIT 0x1A // dest, elem, length + +//Family: Memory ops +#define OP_MOV 0x1B // dest, src +#define OP_SET 0x1C // dest, imm + +//Family: String ops +#define OP_FLATTEN 0x1D // dest, src +#define OP_UNFLATTEN 0x1E // dest, err, src, type +#define OP_NUMTOSTRING 0x1F // dest, src +#define OP_STRINGTONUM 0x20 // dest, offsetpast, src, offset, default +#define OP_STRCAT 0x21 // instrsize, dest, src1, src2, … +#define OP_STRSUBSET 0x22 // dest, src, index, length +#define OP_STRTOBYTEARR 0x23 // dest, src +#define OP_BYTEARRTOSTR 0x24 // dest, src + +//Family: Control flow +#define OP_JMP 0x25 // offset +#define OP_BRCMP 0x26 // offset, src1, src2 +#define OP_BRTST 0x27 // offset, src +#define OP_SYSCALL 0x28 // func, args +#define OP_STOP 0x29 // stop? + +//Family: Clump scheduling +#define OP_FINCLUMP 0x2A // start, end +#define OP_FINCLUMPIMMED 0x2B // clumpID +#define OP_ACQUIRE 0x2C // mutexID +#define OP_RELEASE 0x2D // mutexID +#define OP_SUBCALL 0x2E // subroutine, callerID +#define OP_SUBRET 0x2F // callerID + +//Family: IO ops +#define OP_SETIN 0x30 // src, port, propid +#define OP_SETOUT 0x31 // src, port, propid +#define OP_GETIN 0x32 // dest, port, propid +#define OP_GETOUT 0x33 // dest, port, propid + +//Family: Timing +#define OP_WAIT 0x34 // dest, src +#define OP_GETTICK 0x35 // dest + +//Family: Math NEW +#define OP_SQRT 0x36 // dest, src +#define OP_ABS 0x37 // dest, src + +// condition code definitions +#define OPCC1_LT 0x00 +#define OPCC1_GT 0x01 +#define OPCC1_LTEQ 0x02 +#define OPCC1_GTEQ 0x03 +#define OPCC1_EQ 0x04 +#define OPCC1_NEQ 0x05 + + + +// +// short op definitions +// +#define USE_SHORT_OPS +#define SHORT_OP_MOV 0 +#define SHORT_OP_ACQUIRE 1 +#define SHORT_OP_RELEASE 2 +#define SHORT_OP_SUBCALL 3 + +// +// short op mapping table +// +static UBYTE ShortOpMap[4] = +{ + OP_MOV, + OP_ACQUIRE, + OP_RELEASE, + OP_SUBCALL +}; + +#endif // C_CMD_BYTECODES diff --git a/src/c_cmd_drawing.inc b/src/c_cmd_drawing.inc new file mode 100644 index 0000000..0132d44 --- /dev/null +++ b/src/c_cmd_drawing.inc @@ -0,0 +1,894 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 8/26/05 4:17p $ +// +// Filename $Workfile:: c_cmd.c $ +// +// Version $Revision:: 35 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_cmd_drawing.c $ +// +// Platform C +// + +//absolute value of a +#define ABS(a) (((a)<0) ? -(a) : (a)) + +//take binary sign of a, either -1, or 1 if >= 0 +#define SGN(a) (((a)<0) ? -1 : 1) + +#define DISP_BUFFER_P ((UBYTE*)&(pMapDisplay->Normal)) + +//------------------------------------------------------------------ +// cCmdClearScreenIfNeeded - Clear entire sceen buffer if explicitly requested or implicitly required. +void cCmdClearScreenIfNeeded(ULONG DrawOptions); + +//------------------------------------------------------------------ +// cCmdRestorDefaultScreen - Restore screen to default 'Running' screen +void cCmdRestoreDefaultScreen(void); + +//------------------------------------------------------------------ +// cCmdDrawString - Draw string to display buffer +void cCmdDrawString(UBYTE *pString, ULONG X, ULONG Y); + +// OP codes supported by RIC files +enum { + IMG_DESCRIPTION_ID = 0, // Ignored at this time + IMG_SPRITE_ID = 1, + IMG_VARMAP_ID = 2, + IMG_COPYBITS_ID = 3, + IMG_PIXEL_ID = 4, + IMG_LINE_ID = 5, + IMG_RECTANGLE_ID = 6, + IMG_CIRCLE_ID = 7, + IMG_NUMBOX_ID = 8 +}; + +#define IMG_SYMB_USEARGS(_v) (_v & (SWORD)0xF000) +#define IMG_SYMB_MAP(_v) ((_v & 0x0F00) >> 8) +#define IMG_SYMB_ARG(_v) (_v & 0x000F) + +// DrawingOptions +#define DRAW_OPT_CLEAR_WHOLE_SCREEN (0x0001) +#define DRAW_OPT_CLEAR_EXCEPT_STATUS_SCREEN (0x0002) +#define DRAW_OPT_CLEAR_MODE(_v) ((_v) & 0x0003) + + +// Clear Before Drawing Modes for Draw functions +enum { + DO_NOT_CLEAR = 0, + CLEAR_B4_DRAW = 1 +}; + +// Screen Modes for SetScreenMode function +enum { + RESTORE_NXT_SCREEN = 0 +}; + +#define IMG_COMMON_FIELDS UWORD OpSize; UWORD OpCode; + +#define TRANSLATE_Y(_y) ((DISPLAY_HEIGHT-1) - (_y)) + +typedef struct +{ + SWORD X, Y; +} IMG_PT; + +typedef struct +{ + IMG_PT Pt; + SWORD Width, Height; +} IMG_RECT; + +typedef struct +{ + IMG_COMMON_FIELDS +} IMG_OP_CORE; + +typedef struct +{ + IMG_COMMON_FIELDS + UWORD Options; + UWORD Width; + UWORD Height; +} IMG_OP_DESCRIPTION; + +typedef struct +{ + IMG_COMMON_FIELDS + UWORD DataAddr; //Address sprite handle will be stored in. + UWORD Rows; //Second deminsion of the array below. + UWORD RowBytes; //The actual size of the following array. Must be even. + UBYTE Bytes[2]; //Minimum of two for alignment purposes +} IMG_OP_SPRITE; + +typedef struct +{ + IMG_COMMON_FIELDS + UWORD DataAddr; //Address sprite handle will be stored in. + UWORD MapCount; //The actual size of the following array. Must be even. + struct + { //Minimum of two for alignment purposes + UWORD Domain; + UWORD Range; + } MapElt[1]; +} IMG_OP_VARMAP; + +typedef struct +{ + IMG_COMMON_FIELDS + UWORD CopyOptions; // Copy, CopyNot, Or, BitClear; + UWORD DataAddr; // Address of an already defined sprite + IMG_RECT Src; // Source rectangle + IMG_PT Dst; // Destination left top +} IMG_OP_COPYBITS; + +typedef struct +{ + IMG_COMMON_FIELDS + UWORD CopyOptions; + IMG_PT Pt; + UWORD Value; // typically mapped to an argument +} IMG_OP_PIXEL; + +typedef struct +{ + IMG_COMMON_FIELDS + UWORD CopyOptions; + IMG_PT Pt1; + IMG_PT Pt2; +} IMG_OP_LINE; + +typedef struct +{ + IMG_COMMON_FIELDS + UWORD CopyOptions; + IMG_PT Pt; + SWORD Width, Height; +} IMG_OP_RECT; + +typedef struct +{ + IMG_COMMON_FIELDS + UWORD CopyOptions; + IMG_PT Pt; + UWORD Radius; +} IMG_OP_CIRCLE; + +typedef struct +{ + IMG_COMMON_FIELDS + UWORD CopyOptions; + IMG_PT Pt; + UWORD Value; // typically mapped to an argument +} IMG_OP_NUMBOX; + +typedef union +{ IMG_OP_CORE Core; + IMG_OP_DESCRIPTION Desc; + IMG_OP_SPRITE Sprite; + IMG_OP_VARMAP VarMap; + IMG_OP_COPYBITS CopyBits; + IMG_OP_PIXEL Pixel; + IMG_OP_LINE Line; + IMG_OP_RECT Rect; + IMG_OP_CIRCLE Circle; + IMG_OP_NUMBOX NumBox; +} IMG_OP_UNION; + +// Variables for DrawImage +#define IMG_MAX_DATA 11 +IMG_OP_UNION * gpImgData[IMG_MAX_DATA]; +SLONG * gpPassedImgVars; +SWORD gPassedVarsCount; + +// Private Prototypes +void cCmdDrawLine(SLONG x1, SLONG y1, SLONG x2, SLONG y2); +void cCmdDrawRect(SLONG left, SLONG bottom, SLONG width, SLONG hieght); +void cCmdCopyBitMapBits(SLONG dst_x, SLONG dst_y, + SLONG src_x, SLONG src_y, SLONG src_width, SLONG src_height, + IMG_OP_SPRITE * pSprite); +SLONG cCmdResolveValue(SWORD Value); +void cCmdSetPixel(SLONG X, SLONG Y, ULONG Val); + +//----------------------------------------------------------------- +//cCmdWrapDrawText +//ArgV[0]: (Function return) Status byte, SBYTE +//ArgV[1]: Location (IMG_PT *) +//ArgV[2]: Text (CStr) +//ArgV[3]: Options (ULONG) +// +NXT_STATUS cCmdWrapDrawText(UBYTE * ArgV[]) +{ + IMG_PT * pPt = (IMG_PT*) ArgV[1]; + + ArgV[2] = (UBYTE*)cCmdDVPtr(*(DV_INDEX *)(ArgV[2])); //Resolve array argument + + cCmdClearScreenIfNeeded(*(ULONG*)ArgV[3]); + + // Display the String + cCmdDrawString(ArgV[2], (UBYTE)pPt->X, (UBYTE)(pPt->Y)); + pMapDisplay->UpdateMask |= SCREEN_BIT(SCREEN_BACKGROUND); + + // Set return value + *((SBYTE*)(ArgV[0])) = NO_ERR; + + return NO_ERR; +} + +//----------------------------------------------------------------- +//cCmdWrapDrawPoint +//ArgV[0]: (Function return) Status byte, SBYTE +//ArgV[1]: Location (IMG_PT *) +//ArgV[2]: Options (ULONG) +NXT_STATUS cCmdWrapDrawPoint(UBYTE * ArgV[]) +{ + IMG_PT * pPt = (IMG_PT*) ArgV[1]; + + cCmdClearScreenIfNeeded(*(ULONG*)ArgV[2]); + + // Display the String + cCmdSetPixel(pPt->X, pPt->Y, TRUE); + + pMapDisplay->UpdateMask |= SCREEN_BIT(SCREEN_BACKGROUND); + + // Set return value + *((SBYTE*)(ArgV[0])) = NO_ERR; + + return NO_ERR; +} + +//----------------------------------------------------------------- +//cCmdWrapDrawLine +//ArgV[0]: (Function return) Status byte, SBYTE +//ArgV[1]: Start Location (IMG_PT *) +//ArgV[2]: End Location (IMG_PT *) +//ArgV[3]: Options (ULONG) +NXT_STATUS cCmdWrapDrawLine(UBYTE * ArgV[]) +{ + IMG_PT * pPt1 = (IMG_PT*) ArgV[1]; + IMG_PT * pPt2 = (IMG_PT*) ArgV[2]; + + cCmdClearScreenIfNeeded(*(ULONG*)ArgV[3]); + + cCmdDrawLine(pPt1->X, pPt1->Y, pPt2->X, pPt2->Y); + + pMapDisplay->UpdateMask |= SCREEN_BIT(SCREEN_BACKGROUND); + + // Set return value + *((SBYTE*)(ArgV[0])) = NO_ERR; + + return NO_ERR; +} + +//----------------------------------------------------------------- +//cCmdWrapDrawCircle +//ArgV[0]: (Function return) Status byte, SBYTE +//ArgV[1]: Start Location (IMG_PT *) +//ArgV[2]: Radius (U8) +//ArgV[3]: Options (ULONG) +NXT_STATUS cCmdWrapDrawCircle(UBYTE * ArgV[]) +{ + SLONG x, x1, y1, y, dp, delta; + IMG_PT * pPt = (IMG_PT*) ArgV[1]; + SLONG radius = *(UBYTE*)ArgV[2]; + + cCmdClearScreenIfNeeded(*(ULONG*)ArgV[3]); + + x1 = pPt->X; + y1 = pPt->Y; + x = 0; + y = radius; + dp=2*(1-radius); + while(y >= 0) + { + cCmdSetPixel((x+x1), (y+y1), TRUE); + cCmdSetPixel((-x+x1),(-y+y1), TRUE); + cCmdSetPixel((x+x1), (-y+y1), TRUE); + cCmdSetPixel((-x+x1),(y+y1), TRUE); + if(dp<0) + { + delta = 2*dp + 2*y - 1; + if (delta > 0) + { + x++; + y--; + dp += 2*x - 2*y + 2; + } + else + { + x++; + dp += 2*x + 1; + } + } + else if (dp > 0) + { + delta = 2*dp - 2*x - 1; + if (delta > 0) + { + y--; + dp += 1 - 2*y; + } + else + { + x++; + y--; + dp += 2*x - 2*y + 2; + } + } + else + { + x++; + y--; + dp += 2*x - 2*y +2; + } + } + + pMapDisplay->UpdateMask |= SCREEN_BIT(SCREEN_BACKGROUND); + + // Set return value + *((SBYTE*)(ArgV[0])) = NO_ERR; + + return NO_ERR; +} + +//----------------------------------------------------------------- +//cCmdWrapDrawRect +//ArgV[0]: (Function return) Status byte, SBYTE +//ArgV[1]: TopLeft (IMG_PT *) +//ArgV[2]: BottomRight (IMG_PT *) +//ArgV[3]: Options (ULONG) +NXT_STATUS cCmdWrapDrawRect(UBYTE * ArgV[]) +{ + IMG_PT * pPt1 = (IMG_PT*) ArgV[1]; + IMG_PT * pPt2 = (IMG_PT*) ArgV[2]; // Second point is actually (width, height) + + cCmdClearScreenIfNeeded(*(ULONG*)ArgV[3]); + + cCmdDrawRect(pPt1->X, pPt1->Y, pPt2->X, pPt2->Y); + + pMapDisplay->UpdateMask |= SCREEN_BIT(SCREEN_BACKGROUND); + + // Set return value + *((SBYTE*)(ArgV[0])) = NO_ERR; + + return NO_ERR; +} + +//----------------------------------------------------------------- +IMG_OP_UNION * cCmdGetIMGData(ULONG DataAddr) +{ + if (DataAddr >= IMG_MAX_DATA) + return NULL; + else + return gpImgData[DataAddr]; +} + +//----------------------------------------------------------------- +void cCmdSetIMGData(ULONG DataAddr, IMG_OP_UNION * pSprite) +{ + if ((DataAddr >= 1) && (DataAddr < IMG_MAX_DATA)) + gpImgData[DataAddr] = pSprite; +} + +//----------------------------------------------------------------- +SLONG cCmdResolveValue(SWORD Value) +{ + if (!IMG_SYMB_USEARGS(Value)) + { + return Value; + } + else + { + IMG_OP_VARMAP * pVarMap; + SLONG Arg; + + pVarMap = (IMG_OP_VARMAP *) cCmdGetIMGData((SWORD)IMG_SYMB_MAP(Value)); + Arg = gpPassedImgVars[IMG_SYMB_ARG(Value)]; + + if (!pVarMap) + { + // No map, this implies a 1:1 mapping. + return Arg; + } + else + { + // Scan through the list finding the pair the Arg lies between + // Then linearly interpolate the mapping. + SLONG i, DCur, RCur, DSpread, VSpread, RSpread; + SLONG Count = pVarMap->MapCount; + SLONG DPrev = pVarMap->MapElt[0].Domain; + SLONG RPrev = pVarMap->MapElt[0].Range; + if (Arg <= DPrev) + { + // Too small, map it to the first point + return RPrev; + } + + for (i = 1; i < Count; i++) + { + DCur = pVarMap->MapElt[i].Domain; + RCur = pVarMap->MapElt[i].Range; + if (Arg < DCur) + { + DSpread = DCur - DPrev; + VSpread = Arg - DPrev; + RSpread = RCur - RPrev; + // Found the point and mapped, it return. + return (RPrev+((VSpread*RSpread)/DSpread)); + } + DPrev = DCur; + RPrev = RCur; + } + // If we get this far then it is too large, map it to the last point. + return RCur; + } + } +} + + +//----------------------------------------------------------------- +//cCmdWrapDrawGraphic +//ArgV[0]: (Function return) Status Byte, SBYTE +//ArgV[1]: Left Top (IMG_PT *) +//ArgV[2]: Filename, CStr +//ArgV[3]: Variables, array of I32 +//ArgV[4]: Options (ULONG) +NXT_STATUS cCmdWrapDrawPicture(UBYTE * ArgV[]) +{ + SBYTE * pReturnVal = (SBYTE*)(ArgV[0]); + LOADER_STATUS LStatus; + NXT_STATUS DStatus = NO_ERR; + ULONG DataSize; + SLONG OpSize; + IMG_PT Pt; // Where to draw the picture at (up and to the right) + UBYTE ImageHandle; + IMG_OP_UNION * pImage; + + //Resolve array argument + ArgV[2] = (UBYTE*)cCmdDVPtr(*(DV_INDEX *)(ArgV[2])); + ArgV[3] = (UBYTE*)cCmdDVPtr(*(DV_INDEX *)(ArgV[3])); + + cCmdClearScreenIfNeeded(*(ULONG*)ArgV[4]); + + //Open the file in memory map mode. return if failure. + LStatus = pMapLoader->pFunc(OPENREADLINEAR, ArgV[2], (UBYTE*)(&pImage), &DataSize); + ImageHandle = LOADER_HANDLE(LStatus); + + //If error opening file, give up and write loader status back to user. + if (LOADER_ERR(LStatus) != SUCCESS || pImage == NULL) + { + *pReturnVal = (SBYTE)(LOADER_ERR_BYTE(LStatus)); + return (NO_ERR); + } + //Else, start interpretting the file + else + { + // Read the ArgV params, Clear the data table. + Pt = *(IMG_PT*)ArgV[1]; + //!!! Unsafe assumption that array is non-empty. Should check and avoid using pointer if empty. + gpPassedImgVars = (SLONG*)ArgV[3]; + memset(gpImgData,0,sizeof(gpImgData)); + + // Run through the op codes. + while(!IS_ERR(DStatus)) + { + // Setup to look at an opcode, make sure it looke reasonable. + if (DataSize < sizeof(IMG_OP_CORE)) + { + DStatus = ERR_FILE; + break; // Too small to look at, somethings wrong. + } + OpSize = pImage->Core.OpSize + sizeof(UWORD); + if (OpSize & 0x01) + { + DStatus = ERR_FILE; + break; // Odd sizes not allowed. + } + + switch(pImage->Core.OpCode) + { + case IMG_SPRITE_ID: + { + if (OpSize >= sizeof(IMG_OP_SPRITE)) + cCmdSetIMGData(pImage->Sprite.DataAddr, pImage); + } + break; + + case IMG_VARMAP_ID: + { + if (OpSize >= sizeof(IMG_OP_VARMAP)) + cCmdSetIMGData(pImage->VarMap.DataAddr, pImage); + } + break; + + case IMG_COPYBITS_ID: + { + if (OpSize >= sizeof(IMG_OP_COPYBITS)) + { + IMG_OP_COPYBITS * pCB = &(pImage->CopyBits); + cCmdCopyBitMapBits( + (cCmdResolveValue(pCB->Dst.X) + Pt.X), + (cCmdResolveValue(pCB->Dst.Y) + Pt.Y), + cCmdResolveValue((pCB->Src.Pt.X)), + cCmdResolveValue((pCB->Src.Pt.Y)), + cCmdResolveValue((pCB->Src.Width)), + cCmdResolveValue((pCB->Src.Height)), + (IMG_OP_SPRITE*)cCmdGetIMGData(cCmdResolveValue(pCB->DataAddr))); + } + } + break; + + case IMG_LINE_ID: + { + if (OpSize >= sizeof(IMG_OP_LINE)) + { + IMG_OP_LINE * pL = &(pImage->Line); + cCmdDrawLine( + (cCmdResolveValue(pL->Pt1.X)+Pt.X), + (cCmdResolveValue(pL->Pt1.Y)+Pt.Y), + (cCmdResolveValue(pL->Pt2.X)+Pt.X), + (cCmdResolveValue(pL->Pt2.Y)+Pt.Y) + ); + } + } + break; + + case IMG_RECTANGLE_ID: + { + if (OpSize >= sizeof(IMG_OP_LINE)) + { + IMG_OP_RECT * pL = &(pImage->Rect); + cCmdDrawRect( + (SWORD)(cCmdResolveValue(pL->Pt.X)+Pt.X), + (SWORD)(cCmdResolveValue(pL->Pt.Y)+Pt.Y), + (SWORD)(cCmdResolveValue(pL->Width)), + (SWORD)(cCmdResolveValue(pL->Height)) + ); + } + } + break; + + case IMG_PIXEL_ID: + { + if (OpSize >= sizeof(IMG_OP_PIXEL)) + { + cCmdSetPixel( + (cCmdResolveValue(pImage->Pixel.Pt.X) + Pt.X), + (cCmdResolveValue(pImage->Pixel.Pt.Y) + Pt.Y), + TRUE); + } + } + break; + + case IMG_NUMBOX_ID: + { + if (OpSize >= sizeof(IMG_OP_NUMBOX)) + { + UBYTE NumStr[20]; + IMG_OP_NUMBOX * pNB = &(pImage->NumBox); + sprintf((PSZ)NumStr, "%d", cCmdResolveValue(pNB->Value)); + cCmdDrawString( + NumStr, + (UBYTE) (cCmdResolveValue(pNB->Pt.X) + Pt.X), + (UBYTE) (cCmdResolveValue(pNB->Pt.Y) + Pt.Y)); + } + } + break; + + case IMG_DESCRIPTION_ID: + { + //No-op + } + break; + + default: + { + //Unrecognized opcode, pass an error back to the user. + DStatus = ERR_FILE; + } + break; + } + + DataSize -= OpSize; + pImage = (IMG_OP_UNION*) ((UBYTE*)pImage + OpSize); + } + + pMapDisplay->UpdateMask |= SCREEN_BIT(SCREEN_BACKGROUND); + } + + // Set return value, close file and return + *pReturnVal = DStatus; + pMapLoader->pFunc(CLOSE, &ImageHandle, NULL, NULL); + return (NO_ERR); +} + +//----------------------------------------------------------------- +// cCmdDrawLine - draw a line. All clipping is done by the set pixel function. +void cCmdDrawLine( + SLONG x1, + SLONG y1, + SLONG x2, + SLONG y2) +{ + SLONG d,x,y,ax,ay,sx,sy,dx,dy; + + // Initialize variables + dx = x2-x1; ax = ABS(dx)<<1; sx = SGN(dx); + dy = y2-y1; ay = ABS(dy)<<1; sy = SGN(dy); + x = x1; + y = y1; + if (ax>ay) + { /* x dominant */ + d = ay-(ax>>1); + for (;;) + { + cCmdSetPixel(x, y, TRUE); + if (x==x2) + return; + if (d>=0) + { + y += sy; + d -= ax; + } + x += sx; + d += ay; + } + } + else + { /* y dominant */ + d = ax-(ay>>1); + for (;;) + { + cCmdSetPixel(x, y, TRUE); + if (y==y2) + return; + if (d>=0) + { + x += sx; + d -= ay; + } + y += sy; + d += ax; + } + } +} + + +//----------------------------------------------------------------- +// cCmdDrawRect - draw a rectangle. All clipping is done by the set pixel function. +void cCmdDrawRect( + SLONG left, + SLONG bottom, + SLONG width, + SLONG height) +{ + SLONG right = left + width; + SLONG top = bottom + height; + + // Draw the four line segments + cCmdDrawLine(left, top, right, top); + cCmdDrawLine(right, top, right, bottom); + cCmdDrawLine(right, bottom, left, bottom); + cCmdDrawLine(left, bottom, left, top); +} + + +#ifndef DISPLAY_REALWIDTH + #define DISPLAY_REALWIDTH DISPLAY_WIDTH +#endif +//----------------------------------------------------------------- +//cCmdCopyBitMapBits +void cCmdCopyBitMapBits( + SLONG dst_x, // left pixel on LCD + SLONG dst_y, // bottom pixel on LCD + SLONG src_x, // starting pixel x coordinate from source map + SLONG src_y, // starting pixel y coordinate from source map + SLONG src_width, // width in pixels to the right (negative implies to the left) + SLONG src_height, // height in pixels down (negative implies down) + IMG_OP_SPRITE * pSprite) +{ + SLONG dy; // Location in the destination pixmap , the screen that is + SLONG sx; + SLONG sy; // Location in the source pixmap. + SLONG trim, last_x, last_y, rowbytes; + UBYTE *pSrcByte; + UBYTE *pDstBytes; + UBYTE *pDstByte, *pFirstDstByte; + UBYTE *pLastDstByte; + UBYTE bit_y, not_bit_y; + UBYTE masks[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; + + // Data in the image file is row major 8 pixels per byte.top row first. + // src and dst coordinates treat the bottom left most pixel as (0,0) + + if (!pSprite || pSprite->OpCode!=IMG_SPRITE_ID) + return; + + pDstBytes = DISP_BUFFER_P; + + // Clip the edges. Modify the source and width as well. + if (dst_x < 0) { // bounds check start of x + trim = (0 - dst_x); + dst_x = 0; + src_x += trim; + src_width -= trim; + } + + last_x = dst_x + src_width; + if (last_x > DISPLAY_WIDTH) // bound check end of x + last_x = DISPLAY_WIDTH; + + if (dst_y < 0) { // bound check start of y + trim = (0 - dst_y); + dst_y = 0; + src_y += trim; // fix up source as well since we are clipping the start of the loop + src_height -= trim; + } + + last_y = dst_y + src_height; + if (last_y > DISPLAY_HEIGHT) // bound check end of y + last_y = DISPLAY_HEIGHT; + + // Convert the 0,0 bottom left origin to the top left 0,0 used by the actual + // buffer + last_y = TRANSLATE_Y(last_y); + dst_y = TRANSLATE_Y(dst_y); + + // The last row is the top most scan line in the LCD Buffer + // so limit if the copy would copy into memory before the buffer. + // The first row copied will be the one closest to the bottom of the LCD + // If that is off screen then limit as well and adjust the start point on the start + + // Copy bits top to top moving down. + sy = src_y; + rowbytes = pSprite->RowBytes; + + pSrcByte = pSprite->Bytes + ((pSprite->Rows - 1 - sy) * rowbytes); + pFirstDstByte = pDstBytes + ((dst_y >> 3) * DISPLAY_REALWIDTH) + dst_x; + for (dy = dst_y; dy > last_y; dy--) + { + sx = src_x; + bit_y = masks[7 - (dy & 0x07)]; + not_bit_y = ~ bit_y; + pDstByte = pFirstDstByte; + pLastDstByte = pDstByte + (last_x - dst_x); + for (; pDstByte < pLastDstByte; pDstByte++) + { + if ( *(pSrcByte + (sx >> 3)) & masks[sx & 0x07] ){ + *pDstByte |= bit_y; + } else { + *pDstByte &= not_bit_y; + } + sx ++; + } + pSrcByte -= rowbytes; + sy ++; + if ((dy & 0x07) == 0) // bump back the scan line start point at rollover + pFirstDstByte -= DISPLAY_REALWIDTH; + } + +} + +//----------------------------------------------------------------- +// cCmdSetPixel - Set or clear a pixel based on Val +void cCmdSetPixel(SLONG X, SLONG Y, ULONG Val) +{ + Y = TRANSLATE_Y(Y); + + pMapDisplay->pFunc(DISPLAY_PIXEL, (UBYTE)Val, (UBYTE)X, (UBYTE)Y, 0, 0); +} + + +//----------------------------------------------------------------- +//cCmdWrapSetScreenMode +//ArgV[0]: (Function return) Status code, SBYTE +//ArgV[1]: ScreenMode ULONG +NXT_STATUS cCmdWrapSetScreenMode(UBYTE * ArgV[]) +{ + ULONG ScreenMode = (ULONG)(*ArgV[1]); + if (ScreenMode == RESTORE_NXT_SCREEN) { + cCmdRestoreDefaultScreen(); + } + + // Set return value + *(SBYTE*)(ArgV[0]) = NO_ERR; + return NO_ERR; +} + +//------------------------------------------------------------------ +// cCmdClearScreenIfNeeded - Clear entire sceen buffer if explicitly requested or implicitly required. +void cCmdClearScreenIfNeeded(ULONG DrawOptions) +{ + //If we are the first drawing command, clear the screen and record that we've done so + if (VarsCmd.DirtyDisplay == FALSE) + { + VarsCmd.DirtyDisplay = TRUE; + pMapUi->Flags &= ~UI_ENABLE_STATUS_UPDATE; + + //Override DrawOptions because we have to clear anyway + DrawOptions = DRAW_OPT_CLEAR_WHOLE_SCREEN; + } + + if (DRAW_OPT_CLEAR_MODE(DrawOptions)) + { + pMapDisplay->pFunc(DISPLAY_ERASE_ALL, 0, 0, 0, 0, 0); + + //Clear UpdateMask to kill any pending updates + pMapDisplay->UpdateMask = 0; + } + + return; +} + +//------------------------------------------------------------------ +// cCmdDrawString - Draw string to display buffer +// Properly uses 'Normal' display buffer to avoid conflicts with popup buffer +// Clips text at bottom and right hand edges of the screen buffer +//!!! Function copied and modified from cDisplayString +void cCmdDrawString(UBYTE *pString, ULONG X, ULONG Y) +{ + UBYTE *pSource; + UBYTE *pDestination; + FONT *pFont; + ULONG FontWidth; + ULONG Items; + ULONG Item; + ULONG Line; + + //Get current font information + pFont = pMapDisplay->pFont; + Items = pFont->ItemsX * pFont->ItemsY; + + //Invert Y coordinate to match display buffer + Y = TRANSLATE_Y(Y); + Line = (Y & 0xF8) / 8; + + //If text line is out of bounds, do nothing. + if (Line >= TEXTLINES) + return; + + //Calculate pointer to first byte of drawing destination + pDestination = &(DISP_BUFFER_P[Line * DISPLAY_WIDTH + X]); + + while (*pString) + { + FontWidth = pFont->ItemPixelsX; + //Calculate X coordinate of the right edge of this character. + //If it will extend past the right edge, clip the string. + X += FontWidth; + if (X >= DISPLAY_WIDTH) + break; + + //If Item is defined by the font, display it. Else, ignore it. + Item = *pString - ' '; + if (Item < Items) + { + pSource = (UBYTE*)&(pFont->Data[Item * FontWidth]); + while (FontWidth--) + { + *pDestination = *pSource; + pDestination++; + pSource++; + } + } + pString++; + } +} + +//------------------------------------------------------------------ +// cCmdRestoreDefaultScreen - Restore to Default 'Running' screen +void cCmdRestoreDefaultScreen(void) +{ + //If this program has taken over the display, reset it for the UI + if (VarsCmd.DirtyDisplay == TRUE) + { + VarsCmd.DirtyDisplay = FALSE; + + pMapDisplay->pFunc(DISPLAY_ERASE_ALL, 0, 0, 0, 0, 0); + pMapDisplay->UpdateMask = SCREEN_BIT(SCREEN_BACKGROUND); + + pMapUi->Flags |= UI_ENABLE_STATUS_UPDATE | UI_REDRAW_STATUS; + } +} diff --git a/src/c_comm.c b/src/c_comm.c new file mode 100644 index 0000000..176a1ff --- /dev/null +++ b/src/c_comm.c @@ -0,0 +1,3714 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date: 8-09-08 14:11 $ +// +// Filename $Workfile:: c_comm.c $ +// +// Version $Revision: 7 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_comm $ +// +// Platform C +// + +#include "stdconst.h" +#include "modules.h" +#include "c_comm.iom" +#include "c_loader.iom" +#include "c_ioctrl.iom" +#include "c_ui.iom" +#include "c_cmd.iom" +#include "c_display.iom" +#include "c_comm.h" +#include "d_usb.h" +#include "d_hispeed.h" +#include "d_bt.h" +#include +#include +#ifdef ARMDEBUG +#include "debug_stub.h" +#endif + +enum +{ + DEVICE_VERIFIED, + DEVICE_UPDATED, + DEVICE_INSERTED +}; + +#define DEFAULTBTADR "\x00\x16\x53\xFF\xFF\xFF" +#define BTSTREAMTOUT 610 + +#define LOOKUPNO 3 + +#define CLEARExtMode {\ + UBYTE Tmp;\ + for(Tmp = 0; Tmp < NO_OF_CHANNELS; Tmp++)\ + {\ + VarsComm.ExtMode[Tmp].Status = FALSE;\ + }\ + } + +#define CHNumber(Bit) (Bit>>1) +#define SETBtStateIdle VarsComm.ActiveUpdate = UPD_IDLE;\ + VarsComm.UpdateState = 0;\ + VarsComm.StreamStateCnt = 0;\ + VarsComm.CmdSwitchCnt = 0;\ + VarsComm.CloseConn0Cnt = 0;\ + VarsComm.DiscAllCnt = 0;\ + VarsComm.ResetBtCnt = 0 + +#define SETBtCmdState VarsComm.BtState = BT_ARM_CMD_MODE;\ + IOMapComm.BtInBuf.InPtr = 0;\ + CLEARExtMode;\ + dBtClearArm7CmdSignal();\ + dBtInitReceive(VarsComm.BtModuleInBuf.Buf, (UBYTE)CMD_MODE); + +#define SETBtDataState IOMapComm.BtInBuf.InPtr = 0;\ + VarsComm.BtState = BT_ARM_DATA_MODE;\ + dBtClearTimeOut(); /* stop cmd timeout because in datamode */\ + dBtSetArm7CmdSignal();\ + dBtInitReceive(VarsComm.BtModuleInBuf.Buf, (UBYTE)STREAM_MODE) + +#define SETBtOff VarsComm.BtState = BT_ARM_OFF;\ + dBtSetBcResetPinLow() + +#define CLEARConnEntry(Index) memset((IOMapComm.BtConnectTable[Index].BdAddr), 0, SIZE_OF_BDADDR);\ + memset(IOMapComm.BtConnectTable[Index].Name, 0, SIZE_OF_BT_NAME);\ + memset((IOMapComm.BtConnectTable[Index].ClassOfDevice), 0, SIZE_OF_CLASS_OF_DEVICE);\ + memset((IOMapComm.BtConnectTable[Index].PinCode), 0, SIZE_OF_BT_PINCODE);\ + IOMapComm.BtConnectTable[Index].HandleNr = BLUETOOTH_HANDLE_UNDEFIEND;\ + IOMapComm.BtConnectTable[Index].StreamStatus = 0;\ + IOMapComm.BtConnectTable[Index].LinkQuality = 0 + +#define FILETXTOUT 30000 + +const UBYTE BootString[] = {"Let's dance: SAMBA"}; +const UBYTE NoName[SIZE_OF_BT_NAME] = {"No Name"}; + +static IOMAPCOMM IOMapComm; +static VARSCOMM VarsComm; +static HEADER **pHeaders; + +const HEADER cComm = +{ + 0x00050001L, + "Comm", + cCommInit, + cCommCtrl, + cCommExit, + (void *)&IOMapComm, + (void *)&VarsComm, + (UWORD)sizeof(IOMapComm), + (UWORD)sizeof(VarsComm), + 0x0000 /* Code size - not used so far */ +}; + +UWORD cCommReceivedBtData(void); +void cCommBtCmdInterpreter(void); +UWORD cCommInterprete(UBYTE *pInBuf, UBYTE *pOutBuf, UBYTE *pLength, UBYTE CmdBit, UWORD MsgLength); +UWORD cCommInterpreteCmd(UBYTE Cmd, UBYTE *pInBuf, UBYTE *pOutBuf, UBYTE *pLength, UBYTE CmdBit, UWORD MsgLength); +void cCommCpyToUpper(UBYTE *pDst, UBYTE *pSrc, UBYTE Length); +void cCommCopyFileName(UBYTE *pDst, UBYTE *pSrc); +void cCommSendHiSpeedData(void); +void cCommReceivedHiSpeedData(void); +UWORD cCommReq(UBYTE Cmd, UBYTE Param1, UBYTE Param2, UBYTE Param3, UBYTE *pName, UWORD *pRetVal); +UBYTE cCommBtValidateCmd(void); + +void cCommClearStreamStatus(void); +void cCommUpdateBt(void); +UWORD cCommCopyBdaddr(UBYTE *pDst, UBYTE *pSrc); +UWORD cCommInsertBtName(UBYTE *pDst, UBYTE *pSrc); +UWORD cCommCheckBdaddr(UBYTE *pAdr, UBYTE *pSrc); +UWORD cCommInsertDevice(UBYTE *pBdaddr, UBYTE *pName, UBYTE *pCod, UBYTE DeviceStatus, UBYTE *pAddInfo); +void cCommsSetCmdMode(UBYTE *pNextState); +void cCommsOpenStream(UBYTE *pNextState); +void cCommsCloseConn0(UBYTE *pNextState); +void cCommsDisconnectAll(UBYTE *pNextState); +void cCommsBtReset(UBYTE *pNextState); +void cCommPinCode(UBYTE *pPinCode); +void cCommClrConnTable(void); +SBYTE cCommSearchBTDevTableForName(UBYTE*); + +void cCommInit(void* pHeader) +{ + UBYTE Tmp; + + pHeaders = pHeader; + IOMapComm.pFunc = &cCommReq; + IOMapComm.pFunc2 = &cCommPinCode; + IOMapComm.UsbState = FALSE; + IOMapComm.UsbOutBuf.OutPtr = 0; + + CLEARExtMode; + + dUsbInit(); + dBtInit(); + + SETBtStateIdle; + VarsComm.BtModuleInBuf.InPtr = 0; + VarsComm.BtWaitTimeCnt = 0; + + /* Force a reset sequence on the BC4 */ + VarsComm.pRetVal = &(VarsComm.RetVal); + VarsComm.ActiveUpdate = UPD_RESET; + + VarsComm.BtState = BT_ARM_CMD_MODE; + IOMapComm.BrickData.BtHwStatus = BT_DISABLE; + + for (Tmp = 0; Tmp < SIZE_OF_BT_DEVICE_TABLE; Tmp++) + { + IOMapComm.BtDeviceTable[Tmp].DeviceStatus = BT_DEVICE_EMPTY; + } + IOMapComm.BtDeviceCnt = 0; + IOMapComm.BrickData.BtStateStatus = 0; + + cCommClrConnTable(); + + dBtInitReceive(VarsComm.BtModuleInBuf.Buf, (UBYTE)CMD_MODE); + dBtStartADConverter(); + + dHiSpeedInit(); + VarsComm.HsState = 0; + + IOMapComm.UsbPollBuf.InPtr = 0; + IOMapComm.UsbPollBuf.OutPtr = 0; + + VarsComm.BtAdrStatus = COLDBOOT; +} + +void cCommCtrl(void) +{ + + if (FALSE == cCommReceivedBtData()) + { + + /* there has been a timeout on the BC4 channel */ + SETBtStateIdle; + *(VarsComm.pRetVal) = BTTIMEOUT; + if (COLDBOOT == VarsComm.BtAdrStatus) + { + + /* there is an BT fatal error - set default bt adr and name*/ + strcpy((char*)IOMapComm.BrickData.Name, (char*)UI_NAME_DEFAULT); + dUsbStoreBtAddress((UBYTE*)DEFAULTBTADR); + pMapUi->Flags |= UI_REDRAW_STATUS; + dBtSetBcResetPinLow(); + VarsComm.BtAdrStatus = BTADRERROR; + } + } + cCommUpdateBt(); + VarsComm.BtBcPinLevel = dBtGetBc4CmdSignal(); + + if (UPD_IDLE == VarsComm.ActiveUpdate) + { + switch (VarsComm.BtState) + { + + /* Bluetooth device can either be in CMD, DATA or OFF state at top level */ + case BT_ARM_OFF: + { + } + break; + case BT_ARM_CMD_MODE: + { + if (VarsComm.BtBcPinLevel) + { + SETBtDataState; + } + } + break; + + case BT_ARM_DATA_MODE: + { + if (!(VarsComm.BtBcPinLevel)) + { + SETBtCmdState; + } + } + break; + } + } + IOMapComm.BtInBuf.Buf[BT_CMD_BYTE] = 0; + + + /* Here comes the the HIGHSPEED_PORT implementation */ + if (IOMapComm.HsFlags & HS_UPDATE) + { + IOMapComm.HsFlags &= ~HS_UPDATE; + switch (IOMapComm.HsState) + { + case HS_INITIALISE: + { + dHiSpeedSetupUart(); + IOMapComm.HsState = HS_INIT_RECEIVER; + IOMapComm.HsFlags |= HS_UPDATE; + } + break; + + case HS_INIT_RECEIVER: + { + dHiSpeedInitReceive(VarsComm.HsModuleInBuf.Buf); + VarsComm.HsState = 0x01; + } + break; + + case HS_SEND_DATA: + { + cCommSendHiSpeedData(); + } + break; + + case HS_DISABLE: + { + VarsComm.HsState = 0x00; + dHiSpeedExit(); + } + break; + } + } + + if (VarsComm.HsState != 0) + { + cCommReceivedHiSpeedData(); + } + + /* Here comes the the USB implementation */ + ULONG Length; + UWORD Status; + + if (0 != IOMapComm.UsbOutBuf.OutPtr) + { + dUsbWrite((const UBYTE *)IOMapComm.UsbOutBuf.Buf, (ULONG)IOMapComm.UsbOutBuf.OutPtr); + IOMapComm.UsbOutBuf.OutPtr = 0; + } + + Length = 0; + + if (TRUE == dUsbCheckConnection()) + { + pMapUi->UsbState = 1; + if (TRUE == dUsbIsConfigured()) + { + Length = dUsbRead(IOMapComm.UsbInBuf.Buf, sizeof(IOMapComm.UsbInBuf.Buf)); + IOMapComm.UsbState = TRUE; + pMapUi->UsbState = 2; + } + } + else + { + pMapUi->UsbState = 0; + dUsbResetConfig(); + if (TRUE == IOMapComm.UsbState) + { + IOMapComm.UsbState = FALSE; + Status = dUsbGetFirstHandle(); + while(0 == LOADER_ERR(Status)) + { + IOMapComm.UsbInBuf.Buf[0] = LOADER_HANDLE(Status); + pMapLoader->pFunc(CLOSE, &(IOMapComm.UsbInBuf.Buf[0]), &(IOMapComm.UsbInBuf.Buf[2]), &Length); + dUsbRemoveHandle(IOMapComm.UsbInBuf.Buf[0]); + Status = dUsbGetNextHandle(); + } + } + } + + if (0 != Length) + { + cCommInterprete(IOMapComm.UsbInBuf.Buf, IOMapComm.UsbOutBuf.Buf, (UBYTE*)&Length, USB_CMD_READY, (UWORD)Length); + if (Length) + { + dUsbWrite((const UBYTE *)IOMapComm.UsbOutBuf.Buf, Length); + } + } + dBtStartADConverter(); +} + +void cCommExit(void) +{ + dUsbExit(); + dHiSpeedExit(); + dBtExit(); +} + + +UBYTE cCommCheckSysFileType(UBYTE *pName) +{ + UBYTE RtnVal; + UBYTE TmpFilename[FILENAME_LENGTH + 1]; + + RtnVal = FALSE; + cCommCpyToUpper(TmpFilename, &pName[1], (UBYTE)(FILENAME_LENGTH + 1)); + if ((0 != strstr((PSZ)(TmpFilename), ".RXE")) || + (0 != strstr((PSZ)(TmpFilename), ".SYS")) || + (0 != strstr((PSZ)(TmpFilename), ".RTM"))) + { + RtnVal = TRUE; + } + return(RtnVal); +} + + +UWORD cCommInterprete(UBYTE *pInBuf, UBYTE *pOutBuf, UBYTE *pLength, UBYTE CmdBit, UWORD MsgLength) +{ + UWORD ReturnStatus; + UBYTE Channel; + + Channel = CHNumber(CmdBit); + if (FALSE == VarsComm.ExtMode[Channel].Status) + { + + switch (((pInBuf[0]) & ~NO_REPLY_BIT)) + { + case SYSTEM_CMD: + { + ReturnStatus = cCommInterpreteCmd(pInBuf[1], &(pInBuf[1]), &(pOutBuf[2]), pLength, CmdBit, MsgLength); + + /* Check if reply is requested */ + if ((pInBuf[0]) & NO_REPLY_BIT) + { + + /* Sender has choosen no reply */ + *pLength = 0; + + /* if extended mode then remember the reply bit */ + VarsComm.ExtMode[Channel].Type |= NO_REPLY_BIT; + } + else + { + + /* Check if receiver wants to reply */ + if (*pLength) + { + (*pLength)+= 2; + pOutBuf[0] = REPLY_CMD; + pOutBuf[1] = pInBuf[1]; + } + } + } + break; + + case DIRECT_CMD: + { + + /* Adjust length to account for cmd type byte */ + (*pLength) -= 1; + + /* If no reply requested, pass NULL output buffer pointer and clear *pLength */ + if ((pInBuf[0]) & NO_REPLY_BIT) + { + pMapCmd->pRCHandler(&(pInBuf[0]), NULL, pLength); + } + else + { + pMapCmd->pRCHandler(&(pInBuf[0]), &(pOutBuf[2]), pLength); + if (*pLength) + { + (*pLength) += 2; + pOutBuf[0] = REPLY_CMD; + pOutBuf[1] = pInBuf[1]; + } + } + } + break; + + case REPLY_CMD: + { + + /* If this is a reply to a direct command opcode, pRCHandler will handle it */ + if (pInBuf[1] < NUM_RC_OPCODES) + pMapCmd->pRCHandler(&(pInBuf[0]), NULL, pLength); + + /* No Reply ever required on REPLY_CMD messages */ + *pLength = 0; + } + break; + +#ifdef ARMDEBUG + case DEBUG_CMD: + { + ReturnStatus = cCommHandleDebug(&(pInBuf[0]), CmdBit, MsgLength); /* Pass everything (incl. message command byte) to function */ + /* Check that Debug Command does not expect reply */ + ReturnStatus = (0 == ((pInBuf[0]) & NO_REPLY_BIT)); + *pLength = 0; + } + break; +#endif + + default: + { + + /* UNSUPPORTED - don't reply on these messages */ + *pLength = 0; + } + break; + } + + } + else + { + switch (VarsComm.ExtMode[Channel].Type & ~NO_REPLY_BIT) + { + case SYSTEM_CMD: + { + ReturnStatus = cCommInterpreteCmd(VarsComm.ExtMode[Channel].Cmd, &(pInBuf[0]), &(pOutBuf[2]), pLength, CmdBit, MsgLength); + if ((VarsComm.ExtMode[Channel].Type) & NO_REPLY_BIT) + { + + /* Sender has choosen no reply */ + *pLength = 0; + } + else + { + + /* Check if receiver wants to reply */ + if (*pLength) + { + (*pLength) += 2; + pOutBuf[0] = REPLY_CMD; + pOutBuf[1] = VarsComm.ExtMode[Channel].Cmd; + } + } + } + break; + case DIRECT_CMD: + { + } + break; + case REPLY_CMD: + { + } + break; + default: + { + } + break; + } + } + + return(ReturnStatus); +} + + +UWORD cCommInterpreteCmd(UBYTE Cmd, UBYTE *pInBuf, UBYTE *pOutBuf, UBYTE *pLength, UBYTE CmdBit, UWORD MsgLength) +{ + ULONG FileLength; + UWORD Status; + UBYTE Channel; + + Channel = CHNumber(CmdBit); + switch(Cmd) + { + case OPENWRITE: + { + FileLength = pInBuf[21]; + FileLength += (ULONG)pInBuf[22] << 8; + FileLength += (ULONG)pInBuf[23] << 16; + FileLength += (ULONG)pInBuf[24] << 24; + + if(TRUE == cCommCheckSysFileType(&pInBuf[1])) + { + Status = pMapLoader->pFunc(OPENWRITELINEAR, &pInBuf[1], NULL, &FileLength); + } + else + { + Status = pMapLoader->pFunc(OPENWRITE, &pInBuf[1], NULL, &FileLength); + } + pOutBuf[0] = LOADER_ERR_BYTE(Status); + pOutBuf[1] = LOADER_HANDLE(Status); + *pLength = 2; + if ((SUCCESS == LOADER_ERR(Status)) && (CmdBit & USB_CMD_READY)) + { + dUsbInsertHandle(LOADER_HANDLE(Status)); + } + } + break; + case WRITE: + { + + if (FALSE == VarsComm.ExtMode[Channel].Status) + { + + FileLength = *pLength - 3; + Status = pMapLoader->pFunc(WRITE, &(pInBuf[1]), &(pInBuf[2]), &FileLength); + pOutBuf[2] = (UBYTE)(FileLength); + pOutBuf[3] = (UBYTE)(FileLength >> 8); + if ((*pLength != MsgLength) && (MsgLength != 0)) + { + + /* This is the beginnig of and extended write command*/ + VarsComm.ExtMode[Channel].Cmd = WRITE; + VarsComm.ExtMode[Channel].Type = SYSTEM_CMD; + VarsComm.ExtMode[Channel].Status = TRUE; + VarsComm.ExtMode[Channel].Handle = LOADER_HANDLE(Status); + *pLength = 0; + } + else + { + + /* Normal write */ + pOutBuf[0] = LOADER_ERR_BYTE(Status); + pOutBuf[1] = LOADER_HANDLE(Status); + *pLength = 4; + } + } + else + { + UWORD TmpLen; + FileLength = *pLength; + Status = pMapLoader->pFunc(WRITE, &(VarsComm.ExtMode[Channel].Handle), &(pInBuf[0]), &FileLength); + TmpLen = pOutBuf[3]; + TmpLen <<= 8; + TmpLen |= pOutBuf[2]; + TmpLen += FileLength; + pOutBuf[2] = (UBYTE)(TmpLen); + pOutBuf[3] = (UBYTE)(TmpLen >> 8); + if (MsgLength) + { + + /* Don't answer before complete message has been received */ + *pLength = 0; + } + else + { + + /* Complete msg has been received */ + VarsComm.ExtMode[Channel].Status = FALSE; + pOutBuf[0] = LOADER_ERR_BYTE(Status); + pOutBuf[1] = LOADER_HANDLE(Status); + *pLength = 4; /* Remember the 2 length bytes */ + + } + } + + } + break; + case OPENWRITEDATA: + { + FileLength = pInBuf[21]; + FileLength += (ULONG)pInBuf[22] << 8; + FileLength += (ULONG)pInBuf[23] << 16; + FileLength += (ULONG)pInBuf[24] << 24; + + if(TRUE == cCommCheckSysFileType(&pInBuf[1])) + { + Status = ILLEGALFILENAME; + } + else + { + Status = pMapLoader->pFunc(OPENWRITEDATA, &pInBuf[1], NULL, &FileLength); + } + pOutBuf[0] = LOADER_ERR_BYTE(Status); + pOutBuf[1] = LOADER_HANDLE(Status); + *pLength = 2; + if ((SUCCESS == LOADER_ERR(Status)) && (CmdBit & USB_CMD_READY)) + { + dUsbInsertHandle(LOADER_HANDLE(Status)); + } + } + break; + case OPENAPPENDDATA: + { + Status = pMapLoader->pFunc(OPENAPPENDDATA, &pInBuf[1], NULL, &FileLength); + pOutBuf[0] = LOADER_ERR_BYTE(Status); + pOutBuf[1] = LOADER_HANDLE(Status); + + pOutBuf[2] = (UBYTE)FileLength; + pOutBuf[3] = (UBYTE)(FileLength >> 8); + pOutBuf[4] = (UBYTE)(FileLength >> 16); + pOutBuf[5] = (UBYTE)(FileLength >> 24); + *pLength = 6; + if ((SUCCESS == LOADER_ERR(Status)) && (CmdBit & USB_CMD_READY)) + { + dUsbInsertHandle(LOADER_HANDLE(Status)); + } + } + break; + case CLOSE: + { + if (CmdBit & USB_CMD_READY) + { + dUsbRemoveHandle(pInBuf[1]); + } + Status = pMapLoader->pFunc(CLOSE, &(pInBuf[1]), NULL, &FileLength); + pOutBuf[0] = LOADER_ERR_BYTE(Status); + pOutBuf[1] = LOADER_HANDLE(Status); + *pLength = 2; + } + break; + case CROPDATAFILE: + { + Status = pMapLoader->pFunc(CROPDATAFILE, &(pInBuf[1]), NULL, &FileLength); + pOutBuf[0] = LOADER_ERR_BYTE(Status); + pOutBuf[1] = LOADER_HANDLE(Status); + *pLength = 2; + } + break; + case OPENREAD: + { + Status = pMapLoader->pFunc(OPENREAD, &pInBuf[1], NULL, &FileLength); + pOutBuf[0] = LOADER_ERR_BYTE(Status); + pOutBuf[1] = LOADER_HANDLE(Status); + pOutBuf[2] = (UBYTE)FileLength; + pOutBuf[3] = (UBYTE)(FileLength >> 8); + pOutBuf[4] = (UBYTE)(FileLength >> 16); + pOutBuf[5] = (UBYTE)(FileLength >> 24); + *pLength = 6; + if ((SUCCESS == LOADER_ERR(Status)) && (CmdBit & USB_CMD_READY)) + { + dUsbInsertHandle(LOADER_HANDLE(Status)); + } + } + break; + case READ: + { + ULONG Length; + + FileLength = pInBuf[3]; + FileLength <<= 8; + FileLength |= pInBuf[2]; + Length = FileLength; + + /* Here test for channel - USB can only handle a 64 byte return (- wrapping )*/ + if (CmdBit & USB_CMD_READY) + { + if (FileLength > (SIZE_OF_USBBUF - 6)) + { + + /* Buffer cannot hold the requested data adjust to buffer size */ + FileLength = (SIZE_OF_USBBUF - 6); + } + *pLength = FileLength + 4; + Status = pMapLoader->pFunc(READ, &pInBuf[1], &pOutBuf[4], &FileLength); + pOutBuf[0] = LOADER_ERR_BYTE(Status); + pOutBuf[1] = LOADER_HANDLE(Status); + pOutBuf[2] = (UBYTE)Length; + pOutBuf[3] = (UBYTE)(Length >> 8); + + if (FileLength < Length) + { + + /* End of file is detcted - add up with zeros to the requested msg length */ + Length -= FileLength; + memset(&(pOutBuf[(FileLength + 4)]),0x00,Length); + } + } + else + { + + /* This is a BT request - BT can handle large packets */ + if (FileLength > (SIZE_OF_BTBUF - 6)) + { + + /* Read length exceeds buffer length check for extended read back */ + if (SUCCESS == cCommReq(EXTREAD, 0x00, 0x00, 0x00, NULL, &(VarsComm.RetVal))) + { + + /* More data requested than buffer can hold .... go into extended mode */ + VarsComm.ExtTx.RemMsgSize = FileLength; + VarsComm.ExtTx.SrcHandle = pInBuf[1]; + VarsComm.ExtTx.Cmd = READ; + *pLength = 0; + } + else + { + + /* We were not able to go into extended mode bt was busy */ + /* for now do not try to reply as it is not possible to */ + /* return the requested bytes */ + *pLength = 0; + } + } + else + { + + *pLength = FileLength + 4; + Status = pMapLoader->pFunc(READ, &pInBuf[1], &pOutBuf[4], &FileLength); + pOutBuf[0] = LOADER_ERR_BYTE(Status); + pOutBuf[1] = LOADER_HANDLE(Status); + pOutBuf[2] = (UBYTE)Length; + pOutBuf[3] = (UBYTE)(Length >> 8); + + if (FileLength < Length) + { + + /* End of file is detcted - add up with zeros to the requested msg length */ + Length -= FileLength; + memset(&(pOutBuf[(FileLength + 4)]),0x00,Length); + } + } + } + } + break; + case DELETE: + { + Status = pMapLoader->pFunc(DELETE, &pInBuf[1], NULL, &FileLength); + pOutBuf[0] = LOADER_ERR_BYTE(Status); + cCommCopyFileName(&pOutBuf[1], &pInBuf[1]); + *pLength = FILENAME_LENGTH + 1 + 1; /*Filemname + 0 terminator + error byte */ + } + break; + case FINDFIRST: + { + Status = pMapLoader->pFunc(FINDFIRST, &(pInBuf[1]), &(pOutBuf[2]), &FileLength); + pOutBuf[0] = LOADER_ERR_BYTE(Status); + pOutBuf[1] = LOADER_HANDLE(Status); + if (LOADER_ERR_BYTE(SUCCESS) == pOutBuf[0]) + { + pOutBuf[22] = (UBYTE)FileLength; + pOutBuf[23] = (UBYTE)(FileLength >> 8); + pOutBuf[24] = (UBYTE)(FileLength >> 16); + pOutBuf[25] = (UBYTE)(FileLength >> 24); + if (CmdBit & USB_CMD_READY) + { + dUsbInsertHandle(pOutBuf[1]); + } + } + else + { + + /* ERROR - Fill with zeros */ + memset(&(pOutBuf[2]),0x00,24); + } + + *pLength = 26; + } + break; + case FINDNEXT: + { + Status = pMapLoader->pFunc(FINDNEXT, &(pInBuf[1]), &(pOutBuf[2]), &FileLength); + pOutBuf[0] = LOADER_ERR_BYTE(Status); + pOutBuf[1] = LOADER_HANDLE(Status); + if (LOADER_ERR_BYTE(SUCCESS) == pOutBuf[0]) + { + pOutBuf[22] = (UBYTE)FileLength; + pOutBuf[23] = (UBYTE)(FileLength >> 8); + pOutBuf[24] = (UBYTE)(FileLength >> 16); + pOutBuf[25] = (UBYTE)(FileLength >> 24); + } + else + { + + /* ERROR - Fill with zeros */ + memset(&(pOutBuf[2]),0x00,24); + } + *pLength = 26; + } + break; + case OPENREADLINEAR: + { + + /* For internal use only */ + } + break; + case VERSIONS: + { + pOutBuf[0] = LOADER_ERR_BYTE(SUCCESS); + pOutBuf[1] = (UBYTE)PROTOCOLVERSION; + pOutBuf[2] = (UBYTE)(PROTOCOLVERSION>>8); + pOutBuf[3] = (UBYTE)FIRMWAREVERSION; + pOutBuf[4] = (UBYTE)(FIRMWAREVERSION>>8); + *pLength = 5; + } + break; + case OPENWRITELINEAR: + { + FileLength = pInBuf[21]; + FileLength += (ULONG)pInBuf[22] << 8; + FileLength += (ULONG)pInBuf[23] << 16; + FileLength += (ULONG)pInBuf[24] << 24; + Status = pMapLoader->pFunc(OPENWRITELINEAR, &pInBuf[1], NULL, &FileLength); + pOutBuf[0] = LOADER_ERR_BYTE(Status); + pOutBuf[1] = LOADER_HANDLE(Status); + *pLength = 2; + if ((SUCCESS == LOADER_ERR(Status)) && (CmdBit & USB_CMD_READY)) + { + dUsbInsertHandle(LOADER_HANDLE(Status)); + } + } + break; + case FINDFIRSTMODULE: + { + Status = pMapLoader->pFunc(FINDFIRSTMODULE, &pInBuf[1], &pOutBuf[2], &FileLength); + pOutBuf[0] = LOADER_ERR_BYTE(Status); + pOutBuf[1] = 0; + + if (LOADER_ERR_BYTE(SUCCESS) != pOutBuf[0]) + { + memset(&pOutBuf[2], 0x00, 30); + } + *pLength = 32; + } + break; + + case FINDNEXTMODULE: + { + Status = pMapLoader->pFunc(FINDNEXTMODULE, pInBuf, &pOutBuf[2], &FileLength); + pOutBuf[0] = LOADER_ERR_BYTE(Status); + pOutBuf[1] = 0; + + if (LOADER_ERR_BYTE(SUCCESS) != pOutBuf[0]) + { + memset(&pOutBuf[2], 0x00, 30); + } + *pLength = 32; + } + break; + + case CLOSEMODHANDLE: + { + Status = pMapLoader->pFunc(CLOSEMODHANDLE, NULL, NULL, NULL); + pOutBuf[0] = LOADER_ERR_BYTE(Status); + pOutBuf[1] = 0; + *pLength = 2; + } + break; + + case IOMAPREAD: + { + ULONG ModuleId; + UWORD Length; + + ModuleId = pInBuf[1]; + ModuleId |= (ULONG)pInBuf[2] << 8; + ModuleId |= (ULONG)pInBuf[3] << 16; + ModuleId |= (ULONG)pInBuf[4] << 24; + + /* Transfer the Module id */ + pOutBuf[1] = pInBuf[1]; + pOutBuf[2] = pInBuf[2]; + pOutBuf[3] = pInBuf[3]; + pOutBuf[4] = pInBuf[4]; + + /* Transfer the offset into the iomap (pOutBuf[6] is intended...)*/ + pOutBuf[5] = pInBuf[5]; + pOutBuf[6] = pInBuf[6]; + + /* Get the read *pLength */ + FileLength = pInBuf[8]; + FileLength <<= 8; + FileLength |= pInBuf[7]; + + if (CmdBit & USB_CMD_READY) + { + + /* test for USB buffer overrun */ + if (FileLength > (SIZE_OF_USBBUF - 9)) + { + FileLength = SIZE_OF_USBBUF - 9; + } + } + else + { + + /* test for BT buffer overrun */ + if (FileLength > (SIZE_OF_BTBUF - 9)) + { + FileLength = SIZE_OF_BTBUF - 9; + } + } + + Length = FileLength; + *pLength = Length + 7; + Status = pMapLoader->pFunc(IOMAPREAD, (UBYTE *)&ModuleId, &pOutBuf[5], &FileLength); + + pOutBuf[0] = LOADER_ERR_BYTE(Status); + pOutBuf[5] = (UBYTE)FileLength; + pOutBuf[6] = (UBYTE)(FileLength >> 8); + + if (Length > FileLength) + { + Length -= FileLength; + memset(&(pOutBuf[FileLength + 7]), 0x00, Length); + } + } + break; + + case IOMAPWRITE: + { + ULONG ModuleId; + + pOutBuf[1] = pInBuf[1]; + pOutBuf[2] = pInBuf[2]; + pOutBuf[3] = pInBuf[3]; + pOutBuf[4] = pInBuf[4]; + + ModuleId = pInBuf[1]; + ModuleId |= (ULONG)pInBuf[2] << 8; + ModuleId |= (ULONG)pInBuf[3] << 16; + ModuleId |= (ULONG)pInBuf[4] << 24; + + FileLength = pInBuf[8]; + FileLength <<= 8; + FileLength |= pInBuf[7]; + + /* Place offset right before data */ + pInBuf[8] = pInBuf[6]; + pInBuf[7] = pInBuf[5]; + + Status = pMapLoader->pFunc(IOMAPWRITE, (UBYTE *)&ModuleId, &pInBuf[7], &FileLength); + + pOutBuf[0] = LOADER_ERR_BYTE(Status); + pOutBuf[5] = (UBYTE)FileLength; + pOutBuf[6] = (UBYTE)(FileLength >> 8); + + *pLength = 7; + } + break; + + case BOOTCMD: + { + + UBYTE Tmp; + + /* The boot command is only allowed by USB - as firmware download can ONLY */ + /* be send by USB */ + pOutBuf[0] = LOADER_ERR_BYTE(UNDEFINEDERROR); + memset(&(pOutBuf[1]), 0, 4); + *pLength = 5; + + if (CmdBit & USB_CMD_READY) + { + + Tmp = 0; + while((Tmp < (sizeof(BootString) - 1)) && (BootString[Tmp] == pInBuf[Tmp+1])) + { + Tmp++; + } + if (Tmp == (sizeof(BootString) - 1)) + { + + /* Yes valid boot sequence */ + pMapDisplay->Flags &= ~DISPLAY_ON; + pMapDisplay->Flags |= DISPLAY_REFRESH; + pMapIoCtrl->PowerOn = BOOT; + pOutBuf[0] = LOADER_ERR_BYTE(SUCCESS); + pOutBuf[1] = 'Y'; + pOutBuf[2] = 'e'; + pOutBuf[3] = 's'; + pOutBuf[4] = '\0'; + } + } + } + break; + + case SETBRICKNAME: + { + + UWORD RtnVal; + + *pLength = 1; + + /* Update the name in the BT device - reply for this command is send */ + /* before command is actually executed */ + if (SUCCESS == cCommReq(SETBTNAME, 0, 0, 0, &pInBuf[1], &RtnVal)) + { + pOutBuf[0] = LOADER_ERR_BYTE(SUCCESS); + cCommInsertBtName(IOMapComm.BrickData.Name, &pInBuf[1]); + pMapUi->Flags |= UI_REDRAW_STATUS; + } + else + { + pOutBuf[0] = LOADER_ERR_BYTE(BTBUSY); + } + } + break; + + case BTGETADR: + { + UBYTE Tmp; + UBYTE *pAdr; + + pAdr = (IOMapComm.BrickData.BdAddr); + for (Tmp = 0; Tmp < 7; Tmp++) + { + pOutBuf[Tmp + 1] = pAdr[Tmp]; + } + pOutBuf[0] = LOADER_ERR_BYTE(SUCCESS); + *pLength = 8; + } + break; + + case DEVICEINFO: + { + + pOutBuf[0] = LOADER_ERR_BYTE(SUCCESS); + + /* Brick name */ + memcpy(&(pOutBuf[1]), IOMapComm.BrickData.Name, 15); + + /* BT address */ + cCommCopyBdaddr(&(pOutBuf[16]), (IOMapComm.BrickData.BdAddr)); + + /* Link quality of the 4 possible connected devices */ + pOutBuf[23] = IOMapComm.BtConnectTable[0].LinkQuality; + pOutBuf[24] = IOMapComm.BtConnectTable[1].LinkQuality; + pOutBuf[25] = IOMapComm.BtConnectTable[2].LinkQuality; + pOutBuf[26] = IOMapComm.BtConnectTable[3].LinkQuality; + + /* Free user flash */ + memcpy(&(pOutBuf[27]), &(pMapLoader->FreeUserFlash), sizeof(pMapLoader->FreeUserFlash)); + + /* Set answer length */ + *pLength = 31; + } + break; + + case DELETEUSERFLASH: + { + Status = pMapLoader->pFunc(DELETEUSERFLASH, NULL, NULL, NULL); + pOutBuf[0] = LOADER_ERR_BYTE(SUCCESS); + *pLength = 1; + } + break; + + case POLLCMDLEN: + { + + pOutBuf[0] = LOADER_ERR_BYTE(SUCCESS); + pOutBuf[1] = pInBuf[1]; /* This is the Buf Number */ + if (0 == pInBuf[1]) + { + + /* USB poll buffer */ + pOutBuf[2] = ((IOMapComm.UsbPollBuf.InPtr - IOMapComm.UsbPollBuf.OutPtr) & (SIZE_OF_USBBUF - 1)); + } + else + { + + /* HI speed poll buffer */ + pOutBuf[2] = ((IOMapComm.HsInBuf.InPtr - IOMapComm.HsInBuf.OutPtr) & (SIZE_OF_HSBUF - 1)); + } + *pLength = 3; + } + break; + + case POLLCMD: + { + UBYTE Tmp; + UBYTE MaxBufData; + + pOutBuf[0] = LOADER_ERR_BYTE(SUCCESS); + pOutBuf[1] = pInBuf[1]; + *pLength = pInBuf[2]; + + if (CmdBit & USB_CMD_READY) + { + MaxBufData = (SIZE_OF_USBDATA - 5); /* Substract wrapping */ + } + else + { + MaxBufData = (SIZE_OF_BTBUF - 7); /* Substract wrapping + length bytes for BT*/ + } + + if (0x00 == pInBuf[1]) + { + + /* Data from USB poll buffer are requested */ + if (*pLength <= MaxBufData) + { + for (Tmp = 0; ((Tmp < (*pLength)) && (IOMapComm.UsbPollBuf.InPtr != IOMapComm.UsbPollBuf.OutPtr)); Tmp++) + { + pOutBuf[3 + Tmp] = IOMapComm.UsbPollBuf.Buf[IOMapComm.UsbPollBuf.OutPtr]; + IOMapComm.UsbPollBuf.OutPtr = ((IOMapComm.UsbPollBuf.OutPtr) + 1) % SIZE_OF_USBBUF; + } + pOutBuf[2] = Tmp; + + /* if end of buffer has been reached fill up with zeros */ + memset(&(pOutBuf[Tmp + 3]), 0x00, (*pLength - Tmp)); + } + else + { + + /* if more data requested than possible to return */ + pOutBuf[0] = LOADER_ERR_BYTE(UNDEFINEDERROR); + pOutBuf[1] = pInBuf[1]; /* This is buffer number */ + pOutBuf[2] = 0; /* no of bytes returned */ + *pLength = 0; + } + } + else + { + + /* Data from hi speed buffer are requested */ + if (*pLength <= MaxBufData) + { + for (Tmp = 0; ((Tmp < (*pLength)) && (IOMapComm.HsInBuf.InPtr != IOMapComm.HsInBuf.OutPtr)); Tmp++) + { + pOutBuf[3 + Tmp] = IOMapComm.HsInBuf.Buf[IOMapComm.HsInBuf.OutPtr]; + IOMapComm.HsInBuf.OutPtr = ((IOMapComm.HsInBuf.OutPtr) + 1) % SIZE_OF_USBBUF; + } + pOutBuf[2] = Tmp; + + /* if end of buffer has been reached fill up with zeros */ + memset(&(pOutBuf[Tmp + 3]), 0x00, (*pLength - Tmp)); + } + else + { + + /* if more data requested than possible to return */ + pOutBuf[0] = LOADER_ERR_BYTE(UNDEFINEDERROR); + pOutBuf[1] = pInBuf[1]; /* This is buffer number */ + pOutBuf[2] = 0; /* no of bytes returned */ + *pLength = 0; + } + } + (*pLength) += 3; /* Add 3 bytes for the status byte, length byte and Buf no */ + } + break; + + case BTFACTORYRESET: + { + UWORD RtnVal; + + if (CmdBit & USB_CMD_READY) + { + if (SUCCESS == cCommReq(FACTORYRESET, 0, 0, 0, NULL, &RtnVal)) + { + + /* Request success */ + pOutBuf[0] = LOADER_ERR_BYTE(SUCCESS); + } + else + { + + /* BT request error */ + pOutBuf[0] = LOADER_ERR_BYTE(UNDEFINEDERROR); + } + } + else + { + + /* Factory reset request cannot be done by bluetooth */ + pOutBuf[0] = LOADER_ERR_BYTE(UNDEFINEDERROR); + } + *pLength = 1; + } + break; + + default: + { + } + break; + } + return(Status); +} + + +UWORD cCommReceivedBtData(void) +{ + UWORD NumberOfBytes; + UWORD BytesToGo; + UWORD RtnVal; + + RtnVal = dBtReceivedData(&NumberOfBytes, &BytesToGo); + if (TRUE == RtnVal) + { + + /* Everything is fine go on */ + if (NumberOfBytes != 0) + { + + /* Copy the bytes into the IOMapBuffer */ + memcpy((IOMapComm.BtInBuf.Buf), (VarsComm.BtModuleInBuf.Buf), NumberOfBytes); + + if (VarsComm.BtState == BT_ARM_CMD_MODE) + { + + /* Call the BC4 command interpreter */ + cCommBtCmdInterpreter(); + IOMapComm.BtInBuf.InPtr = 0; + } + else + { + + /* ActiveUpdate has to be idle because BC4 can send stream data even if CMD */ + /* mode has been requested - dont try to interprete the data */ + /* VarsComm.CmdSwitchCnt != 0 if a transition to Cmd mode is in process */ + if ((VarsComm.BtState == BT_ARM_DATA_MODE) && (0 == VarsComm.CmdSwitchCnt)) + { + + /* Move the inptr ahead */ + IOMapComm.BtInBuf.InPtr = NumberOfBytes; + + /* using the outbuf inptr in order to get the number of bytes in the return answer at the right place*/ + IOMapComm.BtOutBuf.InPtr = NumberOfBytes; + + /* call the data stream interpreter */ + cCommInterprete(IOMapComm.BtInBuf.Buf, IOMapComm.BtOutBuf.Buf, &(IOMapComm.BtOutBuf.InPtr), (UBYTE) BT_CMD_READY, BytesToGo); + + /* if there is a reply to be send then send it */ + if (IOMapComm.BtOutBuf.InPtr) + { + dBtSendMsg(IOMapComm.BtOutBuf.Buf, IOMapComm.BtOutBuf.InPtr, IOMapComm.BtOutBuf.InPtr); + IOMapComm.BtOutBuf.InPtr = 0; + } + } + } + } + } + return(RtnVal); +} + +void cCommBtCmdInterpreter(void) +{ + + /* this function handles all bluecode commands that can be */ + /* initiated from the outside, meaning from other devices */ + if(cCommBtValidateCmd()) + { + switch (IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) + { + case MSG_REQUEST_PIN_CODE: + { + + /* Pass the pin request on to cCommReq it'l handle it */ + cCommReq(PINREQ, 0x00, 0x00, 0x00, NULL, &(VarsComm.RetVal)); + } + break; + + case MSG_REQUEST_CONNECTION: + { + + /* Connect request from the outside */ + cCommReq(CONNECTREQ, 0x00, 0x00, 0x00, NULL, &(VarsComm.RetVal)); + } + break; + + case MSG_LIST_RESULT: + { + switch (IOMapComm.BtInBuf.Buf[2]) + { + case LR_SUCCESS: + { + } + break; + case LR_ENTRY_REMOVED: + { + } + break; +/* + case LR_COULD_NOT_SAVE: + case LR_STORE_IS_FULL: + case LR_UNKOWN_ADDR: +*/ + default: + { + pMapUi->Error = (UBYTE)IOMapComm.BtInBuf.Buf[2]; + pMapUi->BluetoothState |= BT_ERROR_ATTENTION; + } + break; + } + } + break; + + case MSG_CLOSE_CONNECTION_RESULT: + { + UBYTE ConnNo; + + for (ConnNo = 0; ConnNo < SIZE_OF_BT_CONNECT_TABLE; ConnNo++) + { + if (IOMapComm.BtConnectTable[ConnNo].HandleNr == IOMapComm.BtInBuf.Buf[3]) + { + IOMapComm.BrickData.BtStateStatus &= ~(BT_CONNECTION_0_ENABLE<BluetoothState &= ~BT_STATE_CONNECTED; + } + pMapUi->Flags |= UI_REDRAW_STATUS; + } + break; + + case MSG_PORT_OPEN_RESULT: + { + if (IOMapComm.BtInBuf.Buf[2] == 1) + { + IOMapComm.BtConnectTable[0].HandleNr = IOMapComm.BtInBuf.Buf[3]; + IOMapComm.BrickData.BtStateStatus |= BT_BRICK_PORT_OPEN; + } + else + { + + /* There was an error setting up the OpenPort command in BC4 */ + IOMapComm.BtConnectTable[0].HandleNr = BLUETOOTH_HANDLE_UNDEFIEND; + IOMapComm.BrickData.BtStateStatus &= ~BT_BRICK_PORT_OPEN; + } + } + break; + + case MSG_CLOSE_PORT_RESULT: + { + if (IOMapComm.BtInBuf.Buf[2] == 1) + { + IOMapComm.BtConnectTable[0].HandleNr = BLUETOOTH_HANDLE_UNDEFIEND; + IOMapComm.BrickData.BtStateStatus &= ~BT_BRICK_PORT_OPEN; + } + } + break; + + case MSG_PIN_CODE_ACK: + { + pMapUi->BluetoothState &= ~BT_PIN_REQUEST; + } + break; + + case MSG_DISCOVERABLE_ACK: + { + if (VarsComm.BtCmdData.ParamOne == 1) + { + IOMapComm.BrickData.BtStateStatus |= BT_BRICK_VISIBILITY; + pMapUi->BluetoothState |= BT_STATE_VISIBLE; + } + else + { + IOMapComm.BrickData.BtStateStatus &= ~BT_BRICK_VISIBILITY; + pMapUi->BluetoothState &= ~BT_STATE_VISIBLE; + } + } + break; + case MSG_RESET_INDICATION: + { + if ((UPD_RESET != VarsComm.ActiveUpdate) && + (UPD_BRICKNAME != VarsComm.ActiveUpdate) && + (UPD_FACTORYRESET != VarsComm.ActiveUpdate)) + { + + /* Not intended reset indication - restart the bluecore */ + if (VarsComm.ActiveUpdate != UPD_IDLE) + { + + /* Something was ongoing send error message */ + *(VarsComm.pRetVal) = (UWORD)ERR_COMM_BUS_ERR; + *(VarsComm.pRetVal) |= 0x8000; + } + + SETBtStateIdle; + VarsComm.pRetVal = &(VarsComm.RetVal); + VarsComm.ActiveUpdate = UPD_RESET; + } + } + break; + } + } + else + { + /* Receive a message with wrong checkSum ! */ + } +} + +void cCommCpyToUpper(UBYTE *pDst, UBYTE *pSrc, UBYTE Length) +{ + UBYTE Tmp; + + for(Tmp = 0; Tmp < Length; Tmp++) + { + pDst[Tmp] =(UBYTE)toupper((UWORD)pSrc[Tmp]); + } + + /* The requried length has been copied - now fill with zeros */ + for(Tmp = Length; Tmp < (FILENAME_LENGTH + 1); Tmp++) + { + pDst[Tmp] = '\0'; + } +} + +void cCommCopyFileName(UBYTE *pDst, UBYTE *pSrc) +{ + UBYTE Tmp; + + for(Tmp = 0; Tmp < (FILENAME_LENGTH + 1); Tmp++, pDst++) + { + if ('\0' != *pSrc) + { + *pDst = *pSrc; + pSrc++; + } + else + { + *pDst = '\0'; + } + } +} + +void cCommSendHiSpeedData(void) +{ + VarsComm.HsModuleOutBuf.OutPtr = 0; + for (VarsComm.HsModuleOutBuf.InPtr = 0; VarsComm.HsModuleOutBuf.InPtr < IOMapComm.HsOutBuf.InPtr; VarsComm.HsModuleOutBuf.InPtr++) + { + VarsComm.HsModuleOutBuf.Buf[VarsComm.HsModuleOutBuf.InPtr] = IOMapComm.HsOutBuf.Buf[IOMapComm.HsOutBuf.OutPtr]; + IOMapComm.HsOutBuf.OutPtr++; + } + dHiSpeedSendData(VarsComm.HsModuleOutBuf.Buf, (VarsComm.HsModuleOutBuf.InPtr - VarsComm.HsModuleOutBuf.OutPtr)); +} + +void cCommReceivedHiSpeedData(void) +{ + UWORD NumberOfBytes; + UWORD Tmp; + + dHiSpeedReceivedData(&NumberOfBytes); + + if (NumberOfBytes != 0) + { + for (Tmp = 0; Tmp < NumberOfBytes; Tmp++) + { + IOMapComm.HsInBuf.Buf[IOMapComm.HsInBuf.InPtr] = VarsComm.HsModuleInBuf.Buf[Tmp]; + IOMapComm.HsInBuf.InPtr++; + if (IOMapComm.HsInBuf.InPtr > (SIZE_OF_HSBUF - 1)) + { + IOMapComm.HsInBuf.InPtr = 0; + } + VarsComm.HsModuleInBuf.Buf[Tmp] = 0; + } + + /* Now new data is available from the HIGH SPEED port ! */ + } +} + +UBYTE cCommBtValidateCmd(void) +{ + UWORD CheckSumTmp = 0; + UBYTE Tmp, CheckSumHigh, CheckSumLow; + + for (Tmp = 0; Tmp < (IOMapComm.BtInBuf.Buf[0] - 1);Tmp++) + { + CheckSumTmp += IOMapComm.BtInBuf.Buf[Tmp]; + } + CheckSumTmp = (UWORD) (1 + (0xFFFF - CheckSumTmp)); + CheckSumHigh = (UBYTE)((CheckSumTmp & 0xFF00)>>8); + CheckSumLow = (UBYTE)(CheckSumTmp & 0x00FF); + + if ((CheckSumHigh == IOMapComm.BtInBuf.Buf[IOMapComm.BtInBuf.Buf[0] - 1]) && (CheckSumLow == IOMapComm.BtInBuf.Buf[IOMapComm.BtInBuf.Buf[0]])) + { + return(TRUE); + } + else + { + return(FALSE); + } +} + +void cCommClearStreamStatus(void) +{ + IOMapComm.BtConnectTable[0].StreamStatus = 0; + IOMapComm.BtConnectTable[1].StreamStatus = 0; + IOMapComm.BtConnectTable[2].StreamStatus = 0; + IOMapComm.BtConnectTable[3].StreamStatus = 0; +} + +void cCommUpdateBt(void) +{ + UBYTE Tmp, Tmp2, Handle; + + Tmp = 0; + Tmp2 = 0; + + switch(VarsComm.ActiveUpdate) + { + case UPD_RESET: + { + + switch(VarsComm.UpdateState) + { + case 0: + { + /* Setup Reset sequence */ + pMapUi->BluetoothState = BT_STATE_OFF; + VarsComm.UpdateState = 1; + } + break; + + case 1: + { + cCommsBtReset(&(VarsComm.UpdateState)); + } + break; + + case 2: + { + (VarsComm.UpdateState)++; + dBtSendBtCmd((UBYTE)MSG_GET_LOCAL_ADDR, 0, 0, NULL, NULL, NULL, NULL); + } + break; + + case 3: + { + if (MSG_GET_LOCAL_ADDR_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) + { + cCommCopyBdaddr((IOMapComm.BrickData.BdAddr), &(IOMapComm.BtInBuf.Buf[BT_CMD_BYTE + 1])); + dUsbStoreBtAddress( &(IOMapComm.BtInBuf.Buf[BT_CMD_BYTE + 1])); + dBtSendBtCmd((UBYTE)MSG_GET_FRIENDLY_NAME, 0, 0, NULL, NULL, NULL, NULL); + VarsComm.BtAdrStatus = INITIALIZED; + (VarsComm.UpdateState)++; + } + } + break; + + case 4: + { + if (MSG_GET_FRIENDLY_NAME_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) + { + memcpy(IOMapComm.BrickData.Name, &(IOMapComm.BtInBuf.Buf[BT_CMD_BYTE + 1]), SIZE_OF_BRICK_NAME); + pMapUi->Flags |= UI_REDRAW_STATUS; + IOMapComm.BtDeviceCnt = 0; + IOMapComm.BtDeviceNameCnt = 0; + dBtSendBtCmd((UBYTE)MSG_DUMP_LIST, 0, 0, NULL, NULL, NULL, NULL); + (VarsComm.UpdateState)++; + } + } + break; + + case 5: + { + if (MSG_LIST_ITEM == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) + { + cCommCopyBdaddr((IOMapComm.BtDeviceTable[IOMapComm.BtDeviceCnt].BdAddr), &(IOMapComm.BtInBuf.Buf[2])); + cCommInsertBtName(IOMapComm.BtDeviceTable[IOMapComm.BtDeviceCnt].Name, &(IOMapComm.BtInBuf.Buf[9])); + IOMapComm.BtDeviceTable[IOMapComm.BtDeviceCnt].DeviceStatus = BT_DEVICE_KNOWN; + + memcpy(IOMapComm.BtDeviceTable[IOMapComm.BtDeviceCnt].ClassOfDevice, &(IOMapComm.BtInBuf.Buf[9+SIZE_OF_BT_NAME]), sizeof(IOMapComm.BtDeviceTable[IOMapComm.BtDeviceCnt].ClassOfDevice)); + + IOMapComm.BtDeviceCnt++; + IOMapComm.BtDeviceNameCnt++; + } + + if (MSG_LIST_DUMP_STOPPED == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) + { + dBtSendBtCmd((UBYTE)MSG_GET_VERSION, 0, 0, NULL, NULL, NULL, NULL); + (VarsComm.UpdateState)++; + } + IOMapComm.BtInBuf.Buf[BT_CMD_BYTE] = 0; + } + break; + + case 6: + { + if (MSG_GET_VERSION_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) + { + + IOMapComm.BrickData.BluecoreVersion[0] = IOMapComm.BtInBuf.Buf[3]; + IOMapComm.BrickData.BluecoreVersion[1] = IOMapComm.BtInBuf.Buf[2]; + + /* BtHwStatus indicates cold boot or user interaction */ + if (BT_DISABLE == IOMapComm.BrickData.BtHwStatus) + { + + /* This is from brick turning on */ + dBtSendBtCmd((UBYTE)MSG_GET_BRICK_STATUSBYTE, 0, 0, NULL, NULL, NULL, NULL); + } + else + { + + /* this is user interaction setting the brick on */ + dBtSendBtCmd((UBYTE)MSG_SET_BRICK_STATUSBYTE, BT_ENABLE, 0, NULL, NULL, NULL, NULL); + } + (VarsComm.UpdateState)++; + pMapUi->Flags |= UI_REDRAW_STATUS; + } + } + break; + + case 7: + { + if (MSG_GET_BRICK_STATUSBYTE_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) + { + IOMapComm.BrickData.TimeOutValue = IOMapComm.BtInBuf.Buf[BT_CMD_BYTE + 2]; + + /* Check for brick to be on or off */ + if (BT_ENABLE == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE + 1]) + { + pMapUi->BluetoothState &= ~BT_STATE_OFF; + IOMapComm.BrickData.BtHwStatus = BT_ENABLE; + dBtSendBtCmd((UBYTE)MSG_GET_DISCOVERABLE, 0, 0, NULL, NULL, NULL, NULL); + (VarsComm.UpdateState)++; + } + else + { + SETBtOff; + IOMapComm.BrickData.BtHwStatus = BT_ENABLE; + SETBtStateIdle; + *(VarsComm.pRetVal) = SUCCESS; + } + } + if (MSG_SET_BRICK_STATUSBYTE_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) + { + + /* brick to be on*/ + pMapUi->BluetoothState &= ~BT_STATE_OFF; + IOMapComm.BrickData.BtHwStatus = BT_ENABLE; + dBtSendBtCmd((UBYTE)MSG_GET_DISCOVERABLE, 0, 0, NULL, NULL, NULL, NULL); + (VarsComm.UpdateState)++; + } + } + break; + + case 8: + { + if (MSG_GET_DISCOVERABLE_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) + { + if (IOMapComm.BtInBuf.Buf[2] & 0x01) + { + IOMapComm.BrickData.BtStateStatus |= BT_BRICK_VISIBILITY; + pMapUi->BluetoothState |= BT_STATE_VISIBLE; + } + else + { + IOMapComm.BrickData.BtStateStatus &= ~BT_BRICK_VISIBILITY; + pMapUi->BluetoothState &= ~BT_STATE_VISIBLE; + } + dBtSendBtCmd((UBYTE)MSG_OPEN_PORT, 0, 0, NULL, NULL, NULL, NULL); + (VarsComm.UpdateState)++; + } + } + break; + + case 9: + { + + if (MSG_PORT_OPEN_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) + { + if (IOMapComm.BtInBuf.Buf[BT_CMD_BYTE + 1] & 0x01) + { + IOMapComm.BrickData.BtStateStatus |= BT_BRICK_PORT_OPEN; + } + else + { + IOMapComm.BrickData.BtStateStatus &= ~BT_BRICK_PORT_OPEN; + } + + SETBtStateIdle; + *(VarsComm.pRetVal) = SUCCESS; + } + } + break; + } + } + break; + + case UPD_FACTORYRESET: + { + switch(VarsComm.UpdateState) + { + + case 0: + { + if (BT_STATE_OFF & (pMapUi->BluetoothState)) + { + + /* Bluetooth is off - now start it up */ + (VarsComm.UpdateState)++; + } + else + { + + /* BT is already on - continue */ + (VarsComm.UpdateState) += 2; + } + } + break; + case 1: + { + cCommsBtReset(&(VarsComm.UpdateState)); + } + break; + case 2: + { + cCommsSetCmdMode(&(VarsComm.UpdateState)); + } + break; + case 3: + { + cCommsDisconnectAll(&(VarsComm.UpdateState)); + } + break; + case 4: + { + + /* Now bc4 is in cmd mode now factory can be sent */ + /* Just leave the BC4 in cmd mode */ + dBtSendBtCmd((UBYTE)MSG_SET_FACTORY_SETTINGS, 0, 0, NULL, NULL, NULL, NULL); + (VarsComm.UpdateState)++; + } + break; + case 5: + { + if (MSG_SET_FACTORY_SETTINGS_ACK == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) + { + SETBtStateIdle; + IOMapComm.BrickData.BtHwStatus = BT_DISABLE; /* Boot BT like cold boot*/ + VarsComm.ActiveUpdate = UPD_RESET; + } + } + break; + } + } + break; + + case UPD_BRICKNAME: + { + switch(VarsComm.UpdateState) + { + case 0: + { + + if (BT_STATE_OFF & (pMapUi->BluetoothState)) + { + + /* Bluetooth is off - now start it up */ + (VarsComm.UpdateState)++; + } + else + { + VarsComm.UpdateState = 2; + } + } + break; + + case 1: + { + cCommsBtReset(&(VarsComm.UpdateState)); + } + break; + + case 2: + { + VarsComm.BtUpdateDataConnectNr = 0; + if (BT_ARM_DATA_MODE == VarsComm.BtState) + { + for (Tmp = 0; Tmp < SIZE_OF_BT_CONNECT_TABLE; Tmp++) + { + if (IOMapComm.BtConnectTable[Tmp].StreamStatus) + { + VarsComm.BtUpdateDataConnectNr = Tmp | 0x80; + } + } + (VarsComm.UpdateState)++; + } + else + { + (VarsComm.UpdateState) += 2; + } + } + break; + + case 3: + { + cCommsSetCmdMode(&(VarsComm.UpdateState)); + } + break; + + case 4: + { + + /* Brick name has been updated prior to this */ + dBtSendBtCmd((UBYTE)MSG_SET_FRIENDLY_NAME, 0, 0, NULL, IOMapComm.BrickData.Name, NULL, NULL); + (VarsComm.UpdateState)++; + } + break; + + case 5: + { + if (MSG_SET_FRIENDLY_NAME_ACK == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) + { + + /* Set name has been executed */ + if (VarsComm.BtUpdateDataConnectNr & 0x80) + { + dBtSendBtCmd((UBYTE)MSG_OPEN_STREAM, IOMapComm.BtConnectTable[(VarsComm.BtUpdateDataConnectNr & ~0x80)].HandleNr, + 0, NULL, NULL, NULL, NULL); + (VarsComm.UpdateState)++; + } + else + { + if (BT_STATE_OFF & (pMapUi->BluetoothState)) + { + SETBtOff; + } + SETBtStateIdle; + *(VarsComm.pRetVal) = SUCCESS; + } + pMapUi->Flags |= UI_REDRAW_STATUS; + } + } + break; + case 6: + { + if (VarsComm.BtBcPinLevel) + { + IOMapComm.BtConnectTable[(VarsComm.BtUpdateDataConnectNr & ~0x80)].StreamStatus = 1; + *(VarsComm.pRetVal) = SUCCESS; + SETBtDataState; + SETBtStateIdle; + } + } + break; + } + } + break; + + case UPD_REQCMDMODE: + { + switch(VarsComm.UpdateState) + { + case 0: + { + cCommsSetCmdMode(&(VarsComm.UpdateState)); + } + break; + case 1: + { + *(VarsComm.pRetVal) = SUCCESS; + SETBtStateIdle; + } + break; + } + } + break; + + case UPD_OPENSTREAM: + { + switch(VarsComm.UpdateState) + { + case 0: + { + cCommsOpenStream(&(VarsComm.UpdateState)); + } + break; + + case 1: + { + *(VarsComm.pRetVal) = SUCCESS; + SETBtStateIdle; + } + break; + } + } + break; + + case UPD_SENDFILE: + { + switch (VarsComm.UpdateState) + { + case 0: + { + cCommsOpenStream(&(VarsComm.UpdateState)); + } + break; + + case 1: + { + + /* Here we wait for the open stream to succeed*/ + if (IOMapComm.BtConnectTable[VarsComm.ExtTx.SlotNo].StreamStatus) + { + + /* Stream has been opened send the openwrite command */ + VarsComm.BtModuleOutBuf.Buf[0] = SYSTEM_CMD; + VarsComm.BtModuleOutBuf.Buf[1] = OPENWRITE; + memcpy((UBYTE*)&(VarsComm.BtModuleOutBuf.Buf[2]),(UBYTE*)VarsComm.ExtTx.FileName, FILENAME_LENGTH + 1); + memcpy((UBYTE*)&(VarsComm.BtModuleOutBuf.Buf[22]),(UBYTE*)&(VarsComm.ExtTx.RemFileSize), sizeof(VarsComm.ExtTx.RemFileSize)); + dBtSendMsg(VarsComm.BtModuleOutBuf.Buf, 26, 26); + + VarsComm.ExtTx.Timer = 0; + VarsComm.UpdateState = 2; + + } + else + { + if (VarsComm.ExtTx.Timer >= FILETXTOUT) + { + *(VarsComm.pRetVal) = FILETX_STREAMERROR; + VarsComm.UpdateState = 8; + } + else + { + (VarsComm.ExtTx.Timer)++; + } + } + } + break; + + case 2: + { + + if (4 == IOMapComm.BtInBuf.InPtr) + { + + /* Data has been received - examine the answer */ + if ((REPLY_CMD == IOMapComm.BtInBuf.Buf[0]) && (OPENWRITE == IOMapComm.BtInBuf.Buf[1])) + { + + /* OpenWrite answer */ + if (LOADER_ERR_BYTE(SUCCESS) == IOMapComm.BtInBuf.Buf[2]) + { + + /* save the handle from the other brick */ + VarsComm.ExtTx.DstHandle = IOMapComm.BtInBuf.Buf[3]; + VarsComm.UpdateState = 3; + IOMapComm.BtInBuf.InPtr = 0; + } + else + { + + /* Open write failiure - terminate file transfer */ + *(VarsComm.pRetVal) = IOMapComm.BtInBuf.Buf[2]; + VarsComm.UpdateState = 8; + } + } + } + + if (VarsComm.ExtTx.Timer >= FILETXTOUT) + { + *(VarsComm.pRetVal) = FILETX_TIMEOUT; + VarsComm.UpdateState = 8; + } + else + { + (VarsComm.ExtTx.Timer)++; + } + } + break; + + case 3: /*SENDWRITE:*/ + { + ULONG Length; + UWORD MsgSize; + + VarsComm.ExtTx.Timer = 0; + + if (VarsComm.ExtTx.RemFileSize > (MAX_BT_MSG_SIZE - 5)) + { + + /* need to use the maximum size available - approx 64K */ + VarsComm.ExtTx.RemMsgSize = (MAX_BT_MSG_SIZE - 5); + } + else + { + + /* Message can hold the remaining message */ + VarsComm.ExtTx.RemMsgSize = VarsComm.ExtTx.RemFileSize; + } + + if (VarsComm.ExtTx.RemMsgSize > (SIZE_OF_BTBUF - 5)) + { + Length = SIZE_OF_BTBUF - 5; + VarsComm.UpdateState = 4; + } + else + { + Length = VarsComm.ExtTx.RemMsgSize; + VarsComm.UpdateState = 5; + } + + Handle = (UBYTE)(VarsComm.ExtTx.SrcHandle); + pMapLoader->pFunc(READ, &Handle, &(VarsComm.BtModuleOutBuf.Buf[3]), &Length); + MsgSize = VarsComm.ExtTx.RemMsgSize + 3; + VarsComm.BtModuleOutBuf.Buf[0] = SYSTEM_CMD; + VarsComm.BtModuleOutBuf.Buf[1] = WRITE; + VarsComm.BtModuleOutBuf.Buf[2] = VarsComm.ExtTx.DstHandle; + dBtSendMsg(VarsComm.BtModuleOutBuf.Buf, Length + 3, MsgSize); + + VarsComm.ExtTx.RemMsgSize -= Length; + VarsComm.ExtTx.RemFileSize -= Length; + } + break; + + case 4: /* CONTINOUSWRITE:*/ + { + ULONG Length; + UWORD Status; + + if(dBtCheckForTxBuf()) + { + + /* do only send more data if buffer is empty */ + VarsComm.ExtTx.Timer = 0; + if (VarsComm.ExtTx.RemMsgSize >= SIZE_OF_BTBUF) + { + Length = SIZE_OF_BTBUF; + } + else + { + Length = VarsComm.ExtTx.RemMsgSize; + } + + VarsComm.ExtTx.RemMsgSize -= Length; + VarsComm.ExtTx.RemFileSize -= Length; + Handle = (UBYTE)(VarsComm.ExtTx.SrcHandle); + Status = pMapLoader->pFunc(READ, &Handle, &(VarsComm.BtModuleOutBuf.Buf[0]), &Length); + if (Status >= 0x8000) + { + Length = 0; + } + dBtSend(VarsComm.BtModuleOutBuf.Buf, Length); + if (!(VarsComm.ExtTx.RemMsgSize)) + { + + /* at this point due to large write command acknowledge is expected */ + VarsComm.UpdateState = 5; + VarsComm.ExtTx.Timer = 0; + IOMapComm.BtInBuf.InPtr = 0; + } + } + } + break; + + case 5: /* WRITEACK: */ + { + if (6 == IOMapComm.BtInBuf.InPtr) + { + if ((WRITE == IOMapComm.BtInBuf.Buf[1]) && + (REPLY_CMD == IOMapComm.BtInBuf.Buf[0]) && + (VarsComm.ExtTx.DstHandle == IOMapComm.BtInBuf.Buf[3])) + { + + /* Ok the the return reply is for me - was it ok? */ + if (LOADER_ERR_BYTE(SUCCESS) == IOMapComm.BtInBuf.Buf[2]) + { + + /* Ok send next write*/ + if (VarsComm.ExtTx.RemFileSize) + { + VarsComm.UpdateState = 3; + } + else + { + VarsComm.UpdateState = 6; + } + IOMapComm.BtInBuf.InPtr = 0; + } + } + } + + if (VarsComm.ExtTx.Timer >= FILETXTOUT) + { + *(VarsComm.pRetVal) = FILETX_TIMEOUT; + VarsComm.UpdateState = 8; + } + else + { + (VarsComm.ExtTx.Timer)++; + } + } + break; + + case 6: /*TERMINATESEND: */ + { + + /* Stream still open close the receiver handle */ + VarsComm.BtModuleOutBuf.Buf[0] = SYSTEM_CMD; + VarsComm.BtModuleOutBuf.Buf[1] = CLOSE; + VarsComm.BtModuleOutBuf.Buf[2] = VarsComm.ExtTx.DstHandle; + dBtSendMsg(VarsComm.BtModuleOutBuf.Buf, 3, 3); + + VarsComm.ExtTx.Timer = 0; + VarsComm.UpdateState = 7; + } + break; + case 7: /* TERMINATEACK:*/ + { + + if (4 == IOMapComm.BtInBuf.InPtr) + { + + if ((CLOSE == IOMapComm.BtInBuf.Buf[1]) && + (REPLY_CMD == IOMapComm.BtInBuf.Buf[0]) && + (VarsComm.ExtTx.DstHandle == IOMapComm.BtInBuf.Buf[3])) + { + if (LOADER_ERR_BYTE(SUCCESS) == IOMapComm.BtInBuf.Buf[2]) + { + *(VarsComm.pRetVal) = SUCCESS; + VarsComm.UpdateState = 8; + } + else + { + *(VarsComm.pRetVal) = FILETX_CLOSEERROR; + VarsComm.UpdateState = 8; + } + IOMapComm.BtInBuf.InPtr = 0; + } + } + + if (VarsComm.ExtTx.Timer >= FILETXTOUT) + { + *(VarsComm.pRetVal) = FILETX_TIMEOUT; + VarsComm.UpdateState = 8; + } + else + { + (VarsComm.ExtTx.Timer)++; + } + } + break; + case 8: + { + UBYTE Handle; + Handle = (UBYTE)(VarsComm.ExtTx.SrcHandle); + pMapLoader->pFunc(CLOSE, &Handle, NULL, NULL); + (VarsComm.UpdateState)++; + } + break; + case 9: + { + cCommsSetCmdMode(&(VarsComm.UpdateState)); + } + break; + case 10: + { + SETBtStateIdle; + } + break; + } + } + break; + + case UPD_EXTREAD: + { + switch (VarsComm.UpdateState) + { + case 0: + { + ULONG MsgLength; + UWORD Status; + + MsgLength = (SIZE_OF_BTBUF - 8); + Handle =(UBYTE)(VarsComm.ExtTx.SrcHandle); + Status = pMapLoader->pFunc(READ, &Handle, &(VarsComm.BtModuleOutBuf.Buf[6]), &MsgLength); + VarsComm.BtModuleOutBuf.Buf[0] = (UBYTE) (REPLY_CMD); + VarsComm.BtModuleOutBuf.Buf[1] = (UBYTE) (VarsComm.ExtTx.Cmd); + VarsComm.BtModuleOutBuf.Buf[2] = LOADER_ERR_BYTE(Status); + VarsComm.BtModuleOutBuf.Buf[3] = LOADER_HANDLE(Status); + VarsComm.BtModuleOutBuf.Buf[4] = (UBYTE)VarsComm.ExtTx.RemMsgSize; + VarsComm.BtModuleOutBuf.Buf[5] = (UBYTE)(VarsComm.ExtTx.RemMsgSize >> 8); + dBtSendMsg(VarsComm.BtModuleOutBuf.Buf, (UBYTE)(SIZE_OF_BTBUF - 2), (VarsComm.ExtTx.RemMsgSize + 6)); + + VarsComm.ExtTx.RemMsgSize -= (SIZE_OF_BTBUF - 8); + VarsComm.UpdateState = 1; + } + break; + + case 1: + { + + ULONG Length; + + if(dBtCheckForTxBuf()) + { + if (VarsComm.ExtTx.RemMsgSize > (SIZE_OF_BTBUF)) + { + + /* Send max number of bytes */ + VarsComm.ExtTx.RemMsgSize -= SIZE_OF_BTBUF; + Length = SIZE_OF_BTBUF; + } + else + { + + /* Buffer can hold the last part of the requested data */ + Length = VarsComm.ExtTx.RemMsgSize; + VarsComm.ExtTx.RemMsgSize = 0; + *(VarsComm.pRetVal) = SUCCESS; + SETBtStateIdle; + } + Handle =(UBYTE)(VarsComm.ExtTx.SrcHandle); + pMapLoader->pFunc(READ, &Handle, (VarsComm.BtModuleOutBuf.Buf), &Length); + dBtSend(VarsComm.BtModuleOutBuf.Buf, Length); + } + } + break; + } + } + break; + + case UPD_SEARCH: + { + switch (VarsComm.UpdateState) + { + case 0: + { + cCommsSetCmdMode(&(VarsComm.UpdateState)); + } + break; + case 1: + { + cCommsCloseConn0(&(VarsComm.UpdateState)); + } + break; + case 2: + { + + /* Now ready for the actual search */ + for (Tmp = 0; Tmp < SIZE_OF_BT_DEVICE_TABLE; Tmp++) + { + if ((IOMapComm.BtDeviceTable[Tmp].DeviceStatus) & BT_DEVICE_KNOWN) + { + (IOMapComm.BtDeviceTable[Tmp].DeviceStatus) = (BT_DEVICE_AWAY | BT_DEVICE_KNOWN); + } + else + { + IOMapComm.BtDeviceTable[Tmp].DeviceStatus = BT_DEVICE_EMPTY; + } + } + dBtSendBtCmd((UBYTE)MSG_BEGIN_INQUIRY, (UBYTE)BT_DEFAULT_INQUIRY_MAX, + BT_DEFAULT_INQUIRY_TIMEOUT_LO, NULL, NULL, NULL, NULL); + (VarsComm.UpdateState)++; + } + break; + case 3: + { + + /* this is the stop search flag */ + /* - meaning that the search should be stopped */ + if (1 == VarsComm.BtCmdData.ParamOne) + { + dBtSendBtCmd((UBYTE)MSG_CANCEL_INQUIRY, 0, 0, NULL, NULL, NULL, NULL); + (VarsComm.UpdateState) = 7; + } + else + { + + + /* when inquiry is running there is 2 alloable return answers */ + /* either inquiry result or inquiry stopped */ + if (MSG_INQUIRY_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) + { + + dBtResetTimeOut(); /* reset the cmd timeout */ + Tmp = cCommInsertDevice(&(IOMapComm.BtInBuf.Buf[2]), &(IOMapComm.BtInBuf.Buf[9]), + &(IOMapComm.BtInBuf.Buf[25]), (UBYTE) BT_DEVICE_UNKNOWN, &Tmp2); + if (SIZE_OF_BT_DEVICE_TABLE > Tmp) + { + + /* Remember to check for already existing entry ....*/ + if (DEVICE_VERIFIED != Tmp2) + { + (IOMapComm.BtDeviceTable[Tmp].DeviceStatus) &= ~BT_DEVICE_AWAY; + IOMapComm.BtDeviceCnt++; + } + } + else + { + + /* We will send a stop inquiry cmd as the table is full! */ + dBtSendBtCmd((UBYTE)MSG_CANCEL_INQUIRY, 0, 0, NULL, NULL, NULL, NULL); + } + } + + if (MSG_INQUIRY_STOPPED == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) + { + VarsComm.BtDeviceIndex = 0; /* Start looking for found devices at index 0 */ + VarsComm.LookUpCnt = 0; /* how many times should we try to ask for the name */ + (VarsComm.UpdateState)++; + } + } + IOMapComm.BtInBuf.Buf[BT_CMD_BYTE] = 0; + } + break; + + case 4: + { + + /* this is the stop search flag */ + /* - meaning that the search should be stopped */ + if (1 == VarsComm.BtCmdData.ParamOne) + { + (VarsComm.UpdateState) = 8; + } + else + { + + /* Needs to run through the hole list as found devices can be placed anywhere */ + /* in the table */ + for (Tmp = (VarsComm.BtDeviceIndex); Tmp < SIZE_OF_BT_DEVICE_TABLE; Tmp++) + { + if ((BT_DEVICE_UNKNOWN == IOMapComm.BtDeviceTable[Tmp].DeviceStatus) || + (BT_DEVICE_KNOWN == IOMapComm.BtDeviceTable[Tmp].DeviceStatus)) + { + VarsComm.BtDeviceIndex = (Tmp + 1); + (VarsComm.UpdateState)++; + dBtSendBtCmd((UBYTE)MSG_LOOKUP_NAME, 0, 0, (IOMapComm.BtDeviceTable[Tmp].BdAddr), + NULL, NULL, NULL); + break; + } + } + if (SIZE_OF_BT_DEVICE_TABLE == Tmp) + { + (VarsComm.LookUpCnt)++; + if (((VarsComm.LookUpCnt) < LOOKUPNO) && ((IOMapComm.BtDeviceNameCnt) != (IOMapComm.BtDeviceCnt))) + { + VarsComm.BtDeviceIndex = 0; + } + else + { + + // all done + SETBtStateIdle; + *(VarsComm.pRetVal) = SUCCESS; + } + } + } + } + break; + + case 5: + { + + if (MSG_LOOKUP_NAME_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) + { + Tmp2 = FALSE; /* Tmp2 used to indicate name change */ + (IOMapComm.BtDeviceNameCnt)++; + + /* Try look the most obvious place in the device table */ + Tmp = VarsComm.BtDeviceIndex - 1; + if (TRUE != cCommCheckBdaddr((IOMapComm.BtDeviceTable[Tmp].BdAddr), &(IOMapComm.BtInBuf.Buf[2]))) + { + + /* there was no match - now look the complete table */ + for (Tmp = 0; Tmp < SIZE_OF_BT_DEVICE_TABLE; Tmp++) + { + if (TRUE == cCommCheckBdaddr((IOMapComm.BtDeviceTable[Tmp].BdAddr), &(IOMapComm.BtInBuf.Buf[2]))) + { + break; + } + } + } + + if (Tmp < SIZE_OF_BT_DEVICE_TABLE) + { + + /* Valid index with matching device adress found */ + if (0 == IOMapComm.BtInBuf.Buf[9]) + { + + if (0 == IOMapComm.BtDeviceTable[Tmp].Name[0]) + { + + /* No valid name recvd and no valid name in table -> insert "No Name" */ + cCommInsertBtName(IOMapComm.BtDeviceTable[Tmp].Name, (UBYTE*)NoName); + } + } + else + { + + /* Valid Name - check it against the one allready stored in the device table */ + /* if it differs then update */ + if (0 != strcmp((char const*)IOMapComm.BtDeviceTable[Tmp].Name, (char const*)&(IOMapComm.BtInBuf.Buf[9]))) + { + cCommInsertBtName(IOMapComm.BtDeviceTable[Tmp].Name, &(IOMapComm.BtInBuf.Buf[9])); + Tmp2 = TRUE; + } + } + if ((BT_DEVICE_KNOWN == (IOMapComm.BtDeviceTable[Tmp].DeviceStatus)) && (TRUE == Tmp2)) + { + dBtSendBtCmd((UBYTE)MSG_ADD_DEVICE, 0, 0, (IOMapComm.BtDeviceTable[Tmp].BdAddr), + (IOMapComm.BtDeviceTable[Tmp].Name), (IOMapComm.BtDeviceTable[Tmp].ClassOfDevice), NULL); + (VarsComm.UpdateState)++; + } + else + { + (VarsComm.UpdateState)--; + } + } + + /* Update devicestatus (name found) so it doesn't look up the name anymore */ + IOMapComm.BtDeviceTable[Tmp].DeviceStatus |= BT_DEVICE_NAME; + } + + if (MSG_LOOKUP_NAME_FAILURE == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) + { + + if ((LOOKUPNO - 1) == VarsComm.LookUpCnt) + { + + /* This is the last time we ask this device -> we will not get a valid name */ + /* Try look the most obvious place in the device table */ + Tmp = VarsComm.BtDeviceIndex - 1; + if (TRUE != cCommCheckBdaddr((IOMapComm.BtDeviceTable[Tmp].BdAddr), &(IOMapComm.BtInBuf.Buf[2]))) + { + for (Tmp = 0; Tmp < SIZE_OF_BT_DEVICE_TABLE; Tmp++) + { + if (TRUE == cCommCheckBdaddr((IOMapComm.BtDeviceTable[Tmp].BdAddr), &(IOMapComm.BtInBuf.Buf[2]))) + { + break; + } + } + if ((Tmp < SIZE_OF_BT_DEVICE_TABLE) && (BT_DEVICE_UNKNOWN == (IOMapComm.BtDeviceTable[Tmp].DeviceStatus))) + { + cCommInsertBtName(IOMapComm.BtDeviceTable[Tmp].Name, (UBYTE*) NoName); + } + } + (IOMapComm.BtDeviceNameCnt)++; + } + (VarsComm.UpdateState)--; + } + IOMapComm.BtInBuf.Buf[BT_CMD_BYTE] = 0; + } + break; + + case 6: + { + + /* Waiting for reply on add device command - List result */ + if (MSG_LIST_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) + { + if (LR_SUCCESS == IOMapComm.BtInBuf.Buf[2]) + { + + /* Return and go through the list*/ + (VarsComm.UpdateState) -= 2; + } + else + { + pMapUi->Error = (UBYTE)IOMapComm.BtInBuf.Buf[2]; + pMapUi->BluetoothState |= BT_ERROR_ATTENTION; + } + } + } + break; + case 7: + { + + /* here because search has been stopped by user during inquiry */ + if (MSG_INQUIRY_STOPPED == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) + { + + /* table should be cleared as no names hes been inquired */ + for (Tmp = 0; Tmp < SIZE_OF_BT_DEVICE_TABLE; Tmp++) + { + if ((IOMapComm.BtDeviceTable[Tmp].DeviceStatus) & BT_DEVICE_KNOWN) + { + (IOMapComm.BtDeviceTable[Tmp].DeviceStatus) = BT_DEVICE_KNOWN; + } + else + { + (IOMapComm.BtDeviceTable[Tmp].DeviceStatus) = BT_DEVICE_EMPTY; + } + IOMapComm.BtDeviceCnt = 0; + IOMapComm.BtDeviceNameCnt = 0; + } + SETBtStateIdle; + *(VarsComm.pRetVal) = SUCCESS; + } + } + break; + case 8: + { + for (Tmp = (VarsComm.BtDeviceIndex); Tmp < SIZE_OF_BT_DEVICE_TABLE; Tmp++) + { + if (BT_DEVICE_UNKNOWN == IOMapComm.BtDeviceTable[Tmp].DeviceStatus) + { + IOMapComm.BtDeviceTable[Tmp].DeviceStatus = BT_DEVICE_EMPTY; + } + } + SETBtStateIdle; + *(VarsComm.pRetVal) = SUCCESS; + } + break; + } + } + break; + + case UPD_CONNECTREQ: + { + switch (VarsComm.UpdateState) + { + + case 0: + { + dBtSendBtCmd((UBYTE)MSG_ACCEPT_CONNECTION, 1, 0, NULL, NULL, NULL, NULL); + cCommCopyBdaddr((IOMapComm.BtConnectTable[0].BdAddr), &(IOMapComm.BtInBuf.Buf[BT_CMD_BYTE + 1])); + (VarsComm.UpdateState)++; + } + break; + + case 1: + { + if (MSG_CONNECT_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) + { + + /* Check for successfull connection */ + if (1 == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE + 1]) + { + + /* Save the handle number and look up the name of the master */ + IOMapComm.BtConnectTable[0].HandleNr = IOMapComm.BtInBuf.Buf[BT_CMD_BYTE + 2]; + pMapUi->BluetoothState |= BT_STATE_CONNECTED; + dBtSendBtCmd((UBYTE)MSG_LOOKUP_NAME, 0, 0, (IOMapComm.BtConnectTable[0].BdAddr), NULL, NULL, NULL); + (VarsComm.UpdateState)++; + } + else + { + + /* Unsuccessful connection */ + SETBtStateIdle; + *(VarsComm.pRetVal) = BTCONNECTFAIL; + } + } + } + break; + + case 2: + { + + /* a close connection can happen during connection sequence - if this */ + /* occurs for connection 0 then abort the rest of the sequence - OxFF */ + /* is unused handle */ + if ((MSG_CLOSE_CONNECTION_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) && + (0xFF == IOMapComm.BtConnectTable[0].HandleNr)) + { + SETBtStateIdle; + *(VarsComm.pRetVal) = BTCONNECTFAIL; + } + else + { + + if (MSG_LOOKUP_NAME_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) + { + Tmp = cCommInsertDevice(&(IOMapComm.BtInBuf.Buf[2]), &(IOMapComm.BtInBuf.Buf[9]), + &(IOMapComm.BtInBuf.Buf[25]), (UBYTE) BT_DEVICE_KNOWN, &Tmp2); + + if (SIZE_OF_BT_DEVICE_TABLE > Tmp) + { + + /* entry has been added or is allready existing in the devicetable */ + cCommInsertBtName(IOMapComm.BtConnectTable[0].Name, &(IOMapComm.BtInBuf.Buf[9])); + cCommCopyBdaddr((IOMapComm.BtConnectTable[0].BdAddr), &(IOMapComm.BtInBuf.Buf[2])); + memcpy(IOMapComm.BtConnectTable[0].ClassOfDevice, + IOMapComm.BtDeviceTable[Tmp].ClassOfDevice, SIZE_OF_CLASS_OF_DEVICE); + dBtSendBtCmd((UBYTE)MSG_ADD_DEVICE, 0, 0, (IOMapComm.BtDeviceTable[Tmp].BdAddr), + (IOMapComm.BtDeviceTable[Tmp].Name), (IOMapComm.BtDeviceTable[Tmp].ClassOfDevice), NULL); + (VarsComm.UpdateState)++; + } + else + { + + /* no room in the devicetable -> reject the request. Param2 is index in connect table */ + dBtSendBtCmd((UBYTE)MSG_CLOSE_CONNECTION, IOMapComm.BtConnectTable[0].HandleNr, + 0, NULL, NULL, NULL, NULL); + SETBtStateIdle; + *(VarsComm.pRetVal) = BTCONNECTFAIL; + } + } + + if (MSG_LOOKUP_NAME_FAILURE == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) + { + + /* not able to get the name - disconnect*/ + dBtSendBtCmd((UBYTE)MSG_CLOSE_CONNECTION, IOMapComm.BtConnectTable[0].HandleNr, + 0, NULL, NULL, NULL, NULL); + *(VarsComm.pRetVal) = BTCONNECTFAIL; + SETBtStateIdle; + } + } + } + break; + + case 3: + { + if (MSG_LIST_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) + { + if (LR_SUCCESS == IOMapComm.BtInBuf.Buf[2]) + { + + /* All success - open stream (Data mode) */ + dBtSendBtCmd((UBYTE)MSG_OPEN_STREAM, IOMapComm.BtConnectTable[0].HandleNr, 0, NULL, NULL, NULL, NULL); + (VarsComm.UpdateState)++; + } + else + { + + /* no room in the BC4 -> reject the request */ + dBtSendBtCmd((UBYTE)MSG_CLOSE_CONNECTION, IOMapComm.BtConnectTable[0].HandleNr, + 0, NULL, NULL, NULL, NULL); + *(VarsComm.pRetVal) = BTCONNECTFAIL; + SETBtStateIdle; + } + } + } + break; + + case 4: + { + if (VarsComm.BtBcPinLevel) + { + IOMapComm.BtConnectTable[0].StreamStatus = 1; + *(VarsComm.pRetVal) = SUCCESS; + SETBtDataState; + SETBtStateIdle; + } + } + break; + } + } + break; + + case UPD_CONNECT: + { + switch (VarsComm.UpdateState) + { + case 0: + { + cCommsSetCmdMode(&(VarsComm.UpdateState)); + } + break; + case 1: + { + cCommsCloseConn0(&(VarsComm.UpdateState)); + } + break; + case 2: + { + dBtSendBtCmd((UBYTE)MSG_CONNECT, 0, 0, + IOMapComm.BtDeviceTable[VarsComm.BtCmdData.ParamOne].BdAddr, NULL, NULL, NULL); + (VarsComm.UpdateState)++; + } + break; + + case 3: + { + if (MSG_CONNECT_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) + { + if (IOMapComm.BtInBuf.Buf[2] == 1) + { + + IOMapComm.BtConnectTable[VarsComm.BtCmdData.ParamTwo].HandleNr = IOMapComm.BtInBuf.Buf[3]; + pMapUi->BluetoothState |= BT_STATE_CONNECTED; + + //Now we need to copy the data to the connectiontable + memcpy((IOMapComm.BtConnectTable[VarsComm.BtCmdData.ParamTwo].BdAddr), (IOMapComm.BtDeviceTable[VarsComm.BtCmdData.ParamOne].BdAddr), SIZE_OF_BDADDR); + cCommInsertBtName(IOMapComm.BtConnectTable[VarsComm.BtCmdData.ParamTwo].Name, IOMapComm.BtDeviceTable[VarsComm.BtCmdData.ParamOne].Name); + memcpy((IOMapComm.BtConnectTable[VarsComm.BtCmdData.ParamTwo].ClassOfDevice), + (IOMapComm.BtDeviceTable[VarsComm.BtCmdData.ParamOne].ClassOfDevice), SIZE_OF_CLASS_OF_DEVICE); + IOMapComm.BtDeviceTable[VarsComm.BtCmdData.ParamOne].DeviceStatus = BT_DEVICE_KNOWN; + + if (VarsComm.BtCmdData.ParamTwo == 1) + { + IOMapComm.BrickData.BtStateStatus |= BT_CONNECTION_1_ENABLE; + } + else + { + if (VarsComm.BtCmdData.ParamTwo == 2) + { + IOMapComm.BrickData.BtStateStatus |= BT_CONNECTION_2_ENABLE; + } + else + { + if (VarsComm.BtCmdData.ParamTwo == 3) + { + IOMapComm.BrickData.BtStateStatus |= BT_CONNECTION_3_ENABLE; + } + } + } + dBtSendBtCmd((UBYTE)MSG_ADD_DEVICE, 0, 0, (IOMapComm.BtConnectTable[VarsComm.BtCmdData.ParamTwo].BdAddr), + (IOMapComm.BtConnectTable[VarsComm.BtCmdData.ParamTwo].Name), + (IOMapComm.BtDeviceTable[VarsComm.BtCmdData.ParamOne].ClassOfDevice), NULL); + (VarsComm.UpdateState)+=3; /* skip the pin code part */ + } + else + { + + /* Connect request denied */ + *(VarsComm.pRetVal) = BTCONNECTFAIL; + SETBtStateIdle; + } + } + if (MSG_REQUEST_PIN_CODE == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) + { + *(VarsComm.pRetVal) = REQPIN; + VarsComm.pValidPinCode = NULL; + (VarsComm.UpdateState)++; + } + } + break; + + case 4: + { + if (NULL != VarsComm.pValidPinCode) + { + + memcpy((IOMapComm.BtConnectTable[VarsComm.BtCmdData.ParamTwo].PinCode), + VarsComm.pValidPinCode, SIZE_OF_BT_PINCODE); + + dBtSendBtCmd((UBYTE)MSG_PIN_CODE, 0, 0, IOMapComm.BtDeviceTable[VarsComm.BtCmdData.ParamOne].BdAddr, + NULL, NULL, (VarsComm.pValidPinCode)); + (VarsComm.UpdateState)++; + } + if (MSG_CONNECT_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) + { + + /* if no pin code has been accepted then timeout indicated */ + /* by connect failiure - it can only be failiure here */ + *(VarsComm.pRetVal) = BTCONNECTFAIL; + SETBtStateIdle; + } + } + break; + + case 5: + { + + if (MSG_CONNECT_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) + { + + /* Connect failiure can happen at any time */ + *(VarsComm.pRetVal) = BTCONNECTFAIL; + SETBtStateIdle; + } + if (MSG_PIN_CODE_ACK == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) + { + + /* return back and wait for connect ack */ + (VarsComm.UpdateState) = 3; + } + } + break; + case 6: + { + if (MSG_LIST_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) + { + *(VarsComm.pRetVal) = SUCCESS; + SETBtStateIdle; + } + } + break; + } + } + break; + + case UPD_DISCONNECT: + { + switch (VarsComm.UpdateState) + { + case 0: + { + cCommsSetCmdMode(&(VarsComm.UpdateState)); + } + break; + + case 1: + { + if (BLUETOOTH_HANDLE_UNDEFIEND != IOMapComm.BtConnectTable[VarsComm.BtCmdData.ParamOne].HandleNr) + { + VarsComm.BtCmdData.ParamOne = IOMapComm.BtConnectTable[VarsComm.BtCmdData.ParamOne].HandleNr; + dBtSendBtCmd((UBYTE)MSG_CLOSE_CONNECTION, VarsComm.BtCmdData.ParamOne, 0, NULL, NULL, NULL, NULL); + (VarsComm.UpdateState)++; + } + else + { + *(VarsComm.pRetVal) = SUCCESS; + SETBtStateIdle; + } + } + break; + + case 2: + { + + /* look for right message and right handle */ + if ((MSG_CLOSE_CONNECTION_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) && + (VarsComm.BtCmdData.ParamOne == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE + 2])) + { + *(VarsComm.pRetVal) = SUCCESS; + SETBtStateIdle; + } + } + break; + } + } + break; + case UPD_DISCONNECTALL: + { + switch (VarsComm.UpdateState) + { + case 0: + { + cCommsSetCmdMode(&(VarsComm.UpdateState)); + } + break; + case 1: + { + cCommsDisconnectAll(&(VarsComm.UpdateState)); + } + break; + case 2: + { + *(VarsComm.pRetVal) = SUCCESS; + SETBtStateIdle; + } + break; + } + } + break; + case UPD_REMOVEDEVICE: + { + switch (VarsComm.UpdateState) + { + case 0: + { + cCommsSetCmdMode(&(VarsComm.UpdateState)); + } + break; + case 1: + { + cCommsCloseConn0(&(VarsComm.UpdateState)); + } + break; + case 2: + { + dBtSendBtCmd((UBYTE)MSG_REMOVE_DEVICE, 0, 0, + IOMapComm.BtDeviceTable[VarsComm.BtCmdData.ParamOne].BdAddr, NULL, NULL, NULL); + IOMapComm.BtDeviceTable[VarsComm.BtCmdData.ParamOne].DeviceStatus = BT_DEVICE_EMPTY; + (VarsComm.UpdateState)++; + } + break; + case 3: + { + if (MSG_LIST_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) + { + *(VarsComm.pRetVal) = SUCCESS; + SETBtStateIdle; + } + } + break; + } + } + break; + + case UPD_PINREQ: + { + + /* This is pincode request from the outside - always conn 0*/ + switch (VarsComm.UpdateState) + { + case 0: + { + if (NULL != VarsComm.pValidPinCode) + { + memcpy((IOMapComm.BtConnectTable[0].PinCode), + VarsComm.pValidPinCode, SIZE_OF_BT_PINCODE); + dBtSendBtCmd((UBYTE)MSG_PIN_CODE, 0, 0, (IOMapComm.BtConnectTable[0].BdAddr), + NULL, NULL, (VarsComm.pValidPinCode)); + (VarsComm.UpdateState)++; + } + } + break; + case 1: + { + if (MSG_PIN_CODE_ACK == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) + { + SETBtStateIdle; + } + } + break; + } + } + break; + + case UPD_VISIBILITY: + { + switch (VarsComm.UpdateState) + { + case 0: + { + cCommsSetCmdMode(&(VarsComm.UpdateState)); + } + break; + case 1: + { + cCommsCloseConn0(&(VarsComm.UpdateState)); + } + break; + case 2: + { + dBtSendBtCmd((UBYTE)MSG_SET_DISCOVERABLE, VarsComm.BtCmdData.ParamOne, 0, NULL, NULL, NULL, NULL); + (VarsComm.UpdateState)++; + } + break; + case 3: + { + if (MSG_DISCOVERABLE_ACK == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) + { + if (VarsComm.BtCmdData.ParamOne == 1) + { + IOMapComm.BrickData.BtStateStatus |= BT_BRICK_VISIBILITY; + pMapUi->BluetoothState |= BT_STATE_VISIBLE; + } + else + { + IOMapComm.BrickData.BtStateStatus &= ~BT_BRICK_VISIBILITY; + pMapUi->BluetoothState &= ~BT_STATE_VISIBLE; + } + *(VarsComm.pRetVal) = SUCCESS; + SETBtStateIdle; + } + } + break; + } + } + break; + + case UPD_OFF: + { + switch (VarsComm.UpdateState) + { + case 0: + { + cCommsSetCmdMode(&(VarsComm.UpdateState)); + } + break; + case 1: + { + cCommsDisconnectAll(&(VarsComm.UpdateState)); + } + break; + case 2: + { + dBtSendBtCmd((UBYTE)MSG_SET_BRICK_STATUSBYTE, BT_DISABLE, 0, NULL, NULL, NULL, NULL); + (VarsComm.UpdateState)++; + } + break; + case 3: + { + if (MSG_SET_BRICK_STATUSBYTE_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) + { + if (IOMapComm.BtInBuf.Buf[2] == LR_SUCCESS) + { + SETBtOff; + pMapUi->BluetoothState = BT_STATE_OFF; + pMapUi->Flags |= UI_REDRAW_STATUS; + } + *(VarsComm.pRetVal) = SUCCESS; + SETBtStateIdle; + } + } + break; + } + } + break; + case UPD_SENDDATA: + { + switch (VarsComm.UpdateState) + { + case 0: + { + if (1 == IOMapComm.BtConnectTable[VarsComm.BtCmdData.ParamTwo].StreamStatus) + { + + /* Stream is allready open for the requested channel */ + (VarsComm.UpdateState) += 2; + } + else + { + + /* Stream not open - try open it*/ + (VarsComm.UpdateState)++; + } + } + break; + case 1: + { + cCommsOpenStream(&(VarsComm.UpdateState)); + } + break; + case 2: + { + + /* Stream is now opened now send the data */ + IOMapComm.BtInBuf.Buf[0] = 0; + dBtSendMsg((VarsComm.BtModuleOutBuf.Buf), VarsComm.BtCmdData.ParamOne, (UWORD)(VarsComm.BtCmdData.ParamOne)); + (VarsComm.UpdateState)++; + } + break; + case 3: + { + if(dBtCheckForTxBuf()) + { + if (VarsComm.BtCmdData.ParamThree) + { + VarsComm.ExtTx.Timer = 0; + (VarsComm.UpdateState)++; + } + else + { + *(VarsComm.pRetVal) = SUCCESS; + SETBtStateIdle; + } + } + } + break; + case 4: + { + if (0x02 == IOMapComm.BtInBuf.Buf[0]) + { + + /* a reply has been received now release the send sequence */ + *(VarsComm.pRetVal) = SUCCESS; + SETBtStateIdle; + } + else + { + if (++VarsComm.ExtTx.Timer > BTSTREAMTOUT) + { + *(VarsComm.pRetVal) = BTTIMEOUT; + SETBtStateIdle; + } + } + } + break; + } + } + break; + default: + { + + /* This is idle */ + VarsComm.UpdateState = 0; + } + break; + } +} + +UWORD cCommCopyBdaddr(UBYTE *pDst, UBYTE *pSrc) +{ + memcpy(pDst, pSrc, SIZE_OF_BDADDR); + return((UWORD) SIZE_OF_BDADDR); +} + +UWORD cCommCheckBdaddr(UBYTE *pAdr, UBYTE *pSrc) +{ + UWORD RetVal; + + RetVal = FALSE; + if (0 == memcmp((UBYTE*)pAdr, pSrc, SIZE_OF_BDADDR)) + { + RetVal = TRUE; + } + return(RetVal); +} + +UWORD cCommInsertBtName(UBYTE *pDst, UBYTE *pSrc) +{ + UBYTE Cnt; + + Cnt = 0; + + /* Complete brick name */ + while ((pSrc[Cnt]) && (Cnt < (SIZE_OF_BT_NAME - 1))) + { + pDst[Cnt] = pSrc[Cnt]; + Cnt++; + } + + /* Fill remaining up with zeros */ + while (Cnt < SIZE_OF_BT_NAME) + { + pDst[Cnt] = 0; + Cnt++; + } + + return((UWORD)SIZE_OF_BT_NAME); +} + + +UWORD cCommInsertDevice(UBYTE *pBdaddr, UBYTE *pName, UBYTE *pCod, UBYTE DeviceStatus, UBYTE *pAddInfo) +{ + UWORD Tmp; + UWORD RtnVal; + + RtnVal = FALSE; + *pAddInfo = DEVICE_VERIFIED; + for (Tmp = 0; Tmp < SIZE_OF_BT_DEVICE_TABLE; Tmp++) + { + if ((TRUE == cCommCheckBdaddr((IOMapComm.BtDeviceTable[Tmp].BdAddr), pBdaddr)) && + (IOMapComm.BtDeviceTable[Tmp].DeviceStatus != BT_DEVICE_EMPTY)) + { + + if ((IOMapComm.BtDeviceTable[Tmp].DeviceStatus) & BT_DEVICE_AWAY) + { + *pAddInfo = DEVICE_UPDATED; + (IOMapComm.BtDeviceTable[Tmp].DeviceStatus) &= ~BT_DEVICE_AWAY; + } + + if (BT_DEVICE_UNKNOWN == IOMapComm.BtDeviceTable[Tmp].DeviceStatus) + { + + /* Former unknown adresses can be upgraded - downgrading is not possible */ + IOMapComm.BtDeviceTable[Tmp].DeviceStatus = DeviceStatus; + } + if (pCod != NULL) + { + + /* Class of device can also upgraded - never downgraded to 0 */ + memcpy(&(IOMapComm.BtDeviceTable[Tmp].ClassOfDevice), pCod, SIZE_OF_CLASS_OF_DEVICE); + } + if ((*pName) != 0) + { + + /* Only upgrade name if name is received */ + cCommInsertBtName(IOMapComm.BtDeviceTable[Tmp].Name, pName); + } + RtnVal = TRUE; + + /* Break out - entry can only be found once */ + break; + } + } + + if (FALSE == RtnVal) + { + for (Tmp = 0; Tmp < SIZE_OF_BT_DEVICE_TABLE; Tmp++) + { + if (IOMapComm.BtDeviceTable[Tmp].DeviceStatus == BT_DEVICE_EMPTY) + { + *pAddInfo = DEVICE_INSERTED; + IOMapComm.BtDeviceTable[Tmp].DeviceStatus = DeviceStatus; + cCommCopyBdaddr((IOMapComm.BtDeviceTable[Tmp].BdAddr), pBdaddr); + cCommInsertBtName(IOMapComm.BtDeviceTable[Tmp].Name, pName); + if (NULL != pCod) + { + memcpy((IOMapComm.BtDeviceTable[Tmp].ClassOfDevice), pCod, SIZE_OF_CLASS_OF_DEVICE); + } + else + { + memset((IOMapComm.BtDeviceTable[Tmp].ClassOfDevice), 0, SIZE_OF_CLASS_OF_DEVICE); + } + RtnVal = TRUE; + break; + } + } + } + + /* Function returns SIZE_OF_BT_DEVICE_TABLE if device is not in the list */ + return(Tmp); +} + +void cCommsSetCmdMode(UBYTE *pNextState) +{ + switch(VarsComm.CmdSwitchCnt) + { + case 0: + { + if (BT_ARM_CMD_MODE != VarsComm.BtState) + { + cCommClearStreamStatus(); + VarsComm.BtCmdModeWaitCnt = 0; + VarsComm.CmdSwitchCnt++; + } + else + { + + /* allready in CMD mode - Exit */ + VarsComm.CmdSwitchCnt = 0; + (*pNextState)++; + } + } + break; + + case 1: + { + + /* stream status has been cleared now wait until buffers has been emptied */ + if (TRUE == dBtTxEnd()) + { + + /* Wait 100 ms after last byte has been sent to BC4 - else BC4 can crash */ + if (++(VarsComm.BtCmdModeWaitCnt) > 100) + { + dBtClearArm7CmdSignal(); + VarsComm.CmdSwitchCnt++; + } + } + } + break; + + case 2: + { + if (VarsComm.BtBcPinLevel == 0) + { + + /* Bluecore has entered cmd mode */ + SETBtCmdState; + VarsComm.CmdSwitchCnt = 0; + (*pNextState)++; + } + } + break; + + default: + { + VarsComm.CmdSwitchCnt = 0; + } + break; + } +} + +void cCommsOpenStream(UBYTE *pNextState) +{ + switch(VarsComm.StreamStateCnt) + { + case 0: + { + + if (SIZE_OF_BT_CONNECT_TABLE > VarsComm.BtCmdData.ParamTwo) + { + + /* first check if there is a connection on the requested channel */ + if ('\0' != IOMapComm.BtConnectTable[VarsComm.BtCmdData.ParamTwo].Name[0]) + { + + if (1 == IOMapComm.BtConnectTable[VarsComm.BtCmdData.ParamTwo].StreamStatus) + { + + /* Stream is allready open - continue */ + (*pNextState)++; + } + else + { + + /* There is a connection on requested channel proceed */ + VarsComm.StreamStateCnt = 1; + } + } + else + { + + /* Error - no connecteion on requested channel - exit */ + *(VarsComm.pRetVal) = (UWORD)ERR_COMM_CHAN_NOT_READY; + *(VarsComm.pRetVal) |= 0x8000; + SETBtStateIdle; + } + } + else + { + + /* Error - Illegal channel no - exit */ + *(VarsComm.pRetVal) = (UWORD)ERR_COMM_CHAN_INVALID; + *(VarsComm.pRetVal) |= 0x8000; + SETBtStateIdle; + } + } + break; + + case 1: + { + cCommsSetCmdMode(&(VarsComm.StreamStateCnt)); + } + break; + + case 2: + { + cCommsCloseConn0(&(VarsComm.StreamStateCnt)); + } + break; + + case 3: + { + + /* Open stream on the specified channel */ + VarsComm.StreamStateCnt = 4; + dBtSendBtCmd((UBYTE)MSG_OPEN_STREAM, IOMapComm.BtConnectTable[VarsComm.BtCmdData.ParamTwo].HandleNr, + 0, NULL, NULL, NULL, NULL); + } + break; + + case 4: + { + if (VarsComm.BtBcPinLevel) + { + SETBtDataState; + IOMapComm.BtConnectTable[VarsComm.BtCmdData.ParamTwo].StreamStatus = 1; + VarsComm.StreamStateCnt = 0; + (*pNextState)++; + } + } + break; + + default: + { + VarsComm.StreamStateCnt = 0; + } + break; + } +} + +void cCommsCloseConn0(UBYTE *pNextState) +{ + switch(VarsComm.CloseConn0Cnt) + { + case 0: + { + if ('\0' != IOMapComm.BtConnectTable[0].Name[0]) + { + + /* now disconnect channel 0 */ + VarsComm.CloseConn0Cnt = 1; + dBtSendBtCmd((UBYTE)MSG_CLOSE_CONNECTION, IOMapComm.BtConnectTable[0].HandleNr, 0, NULL, NULL, NULL, NULL); + } + else + { + (*pNextState)++; + } + } + break; + case 1: + { + if (MSG_CLOSE_CONNECTION_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) + { + VarsComm.CloseConn0Cnt = 0; + (*pNextState)++; + } + } + break; + default: + { + VarsComm.CloseConn0Cnt = 0; + } + break; + } +} + +void cCommsDisconnectAll(UBYTE *pNextState) +{ + switch(VarsComm.DiscAllCnt) + { + case 0: + { + VarsComm.BtCmdData.ParamOne = 0; + (VarsComm.DiscAllCnt)++; + } + break; + case 1: + { + while (('\0' == IOMapComm.BtConnectTable[VarsComm.BtCmdData.ParamOne].Name[0]) && + (VarsComm.BtCmdData.ParamOne < 4)) + { + VarsComm.BtCmdData.ParamOne++; + } + if (VarsComm.BtCmdData.ParamOne < 4) + { + + /* now disconnect selected channel */ + dBtSendBtCmd((UBYTE)MSG_CLOSE_CONNECTION, IOMapComm.BtConnectTable[VarsComm.BtCmdData.ParamOne].HandleNr, + 0, NULL, NULL, NULL, NULL); + VarsComm.BtCmdData.ParamOne++; + (VarsComm.DiscAllCnt)++; + } + else + { + + /* no more connections - move on */ + (VarsComm.DiscAllCnt) = 0; + (*pNextState)++; + } + } + break; + case 2: + { + if (MSG_CLOSE_CONNECTION_RESULT == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE]) + { + + /* Go back and check for more connections to close */ + (VarsComm.DiscAllCnt)--; + } + } + break; + } +} + +void cCommsBtReset(UBYTE *pNextState) +{ + switch(VarsComm.ResetBtCnt) + { + case 0: + { + + /* Setup Reset sequence */ + VarsComm.BtResetTimeCnt = 0; + VarsComm.ResetBtCnt = 1; + dBtSetBcResetPinLow(); + } + break; + case 1: + { + + /* Reset should be held low for a certain time "BLUECORE_RESET_TIME" */ + VarsComm.BtResetTimeCnt++; + if (VarsComm.BtResetTimeCnt > BLUECORE_RESET_TIME) + { + dBtSetBcResetPinHigh(); + VarsComm.BtWaitTimeCnt = 0; + VarsComm.ResetBtCnt = 2; + } + } + break; + case 2: + { + + /* Wait after reset is released either wait a minimum time or wait for the reset indication telegram */ + VarsComm.BtWaitTimeCnt++; + if ((VarsComm.BtWaitTimeCnt > BLUECORE_WAIT_BEFORE_INIT) || (MSG_RESET_INDICATION == IOMapComm.BtInBuf.Buf[BT_CMD_BYTE])) + { + memset(&(IOMapComm.BtDeviceTable), 0, sizeof(IOMapComm.BtDeviceTable)); + cCommClrConnTable(); + VarsComm.ResetBtCnt = 3; + } + } + break; + + case 3: + { + SETBtCmdState; + VarsComm.ResetBtCnt = 0; + (*pNextState)++; + } + break; + } +} + + +UWORD cCommReq(UBYTE Cmd, UBYTE Param1, UBYTE Param2, UBYTE Param3, UBYTE *pName, UWORD *pRetVal) +{ + ULONG Length; + UWORD ReturnVal; + SBYTE foundIndex= 0; + + ReturnVal = BTBUSY; + *pRetVal = BTBUSY; + if ((UPD_IDLE == (VarsComm.ActiveUpdate)) || ((UPD_SEARCH == (VarsComm.ActiveUpdate)) && (STOPSEARCH == Cmd))) + { + + ReturnVal = SUCCESS; + *pRetVal = INPROGRESS; + VarsComm.pRetVal = pRetVal; + switch(Cmd) + { + case SENDFILE: + { + ReturnVal = SUCCESS; + + /* No file is currently beeing send - Now open the file */ + VarsComm.ExtTx.SrcHandle = pMapLoader->pFunc(OPENREAD, pName, NULL, &Length); + VarsComm.ExtTx.RemFileSize = Length; + VarsComm.ExtTx.SlotNo = Param1; + VarsComm.BtCmdData.ParamTwo = Param1; /* This is used to open the correct stream */ + + if (0x8000 > VarsComm.ExtTx.SrcHandle) + { + + /* Source file is ok - go ahead */ + VarsComm.ActiveUpdate = UPD_SENDFILE; + VarsComm.ExtTx.Timer = 0; + VarsComm.ExtTx.Cmd = WRITE; + cCommCopyFileName(VarsComm.ExtTx.FileName, pName); + } + else + { + + /* Error in opening source file for read - file do not exist */ + ReturnVal = FILETX_SRCMISSING; + } + } + break; + case CONNECTBYNAME: // redo Param1, then fall through existing CONNECT code + foundIndex= cCommSearchBTDevTableForName(pName); + if(foundIndex != -1) + Param1= foundIndex; + case CONNECT: + { + + if (BLUETOOTH_HANDLE_UNDEFIEND == IOMapComm.BtConnectTable[Param2].HandleNr && foundIndex != -1) + { + + /* Connection not occupied */ + VarsComm.ActiveUpdate = UPD_CONNECT; + VarsComm.BtCmdData.ParamOne = Param1; + VarsComm.BtCmdData.ParamTwo = Param2; + } + else + { + + /* Connection occupied */ + ReturnVal = BTCONNECTFAIL; + *pRetVal = BTCONNECTFAIL; + } + } + break; + + case DISCONNECT: + { + VarsComm.ActiveUpdate = UPD_DISCONNECT; + VarsComm.BtCmdData.ParamOne = Param1; + } + break; + + case DISCONNECTALL: + { + VarsComm.ActiveUpdate = UPD_DISCONNECTALL; + } + break; + + case SEARCH: + { + VarsComm.ActiveUpdate = UPD_SEARCH; + IOMapComm.BtDeviceNameCnt = 0; + IOMapComm.BtDeviceCnt = 0; + VarsComm.BtCmdData.ParamOne = 0; + } + break; + case STOPSEARCH: + { + if (UPD_SEARCH == (VarsComm.ActiveUpdate)) + { + VarsComm.BtCmdData.ParamOne = 1; + } + else + { + *pRetVal = SUCCESS; + } + } + break; + case REMOVEDEVICE: + { + VarsComm.ActiveUpdate = UPD_REMOVEDEVICE; + VarsComm.BtCmdData.ParamOne = Param1; + } + break; + case VISIBILITY: + { + VarsComm.ActiveUpdate = UPD_VISIBILITY; + VarsComm.BtCmdData.ParamOne = Param1; + } + break; + case SETCMDMODE: + { + VarsComm.ActiveUpdate = UPD_REQCMDMODE; + } + break; + case FACTORYRESET: + { + VarsComm.ActiveUpdate = UPD_FACTORYRESET; + } + break; + case BTON: + { + if (BT_STATE_OFF & (pMapUi->BluetoothState)) + { + VarsComm.ActiveUpdate = UPD_RESET; + } + else + { + + /* Device is already on*/ + *pRetVal = SUCCESS; + } + } + break; + case BTOFF: + { + VarsComm.ActiveUpdate = UPD_OFF; + } + break; + case SENDDATA: + { + + /* Param2 indicates the port that the data should be */ + /* be sent on - param1 indicates the number of data */ + /* to be sent. pName is the pointer to the data */ + if (Param1 <= sizeof(VarsComm.BtModuleOutBuf.Buf)) + { + if ('\0' != IOMapComm.BtConnectTable[Param2].Name[0]) + { + VarsComm.BtCmdData.ParamOne = Param1; + VarsComm.BtCmdData.ParamTwo = Param2; + VarsComm.BtCmdData.ParamThree = Param3; + memcpy((VarsComm.BtModuleOutBuf.Buf), pName, Param1); + VarsComm.ActiveUpdate = UPD_SENDDATA; + } + else + { + ReturnVal = (UWORD)ERR_COMM_CHAN_NOT_READY; + ReturnVal |= 0x8000; + } + } + else + { + ReturnVal = (UWORD)ERR_COMM_BUFFER_FULL; + ReturnVal |= 0x8000; + } + } + break; + case OPENSTREAM: + { + VarsComm.BtCmdData.ParamTwo = Param2; + VarsComm.ActiveUpdate = UPD_OPENSTREAM; + } + break; + case SETBTNAME: + { + VarsComm.ActiveUpdate = UPD_BRICKNAME; + } + break; + case EXTREAD: + { + VarsComm.ActiveUpdate = UPD_EXTREAD; + } + break; + case PINREQ: + { + + /* This is an incomming pinrequest for connection on connection 0 because */ + /* ActiveUpdate is idle (if it was incomming it is not idle) */ + cCommCopyBdaddr((IOMapComm.BtConnectTable[0].BdAddr), &(IOMapComm.BtInBuf.Buf[2])); + pMapUi->BluetoothState |= (BT_CONNECT_REQUEST | BT_PIN_REQUEST); + VarsComm.pValidPinCode = NULL; + VarsComm.ActiveUpdate = UPD_PINREQ; + } + break; + case CONNECTREQ: + { + VarsComm.ActiveUpdate = UPD_CONNECTREQ; + } + break; + } + } + return(ReturnVal); +} + +void cCommPinCode(UBYTE *pPinCode) +{ + VarsComm.pValidPinCode = pPinCode; + if (REQPIN == (*(VarsComm.pRetVal))) + { + *(VarsComm.pRetVal) = INPROGRESS; + } +} + +void cCommClrConnTable(void) +{ + UBYTE Tmp; + + for (Tmp = 0; Tmp < SIZE_OF_BT_CONNECT_TABLE; Tmp++) + { + CLEARConnEntry(Tmp); + } + IOMapComm.BrickData.BtStateStatus &= ~(BT_CONNECTION_0_ENABLE | BT_CONNECTION_1_ENABLE | BT_CONNECTION_2_ENABLE | BT_CONNECTION_3_ENABLE); + pMapUi->BluetoothState &= ~BT_STATE_CONNECTED; + pMapUi->Flags |= UI_REDRAW_STATUS; +} + + /* search the BT table */ +SBYTE cCommSearchBTDevTableForName(UBYTE *name) { + UBYTE Tmp; + for (Tmp = 0; Tmp < SIZE_OF_BT_DEVICE_TABLE; Tmp++) + { + if (0 == strcmp((char*)(IOMapComm.BtDeviceTable[Tmp].Name), (char*)name)) + return Tmp; + } + return -1; +} diff --git a/src/c_comm.h b/src/c_comm.h new file mode 100644 index 0000000..06137b2 --- /dev/null +++ b/src/c_comm.h @@ -0,0 +1,154 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: c_comm.h $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_comm $ +// +// Platform C +// + +#ifndef C_COMM +#define C_COMM + + +#define BLUECORE_RESET_TIME 100 // Time in mS +#define BLUECORE_WAIT_BEFORE_INIT 5000 // Time in mS +#define BLUETOOTH_HANDLE_UNDEFIEND 0xFF + +/* Constants related to BtAdrStatus*/ +enum +{ + COLDBOOT, + INITIALIZED, + BTADRERROR +}; + + +enum +{ + USB_CH, + BT_CH, + HISPEED_CH, + NO_OF_CHANNELS +}; + + +/* enum reffering to BT update */ +enum +{ + UPD_BRICKNAME, + UPD_FACTORYRESET, + UPD_OPENSTREAM, + UPD_REQCMDMODE, + UPD_CONNECT, + UPD_CONNECTREQ, + UPD_PINREQ, + UPD_DISCONNECT, + UPD_DISCONNECTALL, + UPD_REMOVEDEVICE, + UPD_SEARCH, + UPD_RESET, + UPD_EXTREAD, + UPD_SENDFILE, + UPD_OFF, + UPD_VISIBILITY, + UPD_SENDDATA, + UPD_IDLE +}; + +/* Constants reffering to Protocol */ +enum +{ + DIRECT_CMD = 0x00, + SYSTEM_CMD = 0x01, + REPLY_CMD = 0x02, +#ifdef ARMDEBUG + DEBUG_CMD = 0x0d, +#endif + NO_REPLY_BIT = 0x80 +}; + +typedef struct +{ + ULONG RemFileSize; + UWORD RemMsgSize; + UWORD SrcHandle; + UWORD DstHandle; + UWORD Timer; + UBYTE FileName[FILENAME_LENGTH + 1]; + UBYTE Cmd; + UBYTE SlotNo; +}EXTTX; + +typedef struct +{ + UBYTE Buf[256]; + UWORD InPtr; + UWORD OutPtr; +}BTDATA; + +typedef struct +{ + UBYTE Buf[256]; + UWORD InPtr; + UWORD OutPtr; +}HSDATA; + +typedef struct +{ + UBYTE Status; + UBYTE Type; + UBYTE Handle; + UBYTE Cmd; +}EXTMODE; + +typedef struct +{ + UBYTE ParamOne; + UBYTE ParamTwo; + UBYTE ParamThree; +}BTCMD; + +typedef struct +{ + UBYTE BtUpdateDataConnectNr; + UBYTE BtBcPinLevel; + UBYTE BtResetTimeCnt; + UWORD BtWaitTimeCnt; + BTDATA BtModuleInBuf; + BTDATA BtModuleOutBuf; + BTCMD BtCmdData; + UBYTE HsState; + HSDATA HsModuleInBuf; + HSDATA HsModuleOutBuf; + EXTTX ExtTx; + EXTMODE ExtMode[NO_OF_CHANNELS]; + UBYTE ActiveUpdate; + UBYTE UpdateState; + UBYTE BtDeviceIndex; + UBYTE CmdSwitchCnt; + UBYTE StreamStateCnt; + UBYTE CloseConn0Cnt; + UBYTE DiscAllCnt; + UBYTE ResetBtCnt; + UBYTE BtState; + UWORD *pRetVal; + UWORD RetVal; + UBYTE *pValidPinCode; + UBYTE LookUpCnt; + UBYTE BtAdrStatus; + UBYTE BtCmdModeWaitCnt; +}VARSCOMM; + +void cCommInit(void* pHeader); +void cCommCtrl(void); +void cCommExit(void); + +extern const HEADER cComm; + +#endif diff --git a/src/c_comm.iom b/src/c_comm.iom new file mode 100644 index 0000000..2dfe994 --- /dev/null +++ b/src/c_comm.iom @@ -0,0 +1,223 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 9-06-08 14:57 $ +// +// Filename $Workfile:: c_comm.iom $ +// +// Version $Revision:: 2 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_comm $ +// +// Platform C +// + +#ifndef CCOMM_IOM +#define CCOMM_IOM + +#define pMapComm ((IOMAPCOMM*)(pHeaders[ENTRY_COMM]->pIOMap)) + +#define SIZE_OF_USBBUF 64 +#define USB_PROTOCOL_OVERHEAD 1 + 1 /* Command type byte + Command */ +#define SIZE_OF_USBDATA (SIZE_OF_USBBUF - USB_PROTOCOL_OVERHEAD) +#define SIZE_OF_HSBUF 128 +#define SIZE_OF_BTBUF 128 + +#define BT_CMD_BYTE 1 +#define SIZE_OF_BT_DEVICE_TABLE 30 +#define SIZE_OF_BT_CONNECT_TABLE 4 /* Index 0 is alway incomming connections */ +#define MAX_BT_MSG_SIZE 60000L + +#define BT_DEFAULT_INQUIRY_MAX 0 /* Unlimited no */ +#define BT_DEFAULT_INQUIRY_TIMEOUT_LO 15 /* 15 x 1,28 Sec = 19,2 Sec */ + + +// Constants reffering to BtState +enum +{ + BT_ARM_OFF, + BT_ARM_CMD_MODE, + BT_ARM_DATA_MODE, +}; + +//Constant reffering to BtStateStatus +#define BT_BRICK_VISIBILITY 0x01 +#define BT_BRICK_PORT_OPEN 0x02 +#define BT_CONNECTION_0_ENABLE 0x10 +#define BT_CONNECTION_1_ENABLE 0x20 +#define BT_CONNECTION_2_ENABLE 0x40 +#define BT_CONNECTION_3_ENABLE 0x80 + +//Constant reffering to BtHwStatus +#define BT_ENABLE 0x00 +#define BT_DISABLE 0x01 + +// Constants reffering to HsFlags +enum +{ + HS_UPDATE = 1 +}; + +// Constants reffering to HsState +enum +{ + HS_INITIALISE = 1, + HS_INIT_RECEIVER, + HS_SEND_DATA, + HS_DISABLE +}; + +//Constants refering to DeviceStatus within DeviceTable +enum +{ + BT_DEVICE_EMPTY = 0x00, + BT_DEVICE_UNKNOWN = 0x01, + BT_DEVICE_KNOWN = 0x02, + BT_DEVICE_NAME = 0x40, + BT_DEVICE_AWAY = 0x80 +}; + +/* Interface between command other modules */ +enum +{ + SENDFILE, + SEARCH, + STOPSEARCH, + CONNECT, + DISCONNECT, + DISCONNECTALL, + REMOVEDEVICE, + VISIBILITY, + SETCMDMODE, + OPENSTREAM, + SENDDATA, + FACTORYRESET, + BTON, + BTOFF, + SETBTNAME, + EXTREAD, + PINREQ, + CONNECTREQ, + CONNECTBYNAME +}; + + +enum +{ + LR_SUCCESS = 0x50, + LR_COULD_NOT_SAVE, + LR_STORE_IS_FULL, + LR_ENTRY_REMOVED, + LR_UNKOWN_ADDR +}; + +enum +{ + USB_CMD_READY = 0x01, + BT_CMD_READY = 0x02, + HS_CMD_READY = 0x04 +}; + +typedef struct +{ + UBYTE Buf[SIZE_OF_USBBUF]; + UBYTE InPtr; + UBYTE OutPtr; + UBYTE Spare1; + UBYTE Spare2; +}USBBUF; + +typedef struct +{ + UBYTE Buf[SIZE_OF_HSBUF]; + UBYTE InPtr; + UBYTE OutPtr; + UBYTE Spare1; + UBYTE Spare2; +}HSBUF; + +typedef struct +{ + UBYTE Buf[SIZE_OF_BTBUF]; + UBYTE InPtr; + UBYTE OutPtr; + UBYTE Spare1; + UBYTE Spare2; +}BTBUF; + +typedef struct +{ + UBYTE Name[SIZE_OF_BT_NAME]; + UBYTE ClassOfDevice[SIZE_OF_CLASS_OF_DEVICE]; + UBYTE BdAddr[SIZE_OF_BDADDR]; + UBYTE DeviceStatus; + UBYTE Spare1; + UBYTE Spare2; + UBYTE Spare3; +}BDDEVICETABLE; + +typedef struct +{ + UBYTE Name[SIZE_OF_BT_NAME]; + UBYTE ClassOfDevice[SIZE_OF_CLASS_OF_DEVICE]; + UBYTE PinCode[16]; + UBYTE BdAddr[SIZE_OF_BDADDR]; + UBYTE HandleNr; + UBYTE StreamStatus; + UBYTE LinkQuality; + UBYTE Spare; +}BDCONNECTTABLE; + +typedef struct +{ + UBYTE Name[SIZE_OF_BT_NAME]; + UBYTE BluecoreVersion[2]; + UBYTE BdAddr[SIZE_OF_BDADDR]; + UBYTE BtStateStatus; + UBYTE BtHwStatus; + UBYTE TimeOutValue; + UBYTE Spare1; + UBYTE Spare2; + UBYTE Spare3; +}BRICKDATA; + +typedef struct +{ + UWORD (*pFunc)(UBYTE, UBYTE, UBYTE, UBYTE, UBYTE*, UWORD*); + void (*pFunc2)(UBYTE*); + + // BT related entries + BDDEVICETABLE BtDeviceTable[SIZE_OF_BT_DEVICE_TABLE]; + BDCONNECTTABLE BtConnectTable[SIZE_OF_BT_CONNECT_TABLE]; + + //General brick data + BRICKDATA BrickData; + + BTBUF BtInBuf; + BTBUF BtOutBuf; + + // HI Speed related entries + HSBUF HsInBuf; + HSBUF HsOutBuf; + + // USB related entries + USBBUF UsbInBuf; + USBBUF UsbOutBuf; + USBBUF UsbPollBuf; + + UBYTE BtDeviceCnt; + UBYTE BtDeviceNameCnt; + + UBYTE HsFlags; + UBYTE HsSpeed; + UBYTE HsState; + + UBYTE UsbState; + +}IOMAPCOMM; + + +#endif + + + diff --git a/src/c_display.c b/src/c_display.c new file mode 100644 index 0000000..6b15495 --- /dev/null +++ b/src/c_display.c @@ -0,0 +1,849 @@ +// +// Programmer +// +// Date init 14.12.2004 +// +// Reviser $Author: Dkflebun $ +// +// Revision date $Date: 9-06-08 13:35 $ +// +// Filename $Workfile:: c_display.c $ +// +// Version $Revision: 2 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_disp $ +// +// Platform C +// + +#include +#include "stdconst.h" +#include "modules.h" +#include "c_display.iom" +#include "c_display.h" +#include "d_display.h" + + +static IOMAPDISPLAY IOMapDisplay; +static VARSDISPLAY VarsDisplay; + +const HEADER cDisplay = +{ + 0x000A0001L, + "Display", + cDisplayInit, + cDisplayCtrl, + cDisplayExit, + (void *)&IOMapDisplay, + (void *)&VarsDisplay, + (UWORD)sizeof(IOMapDisplay), + (UWORD)sizeof(VarsDisplay), + 0x0000 //Code size - not used so far +}; + + +const SCREEN_CORDINATE SCREEN_CORDINATES[SCREENS] = +{ + { 0, 0,DISPLAY_WIDTH,DISPLAY_HEIGHT }, // Background + { 0, 8,DISPLAY_WIDTH,DISPLAY_HEIGHT - 8 }, // Large + { 0, 8,DISPLAY_WIDTH,24 } // Small +}; + +const SCREEN_CORDINATE SELECT_FRAME_CORDINATES = +{ + 38,41,24,24 +}; + + +const SCREEN_CORDINATE MENUICON_CORDINATES[MENUICONS] = +{ + { DISPLAY_MENUICONS_X_OFFS,DISPLAY_MENUICONS_Y,24,24 }, // Left + { DISPLAY_MENUICONS_X_OFFS + DISPLAY_MENUICONS_X_DIFF,DISPLAY_MENUICONS_Y,24,24 }, // Center + { DISPLAY_MENUICONS_X_OFFS + DISPLAY_MENUICONS_X_DIFF * 2,DISPLAY_MENUICONS_Y,24,24 },// Right +}; + +const SCREEN_CORDINATE STATUSICON_CORDINATES[STATUSICONS] = +{ + { 0, 0,12, 8 }, // Bluetooth + { 12, 0,12, 8 }, // Usb + { 76, 0,12, 8 }, // Vm + { 88, 0,12, 8 } // Battery +}; + + +const SCREEN_CORDINATE STEPICON_CORDINATES[STEPICONS] = +{ + { 11,16,11,16 }, // Step 1 + { 28,16,11,16 }, // Step 2 + { 45,16,11,16 }, // Step 3 + { 62,16,11,16 }, // Step 4 + { 79,16,11,16 } // Step 5 +}; + + +void cDisplaySetPixel(UBYTE X,UBYTE Y) +{ + if ((X < DISPLAY_WIDTH) && (Y < DISPLAY_HEIGHT)) + { + IOMapDisplay.Display[(Y / 8) * DISPLAY_WIDTH + X] |= (1 << (Y % 8)); + } +} + + +void cDisplayClrPixel(UBYTE X,UBYTE Y) +{ + if ((X < DISPLAY_WIDTH) && (Y < DISPLAY_HEIGHT)) + { + IOMapDisplay.Display[(Y / 8) * DISPLAY_WIDTH + X] &= ~(1 << (Y % 8)); + } +} + + +void cDisplayChar(FONT *pFont,UBYTE On,UBYTE X,UBYTE Y,UBYTE Char) +{ + UBYTE *pSource; + UBYTE FontWidth; + UBYTE FontHeight; + UBYTE Items; + UBYTE Item; + UBYTE TmpY; + + + Items = pFont->ItemsX * pFont->ItemsY; + Item = Char - ' '; + if (Item < Items) + { + FontWidth = pFont->ItemPixelsX; + pSource = (UBYTE*)&pFont->Data[Item * FontWidth]; + while (FontWidth--) + { + TmpY = 0; + FontHeight = pFont->ItemPixelsY; + while (FontHeight--) + { + if (On == TRUE) + { + if (((*pSource) & (1 << TmpY))) + { + cDisplaySetPixel(X,Y + TmpY); + } + else + { + cDisplayClrPixel(X,Y + TmpY); + } + } + else + { + if (((*pSource) & (1 << TmpY))) + { + cDisplayClrPixel(X,Y + TmpY); + } + else + { + cDisplaySetPixel(X,Y + TmpY); + } + } + TmpY++; + } + X++; + pSource++; + } + } +} + + +void cDisplayString(FONT *pFont,UBYTE X,UBYTE Y,UBYTE *pString) +{ + UBYTE *pSource; + UBYTE *pDestination; + UBYTE FontWidth; + UBYTE Line; + UBYTE Items; + UBYTE Item; + + + Line = (Y & 0xF8) / 8; + Items = pFont->ItemsX * pFont->ItemsY; + pDestination = (UBYTE*)&IOMapDisplay.Display[Line * DISPLAY_WIDTH + X]; + + while (*pString) + { + Item = *pString - ' '; + if (Item < Items) + { + FontWidth = pFont->ItemPixelsX; + pSource = (UBYTE*)&pFont->Data[Item * FontWidth]; + while (FontWidth--) + { + *pDestination = *pSource; + pDestination++; + pSource++; + } + } + pString++; + } +} + + +void cDisplayUpdateScreen(SCREEN_CORDINATE *pCord,BMPMAP *pBitmap) +{ + UBYTE *pSource; + UBYTE *pDestination; + UBYTE Line; + UBYTE Lines; + + if (pBitmap) + { + if ((((pBitmap->StartY + pCord->StartY) & 0x07) == 0) && ((pBitmap->PixelsY & 0x07) == 0)) + { + pSource = pBitmap->Data; + Line = (pBitmap->StartY + pCord->StartY) / 8; + Lines = Line + pBitmap->PixelsY / 8; + while (Line < Lines) + { + pDestination = &IOMapDisplay.Display[Line * DISPLAY_WIDTH + pBitmap->StartX + pCord->StartX]; + memcpy(pDestination,pSource,(size_t)pBitmap->PixelsX); + pSource += pBitmap->PixelsX; + Line++; + } + } + } +} + + +void cDisplayCenterString(FONT *pFont,UBYTE *pString,UBYTE Line) +{ + UWORD Chars; + UBYTE Column; + + if (pString) + { + Chars = 0; + while (pString[Chars]) + { + Chars++; + } + Column = (DISPLAY_WIDTH - Chars * pFont->ItemPixelsX) / 2; + cDisplayString(pFont,Column,Line * 8,pString); + } +} + + +void cDisplayUpdateMenuIcon(UBYTE *pIcon,SCREEN_CORDINATE *pCord) +{ + UBYTE *pDestination; + UBYTE Line; + UBYTE Column; + UBYTE Lines; + UBYTE Columns; + + if (((pCord->StartY & 0x07) == 0) && ((pCord->PixelsY & 0x07) == 0)) + { + Line = pCord->StartY / 8; + Lines = Line + pCord->PixelsY / 8; + Columns = pCord->StartX + pCord->PixelsX; + if (pIcon != NULL) + { + while (Line < Lines) + { + Column = pCord->StartX; + pDestination = &IOMapDisplay.Display[Line * DISPLAY_WIDTH + Column]; + + while (Column < Columns) + { + *pDestination |= *pIcon; + pIcon++; + pDestination++; + Column++; + } + Line++; + } + } + else + { + while (Line < Lines) + { + pDestination = &IOMapDisplay.Display[Line * DISPLAY_WIDTH + pCord->StartX]; + memset(pDestination,0,(size_t)pCord->PixelsX); + Line++; + } + } + } +} + + +void cDisplayUpdateIcon(ICON *pIcons,UBYTE Index,SCREEN_CORDINATE *pCord) +{ + UBYTE *pSource; + UBYTE *pDestination; + UBYTE Line; + UBYTE Lines; + + if (pIcons) + { + if ((Index > 0) && (Index <= (pIcons->ItemsX * pIcons->ItemsY))) + { + Index--; + if (((pCord->StartY & 0x07) == 0) && ((pCord->PixelsY & 0x07) == 0)) + { + Line = pCord->StartY / 8; + Lines = Line + pCord->PixelsY / 8; + pSource = &pIcons->Data[((Index / pIcons->ItemsX) * pIcons->ItemsX * pIcons->ItemPixelsX * pIcons->ItemPixelsY / 8) + ((Index % pIcons->ItemsX) * pIcons->ItemPixelsX)]; + while (Line < Lines) + { + pDestination = &IOMapDisplay.Display[Line * DISPLAY_WIDTH + pCord->StartX]; + memcpy(pDestination,pSource,(size_t)pCord->PixelsX); + pSource += (pIcons->ItemPixelsX * pIcons->ItemsX); + Line++; + } + } + } + else + { + if (((pCord->StartY & 0x07) == 0) && ((pCord->PixelsY & 0x07) == 0)) + { + Line = pCord->StartY / 8; + Lines = Line + pCord->PixelsY / 8; + while (Line < Lines) + { + pDestination = &IOMapDisplay.Display[Line * DISPLAY_WIDTH + pCord->StartX]; + memset(pDestination,0,(size_t)pCord->PixelsX); + Line++; + } + } + } + } +} + + +void cDisplayLineX(UBYTE X1,UBYTE X2,UBYTE Y) +{ + UBYTE X; + UBYTE M; + + M = 1 << (Y % 8); + Y >>= 3; + for (X = X1;X < X2;X++) + { + IOMapDisplay.Display[Y * DISPLAY_WIDTH + X] |= M; + } +} + +void cDisplayLineY(UBYTE X,UBYTE Y1,UBYTE Y2) +{ + UBYTE Y; + + for (Y = Y1;Y < Y2;Y++) + { + IOMapDisplay.Display[(Y / 8) * DISPLAY_WIDTH + X] |= (1 << (Y % 8)); + } +} + +void cDisplayFrame(SCREEN_CORDINATE *pCord) +{ + cDisplayLineX(pCord->StartX,pCord->StartX + pCord->PixelsX - 1,pCord->StartY); + cDisplayLineY(pCord->StartX,pCord->StartY,pCord->StartY + pCord->PixelsY - 1); + cDisplayLineY(pCord->StartX + pCord->PixelsX - 1,pCord->StartY,pCord->StartY + pCord->PixelsY - 1); +} + + +void cDisplayEraseLine(UBYTE Line) +{ + memset(&IOMapDisplay.Display[Line * DISPLAY_WIDTH], 0x00, DISPLAY_WIDTH); +} + + +void cDisplayErase(void) +{ + memset(&IOMapDisplay.Display[0], 0x00, DISPLAY_WIDTH*DISPLAY_HEIGHT/8); +} + + +void cDisplayEraseScreen(SCREEN_CORDINATE *pCord) +{ + UBYTE *pDestination; + UBYTE Line; + UBYTE Lines; + + if (((pCord->StartY & 0x07) == 0) && ((pCord->PixelsY & 0x07) == 0)) + { + Line = pCord->StartY / 8; + Lines = Line + pCord->PixelsY / 8; + + while (Line < Lines) + { + pDestination = &IOMapDisplay.Display[Line * DISPLAY_WIDTH + pCord->StartX]; + memset(pDestination,0,(size_t)pCord->PixelsX); + Line++; + } + } +} + + +void cDisplayDraw(UBYTE Cmd,UBYTE On,UBYTE X1,UBYTE Y1,UBYTE X2,UBYTE Y2) +{ + switch (Cmd) + { + case DISPLAY_ERASE_ALL : + { + cDisplayErase(); + } + break; + + case DISPLAY_PIXEL : + { + if (On == TRUE) + { + cDisplaySetPixel(X1,Y1); + } + else + { + cDisplayClrPixel(X1,Y1); + } + } + break; + + case DISPLAY_HORISONTAL_LINE : + { + if (On == TRUE) + { + if (X1 > X2) + { + cDisplayLineX(X2,X1,Y1); + } + else + { + cDisplayLineX(X1,X2,Y1); + } + } + } + break; + + case DISPLAY_VERTICAL_LINE : + { + if (On == TRUE) + { + if (Y1 > Y2) + { + cDisplayLineY(X1,Y2,Y1); + } + else + { + cDisplayLineY(X1,Y1,Y2); + } + } + } + break; + + case DISPLAY_CHAR : + { + cDisplayChar(IOMapDisplay.pFont,On,X1,Y1,X2); + } + break; + + } +} + + +void cDisplayInit(void* pHeader) +{ + dDisplayInit(); + IOMapDisplay.Display = (UBYTE*)IOMapDisplay.Normal; + IOMapDisplay.pFunc = &cDisplayDraw; + IOMapDisplay.EraseMask = 0; + IOMapDisplay.UpdateMask = 0; + IOMapDisplay.TextLinesCenterFlags = 0; + IOMapDisplay.Flags = DISPLAY_REFRESH | DISPLAY_ON; + VarsDisplay.ErasePointer = 0; + VarsDisplay.UpdatePointer = 0; +} + + +void cDisplayCtrl(void) +{ + ULONG TmpMask; + UBYTE Tmp; + SCREEN_CORDINATE Cordinate; + + if (!(IOMapDisplay.Flags & DISPLAY_POPUP)) + { + if (IOMapDisplay.Display == (UBYTE*)IOMapDisplay.Popup) + { + IOMapDisplay.Display = VarsDisplay.DisplaySave; + } + } + else + { + if (IOMapDisplay.Display != (UBYTE*)IOMapDisplay.Popup) + { + VarsDisplay.DisplaySave = IOMapDisplay.Display; + IOMapDisplay.Display = (UBYTE*)IOMapDisplay.Popup; + } + } + + if (IOMapDisplay.EraseMask) + { + + VarsDisplay.ErasePointer = 31; + while ((VarsDisplay.ErasePointer) && (!(IOMapDisplay.EraseMask & (0x00000001 << VarsDisplay.ErasePointer)))) + { + VarsDisplay.ErasePointer--; + } + + TmpMask = IOMapDisplay.EraseMask & (1 << VarsDisplay.ErasePointer); + if ((TmpMask & TEXTLINE_BITS)) + { + Tmp = 0; + while (!(TmpMask & TEXTLINE_BIT(Tmp))) + { + Tmp++; + } + if (Tmp < TEXTLINES) + { + cDisplayEraseLine(Tmp); + } + } + else + { + if ((TmpMask & MENUICON_BITS)) + { + Tmp = 0; + while (!(TmpMask & MENUICON_BIT(Tmp))) + { + Tmp++; + } + if (Tmp < MENUICONS) + { + cDisplayEraseScreen((SCREEN_CORDINATE*)&MENUICON_CORDINATES[Tmp]); + } + } + else + { + if ((TmpMask & STATUSICON_BITS)) + { + Tmp = 0; + while (!(TmpMask & STATUSICON_BIT(Tmp))) + { + Tmp++; + } + if (Tmp < STATUSICONS) + { + cDisplayEraseScreen((SCREEN_CORDINATE*)&STATUSICON_CORDINATES[Tmp]); + } + } + else + { + if ((TmpMask & SCREEN_BITS)) + { + Tmp = 0; + while (!(TmpMask & SCREEN_BIT(Tmp))) + { + Tmp++; + } + if (Tmp < SCREENS) + { + cDisplayEraseScreen((SCREEN_CORDINATE*)&SCREEN_CORDINATES[Tmp]); + } + if ((TmpMask & SCREEN_BIT(SCREEN_LARGE))) + { + if ((IOMapDisplay.UpdateMask & SPECIAL_BIT(TOPLINE))) + { + cDisplayLineX(0,DISPLAY_WIDTH - 1,9); + IOMapDisplay.UpdateMask &= ~SPECIAL_BIT(TOPLINE); + } + } + } + else + { + if ((TmpMask & BITMAP_BITS)) + { + Tmp = 0; + while (!(TmpMask & BITMAP_BIT(Tmp))) + { + Tmp++; + } + if (Tmp < BITMAPS) + { + Cordinate.StartX = VarsDisplay.pOldBitmaps[Tmp]->StartX; + Cordinate.StartY = VarsDisplay.pOldBitmaps[Tmp]->StartY; + Cordinate.PixelsX = VarsDisplay.pOldBitmaps[Tmp]->PixelsX; + Cordinate.PixelsY = VarsDisplay.pOldBitmaps[Tmp]->PixelsY; + cDisplayEraseScreen(&Cordinate); + } + } + else + { + if ((TmpMask & SPECIAL_BITS)) + { + Tmp = 0; + while (!(TmpMask & SPECIAL_BIT(Tmp))) + { + Tmp++; + } + switch (Tmp) + { + case FRAME_SELECT : + { + } + break; + + case MENUTEXT : + { + cDisplayEraseLine(TEXTLINE_5); + } + break; + + case STATUSTEXT : + { + cDisplayEraseLine(TEXTLINE_1); + } + break; + + case STEPLINE : + { + } + break; + + case TOPLINE : + { + } + break; + + } + } + else + { + if ((TmpMask & STEPICON_BITS)) + { + Tmp = 0; + while (!(TmpMask & STEPICON_BIT(Tmp))) + { + Tmp++; + } + if (Tmp < STEPICONS) + { + cDisplayEraseScreen((SCREEN_CORDINATE*)&STEPICON_CORDINATES[Tmp]); + } + } + } + } + } + } + } + } + IOMapDisplay.EraseMask &= ~TmpMask; + + if (++VarsDisplay.ErasePointer >= 32) + { + VarsDisplay.ErasePointer = 0; + } + VarsDisplay.UpdatePointer = 0; + } + else + { + if (IOMapDisplay.UpdateMask) + { + + VarsDisplay.UpdatePointer = 31; + while ((VarsDisplay.UpdatePointer) && (!(IOMapDisplay.UpdateMask & (0x00000001 << VarsDisplay.UpdatePointer)))) + { + VarsDisplay.UpdatePointer--; + } + TmpMask = IOMapDisplay.UpdateMask & (0x00000001 << VarsDisplay.UpdatePointer); + + if ((TmpMask & TEXTLINE_BITS)) + { + Tmp = 0; + while (!(TmpMask & TEXTLINE_BIT(Tmp))) + { + Tmp++; + } + if (Tmp < TEXTLINES) + { + if ((IOMapDisplay.TextLinesCenterFlags & (UBYTE)TmpMask)) + { + cDisplayCenterString(IOMapDisplay.pFont,IOMapDisplay.pTextLines[Tmp],TEXTLINE_1 + Tmp); + } + else + { + cDisplayString(IOMapDisplay.pFont,0,Tmp * 8,IOMapDisplay.pTextLines[Tmp]); + } + } + } + else + { + if ((TmpMask & MENUICON_BITS)) + { + Tmp = 0; + while (!(TmpMask & MENUICON_BIT(Tmp))) + { + Tmp++; + } + if (Tmp < MENUICONS) + { + cDisplayUpdateMenuIcon(IOMapDisplay.pMenuIcons[Tmp],(SCREEN_CORDINATE*)&MENUICON_CORDINATES[Tmp]); + } + } + else + { + if ((TmpMask & STATUSICON_BITS)) + { + Tmp = 0; + while (!(TmpMask & STATUSICON_BIT(Tmp))) + { + Tmp++; + } + if (Tmp < STATUSICONS) + { + cDisplayUpdateIcon(IOMapDisplay.pStatusIcons,IOMapDisplay.StatusIcons[Tmp],(SCREEN_CORDINATE*)&STATUSICON_CORDINATES[Tmp]); + } + } + else + { + if ((TmpMask & SCREEN_BITS)) + { + Tmp = 0; + while (!(TmpMask & SCREEN_BIT(Tmp))) + { + Tmp++; + } + if (Tmp < SCREENS) + { + cDisplayUpdateScreen((SCREEN_CORDINATE*)&SCREEN_CORDINATES[Tmp],IOMapDisplay.pScreens[Tmp]); + } + } + else + { + if ((TmpMask & BITMAP_BITS)) + { + Tmp = 0; + while (!(TmpMask & BITMAP_BIT(Tmp))) + { + Tmp++; + } + if (Tmp < BITMAPS) + { + VarsDisplay.pOldBitmaps[Tmp] = IOMapDisplay.pBitmaps[Tmp]; + cDisplayUpdateScreen((SCREEN_CORDINATE*)&SCREEN_CORDINATES[SCREEN_BACKGROUND],IOMapDisplay.pBitmaps[Tmp]); + } + } + else + { + if ((TmpMask & SPECIAL_BITS)) + { + Tmp = 0; + while (!(TmpMask & SPECIAL_BIT(Tmp))) + { + Tmp++; + } + switch (Tmp) + { + case FRAME_SELECT : + { + cDisplayFrame((SCREEN_CORDINATE*)&SELECT_FRAME_CORDINATES); + } + break; + + case MENUTEXT : + { + cDisplayCenterString(IOMapDisplay.pFont,IOMapDisplay.pMenuText,TEXTLINE_5); + } + break; + + case STATUSTEXT : + { + cDisplayCenterString(IOMapDisplay.pFont,IOMapDisplay.pStatusText,TEXTLINE_1); + } + break; + + case STEPLINE : + { + cDisplayLineX(22,28,20); + cDisplayLineX(39,45,20); + cDisplayLineX(56,62,20); + cDisplayLineX(73,79,20); + } + break; + + case TOPLINE : + { + cDisplayLineX(0,DISPLAY_WIDTH - 1,9); + } + break; + + } + } + else + { + if ((TmpMask & STEPICON_BITS)) + { + Tmp = 0; + while (!(TmpMask & STEPICON_BIT(Tmp))) + { + Tmp++; + } + if (Tmp < STEPICONS) + { + cDisplayUpdateIcon(IOMapDisplay.pStepIcons,IOMapDisplay.StepIcons[Tmp],(SCREEN_CORDINATE*)&STEPICON_CORDINATES[Tmp]); + } + } + } + } + } + } + } + } + IOMapDisplay.TextLinesCenterFlags &= (UBYTE)(~TmpMask); + IOMapDisplay.UpdateMask &= ~TmpMask; + if (++VarsDisplay.UpdatePointer >= 32) + { + VarsDisplay.UpdatePointer = 0; + } + } + VarsDisplay.ErasePointer = 0; + } + if (!(IOMapDisplay.Flags & DISPLAY_POPUP)) + { + if (!(IOMapDisplay.Flags & DISPLAY_REFRESH_DISABLED)) + { + if ((IOMapDisplay.Flags & DISPLAY_ON)) + { + dDisplayOn(TRUE); + } + else + { + dDisplayOn(FALSE); + } + if (!(dDisplayUpdate(DISPLAY_HEIGHT,DISPLAY_WIDTH,(UBYTE*)IOMapDisplay.Normal))) + { + IOMapDisplay.Flags &= ~DISPLAY_BUSY; + if (!(IOMapDisplay.Flags & DISPLAY_REFRESH)) + { + IOMapDisplay.Flags |= DISPLAY_REFRESH_DISABLED; + } + } + else + { + IOMapDisplay.Flags |= DISPLAY_BUSY; + } + } + else + { + if ((IOMapDisplay.Flags & DISPLAY_REFRESH)) + { + IOMapDisplay.Flags &= ~DISPLAY_REFRESH_DISABLED; + } + } + } + else + { + dDisplayUpdate(DISPLAY_HEIGHT,DISPLAY_WIDTH,(UBYTE*)IOMapDisplay.Popup); + } +} + + +void cDisplayExit(void) +{ + dDisplayExit(); +} + diff --git a/src/c_display.h b/src/c_display.h new file mode 100644 index 0000000..56b6744 --- /dev/null +++ b/src/c_display.h @@ -0,0 +1,43 @@ +// +// Programmer +// +// Date init 14.12.2004 +// +// Reviser $Author:: Dkandlun $ +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: c_display.h $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_disp $ +// +// Platform C +// + +#ifndef C_DISPLAY +#define C_DISPLAY + +#ifndef INCLUDE_OS + +typedef struct +{ + UBYTE *DisplaySave; + BMPMAP *pOldBitmaps[BITMAPS]; + UBYTE ErasePointer; + UBYTE UpdatePointer; +}VARSDISPLAY; + +#endif + + +void cDisplayInit(void* pHeader); +void cDisplayCtrl(void); +void cDisplayExit(void); + + +extern const HEADER cDisplay; + + +#endif diff --git a/src/c_display.iom b/src/c_display.iom new file mode 100644 index 0000000..2e1ab74 --- /dev/null +++ b/src/c_display.iom @@ -0,0 +1,177 @@ +// +// Programmer +// +// Date init 14.12.2004 +// +// Reviser $Author:: Dkandlun $ +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: c_display.iom $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_disp $ +// +// Platform C +// + +#ifndef CDISPLAY_IOM +#define CDISPLAY_IOM + +#define pMapDisplay ((IOMAPDISPLAY*)(pHeaders[ENTRY_DISPLAY]->pIOMap)) + +// Constants related to simple draw entry (x = dont care) +enum +{ + DISPLAY_ERASE_ALL = 0x00, // W - erase entire screen (CMD,x,x,x,x,x) + DISPLAY_PIXEL = 0x01, // W - set pixel (on/off) (CMD,TRUE/FALSE,X,Y,x,x) + DISPLAY_HORISONTAL_LINE = 0x02, // W - draw horisontal line (CMD,TRUE,X1,Y1,X2,x) + DISPLAY_VERTICAL_LINE = 0x03, // W - draw vertical line (CMD,TRUE,X1,Y1,x,Y2) + DISPLAY_CHAR = 0x04 // W - draw char (actual font) (CMD,TRUE,X1,Y1,Char,x) +}; + +// Constants related to Flags +enum +{ + DISPLAY_ON = 0x01, // W - Display on + DISPLAY_REFRESH = 0x02, // W - Enable refresh + DISPLAY_POPUP = 0x08, // W - Use popup display memory + DISPLAY_REFRESH_DISABLED = 0x40, // R - Refresh disabled + DISPLAY_BUSY = 0x80 // R - Refresh in progress +}; + + +#define DISPLAY_HEIGHT 64 // Y pixels +#define DISPLAY_WIDTH 100 // X pixels + +#define DISPLAY_MENUICONS_Y 40 +#define DISPLAY_MENUICONS_X_OFFS 7 +#define DISPLAY_MENUICONS_X_DIFF 31 + +#define DISPLAY_IDLE ((pMapDisplay->EraseMask == 0) && (pMapDisplay->UpdateMask == 0)) + +enum TEXTLINE_NO // Used in macro "TEXTLINE_BIT" +{ + TEXTLINE_1, // Upper most line + TEXTLINE_2, // + TEXTLINE_3, // + TEXTLINE_4, // + TEXTLINE_5, // + TEXTLINE_6, // + TEXTLINE_7, // + TEXTLINE_8, // Buttom line + TEXTLINES +}; + +enum MENUICON_NO // Used in macro "MENUICON_BIT" +{ + MENUICON_LEFT, // Left icon + MENUICON_CENTER, // Center icon + MENUICON_RIGHT, // Right icon + MENUICONS +}; + +enum SPECIAL_NO // Used in macro "SPECIAL_BIT" +{ + FRAME_SELECT, // Center icon select frame + STATUSTEXT, // Status text (BT name) + MENUTEXT, // Center icon text + STEPLINE, // Step collection lines + TOPLINE, // Top status underline + SPECIALS +}; + +enum STATUSICON_NO // Used in macro "STATUSICON_BIT" +{ + STATUSICON_BLUETOOTH, // BlueTooth status icon collection + STATUSICON_USB, // USB status icon collection + STATUSICON_VM, // VM status icon collection + STATUSICON_BATTERY, // Battery status icon collection + STATUSICONS +}; + +enum SCREEN_NO // Used in macro "SCREEN_BIT" +{ + SCREEN_BACKGROUND, // Entire screen + SCREEN_LARGE, // Entire screen except status line + SCREEN_SMALL, // Screen between menu icons and status line + SCREENS +}; + +enum BITMAP_NO // Used in macro "BITMAP_BIT" +{ + BITMAP_1, // Bitmap 1 + BITMAP_2, // Bitmap 2 + BITMAP_3, // Bitmap 3 + BITMAP_4, // Bitmap 4 + BITMAPS +}; + +enum STEP_NO // Used in macro "STEPICON_BIT" +{ + STEPICON_1, // Left most step icon + STEPICON_2, // + STEPICON_3, // + STEPICON_4, // + STEPICON_5, // Right most step icon + STEPICONS +}; + +#define SCREEN_BITS ((ULONG)0xE0000000) // Executed as 1. +#define STEPICON_BITS ((ULONG)0x1F000000) // Executed as 2. +#define BITMAP_BITS ((ULONG)0x00F00000) // Executed as 3. +#define MENUICON_BITS ((ULONG)0x000E0000) // Executed as 4. +#define STATUSICON_BITS ((ULONG)0x0001E000) // Executed as 5. +#define SPECIAL_BITS ((ULONG)0x00001F00) // Executed as 6. +#define TEXTLINE_BITS ((ULONG)0x000000FF) // Executed as 7. + +#define SCREEN_BIT(No) ((ULONG)0x20000000 << (No)) +#define STEPICON_BIT(No) ((ULONG)0x01000000 << (No)) +#define BITMAP_BIT(No) ((ULONG)0x00100000 << (No)) +#define MENUICON_BIT(No) ((ULONG)0x00020000 << (No)) +#define STATUSICON_BIT(No) ((ULONG)0x00002000 << (No)) +#define SPECIAL_BIT(No) ((ULONG)0x00000100 << (No)) +#define TEXTLINE_BIT(No) ((ULONG)0x00000001 << (No)) + + +typedef struct +{ + void (*pFunc)(UBYTE,UBYTE,UBYTE,UBYTE,UBYTE,UBYTE); // Simple draw entry + + ULONG EraseMask; // Section erase mask (executed first) + ULONG UpdateMask; // Section update mask (executed next) + + FONT *pFont; // Pointer to font file + UBYTE *pTextLines[TEXTLINES]; // Pointer to text strings + + UBYTE *pStatusText; // Pointer to status text string + ICON *pStatusIcons; // Pointer to status icon collection file + + BMPMAP *pScreens[SCREENS]; // Pointer to screen bitmap file + BMPMAP *pBitmaps[BITMAPS]; // Pointer to free bitmap files + + UBYTE *pMenuText; // Pointer to menu icon text (NULL == none) + UBYTE *pMenuIcons[MENUICONS]; // Pointer to menu icon images (NULL == none) + + ICON *pStepIcons; // Pointer to step icon collection file + + UBYTE *Display; // Display content copied to physical display every 17 mS + + UBYTE StatusIcons[STATUSICONS]; // Index in status icon collection file (index = 0 -> none) + + UBYTE StepIcons[STEPICONS]; // Index in step icon collection file (index = 0 -> none) + + UBYTE Flags; // Update flags enumerated above + + UBYTE TextLinesCenterFlags; // Mask to center TextLines + + UBYTE Normal[DISPLAY_HEIGHT / 8][DISPLAY_WIDTH]; // Raw display memory for normal screen + UBYTE Popup[DISPLAY_HEIGHT / 8][DISPLAY_WIDTH]; // Raw display memory for popup screen +} +IOMAPDISPLAY; + +#endif + + + diff --git a/src/c_input.c b/src/c_input.c new file mode 100644 index 0000000..2cb9be1 --- /dev/null +++ b/src/c_input.c @@ -0,0 +1,1335 @@ + +// +// Date init 14.12.2004 +// +// Revision date $Date:: 3/21/09 10:31a $ +// +// Filename $Workfile:: c_input.c $ +// +// Version $Revision:: 39 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_inpu $ +// +// Platform C +// + +#include "stdconst.h" +#include "modules.h" +#include "c_input.h" +#include "d_input.h" +#include "c_output.iom" +#include "c_loader.iom" +#include + + +#define INVALID_RELOAD_NORMAL 20 +#define INVALID_RELOAD_SOUND 300 +#define INVALID_RELOAD_COLOR 400 + +#define ROT_SLOW_SPEED 30 +#define ROT_OV_SAMPLING 7 + +#define VCC_SENSOR 5000L +#define VCC_SENSOR_DIODE 4300L +#define AD_MAX 1023L + +#define REFLECTIONSENSORMIN (1906L/(VCC_SENSOR/AD_MAX)) +#define REFLECTIONSENSORMAX ((AD_MAX * 4398L)/VCC_SENSOR) +#define REFLECTIONSENSORPCTDYN (UBYTE)(((REFLECTIONSENSORMAX - REFLECTIONSENSORMIN) * 100L)/AD_MAX) + +#define NEWLIGHTSENSORMIN (800L/(VCC_SENSOR/AD_MAX)) +#define NEWLIGHTSENSORMAX ((AD_MAX * 4400L)/VCC_SENSOR) +#define NEWLIGHTSENSORPCTDYN (UBYTE)(((NEWLIGHTSENSORMAX - NEWLIGHTSENSORMIN) * 100L)/AD_MAX) + +#define NEWSOUNDSENSORMIN (650L/(VCC_SENSOR/AD_MAX)) +#define NEWSOUNDSENSORMAX ((AD_MAX * 4980L)/VCC_SENSOR) +#define NEWSOUNDSENSORPCTDYN (UBYTE)(((NEWSOUNDSENSORMAX - NEWSOUNDSENSORMIN) * 100L)/AD_MAX) + +/* Remember this is ARM AD converter - 3,3 VDC as max voltage */ +/* When in color mode background value is substracted => min = 0!!! */ +#define COLORSENSORBGMIN (214/(3300/AD_MAX)) +#define COLORSENSORMIN (1L/(3300/AD_MAX)) /* 1 inserted else div 0 (1L/(120/AD_MAX)) */ +#define COLORSENSORMAX ((AD_MAX * 3300L)/3300) +#define COLORSENSORPCTDYN (UBYTE)(((COLORSENSORMAX - COLORSENSORMIN) * 100L)/AD_MAX) +#define COLORSENSORBGPCTDYN (UBYTE)(((COLORSENSORMAX - COLORSENSORBGMIN) * 100L)/AD_MAX) + +enum +{ + POWER = 0x00, + NO_POWER = 0x01, + ACTIVE = 0x02, + ALWAYS_ACTIVE = 0x04, + DIGI_0_HIGH = 0x08, + DIGI_1_HIGH = 0x10, + DIGI_0_IN = 0x20, + DIGI_1_IN = 0x40, + CUSTOM_SETUP = 0x80 +}; + +static IOMAPINPUT IOMapInput; +static VARSINPUT VarsInput; + +const HEADER cInput = +{ + 0x00030001L, + "Input", + cInputInit, + cInputCtrl, + cInputExit, + (void *)&IOMapInput, + (void *)&VarsInput, + (UWORD)sizeof(IOMapInput), + (UWORD)sizeof(VarsInput), + 0x0000 //Code size - not used so far +}; + +void cInputCalcFullScale(UWORD *pRawVal, UWORD ZeroPointOffset, UBYTE PctFullScale, UBYTE InvState); +void cInputCalcSensorValue(UWORD NewSensorRaw, UWORD *pOldSensorRaw, SWORD *pSensorValue, + UBYTE *pBoolean, UBYTE *pDebounce, UBYTE *pSampleCnt, + UBYTE *LastAngle, UBYTE *pEdgeCnt, UBYTE Slope, + UBYTE Mode); +void cInputSetupType(UBYTE Port, UBYTE *pType, UBYTE OldType); +void cInputSetupCustomSensor(UBYTE Port); +void cInputCalcSensorValues(UBYTE No); +UBYTE cInputInitColorSensor(UBYTE Port, UBYTE *pInitStatus); +void cInputCalibrateColor(COLORSTRUCT *pC, UWORD *pNewVals); +SWORD cInputTempConv(UWORD InputVal); + +void cInputInit(void* pHeader) +{ + UBYTE Tmp; + + memset(IOMapInput.Colors, 0, sizeof(IOMapInput.Colors)); + memset(VarsInput.VarsColor, 0, sizeof(VarsInput.VarsColor)); + + /* Init IO map */ + for (Tmp = 0; Tmp < NO_OF_INPUTS; Tmp++) + { + IOMapInput.Inputs[Tmp].SensorType = NO_SENSOR; + IOMapInput.Inputs[Tmp].SensorMode = RAWMODE; + IOMapInput.Inputs[Tmp].SensorRaw = 0; + IOMapInput.Inputs[Tmp].SensorValue = 0; + IOMapInput.Inputs[Tmp].SensorBoolean = 0; + IOMapInput.Inputs[Tmp].InvalidData = INVALID_DATA; + IOMapInput.Inputs[Tmp].DigiPinsDir = 0; + IOMapInput.Inputs[Tmp].DigiPinsOut = 0; + IOMapInput.Inputs[Tmp].CustomActiveStatus = CUSTOMINACTIVE; + IOMapInput.Inputs[Tmp].CustomZeroOffset = 0; + IOMapInput.Inputs[Tmp].CustomPctFullScale = 0; + dInputRead0(Tmp, &(IOMapInput.Inputs[Tmp].DigiPinsIn)); + dInputRead1(Tmp, &(IOMapInput.Inputs[Tmp].DigiPinsIn)); + + VarsInput.EdgeCnt[Tmp] = 0; + VarsInput.InputDebounce[Tmp] = 0; + VarsInput.LastAngle[Tmp] = 0; + VarsInput.SampleCnt[Tmp] = 0; + VarsInput.InvalidTimer[Tmp] = INVALID_RELOAD_NORMAL; + VarsInput.OldSensorType[Tmp] = NO_SENSOR; + } + + VarsInput.ColorStatus = 0; + VarsInput.ColorCnt = 0; + + dInputInit(); +} + +void cInputCtrl(void) +{ + UBYTE Tmp; + + + if (VarsInput.ColorStatus) + { + switch(VarsInput.ColorCnt) + { + case 0: + { + VarsInput.ColorCnt = 1; + dInputSetColorClkInput(); + + } + break; + case 1: + { + VarsInput.ColorCnt = 2; + } + break; + case 2: + { + VarsInput.ColorCnt = 0; + dInputGetAllColors(IOMapInput.Colors, VarsInput.ColorStatus); + } + break; + default: + { + VarsInput.ColorCnt = 0; + } + break; + } + } + + for (Tmp = 0; Tmp < NO_OF_INPUTS; Tmp++) + { + UBYTE sType = IOMapInput.Inputs[Tmp].SensorType; + UBYTE *pType = &IOMapInput.Inputs[Tmp].SensorType; + UBYTE oldType = VarsInput.OldSensorType[Tmp]; + + if (sType != oldType) + { + + /* Clear all variables for this sensor */ + VarsInput.EdgeCnt[Tmp] = 0; + VarsInput.InputDebounce[Tmp] = 0; + VarsInput.LastAngle[Tmp] = 0; + VarsInput.SampleCnt[Tmp] = 0; + VarsInput.ColorStatus &= ~(0x01< 928) + InputVal = 928; + InputVal = cInputTempConv(InputVal - 290); + InputVal = InputVal + 200; + InputVal = (UWORD)(((SLONG)InputVal * (SLONG)1023)/(SLONG)900); + } + else if (sType == LIGHT_ACTIVE || sType == LIGHT_INACTIVE) + { + cInputCalcFullScale(&InputVal, NEWLIGHTSENSORMIN, NEWLIGHTSENSORPCTDYN, TRUE); + } + else if (sType == SOUND_DB || sType == SOUND_DBA) + { + cInputCalcFullScale(&InputVal, NEWSOUNDSENSORMIN, NEWSOUNDSENSORPCTDYN, TRUE); + } + else if (sType == CUSTOM) + { + cInputCalcFullScale(&InputVal, IOMapInput.Inputs[No].CustomZeroOffset, IOMapInput.Inputs[No].CustomPctFullScale, FALSE); + } + cInputCalcSensorValue( InputVal, + &(IOMapInput.Inputs[No].SensorRaw), + &(IOMapInput.Inputs[No].SensorValue), + &(IOMapInput.Inputs[No].SensorBoolean), + &(VarsInput.InputDebounce[No]), + &(VarsInput.SampleCnt[No]), + &(VarsInput.LastAngle[No]), + &(VarsInput.EdgeCnt[No]), + ((IOMapInput.Inputs[No].SensorMode) & SLOPEMASK), + ((IOMapInput.Inputs[No].SensorMode) & MODEMASK)); + } + break; + + /* Tripple case intended */ + case LOWSPEED: + case LOWSPEED_9V: + case HIGHSPEED: + { + } + break; + + /* Four cases intended */ + case COLORRED: + case COLORGREEN: + case COLORBLUE: + case COLORNONE: + { + + UWORD InputVal; + switch (IOMapInput.Colors[No].CalibrationState) + { + case SENSOROFF: + { + + /* Make sure that sensor data are invalid while unplugged*/ + VarsInput.InvalidTimer[No] = INVALID_RELOAD_COLOR; + IOMapInput.Inputs[No].InvalidData = INVALID_DATA; + + /* Check if sensor has been attached */ + if (dInputCheckColorStatus(No)) + { + + /* Sensor has been attached now get cal data */ + VarsInput.VarsColor[No].ColorInitState = 0; + (IOMapInput.Colors[No].CalibrationState) = SENSORCAL; + } + } + break; + case SENSORCAL: + { + + UBYTE Status; + if (FALSE == cInputInitColorSensor(No, &Status)) + { + + /* Color sensor has been removed during calibration */ + (IOMapInput.Colors[No].CalibrationState) = SENSOROFF; + } + + if (TRUE == Status) + { + + /* Use clock to detect errors */ + dInputSetDirInDigi0(No); + (IOMapInput.Colors[No].CalibrationState) = 0; + } + } + break; + default: + { + if (dInputGetColor(No, &(IOMapInput.Inputs[No].ADRaw))) + { + InputVal = IOMapInput.Inputs[No].ADRaw; + cInputCalcFullScale(&InputVal, COLORSENSORBGMIN, COLORSENSORBGPCTDYN, FALSE); + cInputCalcSensorValue(InputVal, + &(IOMapInput.Inputs[No].SensorRaw), + &(IOMapInput.Inputs[No].SensorValue), + &(IOMapInput.Inputs[No].SensorBoolean), + &(VarsInput.InputDebounce[No]), + &(VarsInput.SampleCnt[No]), + &(VarsInput.LastAngle[No]), + &(VarsInput.EdgeCnt[No]), + ((IOMapInput.Inputs[No].SensorMode) & SLOPEMASK), + ((IOMapInput.Inputs[No].SensorMode) & MODEMASK)); + } + else + { + IOMapInput.Colors[No].CalibrationState = SENSOROFF; + } + } + break; + } + } + break; + case COLORFULL: + { + switch (IOMapInput.Colors[No].CalibrationState) + { + case SENSOROFF: + { + + /* Make sure that sensor data are invalid while unplugged */ + VarsInput.InvalidTimer[No] = INVALID_RELOAD_COLOR; + IOMapInput.Inputs[No].InvalidData = INVALID_DATA; + + /* Check if sensor has been attached */ + if (dInputCheckColorStatus(No)) + { + + /* Sensor has been attached now get cal data */ + VarsInput.VarsColor[No].ColorInitState = 0; + (IOMapInput.Colors[No].CalibrationState) = SENSORCAL; + } + } + break; + case SENSORCAL: + { + UBYTE Status; + + if (FALSE == cInputInitColorSensor(No, &Status)) + { + + /* Color sensor has been removed during calibration */ + (IOMapInput.Colors[No].CalibrationState) = SENSOROFF; + VarsInput.ColorStatus &= ~(0x01<SensorRaw[RED]) > (pC->SensorRaw[BLUE] )) && + ((pC->SensorRaw[RED]) > (pC->SensorRaw[GREEN]))) + { + + /* If all 3 colors are less than 65 OR (Less that 110 and bg less than 40)*/ + if (((pC->SensorRaw[RED]) < 65) || + (((pC->SensorRaw[BLANK]) < 40) && ((pC->SensorRaw[RED]) < 110))) + { + IOMapInput.Inputs[No].SensorValue = BLACKCOLOR; + } + else + { + if (((((pC->SensorRaw[BLUE]) >> 2) + ((pC->SensorRaw[BLUE]) >> 3) + (pC->SensorRaw[BLUE])) < (pC->SensorRaw[GREEN])) && + ((((pC->SensorRaw[GREEN]) << 1)) > (pC->SensorRaw[RED]))) + { + IOMapInput.Inputs[No].SensorValue = YELLOWCOLOR; + } + else + { + + if ((((pC->SensorRaw[GREEN]) << 1) - ((pC->SensorRaw[GREEN]) >> 2)) < (pC->SensorRaw[RED])) + { + + IOMapInput.Inputs[No].SensorValue = REDCOLOR; + } + else + { + + if ((((pC->SensorRaw[BLUE]) < 70) || + ((pC->SensorRaw[GREEN]) < 70)) || + (((pC->SensorRaw[BLANK]) < 140) && ((pC->SensorRaw[RED]) < 140))) + { + IOMapInput.Inputs[No].SensorValue = BLACKCOLOR; + } + else + { + IOMapInput.Inputs[No].SensorValue = WHITECOLOR; + } + } + } + } + } + else + { + + /* Red is not the dominant color */ + if ((pC->SensorRaw[GREEN]) > (pC->SensorRaw[BLUE])) + { + + /* Green is the dominant color */ + /* If all 3 colors are less than 40 OR (Less that 70 and bg less than 20)*/ + if (((pC->SensorRaw[GREEN]) < 40) || + (((pC->SensorRaw[BLANK]) < 30) && ((pC->SensorRaw[GREEN]) < 70))) + { + IOMapInput.Inputs[No].SensorValue = BLACKCOLOR; + } + else + { + if ((((pC->SensorRaw[BLUE]) << 1)) < (pC->SensorRaw[RED])) + { + IOMapInput.Inputs[No].SensorValue = YELLOWCOLOR; + } + else + { + if ((((pC->SensorRaw[RED]) + ((pC->SensorRaw[RED])>>2)) < (pC->SensorRaw[GREEN])) || + (((pC->SensorRaw[BLUE]) + ((pC->SensorRaw[BLUE])>>2)) < (pC->SensorRaw[GREEN]))) + { + IOMapInput.Inputs[No].SensorValue = GREENCOLOR; + } + else + { + if ((((pC->SensorRaw[RED]) < 70) || + ((pC->SensorRaw[BLUE]) < 70)) || + (((pC->SensorRaw[BLANK]) < 140) && ((pC->SensorRaw[GREEN]) < 140))) + { + IOMapInput.Inputs[No].SensorValue = BLACKCOLOR; + } + else + { + IOMapInput.Inputs[No].SensorValue = WHITECOLOR; + } + } + } + } + } + else + { + + /* Blue is the most dominant color */ + /* Colors can be blue, white or black */ + /* If all 3 colors are less than 48 OR (Less that 85 and bg less than 25)*/ + if (((pC->SensorRaw[BLUE]) < 48) || + (((pC->SensorRaw[BLANK]) < 25) && ((pC->SensorRaw[BLUE]) < 85))) + { + IOMapInput.Inputs[No].SensorValue = BLACKCOLOR; + } + else + { + if ((((((pC->SensorRaw[RED]) * 48) >> 5) < (pC->SensorRaw[BLUE])) && + ((((pC->SensorRaw[GREEN]) * 48) >> 5) < (pC->SensorRaw[BLUE]))) + || + (((((pC->SensorRaw[RED]) * 58) >> 5) < (pC->SensorRaw[BLUE])) || + ((((pC->SensorRaw[GREEN]) * 58) >> 5) < (pC->SensorRaw[BLUE])))) + { + IOMapInput.Inputs[No].SensorValue = BLUECOLOR; + } + else + { + + /* Color is white or Black */ + if ((((pC->SensorRaw[RED]) < 60) || + ((pC->SensorRaw[GREEN]) < 60)) || + (((pC->SensorRaw[BLANK]) < 110) && ((pC->SensorRaw[BLUE]) < 120))) + { + IOMapInput.Inputs[No].SensorValue = BLACKCOLOR; + } + else + { + if ((((pC->SensorRaw[RED]) + ((pC->SensorRaw[RED]) >> 3)) < (pC->SensorRaw[BLUE])) || + (((pC->SensorRaw[GREEN]) + ((pC->SensorRaw[GREEN]) >> 3)) < (pC->SensorRaw[BLUE]))) + { + IOMapInput.Inputs[No].SensorValue = BLUECOLOR; + } + else + { + IOMapInput.Inputs[No].SensorValue = WHITECOLOR; + } + } + } + } + } + } + } + else + { + IOMapInput.Colors[No].CalibrationState = SENSOROFF; + VarsInput.ColorStatus &= ~(0x01< THRESHOLD_FALSE) + { + PresentBoolean = FALSE; + } + else + { + if (NewSensorRaw < THRESHOLD_TRUE) + { + PresentBoolean = TRUE; + } + } + } + else + { + + /* This is dynamic measure method */ + if (NewSensorRaw > (ACTUAL_AD_RES - Slope)) + { + PresentBoolean = FALSE; + } + else + { + if (NewSensorRaw < Slope) + { + PresentBoolean = TRUE; + } + else + { + Delta = *pOldSensorRaw - NewSensorRaw; + if (Delta < 0) + { + if (-Delta > Slope) + { + PresentBoolean = FALSE; + } + } + else + { + if (Delta > Slope) + { + PresentBoolean = TRUE; + } + } + } + } + } + *pOldSensorRaw = NewSensorRaw; + + switch(Mode) + { + + case RAWMODE: + { + *pSensorValue = NewSensorRaw; + } + break; + + case BOOLEANMODE: + { + *pSensorValue = PresentBoolean; + } + break; + + case TRANSITIONCNTMODE: + { + if ((*pDebounce) > 0) + { + (*pDebounce)--; + } + else + { + if (*pBoolean != PresentBoolean) + { + (*pDebounce) = DEBOUNCERELOAD; + (*pSensorValue)++; + } + } + } + break; + + case PERIODCOUNTERMODE: + { + if ((*pDebounce) > 0) + { + (*pDebounce)--; + } + else + { + if (*pBoolean != PresentBoolean) + { + (*pDebounce) = DEBOUNCERELOAD; + *pBoolean = PresentBoolean; + if (++(*pEdgeCnt) > 1) + { + if (PresentBoolean == 0) + { + (*pEdgeCnt) = 0; + (*pSensorValue)++; + } + } + } + } + } + break; + + case PCTFULLSCALEMODE: + { + + /* Output is 0-100 pct */ + *pSensorValue = ((NewSensorRaw) * 100)/SENSOR_RESOLUTION; + } + break; + + case FAHRENHEITMODE: + { + + /* Fahrenheit mode goes from -40 to 158 degrees */ + *pSensorValue = (((ULONG)(NewSensorRaw) * 900L)/SENSOR_RESOLUTION) - 200; + *pSensorValue = ((180L * (ULONG)(*pSensorValue))/100L) + 320; + } + break; + + case CELSIUSMODE: + { + + /* Celsius mode goes from -20 to 70 degrees */ + *pSensorValue = (((ULONG)(NewSensorRaw * 900L)/SENSOR_RESOLUTION) - 200); + } + break; + + case ANGLESTEPSMODE: + { + *pBoolean = PresentBoolean; + + if (NewSensorRaw < ANGLELIMITA) + { + Sample = 0; + } + else + { + if (NewSensorRaw < ANGLELIMITB) + { + Sample = 1; + } + else + { + if (NewSensorRaw < ANGLELIMITC) + { + Sample = 2; + } + else + { + Sample = 3; + } + } + } + + switch (*LastAngle) + { + case 0 : + { + if (Sample == 1) + { + if ((*pSampleCnt) >= ROT_SLOW_SPEED ) + { + + if (++(*pSampleCnt) >= (ROT_SLOW_SPEED + ROT_OV_SAMPLING)) + { + (*pSensorValue)++; + (*LastAngle) = Sample; + } + } + else + { + (*pSensorValue)++; + (*LastAngle) = Sample; + } + } + if (Sample == 2) + { + (*pSensorValue)--; + (*LastAngle) = Sample; + } + if (Sample == 0) + { + if ((*pSampleCnt) < ROT_SLOW_SPEED) + { + (*pSampleCnt)++; + } + } + } + break; + case 1 : + { + if (Sample == 3) + { + (*pSensorValue)++; + (*LastAngle) = Sample; + } + if (Sample == 0) + { + (*pSensorValue)--; + (*LastAngle) = Sample; + } + (*pSampleCnt) = 0; + } + break; + case 2 : + { + if (Sample == 0) + { + (*pSensorValue)++; + (*LastAngle) = Sample; + } + if (Sample == 3) + { + (*pSensorValue)--; + (*LastAngle) = Sample; + } + (*pSampleCnt) = 0; + } + break; + case 3 : + { + if (Sample == 2) + { + if ((*pSampleCnt) >= ROT_SLOW_SPEED) + { + + if (++(*pSampleCnt) >= (ROT_SLOW_SPEED + ROT_OV_SAMPLING)) + { + (*pSensorValue)++; + (*LastAngle) = Sample; + } + } + else + { + (*pSensorValue)++; + (*LastAngle) = Sample; + } + } + if (Sample == 1) + { + (*pSensorValue)--; + (*LastAngle) = Sample; + } + if (Sample == 3) + { + if ((*pSampleCnt) < ROT_SLOW_SPEED) + { + (*pSampleCnt)++; + } + } + } + break; + } + } + } + + *pBoolean = PresentBoolean; +} + +void cInputCalcFullScale(UWORD *pRawVal, UWORD ZeroPointOffset, UBYTE PctFullScale, UBYTE InvStatus) +{ + if (*pRawVal >= ZeroPointOffset) + { + *pRawVal -= ZeroPointOffset; + } + else + { + *pRawVal = 0; + } + + *pRawVal = (*pRawVal * 100)/PctFullScale; + if (*pRawVal > SENSOR_RESOLUTION) + { + *pRawVal = SENSOR_RESOLUTION; + } + if (TRUE == InvStatus) + { + *pRawVal = SENSOR_RESOLUTION - *pRawVal; + } +} + + +void cInputSetupType(UBYTE Port, UBYTE *pType, UBYTE OldType) +{ + + VarsInput.InvalidTimer[Port] = INVALID_RELOAD_NORMAL; + + /* If old type is color sensor in color lamp mode then turn off leds */ + switch (OldType) + { + case COLORRED: + case COLORGREEN: + case COLORBLUE: + case COLORFULL: + case COLOREXIT: + { + if (NO_SENSOR == *pType) + { + VarsInput.InvalidTimer[Port] = INVALID_RELOAD_COLOR; + *pType = COLOREXIT; + } + } + break; + } + switch(*pType) + { + case NO_SENSOR: + case SWITCH: + case TEMPERATURE: + { + dInputSetInactive(Port); + dInputSetDirInDigi0(Port); + dInputSetDirInDigi1(Port); + } + break; + + case REFLECTION: + case ANGLE: + { + dInputSetActive(Port); + dInputClearDigi0(Port); + dInputClearDigi1(Port); + } + break; + + case LIGHT_ACTIVE: + { + dInputSetInactive(Port); + dInputSetDigi0(Port); + dInputClearDigi1(Port); + } + break; + + case LIGHT_INACTIVE: + { + dInputSetInactive(Port); + dInputClearDigi0(Port); + dInputClearDigi1(Port); + } + break; + + case SOUND_DB: + { + VarsInput.InvalidTimer[Port] = INVALID_RELOAD_SOUND; + dInputSetInactive(Port); + dInputSetDigi0(Port); + dInputClearDigi1(Port); + } + break; + + case SOUND_DBA: + { + VarsInput.InvalidTimer[Port] = INVALID_RELOAD_SOUND; + dInputSetInactive(Port); + dInputClearDigi0(Port); + dInputSetDigi1(Port); + } + break; + + case CUSTOM: + { + cInputSetupCustomSensor(Port); + } + break; + + case LOWSPEED: + { + dInputSetInactive(Port); + dInputSetDigi0(Port); + dInputSetDigi1(Port); + } + break; + + case LOWSPEED_9V: + { + dInputSet9v(Port); + dInputSetDigi0(Port); + dInputSetDigi1(Port); + } + break; + + case HIGHSPEED: + { + dInputSetInactive(Port); + dInputSetDirInDigi0(Port); + dInputSetDirInDigi1(Port); + } + break; + + case COLORFULL: + case COLORRED: + case COLORGREEN: + case COLORBLUE: + case COLORNONE: + { + VarsInput.InvalidTimer[Port] = INVALID_RELOAD_COLOR; + dInputSetInactive(Port); + dInputSetDigi0(Port); + dInputSetDirInDigi1(Port); + IOMapInput.Colors[Port].CalibrationState = SENSORCAL; + VarsInput.VarsColor[Port].ColorInitState = 0; + } + break; + + default: + { + } + break; + } +} + +void cInputSetupCustomSensor(UBYTE Port) +{ + if ((IOMapInput.Inputs[Port].DigiPinsDir) & 0x01) + { + if ((IOMapInput.Inputs[Port].DigiPinsOut) & 0x01) + { + dInputSetDigi0(Port); + } + else + { + dInputClearDigi0(Port); + } + } + if ((IOMapInput.Inputs[Port].DigiPinsDir) & 0x02) + { + if ((IOMapInput.Inputs[Port].DigiPinsOut) & 0x02) + { + dInputSetDigi1(Port); + } + else + { + dInputClearDigi1(Port); + } + } + else + { + dInputSetDirInDigi1(Port); + } + + if (CUSTOMACTIVE == (IOMapInput.Inputs[Port].CustomActiveStatus)) + { + dInputSetActive(Port); + } + else + { + if (CUSTOM9V == (IOMapInput.Inputs[Port].CustomActiveStatus)) + { + dInputSet9v(Port); + } + else + { + dInputSetInactive(Port); + } + } +} + + +SWORD cInputTempConv(UWORD InputVal) +{ + static const long long TempCoeff[] = { -5425ll, 9261399ll, -6686663252ll, + 2573629857807ll, -822478326197838ll, 195856762719738784ll }; + const unsigned int TempCoeffShift = 48; + /* Replace the original table with polynomial. */ + int i; + long long Input = InputVal; + long long Output = TempCoeff[0]; + for (i = 1; i < sizeof TempCoeff / sizeof TempCoeff[0]; i++) + Output = Output * Input + TempCoeff[i]; + /* Round. */ + return Output + (1ll << TempCoeffShift - 1) >> TempCoeffShift; +} + + +UBYTE cInputInitColorSensor(UBYTE Port, UBYTE *pInitStatus) +{ + + *pInitStatus = FALSE; + switch(VarsInput.VarsColor[Port].ColorInitState) + { + case 0: + { + dInputSetDigi0(Port); + dInputSetDigi1(Port); + VarsInput.VarsColor[Port].ColorInitState++; + } + break; + case 1: + { + dInputClearDigi0(Port); + VarsInput.VarsColor[Port].ColorInitState++; + } + break; + + case 2: + { + dInputSetDigi0(Port); + VarsInput.VarsColor[Port].ColorInitState++; + } + break; + case 3: + { + + dInputClearDigi0(Port); + + /* Clear clock for 100mS - use pit timer*/ + dInputClearColor100msTimer(Port); + VarsInput.VarsColor[Port].ColorInitState++; + } + break; + case 4: + { + + /* Wait 100mS */ + if (dInputChkColor100msTimer(Port)) + { + VarsInput.VarsColor[Port].ColorInitState += 1; + } + } + break; + case 5: + { + UBYTE TmpType; + + if (COLOREXIT == IOMapInput.Inputs[Port].SensorType) + { + TmpType = COLORNONE; + } + else + { + TmpType = IOMapInput.Inputs[Port].SensorType; + } + dInputColorTx(Port, TmpType); + + /* Be ready to receive data from sensor */ + dInputSetDirInDigi1(Port); + VarsInput.VarsColor[Port].ReadCnt = 0; + VarsInput.VarsColor[Port].ColorInitState++; + } + break; + case 6: + { + UBYTE Data; + UBYTE DataCnt; + UBYTE *pData; + + DataCnt = (VarsInput.VarsColor[Port].ReadCnt); + pData = (UBYTE*)(IOMapInput.Colors[Port].Calibration); + + /* Read first byte of cal data */ + dInputReadCal(Port, &Data); + + pData[DataCnt] = Data; + + /* If all bytes has been read - then continue to next step */ + if (++(VarsInput.VarsColor[Port].ReadCnt) >= ((sizeof(IOMapInput.Colors[Port].Calibration) + sizeof(IOMapInput.Colors[Port].CalLimits)))) + { + VarsInput.VarsColor[Port].ColorInitState++; + } + } + break; + case 7: + { + + /* Check CRC then continue or restart if false */ + UWORD Crc, CrcCheck; + UBYTE Cnt; + UBYTE Data; + UBYTE *pData; + + dInputReadCal(Port, &Data); + Crc = (UWORD)(Data) << 8; + dInputReadCal(Port, &Data); + Crc += (UWORD)Data; + CrcCheck = 0x5AA5; + pData = (UBYTE*)(IOMapInput.Colors[Port].Calibration); + for (Cnt = 0; Cnt < (sizeof(IOMapInput.Colors[Port].Calibration) + sizeof(IOMapInput.Colors[Port].CalLimits)); Cnt++) + { + UWORD i,j; + UBYTE c; + c = pData[Cnt]; + for(i = 0; i != 8; c >>= 1, i++) + { + j = (c^CrcCheck) & 1; + CrcCheck >>= 1; + + if(j) + { + CrcCheck ^= 0xA001; + } + } + + } + if ((CrcCheck != Crc)) + { + + /* incorrect!!! try again */ + VarsInput.VarsColor[Port].ColorInitState = 0; + VarsInput.InvalidTimer[Port] = INVALID_RELOAD_COLOR; + } + else + { + + /* Correct crc sum -> calculate the calibration values then exit */ + VarsInput.VarsColor[Port].ColorInitState = 0; + + /* Sensor is almost ready - needs a little time to make first measurements */ + VarsInput.InvalidTimer[Port] = 10; + *pInitStatus = TRUE; + } + } + break; + default: + { + VarsInput.VarsColor[Port].ColorInitState = 0; + } + break; + } + return(dInputCheckColorStatus(Port)); +} + + +void cInputCalibrateColor(COLORSTRUCT *pC, UWORD *pNewVals) +{ + UBYTE CalRange; + + if ((pC->ADRaw[BLANK]) < pC->CalLimits[1]) + { + CalRange = 2; + } + else + { + if ((pC->ADRaw[BLANK]) < pC->CalLimits[0]) + { + CalRange = 1; + } + else + { + CalRange = 0; + } + } + + pNewVals[RED] = 0; + if ((pC->ADRaw[RED]) > (pC->ADRaw[BLANK])) + { + pNewVals[RED] = (UWORD)(((ULONG)((pC->ADRaw[RED]) - (pC->ADRaw[BLANK])) * (pC->Calibration[CalRange][RED])) >> 16); + } + + pNewVals[GREEN] = 0; + if ((pC->ADRaw[GREEN]) > (pC->ADRaw[BLANK])) + { + pNewVals[GREEN] = (UWORD)(((ULONG)((pC->ADRaw[GREEN]) - (pC->ADRaw[BLANK])) * (pC->Calibration[CalRange][GREEN])) >> 16); + } + + pNewVals[BLUE] = 0; + if ((pC->ADRaw[BLUE]) > (pC->ADRaw[BLANK])) + { + pNewVals[BLUE] = (UWORD)(((ULONG)((pC->ADRaw[BLUE]) -(pC->ADRaw[BLANK])) * (pC->Calibration[CalRange][BLUE])) >> 16); + } + + pNewVals[BLANK] = (pC->ADRaw[BLANK]); + cInputCalcFullScale(&(pNewVals[BLANK]), COLORSENSORBGMIN, COLORSENSORBGPCTDYN, FALSE); + (pNewVals[BLANK]) = (UWORD)(((ULONG)(pNewVals[BLANK]) * (pC->Calibration[CalRange][BLANK])) >> 16); +} + + +void cInputExit(void) +{ + dInputExit(); +} + diff --git a/src/c_input.h b/src/c_input.h new file mode 100644 index 0000000..4e508f3 --- /dev/null +++ b/src/c_input.h @@ -0,0 +1,67 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 14-01-09 10:33 $ +// +// Filename $Workfile:: c_input.h $ +// +// Version $Revision:: 7 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_inpu $ +// +// Platform C +// + +#ifndef C_INPUT +#define C_INPUT + +#ifdef INCLUDE_OS +extern const HEADER cInput; +#endif + +#include "c_input.iom" + +#define ACTUAL_AD_RES 1023L +#define SENSOR_RESOLUTION 1023L +#define DEBOUNCERELOAD 100 +#define THRESHOLD_FALSE (UWORD)(ACTUAL_AD_RES * 45L / 100L) +#define THRESHOLD_TRUE (UWORD)(ACTUAL_AD_RES * 55L / 100L) + +#define ANGLELIMITA (UWORD)(ACTUAL_AD_RES * 4400L / 10000L) +#define ANGLELIMITB (UWORD)(ACTUAL_AD_RES * 6600L / 10000L) +#define ANGLELIMITC (UWORD)(ACTUAL_AD_RES * 8900L / 10000L) + +#define FWDDIR 1 +#define RWDDIR 2 +#define MAXSAMPLECNT 5 + +typedef struct +{ + UBYTE ColorInputDebounce [NO_OF_COLORS]; + UBYTE ColorEdgeCnt [NO_OF_COLORS]; + UBYTE ColorLastAngle [NO_OF_COLORS]; + UBYTE ColorSampleCnt [NO_OF_COLORS]; + UBYTE ColorInitState; + UBYTE ReadCnt; +} VARSCOLOR; + + +typedef struct +{ + UWORD InvalidTimer [NO_OF_INPUTS]; + UBYTE InputDebounce [NO_OF_INPUTS]; + UBYTE EdgeCnt [NO_OF_INPUTS]; + UBYTE LastAngle [NO_OF_INPUTS]; + UBYTE OldSensorType [NO_OF_INPUTS]; + UBYTE SampleCnt [NO_OF_INPUTS]; + VARSCOLOR VarsColor [NO_OF_INPUTS]; + UBYTE ColorCnt; + UBYTE ColorStatus; +}VARSINPUT; + +void cInputInit(void* pHeader); +void cInputCtrl(void); +void cInputExit(void); + + +#endif diff --git a/src/c_input.iom b/src/c_input.iom new file mode 100644 index 0000000..dee1309 --- /dev/null +++ b/src/c_input.iom @@ -0,0 +1,175 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 24-09-08 15:23 $ +// +// Filename $Workfile:: c_input.iom $ +// +// Version $Revision:: 16 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_inpu $ +// +// Platform C +// + +#ifndef CINPUT_IOM +#define CINPUT_IOM + +#define NO_OF_INPUTS 4 +#define pMapInput ((IOMAPINPUT*)(pHeaders[ENTRY_INPUT]->pIOMap)) + + +/* Constants related to sensor type */ +enum +{ + NO_SENSOR = 0, + SWITCH = 1, + TEMPERATURE = 2, + REFLECTION = 3, + ANGLE = 4, + LIGHT_ACTIVE = 5, + LIGHT_INACTIVE = 6, + SOUND_DB = 7, + SOUND_DBA = 8, + CUSTOM = 9, + LOWSPEED = 10, + LOWSPEED_9V = 11, + HIGHSPEED = 12, + COLORFULL = 13, + COLORRED = 14, + COLORGREEN = 15, + COLORBLUE = 16, + COLORNONE = 17, + COLOREXIT = 18, /* For internal use when going from color or Lamp to no_sensor*/ + NO_OF_SENSOR_TYPES = 18 +}; + +/* Constants related to sensor mode */ +enum +{ + RAWMODE = 0x00, + BOOLEANMODE = 0x20, + TRANSITIONCNTMODE = 0x40, + PERIODCOUNTERMODE = 0x60, + PCTFULLSCALEMODE = 0x80, + CELSIUSMODE = 0xA0, + FAHRENHEITMODE = 0xC0, + ANGLESTEPSMODE = 0xE0, + SLOPEMASK = 0x1F, + MODEMASK = 0xE0 +}; + +/* Constants related to Digital I/O */ +enum +{ + DIGI0 = 1, + DIGI1 = 2 +}; + +enum +{ + CUSTOMINACTIVE = 0x00, + CUSTOM9V = 0x01, + CUSTOMACTIVE = 0x02 +}; + +enum +{ + INVALID_DATA = 0x01 +}; + +/* Constants related to Colorstruct */ +enum +{ + RED, + GREEN, + BLUE, + BLANK, + NO_OF_COLORS +}; + + +/* Constants related to color sensor value using */ +/* Color sensor as color detector */ +enum +{ + BLACKCOLOR = 1, + BLUECOLOR = 2, + GREENCOLOR = 3, + YELLOWCOLOR = 4, + REDCOLOR = 5, + WHITECOLOR = 6 +}; + + +/* Constants related to Color CalibrationState */ +/* When STARTCAL is TRUE then calibration is */ +/* in progress */ +enum +{ + SENSORCAL = 0x01, + SENSOROFF = 0x02, + RUNNINGCAL = 0x20, + STARTCAL = 0x40, + RESETCAL = 0x80, +}; + +enum +{ + CAL_POINT_0, + CAL_POINT_1, + CAL_POINT_2, + NO_OF_POINTS +}; + + +typedef struct +{ + UWORD CustomZeroOffset; /* Set the offset of the custom sensor */ + UWORD ADRaw; + UWORD SensorRaw; + SWORD SensorValue; + + UBYTE SensorType; + UBYTE SensorMode; + UBYTE SensorBoolean; + + UBYTE DigiPinsDir; /* Direction of the Digital pins 1 is output 0 is input */ + UBYTE DigiPinsIn; /* Contains the status of the digital pins */ + UBYTE DigiPinsOut; /* Sets the output level of the digital pins */ + UBYTE CustomPctFullScale; /* Sets the Pct full scale of the custom sensor */ + UBYTE CustomActiveStatus; /* Sets the active or inactive state of the custom sensor */ + + UBYTE InvalidData; /* Indicates wether data is invalid (1) or valid (0) */ + + UBYTE Spare1; + UBYTE Spare2; + UBYTE Spare3; + +}INPUTSTRUCT; + +typedef struct +{ + + ULONG Calibration[NO_OF_POINTS][NO_OF_COLORS]; + UWORD CalLimits[NO_OF_POINTS - 1]; + UWORD ADRaw[NO_OF_COLORS]; + UWORD SensorRaw[NO_OF_COLORS]; + SWORD SensorValue[NO_OF_COLORS]; + UBYTE Boolean[NO_OF_COLORS]; + UBYTE CalibrationState; + UBYTE Free1; + UBYTE Free2; + UBYTE Free3; +}COLORSTRUCT; + +typedef struct +{ + INPUTSTRUCT Inputs[NO_OF_INPUTS]; + COLORSTRUCT Colors[NO_OF_INPUTS]; +}IOMAPINPUT; + +#endif + + + diff --git a/src/c_ioctrl.c b/src/c_ioctrl.c new file mode 100644 index 0000000..daab322 --- /dev/null +++ b/src/c_ioctrl.c @@ -0,0 +1,78 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: c_ioctrl.c $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_ioct $ +// +// Platform C +// + + +#include "stdconst.h" +#include "modules.h" +#include "c_ioctrl.iom" +#include "c_ioctrl.h" +#include "d_ioctrl.h" + +static IOMAPIOCTRL IOMapIOCtrl; +static VARSIOCTRL VarsIOCtrl; + +const HEADER cIOCtrl = +{ + 0x00060001L, + "IOCtrl", + cIOCtrlInit, + cIOCtrlCtrl, + cIOCtrlExit, + (void *)&IOMapIOCtrl, + (void *)&VarsIOCtrl, + (UWORD)sizeof(IOMapIOCtrl), + (UWORD)sizeof(VarsIOCtrl), + 0x0000 //Code size - not used so far +}; + + +void cIOCtrlInit(void* pHeader) +{ + dIOCtrlSetPower(0); + dIOCtrlInit(); +} + + +void cIOCtrlCtrl(void) +{ + switch(IOMapIOCtrl.PowerOn) + { + case POWERDOWN: + { + dIOCtrlSetPower((POWERDOWN>>8)); + } + break; + case BOOT: + { + dIOCtrlSetPower((UBYTE)(BOOT>>8)); + dIOCtrlSetPwm((UBYTE)BOOT); + } + break; + default: + { + /* No need to change the default value */ + /* if value is boot or reset it should come */ + /* back from reset - setting the value to 0 */ + } + break; + } + dIOCtrlTransfer(); +} + + +void cIOCtrlExit(void) +{ + dIOCtrlExit(); +} + diff --git a/src/c_ioctrl.h b/src/c_ioctrl.h new file mode 100644 index 0000000..5ad4c8f --- /dev/null +++ b/src/c_ioctrl.h @@ -0,0 +1,28 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: c_ioctrl.h $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_ioct $ +// +// Platform C +// + +#ifndef C_IOCTRL +#define C_IOCTRL + +typedef struct +{ + UBYTE Tmp; +}VARSIOCTRL; + +void cIOCtrlInit(void* pHeader); +void cIOCtrlCtrl(void); +void cIOCtrlExit(void); + +extern const HEADER cIOCtrl; +#endif diff --git a/src/c_ioctrl.iom b/src/c_ioctrl.iom new file mode 100644 index 0000000..9742d04 --- /dev/null +++ b/src/c_ioctrl.iom @@ -0,0 +1,35 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: c_ioctrl.iom $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_ioct $ +// +// Platform C +// + +#ifndef CIOCTRL_IOM +#define CIOCTRL_IOM + +#define pMapIoCtrl ((IOMAPIOCTRL*)(pHeaders[ENTRY_IOCTRL]->pIOMap)) + +enum +{ + POWERDOWN = 0x5A00, + BOOT = 0xA55A +}; + +typedef struct +{ + UWORD PowerOn; +}IOMAPIOCTRL; + + +#endif + + + diff --git a/src/c_loader.c b/src/c_loader.c new file mode 100644 index 0000000..995c920 --- /dev/null +++ b/src/c_loader.c @@ -0,0 +1,464 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 12-03-08 15:28 $ +// +// Filename $Workfile:: c_loader.c $ +// +// Version $Revision:: 5 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_load $ +// +// Platform C +// + +#include "stdconst.h" +#include "modules.h" +#include "c_loader.iom" +#include "c_ioctrl.iom" +#include "d_loader.h" +#include "c_loader.h" + +static IOMAPLOADER IOMapLoader; +static VARSLOADER VarsLoader; +static HEADER **pHeaders; + +const HEADER cLoader = +{ + 0x00090001L, + "Loader", + cLoaderInit, + cLoaderCtrl, + cLoaderExit, + (void *)&IOMapLoader, + (void *)&VarsLoader, + (UWORD)sizeof(IOMapLoader), + (UWORD)sizeof(VarsLoader), + 0x0000 //Code size - not used so far +}; + +UWORD cLoaderFileRq(UBYTE Cmd, UBYTE *pFileName, UBYTE *pBuffer, ULONG *pLength); +UWORD cLoaderGetIoMapInfo(ULONG ModuleId, UBYTE *pIoMap, UWORD *pIoMapSize); +UWORD cLoaderFindModule(UBYTE *pBuffer); +void cLoaderGetModuleName(UBYTE *pDst, UBYTE *pModule); + +void cLoaderInit(void* pHeader) +{ + + IOMapLoader.pFunc = &cLoaderFileRq; + VarsLoader.IoMapHandle = FALSE; + pHeaders = pHeader; + dLoaderInit(); + IOMapLoader.FreeUserFlash = dLoaderReturnFreeUserFlash(); +} + +void cLoaderCtrl(void) +{ +} + + + +UWORD cLoaderFileRq(UBYTE Cmd, UBYTE *pFileName, UBYTE *pBuffer, ULONG *pLength) +{ + UWORD ReturnState; + + ReturnState = SUCCESS; + + switch(Cmd) + { + case OPENREAD: + { + ReturnState = dLoaderOpenRead(pFileName, pLength); + if (0x8000 <= ReturnState) + { + dLoaderCloseHandle(ReturnState); + } + } + break; + case OPENREADLINEAR: + { + ReturnState = dLoaderGetFilePtr(pFileName, pBuffer, pLength); + if (0x8000 <= ReturnState) + { + dLoaderCloseHandle(ReturnState); + } + + } + break; + case OPENWRITE: + { + + /* This is to create a new file */ + ReturnState = dLoaderCreateFileHeader(*pLength, pFileName, (UBYTE) NONLINEAR, SYSTEMFILE); + if (0x8000 <= ReturnState) + { + dLoaderCloseHandle(ReturnState); + } + else + { + IOMapLoader.FreeUserFlash = dLoaderReturnFreeUserFlash(); + } + } + break; + case OPENWRITELINEAR: + { + ReturnState = dLoaderCreateFileHeader(*pLength, pFileName, (UBYTE) LINEAR, SYSTEMFILE); + if (0x8000 <= ReturnState) + { + dLoaderCloseHandle(ReturnState); + } + else + { + IOMapLoader.FreeUserFlash = dLoaderReturnFreeUserFlash(); + } + } + break; + case OPENWRITEDATA: + { + + ReturnState = dLoaderCreateFileHeader(*pLength, pFileName, (UBYTE) NONLINEAR, DATAFILE); + if (0x8000 <= ReturnState) + { + dLoaderCloseHandle(ReturnState); + } + else + { + IOMapLoader.FreeUserFlash = dLoaderReturnFreeUserFlash(); + } + } + break; + case OPENAPPENDDATA: + { + ReturnState = dLoaderOpenAppend(pFileName, pLength); + if (LOADER_ERR(ReturnState) != SUCCESS) + { + dLoaderCloseHandle(ReturnState); + } + } + break; + case CLOSE: + { + ReturnState = dLoaderCloseHandle(*pFileName); + } + break; + case CROPDATAFILE: + { + ReturnState = dLoaderCropDatafile(*pFileName); + IOMapLoader.FreeUserFlash = dLoaderReturnFreeUserFlash(); + } + break; + case READ: + { + ReturnState = dLoaderRead(*pFileName, pBuffer, pLength); + } + break; + case WRITE: + { + ReturnState = dLoaderWriteData(*pFileName, pBuffer, (UWORD*)pLength); + } + break; + case FINDFIRST: + { + ULONG DataLength; + + ReturnState = dLoaderFind(pFileName, pBuffer, pLength, &DataLength, (UBYTE) SEARCHING); + if (0x8000 <= ReturnState) + { + dLoaderCloseHandle(ReturnState); + } + } + break; + case FINDNEXT: + { + UWORD Handle; + ULONG DataLength; + + Handle = *pFileName; + ReturnState = dLoaderFindNext(Handle, pBuffer, pLength, &DataLength); + } + break; + case DELETE: + { + ReturnState = dLoaderDelete(pFileName); + IOMapLoader.FreeUserFlash = dLoaderReturnFreeUserFlash(); + + } + break; + case DELETEUSERFLASH: + { + dLoaderDeleteAllFiles(); + IOMapLoader.FreeUserFlash = dLoaderReturnFreeUserFlash(); + + } + break; + + case FINDFIRSTMODULE: + { + if (FALSE == VarsLoader.IoMapHandle) + { + VarsLoader.IoMapHandle = TRUE; + VarsLoader.ModSearchIndex = 0; + dLoaderInsertSearchStr(VarsLoader.ModSearchStr, pFileName, &(VarsLoader.ModSearchType)); + ReturnState = cLoaderFindModule(pBuffer); + } + else + { + ReturnState = NOMOREHANDLES; + } + } + break; + + case FINDNEXTMODULE: + { + ReturnState = cLoaderFindModule(pBuffer); + } + break; + + case CLOSEMODHANDLE: + { + VarsLoader.IoMapHandle = FALSE; + ReturnState = SUCCESS; + } + break; + + case IOMAPREAD: + { + + UBYTE *pIoMap; + ULONG Ptr; + UWORD IoMapSize; + UBYTE Tmp; + + pIoMap = NULL; + ReturnState = cLoaderGetIoMapInfo((*(ULONG*)(pFileName)),(UBYTE*)(&pIoMap), &IoMapSize); + + /* Did we have a valid module ID ?*/ + if (SUCCESS == LOADER_ERR(ReturnState)) + { + + /* This is the offset */ + Ptr = pBuffer[0]; + Ptr |= (UWORD)pBuffer[1] << 8; + + /* is the offset within the limits of the iomap size? */ + if ((Ptr + *pLength) <= IoMapSize) + { + + /* Add the offset to the pointer */ + pIoMap += Ptr; + + for (Tmp = 0; Tmp < *pLength; Tmp++) + { + pBuffer[Tmp + 2] = *pIoMap; + pIoMap++; + } + } + else + { + + /* Error - not within the bounderies */ + ReturnState = OUTOFBOUNDERY; + *pLength = 0; + } + } + else + { + + /* Error - not a valid module id */ + *pLength = 0; + } + } + break; + + case IOMAPWRITE: + { + UBYTE *pIoMap; + ULONG Ptr; + UWORD IoMapSize; + UWORD Tmp; + + + pIoMap = NULL; + ReturnState = cLoaderGetIoMapInfo(*((ULONG*)pFileName), (UBYTE*)&pIoMap, &IoMapSize); + + if (LOADER_ERR(ReturnState) == SUCCESS) + { + + /* This is the offset */ + Ptr = *pBuffer; + pBuffer++; + Tmp = *pBuffer; + Ptr |= Tmp << 8; + pBuffer++; + + if ((Ptr + *pLength) <= IoMapSize) + { + + pIoMap += Ptr; + for (Tmp = 0; Tmp < *pLength; Tmp++) + { + *pIoMap = pBuffer[Tmp]; + pIoMap++; + } + } + else + { + + /* Error - not within the bounderies */ + ReturnState = OUTOFBOUNDERY; + *pLength = 0; + } + } + else + { + + /* Error - not a valid module id */ + *pLength = 0; + } + } + break; + + case RENAMEFILE: + { + UBYTE FoundName[FILENAME_LENGTH + 1]; + + /* Check for file exists*/ + ReturnState = dLoaderFind(pBuffer, FoundName, pLength, pLength, (UBYTE) SEARCHING); + dLoaderCloseHandle(LOADER_HANDLE(ReturnState)); + if (FILENOTFOUND == LOADER_ERR(ReturnState)) + { + ReturnState = dLoaderFind(pFileName, FoundName, pLength, pLength, (UBYTE) SEARCHING); + if (ReturnState < 0x8000) + { + ReturnState = dLoaderCheckFiles((UBYTE) ReturnState); + if (ReturnState < 0x8000) + { + dLoaderRenameFile((UBYTE) ReturnState, pBuffer); + } + } + dLoaderCloseHandle(LOADER_HANDLE(ReturnState)); + } + else + { + if (SUCCESS == LOADER_ERR(ReturnState)) + { + ReturnState |= FILEEXISTS; + } + } + } + break; + + default: + { + } + break; + } + return (ReturnState); +} + +UWORD cLoaderGetIoMapInfo(ULONG ModuleId, UBYTE *pIoMap, UWORD *pIoMapSize) +{ + UBYTE Tmp; + UBYTE Exit; + UWORD RtnVal; + + RtnVal = SUCCESS; + Tmp = 0; + Exit = FALSE; + while((Tmp < 32) && (Exit == FALSE)) + { + if ((*(pHeaders[Tmp])).ModuleID == ModuleId) + { + Exit = TRUE; + } + else + { + Tmp++; + } + } + + /* Did we have a valid module ID ?*/ + if (TRUE == Exit) + { + /* Get the pointer of the module io map */ + *((ULONG *)pIoMap) = (ULONG)((*(pHeaders[Tmp])).pIOMap); + *pIoMapSize = (*(pHeaders[Tmp])).IOMapSize; + } + else + { + RtnVal = MODULENOTFOUND; + } + + /* To avoid a warning - this is optimized away */ + *pIoMap = *pIoMap; + return(RtnVal); +} + +UWORD cLoaderFindModule(UBYTE *pBuffer) +{ + UBYTE Tmp; + UWORD RtnVal; + UBYTE ModuleName[FILENAME_SIZE]; + + RtnVal = MODULENOTFOUND; + + for (Tmp = VarsLoader.ModSearchIndex; Tmp < 32; Tmp++) + { + if (pHeaders[Tmp] != 0) + { + + cLoaderGetModuleName(ModuleName, ((*(pHeaders[Tmp])).ModuleName)); + if (SUCCESS == dLoaderCheckName(ModuleName, VarsLoader.ModSearchStr, VarsLoader.ModSearchType)) + { + + dLoaderCopyFileName(pBuffer, ModuleName); + + pBuffer[FILENAME_SIZE] = (UBYTE) ((*(pHeaders[Tmp])).ModuleID); + pBuffer[FILENAME_SIZE + 1] = (UBYTE)(((*(pHeaders[Tmp])).ModuleID) >> 8); + pBuffer[FILENAME_SIZE + 2] = (UBYTE)(((*(pHeaders[Tmp])).ModuleID) >> 16); + pBuffer[FILENAME_SIZE + 3] = (UBYTE)(((*(pHeaders[Tmp])).ModuleID) >> 24); + + pBuffer[FILENAME_SIZE + 4] = (UBYTE)(((*(pHeaders[Tmp])).ModuleSize)); + pBuffer[FILENAME_SIZE + 5] = (UBYTE)(((*(pHeaders[Tmp])).ModuleSize) >> 8); + pBuffer[FILENAME_SIZE + 6] = (UBYTE)(((*(pHeaders[Tmp])).ModuleSize) >> 16); + pBuffer[FILENAME_SIZE + 7] = (UBYTE)(((*(pHeaders[Tmp])).ModuleSize) >> 24); + + pBuffer[FILENAME_SIZE + 8] = (UBYTE) ((*(pHeaders[Tmp])).IOMapSize); + pBuffer[FILENAME_SIZE + 9] = (UBYTE)(((*(pHeaders[Tmp])).IOMapSize) >> 8); + + RtnVal = SUCCESS; + (VarsLoader.ModSearchIndex) = Tmp + 1; + Tmp = 32; + } + } + } + return(RtnVal); +} + +void cLoaderGetModuleName(UBYTE *pDst, UBYTE *pModule) +{ + UBYTE Tmp; + + for(Tmp = 0; Tmp < FILENAME_SIZE; Tmp++) + { + if (0 != pModule[Tmp]) + { + pDst[Tmp] = pModule[Tmp]; + } + else + { + pDst[Tmp++] = '.'; + pDst[Tmp++] = 'm'; + pDst[Tmp++] = 'o'; + pDst[Tmp++] = 'd'; + pDst[Tmp] = '\0'; + Tmp = FILENAME_SIZE; + } + } +} + +void cLoaderExit(void) +{ +} + + diff --git a/src/c_loader.h b/src/c_loader.h new file mode 100644 index 0000000..03f8062 --- /dev/null +++ b/src/c_loader.h @@ -0,0 +1,44 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: c_loader.h $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_load $ +// +// Platform C +// + +#ifndef C_LOADER +#define C_LOADER + +enum +{ + LOADER_BUSY, + TOO_MANY_FILES, + NO_MORE_FLASH, + LOADER_SUCCESS +}; + +typedef struct +{ + UBYTE ModSearchStr[FILENAME_LENGTH + 1]; + UBYTE ModSearchIndex; + UBYTE ModSearchType; + UBYTE UsbStatus; + UBYTE IoMapHandle; +}VARSLOADER; + +void cLoaderInit(void* pHeader); +void cLoaderCtrl(void); +void cLoaderExit(void); + +extern const HEADER cLoader; + +#endif + + + diff --git a/src/c_loader.iom b/src/c_loader.iom new file mode 100644 index 0000000..80c8c4e --- /dev/null +++ b/src/c_loader.iom @@ -0,0 +1,85 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 24-06-09 8:53 $ +// +// Filename $Workfile:: c_loader.iom $ +// +// Version $Revision:: 15 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_load $ +// +// Platform C +// + +#ifndef CLOADER_IOM +#define CLOADER_IOM + +#define pMapLoader ((IOMAPLOADER*)(pHeaders[ENTRY_LOADER]->pIOMap)) + +//Version numbers are two bytes, MAJOR.MINOR (big-endian) +//For example, version 1.5 would be 0x0105 +//If these switch to little-endian, be sure to update +//definition and usages of VM_OLDEST_COMPATIBLE_VERSION, too! +#define FIRMWAREVERSION 0x011D // x.y +#define FIRMWAREPATCH 2 // .z, the third number +#define PROTOCOLVERSION 0x017C //1.124 + +enum +{ + OPENREAD = 0x80, + OPENWRITE = 0x81, + READ = 0x82, + WRITE = 0x83, + CLOSE = 0x84, + DELETE = 0x85, + FINDFIRST = 0x86, + FINDNEXT = 0x87, + VERSIONS = 0x88, + OPENWRITELINEAR = 0x89, + OPENREADLINEAR = 0x8A, + OPENWRITEDATA = 0x8B, + OPENAPPENDDATA = 0x8C, + CROPDATAFILE = 0x8D, /* New cmd for datalogging */ + FINDFIRSTMODULE = 0x90, + FINDNEXTMODULE = 0x91, + CLOSEMODHANDLE = 0x92, + IOMAPREAD = 0x94, + IOMAPWRITE = 0x95, + BOOTCMD = 0x97, /* external command only */ + SETBRICKNAME = 0x98, + BTGETADR = 0x9A, + DEVICEINFO = 0x9B, + DELETEUSERFLASH = 0xA0, + POLLCMDLEN = 0xA1, + POLLCMD = 0xA2, + RENAMEFILE = 0xA3, + BTFACTORYRESET = 0xA4 + +}; + +typedef UWORD LOADER_STATUS; + +//Mask out handle byte of Loader status word for error code checks +#define LOADER_ERR(StatusWord) ((StatusWord & 0xFF00)) + +//Byte value of error half of Loader status word +#define LOADER_ERR_BYTE(StatusWord) ((UBYTE)((StatusWord & 0xFF00) >> 8)) + +//Value of handle inside Loader status word +#define LOADER_HANDLE(StatusWord) ((UBYTE)(StatusWord)) + +//Pointer to lower byte of Loader status word +#define LOADER_HANDLE_P(StatusWord) ((UBYTE*)(&StatusWord)) + +typedef struct +{ + UWORD (*pFunc)(UBYTE, UBYTE *, UBYTE *, ULONG *); + ULONG FreeUserFlash; +}IOMAPLOADER; + + +#endif + + + diff --git a/src/c_lowspeed.c b/src/c_lowspeed.c new file mode 100644 index 0000000..26851db --- /dev/null +++ b/src/c_lowspeed.c @@ -0,0 +1,236 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: c_lowspeed.c $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_lows $ +// +// Platform C +// + +#include "stdconst.h" +#include "modules.h" +#include "c_lowspeed.iom" +#include "c_input.iom" +#include "c_lowspeed.h" +#include "d_lowspeed.h" + +static IOMAPLOWSPEED IOMapLowSpeed; +static VARSLOWSPEED VarsLowSpeed; +static HEADER **pHeaders; + +const UBYTE LOWSPEED_CH_NUMBER[4] = {0x01, 0x02, 0x04, 0x08}; + +const HEADER cLowSpeed = +{ + 0x000B0001L, + "Low Speed", + cLowSpeedInit, + cLowSpeedCtrl, + cLowSpeedExit, + (void *)&IOMapLowSpeed, + (void *)&VarsLowSpeed, + (UWORD)sizeof(IOMapLowSpeed), + (UWORD)sizeof(VarsLowSpeed), + 0x0000 //Code size - not used so far +}; + +void cLowSpeedInit(void* pHeader) +{ + pHeaders = pHeader; + + dLowSpeedInit(); + IOMapLowSpeed.State = COM_CHANNEL_NONE_ACTIVE; + VarsLowSpeed.TimerState = TIMER_STOPPED; +} + +void cLowSpeedCtrl(void) +{ + UBYTE Temp; + UBYTE ChannelNumber = 0; + + if (IOMapLowSpeed.State != 0) + { + for (ChannelNumber = 0; ChannelNumber < NO_OF_LOWSPEED_COM_CHANNEL; ChannelNumber++) + { + //Lowspeed com is activated + switch (IOMapLowSpeed.ChannelState[ChannelNumber]) + { + case LOWSPEED_IDLE: + { + } + break; + + case LOWSPEED_INIT: + { + if ((pMapInput->Inputs[ChannelNumber].SensorType == LOWSPEED) || (pMapInput->Inputs[ChannelNumber].SensorType == LOWSPEED_9V)) + { + if (VarsLowSpeed.TimerState == TIMER_STOPPED) + { + dLowSpeedStartTimer(); + VarsLowSpeed.TimerState = TIMER_RUNNING; + } + IOMapLowSpeed.ChannelState[ChannelNumber] = LOWSPEED_LOAD_BUFFER; + IOMapLowSpeed.ErrorType[ChannelNumber] = LOWSPEED_NO_ERROR; + VarsLowSpeed.ErrorCount[ChannelNumber] = 0; + dLowSpeedInitPins(ChannelNumber); + } + else + { + IOMapLowSpeed.ChannelState[ChannelNumber] = LOWSPEED_ERROR; + IOMapLowSpeed.ErrorType[ChannelNumber] = LOWSPEED_CH_NOT_READY; + } + } + break; + + case LOWSPEED_LOAD_BUFFER: + { + if ((pMapInput->Inputs[ChannelNumber].SensorType == LOWSPEED) || (pMapInput->Inputs[ChannelNumber].SensorType == LOWSPEED_9V)) + { + VarsLowSpeed.OutputBuf[ChannelNumber].OutPtr = 0; + for (VarsLowSpeed.OutputBuf[ChannelNumber].InPtr = 0; VarsLowSpeed.OutputBuf[ChannelNumber].InPtr < IOMapLowSpeed.OutBuf[ChannelNumber].InPtr; VarsLowSpeed.OutputBuf[ChannelNumber].InPtr++) + { + VarsLowSpeed.OutputBuf[ChannelNumber].Buf[VarsLowSpeed.OutputBuf[ChannelNumber].InPtr] = IOMapLowSpeed.OutBuf[ChannelNumber].Buf[IOMapLowSpeed.OutBuf[ChannelNumber].OutPtr]; + IOMapLowSpeed.OutBuf[ChannelNumber].OutPtr++; + } + if (dLowSpeedSendData(ChannelNumber, &VarsLowSpeed.OutputBuf[ChannelNumber].Buf[0], (VarsLowSpeed.OutputBuf[ChannelNumber].InPtr - VarsLowSpeed.OutputBuf[ChannelNumber].OutPtr))) + { + if (IOMapLowSpeed.InBuf[ChannelNumber].BytesToRx != 0) + { + dLowSpeedReceiveData(ChannelNumber, &VarsLowSpeed.InputBuf[ChannelNumber].Buf[0], IOMapLowSpeed.InBuf[ChannelNumber].BytesToRx); + VarsLowSpeed.RxTimeCnt[ChannelNumber] = 0; + } + IOMapLowSpeed.ChannelState[ChannelNumber] = LOWSPEED_COMMUNICATING; + IOMapLowSpeed.Mode[ChannelNumber] = LOWSPEED_TRANSMITTING; + } + else + { + IOMapLowSpeed.ChannelState[ChannelNumber] = LOWSPEED_ERROR; + IOMapLowSpeed.ErrorType[ChannelNumber] = LOWSPEED_CH_NOT_READY; + } + } + else + { + IOMapLowSpeed.ChannelState[ChannelNumber] = LOWSPEED_ERROR; + IOMapLowSpeed.ErrorType[ChannelNumber] = LOWSPEED_CH_NOT_READY; + } + } + break; + + case LOWSPEED_COMMUNICATING: + { + if ((pMapInput->Inputs[ChannelNumber].SensorType == LOWSPEED) || (pMapInput->Inputs[ChannelNumber].SensorType == LOWSPEED_9V)) + { + if (IOMapLowSpeed.Mode[ChannelNumber] == LOWSPEED_TRANSMITTING) + { + Temp = dLowSpeedComTxStatus(ChannelNumber); // Returns 0x00 if not done, 0x01 if success, 0xFF if error + + if (Temp == LOWSPEED_COMMUNICATION_SUCCESS) + { + if (IOMapLowSpeed.InBuf[ChannelNumber].BytesToRx != 0) + { + IOMapLowSpeed.Mode[ChannelNumber] = LOWSPEED_RECEIVING; + } + else + { + IOMapLowSpeed.Mode[ChannelNumber] = LOWSPEED_DATA_RECEIVED; + IOMapLowSpeed.ChannelState[ChannelNumber] = LOWSPEED_DONE; + } + } + if (Temp == LOWSPEED_COMMUNICATION_ERROR) + { + //ERROR in Communication, No ACK received from SLAVE, retry send data 3 times! + VarsLowSpeed.ErrorCount[ChannelNumber]++; + if (VarsLowSpeed.ErrorCount[ChannelNumber] > MAX_RETRY_TX_COUNT) + { + IOMapLowSpeed.ChannelState[ChannelNumber] = LOWSPEED_ERROR; + IOMapLowSpeed.ErrorType[ChannelNumber] = LOWSPEED_TX_ERROR; + } + else + { + IOMapLowSpeed.ChannelState[ChannelNumber] = LOWSPEED_LOAD_BUFFER; + } + } + } + if (IOMapLowSpeed.Mode[ChannelNumber] == LOWSPEED_RECEIVING) + { + VarsLowSpeed.RxTimeCnt[ChannelNumber]++; + if (VarsLowSpeed.RxTimeCnt[ChannelNumber] > LOWSPEED_RX_TIMEOUT) + { + IOMapLowSpeed.ChannelState[ChannelNumber] = LOWSPEED_ERROR; + IOMapLowSpeed.ErrorType[ChannelNumber] = LOWSPEED_RX_ERROR; + } + Temp = dLowSpeedComRxStatus(ChannelNumber); + if (Temp == LOWSPEED_COMMUNICATION_SUCCESS) + { + for (VarsLowSpeed.InputBuf[ChannelNumber].OutPtr = 0; VarsLowSpeed.InputBuf[ChannelNumber].OutPtr < IOMapLowSpeed.InBuf[ChannelNumber].BytesToRx; VarsLowSpeed.InputBuf[ChannelNumber].OutPtr++) + { + IOMapLowSpeed.InBuf[ChannelNumber].Buf[IOMapLowSpeed.InBuf[ChannelNumber].InPtr] = VarsLowSpeed.InputBuf[ChannelNumber].Buf[VarsLowSpeed.InputBuf[ChannelNumber].OutPtr]; + IOMapLowSpeed.InBuf[ChannelNumber].InPtr++; + if (IOMapLowSpeed.InBuf[ChannelNumber].InPtr >= SIZE_OF_LSBUF) + { + IOMapLowSpeed.InBuf[ChannelNumber].InPtr = 0; + } + VarsLowSpeed.InputBuf[ChannelNumber].Buf[VarsLowSpeed.InputBuf[ChannelNumber].OutPtr] = 0; + } + IOMapLowSpeed.Mode[ChannelNumber] = LOWSPEED_DATA_RECEIVED; + IOMapLowSpeed.ChannelState[ChannelNumber] = LOWSPEED_DONE; + } + if (Temp == LOWSPEED_COMMUNICATION_ERROR) + { + //There was and error in receiving data from the device + for (VarsLowSpeed.InputBuf[ChannelNumber].OutPtr = 0; VarsLowSpeed.InputBuf[ChannelNumber].OutPtr < IOMapLowSpeed.InBuf[ChannelNumber].BytesToRx; VarsLowSpeed.InputBuf[ChannelNumber].OutPtr++) + { + VarsLowSpeed.InputBuf[ChannelNumber].Buf[VarsLowSpeed.InputBuf[ChannelNumber].OutPtr] = 0; + } + IOMapLowSpeed.ChannelState[ChannelNumber] = LOWSPEED_ERROR; + IOMapLowSpeed.ErrorType[ChannelNumber] = LOWSPEED_RX_ERROR; + } + } + } + else + { + IOMapLowSpeed.ChannelState[ChannelNumber] = LOWSPEED_ERROR; + IOMapLowSpeed.ErrorType[ChannelNumber] = LOWSPEED_CH_NOT_READY; + } + } + break; + + case LOWSPEED_ERROR: + { + IOMapLowSpeed.State = IOMapLowSpeed.State & ~LOWSPEED_CH_NUMBER[ChannelNumber]; + if (IOMapLowSpeed.State == 0) + { + dLowSpeedStopTimer(); + VarsLowSpeed.TimerState = TIMER_STOPPED; + } + } + break; + + case LOWSPEED_DONE: + { + IOMapLowSpeed.State = IOMapLowSpeed.State & ~LOWSPEED_CH_NUMBER[ChannelNumber]; + IOMapLowSpeed.ChannelState[ChannelNumber] = LOWSPEED_IDLE; + if (IOMapLowSpeed.State == 0) + { + dLowSpeedStopTimer(); + VarsLowSpeed.TimerState = TIMER_STOPPED; + } + } + break; + + default: + break; + } + } + } +} + +void cLowSpeedExit(void) +{ + dLowSpeedExit(); +} diff --git a/src/c_lowspeed.h b/src/c_lowspeed.h new file mode 100644 index 0000000..1595158 --- /dev/null +++ b/src/c_lowspeed.h @@ -0,0 +1,61 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: c_lowspeed.h $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_lows $ +// +// Platform C +// + +#ifndef C_LOWSPEED +#define C_LOWSPEED + +#define LOWSPEED_RX_TIMEOUT 100 +#define LOWSPEED_COMMUNICATION_SUCCESS 0x01 +#define LOWSPEED_COMMUNICATION_ERROR 0xFF +#define SIZE_OF_LSBUFDATA 16 +#define NO_OF_LOWSPEED_COM_CH 4 + +enum +{ + LOWSPEED_CHANNEL1, + LOWSPEED_CHANNEL2, + LOWSPEED_CHANNEL3, + LOWSPEED_CHANNEL4 +}; + +enum +{ + TIMER_STOPPED, + TIMER_RUNNING +}; + +typedef struct +{ + UBYTE Buf[SIZE_OF_LSBUFDATA]; + UBYTE InPtr; + UBYTE OutPtr; +}LSDATA; + +typedef struct +{ + LSDATA OutputBuf[NO_OF_LOWSPEED_COM_CH]; + LSDATA InputBuf[NO_OF_LOWSPEED_COM_CH]; + UBYTE RxTimeCnt[NO_OF_LOWSPEED_COM_CH]; + UBYTE ErrorCount[NO_OF_LOWSPEED_COM_CH]; + UBYTE Tmp; + UBYTE TimerState; +}VARSLOWSPEED; + +void cLowSpeedInit(void* pHeader); +void cLowSpeedCtrl(void); +void cLowSpeedExit(void); + +extern const HEADER cLowSpeed; + +#endif diff --git a/src/c_lowspeed.iom b/src/c_lowspeed.iom new file mode 100644 index 0000000..290ed35 --- /dev/null +++ b/src/c_lowspeed.iom @@ -0,0 +1,95 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: c_lowspeed.iom $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_lows $ +// +// Platform C +// + +#ifndef CLOWSPEED_IOM +#define CLOWSPEED_IOM + +#define pMapLowSpeed ((IOMAPLOWSPEED*)(pHeaders[ENTRY_LOWSPEED]->pIOMap)) + +#define MAX_RETRY_TX_COUNT 3 +#define NO_OF_LOWSPEED_COM_CHANNEL 4 +#define NO_OF_LSBUF NO_OF_LOWSPEED_COM_CHANNEL +#define SIZE_OF_LSBUF 16 + +//Constants referring to LowSpeedDeviceType +enum +{ + ULTRA_SONIC = 2, + CUSTOM_LS_DEVICE +}; + +// Constants reffering to State +enum +{ + COM_CHANNEL_NONE_ACTIVE = 0x00, + COM_CHANNEL_ONE_ACTIVE = 0x01, + COM_CHANNEL_TWO_ACTIVE = 0x02, + COM_CHANNEL_THREE_ACTIVE = 0x04, + COM_CHANNEL_FOUR_ACTIVE = 0x08 +}; + +// Constants reffering to ChannelState +enum +{ + LOWSPEED_IDLE, + LOWSPEED_INIT, + LOWSPEED_LOAD_BUFFER, + LOWSPEED_COMMUNICATING, + LOWSPEED_ERROR, + LOWSPEED_DONE +}; + +// Constants reffering to Mode +enum +{ + LOWSPEED_TRANSMITTING = 1, + LOWSPEED_RECEIVING, + LOWSPEED_DATA_RECEIVED +}; + +// Constants reffering to ErrorType +enum +{ + LOWSPEED_NO_ERROR = 0, + LOWSPEED_CH_NOT_READY, + LOWSPEED_TX_ERROR, + LOWSPEED_RX_ERROR +}; + + +typedef struct +{ + UBYTE Buf[SIZE_OF_LSBUF]; + UBYTE InPtr; + UBYTE OutPtr; + UBYTE BytesToRx; +}LSBUF; + +typedef struct +{ + LSBUF InBuf[NO_OF_LSBUF]; + LSBUF OutBuf[NO_OF_LSBUF]; + UBYTE Mode[NO_OF_LSBUF]; + UBYTE ChannelState[NO_OF_LSBUF]; + UBYTE ErrorType[NO_OF_LSBUF]; + UBYTE State; + UBYTE Speed; + UBYTE Spare1; +}IOMAPLOWSPEED; + + +#endif + + + diff --git a/src/c_output.c b/src/c_output.c new file mode 100644 index 0000000..e0645e0 --- /dev/null +++ b/src/c_output.c @@ -0,0 +1,180 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: c_output.c $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_outp $ +// +// Platform C +// + +#include +#include "stdbool.h" +#include "stdconst.h" +#include "modules.h" +#include "c_output.iom" +#include "c_output.h" +#include "d_output.h" +#include "c_display.iom" + +static IOMAPOUTPUT IOMapOutput; +static VARSOUTPUT VarsOutput; + +const HEADER cOutput = +{ + 0x00020001L, + "Output", + cOutputInit, + cOutputCtrl, + cOutputExit, + (void *)&IOMapOutput, + (void *)&VarsOutput, + (UWORD)sizeof(IOMapOutput), + (UWORD)sizeof(VarsOutput), + 0x0000 //Code size - not used so far +}; + + +void cOutputInit(void* pHeader) +{ + UBYTE Tmp; + + for(Tmp = 0; Tmp < NO_OF_OUTPUTS; Tmp++) + { + OUTPUT * pOut = &(IOMapOutput.Outputs[Tmp]); + pOut->Mode = 0x00; + pOut->Speed = 0x00; + pOut->ActualSpeed = 0x00; + pOut->TachoCnt = 0x00; + pOut->RunState = 0x00; + pOut->TachoLimit = 0x00; + pOut->RegPParameter = DEFAULT_P_GAIN_FACTOR; + pOut->RegIParameter = DEFAULT_I_GAIN_FACTOR; + pOut->RegDParameter = DEFAULT_D_GAIN_FACTOR; + pOut->Options = 0x00; + pOut->MaxSpeed = DEFAULT_MAX_SPEED; + pOut->MaxAcceleration = DEFAULT_MAX_ACCELERATION; + } + IOMapOutput.RegulationTime = REGULATION_TIME; + IOMapOutput.RegulationOptions = 0; + VarsOutput.TimeCnt = 0; + dOutputInit(); +} + +void cOutputCtrl(void) +{ + UBYTE Tmp; + + for(Tmp = 0; Tmp < NO_OF_OUTPUTS; Tmp++) + { + OUTPUT * pOut = &(IOMapOutput.Outputs[Tmp]); + if (pOut->Flags != 0) + { + if (pOut->Flags & UPDATE_RESET_ROTATION_COUNT) + { + pOut->Flags &= ~UPDATE_RESET_ROTATION_COUNT; + dOutputResetRotationCaptureCount(Tmp); + } + if (pOut->Flags & UPDATE_RESET_COUNT) + { + pOut->Flags &= ~UPDATE_RESET_COUNT; + dOutputResetTachoLimit(Tmp); + } + if (pOut->Flags & UPDATE_RESET_BLOCK_COUNT) + { + pOut->Flags &= ~UPDATE_RESET_BLOCK_COUNT; + dOutputResetBlockTachoLimit(Tmp); + } + if (pOut->Flags & UPDATE_SPEED) + { + pOut->Flags &= ~UPDATE_SPEED; + if (pOut->Mode & MOTORON) + { + dOutputSetSpeed(Tmp, pOut->RunState, pOut->Speed, pOut->SyncTurnParameter); + } + } + if (pOut->Flags & UPDATE_MODE) + { + pOut->Flags &= ~UPDATE_MODE; + if (pOut->Mode & BRAKE) + { + // Motor is Braked + dOutputSetMode(Tmp, BRAKE); + } + else + { + // Motor is floated + dOutputSetMode(Tmp, 0x00); + } + if (pOut->Mode & MOTORON) + { + if (pOut->Mode & REGULATED) + { + dOutputEnableRegulation(Tmp, pOut->RegMode); + } + else + { + dOutputDisableRegulation(Tmp); + } + } + else + { + dOutputSetSpeed(Tmp, 0x00, 0x00, 0x00); + dOutputDisableRegulation(Tmp); + } + } + if (pOut->Flags & UPDATE_TACHO_LIMIT) + { + pOut->Flags &= ~UPDATE_TACHO_LIMIT; + dOutputSetTachoLimit(Tmp, pOut->TachoLimit); + } + if (pOut->Flags & UPDATE_PID_VALUES) + { + pOut->Flags &= ~UPDATE_PID_VALUES; + dOutputSetPIDParameters(Tmp, pOut->RegPParameter, pOut->RegIParameter, pOut->RegDParameter); + dOutputSetMax(Tmp, pOut->MaxSpeed, pOut->MaxAcceleration); + } + } + } + dOutputSetRegulationTime(IOMapOutput.RegulationTime); + dOutputSetRegulationOptions(IOMapOutput.RegulationOptions); + dOutputCtrl(); + cOutputUpdateIomap(); +} + +void cOutputUpdateIomap(void) +{ + UBYTE TempCurrentMotorSpeed[NO_OF_OUTPUTS]; + UBYTE TempRunState[NO_OF_OUTPUTS]; + UBYTE TempMotorOverloaded[NO_OF_OUTPUTS]; + SLONG TempTachoCount[NO_OF_OUTPUTS]; + SLONG TempBlockTachoCount[NO_OF_OUTPUTS]; + SLONG TempRotationCount[NO_OF_OUTPUTS]; + + UBYTE Tmp; + + dOutputGetMotorParameters(TempCurrentMotorSpeed, TempTachoCount, TempBlockTachoCount, TempRunState, TempMotorOverloaded,TempRotationCount); + + for(Tmp = 0; Tmp < NO_OF_OUTPUTS; Tmp++) + { + OUTPUT * pOut = &(IOMapOutput.Outputs[Tmp]); + pOut->ActualSpeed = TempCurrentMotorSpeed[Tmp]; + pOut->TachoCnt = TempTachoCount[Tmp]; + pOut->BlockTachoCount = TempBlockTachoCount[Tmp]; + pOut->RotationCount = TempRotationCount[Tmp]; + pOut->Overloaded = TempMotorOverloaded[Tmp]; + if (!(pOut->Flags & PENDING_UPDATES)) + { + pOut->RunState = TempRunState[Tmp]; + } + } +} + +void cOutputExit(void) +{ + dOutputExit(); +} diff --git a/src/c_output.h b/src/c_output.h new file mode 100644 index 0000000..14faa2c --- /dev/null +++ b/src/c_output.h @@ -0,0 +1,31 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: c_output.h $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_outp $ +// +// Platform C +// + +#ifndef C_OUTPUT +#define C_OUTPUT + +typedef struct +{ + UBYTE TimeCnt; + UBYTE Tmp; +}VARSOUTPUT; + +void cOutputInit(void* pHeader); +void cOutputCtrl(void); +void cOutputExit(void); +void cOutputUpdateIomap(void); + +extern const HEADER cOutput; + +#endif diff --git a/src/c_output.iom b/src/c_output.iom new file mode 100644 index 0000000..276bcba --- /dev/null +++ b/src/c_output.iom @@ -0,0 +1,94 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: c_output.iom $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_outp $ +// +// Platform C +// + +#ifndef COUTPUT_IOM +#define COUTPUT_IOM + +#define NO_OF_OUTPUTS 3 +#define pMapOutPut ((IOMAPOUTPUT*)(pHeaders[ENTRY_OUTPUT]->pIOMap)) + +// Constants reffering to mode +enum +{ + MOTORON = 0x01, + BRAKE = 0x02, + REGULATED = 0x04, + REG_METHOD = 0xF0 /* Regulation methods - to be designed! */ +}; + +// Constants related to Flags +enum +{ + UPDATE_MODE = 0x01, + UPDATE_SPEED = 0x02, + UPDATE_TACHO_LIMIT = 0x04, + UPDATE_RESET_COUNT = 0x08, + UPDATE_PID_VALUES = 0x10, + UPDATE_RESET_BLOCK_COUNT = 0x20, + UPDATE_RESET_ROTATION_COUNT = 0x40, + PENDING_UPDATES = 0x80 +}; + +// Constant related to RunState +#define MOTOR_RUN_STATE_IDLE 0x00 +#define MOTOR_RUN_STATE_RAMPUP 0x10 +#define MOTOR_RUN_STATE_RUNNING 0x20 +#define MOTOR_RUN_STATE_RAMPDOWN 0x40 + +// Constant related to RegMode +enum +{ + REGULATION_MODE_IDLE = 0, + REGULATION_MODE_MOTOR_SPEED = 1, + REGULATION_MODE_MOTOR_SYNC = 2, + REGULATION_MODE_MOTOR_POS = 4, +}; + +typedef struct +{ + SLONG TachoCnt; /* R - Holds current number of counts, since last reset, updated every 1 mS */ + SLONG BlockTachoCount; /* R - Holds current number of counts for the current output block */ + SLONG RotationCount; /* R - Holds current number of counts for the rotation counter to the output */ + ULONG TachoLimit; /* RW - Holds number of counts to travel, 0 => Run forever */ + SWORD MotorRPM; /* !! Is not updated, will be removed later !! */ + UBYTE Flags; /* RW - Holds flags for which data should be updated */ + UBYTE Mode; /* RW - Holds motor mode: Run, Break, regulated, ... */ + SBYTE Speed; /* RW - Holds the wanted speed */ + SBYTE ActualSpeed; /* R - Holds the current motor speed */ + UBYTE RegPParameter; /* RW - Holds the P-constant use din the regulation, Is set to a default value at init => Setting this value is optional for the user */ + UBYTE RegIParameter; /* RW - Holds the I-constant use din the regulation, Is set to a default value at init => Setting this value is optional for the user */ + UBYTE RegDParameter; /* RW - Holds the D-constant use din the regulation, Is set to a default value at init => Setting this value is optional for the user */ + UBYTE RunState; /* RW - Holds the current RunState in the output module */ + UBYTE RegMode; /* RW - Tells which regulation mode should be used */ + UBYTE Overloaded; /* R - True if the motor has been overloaded within speed control regulation */ + SBYTE SyncTurnParameter; /* RW - Holds the turning parameter need within MoveBlock */ + UBYTE Options; + SBYTE MaxSpeed; /* RW - Maximum speed for absolute regulation, or 0 for no limit */ + SBYTE MaxAcceleration; /* RW - Maximum acceleration for absolute regulation, or 0 for no limit */ +}OUTPUT; + + +typedef struct +{ + OUTPUT Outputs[NO_OF_OUTPUTS]; + UBYTE RegulationTime; /* RW - Interval between regulation computations */ + UBYTE RegulationOptions; /* RW - Options for regulation, see REGOPTION_* */ +}IOMAPOUTPUT; + + + +#endif + + + diff --git a/src/c_sound.c b/src/c_sound.c new file mode 100644 index 0000000..9d0a81d --- /dev/null +++ b/src/c_sound.c @@ -0,0 +1,309 @@ +// +// Programmer +// +// Date init 14.12.2004 +// +// Reviser $Author:: Dkandlun $ +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: c_sound.c $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_soun $ +// +// Platform C +// + +#include +#include +#include "stdconst.h" +#include "modules.h" +#include "c_sound.iom" +#include "c_loader.iom" +#include "c_sound.h" +#include "d_sound.h" + +static IOMAPSOUND IOMapSound; +static VARSSOUND VarsSound; +static HEADER **pHeaders; + +const HEADER cSound = +{ + 0x00080001L, + "Sound", + cSoundInit, + cSoundCtrl, + cSoundExit, + (void *)&IOMapSound, + (void *)&VarsSound, + (UWORD)sizeof(IOMapSound), + (UWORD)sizeof(VarsSound), + 0x0000 //Code size - not used so far +}; + + +UWORD cSoundFile(UBYTE Cmd,UBYTE *pFile,UBYTE *pData,ULONG *pLng) +{ + return (pMapLoader->pFunc(Cmd,pFile,pData,pLng)); +} + + +void cSoundInit(void* pHeader) +{ + pHeaders = pHeader; + IOMapSound.Flags &= ~SOUND_UPDATE; + IOMapSound.Flags &= ~SOUND_RUNNING; + IOMapSound.State = SOUND_IDLE; + IOMapSound.Mode = SOUND_ONCE; + IOMapSound.Volume = SOUNDVOLUMESTEPS; + IOMapSound.SampleRate = 0; + IOMapSound.SoundFilename[0] = 0; + VarsSound.BufferIn = 0; + VarsSound.BufferOut = 0; + dSoundInit(); +} + +void cSoundCtrl(void) +{ + static UWORD FileFormat; + static UBYTE SoundFilename[FILENAME_LENGTH + 1]; + UWORD Handle; + ULONG Length; + UBYTE Header[FILEHEADER_LENGTH]; + UBYTE In,Out,Tmp; + + In = VarsSound.BufferIn; + Out = VarsSound.BufferOut; + + if ((IOMapSound.Flags & SOUND_UPDATE)) + { +// Check if valid update + if (!(SOUND_TONE & IOMapSound.Mode)) + { + Handle = pMapLoader->pFunc(FINDFIRST,IOMapSound.SoundFilename,SoundFilename,&Length); + if (!(Handle & 0x8000)) + { + pMapLoader->pFunc(CLOSE,(UBYTE*)&Handle,NULL,NULL); + } + else + { + IOMapSound.Flags &= ~SOUND_UPDATE; + } + } + if ((IOMapSound.Flags & SOUND_UPDATE)) + { +// Check for open file + if (!(VarsSound.File & 0x8000)) + { + cSoundFile(CLOSE,(UBYTE*)&VarsSound.File,NULL,NULL); + VarsSound.File = 0x8000; + } + + IOMapSound.Flags &= ~SOUND_UPDATE; + + if ((SOUND_TONE & IOMapSound.Mode)) + { + dSoundFreq(IOMapSound.Freq,IOMapSound.Duration,IOMapSound.Volume); + IOMapSound.State = SOUND_FREQ; + } + else + { + if (IOMapSound.Flags & SOUND_RUNNING) + { + dSoundStop(); + IOMapSound.Flags &= ~SOUND_RUNNING; + } + VarsSound.File = pMapLoader->pFunc(OPENREAD,SoundFilename,NULL,&Length); + if (!(VarsSound.File & 0x8000)) + { + Length = FILEHEADER_LENGTH; + pMapLoader->pFunc(READ,(UBYTE*)&VarsSound.File,Header,&Length); + if (Length == FILEHEADER_LENGTH) + { + FileFormat = ((UWORD)Header[0] << 8) + (UWORD)Header[1]; + + if (FILEFORMAT_SOUND == (FileFormat & 0xFF00)) + { + if (IOMapSound.SampleRate) + { + VarsSound.SampleRate = IOMapSound.SampleRate; + IOMapSound.SampleRate = 0; + } + else + { + VarsSound.SampleRate = ((UWORD)Header[4] << 8) + (UWORD)Header[5]; + } + dSoundVolume(IOMapSound.Volume); + Length = SOUNDBUFFERSIZE; + pMapLoader->pFunc(READ,(UBYTE*)&VarsSound.File,VarsSound.Buffer[In],&Length); + VarsSound.Length[In] = (UWORD)Length; + In++; + if (In >= SOUNDBUFFERS) + { + In = 0; + } + IOMapSound.State = SOUND_BUSY; + } + else + { + if (FILEFORMAT_MELODY == FileFormat) + { + Length = SOUNDBUFFERSIZE; + pMapLoader->pFunc(READ,(UBYTE*)&VarsSound.File,VarsSound.Buffer[In],&Length); + VarsSound.Length[In] = (UWORD)Length; + In++; + if (In >= SOUNDBUFFERS) + { + In = 0; + } + IOMapSound.State = SOUND_BUSY; + } + else + { + pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsSound.File,NULL,NULL); + } + } + } + } + } + } + } + + switch (IOMapSound.State) + { + case SOUND_BUSY : + { + IOMapSound.Flags |= SOUND_RUNNING; + if (In != Out) + { + if ((FILEFORMAT_SOUND == FileFormat) || (FILEFORMAT_SOUND_COMPRESSED == FileFormat)) + { + if (dSoundStart(VarsSound.Buffer[Out],VarsSound.Length[Out],VarsSound.SampleRate,(UBYTE)(FileFormat & 0x00FF)) == TRUE) + { + Out++; + if (Out >= SOUNDBUFFERS) + { + Out = 0; + } + } + } + else + { + if (dSoundTone(VarsSound.Buffer[Out],VarsSound.Length[Out],IOMapSound.Volume) == TRUE) + { + Out++; + if (Out >= SOUNDBUFFERS) + { + Out = 0; + } + } + } + } + + Tmp = In; + Tmp++; + if (Tmp >= SOUNDBUFFERS) + { + Tmp = 0; + } + + if (Tmp != Out) + { + Tmp++; + if (Tmp >= SOUNDBUFFERS) + { + Tmp = 0; + } + if (Tmp != Out) + { + Length = SOUNDBUFFERSIZE; + Handle = cSoundFile(READ,(UBYTE*)&VarsSound.File,VarsSound.Buffer[In],&Length); + if ((Handle & 0x8000)) + { + Length = 0L; + } + VarsSound.Length[In] = (UWORD)Length; + if (VarsSound.Length[In] == 0) + { + if (SOUND_LOOP == IOMapSound.Mode) + { + if (!(IOMapSound.Flags & SOUND_UPDATE)) + { + cSoundFile(CLOSE,(UBYTE*)&VarsSound.File,NULL,NULL); + VarsSound.File = cSoundFile(OPENREAD,SoundFilename,NULL,&Length); + Length = FILEHEADER_LENGTH; + cSoundFile(READ,(UBYTE*)&VarsSound.File,Header,&Length); + Length = SOUNDBUFFERSIZE; + cSoundFile(READ,(UBYTE*)&VarsSound.File,VarsSound.Buffer[In],&Length); + VarsSound.Length[In] = (UWORD)Length; + } + } + } + if (VarsSound.Length[In] != 0) + { + In++; + if (In >= SOUNDBUFFERS) + { + In = 0; + } + } + if (VarsSound.Length[Out] == 0) + { + if (!(VarsSound.File & 0x8000)) + { + pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsSound.File,NULL,NULL); + VarsSound.File = 0x8000; + } + IOMapSound.Flags &= ~SOUND_RUNNING; + IOMapSound.State = SOUND_IDLE; + } + } + } + } + break; + + case SOUND_FREQ : + { + IOMapSound.Flags |= SOUND_RUNNING; + if (dSoundReady() == TRUE) + { + if (SOUND_LOOP & IOMapSound.Mode) + { + dSoundFreq(IOMapSound.Freq,IOMapSound.Duration,IOMapSound.Volume); + } + else + { + IOMapSound.Flags &= ~SOUND_RUNNING; + IOMapSound.State = SOUND_IDLE; + } + } + } + break; + + case SOUND_STOP : + { + dSoundStop(); + if (!(VarsSound.File & 0x8000)) + { + pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsSound.File,NULL,NULL); + VarsSound.File = 0x8000; + } + IOMapSound.Flags &= ~SOUND_RUNNING; + IOMapSound.State = SOUND_IDLE; + Out = In; + } + break; + + } + + VarsSound.BufferIn = In; + VarsSound.BufferOut = Out; +} + + +void cSoundExit(void) +{ + dSoundExit(); +} diff --git a/src/c_sound.h b/src/c_sound.h new file mode 100644 index 0000000..ebdbb9a --- /dev/null +++ b/src/c_sound.h @@ -0,0 +1,44 @@ +// +// Programmer +// +// Date init 14.12.2004 +// +// Reviser $Author:: Dkandlun $ +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: c_sound.h $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_soun $ +// +// Platform C +// + + +#ifndef C_SOUND +#define C_SOUND + +#define SOUNDBUFFERSIZE 64 // Flash Sector size ? +#define SOUNDBUFFERS 3 // Min 3 - max 255 + + +typedef struct +{ + UWORD Length[SOUNDBUFFERS]; + UWORD File; + UWORD SampleRate; + UBYTE Buffer[SOUNDBUFFERS][SOUNDBUFFERSIZE]; + UBYTE BufferIn; + UBYTE BufferOut; + UBYTE BufferTmp; +}VARSSOUND; + +void cSoundInit(void* pHeaders); +void cSoundCtrl(void); +void cSoundExit(void); + +extern const HEADER cSound; + +#endif diff --git a/src/c_sound.iom b/src/c_sound.iom new file mode 100644 index 0000000..ec12076 --- /dev/null +++ b/src/c_sound.iom @@ -0,0 +1,109 @@ +// +// Programmer +// +// Date init 14.12.2004 +// +// Reviser $Author:: Dkandlun $ +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: c_sound.iom $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_soun $ +// +// Platform C +// + +#ifndef CSOUND_IOM +#define CSOUND_IOM + +#define pMapSound ((IOMAPSOUND*)(pHeaders[ENTRY_SOUND]->pIOMap)) + + +/* HOW TO + +Start a sound file strcpy((char*)pMapSound->SoundFilename,"xxxxxxx.rso"); + pMapSound->Volume = IOMapUi.Volume; + pMapSound->Mode = SOUND_ONCE; + pMapSound->Flags |= SOUND_UPDATE; + + +Start and loop a sound file strcpy((char*)pMapSound->SoundFilename,"xxxxxxx.rso"); + pMapSound->Volume = IOMapUi.Volume; + pMapSound->Mode = SOUND_LOOP; + pMapSound->Flags |= SOUND_UPDATE; + + +Start a tone pMapSound->Freq = 440; + pMapSound->Duration = 1000; + pMapSound->Volume = IOMapUi.Volume; + pMapSound->Mode = SOUND_TONE; + pMapSound->Flags |= SOUND_UPDATE; + + +Start and loop a tone pMapSound->Freq = 440; + pMapSound->Duration = 1000; + pMapSound->Volume = IOMapUi.Volume; + pMapSound->Mode = SOUND_TONE | SOUND_LOOP; + pMapSound->Flags |= SOUND_UPDATE; + + + +Test for sound finished if (!(pMapSound->Flags & (SOUND_RUNNING | SOUND_UPDATE))) + { + // FINISHED + } + + +Abort sound or tone pMapSound->State = SOUND_STOP; + + +**** Start always abort running sound or tone **** + + + +*/ + +// Constants related to Flags +enum +{ + SOUND_UPDATE = 0x01, // W - Make changes take effect + SOUND_RUNNING = 0x02 // R - Processing tone or file +}; + +// Constants related to State +enum +{ + SOUND_IDLE = 0x00, // R - Idle, ready for start sound (SOUND_UPDATE) + SOUND_BUSY = 0x02, // R - Processing file of sound/melody data + SOUND_FREQ = 0x03, // R - Processing play tone request + SOUND_STOP = 0x04 // W - Stop sound imedately and close hardware +}; + +// Constants related to Mode +enum +{ + SOUND_ONCE = 0x00, // W - Only play file once + SOUND_LOOP = 0x01, // W - Play file until writing "SOUND_STOP" into "State" or new "update" + SOUND_TONE = 0x02 // W - Play tone specified in Freq for Duration ms +}; + +typedef struct +{ + UWORD Freq; // RW - Tone frequency [Hz] + UWORD Duration; // RW - Tone duration [mS] + UWORD SampleRate; // RW - Sound file sample rate [2000..16000] + UBYTE SoundFilename[FILENAME_LENGTH + 1]; // RW - Sound/melody filename + UBYTE Flags; // RW - Play flag - descripted above + UBYTE State; // RW - Play state - descriped above + UBYTE Mode; // RW - Play mode - descriped above + UBYTE Volume; // RW - Sound/melody volume [0..4] 0 = off +}IOMAPSOUND; + + +#endif + + + diff --git a/src/c_ui.c b/src/c_ui.c new file mode 100644 index 0000000..7e39d6f --- /dev/null +++ b/src/c_ui.c @@ -0,0 +1,1944 @@ +// +// Programmer +// +// Date init 14.12.2004 +// +// Reviser $Author:: Dkandlun $ +// +// Revision date $Date:: 10-06-08 9:26 $ +// +// Filename $Workfile:: c_ui.c $ +// +// Version $Revision:: 7 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_ui.c $ +// +// Platform C +// + +#include "stdio.h" +#include "string.h" +#include "ctype.h" +#include "stdconst.h" +#include "modules.h" +#include "c_ui.iom" +#include "c_ui.h" +#include "m_sched.h" +#include "c_display.iom" +#include "c_loader.iom" +#include "c_button.iom" +#include "c_sound.iom" +#include "c_input.iom" +#include "c_output.iom" +#include "c_ioctrl.iom" +#include "c_cmd.iom" +#include "c_comm.iom" +#include "c_lowspeed.iom" + +static IOMAPUI IOMapUi; +static VARSUI VarsUi; +static HEADER **pHeaders; + +const HEADER cUi = +{ + 0x000C0001L, + "Ui", + cUiInit, + cUiCtrl, + cUiExit, + (void *)&IOMapUi, + (void *)&VarsUi, + (UWORD)sizeof(IOMapUi), + (UWORD)sizeof(VarsUi), + 0x0000 // Code size - not used so far +}; + + +// ****** GENERAL GRAPHIC RESOURCES ****************************************** + +#include "Display.txt" // Bitmap for frame used in view and datalog +#include "LowBattery.txt" // Bitmap showed when low battery occures +#include "Font.txt" // Font used for all text +#include "Step.txt" // Bitmap used in On Brick Programming +#include "Cursor.txt" // Bitmap for cursor +#include "Running.txt" // Icon collection used for "running" symbol +#include "Port.txt" // Font used for naming sensor ports in datalog/bluetooth +#include "Ok.txt" // Bitmap for OK buttom in get user string +#include "Wait.txt" // Bitmap for feedback +#include "Fail.txt" // Bitmap for feedback +#include "Info.txt" // Bitmap for feedback +#include "Icons.txt" // Icon collection used for menues + +// ****** INTRO ANIMATION RESOURCES ****************************************** + +#include "RCXintro_1.txt" // Bitmap for picture 1 in the intro animation +#include "RCXintro_2.txt" // Bitmap for picture 2 in the intro animation +#include "RCXintro_3.txt" // Bitmap for picture 3 in the intro animation +#include "RCXintro_4.txt" // Bitmap for picture 4 in the intro animation +#include "RCXintro_5.txt" // Bitmap for picture 5 in the intro animation +#include "RCXintro_6.txt" // Bitmap for picture 6 in the intro animation +#include "RCXintro_7.txt" // Bitmap for picture 7 in the intro animation +#include "RCXintro_8.txt" // Bitmap for picture 8 in the intro animation +#include "RCXintro_9.txt" // Bitmap for picture 9 in the intro animation +#include "RCXintro_10.txt" // Bitmap for picture 10 in the intro animation +#include "RCXintro_11.txt" // Bitmap for picture 11 in the intro animation +#include "RCXintro_12.txt" // Bitmap for picture 12 in the intro animation +#include "RCXintro_13.txt" // Bitmap for picture 13 in the intro animation +#include "RCXintro_14.txt" // Bitmap for picture 14 in the intro animation +#include "RCXintro_15.txt" // Bitmap for picture 15 in the intro animation +#include "RCXintro_16.txt" // Bitmap for picture 16 in the intro animation + +const BMPMAP *Intro[NO_OF_INTROBITMAPS] = // Picture sequence for the intro animation +{ + (BMPMAP*) POINTER_TO_DATA (RCXintro_1), + (BMPMAP*) POINTER_TO_DATA (RCXintro_2), + (BMPMAP*) POINTER_TO_DATA (RCXintro_3), + (BMPMAP*) POINTER_TO_DATA (RCXintro_4), + (BMPMAP*) POINTER_TO_DATA (RCXintro_5), + (BMPMAP*) POINTER_TO_DATA (RCXintro_6), + (BMPMAP*) POINTER_TO_DATA (RCXintro_7), + (BMPMAP*) POINTER_TO_DATA (RCXintro_8), + (BMPMAP*) POINTER_TO_DATA (RCXintro_9), + (BMPMAP*) POINTER_TO_DATA (RCXintro_10), + (BMPMAP*) POINTER_TO_DATA (RCXintro_11), + (BMPMAP*) POINTER_TO_DATA (RCXintro_12), + (BMPMAP*) POINTER_TO_DATA (RCXintro_13), + (BMPMAP*) POINTER_TO_DATA (RCXintro_14), + (BMPMAP*) POINTER_TO_DATA (RCXintro_15), + (BMPMAP*) POINTER_TO_DATA (RCXintro_16) +}; + +// ****** STATUS LINE GRAPHIC RESOURCES ************************************** + +#include "Status.txt" // Status icon collection file + +enum STATUS_NO // Index in status icon collection file +{ + STATUS_NO_NOT_USED, + STATUS_NO_RUNNING_0, + STATUS_NO_RUNNING_1, + STATUS_NO_RUNNING_2, + STATUS_NO_RUNNING_3, + STATUS_NO_RUNNING_4, + STATUS_NO_RUNNING_5, + STATUS_NO_RUNNING_6, + STATUS_NO_RUNNING_7, + STATUS_NO_RUNNING_8, + STATUS_NO_RUNNING_9, + STATUS_NO_RUNNING_10, + STATUS_NO_RUNNING_11, + STATUS_NO_BATTERY_0, + STATUS_NO_BATTERY_1, + STATUS_NO_BATTERY_2, + STATUS_NO_BATTERY_3, + STATUS_NO_BATTERY_4, + STATUS_NO_BATTERY_5, + STATUS_NO_RECHARGEABLE_0, + STATUS_NO_RECHARGEABLE_1, + STATUS_NO_RECHARGEABLE_2, + STATUS_NO_RECHARGEABLE_3, + STATUS_NO_RECHARGEABLE_4, + STATUS_NO_RECHARGEABLE_5, + STATUS_NO_BLUETOOTH_0, + STATUS_NO_BLUETOOTH_1, + STATUS_NO_BLUETOOTH_2, + STATUS_NO_BLUETOOTH_3, + STATUS_NO_BLUETOOTH_4, + STATUS_NO_BLUETOOTH_5, + STATUS_NO_USB_0, + STATUS_NO_USB_1, + STATUS_NO_USB_2, + STATUS_NO_USB_3, + STATUS_NO_USB_4, + STATUS_NO_USB_5 +}; + +// ****** BT DEVICE GRAPHIC RESOURCES **************************************** + +#include "Devices.txt" // Icon collection used for Blue tooth devices + +// ****** BT CONNECTIONS GRAPHIC RESOURCES *********************************** + +#include "Connections.txt" // Icon collection used for Blue tooth connections + +// ****** FREE TEXT GRAPHIC RESOURCES **************************************** + +#include "Ui.txt" // Text strings that is'nt defined in menu files + +enum // String index in text string file +{ + TXT_GENERAL_EMPTY, + // BlueTooth connect + TXT_FB_BT_CONNECTING_WAIT, // "Connecting" + TXT_FB_BT_CONNECT_BUSY_FAIL, // "Line is busy" + TXT_FB_BT_CONNECTING_FAIL, // "Failed!" + + // BlueTooth send file + TXT_FB_BT_SENDING_NO_CONN_FAIL, // "Connection?" + TXT_FB_BT_SENDING_WAIT, // "Sending file" + TXT_FB_BT_SENDING_FAIL, // "Failed!" + + // BlueTooth on/off + TXT_FB_BT_TURNING_ON_WAIT, // "Turning on" + TXT_FB_BT_TURNING_ON_FAIL, // "Failed!" + TXT_FB_BT_TURNING_OFF_WAIT, // "Turning off" + TXT_FB_BT_TURNING_OFF_FAIL, // "Failed!" + + // BlueTooth seach + TXT_FB_BT_SEARCHING_WAIT, // "Searching" + TXT_FB_BT_SEARCH_ABORTED_INFO, // "Aborted!" + TXT_FB_BT_SEARCHING_FAIL, // "Failed!" + + // BlueTooth device list + TXT_FB_BT_REMOVE_FAIL, // "Failed!" + + // BlueTooth connection list + TXT_FB_BT_DISCONNECT_FAIL, // "Failed!" + + // On Brick Programming + TXT_FB_OBP_MEMORY_FULL_FAIL, // "Memory full!" + TXT_FB_OBP_FILE_SAVED_INFO, // "File saved" + TXT_FB_OBP_FILE_EXIST_FAIL, // "File exist" + TXT_FB_OBP_OVERWRITE_FAIL, // "overwrite!" + + // Datalogging + TXT_FB_DL_FILE_SAVED_INFO, // "File saved" + TXT_FB_DL_FILE_EXIST_FAIL, // "File exist" + TXT_FB_DL_OVERWRITE_FAIL, // "overwrite!" + + // File delete + TXT_FB_FD_FILE_DELETED_INFO, // "File deleted" + + // Files delete + TXT_FB_FD_FILES_INFO, // "Files" + TXT_FB_FD_DELETED_INFO, // "deleted" + + // File run + TXT_FILERUN_RUNNING, // "Running" + TXT_FILERUN_ABORTED, // "Aborted!" + TXT_FILERUN_ENDED, // "Ended" + TXT_FILERUN_FILE_ERROR, // "File error!" + + // Files delete + TXT_FILESDELETE_DELETING_ALL, // "Deleting all" + TXT_FILESDELETE_S_FILES, // "%s files!" + + // Datalogging + TXT_DATALOGGING_PRESS_EXIT_TO, // "Press exit to" + TXT_DATALOGGING_STOP_DATALOGGING, // "stop datalogging" + TXT_DATALOGGING_PORT_OCCUPIED, // "Port occupied!" + TXT_DATALOGGING_RATE, // "H:MM:SS:00 + TXT_DATALOGGING_TIME, // "HH:MM:SS" + + // File types + TXT_FILETYPE_SOUND, // "Sound" + TXT_FILETYPE_LMS, // "Software" + TXT_FILETYPE_NXT, // "NXT" + TXT_FILETYPE_TRY_ME, // "Try me" + TXT_FILETYPE_DATA, // "Datalog" + + // Get user string + TXT_GETUSERSTRING_PIN, // "Pin:" + TXT_GETUSERSTRING_FILENAME, // "Filename:" + + // On Brick Programming + TXT_ONBRICKPROGRAMMING_PLEASE_USE_PORT, // "Please use port:" + TXT_ONBRICKPROGRAMMING_1_TOUCH_SENSOR, // "1 - Touch sensor" + TXT_ONBRICKPROGRAMMING_2_SOUND_SENSOR, // "2 - Sound sensor" + TXT_ONBRICKPROGRAMMING_3_LIGHT_SENSOR, // "3 - Light sensor" + TXT_ONBRICKPROGRAMMING_4_ULTRA_SONIC, // "4 - Ultra sonic" + TXT_ONBRICKPROGRAMMING_BC_LR_MOTORS, // "B/C - L/R motors" + + // View + TXT_VIEW_SELECT, // "Select" + + // BlueTooth device list + TXT_BTDEVICELIST_SELECT, // "Select" + + // BlueTooth connection list + TXT_BTCONNECTLIST_SELECT, // "Select" + + // Bluetooth list errors + TXT_FB_BT_ERROR_LR_COULD_NOT_SAVE_1, // BT save data error! + TXT_FB_BT_ERROR_LR_COULD_NOT_SAVE_2, // + TXT_FB_BT_ERROR_LR_STORE_IS_FULL_1, // BT store is full error! + TXT_FB_BT_ERROR_LR_STORE_IS_FULL_2, // + TXT_FB_BT_ERROR_LR_UNKOWN_ADDR_1, // BT unknown addr. error! + TXT_FB_BT_ERROR_LR_UNKOWN_ADDR_2, // + + // Datalog errors + TXT_FB_DL_ERROR_MEMORY_FULL_1, // Memory is full! + TXT_FB_DL_ERROR_MEMORY_FULL_2, // + + // Power of time + TXT_POWEROFFTIME_NEVER // "Never" + +}; + +// ****** FILE TYPE GRAPHIC RESOURCES **************************************** + +#define ALLFILES 0x1A // Icon collection offset + +enum // File type id's +{ + FILETYPE_ALL, // 0 = All + FILETYPE_SOUND, // 1 = Sound + FILETYPE_LMS, // 2 = LMS + FILETYPE_NXT, // 3 = NXT + FILETYPE_TRYME, // 4 = Try me + FILETYPE_DATALOG, // 5 = Datalog + FILETYPES +}; + +const UBYTE TXT_FILE_EXT[FILETYPES][4] = +{ + "*", // 0 = All + TXT_SOUND_EXT, // 1 = Sound + TXT_LMS_EXT, // 2 = LMS + TXT_NXT_EXT, // 3 = NXT + TXT_TRYME_EXT, // 4 = Try me + TXT_DATA_EXT // 5 = Datalog +}; + +const UBYTE TXT_FILETYPE[FILETYPES] = +{ + 0, // NA + TXT_FILETYPE_SOUND, // 1 = Sound + TXT_FILETYPE_LMS, // 2 = LMS + TXT_FILETYPE_NXT, // 3 = NXT + TXT_FILETYPE_TRY_ME,// 4 = Try me + TXT_FILETYPE_DATA // 5 = Datalog +}; + +// ****** POWER OFF DEFINITIONS ********************************************** + +#define POWER_OFF_TIME_STEPS 6 +#define POWER_OFF_TIME_DEFAULT 3 + +const UBYTE PowerOffTimeSteps[POWER_OFF_TIME_STEPS] = { 0,2,5,10,30,60 }; // [min] + +// ****** BATTERY DEFINITIONS ************************************************ + +#define BATTERYLIMITS 4 // [Cnt] +#define BATTERYLIMITHYST 100 // [mV] +#define RECHARGEABLELIMITHYST 50 // [mV] + +const UWORD BatteryLimits[BATTERYLIMITS] = +{ + 6100,6500,7000,7500 // [mV] +}; + +const UWORD RechargeableLimits[BATTERYLIMITS] = +{ + 7100,7200,7300,7500 // [mV] +}; + +//******* UI MENU FILE HANDLER ************************************************************************* + +#include "Mainmenu.rms" +#include "Submenu01.rms" +#include "Submenu02.rms" +#include "Submenu03.rms" +#include "Submenu04.rms" +#include "Submenu05.rms" +#include "Submenu06.rms" +#include "Submenu07.rms" + +const UBYTE *MenuPointers[] = +{ + (UBYTE*)MAINMENU, + (UBYTE*)SUBMENU01, + (UBYTE*)SUBMENU02, + (UBYTE*)SUBMENU03, + (UBYTE*)SUBMENU04, + (UBYTE*)SUBMENU05, + (UBYTE*)SUBMENU06, + (UBYTE*)SUBMENU07 +}; + + +UBYTE* cUiGetMenuPointer(UBYTE FileNo) +{ + return ((UBYTE*)MenuPointers[FileNo]); +} + + +//****************************************************************************************************** + +UBYTE* cUiGetString(UBYTE No) // Get string in text string file +{ + UBYTE *Result = NULL; + TXT *pUi; + UWORD Tmp; + + pUi = (TXT*)Ui; + if (No) + { + if (No <= pUi->ItemsY) + { + Tmp = No - 1; + Tmp *= pUi->ItemCharsX; + Result = &(pUi->Data[Tmp]); + } + } + + return (Result); +} + + +UBYTE cUiReadButtons(void) // Read buttons +{ + UBYTE Result = BUTTON_NONE; + + if (!(IOMapUi.Flags & UI_DISABLE_LEFT_RIGHT_ENTER)) + { + if ((pMapButton->State[BTN3] & PRESSED_STATE)) + { + Result = BUTTON_LEFT; + } + if ((pMapButton->State[BTN2] & PRESSED_STATE)) + { + Result = BUTTON_RIGHT; + } + if ((pMapButton->State[BTN4] & PRESSED_STATE)) + { + Result = BUTTON_ENTER; + } + } + if (!(IOMapUi.Flags & UI_DISABLE_EXIT)) + { + if ((pMapButton->State[BTN1] & PRESSED_STATE)) + { + Result = BUTTON_EXIT; + } + } + if (Result == BUTTON_NONE) + { + // All buttons released + VarsUi.ButtonOld = BUTTON_NONE; + VarsUi.ButtonTime = BUTTON_DELAY_TIME; + } + else + { + // Some button pressed + if (VarsUi.ButtonOld == BUTTON_NONE) + { + // Just pressed + VarsUi.ButtonOld = Result; + VarsUi.ButtonTimer = 0; + } + else + { + // Still pressed + Result = BUTTON_NONE; + + if (VarsUi.ButtonTimer >= VarsUi.ButtonTime) + { + VarsUi.ButtonTimer = 0; + VarsUi.ButtonTime = BUTTON_REPEAT_TIME; + if ((VarsUi.ButtonOld == BUTTON_LEFT) || (VarsUi.ButtonOld == BUTTON_RIGHT)) + { + // If arrow repeat + Result = VarsUi.ButtonOld; + } + } + } + } + if (VarsUi.ButtonOld == BUTTON_NONE) + { + // If no key - check interface + Result = IOMapUi.Button; + IOMapUi.Button = BUTTON_NONE; + } + if (Result != BUTTON_NONE) + { + // If key - play key sound file + sprintf((char*)pMapSound->SoundFilename,"%s.%s",(char*)UI_KEYCLICK_SOUND,(char*)TXT_FILE_EXT[FILETYPE_SOUND]); + pMapSound->Volume = IOMapUi.Volume; + pMapSound->Mode = SOUND_ONCE; + pMapSound->Flags |= SOUND_UPDATE; + + // Reset power down timer + IOMapUi.Flags |= UI_RESET_SLEEP_TIMER; + } + + return (Result); +} + + +void cUiListLeft(UBYTE Limit,UBYTE *Center) +{ + UBYTE Tmp; + + Tmp = *Center; + if (Tmp > 1) + { + Tmp--; + } + else + { + if (Limit > 2) + { + Tmp = Limit; + } + } + *Center = Tmp; +} + + +void cUiListRight(UBYTE Limit,UBYTE *Center) +{ + UBYTE Tmp; + + Tmp = *Center; + if (Tmp < Limit) + { + Tmp++; + } + else + { + if (Limit > 2) + { + Tmp = 1; + } + } + *Center = Tmp; +} + + +void cUiListCalc(UBYTE Limit,UBYTE *Center,UBYTE *Left,UBYTE *Right) +{ + switch (Limit) + { + case 1 : + { + *Left = 0; + *Right = 0; + } + break; + + case 2 : + { + if ((*Center) == 1) + { + *Left = 0; + *Right = 2; + } + else + { + *Left = 1; + *Right = 0; + } + } + break; + + default : + { + *Left = *Center - 1; + if ((*Left) < 1) + { + *Left = Limit; + } + *Right = *Center + 1; + if ((*Right) > Limit) + { + *Right = 1; + } + } + break; + + } +} + + +UBYTE cUiMenuSearchSensorIcon(UBYTE Sensor) +{ + UBYTE Result = 0; + MENUITEM *MenuItem; + UBYTE Index; + + for (Index = 0;(Index < IOMapUi.pMenu->Items) && (Result == NULL);Index++) + { + MenuItem = &IOMapUi.pMenu->Data[Index]; + if (MenuItem->FunctionParameter == Sensor) + { + Result = MenuItem->IconImageNo; + } + } + + return (Result); +} + + +ULONG cUiMenuGetId(MENUITEM *pMenuItem) +{ + ULONG MenuId; + + MenuId = (ULONG)pMenuItem->ItemId01; + MenuId |= (ULONG)pMenuItem->ItemId23 << 8; + MenuId |= (ULONG)pMenuItem->ItemId45 << 16; + MenuId |= (ULONG)pMenuItem->ItemId67 << 24; + + return (MenuId); +} + + +ULONG cUiMenuGetSpecialMask(MENUITEM *pMenuItem) +{ + ULONG Mask; + + Mask = 0; + if (pMenuItem != NULL) + { + Mask = (ULONG)pMenuItem->SpecialMask0; + Mask |= (ULONG)pMenuItem->SpecialMask1 << 8; + Mask |= (ULONG)pMenuItem->SpecialMask2 << 16; + Mask |= (ULONG)pMenuItem->SpecialMask3 << 24; + } + + return (Mask); +} + + +UBYTE* cUiMenuGetIconImage(UBYTE No) +{ + UBYTE *Image; + + Image = NULL; + if (No < (Icons->ItemsX * Icons->ItemsY)) + { + Image = (UBYTE*)&Icons->Data[No * Icons->ItemPixelsX * (Icons->ItemPixelsY / 8)]; + } + + return (Image); +} + + +ULONG cUiMenuMotherId(ULONG Id,UBYTE Level) +{ + ULONG MotherIdMask; + + MotherIdMask = 0xFFFFFFFFL >> ((8 - Level) * 4); + MotherIdMask |= 0xFFFFFFFFL << ((Level + 1) * 4); + + return (Id & MotherIdMask); +} + + +UBYTE cUiMenuIdValid(MENUFILE *pMenuFile,ULONG Id) +{ + ULONG SpecialMask; + ULONG MotherId; + UBYTE Level; + UBYTE Result; + + Result = FALSE; + Level = pMenuFile->MenuLevel; + + if (Level) + { + SpecialMask = pMenuFile->MenuLevels[Level - 1].SpecialFlags; + MotherId = pMenuFile->MenuLevels[Level - 1].Id; + if ((SpecialMask & MENU_SKIP_THIS_MOTHER_ID)) + { + MotherId &= ~(0x0000000F << ((Level - 1) * 4)); + SpecialMask >>= 28; + MotherId |= (SpecialMask << ((Level - 1) * 4)); + } + if (MotherId == cUiMenuMotherId(Id,Level)) + { + Id >>= (Level * 4); + if ((Id & 0x0000000F) && (!(Id & 0xFFFFFFF0))) + { + Result = TRUE; + } + } + } + else + { + if ((Id & 0x0000000F) && (!(Id & 0xFFFFFFF0))) + { + Result = TRUE; + } + } + + return (Result); +} + + +UBYTE cUiMenuGetNoOfMenus(MENU *pMenu,MENUFILE *pMenuFile) +{ + ULONG MenuId; + UBYTE NoOfMenus; + UBYTE Index; + + NoOfMenus = 0; + for (Index = 0;Index < pMenu->Items;Index++) + { + MenuId = cUiMenuGetId(&pMenu->Data[Index]); + + if (cUiMenuIdValid(pMenuFile,MenuId) == TRUE) + { + if ((cUiMenuGetSpecialMask(&pMenu->Data[Index]) & MENU_ONLY_BT_ON)) + { + // BT module must be on + if (!(IOMapUi.BluetoothState & BT_STATE_OFF)) + { + // Yes + NoOfMenus++; + } + } + else + { + if ((cUiMenuGetSpecialMask(&pMenu->Data[Index]) & MENU_ONLY_DATALOG_ENABLED)) + { + // Datalog menu must be enabled + if (VarsUi.NVData.DatalogEnabled) + { + // Yes + NoOfMenus++; + } + } + else + { + // No restrictions + NoOfMenus++; + } + } + } + } + + return (NoOfMenus); +} + + +UBYTE cUiGetMenuItemIndex(MENU *pMenu,MENUFILE *pMenuFile,UBYTE No) +{ + ULONG MenuId; + UBYTE NoOfMenus; + UBYTE Index; + UBYTE TmpIndex = 0; + + NoOfMenus = 0; + for (Index = 0;(Index < pMenu->Items) && (No != NoOfMenus);Index++) + { + MenuId = cUiMenuGetId(&pMenu->Data[Index]); + + if (cUiMenuIdValid(pMenuFile,MenuId) == TRUE) + { + if ((cUiMenuGetSpecialMask(&pMenu->Data[Index]) & MENU_ONLY_BT_ON)) + { + // BT module must be on + if (!(IOMapUi.BluetoothState & BT_STATE_OFF)) + { + // Yes + TmpIndex = Index; + NoOfMenus++; + } + } + else + { + if ((cUiMenuGetSpecialMask(&pMenu->Data[Index]) & MENU_ONLY_DATALOG_ENABLED)) + { + // Datalog menu must be enabled + if (VarsUi.NVData.DatalogEnabled) + { + // Yes + TmpIndex = Index; + NoOfMenus++; + } + } + else + { + // No restrictions + TmpIndex = Index; + NoOfMenus++; + } + } + } + } + if (No != NoOfMenus) + { + Index = TmpIndex + 1; + } + + return (Index); +} + + + +UBYTE cUiMenuGetNo(MENU *pMenu,ULONG Id,UBYTE Level) +{ + ULONG MenuId; + ULONG MotherId; + UBYTE Index; + UBYTE No; + UBYTE NoOfItems; + + No = 0; + NoOfItems = 0; + + MotherId = cUiMenuMotherId(Id,Level); + + for (Index = 0;(Index < pMenu->Items) && (No == 0);Index++) + { + MenuId = cUiMenuGetId(&pMenu->Data[Index]); + + // Scanning all id's until No is found + if (!(MenuId >> ((Level + 1) * 4))) + { + // MenuId is above or on actual level + if (((MenuId >> (Level * 4)) & 0x0000000F)) + { + // MenuId is on actual level + if (MotherId == cUiMenuMotherId(MenuId,Level)) + { + // Same mother id + NoOfItems++; + if (MenuId == Id) + { + No = NoOfItems; + } + } + } + } + } + + return (No); +} + +void cUiUpdateStatus(void) +{ + UWORD Tmp; + UWORD Hyst; + UWORD *pTmp; + UBYTE Pointer; + + if (++VarsUi.UpdateCounter >= RUN_STATUS_CHANGE_TIME) + { + VarsUi.UpdateCounter = 0; + + // Update running status icon pointer + if (++VarsUi.Running >= 12) + { + VarsUi.Running = 0; + } + + // Get battery voltage limits + if ((IoFromAvr.Battery & 0x8000)) + { + IOMapUi.Rechargeable = 1; + pTmp = (UWORD*)RechargeableLimits; + Hyst = RECHARGEABLELIMITHYST; + } + else + { + IOMapUi.Rechargeable = 0; + pTmp = (UWORD*)BatteryLimits; + Hyst = BATTERYLIMITHYST; + } + + // Calculate battery voltage + Tmp = IoFromAvr.Battery & 0x03FF; + Tmp = (UWORD)((float)Tmp * BATTERY_COUNT_TO_MV); + + IOMapUi.BatteryVoltage = Tmp; + + // Find new battery state + Pointer = 0; + while ((Tmp > pTmp[Pointer]) && (Pointer < BATTERYLIMITS)) + { + Pointer++; + } + + // Change battery state + if (Pointer != IOMapUi.BatteryState) + { + if (Pointer > IOMapUi.BatteryState) + { + if (Tmp > (pTmp[IOMapUi.BatteryState] + Hyst)) + { + IOMapUi.BatteryState = Pointer; + } + } + else + { + IOMapUi.BatteryState = Pointer; + } + } + + // Control toggle and bitmap + if (IOMapUi.BatteryState) + { + VarsUi.BatteryToggle = 0; + VarsUi.LowBatt = 0; + } + else + { + if (VarsUi.LowBatt < 255) + { + VarsUi.LowBatt++; + } + + if (VarsUi.BatteryToggle) + { + VarsUi.BatteryToggle = 0; + } + else + { + VarsUi.BatteryToggle = 1; + } + } + + // Ensure frequently status updates + IOMapUi.Flags |= UI_UPDATE; + } + + if ((IOMapUi.Flags & UI_ENABLE_STATUS_UPDATE)) + { + if ((IOMapUi.Flags & UI_UPDATE) || (IOMapUi.Flags & UI_REDRAW_STATUS)) + { + VarsUi.ErrorTimer = 0; + pMapDisplay->pStatusText = (UBYTE*)VarsUi.StatusText; + + // Status line update nessesary + if (IOMapUi.BatteryState < Status->ItemsX) + { + // Update battery status icons + if (IoFromAvr.Battery & 0x8000) + { + VarsUi.NewStatusIcons[STATUSICON_BATTERY] = STATUS_NO_RECHARGEABLE_0 + IOMapUi.BatteryState + VarsUi.BatteryToggle; + } + else + { + VarsUi.NewStatusIcons[STATUSICON_BATTERY] = STATUS_NO_BATTERY_0 + IOMapUi.BatteryState + VarsUi.BatteryToggle; + } + } + + // Update bluetooth status icons + if ((IOMapUi.BluetoothState & (BT_STATE_VISIBLE | BT_STATE_CONNECTED | BT_STATE_OFF)) < Status->ItemsX) + { + VarsUi.NewStatusIcons[STATUSICON_BLUETOOTH] = STATUS_NO_BLUETOOTH_0 + (IOMapUi.BluetoothState & (BT_STATE_VISIBLE | BT_STATE_CONNECTED | BT_STATE_OFF)); + } + + // Update usb status icons + if (IOMapUi.UsbState < 6) + { + VarsUi.NewStatusIcons[STATUSICON_USB] = STATUS_NO_USB_0 + IOMapUi.UsbState; + } + + // Update running status icons + if (IOMapUi.RunState == FALSE) + { + VarsUi.Running = 0; + } + VarsUi.NewStatusIcons[STATUSICON_VM] = STATUS_NO_RUNNING_0 + VarsUi.Running; + + // Update only changed status icons + for (Pointer = 0;Pointer < STATUSICONS;Pointer++) + { + if ((pMapDisplay->StatusIcons[Pointer] != VarsUi.NewStatusIcons[Pointer])) + { + pMapDisplay->StatusIcons[Pointer] = VarsUi.NewStatusIcons[Pointer]; + pMapDisplay->UpdateMask |= STATUSICON_BIT(Pointer); + } + } + + if ((IOMapUi.Flags & UI_REDRAW_STATUS)) + { + // Entire status line needs to be redrawed + if (pMapComm->BrickData.Name[0]) + { + for (Pointer = 0;Pointer < STATUSTEXT_SIZE;Pointer++) + { + VarsUi.StatusText[Pointer] = pMapComm->BrickData.Name[Pointer]; + } + VarsUi.StatusText[Pointer] = 0; + } + pMapDisplay->EraseMask |= SPECIAL_BIT(STATUSTEXT); + pMapDisplay->UpdateMask |= SPECIAL_BIT(STATUSTEXT); + pMapDisplay->UpdateMask |= (SPECIAL_BIT(TOPLINE) | STATUSICON_BITS); + } + + // Clear update flag + IOMapUi.Flags &= ~UI_REDRAW_STATUS; + IOMapUi.Flags &= ~UI_UPDATE; + } + } + else + { + pMapDisplay->UpdateMask &= ~(STATUSICON_BITS | SPECIAL_BIT(TOPLINE) | SPECIAL_BIT(STATUSTEXT)); + } +} + + + + +void cUiMenuCallFunction(UBYTE Function,UBYTE Parameter) +{ + if (Function) + { + VarsUi.Function = Function; + VarsUi.Parameter = Parameter; + } +} + + +void cUiMenuNextFile(void) +{ + MENU *pTmpMenu; + + pTmpMenu = (MENU*)cUiGetMenuPointer(VarsUi.pMenuLevel->NextFileNo); + if (pTmpMenu != NULL) + { + if (VarsUi.MenuFileLevel < (MENUFILELEVELS - 1)) + { + VarsUi.MenuFileLevel++; + VarsUi.MenuFiles[VarsUi.MenuFileLevel].FileId = VarsUi.pMenuLevel->NextFileNo; + VarsUi.MenuFiles[VarsUi.MenuFileLevel].MenuLevel = 0; + VarsUi.MenuFiles[VarsUi.MenuFileLevel].MenuLevels[VarsUi.MenuFiles[VarsUi.MenuFileLevel].MenuLevel].ItemIndex = VarsUi.pMenuLevel->NextMenuNo; + IOMapUi.pMenu = pTmpMenu; + } + } +} + + +void cUiMenuPrevFile(void) +{ + if (VarsUi.MenuFileLevel) + { + VarsUi.MenuFileLevel--; + IOMapUi.pMenu = (MENU*)cUiGetMenuPointer(VarsUi.MenuFiles[VarsUi.MenuFileLevel].FileId); + } +} + + +void cUiMenuNext(void) +{ + if (VarsUi.pMenuFile->MenuLevel < (MENULEVELS - 1)) + { + VarsUi.pMenuFile->MenuLevel++; + VarsUi.pMenuFile->MenuLevels[VarsUi.pMenuFile->MenuLevel].ItemIndex = VarsUi.pMenuLevel->NextMenuNo; + } +} + + +void cUiMenuPrev(void) +{ + if (VarsUi.pMenuFile->MenuLevel) + { + VarsUi.pMenuFile->MenuLevel--; + } +} + + +void cUiMenuEnter(void) +{ + // Call function with parameter (if pressent) + if (!(VarsUi.pMenuLevel->SpecialFlags & MENU_INIT_CALLS)) + { + cUiMenuCallFunction(VarsUi.pMenuLevel->FunctionNo,VarsUi.pMenuLevel->Parameter); + } + + if (VarsUi.EnterOnlyCalls != TRUE) + { + if ((VarsUi.pMenuLevel->SpecialFlags & MENU_ENTER_LEAVES_MENUFILE)) + { + cUiMenuPrevFile(); + } + else + { + // Load new menu file (if pressent) + if (VarsUi.pMenuLevel->NextFileNo) + { + cUiMenuNextFile(); + } + else + { + // Activate next menu level (if pressent) + if (VarsUi.pMenuLevel->NextMenuNo) + { + cUiMenuNext(); + } + } + } + IOMapUi.State = NEXT_MENU; + } + else + { + VarsUi.EnterOnlyCalls = FALSE; + IOMapUi.State = DRAW_MENU; + } +} + + +void cUiMenuExit(void) +{ + + if ((VarsUi.pMenuLevel->SpecialFlags & MENU_EXIT_CALLS)) + { + // Call function with parameter (if pressent) + if (!(VarsUi.pMenuLevel->SpecialFlags & MENU_INIT_CALLS)) + { + cUiMenuCallFunction(VarsUi.pMenuLevel->FunctionNo,VarsUi.pMenuLevel->Parameter); + } + } + + // Call function with 0xFF (if ordered) + if ((VarsUi.pMenuLevel->SpecialFlags & MENU_EXIT_CALLS_WITH_FF)) + { + cUiMenuCallFunction(VarsUi.pMenuLevel->FunctionNo,MENU_EXIT); + } + + if (VarsUi.ExitOnlyCalls != TRUE) + { + if ((VarsUi.pMenuFile->MenuLevel) && (!(VarsUi.pMenuLevel->SpecialFlags & MENU_EXIT_LEAVES_MENUFILE))) + { + if (!(VarsUi.pMenuLevel->SpecialFlags & MENU_EXIT_LOAD_MENU)) + { + cUiMenuPrev(); + if ((VarsUi.pMenuLevel->SpecialFlags & MENU_BACK_TWICE)) + { + if (VarsUi.pMenuFile->MenuLevel) + { + cUiMenuPrev(); + } + VarsUi.SecondTime = FALSE; + } + if ((VarsUi.pMenuLevel->SpecialFlags & MENU_BACK_THREE_TIMES)) + { + if (VarsUi.pMenuFile->MenuLevel) + { + cUiMenuPrev(); + } + if (VarsUi.pMenuFile->MenuLevel) + { + cUiMenuPrev(); + } + VarsUi.SecondTime = FALSE; + } + } + else + { + VarsUi.EnterOnlyCalls = FALSE; + VarsUi.ExitOnlyCalls = FALSE; + if (VarsUi.pMenuLevel->NextFileNo) + { + cUiMenuNextFile(); + } + else + { + // Activate next menu level (if pressent) + if (VarsUi.pMenuLevel->NextMenuNo) + { + cUiMenuNext(); + } + } + } + if ((VarsUi.pMenuLevel->SpecialFlags & MENU_EXIT_LOAD_POINTER)) + { + VarsUi.pMenuFile->MenuLevels[VarsUi.pMenuFile->MenuLevel].ItemIndex = (UBYTE)((VarsUi.pMenuLevel->SpecialFlags) >> 24) & 0x0F; + } + } + else + { + if (!(VarsUi.pMenuLevel->SpecialFlags & MENU_EXIT_LOAD_MENU)) + { + cUiMenuPrevFile(); + } + else + { + VarsUi.EnterOnlyCalls = FALSE; + VarsUi.ExitOnlyCalls = FALSE; + if (VarsUi.pMenuLevel->NextFileNo) + { + cUiMenuNextFile(); + } + else + { + // Activate next menu level (if pressent) + if (VarsUi.pMenuLevel->NextMenuNo) + { + cUiMenuNext(); + } + } + } + } + IOMapUi.State = NEXT_MENU; + } + else + { + VarsUi.ExitOnlyCalls = FALSE; + IOMapUi.State = DRAW_MENU; + } +} + + +void cUiLoadLevel(UBYTE FileLevel,UBYTE MenuLevel,UBYTE MenuIndex) +{ + UBYTE Tmp; + + VarsUi.MenuFileLevel = FileLevel; + VarsUi.MenuFiles[FileLevel].MenuLevel = MenuLevel; + VarsUi.MenuFiles[FileLevel].MenuLevels[MenuLevel].ItemIndex = MenuIndex; + IOMapUi.pMenu = (MENU*)cUiGetMenuPointer(VarsUi.MenuFiles[VarsUi.MenuFileLevel].FileId); + + VarsUi.pMenuFile = &VarsUi.MenuFiles[VarsUi.MenuFileLevel]; + VarsUi.pMenuLevel = &VarsUi.pMenuFile->MenuLevels[VarsUi.pMenuFile->MenuLevel]; + + // Count no of menues on current level + VarsUi.pMenuLevel->Items = cUiMenuGetNoOfMenus(IOMapUi.pMenu,VarsUi.pMenuFile); + + if (VarsUi.pMenuLevel->Items) + { + // if items > 0 -> prepare allways center icon + Tmp = cUiGetMenuItemIndex(IOMapUi.pMenu,VarsUi.pMenuFile,VarsUi.pMenuLevel->ItemIndex); + + if (VarsUi.pMenuItem != &IOMapUi.pMenu->Data[Tmp - 1]) + { + VarsUi.pMenuItem = &IOMapUi.pMenu->Data[Tmp - 1]; + VarsUi.SecondTime = FALSE; + } + + // Save center menu item parameters + VarsUi.pMenuLevel->Id = cUiMenuGetId(VarsUi.pMenuItem); + VarsUi.pMenuLevel->IconImageNo = VarsUi.pMenuItem->IconImageNo; + VarsUi.pMenuLevel->IconText = VarsUi.pMenuItem->IconText; + VarsUi.pMenuLevel->SpecialFlags = cUiMenuGetSpecialMask(VarsUi.pMenuItem); + VarsUi.pMenuLevel->FunctionNo = VarsUi.pMenuItem->FunctionIndex; + VarsUi.pMenuLevel->Parameter = VarsUi.pMenuItem->FunctionParameter; + VarsUi.pMenuLevel->NextFileNo = VarsUi.pMenuItem->FileLoadNo; + VarsUi.pMenuLevel->NextMenuNo = VarsUi.pMenuItem->NextMenu; + } +} + +#include "Functions.inl" + + +void cUiInit(void* pHeader) +{ + pHeaders = pHeader; + VarsUi.Initialized = FALSE; + IOMapUi.BluetoothState = BT_STATE_OFF; + IOMapUi.UsbState = 0; + IOMapUi.State = INIT_DISPLAY; +} + + +void cUiCtrl(void) +{ + UBYTE Tmp; + +// Testcode for low battery voltage +/* + if ((pMapInput->Inputs[0].InvalidData != INVALID_DATA) && (pMapInput->Inputs[0].ADRaw < 500)) + { + if (VarsUi.LowBatt < 255) + { + VarsUi.LowBatt++; + } + } + else + { + VarsUi.LowBatt = 0; + } +*/ +// + +// Testcode for BT connect request +/* + if ((pMapInput->Inputs[0].InvalidData != INVALID_DATA) && (pMapInput->Inputs[0].ADRaw < 500)) + { + IOMapUi.BluetoothState |= BT_CONNECT_REQUEST | BT_PIN_REQUEST; + } +*/ +// + +// Testcode for BT error attention +/* + if ((pMapInput->Inputs[0].InvalidData != INVALID_DATA) && (pMapInput->Inputs[0].ADRaw < 500)) + { + IOMapUi.Error = LR_UNKOWN_ADDR; + IOMapUi.BluetoothState |= BT_ERROR_ATTENTION; + } +*/ +// + +// Testcode for execute program +/* + if ((pMapInput->Inputs[0].InvalidData != INVALID_DATA) && (pMapInput->Inputs[0].ADRaw < 500)) + { + if ((!(IOMapUi.Flags & UI_EXECUTE_LMS_FILE)) && (IOMapUi.State > INIT_MENU)) + { + strcpy((char*)IOMapUi.LMSfilename,"Untitled-1.rxe"); + IOMapUi.Flags |= UI_EXECUTE_LMS_FILE; + } + } +*/ +// + +// Testcode for force off +/* + if ((pMapInput->Inputs[0].InvalidData != INVALID_DATA) && (pMapInput->Inputs[0].ADRaw < 500) && (VarsUi.Initialized == TRUE)) + { + IOMapUi.ForceOff = TRUE; + } +*/ +// + + + VarsUi.CRPasskey++; + VarsUi.ButtonTimer++; + VarsUi.OBPTimer++; + switch (IOMapUi.State) + { + case INIT_DISPLAY : // Load font and icons + { +// pMapLoader->pFunc(DELETEUSERFLASH,NULL,NULL,NULL); + + VarsUi.Initialized = FALSE; + + IOMapUi.Flags = UI_BUSY; + IOMapUi.RunState = 1; + IOMapUi.BatteryState = 0; + IOMapUi.Error = 0; + IOMapUi.ForceOff = FALSE; + VarsUi.LowBatt = 0; + VarsUi.LowBattHasOccured = 0; + + pMapDisplay->pFont = (FONT*)Font; + pMapDisplay->pStatusIcons = (ICON*)Status; + pMapDisplay->pStatusText = (UBYTE*)VarsUi.StatusText; + pMapDisplay->pStepIcons = (ICON*)Step; + + VarsUi.State = 0; + VarsUi.Pointer = 0; + VarsUi.Timer = CONFIG_INTRO ? -INTRO_START_TIME : 0; + + VarsUi.FNOFState = 0; + VarsUi.FBState = 0; + + VarsUi.UpdateCounter = 0; + VarsUi.Running = 0; + VarsUi.BatteryToggle = 0; + + VarsUi.GUSState = 0; + + IOMapUi.pMenu = (MENU*)cUiGetMenuPointer(0); + IOMapUi.State = CONFIG_INTRO ? INIT_INTRO : INIT_WAIT; + + pMapDisplay->EraseMask = SCREEN_BIT(SCREEN_BACKGROUND); + pMapDisplay->pBitmaps[BITMAP_1] = CONFIG_INTRO ? (BMPMAP*)Intro[VarsUi.Pointer] : RCXintro_16; + pMapDisplay->UpdateMask = BITMAP_BIT(BITMAP_1); + pMapDisplay->Flags |= DISPLAY_ON; + + cUiNVRead(); + IOMapUi.Volume = VarsUi.NVData.VolumeStep; + IOMapUi.SleepTimeout = PowerOffTimeSteps[VarsUi.NVData.PowerdownCode]; + } + break; + +#if CONFIG_INTRO + case INIT_LOW_BATTERY : + { + if (++VarsUi.Timer >= (INTRO_LOWBATT_TIME)) + { + VarsUi.LowBattHasOccured = 2; + pMapDisplay->EraseMask = SCREEN_BIT(SCREEN_BACKGROUND); + pMapDisplay->pBitmaps[BITMAP_1] = (BMPMAP*)Intro[VarsUi.Pointer]; + pMapDisplay->UpdateMask = BITMAP_BIT(BITMAP_1); + IOMapUi.Flags &= ~UI_ENABLE_STATUS_UPDATE; + VarsUi.State = 0; + VarsUi.Pointer = 0; + VarsUi.Timer = -INTRO_START_TIME; + IOMapUi.State = INIT_INTRO; + } + } + break; + + case INIT_INTRO : + { + if (VarsUi.LowBattHasOccured == 1) + { + IOMapUi.Flags |= UI_ENABLE_STATUS_UPDATE; + IOMapUi.Flags |= UI_UPDATE; + IOMapUi.Flags |= UI_REDRAW_STATUS; + VarsUi.Timer = 0; + IOMapUi.State = INIT_LOW_BATTERY; + } + else + { + if (VarsUi.LowBattHasOccured == 0) + { + if (VarsUi.LowBatt) + { + pMapDisplay->pBitmaps[BITMAP_1] = (BMPMAP*)LowBattery; + pMapDisplay->UpdateMask = BITMAP_BIT(BITMAP_1); + VarsUi.LowBattHasOccured = 1; + } + } + if (++VarsUi.Timer >= (INTRO_SHIFT_TIME)) + { + switch (VarsUi.State) + { + case 0 : + { + pMapDisplay->Flags &= ~DISPLAY_REFRESH; + VarsUi.State++; + } + break; + + case 1 : + { + if ((pMapDisplay->Flags & DISPLAY_REFRESH_DISABLED)) + { + if (VarsUi.Pointer < NO_OF_INTROBITMAPS) + { + pMapDisplay->EraseMask |= BITMAP_BIT(BITMAP_1); + pMapDisplay->pBitmaps[BITMAP_1] = (BMPMAP*)Intro[VarsUi.Pointer]; + pMapDisplay->UpdateMask = BITMAP_BIT(BITMAP_1); + if (VarsUi.Pointer == 11) + { + sprintf((char*)pMapSound->SoundFilename,"%s.%s",(char*)UI_STARTUP_SOUND,(char*)TXT_FILE_EXT[FILETYPE_SOUND]); + pMapSound->Volume = IOMapUi.Volume; + pMapSound->Mode = SOUND_ONCE; + pMapSound->Flags |= SOUND_UPDATE; + } + VarsUi.Pointer++; + } + else + { + pMapDisplay->Flags |= DISPLAY_REFRESH; + IOMapUi.State = INIT_WAIT; + } + VarsUi.State++; + } + } + break; + + default : + { + if (!(pMapDisplay->UpdateMask & BITMAP_BIT(BITMAP_1))) + { + pMapDisplay->Flags |= DISPLAY_REFRESH; + VarsUi.Timer = 0; + VarsUi.State = 0; + } + } + break; + + } + } + } + } + break; +#endif /* CONFIG_INTRO */ + + case INIT_WAIT : + { + if (++VarsUi.Timer >= INTRO_STOP_TIME) + { + pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_BACKGROUND); + IOMapUi.State = INIT_MENU; + } + } + break; + + case INIT_MENU : + { + // Restart menu system + VarsUi.Function = 0; + VarsUi.MenuFileLevel = 0; + + cUiLoadLevel(0,0,1); + cUiLoadLevel(0,1,1); + + VarsUi.EnterOnlyCalls = FALSE; + VarsUi.ExitOnlyCalls = FALSE; + + IOMapUi.State = NEXT_MENU; + } + break; + + case NEXT_MENU : // prepare icons + { + // Init various variables + VarsUi.State = 0; + + // Init icon pointers + pMapDisplay->pMenuIcons[MENUICON_LEFT] = NULL; + pMapDisplay->pMenuIcons[MENUICON_CENTER] = NULL; + pMapDisplay->pMenuIcons[MENUICON_RIGHT] = NULL; + + cUiLoadLevel(VarsUi.MenuFileLevel,VarsUi.MenuFiles[VarsUi.MenuFileLevel].MenuLevel,VarsUi.MenuFiles[VarsUi.MenuFileLevel].MenuLevels[VarsUi.MenuFiles[VarsUi.MenuFileLevel].MenuLevel].ItemIndex); + + // Find menu icons + if (VarsUi.pMenuLevel->Items) + { + // Prepare center icon + pMapDisplay->pMenuIcons[MENUICON_CENTER] = cUiMenuGetIconImage(VarsUi.pMenuLevel->IconImageNo); + pMapDisplay->pMenuText = VarsUi.pMenuLevel->IconText; + + if (VarsUi.pMenuLevel->Items == 2) + { + // if 2 menues -> prepare left or right icon + if (VarsUi.pMenuLevel->ItemIndex == 1) + { + Tmp = cUiGetMenuItemIndex(IOMapUi.pMenu,VarsUi.pMenuFile,2); + if (Tmp) + { + Tmp--; + pMapDisplay->pMenuIcons[MENUICON_RIGHT] = cUiMenuGetIconImage(IOMapUi.pMenu->Data[Tmp].IconImageNo); + } + } + else + { + Tmp = cUiGetMenuItemIndex(IOMapUi.pMenu,VarsUi.pMenuFile,1); + if (Tmp) + { + Tmp--; + pMapDisplay->pMenuIcons[MENUICON_LEFT] = cUiMenuGetIconImage(IOMapUi.pMenu->Data[Tmp].IconImageNo); + } + } + } + + if (VarsUi.pMenuLevel->Items > 2) + { + // if more menues -> prepare left and right icon + if (VarsUi.pMenuLevel->ItemIndex > 1) + { + Tmp = VarsUi.pMenuLevel->ItemIndex -1; + } + else + { + Tmp = VarsUi.pMenuLevel->Items; + } + Tmp = cUiGetMenuItemIndex(IOMapUi.pMenu,VarsUi.pMenuFile,Tmp); + if (Tmp) + { + Tmp--; + pMapDisplay->pMenuIcons[MENUICON_LEFT] = cUiMenuGetIconImage(IOMapUi.pMenu->Data[Tmp].IconImageNo); + + } + if (VarsUi.pMenuLevel->ItemIndex < VarsUi.pMenuLevel->Items) + { + Tmp = VarsUi.pMenuLevel->ItemIndex + 1; + } + else + { + Tmp = 1; + } + Tmp = cUiGetMenuItemIndex(IOMapUi.pMenu,VarsUi.pMenuFile,Tmp); + if (Tmp) + { + Tmp--; + pMapDisplay->pMenuIcons[MENUICON_RIGHT] = cUiMenuGetIconImage(IOMapUi.pMenu->Data[Tmp].IconImageNo); + } + } + } + if ((VarsUi.pMenuLevel->SpecialFlags & MENU_ENTER_ONLY_CALLS)) + { + VarsUi.EnterOnlyCalls = TRUE; + } + if ((VarsUi.pMenuLevel->SpecialFlags & MENU_EXIT_ONLY_CALLS)) + { + VarsUi.ExitOnlyCalls = TRUE; + } + + IOMapUi.State = DRAW_MENU; + } + break; + + case DRAW_MENU : // If no function active -> erase screen, draw statusline and menu icons + { + if (VarsUi.Function) + { + // Function active + if (VarsUi.Function < FUNC_NO_MAX) + { + if (Functions[VarsUi.Function](VarsUi.Parameter) == 0) + { + VarsUi.Function = 0; + } + } + else + { + VarsUi.Function = 0; + } + } + else + { + // function inactive - erase screen + if (!(VarsUi.pMenuLevel->SpecialFlags & MENU_LEAVE_BACKGROUND)) + { + pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_LARGE); + + // Draw only icons, frame and icon text + pMapDisplay->UpdateMask = (MENUICON_BITS | SPECIAL_BIT(FRAME_SELECT) | SPECIAL_BIT(MENUTEXT)); + pMapDisplay->TextLinesCenterFlags = 0; + } + else + { + pMapDisplay->EraseMask |= (SPECIAL_BIT(MENUTEXT) | MENUICON_BITS); + + // Draw icons, frame and icon text + pMapDisplay->UpdateMask |= (MENUICON_BITS | SPECIAL_BIT(FRAME_SELECT) | SPECIAL_BIT(MENUTEXT)); + } + + // Draw status + IOMapUi.Flags |= (UI_ENABLE_STATUS_UPDATE | UI_UPDATE | UI_REDRAW_STATUS); + + if ((VarsUi.pMenuLevel->SpecialFlags & MENU_INIT_CALLS_WITH_0) && (VarsUi.SecondTime == FALSE)) + { + VarsUi.SecondTime = TRUE; + cUiMenuCallFunction(VarsUi.pMenuLevel->FunctionNo,MENU_INIT); + } + else + { + if ((VarsUi.pMenuLevel->SpecialFlags & MENU_INIT_CALLS_WITH_1) && (VarsUi.SecondTime == FALSE)) + { + VarsUi.SecondTime = TRUE; + cUiMenuCallFunction(VarsUi.pMenuLevel->FunctionNo,MENU_INIT_ALTERNATIVE); + } + else + { + if ((VarsUi.pMenuLevel->SpecialFlags & MENU_INIT_CALLS) && (VarsUi.SecondTime == FALSE)) + { + VarsUi.SecondTime = TRUE; + cUiMenuCallFunction(VarsUi.pMenuLevel->FunctionNo,VarsUi.pMenuLevel->Parameter); + } + else + { + if ((VarsUi.pMenuLevel->SpecialFlags & MENU_AUTO_PRESS_ENTER)) + { + IOMapUi.State = ENTER_PRESSED; + } + else + { + IOMapUi.State = TEST_BUTTONS; + } + } + } + } + } + } + break; + + case TEST_BUTTONS : // Test buttons to execute new functions and new menus + { + if (VarsUi.Initialized == FALSE) + { + VarsUi.Initialized = TRUE; + IOMapUi.Flags &= ~UI_BUSY; + } + + switch (cUiReadButtons()) + { + case BUTTON_LEFT : + { + IOMapUi.State = LEFT_PRESSED; + } + break; + + case BUTTON_RIGHT : + { + IOMapUi.State = RIGHT_PRESSED; + } + break; + + case BUTTON_ENTER : + { + IOMapUi.State = ENTER_PRESSED; + } + break; + + case BUTTON_EXIT : + { + if (!(VarsUi.pMenuLevel->SpecialFlags & MENU_EXIT_DISABLE)) + { + IOMapUi.State = EXIT_PRESSED; + } + } + break; + + } + + } + break; + + case LEFT_PRESSED : + { + if ((VarsUi.pMenuLevel->SpecialFlags & MENU_LEFT_RIGHT_AS_CALL)) + { + cUiMenuCallFunction(VarsUi.pMenuLevel->FunctionNo,MENU_LEFT); + } + else + { + VarsUi.SecondTime = FALSE; + VarsUi.EnterOnlyCalls = FALSE; + VarsUi.ExitOnlyCalls = FALSE; + + if (VarsUi.pMenuLevel->ItemIndex > 1) + { + VarsUi.pMenuLevel->ItemIndex--; + } + else + { + if (VarsUi.pMenuLevel->Items > 2) + { + VarsUi.pMenuLevel->ItemIndex = VarsUi.pMenuLevel->Items; + } + } + } + IOMapUi.State = NEXT_MENU; + } + break; + + case RIGHT_PRESSED : + { + if ((VarsUi.pMenuLevel->SpecialFlags & MENU_LEFT_RIGHT_AS_CALL)) + { + cUiMenuCallFunction(VarsUi.pMenuLevel->FunctionNo,MENU_RIGHT); + } + else + { + VarsUi.SecondTime = FALSE; + VarsUi.EnterOnlyCalls = FALSE; + VarsUi.ExitOnlyCalls = FALSE; + + if (VarsUi.pMenuLevel->ItemIndex < VarsUi.pMenuLevel->Items) + { + VarsUi.pMenuLevel->ItemIndex++; + } + else + { + if (VarsUi.pMenuLevel->Items > 2) + { + VarsUi.pMenuLevel->ItemIndex = 1; + } + } + } + IOMapUi.State = NEXT_MENU; + } + break; + + case ENTER_PRESSED : + { + if ((VarsUi.pMenuLevel->SpecialFlags & MENU_ENTER_ACT_AS_EXIT)) + { + cUiMenuExit(); + } + else + { + cUiMenuEnter(); + } + } + break; + + case EXIT_PRESSED : + { + if ((VarsUi.pMenuLevel->SpecialFlags & MENU_EXIT_ACT_AS_ENTER)) + { + cUiMenuEnter(); + } + else + { + cUiMenuExit(); + } + } + break; + + case CONNECT_REQUEST : + { + if (cUiBTConnectRequest(MENU_INIT) == 0) + { + IOMapUi.BluetoothState &= ~BT_CONNECT_REQUEST; + cUiLoadLevel(0,1,1); + IOMapUi.State = NEXT_MENU; + IOMapUi.Flags &= ~UI_BUSY; + } + } + break; + + case EXECUTE_FILE : + { + cUiLoadLevel(0,1,1); + cUiMenuEnter(); + cUiLoadLevel(VarsUi.MenuFileLevel,VarsUi.MenuFiles[VarsUi.MenuFileLevel].MenuLevel,VarsUi.MenuFiles[VarsUi.MenuFileLevel].MenuLevels[VarsUi.MenuFiles[VarsUi.MenuFileLevel].MenuLevel].ItemIndex); + cUiMenuEnter(); + cUiLoadLevel(VarsUi.MenuFileLevel,VarsUi.MenuFiles[VarsUi.MenuFileLevel].MenuLevel,VarsUi.MenuFiles[VarsUi.MenuFileLevel].MenuLevels[VarsUi.MenuFiles[VarsUi.MenuFileLevel].MenuLevel].ItemIndex); + cUiMenuEnter(); + cUiLoadLevel(VarsUi.MenuFileLevel,VarsUi.MenuFiles[VarsUi.MenuFileLevel].MenuLevel,VarsUi.MenuFiles[VarsUi.MenuFileLevel].MenuLevels[VarsUi.MenuFiles[VarsUi.MenuFileLevel].MenuLevel].ItemIndex); + + VarsUi.Function = 0; + VarsUi.State = 0; + VarsUi.Pointer = 0; + VarsUi.FNOFState = 0; + VarsUi.FBState = 0; + VarsUi.GUSState = 0; + + strcpy((char*)VarsUi.SelectedFilename,(char*)IOMapUi.LMSfilename); + IOMapUi.State = EXECUTING_FILE; + VarsUi.FileType = FILETYPE_LMS; + cUiFileRun(MENU_INIT); + } + break; + + case EXECUTING_FILE : + { + if (cUiFileRun(MENU_RUN) == 0) + { + IOMapUi.Flags &= ~UI_EXECUTE_LMS_FILE; + IOMapUi.State = NEXT_MENU; + } + } + break; + + case LOW_BATTERY : + { + if (DISPLAY_IDLE) + { + if (cUiReadButtons() != BUTTON_NONE) + { + pMapDisplay->Flags &= ~DISPLAY_POPUP; + pMapDisplay->pBitmaps[BITMAP_1] = (BMPMAP*)VarsUi.LowBattSavedBitmap; + IOMapUi.State = VarsUi.LowBattSavedState; + IOMapUi.Flags &= ~UI_BUSY; + } + } + } + break; + + case BT_ERROR : + { + switch (IOMapUi.Error) + { + case LR_COULD_NOT_SAVE : + { + Tmp = TXT_FB_BT_ERROR_LR_COULD_NOT_SAVE_1; + } + break; + + case LR_STORE_IS_FULL : + { + Tmp = TXT_FB_BT_ERROR_LR_STORE_IS_FULL_1; + } + break; + + default : + { + Tmp = TXT_FB_BT_ERROR_LR_UNKOWN_ADDR_1; + } + break; + + } + + if (!cUiFeedback((BMPMAP*)Fail,Tmp,Tmp + 1,DISPLAY_SHOW_ERROR_TIME)) + { + IOMapUi.BluetoothState &= ~BT_ERROR_ATTENTION; + cUiLoadLevel(0,1,1); + IOMapUi.State = NEXT_MENU; + IOMapUi.Flags &= ~UI_BUSY; + } + } + break; + + } + + // Check for low battery voltage + if (VarsUi.LowBatt >= LOW_BATT_THRESHOLD) + { + if (!VarsUi.LowBattHasOccured) + { + if (DISPLAY_IDLE) + { + if (!(IOMapUi.Flags & UI_BUSY)) + { + pMapDisplay->Flags |= DISPLAY_POPUP; + VarsUi.LowBattHasOccured = 1; + VarsUi.LowBattSavedState = IOMapUi.State; + VarsUi.LowBattSavedBitmap = (UBYTE*)pMapDisplay->pBitmaps[BITMAP_1]; + pMapDisplay->pBitmaps[BITMAP_1] = (BMPMAP*)LowBattery; + pMapDisplay->UpdateMask = BITMAP_BIT(BITMAP_1); + IOMapUi.Flags |= UI_REDRAW_STATUS; + IOMapUi.Flags |= UI_BUSY; + IOMapUi.State = LOW_BATTERY; + } + } + } + } + + // Check for incomming BT connection requests + if ((IOMapUi.BluetoothState & BT_CONNECT_REQUEST) && (!(IOMapUi.Flags & UI_BUSY))) + { + IOMapUi.Flags |= UI_BUSY; + IOMapUi.State = CONNECT_REQUEST; + } + + // Check for BT errors + if ((IOMapUi.BluetoothState & BT_ERROR_ATTENTION) && (!(IOMapUi.Flags & UI_BUSY))) + { + IOMapUi.Flags |= UI_BUSY; + IOMapUi.State = BT_ERROR; + } + + // Check for incomming execute program + if ((IOMapUi.Flags & UI_EXECUTE_LMS_FILE) && (!(IOMapUi.Flags & UI_BUSY))) + { + // Reset power down timer + IOMapUi.Flags |= UI_RESET_SLEEP_TIMER; + + // Set state and busy + IOMapUi.Flags |= UI_BUSY; + IOMapUi.State = EXECUTE_FILE; + } + + // Check for power timeout + if ((IOMapUi.Flags & UI_RESET_SLEEP_TIMER)) + { + IOMapUi.Flags &= ~UI_RESET_SLEEP_TIMER; + IOMapUi.SleepTimer = 0; + VarsUi.SleepTimer = 0; + } + if (IOMapUi.SleepTimeout) + { + if (++VarsUi.SleepTimer >= 60000) + { + VarsUi.SleepTimer = 0; + if (++IOMapUi.SleepTimer >= IOMapUi.SleepTimeout) + { + IOMapUi.ForceOff = TRUE; + } + } + } + else + { + IOMapUi.Flags |= UI_RESET_SLEEP_TIMER; + } + + // Check for "long prees on exit" power off + if ((pMapButton->State[BTN1] & LONG_PRESSED_EV) && (pMapCmd->ProgStatus != PROG_RUNNING) && (VarsUi.Initialized == TRUE) && (VarsUi.State == 0)) + { + IOMapUi.ForceOff = TRUE; + } + + // Check for "force" off + if (IOMapUi.ForceOff != FALSE) + { + IOMapUi.ForceOff = FALSE; + VarsUi.Function = FUNC_NO_OFF; + VarsUi.Parameter = MENU_INIT; + VarsUi.State = 0; + IOMapUi.State = DRAW_MENU; + } + + // Update status line + cUiUpdateStatus(); +} + + +void cUiExit(void) +{ + VarsUi.Initialized = FALSE; + IOMapUi.State = INIT_DISPLAY; +} diff --git a/src/c_ui.h b/src/c_ui.h new file mode 100644 index 0000000..e0f8f4a --- /dev/null +++ b/src/c_ui.h @@ -0,0 +1,387 @@ +// +// Programmer +// +// Date init 14.12.2004 +// +// Reviser $Author:: Dktochpe $ +// +// Revision date $Date:: 10/21/08 12:08p $ +// +// Filename $Workfile:: c_ui.h $ +// +// Version $Revision:: 10 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_ui.h $ +// +// Platform C +// + +#ifndef C_UI +#define C_UI + +#define DATALOGENABLED 1 // 1 == Datalog enable + +#define NO_OF_FEEDBACK_CHARS 12 // Chars left when bitmap also showed +#define SIZE_OF_CURSOR 16 // Bitmap size of cursor (header + 8x8 pixels) +#define SIZE_OF_PORTBITMAP 11 // Bitmap size of port no (header + 3x8 pixels) +#define NO_OF_STATUSICONS 4 // Status icons + +#define NO_OF_INTROBITMAPS 16 // Intro bitmaps +#define INTRO_START_TIME 1000 // Intro startup time [mS] +#define INTRO_SHIFT_TIME 100 // Intro inter bitmap time [mS] +#define INTRO_STOP_TIME 1000 // Intro stop time [mS] +#define INTRO_LOWBATT_TIME 2000 // Low battery show time at power up [mS] + +#define MAX_VOLUME 4 // Max volume in UI [cnt] + +#define CHECKBYTE 0x78 // Used to validate NVData + +#define BATTERY_COUNT_TO_MV 13.848f // Battery count to mV factor [mV/cnt] +#define LOW_BATT_THRESHOLD 6 // Low batt conunts before warning + +#define BUTTON_DELAY_TIME 800 // Delay before first repeat [mS] +#define BUTTON_REPEAT_TIME 200 // Repeat time [mS] + +#define RUN_BITMAP_CHANGE_TIME 125 // Running bimap update time [mS] +#define RUN_STATUS_CHANGE_TIME 167 // Running status update time [mS] + +#define DISPLAY_SHOW_ERROR_TIME 2500 // Error string show time [mS] +#define DISPLAY_SHOW_TIME 1500 // Min. response display time [mS] +#define DISPLAY_VIEW_UPDATE 200 // Display update time [mS] +#define MIN_DISPLAY_UPDATE_TIME 50 // OBP min graphics update time [mS] +#define MIN_SENSOR_READ_TIME 100 // Time between sensor reads [mS] + +#define ARM_WAIT_FOR_POWER_OFF 250 // Time for off command to execute [mS] + +#define DISPLAY_SHOW_FILENAME_TIME 3000 // Datalog show saves as time [mS] +#define DATALOG_DEFAULT_SAMPLE_TIME 100L // Default time between samples [mS] + +// Menu special flags + +#define MENU_SKIP_THIS_MOTHER_ID 0x00000001L // Used to seek next common menu (i0000000) + // Free +#define MENU_ENTER_ACT_AS_EXIT 0x00000004L // Enter button acts as exit button +#define MENU_BACK_TWICE 0x00000008L // Exit twice on exit button +#define MENU_EXIT_ACT_AS_ENTER 0x00000010L // Exit button acts as enter button +#define MENU_LEAVE_BACKGROUND 0x00000020L // Don't erase background at next menu +#define MENU_EXIT_CALLS_WITH_FF 0x00000040L // Exit button calls function with MENU_EXIT +#define MENU_EXIT_LEAVES_MENUFILE 0x00000080L // Exit leaves menu file +#define MENU_INIT_CALLS_WITH_0 0x00000100L // Menu init calls with MENU_INIT +#define MENU_LEFT_RIGHT_AS_CALL 0x00000200L // Left calls with MENU_LEFT and right with MENU_RIGHT +#define MENU_ENTER_ONLY_CALLS 0x00000400L // Enter calls only it does not change menues +#define MENU_EXIT_ONLY_CALLS 0x00000800L // Exit calls only it does not change menues +#define MENU_AUTO_PRESS_ENTER 0x00001000L // Enter button is pressed automaticly +#define MENU_ENTER_LEAVES_MENUFILE 0x00002000L // Enter leaves menufile +#define MENU_INIT_CALLS 0x00004000L // Init calls instead of enter +#define MENU_ACCEPT_INCOMMING_REQUEST 0x00008000L // Accept incomming BT connection request +#define MENU_BACK_THREE_TIMES 0x00010000L // Exit three times on exit button +#define MENU_EXIT_DISABLE 0x00020000L // Disable exit button +#define MENU_EXIT_LOAD_POINTER 0x00040000L // Load item index on exit (0i000000) +#define MENU_EXIT_CALLS 0x00080000L // Exit calls as enter +#define MENU_INIT_CALLS_WITH_1 0x00100000L // Menu init calls with MENU_INIT +#define MENU_EXIT_LOAD_MENU 0x00200000L // Exit loads next menu +#define MENU_ONLY_BT_ON 0x00400000L // Only valid when bluecore is on +#define MENU_ONLY_DATALOG_ENABLED 0x00800000L // Only valid when datalog is enabled + +// Menu function call parameter + +#define MENU_SENSOR_EMPTY 0x01 // Empty +#define MENU_SENSOR_SOUND_DB 0x02 // Sound sensor dB +#define MENU_SENSOR_SOUND_DBA 0x03 // Sound sensor dBA +#define MENU_SENSOR_LIGHT 0x04 // Light sensor with flood light +#define MENU_SENSOR_LIGHT_AMB 0x05 // Light sensor without flood light +#define MENU_SENSOR_TOUCH 0x06 // Touch sensor +#define MENU_SENSOR_MOTOR_DEG 0x07 // Motor sensor degrees +#define MENU_SENSOR_MOTOR_ROT 0x08 // Motor sensor rotations +#define MENU_SENSOR_ULTRASONIC_IN 0x09 // Ultrasonic sensor inch +#define MENU_SENSOR_ULTRASONIC_CM 0x0A // Ultrasonic sensor cm +#define MENU_SENSOR_IIC_TEMP_C 0x0B // IIC temp sensor celcius +#define MENU_SENSOR_IIC_TEMP_F 0x0C // IIC temp sensor fahrenheit +#define MENU_SENSOR_COLOR 0x0D // Color sensor +#define MENU_SENSOR_INVALID 0x0E // Invalid + +#define MENU_PORT_EMPTY 0x11 // Port empty +#define MENU_PORT_1 0x12 // Port 1 +#define MENU_PORT_2 0x13 // Port 2 +#define MENU_PORT_3 0x14 // Port 3 +#define MENU_PORT_4 0x15 // Port 4 +#define MENU_PORT_A 0x16 // Port A +#define MENU_PORT_B 0x17 // Port B +#define MENU_PORT_C 0x18 // Port C +#define MENU_PORT_INVALID 0x19 // Invalid + +#define MENU_ACTION_EMPTY 0x21 // Empty +#define MENU_ACTION_FORWARD_1 0x22 // Forward until +#define MENU_ACTION_FORWARD_2 0x23 // Forward 5 +#define MENU_ACTION_BACK_LEFT_2 0x24 // Back left 2 +#define MENU_ACTION_TURN_LEFT_1 0x25 // Turn left until +#define MENU_ACTION_TURN_LEFT_2 0x26 // Turn left 2 +#define MENU_ACTION_BACK_RIGHT_1 0x27 // Back right until +#define MENU_ACTION_TURN_RIGHT_1 0x28 // Turn right until +#define MENU_ACTION_TURN_RIGHT_2 0x29 // Turn right 2 +#define MENU_ACTION_BACK_LEFT_1 0x2A // Back left until +#define MENU_ACTION_TONE_1 0x2B // Tone 1 +#define MENU_ACTION_TONE_2 0x2C // Tone 2 +#define MENU_ACTION_BACKWARD_1 0x2D // Backward until +#define MENU_ACTION_BACKWARD_2 0x2E // Backward 5 +#define MENU_ACTION_BACK_RIGHT_2 0x2F // Back right 2 +#define MENU_ACTION_INVALID 0x30 // Invalid + +#define MENU_WAIT_EMPTY 0x41 // Empty +#define MENU_WAIT_LIGHT 0x42 // Light +#define MENU_WAIT_SEEK_OBJ 0x43 // Seek obj. +#define MENU_WAIT_SOUND 0x44 // Sound +#define MENU_WAIT_TOUCH 0x45 // Touch +#define MENU_WAIT_1 0x46 // Wait 2 +#define MENU_WAIT_2 0x47 // Wait 5 +#define MENU_WAIT_3 0x48 // Wait 10 +#define MENU_WAIT_DARK 0x49 // Dark +#define MENU_WAIT_INVALID 0x4A // Invalid + +#define MENU_INIT 0x00 // Init +#define MENU_INIT_ALTERNATIVE 0x01 // Init alternative +#define MENU_DRAW 0xE9 // Draw +#define MENU_OFF 0xEA // Off +#define MENU_ON 0xEB // On +#define MENU_OPEN_STREAM 0xEC // Open stream +#define MENU_OVERWRITE 0xED // Overwrite file +#define MENU_CALCULATE 0xEE // Calculate +#define MENU_ENTER 0xEF // Enter +#define MENU_DISCONNECT 0xF0 // Disconnect BT +#define MENU_DELETE 0xF1 // Delete +#define MENU_SELECT 0xF2 // Select +#define MENU_RUN_SILENT 0xF3 // Run without graphics +#define MENU_TOGGLE 0xF4 // Toggle +#define MENU_CONNECT 0xF5 // Connect BT +#define MENU_UPDATE 0xF6 // Update +#define MENU_TEXT 0xF7 // Text +#define MENU_RUN 0xF8 // Run +#define MENU_SEND 0xF9 // Send +#define MENU_SAVE 0xFA // Save +#define MENU_STOP 0xFB // Stop +#define MENU_LOOP 0xFC // Loop +#define MENU_LEFT 0xFD // Left +#define MENU_RIGHT 0xFE // Right +#define MENU_EXIT 0xFF // Exit + +#define DATALOGPORTS (MENU_PORT_INVALID - MENU_PORT_EMPTY - 1) +#define MAX_DATALOGS 9999 // Highest datalog file number +#define DATALOGBUFFERSIZE 25 // Largest number of characters buffered before flash write + +#define MENULEVELS 10 // Max no of levels in one file (8 + 2 virtual) +#define MENUFILELEVELS 3 // Max deept in menu file pool + +typedef struct // VarsUi.MenuFiles[VarsUi.MenuFileLevel].MenuLevels[VarsUi.MenuLevel]. +{ + ULONG Id; // Menu item id + UBYTE *IconText; // Menu item icon text pointer + ULONG SpecialFlags; // Menu item special behaivor + UBYTE IconImageNo; // Menu item icon image no + UBYTE FunctionNo; // Menu item function call no (0 = none) + UBYTE Parameter; // Menu item function call parameter + UBYTE NextFileNo; // Menu item next menu file no (0 = none) + UBYTE NextMenuNo; // Menu item next menu no (0 = none) + + UBYTE ItemIndex; // Menu item index on level + UBYTE Items; // Menu items on level +} +MENULEVEL; + +typedef struct +{ + MENULEVEL MenuLevels[MENULEVELS]; // See above + UBYTE FileId; // VarsUi.MenuFiles[VarsUi.MenuFileLevel].FileId + UBYTE MenuLevel; // VarsUi.MenuFiles[VarsUi.MenuFileLevel].MenuLevel +} +MENUFILE; + +typedef struct +{ + UBYTE CheckByte; // Check byte (CHECKBYTE) + UBYTE DatalogEnabled; // Datalog enabled flag (0 = no) + UBYTE VolumeStep; // Volume step (0 - MAX_VOLUME) + UBYTE PowerdownCode; // Power down code + UWORD DatalogNumber; // Datalog file number (0 - MAX_DATALOGS) +} +NVDATA; + +typedef struct +{ + UBYTE StatusText[STATUSTEXT_SIZE + 1]; // RCX name + UBYTE Initialized; // Ui init done + UWORD SleepTimer; // Sleep timer + + // Menu system + MENUFILE MenuFiles[MENUFILELEVELS]; // Menu file array + MENUFILE *pMenuFile; // Actual menu file pointer + MENULEVEL *pMenuLevel; // Actual menu item on level, pointer + MENUITEM *pMenuItem; // Actual menu item in menu flash file + UBYTE MenuFileLevel; // Actual menu file level + UBYTE Function; // Running function (0 = none) + UBYTE Parameter; // Parameter for running function + UBYTE SecondTime; // Second time flag + UBYTE EnterOnlyCalls; // Enter button only calls + UBYTE ExitOnlyCalls; // Exit button only calls + UWORD ButtonTimer; // Button repeat timer + UWORD ButtonTime; // Button repeat time + UBYTE ButtonOld; // Button old state + + // Update status + UWORD UpdateCounter; // Update counter + UBYTE Running; // Running pointer + UBYTE BatteryToggle; // Battery flash toggle flag + UBYTE NewStatusIcons[NO_OF_STATUSICONS]; // New status icons (used to detect changes) + + // Low battery voltage + UBYTE *LowBattSavedBitmap; // Low battery overwritten bitmap placeholder + UBYTE LowBatt; // Low battery volatge flag + UBYTE LowBattHasOccured; // Low battery voltage has occured + UBYTE LowBattSavedState; // Low battery current state placeholder + + // General used variables + UBYTE *MenuIconTextSave; // Menu icon text save + + UBYTE *pTmp; // General UBYTE pointer + ULONG TmpLength; // General filelength (used in filelist) + SWORD TmpHandle; // General filehandle (used in filelist) + + SWORD Timer; // General tmp purpose timer + SWORD ReadoutTimer; // General read out timer + UBYTE Tmp; // General UBYTE + UBYTE FileType; // General file type + UBYTE State; // General tmp purpose state + UBYTE Pointer; // General tmp purpose pointer + UBYTE Counter; // General tmp purpose counter + UBYTE Cursor; // General cursor + UBYTE SelectedSensor; // General used for selected sensor + UBYTE SelectedPort; // General used for selected port + UBYTE SensorReset; + UBYTE SensorState; // Sensor state (reset, ask, read) + SWORD SensorTimer; // Timer used to time sensor states + UBYTE NextState; + + UBYTE SelectedFilename[FILENAME_LENGTH + 1]; // Selected file name + UBYTE FilenameBuffer[FILENAME_LENGTH + 1]; // General filename buffer + UBYTE SearchFilenameBuffer[FILENAME_LENGTH + 1];// General filename buffer + UBYTE DisplayBuffer[DISPLAYLINE_LENGTH + 1]; // General purpose display buffer + + UBYTE PortBitmapLeft[SIZE_OF_PORTBITMAP]; // Port no bitmap for left icon + UBYTE PortBitmapCenter[SIZE_OF_PORTBITMAP]; // Port no bitmap for center icon + UBYTE PortBitmapRight[SIZE_OF_PORTBITMAP]; // Port no bitmap for right icon + + // Find no of files and find name for file no + ULONG FNOFLength; // Length + SWORD FNOFHandle; // Handle + UBYTE FNOFState; // State + UBYTE FNOFSearchBuffer[FILENAME_LENGTH + 1]; // Search buffer + UBYTE FNOFNameBuffer[FILENAME_LENGTH + 1]; // File name buffer + UBYTE FNOFFileNo; // File no + + // File list + UBYTE FileCenter; // File center + UBYTE FileLeft; // File left + UBYTE FileRight; // File right + UBYTE NoOfFiles; // No of files + + // On brick programming menu + UBYTE ProgramSteps[ON_BRICK_PROGRAMSTEPS]; // On brick programming steps + UBYTE ProgramStepPointer; // On brick programming step pointer + UBYTE CursorTmp[SIZE_OF_CURSOR]; // On brick programming cursor + UBYTE FileHeader[FILEHEADER_LENGTH]; // File header for programs + UBYTE *FeedBackText; // Program end text + UWORD OBPTimer; // Graphic update timer + + // BT search menu + UBYTE NoOfDevices; // BT search no of devices found + UBYTE NoOfNames; // BT search no of names found + UBYTE SelectedDevice; // BT selected device + UBYTE SelectedSlot; // BT selected slot + + // BT device list menu + UBYTE DevicesKnown; // BT device known flag + UBYTE Devices; // BT devices + UBYTE DeviceLeft; // BT device left + UBYTE DeviceCenter; // BT device center + UBYTE DeviceRight; // BT device right + UBYTE DeviceType; // BT device type + + // BT connect Menu + UBYTE Slots; // BT connect no of slots + UBYTE SlotLeft; // BT connect + UBYTE SlotCenter; // BT connect + UBYTE SlotRight; // BT connect + + // Get user string + UBYTE GUSTmp; // Seperat tmp for "Get user string" + UBYTE GUSState; // Seperat state for "Get user string" + UBYTE GUSNoname; // No user entry + UBYTE UserString[DISPLAYLINE_LENGTH + 1]; // User string + UBYTE DisplayText[DISPLAYLINE_LENGTH + 1]; // Display buffer + SBYTE FigurePointer; // Figure cursor + UBYTE GUSCursor; // User string cursor + + // Connect request + ULONG CRPasskey; // Passkey to fake wrong pin code + UBYTE CRState; // Seperate state for "Connect request" + UBYTE CRTmp; // Seperate tmp for "Connect request" + + // Run files + UBYTE *RunIconSave; // Menu center icon save + UWORD RunTimer; // Bitmap change timer + UBYTE RunBitmapPointer; // Bitmap pointer + + // Delete files + UBYTE SelectedType; // Type of selected files for delete + + // View + SLONG ViewSampleValue; // Latch for sensor values + UBYTE ViewSampleValid; // Latch for sensor valid + + // Datalog + ULONG DatalogOldTick; + ULONG DatalogRTC; // Real time in mS + ULONG DatalogTimer; // Logging main timer + ULONG DatalogSampleTime; // Logging sample time + ULONG DatalogSampleTimer; // Logging sample timer + SLONG DatalogSampleValue[DATALOGPORTS]; // Latch for sensor values + UBYTE DatalogSampleValid[DATALOGPORTS]; // Latch for sensor valid + UWORD DatalogError; // Error code + UBYTE DatalogPort[DATALOGPORTS]; // Logging sensor + UBYTE Update; // Update icons flag + + // NV storage + ULONG NVTmpLength; // Non volatile filelength + SWORD NVTmpHandle; // Non volatile filehandle + UBYTE NVFilename[FILENAME_LENGTH + 1]; // Non volatile file name + NVDATA NVData; // Non volatile data + + // Feedback + UBYTE *FBText; // Seperate text pointer for feedback + UWORD FBTimer; // Seperate timer for feedback + UBYTE FBState; // Seperate state for feedback + UBYTE FBPointer; // Seperate pointer for feedback + + // BT command + UBYTE BTIndex; // List index + UBYTE BTTmpIndex; // Tmp list index + UBYTE BTCommand; // Last lached BT command + UBYTE BTPar1; // Last lached BT command parameter 1 + UBYTE BTPar2; // Last lached BT command parameter 2 + UWORD BTResult; // Last lached BT command result + + // Error display + UBYTE ErrorTimer; // Error show timer + UBYTE ErrorFunction; // Error latched function + UBYTE ErrorParameter; // Error latched parameter + UBYTE ErrorState; // Error latched state + UBYTE ErrorString[DISPLAYLINE_LENGTH + 1]; // Error string +}VARSUI; + + +void cUiInit(void* pHeader); // Init controller +void cUiCtrl(void); // Run controller +void cUiExit(void); // Exit controller + +extern const HEADER cUi; + +#endif diff --git a/src/c_ui.iom b/src/c_ui.iom new file mode 100644 index 0000000..770b682 --- /dev/null +++ b/src/c_ui.iom @@ -0,0 +1,127 @@ +// +// Programmer +// +// Date init 14.12.2004 +// +// Reviser $Author:: Dkandlun $ +// +// Revision date $Date:: 10-06-08 9:26 $ +// +// Filename $Workfile:: c_ui.iom $ +// +// Version $Revision:: 4 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_ui.i $ +// +// Platform C +// + +#ifndef CUI_IOM +#define CUI_IOM + +#define pMapUi ((IOMAPUI*)(pHeaders[ENTRY_UI]->pIOMap)) + +enum +{ + DEVICETYPE_UNKNOWN, + DEVICETYPE_NXT, + DEVICETYPE_PHONE, + DEVICETYPE_PC +}; + +// Various filenames without extension +#define UI_NONVOLATILE "NVConfig" // Ui non volatile config filename +#define UI_PROGRAM_DEFAULT "Untitled" // On brick programming default filename +#define UI_PROGRAM_TEMP "Program" // On brick programming tmp filename +#define UI_PROGRAM_READER "RPGReader" // On brick programming script reader filename +#define UI_DATALOG_FILENAME "OBD_" // On brick datalog filename +#define UI_DATALOG_DEFAULT "Untitled" // On brick datalog default name +#define UI_DATALOG_TEMP "Tmp" // On brick datalog tmp filename +#define UI_STARTUP_SOUND "! Startup" // Sound file activated when the menu system starts up +#define UI_KEYCLICK_SOUND "! Click" // Sound file activated when key pressed in the menu system +#define UI_ATTENTION_SOUND "! Attention" // Sound file activated when incomming BT requests attention + +// Various text strings +#define UI_NAME_DEFAULT "NXT" // Default blue tooth name +#define UI_PINCODE_DEFAULT "1234" // Default blue tooth pin code +#define UI_PINCODE_NONE_OUT "????" // Fake pin code to deney outgoing request +#define UI_PINCODE_NONE_IN "????" // Fake pin code to deney incomming request + +// Constants related to Flags +enum +{ + UI_UPDATE = 0x01, // W - Make changes take effect + UI_DISABLE_LEFT_RIGHT_ENTER = 0x02, // RW - Disable left, right and enter button + UI_DISABLE_EXIT = 0x04, // RW - Disable exit button + UI_REDRAW_STATUS = 0x08, // W - Redraw entire status line + UI_RESET_SLEEP_TIMER = 0x10, // W - Reset sleep timeout timer + UI_EXECUTE_LMS_FILE = 0x20, // W - Execute LMS file in "LMSfilename" (Try It) + UI_BUSY = 0x40, // R - UI busy running or datalogging (popup disabled) + UI_ENABLE_STATUS_UPDATE = 0x80 // W - Enable status line to be updated +}; + +// Constants related to State +enum +{ + INIT_DISPLAY, // RW - Init display and load font, menu etc. + INIT_LOW_BATTERY, // R - Low battery voltage at power on + INIT_INTRO, // R - Display intro + INIT_WAIT, // RW - Wait for initialization end + INIT_MENU, // RW - Init menu system + NEXT_MENU, // RW - Next menu icons ready for drawing + DRAW_MENU, // RW - Execute function and draw menu icons + TEST_BUTTONS, // RW - Wait for buttons to be pressed + LEFT_PRESSED, // RW - Load selected function and next menu id + RIGHT_PRESSED, // RW - Load selected function and next menu id + ENTER_PRESSED, // RW - Load selected function and next menu id + EXIT_PRESSED, // RW - Load selected function and next menu id + CONNECT_REQUEST, // RW - Request for connection accept + EXECUTE_FILE, // RW - Execute file in "LMSfilename" + EXECUTING_FILE, // R - Executing file in "LMSfilename" + LOW_BATTERY, // R - Low battery at runtime + BT_ERROR // R - BT error +}; + +// Constants related to Button +enum +{ + BUTTON_NONE, // R - Button inserted are executed + BUTTON_LEFT, // W - Insert left arrow button + BUTTON_ENTER, // W - Insert enter button + BUTTON_RIGHT, // W - Insert right arrow button + BUTTON_EXIT // W - Insert exit button +}; + +// Constants related to BlueToothState +enum +{ + BT_STATE_VISIBLE = 0x01, // RW - BT visible + BT_STATE_CONNECTED = 0x02, // RW - BT connected to something + BT_STATE_OFF = 0x04, // RW - BT power off + BT_ERROR_ATTENTION = 0x08, // W - BT error attention + BT_CONNECT_REQUEST = 0x40, // RW - BT get connect accept in progress + BT_PIN_REQUEST = 0x80 // RW - BT get pin code +}; + +typedef struct +{ + MENU *pMenu; // W - Pointer to menu file + UWORD BatteryVoltage; // R - Battery voltage in millivolts + UBYTE LMSfilename[FILENAME_LENGTH + 1]; // W - LMS filename to execute (Try It) + UBYTE Flags; // RW - Update command flags (flags enumerated above) + UBYTE State; // RW - UI state (states enumerated above) + UBYTE Button; // RW - Insert button (buttons enumerated above) + UBYTE RunState; // W - VM Run state (0 = stopped, 1 = running) + UBYTE BatteryState; // W - Battery state (0..4 capacity) + UBYTE BluetoothState; // W - Bluetooth state (0=on, 1=visible, 2=conn, 3=conn.visible, 4=off, 5=dfu) + UBYTE UsbState; // W - Usb state (0=disconnected, 1=connected, 2=working) + UBYTE SleepTimeout; // RW - Sleep timeout time (min) + UBYTE SleepTimer; // RW - Sleep timer (min) + UBYTE Rechargeable; // R - Rechargeable battery (0 = no, 1 = yes) + UBYTE Volume; // RW - Volume used in UI (0 - 4) + UBYTE Error; // W - Error code + UBYTE OBPPointer; // W - Actual OBP step (0 - 4) + UBYTE ForceOff; // W - Force off (> 0 = off) +}IOMAPUI; + +#endif diff --git a/src/config.h b/src/config.h new file mode 100644 index 0000000..d396771 --- /dev/null +++ b/src/config.h @@ -0,0 +1,10 @@ +#ifndef CONFIG_H +#define CONFIG_H +/* + * This file defines compilation options. + */ + +/* Include intro code and images. */ +#define CONFIG_INTRO 1 + +#endif /* CONFIG_H */ diff --git a/src/d_bt.c b/src/d_bt.c new file mode 100644 index 0000000..6e3e47d --- /dev/null +++ b/src/d_bt.c @@ -0,0 +1,452 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 24-04-08 14:33 $ +// +// Filename $Workfile:: d_bt.c $ +// +// Version $Revision:: 3 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_bt.c $ +// +// Platform C +// + + +#include "stdconst.h" +#include "modules.h" +#include "m_sched.h" +#include "d_bt.h" +#include "d_bt.r" +#include + +enum +{ + BT_FAST_TIMEOUT = 500, + BT_CMD_TIMEOUT_2S = 2000, + BT_TIMEOUT_30S = 30000 +}; + +#define SETTimeout(TOut) CmdTOut = 0;\ + CmdTOutLimit = TOut +#define RESETTimeout CmdTOut = 0 + +static UWORD CmdTOut; +static UWORD CmdTOutLimit; + +void dBtInit(void) +{ + SETTimeout(0); + BTInit; + BTInitPIOPins; +} + +void dBtSetBcResetPinLow(void) +{ + BTSetResetLow; /* Set Reset pin to Bluecore chip low */ +} + +void dBtSetBcResetPinHigh(void) +{ + BTSetResetHigh; /* Set Reset pin to Bluecore chip high */ +} + +void dBtStartADConverter(void) +{ + BTStartADConverter; +} + +void dBtInitReceive(UBYTE *InputBuffer, UBYTE Mode) +{ + BTInitReceiver(InputBuffer, Mode); +} + +void dBtSetArm7CmdSignal(void) +{ + BT_SetArm7CmdPin; +} + +void dBtClearArm7CmdSignal(void) +{ + BT_ClearArm7CmdPin; +} + +UBYTE dBtGetBc4CmdSignal(void) +{ + UWORD ADValue; + + BTReadADCValue(ADValue); + + if (ADValue > 0x200) + { + ADValue = 1; + } + else + { + ADValue = 0; + } + return(ADValue); +} + + +UWORD dBtTxEnd(void) +{ + UWORD TxEnd; + + REQTxEnd(TxEnd); + + return(TxEnd); + +} + +UWORD dBtCheckForTxBuf(void) +{ + UWORD AvailBytes; + + AVAILOutBuf(AvailBytes); + + return(AvailBytes); +} + +void dBtSendMsg(UBYTE *OutputBuffer, UBYTE BytesToSend, UWORD MsgSize) +{ + + /* Used for sending a complete message that can be placed in the buffer - */ + /* or to send the first part of a message that cannot be placed in the buffer */ + /* once (bigger than the buffer) */ + BTSendMsg(OutputBuffer,BytesToSend, MsgSize); +} + +void dBtSend(UBYTE *OutputBuffer, UBYTE BytesToSend) +{ + + /* Used for continous stream of data to be send */ + BTSend(OutputBuffer, BytesToSend); +} + +UWORD dBtReceivedData(UWORD *pLength, UWORD *pBytesToGo) +{ + UWORD RtnVal; + + RtnVal = TRUE; + BTReceivedData(pLength, pBytesToGo); + if (*pLength) + { + SETTimeout(0); + } + else + { + if (CmdTOut < CmdTOutLimit) + { + CmdTOut++; + if (CmdTOut >= CmdTOutLimit) + { + SETTimeout(0); + RtnVal = FALSE; + } + } + } + return(RtnVal); +} + +void dBtResetTimeOut(void) +{ + RESETTimeout; +} + +void dBtClearTimeOut(void) +{ + SETTimeout(0); +} + +void dBtSendBtCmd(UBYTE Cmd, UBYTE Param1, UBYTE Param2, UBYTE *pBdAddr, UBYTE *pName, UBYTE *pCod, UBYTE *pPin) +{ + UBYTE Tmp; + UBYTE SendData; + UWORD CheckSumTmp; + UBYTE BtOutBuf[128]; + UBYTE BtOutCnt; + + SendData = 0; + BtOutCnt = 0; + switch (Cmd) + { + case MSG_BEGIN_INQUIRY: + { + BtOutBuf[BtOutCnt++] = MSG_BEGIN_INQUIRY; + BtOutBuf[BtOutCnt++] = Param1; + BtOutBuf[BtOutCnt++] = 0x00; + BtOutBuf[BtOutCnt++] = Param2; + BtOutBuf[BtOutCnt++] = 0x00; + BtOutBuf[BtOutCnt++] = 0x00; + BtOutBuf[BtOutCnt++] = 0x00; + BtOutBuf[BtOutCnt++] = 0x00; + + SendData = 1; + SETTimeout(BT_TIMEOUT_30S); + } + break; + + case MSG_CANCEL_INQUIRY: + { + BtOutBuf[BtOutCnt++] = MSG_CANCEL_INQUIRY; + + SendData = 1; + SETTimeout(BT_FAST_TIMEOUT); + } + break; + + case MSG_CONNECT: + { + BtOutBuf[BtOutCnt++] = MSG_CONNECT; + memcpy(&(BtOutBuf[BtOutCnt]), pBdAddr, SIZE_OF_BDADDR); + BtOutCnt += SIZE_OF_BDADDR; + + SendData = 1; + SETTimeout(BT_TIMEOUT_30S); + } + break; + + case MSG_OPEN_PORT: + { + BtOutBuf[BtOutCnt++] = MSG_OPEN_PORT; + + SendData = 1; + SETTimeout(BT_FAST_TIMEOUT); + } + break; + + case MSG_LOOKUP_NAME: + { + BtOutBuf[BtOutCnt++] = MSG_LOOKUP_NAME; + memcpy(&(BtOutBuf[BtOutCnt]), pBdAddr, SIZE_OF_BDADDR); + BtOutCnt += SIZE_OF_BDADDR; + + SendData = 1; + SETTimeout(BT_TIMEOUT_30S); + } + break; + + case MSG_ADD_DEVICE: + { + BtOutBuf[BtOutCnt++] = MSG_ADD_DEVICE; + memcpy(&(BtOutBuf[BtOutCnt]), pBdAddr, SIZE_OF_BDADDR); + BtOutCnt += SIZE_OF_BDADDR; + memcpy(&(BtOutBuf[BtOutCnt]), pName, SIZE_OF_BT_NAME); + BtOutCnt += SIZE_OF_BT_NAME; + memcpy(&(BtOutBuf[BtOutCnt]), pCod, SIZE_OF_CLASS_OF_DEVICE); + BtOutCnt += SIZE_OF_CLASS_OF_DEVICE; + + SendData = 1; + SETTimeout(BT_TIMEOUT_30S); + } + break; + + case MSG_REMOVE_DEVICE: + { + BtOutBuf[BtOutCnt++] = MSG_REMOVE_DEVICE; + memcpy(&(BtOutBuf[BtOutCnt]), pBdAddr, SIZE_OF_BDADDR); + BtOutCnt += SIZE_OF_BDADDR; + + SendData = 1; + SETTimeout(BT_FAST_TIMEOUT); + } + break; + + case MSG_DUMP_LIST: + { + BtOutBuf[BtOutCnt++] = MSG_DUMP_LIST; + + SendData = 1; + SETTimeout(BT_TIMEOUT_30S); + } + break; + + case MSG_CLOSE_CONNECTION: + { + BtOutBuf[BtOutCnt++] = MSG_CLOSE_CONNECTION; + BtOutBuf[BtOutCnt++] = Param1; + + SendData = 1; + SETTimeout(BT_TIMEOUT_30S); + } + break; + + case MSG_ACCEPT_CONNECTION: + { + BtOutBuf[BtOutCnt++] = MSG_ACCEPT_CONNECTION; + BtOutBuf[BtOutCnt++] = Param1; + + SendData = 1; + SETTimeout(BT_TIMEOUT_30S); + } + break; + + case MSG_PIN_CODE: + { + BtOutBuf[BtOutCnt++] = MSG_PIN_CODE; + memcpy(&(BtOutBuf[BtOutCnt]), pBdAddr, SIZE_OF_BDADDR); + BtOutCnt += SIZE_OF_BDADDR; + memcpy(&(BtOutBuf[BtOutCnt]), pPin, SIZE_OF_BT_PINCODE); + BtOutCnt += SIZE_OF_BT_PINCODE; + + SendData = 1; + SETTimeout(BT_TIMEOUT_30S); + } + break; + + case MSG_OPEN_STREAM: + { + BtOutBuf[BtOutCnt++] = MSG_OPEN_STREAM; + BtOutBuf[BtOutCnt++] = Param1; + + SendData = 1; + SETTimeout(BT_TIMEOUT_30S); + } + break; + + case MSG_START_HEART: + { + BtOutBuf[BtOutCnt++] = MSG_START_HEART; + + SendData = 1; + SETTimeout(BT_FAST_TIMEOUT); + } + break; + + case MSG_SET_DISCOVERABLE: + { + BtOutBuf[BtOutCnt++] = MSG_SET_DISCOVERABLE; + BtOutBuf[BtOutCnt++] = Param1; + + SendData = 1; + SETTimeout(BT_FAST_TIMEOUT); + } + break; + + case MSG_CLOSE_PORT: + { + BtOutBuf[BtOutCnt++] = MSG_CLOSE_PORT; + BtOutBuf[BtOutCnt++] = 0x03; + + SendData = 1; + SETTimeout(BT_FAST_TIMEOUT); + } + break; + + case MSG_SET_FRIENDLY_NAME: + { + BtOutBuf[BtOutCnt++] = MSG_SET_FRIENDLY_NAME; + memcpy(&(BtOutBuf[BtOutCnt]), pName, SIZE_OF_BT_NAME); + BtOutCnt += SIZE_OF_BT_NAME; + + SendData = 1; + SETTimeout(BT_FAST_TIMEOUT); + } + break; + + case MSG_GET_LINK_QUALITY: + { + BtOutBuf[BtOutCnt++] = MSG_GET_LINK_QUALITY; + BtOutBuf[BtOutCnt++] = Param1; + + SendData = 1; + SETTimeout(BT_FAST_TIMEOUT); + } + break; + + case MSG_SET_FACTORY_SETTINGS: + { + BtOutBuf[BtOutCnt++] = MSG_SET_FACTORY_SETTINGS; + + SendData = 1; + SETTimeout(BT_FAST_TIMEOUT); + } + break; + + case MSG_GET_LOCAL_ADDR: + { + BtOutBuf[BtOutCnt++] = MSG_GET_LOCAL_ADDR; + + SendData = 1; + SETTimeout(BT_FAST_TIMEOUT); + } + break; + + case MSG_GET_FRIENDLY_NAME: + { + BtOutBuf[BtOutCnt++] = MSG_GET_FRIENDLY_NAME; + + SendData = 1; + SETTimeout(BT_FAST_TIMEOUT); + } + break; + + case MSG_GET_DISCOVERABLE: + { + BtOutBuf[BtOutCnt++] = MSG_GET_DISCOVERABLE; + + SendData = 1; + SETTimeout(BT_FAST_TIMEOUT); + } + break; + + case MSG_GET_PORT_OPEN: + { + BtOutBuf[BtOutCnt++] = MSG_GET_PORT_OPEN; + + SendData = 1; + SETTimeout(BT_FAST_TIMEOUT); + } + break; + + case MSG_GET_VERSION: + { + BtOutBuf[BtOutCnt++] = MSG_GET_VERSION; + + SendData = 1; + SETTimeout(BT_FAST_TIMEOUT); + } + break; + + case MSG_GET_BRICK_STATUSBYTE: + { + BtOutBuf[BtOutCnt++] = MSG_GET_BRICK_STATUSBYTE; + + SendData = 1; + SETTimeout(BT_FAST_TIMEOUT); + } + break; + + case MSG_SET_BRICK_STATUSBYTE: + { + BtOutBuf[BtOutCnt++] = MSG_SET_BRICK_STATUSBYTE; + BtOutBuf[BtOutCnt++] = Param1; + BtOutBuf[BtOutCnt++] = Param2; + + SendData = 1; + SETTimeout(BT_FAST_TIMEOUT); + } + break; + } + + if (SendData == 1) + { + CheckSumTmp = 0; + for(Tmp = 0; Tmp < BtOutCnt; Tmp++) + { + CheckSumTmp += BtOutBuf[Tmp]; + } + CheckSumTmp = (UWORD) (1 + (0xFFFF - CheckSumTmp)); + BtOutBuf[BtOutCnt++] = (UBYTE)((CheckSumTmp & 0xFF00)>>8); + BtOutBuf[BtOutCnt++] = (UBYTE)(CheckSumTmp & 0x00FF); + BTSendMsg(BtOutBuf, BtOutCnt, (UWORD)BtOutCnt); + } +} + + + +void dBtExit(void) +{ + BTExit; +} diff --git a/src/d_bt.h b/src/d_bt.h new file mode 100644 index 0000000..baf3ab6 --- /dev/null +++ b/src/d_bt.h @@ -0,0 +1,39 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: d_bt.h $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_bt.h $ +// +// Platform C +// + +#ifndef D_BT +#define D_BT + +#define STREAM_MODE 1 +#define CMD_MODE 2 + +void dBtInit(void); +void dBtExit(void); +void dBtStartADConverter(void); +void dBtSetArm7CmdSignal(void); +void dBtClearArm7CmdSignal(void); +void dBtInitReceive(UBYTE *InputBuffer, UBYTE Mode); +void dBtSetBcResetPinLow(void); +void dBtSetBcResetPinHigh(void); +void dBtSendBtCmd(UBYTE Cmd, UBYTE Param1, UBYTE Param2, UBYTE *pBdAddr, UBYTE *pName, UBYTE *pCod, UBYTE *pPin); +void dBtSendMsg(UBYTE *pData, UBYTE Length, UWORD MsgSize); +void dBtSend(UBYTE *pData, UBYTE Length); +void dBtResetTimeOut(void); +void dBtClearTimeOut(void); +UBYTE dBtGetBc4CmdSignal(void); +UWORD dBtTxEnd(void); +UWORD dBtReceivedData(UWORD *pLength, UWORD *pBytesToGo); +UWORD dBtCheckForTxBuf(void); + +#endif diff --git a/src/d_bt.r b/src/d_bt.r new file mode 100644 index 0000000..8c9558f --- /dev/null +++ b/src/d_bt.r @@ -0,0 +1,347 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 24-04-08 14:33 $ +// +// Filename $Workfile:: d_bt.r $ +// +// Version $Revision:: 3 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_bt.r $ +// +// Platform C +// + +#ifdef SAM7S256 + +#if defined (PROTOTYPE_PCB_3) || (PROTOTYPE_PCB_4) + +#define BT_RX_PIN AT91C_PIO_PA21 +#define BT_TX_PIN AT91C_PIO_PA22 +#define BT_SCK_PIN AT91C_PIO_PA23 +#define BT_RTS_PIN AT91C_PIO_PA24 +#define BT_CTS_PIN AT91C_PIO_PA25 + +#define BT_CS_PIN AT91C_PIO_PA31 +#define BT_RST_PIN AT91C_PIO_PA11 + +#define BT_ARM7_CMD_PIN AT91C_PIO_PA27 + +#else + +#endif + +#define BAUD_RATE 460800L + +#define SIZE_OF_INBUF 128 +#define NO_OF_INBUFFERS 2 +#define NO_OF_DMA_OUTBUFFERS 2 +#define SIZE_OF_OUTBUF 256 + +#define PER_ID7_UART_1 0x80 +#define UART1_INQ 0x80 +#define EXT_LEN_MSG_BIT 0x80 + +static UBYTE InBuf[NO_OF_INBUFFERS][SIZE_OF_INBUF]; +static ULONG InBufPtrs[NO_OF_INBUFFERS]; +static UBYTE InBufInPtr; +static UBYTE LengthSize; + +static UBYTE OutDma[NO_OF_DMA_OUTBUFFERS][SIZE_OF_OUTBUF]; +static UBYTE DmaBufPtr; +static UBYTE *pBuffer; + +static UBYTE MsgIn; +static UBYTE InBufOutCnt; +static UWORD FullRxLength; +static UWORD RemainingLength; + + +#define ENABLEDebugOutput {\ + *AT91C_PIOA_PER = 0x20000000; /* Enable PIO on PA029 */\ + *AT91C_PIOA_OER = 0x20000000; /* PA029 set to Output */\ + } + +#define SETDebugOutputHigh *AT91C_PIOA_SODR = 0x20000000 + +#define SETDebugOutputLow *AT91C_PIOA_CODR = 0x20000000 + +#define BTInit {\ + UBYTE Tmp;\ + LengthSize = 1;\ + InBufInPtr = 0;\ + for(Tmp = 0; Tmp < NO_OF_INBUFFERS; Tmp++)\ + {\ + InBufPtrs[Tmp] = (ULONG)&(InBuf[Tmp][0]);\ + }\ + *AT91C_PMC_PCER = PER_ID7_UART_1; /* Enable PMC clock for UART 1 */\ + *AT91C_PIOA_PDR = BT_RX_PIN | BT_TX_PIN | BT_SCK_PIN | BT_RTS_PIN | BT_CTS_PIN; /* Disable Per. A on PA21, PA22, PA23, PA24 & PA25 */\ + *AT91C_PIOA_ASR = BT_RX_PIN | BT_TX_PIN | BT_SCK_PIN | BT_RTS_PIN | BT_CTS_PIN; /* Enable Per. A on PA21, PA22, PA23, PA24 & PA25 */\ + *AT91C_US1_CR = AT91C_US_RSTSTA; /* Resets pins on UART1 */\ + *AT91C_US1_CR = AT91C_US_STTTO; /* Start timeout functionality after 1 byte */\ + *AT91C_US1_RTOR = 10000; /* Approxitely 20 mS,x times bit time with 115200 bit pr s */\ + *AT91C_US1_IDR = AT91C_US_TIMEOUT; /* Disable interrupt on timeout */\ + *AT91C_AIC_IDCR = UART1_INQ; /* Disable UART1 interrupt */\ + *AT91C_AIC_ICCR = UART1_INQ; /* Clear interrupt register */\ + *AT91C_US1_MR = AT91C_US_USMODE_HWHSH; /* Set UART with HW handshake */\ + *AT91C_US1_MR &= ~AT91C_US_SYNC; /* Set UART in asynchronous mode */\ + *AT91C_US1_MR |= AT91C_US_CLKS_CLOCK; /* Clock setup MCK*/\ + *AT91C_US1_MR |= AT91C_US_CHRL_8_BITS; /* UART using 8-bit */\ + *AT91C_US1_MR |= AT91C_US_PAR_NONE; /* UART using none parity bit */\ + *AT91C_US1_MR |= AT91C_US_NBSTOP_1_BIT; /* UART using 1 stop bit */\ + *AT91C_US1_MR |= AT91C_US_OVER; /* UART is using 8-bit sampling */\ + *AT91C_US1_BRGR = ((OSC/8/BAUD_RATE) | (((OSC/8) - ((OSC/8/BAUD_RATE) * BAUD_RATE)) / ((BAUD_RATE + 4)/8)) << 16);\ + *AT91C_US1_PTCR = (AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS); /* Disable of TX & RX with DMA */\ + *AT91C_US1_RCR = 0; /* Receive Counter Register */\ + *AT91C_US1_TCR = 0; /* Transmit Counter Register */\ + *AT91C_US1_RNPR = 0;\ + *AT91C_US1_TNPR = 0;\ + Tmp = *AT91C_US1_RHR;\ + Tmp = *AT91C_US1_CSR;\ + *AT91C_US1_RPR = (unsigned int)&(InBuf[InBufInPtr][0]); /* Initialise receiver buffer using DMA */\ + *AT91C_US1_RCR = SIZE_OF_INBUF;\ + *AT91C_US1_RNPR = (unsigned int)&(InBuf[(InBufInPtr + 1)%NO_OF_INBUFFERS][0]);\ + *AT91C_US1_RNCR = SIZE_OF_INBUF;\ + MsgIn = 0;\ + InBufOutCnt = 0;\ + FullRxLength = 0;\ + RemainingLength = 0;\ + *AT91C_US1_CR = AT91C_US_RXEN | AT91C_US_TXEN; /* Enable Tx & Rx on UART 1*/\ + *AT91C_US1_PTCR = (AT91C_PDC_RXTEN | AT91C_PDC_TXTEN); /* Enable of TX & RX with DMA */\ + } + + +#define BTInitPIOPins {\ + *AT91C_PIOA_PER = BT_CS_PIN | BT_RST_PIN; /* Enable PIO on PA11 & PA31 */\ + *AT91C_PIOA_OER = BT_CS_PIN | BT_RST_PIN; /* PA11 & PA31 set to output */\ + *AT91C_PIOA_SODR = BT_CS_PIN | BT_RST_PIN; /* PA31 & PA11 set output high */\ + *AT91C_PIOA_PPUDR = BT_ARM7_CMD_PIN; /* Disable PULL-UP resistor on PA27 */\ + *AT91C_PIOA_PER = BT_ARM7_CMD_PIN; /* Enable PIO on PA27 */\ + *AT91C_PIOA_CODR = BT_ARM7_CMD_PIN; /* PA27 set output low */\ + *AT91C_PIOA_OER = BT_ARM7_CMD_PIN; /* PA27 set to output */\ + } + +#define BTStartADConverter {\ + *AT91C_ADC_CHER = AT91C_ADC_CH6 | AT91C_ADC_CH4; \ + ADStart; \ + while(!((*AT91C_ADC_SR) & AT91C_ADC_CH6)); \ + *AT91C_ADC_CHDR = AT91C_ADC_CH6 | AT91C_ADC_CH4; \ + } + +#define BTReadADCValue(ADValue) ADValue = *AT91C_ADC_CDR6; + +#define BTSetResetHigh {\ + *AT91C_PIOA_SODR = BT_RST_PIN; /* PA11 set output high */\ + } + +#define BTSetResetLow {\ + *AT91C_PIOA_CODR = BT_RST_PIN; /* PA11 set output low */\ + } + +#define BTInitReceiver(InputBuffer, Mode)\ + {\ + pBuffer = InputBuffer;\ + MsgIn = 0;\ + FullRxLength = 0;\ + if (STREAM_MODE == Mode)\ + {\ + LengthSize = 2;\ + }\ + else\ + {\ + LengthSize = 1;\ + }\ + } + +#define BT_SetArm7CmdPin *AT91C_PIOA_SODR = BT_ARM7_CMD_PIN + +#define BT_ClearArm7CmdPin *AT91C_PIOA_CODR = BT_ARM7_CMD_PIN + +#define BT_GetBc4CmdPin *AT91C_PIOA_PDSR & BT_BC4_CMD_PIN + +#define REQTxEnd(TxEnd) TxEnd = FALSE;\ + if ((!(*AT91C_US1_TNCR)) && (!(*AT91C_US1_TCR)))\ + {\ + TxEnd = TRUE;\ + } + +#define AVAILOutBuf(Avail) if (!(*AT91C_US1_TNCR))\ + {\ + Avail = SIZE_OF_OUTBUF;\ + }\ + else\ + {\ + Avail = 0;\ + } + + +#define BTSend(OutputBuffer, BytesToSend)\ + {\ + UWORD Avail;\ + AVAILOutBuf(Avail);\ + if (BytesToSend < (Avail - 1))\ + {\ + memcpy(&(OutDma[DmaBufPtr][0]), OutputBuffer, BytesToSend);\ + *AT91C_US1_TNPR = (unsigned int)&(OutDma[DmaBufPtr][0]);\ + *AT91C_US1_TNCR = BytesToSend;\ + DmaBufPtr = (DmaBufPtr + 1) % NO_OF_DMA_OUTBUFFERS;\ + }\ + } + + +#define BTSendMsg(OutputBuffer, BytesToSend, MsgSize)\ + {\ + UWORD Avail;\ + AVAILOutBuf(Avail);\ + if (BytesToSend < (Avail - 1))\ + {\ + if (2 == LengthSize)\ + {\ + OutDma[DmaBufPtr][0] = (UBYTE)MsgSize;\ + OutDma[DmaBufPtr][1] = (UBYTE)(MsgSize>>8);\ + }\ + else\ + {\ + OutDma[DmaBufPtr][0] = (UBYTE)MsgSize;\ + }\ + memcpy(&(OutDma[DmaBufPtr][LengthSize]), OutputBuffer, BytesToSend);\ + *AT91C_US1_TNPR = (unsigned int)&(OutDma[DmaBufPtr][0]);\ + *AT91C_US1_TNCR = BytesToSend + LengthSize;\ + DmaBufPtr = (DmaBufPtr + 1) % NO_OF_DMA_OUTBUFFERS;\ + }\ + } + + +#define BTReceivedData(pByteCnt, pToGo)\ + {\ + UWORD InCnt, Cnt;\ + *pByteCnt = 0;\ + *pToGo = 0;\ + InCnt = (SIZE_OF_INBUF - *AT91C_US1_RCR);\ + if (*AT91C_US1_RNCR == 0)\ + {\ + InCnt = SIZE_OF_INBUF;\ + }\ + InCnt -= InBufOutCnt; /* Remove already read bytes */\ + if (InCnt)\ + {\ + if (0 == FullRxLength) /* FullRxLength still to be calculated */\ + {\ + while((MsgIn < LengthSize) && (InCnt > 0))\ + {\ + pBuffer[MsgIn] = InBuf[InBufInPtr][InBufOutCnt];\ + MsgIn++;\ + InBufOutCnt++;\ + InCnt--;\ + }\ + if (LengthSize == MsgIn)\ + {\ + if (2 == LengthSize)\ + {\ + FullRxLength = pBuffer[1];\ + FullRxLength <<= 8;\ + FullRxLength |= pBuffer[0];\ + /* Remove Length when in strean mode */\ + MsgIn = 0;\ + }\ + else\ + {\ + FullRxLength = pBuffer[0];\ + }\ + RemainingLength = FullRxLength;\ + }\ + else\ + {\ + /* Length still not received */\ + FullRxLength = 0;\ + }\ + }\ + if (FullRxLength)\ + {\ + /* Incomming msg in progress */\ + /* room for bytes? */\ + if (InCnt >= RemainingLength)\ + {\ + /* Remaining msg bytes are in the buffer */\ + /* Can remaining byte be stored in buffer? */\ + if ((MsgIn + RemainingLength) <= SIZE_OF_INBUF)\ + {\ + /* All bytes can be stored */\ + for (Cnt = 0; Cnt < RemainingLength; Cnt++)\ + {\ + pBuffer[MsgIn] = InBuf[InBufInPtr][InBufOutCnt];\ + MsgIn++;\ + InBufOutCnt++;\ + }\ + *pByteCnt = MsgIn;\ + *pToGo = 0;\ + FullRxLength = 0;\ + RemainingLength = 0;\ + MsgIn = 0;\ + }\ + else\ + {\ + for (Cnt = 0; MsgIn < SIZE_OF_INBUF; Cnt++)\ + {\ + pBuffer[MsgIn] = InBuf[InBufInPtr][InBufOutCnt];\ + MsgIn++;\ + InBufOutCnt++;\ + }\ + *pByteCnt = SIZE_OF_INBUF;\ + RemainingLength -= Cnt;\ + *pToGo = RemainingLength;\ + MsgIn = 0;\ + }\ + }\ + else\ + {\ + if ((InCnt + MsgIn) < SIZE_OF_INBUF)\ + {\ + /* Received bytes do not fill up the buffer */\ + for (Cnt = 0; Cnt < InCnt; Cnt++)\ + {\ + pBuffer[MsgIn] = InBuf[InBufInPtr][InBufOutCnt];\ + MsgIn++;\ + InBufOutCnt++;\ + }\ + RemainingLength -= InCnt;\ + }\ + else\ + {\ + /* Received bytes fill up the buffer */\ + for (Cnt = 0; MsgIn < SIZE_OF_INBUF; Cnt++)\ + {\ + pBuffer[MsgIn] = InBuf[InBufInPtr][InBufOutCnt];\ + MsgIn++;\ + InBufOutCnt++;\ + }\ + *pByteCnt = SIZE_OF_INBUF;\ + RemainingLength -= Cnt; /* Only substract no removed */\ + *pToGo = RemainingLength;\ + MsgIn = 0;\ + }\ + }\ + }\ + }\ + if ((*AT91C_US1_RNCR == 0) && (SIZE_OF_INBUF == InBufOutCnt))\ + {\ + InBufOutCnt = 0;\ + *AT91C_US1_RNPR = (unsigned int)InBufPtrs[InBufInPtr];\ + *AT91C_US1_RNCR = SIZE_OF_INBUF;\ + InBufInPtr = (InBufInPtr + 1) % NO_OF_INBUFFERS;\ + }\ + } + +#define BTExit {\ + *AT91C_PMC_PCDR = PER_ID7_UART_1; /* Disable PMC clock for UART 1*/\ + *AT91C_US1_IDR = AT91C_US_TIMEOUT; /* Disable interrupt on timeout */\ + *AT91C_AIC_IDCR = UART1_INQ; /* Disable PIO interrupt */\ + *AT91C_AIC_ICCR = UART1_INQ; /* Clear interrupt register */\ + } + + +#endif + +#ifdef PCWIN + +#endif diff --git a/src/d_button.c b/src/d_button.c new file mode 100644 index 0000000..2691e8c --- /dev/null +++ b/src/d_button.c @@ -0,0 +1,36 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: d_button.c $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_butt $ +// +// Platform C +// + +#include "stdconst.h" +#include "m_sched.h" +#include "d_button.h" +#include "d_button.r" + +static UBYTE TimeTick; + +void dButtonInit(UBYTE Prescaler) +{ + TimeTick = Prescaler; + BUTTONInit; +} + +void dButtonRead(UBYTE *pButton) +{ + BUTTONRead(pButton); +} + +void dButtonExit(void) +{ + BUTTONExit; +} diff --git a/src/d_button.h b/src/d_button.h new file mode 100644 index 0000000..10dacac --- /dev/null +++ b/src/d_button.h @@ -0,0 +1,24 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: d_button.h $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_butt $ +// +// Platform C +// + +#ifndef D_BUTTON +#define D_BUTTON + +void dButtonInit(UBYTE Prescaler); +void dButtonExit(void); + +void dButtonRead(UBYTE *pButton); + + +#endif diff --git a/src/d_button.r b/src/d_button.r new file mode 100644 index 0000000..c478394 --- /dev/null +++ b/src/d_button.r @@ -0,0 +1,189 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: d_button.r $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_butt $ +// +// Platform C +// + +#ifdef SAM7S256 + +static UBYTE PrellCnt[NOS_OF_AVR_BTNS]; +static UWORD OldVal; +static UBYTE OldState; +static UBYTE RisingTime; + +#define PRELL_TIME (60/TimeTick) +#define RISING_THRESHOLD (10/TimeTick) + +#define BUTTONInit {\ + UBYTE Tmp;\ + for (Tmp = 0; Tmp < NOS_OF_AVR_BTNS; Tmp++)\ + {\ + PrellCnt[Tmp] = 0;\ + }\ + IoFromAvr.Buttons = 0;\ + OldVal = 0;\ + OldState = 0;\ + RisingTime = 0;\ + } + +#if defined (PROTOTYPE_PCB_3) || (PROTOTYPE_PCB_4) + +/* Buttons read here are free of prell or jitter */ +/* And because it's an AD value returned from the AVR */ +/* then a peak detector is needed */ +#define BUTTONRead(pB) {\ + UBYTE Tmp, BtnPtr;\ + UWORD TmpBtn;\ + *pB = OldState;\ + BtnPtr = 0x01;\ + if (OldVal < IoFromAvr.Buttons)\ + {\ + OldVal = IoFromAvr.Buttons;\ + RisingTime = 0;\ + }\ + else\ + {\ + if (OldVal > (IoFromAvr.Buttons + 20))\ + {\ + OldVal = IoFromAvr.Buttons;\ + RisingTime = 0;\ + }\ + else\ + {\ + if (RisingTime > RISING_THRESHOLD)\ + {\ + TmpBtn = IoFromAvr.Buttons;\ + if (0x40 > TmpBtn)\ + {\ + TmpBtn = 0x00;\ + }\ + else if (0x100 > TmpBtn)\ + {\ + TmpBtn = 0x04;\ + }\ + else if (0x1FF > TmpBtn)\ + {\ + TmpBtn = 0x02;\ + }\ + else if (0x5FF > TmpBtn)\ + {\ + TmpBtn = 0x01;\ + }\ + else\ + {\ + TmpBtn = 0x08;\ + }\ + for (Tmp = 0; Tmp < NOS_OF_AVR_BTNS; Tmp++)\ + {\ + if ((TmpBtn) & BtnPtr)\ + {\ + *pB |= BtnPtr;\ + PrellCnt[Tmp] = PRELL_TIME;\ + }\ + else\ + {\ + /* btn not pressed */\ + if (0 != PrellCnt[Tmp])\ + {\ + PrellCnt[Tmp]--;\ + }\ + else\ + {\ + *pB &= ~BtnPtr;\ + }\ + }\ + BtnPtr <<= 1;\ + }\ + OldState = *pB;\ + }\ + else\ + {\ + RisingTime++;\ + }\ + }\ + }\ + } + +#else + +// Buttons read here are free of prell or jitter +#define BUTTONRead(pB) {\ + UBYTE Tmp, BtnPtr;\ + UWORD TmpBtn;\ + *pB = OldState;\ + BtnPtr = 0x01;\ + if ((OldVal) < IoFromAvr.Buttons)\ + {\ + OldVal = IoFromAvr.Buttons;\ + }\ + else\ + {\ + if ((OldVal) > IoFromAvr.Buttons)\ + {\ + OldVal = IoFromAvr.Buttons;\ + }\ + else\ + {\ + TmpBtn = IoFromAvr.Buttons;\ + if (100 > TmpBtn)\ + {\ + TmpBtn = 0x00;\ + }\ + else if (170 > TmpBtn)\ + {\ + TmpBtn = 0x01;\ + }\ + else if (255 > TmpBtn)\ + {\ + TmpBtn = 0x02;\ + }\ + else if (1000 > TmpBtn)\ + {\ + TmpBtn = 0x04;\ + }\ + else if (1024 > TmpBtn)\ + {\ + TmpBtn = 0x08;\ + }\ + for (Tmp = 0; Tmp < NOS_OF_AVR_BTNS; Tmp++)\ + {\ + if ((TmpBtn) & BtnPtr)\ + {\ + *pB |= BtnPtr;\ + PrellCnt[Tmp] = PRELL_TIME;\ + }\ + else\ + {\ + /* btn not pressed */\ + if (0 != PrellCnt[Tmp])\ + {\ + PrellCnt[Tmp]--;\ + }\ + else\ + {\ + *pB &= ~BtnPtr;\ + }\ + }\ + BtnPtr <<= 1;\ + }\ + OldState = *pB;\ + }\ + }\ + } +#endif + +#define BUTTONExit + +#endif + +#ifdef PCWIN + +#endif diff --git a/src/d_display.c b/src/d_display.c new file mode 100644 index 0000000..99f16c6 --- /dev/null +++ b/src/d_display.c @@ -0,0 +1,53 @@ +// +// Programmer +// +// Date init 14.12.2004 +// +// Reviser $Author:: Dkandlun $ +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: d_display.c $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_disp $ +// +// Platform C +// + +#include "stdconst.h" +#include "m_sched.h" +#include "d_display.h" +#include "d_display.r" + + +void dDisplayInit(void) +{ + DISPLAYInit; +} + + +void dDisplayOn(UBYTE On) +{ + if (On) + { + DISPLAYOn; + } + else + { + DISPLAYOff; + } +} + + +UBYTE dDisplayUpdate(UWORD Height,UWORD Width,UBYTE *pImage) +{ + return (DISPLAYUpdate(Height,Width,pImage)); +} + + +void dDisplayExit(void) +{ + DISPLAYExit; +} diff --git a/src/d_display.h b/src/d_display.h new file mode 100644 index 0000000..a894685 --- /dev/null +++ b/src/d_display.h @@ -0,0 +1,39 @@ +// +// Programmer +// +// Date init 14.12.2004 +// +// Reviser $Author:: Dkandlun $ +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: d_display.h $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_disp $ +// +// Platform C +// + +#ifndef D_DISPLAY +#define D_DISPLAY + +void dDisplayInit(void); +void dDisplayOn(UBYTE On); +UBYTE dDisplayUpdate(UWORD Height,UWORD Width,UBYTE *pImage); +void dDisplayExit(void); + + + +typedef struct +{ + UBYTE StartX; + UBYTE StartY; + UBYTE PixelsX; + UBYTE PixelsY; +} +SCREEN_CORDINATE; + + +#endif diff --git a/src/d_display.r b/src/d_display.r new file mode 100644 index 0000000..e38bb45 --- /dev/null +++ b/src/d_display.r @@ -0,0 +1,374 @@ +// +// Programmer +// +// Date init 14.12.2004 +// +// Reviser $Author:: Dkandlun $ +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: d_display.r $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_disp $ +// +// Platform C +// + +#ifdef SAM7S256 + +// Display 128 x 64 +// 1/65 duty, 1/9 bias +// VLCD 12.0V + +// SPI interface +// +// PCB LCD ARM PIO +// ------ ----- ---- ----- +// CS_DIS -CS1 PA10 NPCS2 (PB) +// DIS_A0 A0 PA12 PA12 +// DIS_SCL SCL PA14 SPCK (PA) +// DIS_SDA SI PA13 MOSI (PA) + + +// CPOL = 0, NCPHA=0, + +#define BT_RESET_OUT AT91C_PIO_PA11 +#define BT_RESET_IN AT91C_PIO_PA29 +#define BT_MOSI_OUT AT91C_PIO_PA13 +#define BT_MOSI_IN AT91C_PIO_PA20 +#define BT_CLK_OUT AT91C_PIO_PA14 +#define BT_CLK_IN AT91C_PIO_PA28 +#define BT_CE_OUT AT91C_PIO_PA31 +#define BT_CE_IN AT91C_PIO_PA19 +#define BT_REA_OUT AT91C_PIO_PA7 +#define BT_MISO_OUT AT91C_PIO_PA6 +#define BT_MISO_IN AT91C_PIO_PA12 + +#pragma optimize=s 9 + +__ramfunc void SpiBtIo(void) +{ + register ULONG Port; + + *AT91C_AIC_IDCR = 0xFFFFFFFF; /* Disable all interrupts */ + + *AT91C_PIOA_PER = BT_RESET_OUT; /* Enable pin RESET out */ + *AT91C_PIOA_OER = BT_RESET_OUT; /* Set output */ + *AT91C_PIOA_SODR = BT_RESET_OUT; /* Set high */ + + *AT91C_PIOA_PER = BT_MOSI_OUT; /* Enable pin MOSI out */ + *AT91C_PIOA_OER = BT_MOSI_OUT; /* Set output */ + + *AT91C_PIOA_PER = BT_CLK_OUT; /* Enable pin CLK out */ + *AT91C_PIOA_OER = BT_CLK_OUT; /* Set output */ + + *AT91C_PIOA_PER = BT_CE_OUT; /* Enable pin CE out */ + *AT91C_PIOA_OER = BT_CE_OUT; /* Set output */ + + *AT91C_PIOA_PER = BT_REA_OUT; /* Enable pin REA out */ + *AT91C_PIOA_OER = BT_REA_OUT; /* Set output */ + *AT91C_PIOA_SODR = BT_REA_OUT; /* Set high */ + + *AT91C_PIOA_PER = BT_MISO_OUT; /* Enable pin MISO out */ + *AT91C_PIOA_OER = BT_MISO_OUT; /* Set output */ + + *AT91C_PIOA_PER = BT_RESET_IN; /* Enable pin RESET in */ + *AT91C_PIOA_ODR = BT_RESET_IN; /* Set input */ + *AT91C_PIOA_IFDR = BT_RESET_IN; /* Disable filter */ + *AT91C_PIOA_IDR = BT_RESET_IN; /* Disable interrupt */ + *AT91C_PIOA_MDDR = BT_RESET_IN; /* Disable multidriver */ + *AT91C_PIOA_PPUDR = BT_RESET_IN; /* Disable pullup */ + + *AT91C_PIOA_PER = BT_MOSI_IN; /* Enable pin MOSI in */ + *AT91C_PIOA_ODR = BT_MOSI_IN; /* Set input */ + *AT91C_PIOA_IFDR = BT_MOSI_IN; /* Disable filter */ + *AT91C_PIOA_IDR = BT_MOSI_IN; /* Disable interrupt */ + *AT91C_PIOA_MDDR = BT_MOSI_IN; /* Disable multidriver */ + *AT91C_PIOA_PPUDR = BT_MOSI_IN; /* Disable pullup */ + + *AT91C_PIOA_PER = BT_CLK_IN; /* Enable pin CLK in */ + *AT91C_PIOA_ODR = BT_CLK_IN; /* Set input */ + *AT91C_PIOA_IFDR = BT_CLK_IN; /* Disable filter */ + *AT91C_PIOA_IDR = BT_CLK_IN; /* Disable interrupt */ + *AT91C_PIOA_MDDR = BT_CLK_IN; /* Disable multidriver */ + *AT91C_PIOA_PPUDR = BT_CLK_IN; /* Disable pullup */ + + *AT91C_PIOA_PER = BT_CE_IN; /* Enable pin CE in */ + *AT91C_PIOA_ODR = BT_CE_IN; /* Set input */ + *AT91C_PIOA_IFDR = BT_CE_IN; /* Disable filter */ + *AT91C_PIOA_IDR = BT_CE_IN; /* Disable interrupt */ + *AT91C_PIOA_MDDR = BT_CE_IN; /* Disable multidriver */ + *AT91C_PIOA_PPUDR = BT_CE_IN; /* Disable pullup */ + + *AT91C_PIOA_PER = BT_MISO_IN; /* Enable pin MISO in */ + *AT91C_PIOA_ODR = BT_MISO_IN; /* Set input */ + *AT91C_PIOA_IFDR = BT_MISO_IN; /* Disable filter */ + *AT91C_PIOA_IDR = BT_MISO_IN; /* Disable interrupt */ + *AT91C_PIOA_MDDR = BT_MISO_IN; /* Disable multidriver */ + *AT91C_PIOA_PPUDR = BT_MISO_IN; /* Disable pullup */ + + while (1) + { + Port = *AT91C_PIOA_PDSR; + if ((Port & BT_MISO_IN)) + { + *AT91C_PIOA_SODR = BT_MISO_OUT; + } + else + { + *AT91C_PIOA_CODR = BT_MISO_OUT; + } + if ((Port & BT_MOSI_IN)) + { + *AT91C_PIOA_SODR = BT_MOSI_OUT; + } + else + { + *AT91C_PIOA_CODR = BT_MOSI_OUT; + } + if ((Port & BT_CLK_IN)) + { + *AT91C_PIOA_SODR = BT_CLK_OUT; + } + else + { + *AT91C_PIOA_CODR = BT_CLK_OUT; + } + if ((Port & BT_CE_IN)) + { + *AT91C_PIOA_SODR = BT_CE_OUT; + } + else + { + *AT91C_PIOA_CODR = BT_CE_OUT; + } + } + +} + + +void BtIo(void) +{ + SpiBtIo(); +} + + + +#define SPI_BITRATE 2000000 + +#define SPIA0High {\ + *AT91C_PIOA_SODR = AT91C_PIO_PA12;\ + } + + +#define SPIA0Low {\ + *AT91C_PIOA_CODR = AT91C_PIO_PA12;\ + } + + +#define SPIInit {\ + *AT91C_PMC_PCER = (1L << AT91C_ID_SPI); /* Enable MCK clock */\ + *AT91C_PIOA_PER = AT91C_PIO_PA12; /* Enable A0 on PA12 */\ + *AT91C_PIOA_OER = AT91C_PIO_PA12;\ + *AT91C_PIOA_CODR = AT91C_PIO_PA12;\ + *AT91C_PIOA_PDR = AT91C_PA14_SPCK; /* Enable SPCK on PA14 */\ + *AT91C_PIOA_ASR = AT91C_PA14_SPCK;\ + *AT91C_PIOA_ODR = AT91C_PA14_SPCK;\ + *AT91C_PIOA_OWER = AT91C_PA14_SPCK;\ + *AT91C_PIOA_MDDR = AT91C_PA14_SPCK;\ + *AT91C_PIOA_PPUDR = AT91C_PA14_SPCK;\ + *AT91C_PIOA_IFDR = AT91C_PA14_SPCK;\ + *AT91C_PIOA_CODR = AT91C_PA14_SPCK;\ + *AT91C_PIOA_IDR = AT91C_PA14_SPCK;\ + *AT91C_PIOA_PDR = AT91C_PA13_MOSI; /* Enable mosi on PA13 */\ + *AT91C_PIOA_ASR = AT91C_PA13_MOSI;\ + *AT91C_PIOA_ODR = AT91C_PA13_MOSI;\ + *AT91C_PIOA_OWER = AT91C_PA13_MOSI;\ + *AT91C_PIOA_MDDR = AT91C_PA13_MOSI;\ + *AT91C_PIOA_PPUDR = AT91C_PA13_MOSI;\ + *AT91C_PIOA_IFDR = AT91C_PA13_MOSI;\ + *AT91C_PIOA_CODR = AT91C_PA13_MOSI;\ + *AT91C_PIOA_IDR = AT91C_PA13_MOSI;\ + *AT91C_PIOA_PDR = AT91C_PA10_NPCS2; /* Enable npcs0 on PA11 */\ + *AT91C_PIOA_BSR = AT91C_PA10_NPCS2;\ + *AT91C_PIOA_ODR = AT91C_PA10_NPCS2;\ + *AT91C_PIOA_OWER = AT91C_PA10_NPCS2;\ + *AT91C_PIOA_MDDR = AT91C_PA10_NPCS2;\ + *AT91C_PIOA_PPUDR = AT91C_PA10_NPCS2;\ + *AT91C_PIOA_IFDR = AT91C_PA10_NPCS2;\ + *AT91C_PIOA_CODR = AT91C_PA10_NPCS2;\ + *AT91C_PIOA_IDR = AT91C_PA10_NPCS2;\ + *AT91C_SPI_CR = AT91C_SPI_SWRST; /* Soft reset */\ + *AT91C_SPI_CR = AT91C_SPI_SPIEN; /* Enable spi */\ + *AT91C_SPI_MR = AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | (0xB << 16);\ + AT91C_SPI_CSR[2] = ((OSC / SPI_BITRATE) << 8) | AT91C_SPI_CPOL;\ + } + + +#define SPIWrite(pString,Length) {\ + *AT91C_SPI_TPR = (unsigned int)pString;\ + *AT91C_SPI_TCR = (unsigned int)Length;\ + *AT91C_SPI_PTCR = AT91C_PDC_TXTEN;\ + } + + + +#define CMD 0 +#define DAT 1 +#define DISP_LINES 8 + +#if defined (PROTOTYPE_PCB_3) || (PROTOTYPE_PCB_4) + +#define ACTUAL_WIDTH 100 + +UBYTE DisplayInitString[] = +{ + 0xEB, // LCD bias setting = 1/9 0xEB + 0x2F, // Power control = internal 0x2F + 0xA4, // All points not on 0xA4 + 0xA6, // Not inverse 0xA6 + 0x40, // Start line = 0 0x40 + 0x81, // Electronic volume 0x81 + 0x5A, // -"- 0x5F + 0xC4, // LCD mapping 0xC4 + 0x27, // Set temp comp. 0x27- + 0x29, // Panel loading 0x28 0-1 + 0xA0, // Framerate 0xA0- + 0x88, // CA++ 0x88- + 0x23, // Multiplex 1:65 0x23 + 0xAF // Display on 0xAF +}; + +#else + +#define ACTUAL_WIDTH 128 + +UBYTE DisplayInitString[] = +{ + 0xA2, // LCD bias setting = 1/9 + 0x2F, // Power control = internal + 0xA4, // All points not on + 0xA6, // Not inverse + 0x40, // Start line = 0 + 0x81, // Electronic volume + 0x3F, // -"- + 0xA0, // LCD mapping + 0x27, // Resistor ratio + 0xC8, // Common output state selection + 0xF8, // Booster ratio + 0x00, // -"- + 0xE3, // nop + 0xAF // Display on +}; + +#endif + +UBYTE DisplayLineString[DISP_LINES][3] = +{ + { 0xB0,0x10,0x00 }, + { 0xB1,0x10,0x00 }, + { 0xB2,0x10,0x00 }, + { 0xB3,0x10,0x00 }, + { 0xB4,0x10,0x00 }, + { 0xB5,0x10,0x00 }, + { 0xB6,0x10,0x00 }, + { 0xB7,0x10,0x00 } +}; + +UBYTE DisplayWrite(UBYTE Type,UBYTE *pData,UWORD Length) +{ + UBYTE Result = FALSE; + + if ((*AT91C_SPI_SR & AT91C_SPI_TXEMPTY)) + { + if (Type) + { + SPIA0High; + } + else + { + SPIA0Low; + } + SPIWrite(pData,Length); + Result = TRUE; + } + + return (Result); +} + +UBYTE DisplayUpdate(UWORD Height,UWORD Width,UBYTE *pImage) +{ + static UWORD State = 0; + static UWORD Line; + + if (State == 0) + { + if (DisplayWrite(CMD,(UBYTE*)DisplayInitString,sizeof(DisplayInitString)) == TRUE) + { + Line = 0; + State++; + } + } + else + { + if ((State & 1)) + { + if (DisplayWrite(CMD,(UBYTE*)DisplayLineString[Line],3) == TRUE) + { + State++; + } + } + else + { + if (DisplayWrite(DAT,(UBYTE*)&pImage[Line * Width],ACTUAL_WIDTH) == TRUE) + { + State++; + if (++Line >= (Height / 8)) + { + State = 0; + } + } + } + } + + return (State); +} + + +#if defined (PROTOTYPE_PCB_3) + +#define DISPLAYInit {\ + TSTInit;\ + TSTOn;\ + SPIInit;\ + } + +#else + +#define DISPLAYInit {\ + SPIInit;\ + } + +#endif + +#define DISPLAYOn {\ + DisplayInitString[6] = 0x5A;\ + DisplayInitString[13] = 0xAF;\ + } + +#define DISPLAYOff {\ + DisplayInitString[6] = 0x00;\ + DisplayInitString[13] = 0xAE;\ + } + +#define DISPLAYUpdate(H,W,I) DisplayUpdate(H,W,I) + +#define DISPLAYExit + +#endif + +#ifdef PCWIN + +#endif diff --git a/src/d_hispeed.c b/src/d_hispeed.c new file mode 100644 index 0000000..01f2d07 --- /dev/null +++ b/src/d_hispeed.c @@ -0,0 +1,48 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: d_hispeed.c $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_hisp $ +// +// Platform C +// + +#include "stdconst.h" +#include "m_sched.h" +#include "d_hispeed.h" +#include "d_hispeed.r" + +void dHiSpeedInit(void) +{ + HIGHSPEEDInit; +} + +void dHiSpeedSendData(UBYTE *OutputBuffer, UBYTE BytesToSend) +{ + HIGHSPEEDSendDmaData(OutputBuffer,BytesToSend); +} + +void dHiSpeedSetupUart(void) +{ + HIGHSPEEDSetupUart; +} + +void dHiSpeedInitReceive(UBYTE *InputBuffer) +{ + HIGHSPEEDInitReceiver(InputBuffer); +} + +void dHiSpeedReceivedData(UWORD *ByteCnt) +{ + HIGHSPEEDReceivedData(ByteCnt); +} + +void dHiSpeedExit(void) +{ + HIGHSPEEDExit; +} diff --git a/src/d_hispeed.h b/src/d_hispeed.h new file mode 100644 index 0000000..669a5d1 --- /dev/null +++ b/src/d_hispeed.h @@ -0,0 +1,25 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: d_hispeed.h $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_hisp $ +// +// Platform C +// + +#ifndef D_HISPEED +#define D_HISPEED + +void dHiSpeedInit(void); +void dHiSpeedSendData(UBYTE *OutputBuffer, UBYTE BytesToSend); +void dHiSpeedSetupUart(void); +void dHiSpeedInitReceive(UBYTE *InputBuffer); +void dHiSpeedReceivedData(UWORD *ByteCnt); +void dHiSpeedExit(void); + +#endif diff --git a/src/d_hispeed.r b/src/d_hispeed.r new file mode 100644 index 0000000..52d5e14 --- /dev/null +++ b/src/d_hispeed.r @@ -0,0 +1,190 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: d_hispeed.r $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_hisp $ +// +// Platform C +// + +#ifdef SAM7S256 + +#if defined (PROTOTYPE_PCB_3) || (PROTOTYPE_PCB_4) + +#define HIGHSPEED_RX_PIN AT91C_PIO_PA5 +#define HIGHSPEED_TX_PIN AT91C_PIO_PA6 +#define HIGHSPEED_RTS_PIN AT91C_PIO_PA7 + +#else + + +#endif + +#define PER_ID6_UART_0 0x40 +#define UART0_INQ 0x40 +#define BAUD_RATE 921600L + +#define SIZE_OF_INBUF 128 +#define NO_OF_INBUFFERS 2 +#define SIZE_OF_OUTBUF 128 +#define NO_OF_DMA_OUTBUFFERS 1 + +static UBYTE InBuf[NO_OF_INBUFFERS][SIZE_OF_INBUF]; +static ULONG InBufPtrs[NO_OF_INBUFFERS]; +static UBYTE InBufInPtr; + +static UBYTE OutDma[NO_OF_DMA_OUTBUFFERS][SIZE_OF_OUTBUF]; +static UBYTE DmaBufPtr; +static UBYTE *pBuffer; + +static UBYTE MsgIn; +static UBYTE InBufOutCnt; + +#define HIGHSPEEDInit {\ + *AT91C_PIOA_PER = HIGHSPEED_TX_PIN | HIGHSPEED_RTS_PIN | HIGHSPEED_RX_PIN; /* Enable PIO on PA07, PA06 & PA05 */\ + *AT91C_PIOA_PPUDR = HIGHSPEED_RX_PIN | HIGHSPEED_TX_PIN | HIGHSPEED_RTS_PIN; /* Disable Pull-up resistor */\ + *AT91C_PIOA_OER = HIGHSPEED_TX_PIN | HIGHSPEED_RTS_PIN | HIGHSPEED_RX_PIN; /* PA07 & PA06 set to Output */\ + *AT91C_PIOA_CODR = HIGHSPEED_TX_PIN | HIGHSPEED_RTS_PIN | HIGHSPEED_RX_PIN; /* Set output low */\ + } + + +#define HIGHSPEEDSetupUart {\ + UBYTE Tmp;\ + InBufInPtr = 0;\ + for(Tmp = 0; Tmp < NO_OF_INBUFFERS; Tmp++)\ + {\ + InBufPtrs[Tmp] = (ULONG)&(InBuf[Tmp][0]);\ + }\ + *AT91C_PMC_PCER = PER_ID6_UART_0; /* Enable PMC clock for UART 0 */\ + *AT91C_PIOA_PPUDR = HIGHSPEED_RX_PIN | HIGHSPEED_TX_PIN | HIGHSPEED_RTS_PIN; /* Disable Pull-up resistor */\ + *AT91C_PIOA_PDR = HIGHSPEED_TX_PIN | HIGHSPEED_RTS_PIN | HIGHSPEED_RX_PIN; /* Disable Per. A on PA5, PA6 & PA7 */\ + *AT91C_PIOA_ASR = HIGHSPEED_TX_PIN | HIGHSPEED_RTS_PIN | HIGHSPEED_RX_PIN;; /* Enable Per. A on PA5, PA6 & PA7 */\ + *AT91C_US0_CR = AT91C_US_RSTSTA; /* Resets pins on UART0 */\ + *AT91C_US0_CR = AT91C_US_STTTO; /* Start timeout functionality after 1 byte */\ + *AT91C_US0_RTOR = 2400; /* Approxitely 20 mS,x times bit time with 115200 bit pr s */\ + *AT91C_US0_IDR = AT91C_US_TIMEOUT; /* Disable interrupt on timeout */\ + *AT91C_AIC_IDCR = UART0_INQ; /* Disable UART0 interrupt */\ + *AT91C_AIC_ICCR = UART0_INQ; /* Clear interrupt register */\ + *AT91C_US0_MR = AT91C_US_USMODE_RS485; /* Set UART to RUN RS485 Mode*/\ + *AT91C_US0_MR &= ~AT91C_US_SYNC; /* Set UART in asynchronous mode */\ + *AT91C_US0_MR |= AT91C_US_CLKS_CLOCK; /* Clock setup MCK*/\ + *AT91C_US0_MR |= AT91C_US_CHRL_8_BITS; /* UART using 8-bit */\ + *AT91C_US0_MR |= AT91C_US_PAR_NONE; /* UART using none parity bit */\ + *AT91C_US0_MR |= AT91C_US_NBSTOP_1_BIT; /* UART using 1 stop bit */\ + *AT91C_US0_MR |= AT91C_US_OVER; /* UART is using 8-bit sampling */\ + *AT91C_US0_BRGR = ((OSC/8/BAUD_RATE) | (((OSC/8) - ((OSC/8/BAUD_RATE) * BAUD_RATE)) / ((BAUD_RATE + 4)/8)) << 16);\ + *AT91C_US0_PTCR = (AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS); /* Disable of TX & RX with DMA */\ + *AT91C_US0_RCR = 0; /* Receive Counter Register */\ + *AT91C_US0_TCR = 0; /* Transmit Counter Register */\ + *AT91C_US0_RNPR = 0;\ + *AT91C_US0_TNPR = 0;\ + Tmp = *AT91C_US0_RHR;\ + Tmp = *AT91C_US0_CSR;\ + *AT91C_US0_RPR = (unsigned int)&(InBuf[InBufInPtr][0]); /* Initialise receiver buffer using DMA */\ + *AT91C_US0_RCR = SIZE_OF_INBUF;\ + *AT91C_US0_RNPR = (unsigned int)&(InBuf[(InBufInPtr + 1)%NO_OF_INBUFFERS][0]);\ + *AT91C_US0_RNCR = SIZE_OF_INBUF;\ + MsgIn = 0;\ + InBufOutCnt = 0;\ + *AT91C_US0_CR = AT91C_US_RXEN | AT91C_US_TXEN; /* Enable Tx & Rx on UART 0*/\ + *AT91C_US0_PTCR = (AT91C_PDC_RXTEN | AT91C_PDC_TXTEN); /* Enable of TX & RX with DMA */\ + } + +#define HIGHSPEEDInitReceiver(InputBuffer)\ + {\ + UBYTE Tmp;\ + pBuffer = InputBuffer;\ + *AT91C_US0_PTCR = (AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS); /* Disable of TX & RX with DMA */\ + *AT91C_US0_RCR = 0; /* Receive Counter Register */\ + *AT91C_US0_TCR = 0; /* Transmit Counter Register */\ + *AT91C_US0_RNPR = 0;\ + *AT91C_US0_TNPR = 0;\ + Tmp = *AT91C_US0_RHR;\ + Tmp = *AT91C_US0_CSR;\ + Tmp = Tmp;\ + *AT91C_US0_RPR = (unsigned int)&(InBuf[InBufInPtr][0]); /* Initialise receiver buffer using DMA */\ + *AT91C_US0_RCR = SIZE_OF_INBUF;\ + *AT91C_US0_RNPR = (unsigned int)&(InBuf[(InBufInPtr + 1)%NO_OF_INBUFFERS][0]);\ + *AT91C_US0_RNCR = SIZE_OF_INBUF;\ + MsgIn = 0;\ + InBufOutCnt = 0;\ + *AT91C_US0_CR = AT91C_US_RXEN | AT91C_US_TXEN; /* Enable Tx & Rx on UART 0*/\ + *AT91C_US0_PTCR = (AT91C_PDC_RXTEN | AT91C_PDC_TXTEN); /* Enable of TX & RX with DMA */\ + } + + +#define HIGHSPEEDReceivedData(pByteCnt)\ + {\ + UWORD InCnt;\ + *pByteCnt = 0;\ + InCnt = (SIZE_OF_INBUF - *AT91C_US0_RCR);\ + if (*AT91C_US0_RNCR == 0)\ + {\ + InCnt = SIZE_OF_INBUF;\ + }\ + InCnt -= InBufOutCnt; /* Remove already read bytes */\ + if(InCnt)\ + {\ + while(InCnt > 0)\ + {\ + pBuffer[MsgIn] = InBuf[InBufInPtr][InBufOutCnt];\ + MsgIn++;\ + InBufOutCnt++;\ + InCnt--;\ + }\ + *pByteCnt = MsgIn;\ + MsgIn = 0;\ + }\ + if ((*AT91C_US0_RNCR == 0) && (SIZE_OF_INBUF == InBufOutCnt))\ + {\ + InBufOutCnt = 0;\ + *AT91C_US0_RNPR = (unsigned int)InBufPtrs[InBufInPtr];\ + *AT91C_US0_RNCR = SIZE_OF_INBUF;\ + InBufInPtr = (InBufInPtr + 1) % NO_OF_INBUFFERS;\ + }\ + } + +#define AVAILOutBuf(Avail) if (!(*AT91C_US0_TNCR))\ + {\ + Avail = SIZE_OF_OUTBUF;\ + }\ + else\ + {\ + Avail = 0;\ + } + +#define HIGHSPEEDSendDmaData(OutputBuffer, BytesToSend)\ + {\ + UWORD Avail, Cnt;\ + AVAILOutBuf(Avail);\ + if (BytesToSend < (Avail - 1))\ + {\ + for (Cnt = 0; Cnt < BytesToSend; Cnt++)\ + {\ + OutDma[DmaBufPtr][Cnt] = OutputBuffer[Cnt];\ + }\ + *AT91C_US0_TNPR = (unsigned int)&(OutDma[DmaBufPtr][0]);\ + *AT91C_US0_TNCR = BytesToSend;\ + DmaBufPtr = (DmaBufPtr + 1) % NO_OF_DMA_OUTBUFFERS;\ + }\ + } + +#define HIGHSPEEDExit {\ + *AT91C_PMC_PCDR = PER_ID6_UART_0; /* Disable PMC clock for UART 0*/\ + *AT91C_PIOA_PER = HIGHSPEED_TX_PIN | HIGHSPEED_RTS_PIN | HIGHSPEED_RX_PIN; /* Enable PIO on PA07, PA06 & PA05 */\ + *AT91C_PIOA_PPUDR = HIGHSPEED_RX_PIN | HIGHSPEED_TX_PIN | HIGHSPEED_RTS_PIN; /* Disable Pull-up resistor */\ + *AT91C_PIOA_OER = HIGHSPEED_TX_PIN | HIGHSPEED_RTS_PIN | HIGHSPEED_RX_PIN; /* PA07 & PA06 set to Output */\ + *AT91C_PIOA_CODR = HIGHSPEED_TX_PIN | HIGHSPEED_RTS_PIN | HIGHSPEED_RX_PIN; /* Set output low */\ + } + + +#endif + +#ifdef PCWIN + +#endif diff --git a/src/d_input.c b/src/d_input.c new file mode 100644 index 0000000..771eb3e --- /dev/null +++ b/src/d_input.c @@ -0,0 +1,152 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 14-01-09 10:34 $ +// +// Filename $Workfile:: d_input.c $ +// +// Version $Revision:: 12 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_inpu $ +// +// Platform C +// + +#include "stdconst.h" +#include "m_sched.h" +#include "c_input.h" +#include "d_input.h" +#include "d_input.r" + + +void dInputInit(void) +{ + INPUTInit; +} + +void dInputSetColorClkInput(void) +{ + COLORClkInput; +} + +void dInputGetAllColors(COLORSTRUCT *pRaw, UBYTE Status) +{ + UPDATEAllColors(pRaw, Status); +} + +void dInputGetRawAd(UWORD *pValues, UBYTE No) +{ + INPUTGetVal(pValues, No); +} + +void dInputSetDirOutDigi0(UBYTE Port) +{ + INPUTSetOutDigi0(Port); +} + +void dInputSetDirOutDigi1(UBYTE Port) +{ + INPUTSetOutDigi1(Port); +} + +void dInputSetDirInDigi0(UBYTE Port) +{ + INPUTSetInDigi0(Port); +} + +void dInputSetDirInDigi1(UBYTE Port) +{ + INPUTSetInDigi1(Port); +} + +void dInputClearDigi0(UBYTE Port) +{ + INPUTClearDigi0(Port); + INPUTSetOutDigi0(Port); +} + +void dInputClearDigi1(UBYTE Port) +{ + INPUTClearDigi1(Port); + INPUTSetOutDigi1(Port); +} + +void dInputSetDigi0(UBYTE Port) +{ + INPUTSetDigi0(Port); + INPUTSetOutDigi0(Port); +} + +void dInputSetDigi1(UBYTE Port) +{ + INPUTSetDigi1(Port); + INPUTSetOutDigi1(Port); +} + +void dInputRead0(UBYTE Port, UBYTE *pData) +{ + INPUTReadDigi0(Port, pData); +} + +void dInputRead1(UBYTE Port, UBYTE * pData) +{ + INPUTReadDigi1(Port, pData); +} + +void dInputSetActive(UBYTE Port) +{ + INPUTSetActive(Port); +} + +void dInputSet9v(UBYTE Port) +{ + INPUTSet9v(Port); +} + +void dInputSetInactive(UBYTE Port) +{ + INPUTSetInactive(Port); +} + +UBYTE dInputGetColor(UBYTE No, UWORD *pCol) +{ + UBYTE Status; + UPDATELed(No, pCol, Status); + return(Status); +} + +void dInputColorTx(UBYTE Port, UBYTE Data) +{ + COLORTx(Port, Data); +} + +void dInputReadCal(UBYTE Port, UBYTE *pData) +{ + CALDataRead(Port, pData); +} + +UBYTE dInputCheckColorStatus(UBYTE Port) +{ + UBYTE Status; + + CHECKColorState(Port,Status); + return(Status); +} + +void dInputClearColor100msTimer(UBYTE No) +{ + CLEARColor100msTimer(No); +} + +UBYTE dInputChkColor100msTimer(UBYTE No) +{ + UBYTE State; + COLOR100msStatus(No, State); + return(State); +} + +void dInputExit(void) +{ + INPUTExit; +} + diff --git a/src/d_input.h b/src/d_input.h new file mode 100644 index 0000000..d365dd1 --- /dev/null +++ b/src/d_input.h @@ -0,0 +1,48 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 14-01-09 10:33 $ +// +// Filename $Workfile:: d_input.h $ +// +// Version $Revision:: 12 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_inpu $ +// +// Platform C +// + +#ifndef D_INPUT +#define D_INPUT + +void dInputInit(void); +void dInputExit(void); + +void dInputGetRawAd(UWORD *pValues, UBYTE No); +void dInputSetActive(UBYTE Port); +void dInputSet9v(UBYTE Port); +void dInputSetInactive(UBYTE Port); + +void dInputSetDirOutDigi0(UBYTE Port); +void dInputSetDirOutDigi1(UBYTE Port); +void dInputSetDirInDigi0(UBYTE Port); +void dInputSetDirInDigi1(UBYTE Port); +void dInputClearDigi0(UBYTE Port); +void dInputClearDigi1(UBYTE Port); +void dInputSetDigi0(UBYTE Port); +void dInputSetDigi1(UBYTE Port); +void dInputRead0(UBYTE Port, UBYTE *pData); +void dInputRead1(UBYTE Port, UBYTE *pData); + +UBYTE dInputGetColor(UBYTE No, UWORD *pCol); + +void dInputColorTx(UBYTE Port, UBYTE Data); +void dInputReadCal(UBYTE Port, UBYTE *pData); +UBYTE dInputCheckColorStatus(UBYTE Port); +void dInputGetAllColors(COLORSTRUCT *pRaw, UBYTE Status); +void dInputSetColorClkInput(void); +void dInputClearColor100msTimer(UBYTE No); +UBYTE dInputChkColor100msTimer(UBYTE No); + + +#endif diff --git a/src/d_input.r b/src/d_input.r new file mode 100644 index 0000000..3dc567e --- /dev/null +++ b/src/d_input.r @@ -0,0 +1,312 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 14-01-09 10:33 $ +// +// Filename $Workfile:: d_input.r $ +// +// Version $Revision:: 24 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_inpu $ +// +// Platform C +// + + +#ifdef SAM7S256 + +void rInputWait2uS(void); +void rInputWait20uS(void); +void rInputWait30uS(void); +void rInputSingleADC(UBYTE Port, UWORD *Val); + +const ULONG Digi0Alloc[] = {AT91C_PIO_PA23, AT91C_PIO_PA28, AT91C_PIO_PA29, AT91C_PIO_PA30}; +const ULONG Digi1Alloc[] = {AT91C_PIO_PA18, AT91C_PIO_PA19, AT91C_PIO_PA20, AT91C_PIO_PA2}; +const ULONG ADPinDef[NO_OF_INPUTS] = {AT91C_ADC_CH1, AT91C_ADC_CH2, AT91C_ADC_CH3, AT91C_ADC_CH7}; +unsigned int volatile* ADValRegs[NO_OF_INPUTS] = {AT91C_ADC_CDR1, AT91C_ADC_CDR2, AT91C_ADC_CDR3, AT91C_ADC_CDR7}; + +static UBYTE ColorReset[NO_OF_INPUTS]; +static ULONG ColorClkDef; +static ULONG ColorTimer[NO_OF_INPUTS]; + +#define TIME2US ((OSC/16)/500000L) +#define TIME20US ((OSC/16)/50000L) +#define TIME30US ((OSC/16)/33333L) +#define TIME100MS ((OSC/16)/10L) + +#define MAX_AD_VALUE 0x3FF + +#define INPUTInit {\ + UBYTE Tmp; \ + for (Tmp = 0; Tmp < NOS_OF_AVR_INPUTS; Tmp++)\ + { \ + IoFromAvr.AdValue[Tmp] = MAX_AD_VALUE; \ + } \ + IoToAvr.InputPower = 0; \ + for (Tmp = 0; Tmp < NO_OF_INPUTS; Tmp++) \ + { \ + *AT91C_PIOA_PPUDR = Digi0Alloc[Tmp]; \ + *AT91C_PIOA_PPUDR = Digi1Alloc[Tmp]; \ + INPUTSetInDigi0(Tmp); \ + INPUTSetInDigi1(Tmp); \ + ColorReset[Tmp] = FALSE; \ + } \ + ColorClkDef = 0; \ + } + +#define INPUTGetVal(pValues, No) *pValues = (UWORD)IoFromAvr.AdValue[No]; \ + *pValues &= 0x03FF + +#define INPUTSetActive(Input) IoToAvr.InputPower |= (0x01 << Input); \ + IoToAvr.InputPower &= ~(0x10 << Input) +#define INPUTSet9v(Input) IoToAvr.InputPower |= (0x10 << Input); \ + IoToAvr.InputPower &= ~(0x01 << Input) +#define INPUTSetInactive(Input) IoToAvr.InputPower &= ~(0x11 << Input) + +#define INPUTSetOutDigi0(Input) *AT91C_PIOA_PER = Digi0Alloc[Input]; \ + *AT91C_PIOA_OER = Digi0Alloc[Input] + +#define INPUTSetOutDigi1(Input) *AT91C_PIOA_PER = Digi1Alloc[Input]; \ + *AT91C_PIOA_OER = Digi1Alloc[Input] + +#define INPUTSetInDigi0(Input) *AT91C_PIOA_PER = Digi0Alloc[Input]; \ + *AT91C_PIOA_ODR = Digi0Alloc[Input] + +#define INPUTSetInDigi1(Input) *AT91C_PIOA_PER = Digi1Alloc[Input]; \ + *AT91C_PIOA_ODR = Digi1Alloc[Input] + +#define INPUTSetDigi0(Input) *AT91C_PIOA_SODR = Digi0Alloc[Input] + +#define INPUTSetDigi1(Input) *AT91C_PIOA_SODR = Digi1Alloc[Input] + +#define INPUTClearDigi0(Input) *AT91C_PIOA_CODR = Digi0Alloc[Input] + +#define INPUTClearDigi1(Input) *AT91C_PIOA_CODR = Digi1Alloc[Input] + +#define INPUTReadDigi0(Input, Data) if ((*AT91C_PIOA_PDSR) & Digi0Alloc[Input]) \ + { \ + *Data |= 0x00000001; \ + } \ + else \ + { \ + *Data &= ~0x00000001; \ + } +#define INPUTReadDigi1(Input, Data) if ((*AT91C_PIOA_PDSR) & Digi1Alloc[Input]) \ + { \ + *Data |= 0x00000002; \ + } \ + else \ + { \ + *Data &= ~0x00000002; \ + } + +#define INPUTClkHigh(Port) INPUTSetDigi0(Port); \ + INPUTSetOutDigi0(Port); \ + rInputWait2uS() + +#define INPUTClkLow(Port) INPUTClearDigi0(Port); \ + INPUTSetOutDigi0(Port); \ + rInputWait2uS() + +#define COLORClkInput *AT91C_PIOA_ODR = ColorClkDef + +#define UPDATEAllColors(Vals, Status){\ + ULONG ADDef; \ + ADDef = 0; \ + ColorClkDef = 0; \ + if (0x01 & Status) \ + { \ + ADDef |= ADPinDef[0]; \ + ColorClkDef |= Digi0Alloc[0]; \ + if ((*AT91C_PIOA_PDSR) & Digi0Alloc[0]) \ + { \ + ColorReset[0] = TRUE; \ + } \ + } \ + if (0x02 & Status) \ + { \ + ADDef |= ADPinDef[1]; \ + ColorClkDef |= Digi0Alloc[1]; \ + if ((*AT91C_PIOA_PDSR) & Digi0Alloc[1]) \ + { \ + ColorReset[1] = TRUE; \ + } \ + } \ + if (0x04 & Status) \ + { \ + ADDef |= ADPinDef[2]; \ + ColorClkDef |= Digi0Alloc[2]; \ + if ((*AT91C_PIOA_PDSR) & Digi0Alloc[2]) \ + { \ + ColorReset[2] = TRUE; \ + } \ + } \ + if (0x08 & Status) \ + { \ + ADDef |= ADPinDef[3]; \ + ColorClkDef |= Digi0Alloc[3]; \ + if ((*AT91C_PIOA_PDSR) & Digi0Alloc[3]) \ + { \ + ColorReset[3] = TRUE; \ + } \ + } \ + *AT91C_PIOA_OER = ColorClkDef; \ + *AT91C_ADC_CHER = ADDef; \ + GetAdVals(Vals, BLANK, Status); \ + *AT91C_PIOA_SODR = ColorClkDef; \ + rInputWait20uS(); \ + GetAdVals(Vals, RED, Status); \ + *AT91C_PIOA_CODR = ColorClkDef; \ + rInputWait20uS(); \ + GetAdVals(Vals, GREEN, Status); \ + *AT91C_PIOA_SODR = ColorClkDef; \ + rInputWait20uS(); \ + GetAdVals(Vals, BLUE, Status); \ + *AT91C_PIOA_CODR = ColorClkDef; \ + *AT91C_ADC_CHDR = ADDef; \ + } + +#define UPDATELed(Port, Col, Status) { \ + rInputSingleADC(Port, Col); \ + if ((*AT91C_PIOA_PDSR) & Digi0Alloc[Port]) \ + { \ + ColorReset[Port] = TRUE; \ + } \ + CHECKColorState(Port, Status); \ + } + +#define SETClkHi(Port) INPUTClkHigh(Port) \ + +#define COLORTx(Port, Data) { \ + UBYTE BitCnt; \ + BitCnt = 0; \ + while(BitCnt++ < 8) \ + { \ + INPUTClkHigh(Port); \ + if (Data & 0x01) \ + { \ + INPUTSetDigi1(Port); \ + } \ + else \ + { \ + INPUTClearDigi1(Port); \ + } \ + rInputWait30uS(); \ + Data >>= 1; \ + INPUTClkLow(Port); \ + rInputWait30uS(); \ + } \ + } + +#define CALDataRead(Port, pData) {\ + UBYTE BitCnt; \ + UBYTE Data; \ + BitCnt = 0; \ + INPUTClkHigh(Port); \ + rInputWait2uS(); \ + while(BitCnt++ < 8) \ + { \ + INPUTClkHigh(Port); \ + rInputWait2uS(); \ + rInputWait2uS(); \ + INPUTClkLow(Port); \ + Data >>= 1; \ + if ((*AT91C_PIOA_PDSR) & Digi1Alloc[Port])\ + { \ + Data |= 0x80; \ + } \ + rInputWait2uS(); \ + } \ + *pData = Data; \ + } + +#define CHECKColorState(Port, Status) {\ + Status = TRUE; \ + if ((IoFromAvr.AdValue[Port] > 50) || (TRUE == ColorReset[Port])) \ + { \ + Status = FALSE; \ + ColorReset[Port] = FALSE; \ + } \ + } + + +#define INPUTExit { \ + UBYTE Tmp; \ + *AT91C_ADC_CHDR = (AT91C_ADC_CH1 | AT91C_ADC_CH2 | AT91C_ADC_CH3 | AT91C_ADC_CH7);\ + for (Tmp = 0; Tmp < NO_OF_INPUTS; Tmp++) \ + { \ + INPUTSetInDigi0(Tmp); \ + INPUTSetInDigi1(Tmp); \ + } \ + } + +#define CLEARColor100msTimer(No) ColorTimer[No] = (*AT91C_PITC_PIIR);\ + +#define COLOR100msStatus(No,V) V = FALSE;\ + if (((*AT91C_PITC_PIIR) - ColorTimer[No]) > TIME100MS)\ + {\ + V = TRUE;\ + } + + + +void rInputSingleADC(UBYTE Port, UWORD *Val) +{ + *Val = *AT91C_ADC_LCDR; + *AT91C_ADC_CHER = ADPinDef[Port]; + ADStart; + while(!((*AT91C_ADC_SR) & AT91C_ADC_DRDY)); + *Val = *AT91C_ADC_LCDR; + *AT91C_ADC_CHDR = ADPinDef[Port]; +} + +void GetAdVals(COLORSTRUCT *pColStruct, UBYTE Color, UBYTE Status) +{ + UBYTE ChCnt; + ADStart; + for(ChCnt = 0; ChCnt < NO_OF_INPUTS; ChCnt++) + { + if (Status & (0x01 << ChCnt)) + { + while(!((*AT91C_ADC_SR) & ADPinDef[ChCnt])); + pColStruct[ChCnt].ADRaw[Color] = *ADValRegs[ChCnt]; + } + } + ADStart; + for(ChCnt = 0; ChCnt < NO_OF_INPUTS; ChCnt++) + { + if (Status & (0x01 << ChCnt)) + { + while(!((*AT91C_ADC_SR) & ADPinDef[ChCnt])); + pColStruct[ChCnt].ADRaw[Color] += *ADValRegs[ChCnt]; + pColStruct[ChCnt].ADRaw[Color] = (pColStruct[ChCnt].ADRaw[Color])>>1; + } + } +} + +void rInputWait2uS(void) +{ + ULONG PitTmr; + PitTmr = (*AT91C_PITC_PIIR); + while (((*AT91C_PITC_PIIR) - PitTmr) < TIME2US); +} + +void rInputWait20uS(void) +{ + ULONG PitTmr; + PitTmr = (*AT91C_PITC_PIIR); + while (((*AT91C_PITC_PIIR) - PitTmr) < TIME20US); +} + +void rInputWait30uS(void) +{ + ULONG PitTmr; + PitTmr = (*AT91C_PITC_PIIR); + while (((*AT91C_PITC_PIIR) - PitTmr) < TIME30US); +} + +#endif + +#ifdef PCWIN + +#endif diff --git a/src/d_ioctrl.c b/src/d_ioctrl.c new file mode 100644 index 0000000..2506172 --- /dev/null +++ b/src/d_ioctrl.c @@ -0,0 +1,47 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 5-12-07 15:23 $ +// +// Filename $Workfile:: d_ioctrl.c $ +// +// Version $Revision:: 2 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_ioct $ +// +// Platform C +// + + +#include +#include "stdconst.h" +#include "m_sched.h" +#include "d_ioctrl.h" +#include "d_ioctrl.r" + + +void dIOCtrlInit(void) +{ + IOCTRLInit; +} + +void dIOCtrlSetPower(UBYTE Power) +{ + INSERTPower(Power); +} + +void dIOCtrlSetPwm(UBYTE Pwm) +{ + INSERTPwm(Pwm); +} + +void dIOCtrlTransfer(void) +{ + I2CTransfer; +} + +void dIOCtrlExit(void) +{ + IOCTRLExit; +} + diff --git a/src/d_ioctrl.h b/src/d_ioctrl.h new file mode 100644 index 0000000..4b7ae4f --- /dev/null +++ b/src/d_ioctrl.h @@ -0,0 +1,25 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: d_ioctrl.h $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_ioct $ +// +// Platform C +// + +#ifndef D_AVRCOMM +#define D_AVRCOMM + +void dIOCtrlInit(void); +void dIOCtrlExit(void); + +void dIOCtrlSetPower(UBYTE Power); +void dIOCtrlSetPwm(UBYTE Pwm); +void dIOCtrlTransfer(void); + +#endif diff --git a/src/d_ioctrl.r b/src/d_ioctrl.r new file mode 100644 index 0000000..1071276 --- /dev/null +++ b/src/d_ioctrl.r @@ -0,0 +1,237 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 7-12-07 14:09 $ +// +// Filename $Workfile:: d_ioctrl.r $ +// +// Version $Revision:: 4 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_ioct $ +// +// Platform C +// + + +#ifdef SAM7S256 + +extern void I2cHandler(void); + +enum +{ + I2C_IDLE = 1, + I2C_ERROR = 2, + I2C_TX = 3, + I2C_RX = 4 +}; + +#define NO_TO_TX BYTES_TO_TX + 1 +#define NO_TO_RX BYTES_TO_RX + 1 +#define TIMEOUT (((OSC/16)/1000)*30) /* 100 ms timeout on I2C*/ +#define I2CCLK 400000L +#define TIME400KHZ (((OSC/16L)/(I2CCLK * 2)) + 1) +#define CLDIV (((OSC/I2CCLK)/2)-3) +#define DEVICE_ADR 0x01 + + +static UBYTE *pIrq; +static UBYTE volatile Cnt; +static UBYTE I2cStatus; +static UBYTE I2cLastStatus; +static UBYTE I2cInBuffer[NO_TO_RX]; +static UBYTE I2cOutBuffer[COPYRIGHTSTRINGLENGTH + 1]; +static UBYTE RxSum; +static ULONG I2CTimerValue; + + +#define DISABLEI2cIrqs *AT91C_TWI_IDR = 0x000001C7 +#define ISSUEStopCond *AT91C_TWI_CR = AT91C_TWI_STOP +#define INSERTPower(Power) IoToAvr.Power = Power +#define INSERTPwm(Pwm) IoToAvr.PwmFreq = Pwm +#define SETTime I2CTimerValue = ((*AT91C_PITC_PIIR) & AT91C_PITC_CPIV) + + +#define DISABLETwi *AT91C_PIOA_PPUDR = (AT91C_PA4_TWCK | AT91C_PA3_TWD);/* no pull up */\ + *AT91C_PIOA_MDER = (AT91C_PA4_TWCK | AT91C_PA3_TWD);/* SCL + SDA is open drain*/\ + *AT91C_PIOA_SODR = (AT91C_PA4_TWCK | AT91C_PA3_TWD);/* SCL + SDA is high */\ + *AT91C_PIOA_OER = (AT91C_PA4_TWCK | AT91C_PA3_TWD);/* SCL + SDA is output */\ + *AT91C_PIOA_PER = (AT91C_PA4_TWCK | AT91C_PA3_TWD);/* Disable peripheal */\ + + +#define STARTIrqTx I2cStatus = I2C_TX;\ + I2cLastStatus = I2C_TX;\ + pIrq = I2cOutBuffer;\ + *AT91C_TWI_CR = AT91C_TWI_MSEN;\ + *AT91C_TWI_MMR = (AT91C_TWI_IADRSZ_NO | (DEVICE_ADR << 16)); /* no int. adr, write dir */\ + *AT91C_TWI_IER = 0x00000104; /* Enable TX related irq */\ + *AT91C_TWI_THR = *pIrq + + +#define WAITClk {\ + ULONG PitTmr;\ + PitTmr = (*AT91C_PITC_PIIR & AT91C_PITC_CPIV) + TIME400KHZ;\ + if (PitTmr >= (*AT91C_PITC_PIMR & AT91C_PITC_CPIV))\ + {\ + PitTmr -= (*AT91C_PITC_PIMR & AT91C_PITC_CPIV);\ + }\ + while ((*AT91C_PITC_PIIR & AT91C_PITC_CPIV) < PitTmr);\ + } + + +#define RESETI2c {\ + UBYTE Tmp;\ + DISABLETwi;\ + Tmp = 0;\ + /* Clock minimum 9 times and both SCK and SDA should be high */\ + while((!(*AT91C_PIOA_PDSR & AT91C_PA3_TWD)) || (Tmp <= 9))\ + {\ + if ((*AT91C_PIOA_PDSR) & AT91C_PA4_TWCK) /* Clk strectching? */\ + {\ + *AT91C_PIOA_CODR = AT91C_PA4_TWCK; /* SCL is low */\ + WAITClk;\ + *AT91C_PIOA_SODR = AT91C_PA4_TWCK; /* SCL is high */\ + WAITClk;\ + Tmp++;\ + }\ + }\ + *AT91C_TWI_CR = AT91C_TWI_MSDIS;\ + *AT91C_TWI_CR = AT91C_TWI_SWRST;\ + *AT91C_PIOA_ASR = (AT91C_PA4_TWCK | AT91C_PA3_TWD); /* Sel. per. A */\ + *AT91C_PIOA_PDR = (AT91C_PA4_TWCK | AT91C_PA3_TWD); /* Sel. per on pins*/\ + } + + +#define IOCTRLInit *AT91C_AIC_IDCR = (1L< +#include + +#define FILEVERSION (0x0000010DL) + +#define MAX_FILES ((FILETABLE_SIZE) - 1) /* Last file entry is used for file version*/ +#define FILEVERSIONINDEX ((FILETABLE_SIZE) - 1) /* Last file entry is used for file version*/ +#define MAX_WRITE_BUFFERS 4 +#define FLASHOFFSET (0x100000L) + +#define IS_LOADER_ERR(LStatus) (((LStatus) & 0xFF00) != SUCCESS) +#define SECTORINDEXUSERFLASH ((STARTOFUSERFLASH & ~FLASHOFFSET)/256/32) +#define SECTORPOINTERUSERFLASH (((STARTOFUSERFLASH & ~FLASHOFFSET) - ((SECTORINDEXUSERFLASH * 32) * 256))/256) + +typedef struct +{ + const UBYTE *pFlash; + const UWORD *pSectorNo; + ULONG ReadLength; + ULONG DataLength; + ULONG FileDlPtr; + UBYTE SearchStr[FILENAME_SIZE]; + UWORD FileIndex; + UWORD CheckSum; + UBYTE SearchType; + UBYTE Status; + UBYTE FileType; + UBYTE WriteBufNo; +}HANDLE; + +typedef struct +{ + ULONG Buf[SECTORSIZE/4]; + UBYTE BufIndex; + UBYTE Status; +}WRITEBUF; + +static HANDLE HandleTable[MAX_HANDLES]; +static WRITEBUF WriteBuffer[MAX_WRITE_BUFFERS]; +static ULONG SectorTable[NOOFSECTORS>>5]; +static FILEHEADER Header; +static ULONG FreeUserFlash; +static UWORD FreeSectors; + +void dLoaderUpdateSectorTable(void); +UWORD dLoaderGetFreeHandle(void); +const UBYTE * dLoaderGetNextSectorPtr(UBYTE Handle); +ULONG dLoaderReturnFreeFlash(void); +UWORD dLoaderAllocateHeader(UWORD Handle, ULONG *FileStartAdr, FILEHEADER *pHeader, UWORD HeaderByteSize, UWORD CompleteFileSectorSize); +UWORD dLoaderFlashFileHeader(UWORD Handle, ULONG FileStartAdr, FILEHEADER *pHeader, UWORD HeaderByteSize); +UWORD dLoaderFindFirstSector(UBYTE Type, UWORD SectorCount, UWORD *pSector); +UWORD dLoaderAllocateWriteBuffer(UWORD Handle); +UWORD dLoaderSetFilePointer(UWORD Handle, ULONG BytePtr, const UBYTE **pData); +UWORD dLoaderGetSectorNumber(ULONG Adr); +void dLoaderCheckVersion(void); +UWORD dLoaderCheckHandle(UWORD Handle, UBYTE Operation); +ULONG dLoaderCalcFreeFileSpace(UWORD NosOfFreeSectors); +UWORD dLoaderCheckDownload(UBYTE *pName); +UWORD dLoaderAvailFileNo(void); + + +void dLoaderInit(void) +{ + UWORD Tmp; + + LOADERInit; + + /* Clear handle table */ + for (Tmp = 0; Tmp < MAX_HANDLES; Tmp++) + { + HandleTable[Tmp].Status = FREE; + HandleTable[Tmp].WriteBufNo = FREEBUFNO; + } + + /* Clear write buffers */ + for (Tmp = 0; Tmp < MAX_WRITE_BUFFERS; Tmp++) + { + WriteBuffer[Tmp].Status = FREE; + } + + dLoaderCheckVersion(); + dLoaderUpdateSectorTable(); +} + + +UWORD dLoaderAvailFileNo(void) +{ + UBYTE Tmp, Tmp2; + UWORD ReturnVal; + + ReturnVal = NOMOREFILES; + Tmp2 = 0; + for(Tmp = 0; Tmp < MAX_HANDLES; Tmp++) + { + + /* Check for files allready downloading except datafiles as the have entered their */ + /* filepointer in the filepointer table at begin of download */ + if ((DOWNLOADING == HandleTable[Tmp].Status) && (DATAFILE != HandleTable[Tmp].FileType)) + { + Tmp2++; + } + } + if ((0xFFFFFFFF == FILEPTRTABLE[(MAX_FILES - 1) - Tmp2]) || (0 == FILEPTRTABLE[(MAX_FILES - 1) - Tmp2])) + { + ReturnVal = SUCCESS; + } + return(ReturnVal); +} + + +void dLoaderWriteFilePtrTable(ULONG *RamFilePtrTable) +{ + UWORD TmpTableSize; + + /* FILETABLE_SIZE is in LONG */ + TmpTableSize = (FILETABLE_SIZE * 4); + while(TmpTableSize) + { + TmpTableSize -= SECTORSIZE; + dLoaderWritePage((ULONG)FILEPTRTABLE + TmpTableSize, SECTORSIZE, RamFilePtrTable + (TmpTableSize/4)); + } +} + + +UWORD dLoaderInsertPtrTable(const UBYTE *pAdr, UWORD Handle) +{ + UWORD TmpCnt; + UWORD Status; + ULONG PtrTable[FILETABLE_SIZE]; + + /* It is possible to add the file as checking for number of files */ + /* is done when initiating the file download */ + memset(PtrTable, 0, sizeof(PtrTable)); + TmpCnt = MAX_FILES - 1; + while(TmpCnt) + { + + /* TmpCnt-- first because you want to copy from index 0 */ + TmpCnt--; + PtrTable[TmpCnt + 1] = FILEPTRTABLE[TmpCnt]; + } + + /* Copy the new file in position 0 */ + PtrTable[0] = (ULONG)pAdr; + + /* Add the File version to the top of the file list */ + PtrTable[FILEVERSIONINDEX] = FILEPTRTABLE[FILEVERSIONINDEX]; + + /* Write the file pointer table to flash */ + dLoaderWriteFilePtrTable(PtrTable); + + /* FileIndex in HandleTable should be incremented by one - new file index is 0 */ + for (TmpCnt = 0; TmpCnt < MAX_HANDLES; TmpCnt++) + { + if (HandleTable[TmpCnt].Status != FREE) + { + (HandleTable[TmpCnt].FileIndex)++; + } + } + HandleTable[Handle].FileIndex = 0; + Status = SUCCESS | Handle; + + return(Status); +} + + +UWORD dLoaderDeleteFilePtr(UWORD Handle) +{ + UWORD ErrorCode; + UWORD LongCnt; + ULONG PtrTable[FILETABLE_SIZE]; + + ErrorCode = SUCCESS; + if (0xFFFFFFFF != FILEPTRTABLE[HandleTable[Handle].FileIndex]) + { + ErrorCode = dLoaderCheckFiles(Handle); + if (0x8000 > ErrorCode) + { + for (LongCnt = 0; LongCnt < (HandleTable[Handle].FileIndex); LongCnt++) + { + PtrTable[LongCnt] = FILEPTRTABLE[LongCnt]; + } + + /* Skip the file that has to be deleted "LongCnt + 1" */ + for ( ; LongCnt < (MAX_FILES - 1); LongCnt++) + { + PtrTable[LongCnt] = FILEPTRTABLE[LongCnt+1]; + } + + /* The top file entry is now free */ + PtrTable[MAX_FILES - 1] = 0xFFFFFFFF; + + /* Insert the file version */ + PtrTable[MAX_FILES] = FILEPTRTABLE[MAX_FILES]; + + /* Write the file pointer table back into flash */ + dLoaderWriteFilePtrTable(PtrTable); + dLoaderUpdateSectorTable(); + + /* Update the HandleTable[].FileIndex */ + for (LongCnt = 0; LongCnt < MAX_HANDLES; LongCnt++) + { + + /* FileIndex must not be decremented for to the file to be deleted (when Handle = LongCnt)*/ + if ((HandleTable[Handle].FileIndex < HandleTable[LongCnt].FileIndex) && (FREE != HandleTable[LongCnt].Status)) + { + (HandleTable[LongCnt].FileIndex)--; + } + } + } + } + else + { + ErrorCode = FILENOTFOUND; + } + return(ErrorCode | Handle); +} + + +void dLoaderDeleteAllFiles(void) +{ + ULONG Tmp; + ULONG PtrTable[FILETABLE_SIZE]; + + /* Close all handles - all files is to be wiped out */ + for (Tmp = 0; Tmp < MAX_HANDLES; Tmp++) + { + dLoaderCloseHandle(Tmp); + } + + for (Tmp = ((STARTOFUSERFLASH-FLASHOFFSET)/SECTORSIZE); Tmp < (SIZEOFFLASH/SECTORSIZE); Tmp++) + { + dLoaderErasePage(Tmp<>5] |= (0x1 << (SectorNo & 0x001F)); + Tmp += (SECTORSIZE >> 2); + } + + for (Tmp = 0; Tmp < MAX_FILES; Tmp++) + { + if ((0xFFFFFFFF != FILEPTRTABLE[Tmp]) && (0x00000000 != FILEPTRTABLE[Tmp])) + { + pFile = (const FILEHEADER *) FILEPTRTABLE[Tmp]; + + /* This is necessary if the start address is at the first address in an sector */ + SectorNo = dLoaderGetSectorNumber((ULONG)pFile->FileStartAdr); + SectorTable[SectorNo>>5] |= (0x1 << (SectorNo & 0x001F)); + + /* This is necessary as the first sector (where the fileheader is) is not */ + /* included in the sector table */ + SectorNo = dLoaderGetSectorNumber((ULONG)FILEPTRTABLE[Tmp]); + SectorTable[SectorNo>>5] |= (0x1 << (SectorNo & 0x001F)); + + /* First Sector with data has been allocated add this as the initial */ + /* file size */ + FileSize = SECTORSIZE - ((pFile->FileStartAdr) & (SECTORSIZE-1)) ; + pSectorTable = pFile->FileSectorTable; + while((FileSize < (pFile->FileSize)) && (NOOFSECTORS > (*pSectorTable))) + { + SectorTable[(*pSectorTable)>>5] |= (0x1 << ((*pSectorTable) & 0x1F)); + if (0 == ((ULONG)(pSectorTable + 1) & (SECTORSIZE-1))) + { + pSectorTable = (UWORD*)(((ULONG)(*pSectorTable) << SECTORSIZESHIFT) | FLASHOFFSET); + } + else + { + *pSectorTable++; + FileSize += SECTORSIZE; + } + } + } + } + FreeUserFlash = dLoaderReturnFreeFlash(); +} + + +UWORD dLoaderCreateFileHeader(ULONG FileSize, UBYTE *pName, UBYTE LinearState, UBYTE FileType) +{ + UWORD HeaderByteSize; + ULONG FileStartAdr; + ULONG CompleteFileByteSize; + UWORD Handle; + UBYTE Name[FILENAME_SIZE]; + ULONG FileLength; + ULONG DataLength; + UWORD ErrorCode; + UWORD CompleteSectorNo; + UWORD Tmp; + + memset(&(Header.FileName), 0, sizeof(Header.FileName)); + memset(&(Header.FileSectorTable), 0xFF, sizeof(Header.FileSectorTable)); + + ErrorCode = dLoaderFind(pName, Name, &FileLength, &DataLength, (UBYTE)BUSY); + Handle = ErrorCode & 0x00FF; + if (SUCCESS == (ErrorCode & 0xFF00)) + { + ErrorCode |= FILEEXISTS; + } + if (FILENOTFOUND == (ErrorCode & 0xFF00)) + { + + /* Here check for the download buffers for a matching download */ + /* in progress */ + ErrorCode &= 0x00FF; + ErrorCode = dLoaderCheckDownload(pName); + + if (0x8000 > ErrorCode) + { + + /* Check for file overflow */ + ErrorCode = dLoaderAvailFileNo(); + if (0x8000 > ErrorCode) + { + + ErrorCode = dLoaderAllocateWriteBuffer(Handle); + if (0x8000 > ErrorCode) + { + + dLoaderCopyFileName((Header.FileName), pName); + HandleTable[Handle].pSectorNo = 0; + HandleTable[Handle].DataLength = FileSize; /* used for end of file detection */ + Header.FileSize = FileSize; /* used to program into flash */ + if (DATAFILE == FileType) + { + Header.DataSize = 0; + } + else + { + Header.DataSize = FileSize; + } + HandleTable[Handle].FileType = FileType | LinearState; /* if it is a datafile it can be stopped */ + Header.FileType = FileType | LinearState; /* FileType included for future appending */ + + /* File body size calculation*/ + CompleteFileByteSize = FileSize; + + /* Add the the fixed header to the fixed size */ + CompleteFileByteSize += HEADERFIXEDSIZE; + + /* Find the number of sectors used by the fixed file size */ + CompleteSectorNo = (CompleteFileByteSize - 1) >> SECTORSIZESHIFT; + + /* Add the size taken by the sectortable */ + CompleteFileByteSize += (CompleteSectorNo << 1); + + /* Recalc the number of sectors - to see wether the sectortable has caused */ + /* the sectornumber to encrease */ + Tmp = ((CompleteFileByteSize - 1) >> SECTORSIZESHIFT); + + /* Substract from the original sectors used - Tmp holds the encreased number*/ + Tmp -= CompleteSectorNo; + if (Tmp) + { + /* The sectortable takes up more than one sector */ + CompleteFileByteSize += Tmp << 1; + CompleteSectorNo += Tmp; + } + + HeaderByteSize = CompleteFileByteSize - FileSize; + + if (HeaderByteSize & 0x0003) + { + /* Header size is not a multiplum of 4 - now make it a mul 4 */ + HeaderByteSize += (0x0004 - (HeaderByteSize & 0x0003)); + } + + if (FileSize <= FreeUserFlash) + { + + /* Allocate file header */ + Tmp = (((CompleteFileByteSize - 1) >> SECTORSIZESHIFT) + 1); + Handle = dLoaderAllocateHeader(Handle, &FileStartAdr, &Header, HeaderByteSize, Tmp); + if (Handle < 0x8000) + { + dLoaderFlashFileHeader(Handle, FileStartAdr, &Header, HeaderByteSize); + + /* If this is a datafile then add the filepointer to the filepointer table */ + /* now as the datafile do not need to have a special size to be valid */ + if (DATAFILE & HandleTable[Handle].FileType) + { + ErrorCode = dLoaderInsertPtrTable((const UBYTE *)HandleTable[Handle].FileDlPtr, Handle); + } + FreeSectors -= Tmp; + FreeUserFlash = dLoaderCalcFreeFileSpace(FreeSectors); + HandleTable[Handle].Status = DOWNLOADING; + } + } + else + { + ErrorCode = NOSPACE; + } + } + } + } + } + + return(ErrorCode | Handle); +} + + +UWORD dLoaderWriteData(UWORD Handle, UBYTE *pBuf, UWORD *pLen) +{ + UWORD Tmp; + UBYTE *pSectorBuf; + + Handle = dLoaderCheckHandle(Handle, DOWNLOADING); + if (0x8000 > Handle) + { + + if (*pLen > HandleTable[Handle].DataLength) + { + + /* Write request exceeds filesize - only flash up to filesize*/ + *pLen = HandleTable[Handle].DataLength; + WriteBuffer[HandleTable[Handle].WriteBufNo].Status = DLERROR; /* save error untill close handle */ + } + + pSectorBuf = (UBYTE *)WriteBuffer[HandleTable[Handle].WriteBufNo].Buf; + for(Tmp = 0; Tmp < *pLen; Tmp++) + { + pSectorBuf[WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex] = pBuf[Tmp]; + if ((WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex) >= (SECTORSIZE-1)) + { + dLoaderWritePage(((ULONG)HandleTable[Handle].pFlash & ~(SECTORSIZE - 1)), SECTORSIZE, WriteBuffer[HandleTable[Handle].WriteBufNo].Buf); + WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex = 0; + HandleTable[Handle].pFlash = dLoaderGetNextSectorPtr(Handle); + memset(WriteBuffer[HandleTable[Handle].WriteBufNo].Buf, 0xFF, sizeof(WriteBuffer[0].Buf)); + } + else + { + (WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex)++; + } + } + HandleTable[Handle].DataLength -= *pLen; + + /* Check for correct end of file */ + if (0 == HandleTable[Handle].DataLength) + { + if ((WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex) != 0) + { + + /* write the last data into the file */ + dLoaderWritePage(((ULONG)HandleTable[Handle].pFlash & ~(SECTORSIZE - 1)), WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex, WriteBuffer[HandleTable[Handle].WriteBufNo].Buf); + WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex = 0; + } + } + } + else + { + *pLen = 0; + } + + if (DLERROR == WriteBuffer[HandleTable[Handle].WriteBufNo].Status) + { + + /* DLERROR set due to over flow a file - EOFEXSPECTED should be set */ + /* for repeated overflow requests */ + Handle |= EOFEXSPECTED; + } + return(Handle); +} + + +UWORD dLoaderGetFreeHandle(void) +{ + UBYTE Tmp; + UWORD Handle; + + Handle = NOMOREHANDLES; + for(Tmp = 0; Tmp < MAX_HANDLES; Tmp++) + { + if (FREE == HandleTable[Tmp].Status) + { + HandleTable[Tmp].Status = BUSY; + Handle = 0; /* Clear NOMOREHANDLES */ + Handle = Tmp; + Tmp = MAX_HANDLES; + } + } + return(Handle); +} + +const UBYTE * dLoaderGetNextSectorPtr(UBYTE Handle) +{ + const UBYTE *pAdr; + + /* Check for the last entry in a sector - if so, */ + /* then this is the sector number on the next sector table */ + if (!((ULONG)(HandleTable[Handle].pSectorNo + 1) & (SECTORSIZE-1))) + { + HandleTable[Handle].pSectorNo = (const UWORD *)(((ULONG)(*(HandleTable[Handle].pSectorNo)) << SECTORSIZESHIFT) | FLASHOFFSET); + } + + /* If pointing at an illegal adr then set it to NULL */ + if (SIZEOFFLASH < (ULONG)((ULONG)(HandleTable[Handle].pSectorNo) & ~FLASHOFFSET)) + { + pAdr = NULL; + } + else + { + pAdr = (const UBYTE *)(((ULONG)(*(HandleTable[Handle].pSectorNo)) << SECTORSIZESHIFT) | FLASHOFFSET); + } + + (HandleTable[Handle].pSectorNo)++; + return(pAdr); +} + +UWORD dLoaderCloseHandle(UWORD Handle) +{ + UWORD RtnStatus; + FILEHEADER *TmpFileHeader; + + RtnStatus = Handle; + + /* if it is a normal handle or handle closed due to an error then error must be different */ + /* from the no more handles available error (else you would delete a used handle) */ + if (((0x8000 > Handle) || (NOMOREHANDLES != (Handle & 0xFF00))) && ((UBYTE)Handle < MAX_HANDLES)) + { + Handle &= 0x00FF; + if (FREE == HandleTable[Handle].Status) + { + RtnStatus |= HANDLEALREADYCLOSED; + } + else + { + + /* Handle was NOT free - now close it */ + if (DOWNLOADING == HandleTable[Handle].Status) + { + if (DATAFILE & HandleTable[Handle].FileType) + { + + /* This is a Datafile that should be closed and this is a legal action */ + /* 1. Write the data from the writebuffer into flash */ + /* 2. Update the Datalength in the file header */ + /* This takes minimum 8 mS (2 page writes into flash) */ + + if (WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex) + { + + /* There are databytes in the writebuffer write them into flash */ + dLoaderWritePage(((ULONG)HandleTable[Handle].pFlash & ~(SECTORSIZE - 1)), WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex, WriteBuffer[HandleTable[Handle].WriteBufNo].Buf); + } + + /* Now the databuffer is free now use if for a buffer for the fileheader*/ + memcpy(WriteBuffer[HandleTable[Handle].WriteBufNo].Buf, (void const*)HandleTable[Handle].FileDlPtr, SECTORSIZE); + TmpFileHeader = (FILEHEADER *) WriteBuffer[HandleTable[Handle].WriteBufNo].Buf; + TmpFileHeader->DataSize = TmpFileHeader->FileSize - HandleTable[Handle].DataLength; + dLoaderWritePage(((ULONG)HandleTable[Handle].FileDlPtr & ~(SECTORSIZE - 1)), SECTORSIZE, WriteBuffer[HandleTable[Handle].WriteBufNo].Buf); + } + else + { + + /* This is a system file being closed now update the file pointer table if no error and complete file written */ + if ((DLERROR != WriteBuffer[HandleTable[Handle].WriteBufNo].Status) && (0 == HandleTable[Handle].DataLength)) + { + + /* no error durig download - add the file pointer to the file pointer table */ + Handle = dLoaderInsertPtrTable((const UBYTE *) HandleTable[Handle].FileDlPtr, Handle); + } + else + { + + /* an error has occured during download - now clean up the mess... */ + dLoaderUpdateSectorTable(); + } + } + } + if (HandleTable[Handle].WriteBufNo != FREEBUFNO) + { + WriteBuffer[HandleTable[Handle].WriteBufNo].Status = FREE; + HandleTable[Handle].WriteBufNo = FREEBUFNO; + } + HandleTable[Handle].Status = FREE; + } + } + return(RtnStatus); +} + + +UWORD dLoaderOpenRead(UBYTE *pFileName, ULONG *pLength) +{ + UWORD Handle; + UBYTE Name[16]; + const FILEHEADER *TmpHeader; + ULONG FileLength; + ULONG DataLength; + + Handle = dLoaderFind(pFileName, Name, &FileLength, &DataLength, (UBYTE)BUSY); + if (0x8000 > Handle) + { + if (FileLength) + { + TmpHeader = (FILEHEADER const *)(FILEPTRTABLE[HandleTable[Handle].FileIndex]); + HandleTable[Handle].pFlash = (const UBYTE *)TmpHeader->FileStartAdr; + HandleTable[Handle].pSectorNo = TmpHeader->FileSectorTable; + HandleTable[Handle].DataLength = TmpHeader->DataSize; + HandleTable[Handle].ReadLength = 0; + *pLength = TmpHeader->DataSize; + } + else + { + Handle = FILENOTFOUND; + } + } + return(Handle); +} + +UWORD dLoaderRead(UBYTE Handle, UBYTE *pBuffer, ULONG *pLength) +{ + UWORD ByteCnt, Status; + + Status = dLoaderCheckHandle(Handle, BUSY); + if (0x8000 > Status) + { + Status = Handle; + ByteCnt = 0; + while (ByteCnt < *pLength) + { + if (HandleTable[Handle].DataLength <= HandleTable[Handle].ReadLength) + { + *pLength = ByteCnt; + Status |= ENDOFFILE; + } + else + { + *pBuffer = *(HandleTable[Handle].pFlash); + pBuffer++; + ByteCnt++; + HandleTable[Handle].pFlash++; + HandleTable[Handle].ReadLength++; + if (!((ULONG)(HandleTable[Handle].pFlash) & (SECTORSIZE-1))) + { + HandleTable[Handle].pFlash = dLoaderGetNextSectorPtr(Handle); + } + } + } + } + return(Status); +} + +UWORD dLoaderDelete(UBYTE *pFile) +{ + UWORD LStatus; + ULONG FileLength; + ULONG DataLength; + UBYTE Name[FILENAME_LENGTH + 1]; + + LStatus = dLoaderFind(pFile, Name, &FileLength, &DataLength, (UBYTE)BUSY); + + if (!IS_LOADER_ERR(LStatus)) + { + LStatus = dLoaderDeleteFilePtr((UBYTE)LStatus); + } + + dLoaderCloseHandle(LStatus); + + return(LStatus); +} + +UWORD dLoaderFind(UBYTE *pFind, UBYTE *pFound, ULONG *pFileLength, ULONG *pDataLength, UBYTE Session) +{ + UWORD Handle; + + Handle = dLoaderGetFreeHandle(); + if (Handle < 0x8000) + { + if (FILENAME_LENGTH < strlen((const char*)pFind)) + { + Handle |= ILLEGALFILENAME; + } + else + { + HandleTable[Handle].FileIndex = 0xFFFF; + HandleTable[Handle].Status = Session; + dLoaderInsertSearchStr((HandleTable[Handle].SearchStr), pFind, &(HandleTable[Handle].SearchType)); + Handle = dLoaderFindNext(Handle, pFound, pFileLength, pDataLength); + } + } + + return(Handle); +} + +UWORD dLoaderFindNext(UWORD Handle, UBYTE *pFound, ULONG *pFileLength, ULONG *pDataLength) +{ + UBYTE Tmp; + UWORD ReturnVal; + FILEHEADER *pHeader; + + *pFileLength = 0; + ReturnVal = Handle | FILENOTFOUND; + + + for (Tmp = ((HandleTable[Handle].FileIndex) + 1); Tmp < MAX_FILES; Tmp++) + { + if (0xFFFFFFFF != FILEPTRTABLE[Tmp]) + { + if (SUCCESS == dLoaderCheckName((UBYTE*)FILEPTRTABLE[Tmp], HandleTable[Handle].SearchStr, HandleTable[Handle].SearchType)) + { + HandleTable[Handle].FileIndex = Tmp; + Tmp = MAX_FILES; + ReturnVal = Handle; + } + } + } + if (0x8000 > ReturnVal) + { + pHeader = (FILEHEADER *)FILEPTRTABLE[HandleTable[Handle].FileIndex]; + if (NULL != pFileLength) + { + *pFileLength = pHeader->FileSize; + } + if (NULL != pDataLength) + { + *pDataLength = pHeader->DataSize; + } + if (NULL != pFound) + { + dLoaderCopyFileName(pFound, (UBYTE *)pHeader->FileName); + } + } + return(ReturnVal); +} + + +ULONG dLoaderReturnFreeFlash(void) +{ + ULONG SectorCnt, IndexPtr; + UWORD Sectors; + + + Sectors = 0; + IndexPtr = (ULONG)0x01 << SECTORPOINTERUSERFLASH; /* Offset in first index can be different from 0 */ + for(SectorCnt = SECTORINDEXUSERFLASH; SectorCnt <= ((NOOFSECTORS>>5)-1); SectorCnt++) + { + for( ; IndexPtr > 0; IndexPtr<<=1) + { + if (!(SectorTable[SectorCnt] & IndexPtr)) + { + Sectors++; + } + } + IndexPtr = 0x00000001; + } + + FreeSectors = Sectors; + return(dLoaderCalcFreeFileSpace(Sectors)); +} + +ULONG dLoaderCalcFreeFileSpace(UWORD NosOfFreeSectors) +{ + UWORD SectorCnt; + ULONG Space; + ULONG HeaderSpace; + + /* Calculate only if any sectors available */ + if (NosOfFreeSectors) + { + + Space = (ULONG)NosOfFreeSectors << SECTORSIZESHIFT; + + /* (FreeSectors - 1) is beacuse the the first sector of a file do not */ + /* require an entry in the sector table - it is pointed to by the filepointer */ + /* in the file pointer table*/ + SectorCnt = NosOfFreeSectors - 1; + + /* If more that one sector is used for the header the first filebody sector do not */ + /* require an entry in the sectortable - it is pointed to by the file startpointer */ + /* in the file header */ + if ((((SectorCnt<<1) + HEADERFIXEDSIZE) & (SECTORSIZE - 1)) < 4) + { + SectorCnt--; + } + + HeaderSpace = (HEADERFIXEDSIZE + (SectorCnt << 1)); + if (HeaderSpace & 0x0003) + { + /* Header size is not a multiplum of 4 - now make it a mul 4 */ + HeaderSpace += (0x0004 - (HeaderSpace & 0x0003)); + } + Space -= HeaderSpace; + } + return(Space); +} + + +UWORD dLoaderGetFilePtr(UBYTE *pFileName, UBYTE *pPtrToFile, ULONG *pFileLength) +{ + UWORD RtnVal; + UBYTE FoundFile[16]; + FILEHEADER *File; + ULONG DataLength; + + + RtnVal = dLoaderFind(pFileName, FoundFile, pFileLength, &DataLength, (UBYTE)BUSY); + if (0x8000 > RtnVal) + { + + File = (FILEHEADER*) FILEPTRTABLE[HandleTable[RtnVal].FileIndex]; + if (LINEAR & File->FileType) + { + *((ULONG*)pPtrToFile) = File->FileStartAdr; + } + else + { + RtnVal |= NOTLINEARFILE; + } + } + return(RtnVal); +} + +UWORD dLoaderAllocateHeader(UWORD Handle, ULONG *FileStartAdr, FILEHEADER *pHeader, UWORD HeaderByteSize, UWORD CompleteFileSectorSize) +{ + UWORD Tmp; + UWORD SectorTableIndex; + ULONG SectorIndex; + UWORD HeaderSectorSize; + UBYTE EvenHeader; + UWORD FileBodySectorSize; + UWORD ErrorCode; + + HeaderSectorSize = ((HeaderByteSize - 1) >> SECTORSIZESHIFT) + 1; + FileBodySectorSize = (((pHeader->FileSize - (SECTORSIZE - (HeaderByteSize & (SECTORSIZE - 1)))) - 1) >> SECTORSIZESHIFT) + 1; + + /* First allocate the file file header - this means the file name, */ + /* the file start adress, and the sector table */ + + /* SectorTableIndex indicates in the last word of a sector in which */ + /* sector the sectortable continues */ + SectorTableIndex = ((SECTORSIZE - HEADERFIXEDSIZE)>>1) - 1; + + /* Find first free sector - here there is a differende between linear or not*/ + ErrorCode = dLoaderFindFirstSector(pHeader->FileType, CompleteFileSectorSize, &Tmp); + + if (SUCCESS == ErrorCode) + { + *FileStartAdr = (ULONG)((ULONG)Tmp << SECTORSIZESHIFT) | FLASHOFFSET; + HandleTable[Handle].FileDlPtr = *FileStartAdr; + + SectorIndex = (Tmp >> 5); + Tmp &= 0x1F; + + SectorTable[SectorIndex]|= (0x01<FileStartAdr = (ULONG)(*FileStartAdr) + HeaderByteSize; + + /* if there is a sectortable it always starts right after the fixed header (Name + start + size)*/ + HandleTable[Handle].pSectorNo = (const UWORD *)(*FileStartAdr + HEADERFIXEDSIZE); + + /* First header has been allocated by find first function */ + HeaderSectorSize--; + UWORD TmpHSS = HeaderSectorSize; + + /* Next part is only executed when more than one sector is used */ + if (HeaderSectorSize) + { + UBYTE ExitCode = FALSE; + + while ((FALSE == ExitCode) && (SectorIndex < (NOOFSECTORS/32))) + { + for(; ((Tmp < 32) && (ExitCode == FALSE)); Tmp++) + { + if (!(SectorTable[SectorIndex] & (0x01<FileSectorTable[SectorTableIndex] = (SectorIndex << 5) + Tmp; + SectorTableIndex += (SECTORSIZE/2); + HeaderSectorSize--; + if (0 == HeaderSectorSize) + { + pHeader->FileStartAdr = (((SectorIndex << 5) + Tmp) << SECTORSIZESHIFT) + (HeaderByteSize - (TmpHSS<= (SECTORSIZE - 2)) || (0 == (HeaderByteSize & (SECTORSIZE - 1)))) + { + + /* The header uses exact one or several sectors */ + /* meaning that the next sector do not go into */ + /* the sectortable as it is pointed to by the */ + /* FileStart pointer */ + EvenHeader = TRUE; + } + + /* Now allocated the file body */ + SectorTableIndex = 0; + while ((FileBodySectorSize > 0) && (SectorIndex < (NOOFSECTORS/32))) + { + for(; Tmp < 32; Tmp++) + { + if (!(SectorTable[SectorIndex] & (0x01<FileStartAdr = (((SectorIndex << 5) + Tmp) << SECTORSIZESHIFT) | FLASHOFFSET; + EvenHeader = FALSE; + } + else + { + + /* Sector is free you can have this one */ + SectorTable[SectorIndex] |= (0x01<>1)-1) == SectorTableIndex) || (((SectorTableIndex - ((SECTORSIZE - HEADERFIXEDSIZE)>>1)) & 0x7F) == 127)) + { + SectorTableIndex++; + } + pHeader->FileSectorTable[SectorTableIndex] = (SectorIndex << 5) + Tmp; + SectorTableIndex++; + FileBodySectorSize--; + if (0 == FileBodySectorSize) + { + Tmp = 32; + SectorIndex = (NOOFSECTORS/32); + } + } + } + } + SectorIndex++; + Tmp = 0; + } + } + else + { + Handle |= ErrorCode; + } + return(Handle); +} + + +UWORD dLoaderFindFirstSector(UBYTE Type, UWORD SectorCount, UWORD *pSector) +{ + UWORD CompleteSectorSize; + UWORD SectorIndex; + UBYTE Tmp; + UWORD SectorCnt; + UWORD ErrorCode; + + + ErrorCode = SUCCESS; + + SectorIndex = SECTORINDEXUSERFLASH; + Tmp = SECTORPOINTERUSERFLASH; + + + + if (LINEAR & Type) + { + CompleteSectorSize = SectorCount; + ErrorCode = NOLINEARSPACE; + + /* find linear adress space */ + SectorCnt = CompleteSectorSize; + + while ((SectorCnt > 0) && (SectorIndex < (NOOFSECTORS>>5))) + { + if ((SectorTable[SectorIndex]) & ((ULONG)0x01<>5); + ErrorCode = SUCCESS; + } + } + + if (0x1F == Tmp) + { + SectorIndex++; + } + Tmp = (Tmp + 1) & 0x1F; + } + } + else + { + ErrorCode = UNDEFINEDERROR; + while(SectorIndex < (NOOFSECTORS>>5)) + { + if (!((SectorTable[SectorIndex]) & ((ULONG)0x01<>5); + ErrorCode = SUCCESS; + } + if (0x1F == Tmp) + { + SectorIndex++; + } + Tmp = (Tmp + 1) & 0x1F; + } + } + return(ErrorCode); +} + + +UWORD dLoaderFlashFileHeader(UWORD Handle, ULONG FileStartAdr, FILEHEADER *pHeader, UWORD HeaderByteSize) +{ + ULONG *pBufPtr; + ULONG FlashPtr; + UWORD HeaderSectorSize; + + pBufPtr = (ULONG*)pHeader; + FlashPtr = FileStartAdr; + HeaderSectorSize = (HeaderByteSize - 1) >> SECTORSIZESHIFT; + + dLoaderWritePage(FlashPtr, SECTORSIZE, pBufPtr); + + while(HeaderSectorSize) + { + pBufPtr += (SECTORSIZE>>2); + FlashPtr = (((*(pBufPtr - 1) & 0xFFFF0000) >> 16) << SECTORSIZESHIFT) | FLASHOFFSET; + dLoaderWritePage(FlashPtr, SECTORSIZE, pBufPtr); + HeaderSectorSize--; + } + + /* Prepare for actual data download */ + memcpy(WriteBuffer[HandleTable[Handle].WriteBufNo].Buf, pBufPtr, SECTORSIZE); + WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex = (UWORD)(pHeader->FileStartAdr) & (SECTORSIZE-1); + HandleTable[Handle].pFlash = (UBYTE *)pHeader->FileStartAdr; + + return(Handle); +} + + +UWORD dLoaderGetSectorNumber(ULONG Adr) +{ + UWORD SectorNo; + + SectorNo = (Adr & ~FLASHOFFSET)>>SECTORSIZESHIFT; + + return(SectorNo); +} + + +UWORD dLoaderAllocateWriteBuffer(UWORD Handle) +{ + UBYTE Tmp; + UWORD ErrorCode; + + ErrorCode = NOWRITEBUFFERS; + for (Tmp = 0; Tmp < MAX_WRITE_BUFFERS; Tmp++) + { + if (FREE == WriteBuffer[Tmp].Status) + { + WriteBuffer[Tmp].Status = BUSY; + memset(WriteBuffer[Tmp].Buf, 0xFF, sizeof(WriteBuffer[Tmp].Buf)); + WriteBuffer[Tmp].BufIndex = 0; + HandleTable[Handle].WriteBufNo = Tmp; + ErrorCode = SUCCESS; + Tmp = MAX_WRITE_BUFFERS; + } + } + Handle |= ErrorCode; + return(Handle); +} + +UWORD dLoaderCheckFiles(UBYTE Handle) +{ + UBYTE Tmp; + UBYTE Index; + UWORD ErrorCode; + + ErrorCode = SUCCESS; + Index = HandleTable[Handle].FileIndex; + for (Tmp = 0; Tmp < MAX_HANDLES; Tmp++) + { + if (((BUSY == HandleTable[Tmp].Status) || (DOWNLOADING == HandleTable[Tmp].Status)) && (Index == HandleTable[Tmp].FileIndex) && (Tmp != Handle)) + { + ErrorCode = FILEISBUSY; + } + } + return(Handle | ErrorCode); +} + + +void dLoaderCopyFileName(UBYTE *pDst, UBYTE *pSrc) +{ + UBYTE Tmp; + + for(Tmp = 0; Tmp < FILENAME_SIZE; Tmp++, pDst++) + { + if ('\0' != *pSrc) + { + *pDst = *pSrc; + pSrc++; + } + else + { + *pDst = '\0'; + } + } +} + + +void dLoaderCheckVersion(void) +{ + if (FILEPTRTABLE[FILEVERSIONINDEX] != FILEVERSION) + { + dLoaderDeleteAllFiles(); + } +} + + +UWORD dLoaderOpenAppend(UBYTE *pFileName, ULONG *pAvailSize) +{ + UWORD Handle; + ULONG FileSize, DataSize; + UBYTE Name[FILENAME_SIZE]; + FILEHEADER *pHeader; + + *pAvailSize = 0; + + Handle = dLoaderFind(pFileName, Name, &FileSize, &DataSize, (UBYTE)BUSY); + if (0x8000 > Handle) + { + + /* Check for an append in progress for this file */ + if (0x8000 > dLoaderCheckDownload(pFileName)) + { + + /* File has bee found - check for then correct filetype (Datafile) */ + pHeader = (FILEHEADER *)FILEPTRTABLE[HandleTable[Handle].FileIndex]; + if (DATAFILE & pHeader->FileType) + { + if (FileSize > DataSize) + { + /* Append is possible */ + Handle = dLoaderAllocateWriteBuffer(Handle); + if (Handle < 0x8000) + { + dLoaderSetFilePointer(Handle, DataSize, &(HandleTable[Handle].pFlash)); + WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex = (ULONG)(HandleTable[Handle].pFlash) & (SECTORSIZE - 1); + memcpy(WriteBuffer[HandleTable[Handle].WriteBufNo].Buf, (const UBYTE *)((ULONG)(HandleTable[Handle].pFlash) & ~(SECTORSIZE - 1)), WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex ); + HandleTable[Handle].FileDlPtr = FILEPTRTABLE[HandleTable[Handle].FileIndex]; + HandleTable[Handle].Status = (UBYTE)DOWNLOADING; + *pAvailSize = FileSize - DataSize; + HandleTable[Handle].DataLength = *pAvailSize; + HandleTable[Handle].FileType = pHeader->FileType; + } + } + else + { + Handle |= FILEISFULL; + } + } + else + { + Handle |= APPENDNOTPOSSIBLE; + } + } + else + { + Handle |= FILEISBUSY; + } + } + + return(Handle); +} + + +UWORD dLoaderSetFilePointer(UWORD Handle, ULONG BytePtr, const UBYTE **pData) +{ + ULONG AdrOffset; + const UBYTE *Adr; + UWORD SectorNo; + UWORD Tmp; + FILEHEADER *pHeader; + + + pData = pData; + pHeader = (FILEHEADER*)FILEPTRTABLE[HandleTable[Handle].FileIndex]; + HandleTable[Handle].pSectorNo = pHeader->FileSectorTable; + + /* Get the sector offset */ + AdrOffset = SECTORSIZE - ((pHeader->FileStartAdr) & (SECTORSIZE - 1)); + + if (BytePtr > AdrOffset) + { + BytePtr = BytePtr - AdrOffset; + SectorNo = ((BytePtr >> SECTORSIZESHIFT) + 1); + + for (Tmp = 0; Tmp < SectorNo; Tmp++) + { + Adr = dLoaderGetNextSectorPtr(Handle); + if (BytePtr > SECTORSIZE) + { + BytePtr -= SECTORSIZE; + } + } + *pData = (const UBYTE *)((ULONG)Adr + BytePtr); + } + else + { + + /* Pointer reside in the first sector of the file body */ + *pData = (const UBYTE *)((ULONG)(pHeader->FileStartAdr) + BytePtr); + } + return(Handle); +} + +void dLoaderCpyToLower(UBYTE *pDst, UBYTE *pSrc, UBYTE Length) +{ + UBYTE Tmp; + + for(Tmp = 0; Tmp < Length; Tmp++) + { + pDst[Tmp] =(UBYTE)toupper((UWORD)pSrc[Tmp]); + } + + /* The requried length has been copied - now fill with zeros */ + for(Tmp = Length; Tmp < FILENAME_SIZE; Tmp++) + { + pDst[Tmp] = '\0'; + } +} + +UWORD dLoaderCheckName(UBYTE *pName, UBYTE *pSearchStr, UBYTE SearchType) +{ + UBYTE TmpName[FILENAME_SIZE]; + UWORD RtnVal; + + RtnVal = UNDEFINEDERROR; + + dLoaderCpyToLower(TmpName, pName, (UBYTE)FILENAME_SIZE); + + RtnVal = SUCCESS; + switch (SearchType) + { + case FULLNAME: + { + if (0 != strcmp((const char*)TmpName, (const char *)pSearchStr)) + { + RtnVal = UNDEFINEDERROR; + } + } + break; + case NAME: + { + if (0 != memcmp(TmpName, pSearchStr, strlen((const char *)pSearchStr))) + { + RtnVal = UNDEFINEDERROR; + } + } + break; + case EXTENTION: + { + if (0 == strstr((const char *)TmpName, (const char*)pSearchStr)) + { + RtnVal = UNDEFINEDERROR; + } + } + break; + case WILDCARD: + { + RtnVal = SUCCESS; + } + break; + default: + { + } + break; + } + return(RtnVal); +} + +void dLoaderInsertSearchStr(UBYTE *pDst, UBYTE *pSrc, UBYTE *pSearchType) +{ + UBYTE Tmp; + + *pSearchType = WILDCARD; + if (0 != strstr((char const *)pSrc, "*.*")) + { + + /* find all */ + strcpy ((PSZ)pDst, (PSZ)pSrc); + *pSearchType = WILDCARD; + } + else + { + + /* Using other wild cards? */ + Tmp = strlen((char const *)pSrc); + if (0 != strstr((PSZ)(pSrc), ".*")) + { + + /* Extention wildcard */ + dLoaderCpyToLower(pDst, pSrc, (Tmp-1)); + *pSearchType = NAME; + } + else + { + if (0 != strstr((PSZ)(pSrc), "*.")) + { + + /* Filename wildcard */ + dLoaderCpyToLower(pDst, &pSrc[1], (UBYTE)4); + *pSearchType = EXTENTION; + } + else + { + + /* no wildcards used */ + dLoaderCpyToLower(pDst, pSrc, Tmp); + *pSearchType = FULLNAME; + } + } + } +} + +UWORD dLoaderCheckHandle(UWORD Handle, UBYTE Operation) +{ + + if (MAX_HANDLES > Handle) + { + if (Operation != HandleTable[(UBYTE)Handle].Status) + { + Handle |= ILLEGALHANDLE; + } + } + else + { + Handle |= ILLEGALHANDLE; + } + return(Handle); +} + +ULONG dLoaderReturnFreeUserFlash(void) +{ + return(FreeUserFlash); +} + +UWORD dLoaderRenameFile(UBYTE Handle, UBYTE *pNewName) +{ + ULONG SectorBuf[SECTORSIZE/4]; + ULONG *pFile; + UBYTE Tmp; + FILEHEADER *pHeader; + + pFile = (ULONG *)FILEPTRTABLE[HandleTable[Handle].FileIndex]; + for (Tmp = 0; Tmp < (SECTORSIZE/4); Tmp++) + { + SectorBuf[Tmp] = pFile[Tmp]; + } + + pHeader = (FILEHEADER *) SectorBuf; + + dLoaderCopyFileName((pHeader->FileName), pNewName); + dLoaderWritePage((ULONG)pFile, SECTORSIZE, SectorBuf); + return(SUCCESS); +} + + +UWORD dLoaderCheckDownload(UBYTE *pName) +{ + UBYTE Tmp; + UWORD ErrorCode; + + ErrorCode = SUCCESS; + for(Tmp = 0; Tmp < MAX_HANDLES; Tmp ++) + { + if (DOWNLOADING == HandleTable[Tmp].Status) + { + if (SUCCESS == dLoaderCheckName(pName, HandleTable[Tmp].SearchStr, FULLNAME)) + { + Tmp = MAX_HANDLES; + ErrorCode = FILEEXISTS; + } + } + } + return(ErrorCode); +} + + + + +UWORD dLoaderCropDatafile(UBYTE Handle) +{ + UWORD ReturnVal; + ULONG SectorBuffer[SECTORSIZE]; + UBYTE FileIndex; + + /* Save the fileindex for use after the handle has been closed */ + FileIndex = HandleTable[Handle].FileIndex; + + ReturnVal = dLoaderCloseHandle(Handle); + if (0x8000 > ReturnVal) + { + + /* Successful close handle now try to crop the file if filesize and datasize differs */ + /* and File exists */ + if (((FILEPTRTABLE[FileIndex]) != 0x00000000) && ((FILEPTRTABLE[FileIndex]) != 0xFFFFFFFF)) + { + if (((FILEHEADER const *)(FILEPTRTABLE[FileIndex]))->FileSize != ((FILEHEADER const *)(FILEPTRTABLE[FileIndex]))->DataSize) + { + memcpy(SectorBuffer, (void const*)(FILEPTRTABLE[FileIndex]), SECTORSIZE); + ((FILEHEADER*)SectorBuffer)->FileSize = ((FILEHEADER const *)(FILEPTRTABLE[FileIndex]))->DataSize; + dLoaderWritePage((ULONG)(FILEPTRTABLE[HandleTable[Handle].FileIndex]), SECTORSIZE, SectorBuffer); + + /* Update sectortable and available flash size */ + dLoaderUpdateSectorTable(); + } + } + } + return(ReturnVal); +} + +void dLoaderExit(void) +{ +} diff --git a/src/d_loader.h b/src/d_loader.h new file mode 100644 index 0000000..902c7f7 --- /dev/null +++ b/src/d_loader.h @@ -0,0 +1,109 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 24-06-09 12:15 $ +// +// Filename $Workfile:: d_loader.h $ +// +// Version $Revision:: 18 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_load $ +// +// Platform C +// + +#ifndef D_LOADER +#define D_LOADER + +#define FILETABLE_SIZE ((2 * SECTORSIZE)/4) +#define STARTOFFILETABLE (0x140000L - (FILETABLE_SIZE*4)) +#define FILEPTRTABLE ((const ULONG*)(0x140000L - (FILETABLE_SIZE*4))) +#ifndef STARTOFUSERFLASH_FROM_LINKER +#define STARTOFUSERFLASH (0x122100L) +#define SIZEOFUSERFLASH_MAX SIZEOFUSERFLASH +#else +extern char __STARTOFUSERFLASH_FROM_LINKER; +#define STARTOFUSERFLASH ((ULONG) &__STARTOFUSERFLASH_FROM_LINKER) +#define SIZEOFUSERFLASH_MAX ((ULONG) (128 * 1024)) +#endif +#define SIZEOFUSERFLASH ((ULONG)STARTOFFILETABLE - STARTOFUSERFLASH) + +#define SIZEOFFLASH 262144L +#define SECTORSIZE 256L +#define SECTORSIZESHIFT 8 +#define NOOFSECTORS (SIZEOFFLASH/SECTORSIZE) +#define HEADERFIXEDSIZE (FILENAME_SIZE + 4 + 4 + 4 + 2 + 2) +#define FILENAME_SIZE (FILENAME_LENGTH + 1) + +#define FULLNAME 1 +#define NAME 2 +#define EXTENTION 3 +#define WILDCARD 4 + +/* Enum related to HandleTable Status */ +enum +{ + FREE, + BUSY, + DOWNLOADING, + SEARCHING, + DLERROR +}; + +/* Enum related to HandleTable WriteBufNo */ +enum +{ + FREEBUFNO = 0xFF +}; + + +/* Constants related to filetype */ +enum +{ + SYSTEMFILE = 0x01, + DATAFILE = 0x02, + LINEAR = 0x04, + NONLINEAR = 0x08 +}; + +typedef struct +{ + UBYTE FileName[FILENAME_SIZE]; + ULONG FileStartAdr; + ULONG FileSize; + ULONG DataSize; + UWORD CheckSum; + UWORD FileType; + UWORD FileSectorTable[(SIZEOFUSERFLASH_MAX/SECTORSIZE)]; +}FILEHEADER; + +void dLoaderInit(void); +__ramfunc UWORD dLoaderWritePage(ULONG Flash_Address, UWORD Size, ULONG *pBuf); +UWORD dLoaderInsertPtrTable(const UBYTE *pAdr, UWORD Handle); +UWORD dLoaderCreateFileHeader(ULONG FileSize, UBYTE *pName, UBYTE LinearState, UBYTE FileType); +UWORD dLoaderWriteData(UWORD Handle, UBYTE *pBuf, UWORD *pLen); +UWORD dLoaderCloseHandle(UWORD Handle); +UWORD dLoaderOpenRead(UBYTE *pFileName, ULONG *pLength); +UWORD dLoaderRead(UBYTE Handle, UBYTE *pBuf, ULONG *pLength); +UWORD dLoaderDelete(UBYTE *pFile); +UWORD dLoaderFind(UBYTE *pFind, UBYTE *pFound, ULONG *pFileLength, ULONG *pDataLength, UBYTE Session); +UWORD dLoaderFindNext(UWORD Handle, UBYTE *pFound, ULONG *pFileLength, ULONG *pDataLength); +UWORD dLoaderDeleteFilePtr(UWORD Handle); +void dLoaderDeleteAllFiles(void); +UWORD dLoaderGetFilePtr(UBYTE *pFileName, UBYTE *pPtrToFile, ULONG *pFileLength); +void dLoaderCopyFileName(UBYTE *pDst, UBYTE *pSrc); +UWORD dLoaderOpenAppend(UBYTE *pFileName, ULONG *pAvailSize); +void dLoaderCpyToLower(UBYTE *pDst, UBYTE *pSrc, UBYTE Length); +UWORD dLoaderCheckName(UBYTE *pName, UBYTE *pSearchStr, UBYTE SearchType); +void dLoaderInsertSearchStr(UBYTE *pDst, UBYTE *pSrc, UBYTE *pSearchType); +ULONG dLoaderReturnFreeUserFlash(void); +UWORD dLoaderRenameFile(UBYTE Handle, UBYTE *pNewName); +UWORD dLoaderCheckFiles(UBYTE Handle); + +UWORD dLoaderCropDatafile(UBYTE Handle); + + + +void dLoaderExit(void); + +#endif diff --git a/src/d_loader.r b/src/d_loader.r new file mode 100644 index 0000000..3fb2556 --- /dev/null +++ b/src/d_loader.r @@ -0,0 +1,117 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: d_loader.r $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_load $ +// +// Platform C +// + +#ifdef SAM7S256 + +#define AT91C_MC_CORRECT_KEY 0x5A000000L + +static ULONG SectorImage[SECTORSIZE>>2]; + +#define LOADERInit + + +__ramfunc UWORD AT91F_Flash_Ready (void) +{ + UWORD status; + status = 0; + + //* Wait the end of command + while ((status & AT91C_MC_FRDY) != AT91C_MC_FRDY ) + { + status = AT91C_BASE_MC->MC_FSR; + } + return status; +} + +__ramfunc UWORD dLoaderWritePage(ULONG Flash_Address, UWORD Size, ULONG *pBuf) +{ + //* set the Flash controller base address + AT91PS_MC ptMC = AT91C_BASE_MC; + unsigned int i, page, status; + unsigned int * Flash; + + //* init flash pointer + Flash = (unsigned int *) (Flash_Address | (unsigned int)AT91C_IFLASH); + + //* Get the Flash page number + page = ((Flash_Address & ~(unsigned int)AT91C_IFLASH) >> SECTORSIZESHIFT); + + //* copy the new value + if (Size & 0x0003) + { + Size = Size + (0x0004 - (Size & 0x0003)); + } + for (i=0; (i < SECTORSIZE) & (Size > 0) ;i++, Flash++,pBuf++,Size-=4 ) + { + //* copy the flash to the write buffer ensuring code generation + *Flash=*pBuf; + } + + //* Write the write page command + ptMC->MC_FCR = AT91C_MC_CORRECT_KEY | AT91C_MC_FCMD_START_PROG | (AT91C_MC_PAGEN & (page <<8)); + + //* Wait the end of command + status = AT91F_Flash_Ready(); + + //* Check the result + if ( (status & ( AT91C_MC_PROGE | AT91C_MC_LOCKE ))!=0) + { + return FALSE; + } + return TRUE; + +} + +__ramfunc UWORD dLoaderErasePage(ULONG Flash_Address) +{ + //* set the Flash controller base address + AT91PS_MC ptMC = AT91C_BASE_MC; + unsigned int i, page, status, Size; + unsigned int * Flash; + + Size = SECTORSIZE; + + //* init flash pointer + Flash = (unsigned int *) (Flash_Address | (unsigned int)AT91C_IFLASH); + + //* Get the Flash page number + page = ((Flash_Address & ~(unsigned int)AT91C_IFLASH) >> SECTORSIZESHIFT); + + //* copy the new value + for (i=0; (i < SECTORSIZE) & (Size > 0) ;i++, Flash++,Size-=4 ) + { + //* copy the flash to the write buffer ensuring code generation + *Flash=0xFFFFFFFF; + } + + //* Write the write page command + ptMC->MC_FCR = AT91C_MC_CORRECT_KEY | AT91C_MC_FCMD_START_PROG | (AT91C_MC_PAGEN & (page <<8)); + + //* Wait the end of command + status = AT91F_Flash_Ready(); + + //* Check the result + if ( (status & ( AT91C_MC_PROGE | AT91C_MC_LOCKE ))!=0) + { + return FALSE; + } + return TRUE; + +} + + + + + +#endif diff --git a/src/d_lowspeed.c b/src/d_lowspeed.c new file mode 100644 index 0000000..91c1341 --- /dev/null +++ b/src/d_lowspeed.c @@ -0,0 +1,77 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: d_lowspeed.c $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_lows $ +// +// Platform C +// + +#include "stdconst.h" +#include "m_sched.h" +#include "d_lowspeed.h" +#include "d_lowspeed.r" + + +void dLowSpeedInit(void) +{ + LOWSpeedTxInit; + LOWSpeedTimerInit; + //ENABLEDebugOutput; +} + +void dLowSpeedStartTimer(void) +{ + ENABLEPWMTimerForLowCom; +} + +void dLowSpeedStopTimer(void) +{ + DISABLEPWMTimerForLowCom; +} + +void dLowSpeedInitPins(UBYTE ChannelNumber) +{ + ENABLETxPins(ChannelNumber); +} + +UBYTE dLowSpeedSendData(UBYTE ChannelNumber, UBYTE *DataOutBuffer, UBYTE NumberOfTxByte) +{ + UBYTE Status; + + TxData(ChannelNumber, Status, DataOutBuffer, NumberOfTxByte); + return(Status); +} + +void dLowSpeedReceiveData(UBYTE ChannelNumber, UBYTE *DataInBuffer, UBYTE ByteToRx) +{ + RxData(ChannelNumber, DataInBuffer, ByteToRx); +} + +UBYTE dLowSpeedComTxStatus(UBYTE ChannelNumber) +{ + UBYTE Status; + + STATUSTxCom(ChannelNumber, Status) + + return(Status); +} + +UBYTE dLowSpeedComRxStatus(UBYTE ChannelNumber) +{ + UBYTE Status; + + STATUSRxCom(ChannelNumber, Status) + + return(Status); +} + +void dLowSpeedExit(void) +{ + LOWSpeedExit; +} diff --git a/src/d_lowspeed.h b/src/d_lowspeed.h new file mode 100644 index 0000000..6ec62fd --- /dev/null +++ b/src/d_lowspeed.h @@ -0,0 +1,28 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: d_lowspeed.h $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_lows $ +// +// Platform C +// + +#ifndef D_LOWSPEED +#define D_LOWSPEED + +void dLowSpeedInit(void); +void dLowSpeedStartTimer(void); +void dLowSpeedStopTimer(void); +void dLowSpeedInitPins(UBYTE ChannelNumber); +UBYTE dLowSpeedSendData(UBYTE ChannelNumber, UBYTE *DataOutBuffer, UBYTE NumberOfTxByte); +void dLowSpeedReceiveData(UBYTE ChannelNumber, UBYTE *DataInBuffer, UBYTE ByteToRx); +UBYTE dLowSpeedComTxStatus(UBYTE ChannelNumber); +UBYTE dLowSpeedComRxStatus(UBYTE ChannelNumber); +void dLowSpeedExit(void); + +#endif diff --git a/src/d_lowspeed.r b/src/d_lowspeed.r new file mode 100644 index 0000000..279c10e --- /dev/null +++ b/src/d_lowspeed.r @@ -0,0 +1,612 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 19-02-09 18:51 $ +// +// Filename $Workfile:: d_lowspeed.r $ +// +// Version $Revision:: 4 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_lows $ +// +// Platform C +// + +#ifdef SAM7S256 + +#if defined (PROTOTYPE_PCB_3) || (PROTOTYPE_PCB_4) + +#define CHANNEL_ONE_CLK AT91C_PIO_PA23 /* PA23 is Clk */ +#define CHANNEL_ONE_DATA AT91C_PIO_PA18 /* PA18 is Data */ + +#define CHANNEL_TWO_CLK AT91C_PIO_PA28 /* PA28 is Clk */ +#define CHANNEL_TWO_DATA AT91C_PIO_PA19 /* PA19 is Data */ + +#define CHANNEL_THREE_CLK AT91C_PIO_PA29 /* PA29 is Clk */ +#define CHANNEL_THREE_DATA AT91C_PIO_PA20 /* PA20 is Data */ + +#define CHANNEL_FOUR_CLK AT91C_PIO_PA30 /* PA30 is Clk */ +#define CHANNEL_FOUR_DATA AT91C_PIO_PA2 /* PA2 is Data */ + +#else + +#define CHANNEL_ONE_CLK AT91C_PIO_PA28 /* PA28 is Clk */ +#define CHANNEL_ONE_DATA AT91C_PIO_PA20 /* PA20 is Data */ + +#endif + +typedef struct +{ + UWORD MaskBit; + UBYTE ChannelState; + UBYTE TxState; + UBYTE RxState; + UBYTE ReStartState; + UBYTE TxByteCnt; + UBYTE RxByteCnt; + UBYTE *pComOutBuffer; + UBYTE *pComInBuffer; + UBYTE AckStatus; + UBYTE RxBitCnt; + UBYTE ReStartBit; + UBYTE ComDeviceAddress; + UBYTE RxWaitCnt; + UBYTE ClkStatus; +}LOWSPEEDPARAMETERS; + +static LOWSPEEDPARAMETERS LowSpeedData[4]; + +__ramdata +ULONG DATA_PINS[4] = {CHANNEL_ONE_DATA, CHANNEL_TWO_DATA, CHANNEL_THREE_DATA, CHANNEL_FOUR_DATA}; +__ramdata +ULONG CLK_PINS[4] = {CHANNEL_ONE_CLK, CHANNEL_TWO_CLK, CHANNEL_THREE_CLK, CHANNEL_FOUR_CLK}; + +#define LOWSPEED_CHANNEL1 0 +#define LOWSPEED_CHANNEL2 1 +#define LOWSPEED_CHANNEL3 2 +#define LOWSPEED_CHANNEL4 3 +#define NO_OF_LOWSPEED_COM_CHANNEL 4 + +#define MASK_BIT_8 0x80 + +#define PIO_INQ 0x04 + +//Used for variable ChannelState +#define LOWSPEED_IDLE 0x00 +#define LOWSPEED_TX_STOP_BIT 0x01 +#define LOWSPEED_TRANSMITTING 0x02 +#define LOWSPEED_RECEIVING 0x04 +#define LOWSPEED_TEST_WAIT_STATE 0x08 +#define LOWSPEED_RESTART_CONDITION 0x10 +#define LOWSPEED_WAIT_BEFORE_RX 0x20 + +//Used for variable TxState +#define TX_IDLE 0x00 +#define TX_DATA_MORE_DATA 0x01 +#define TX_DATA_CLK_HIGH 0x02 +#define TX_EVALUATE_ACK_CLK_HIGH 0x03 +#define TX_DATA_READ_ACK_CLK_LOW 0x04 +#define TX_DATA_CLK_LOW 0x05 +#define TX_ACK_EVALUATED_CLK_LOW 0x06 + +//Used for variable RxState +#define RX_IDLE 0x00 +#define RX_START_BIT_CLK_HIGH 0x01 +#define RX_DATA_CLK_HIGH 0x02 +#define RX_ACK_TX_CLK_HIGH 0x03 +#define RX_DATA_CLK_LOW 0x04 +#define RX_DONE_OR_NOT_CLK_LOW 0x05 + +//Used for variable ReStart +#define RESTART_STATE_IDLE 0x00 +#define RESTART_STATE_ONE 0x01 +#define RESTART_STATE_TWO 0x02 +#define RESTART_STATE_THREE 0x03 +#define RESTART_STATE_FOUR 0x04 +#define RESTART_STATE_FIVE 0x05 +#define RESTART_STATE_SIX 0x06 +#define RESTART_STATE_SEVEN 0x07 + +#define LOWSpeedTxInit {\ + LowSpeedData[LOWSPEED_CHANNEL1].ChannelState = 0;\ + LowSpeedData[LOWSPEED_CHANNEL2].ChannelState = 0;\ + LowSpeedData[LOWSPEED_CHANNEL3].ChannelState = 0;\ + LowSpeedData[LOWSPEED_CHANNEL4].ChannelState = 0;\ + } + +#define LOWSpeedTimerInit {\ + *AT91C_PMC_PCER = 0x400; /* Enable clock for PWM, PID10*/\ + *AT91C_PWMC_MR = 0x01; /* CLKA is output from prescaler */\ + *AT91C_PWMC_MR |= 0x600; /* Prescaler MCK divided with 64 */\ + *AT91C_PWMC_CH0_CMR = 0x06; /* Channel 0 uses MCK divided by 64 */\ + *AT91C_PWMC_CH0_CMR &= 0xFFFFFEFF; /* Left alignment on periode */\ + *AT91C_PWMC_CH0_CPRDR = 0x20; /* Set to 39 => 52uSecondes interrupt */\ + *AT91C_PWMC_IDR = AT91C_PWMC_CHID0; /* Disable interrupt for PWM output channel 0 */\ + *AT91C_AIC_IDCR = 0x400; /* Disable AIC intterupt on ID10 PWM */\ + AT91C_AIC_SVR[10] = (unsigned int)LowSpeedPwmIrqHandler;\ + AT91C_AIC_SMR[10] = 0x01; /* Enable trigger on level */\ + *AT91C_AIC_ICCR = 0x400; /* Clear interrupt register PID10*/\ + *AT91C_PWMC_IER = AT91C_PWMC_CHID0; /* Enable interrupt for PWM output channel 0 */\ + *AT91C_AIC_IECR = 0x400; /* Enable interrupt from PWM */\ + } + +#define LOWSpeedExit + +#define ENABLEDebugOutput {\ + *AT91C_PIOA_PER = AT91C_PIO_PA29; /* Enable PIO on PA029 */\ + *AT91C_PIOA_OER = AT91C_PIO_PA29; /* PA029 set to Output */\ + *AT91C_PIOA_CODR = 0x20000000;\ + } + +#define SETDebugOutputHigh *AT91C_PIOA_SODR = 0x20000000 + +#define SETDebugOutputLow *AT91C_PIOA_CODR = 0x20000000 + + +#define SETClkLow(ChannelNr) {\ + *AT91C_PIOA_CODR = CLK_PINS[ChannelNr];\ + LowSpeedData[ChannelNr].ClkStatus = 0;\ +} + +#define SETClkHigh(ChannelNr) {\ + *AT91C_PIOA_SODR = CLK_PINS[ChannelNr];\ + LowSpeedData[ChannelNr].ClkStatus = 1;\ +} + +#define SETDataLow(ChannelNr) {\ + *AT91C_PIOA_CODR = DATA_PINS[ChannelNr];\ +} + +#define SETDataHigh(ChannelNr) {\ + *AT91C_PIOA_SODR = DATA_PINS[ChannelNr];\ +} + +#define SETDataToInput(ChannelNr) {\ + *AT91C_PIOA_ODR = DATA_PINS[ChannelNr];\ +} + + +#define SETDataToOutput(ChannelNr) {\ + *AT91C_PIOA_OER = DATA_PINS[ChannelNr];\ +} + +#define GetClkPinLevel(ChannelNr) (*AT91C_PIOA_PDSR & CLK_PINS[ChannelNr]) +#define GetDataPinLevel(ChannelNr) (*AT91C_PIOA_PDSR & DATA_PINS[ChannelNr]) + +#define ENABLEPWMTimerForLowCom {\ + *AT91C_PWMC_ENA = AT91C_PWMC_CHID0; /* Enable PWM output channel 0 */\ + } + +#define DISABLEPWMTimerForLowCom {\ + *AT91C_PWMC_DIS = AT91C_PWMC_CHID0; /* Disable PWM output channel 0 */\ + } + +#define OLD_DISABLEPWMTimerForLowCom {\ + *AT91C_PWMC_DIS = AT91C_PWMC_CHID0; /* Disable PWM output channel 0 */\ + *AT91C_PWMC_IDR = AT91C_PWMC_CHID0; /* Disable interrupt from PWM output channel 0 */\ + *AT91C_AIC_IDCR = 0x400; /* Disable Irq from PID10 */\ + *AT91C_AIC_ICCR = 0x400; /* Clear interrupt register PID10*/\ + *AT91C_PMC_PCDR = 0x400; /* Disable clock for PWM, PID10*/\ + } + +__ramfunc void LowSpeedPwmIrqHandler(void) +{ + ULONG TestVar; + ULONG PinStatus; + UBYTE ChannelNr; + + TestVar = *AT91C_PWMC_ISR; + TestVar = TestVar; + PinStatus = *AT91C_PIOA_PDSR; + + for (ChannelNr = 0; ChannelNr < NO_OF_LOWSPEED_COM_CHANNEL; ChannelNr++) + { + if (((LowSpeedData[ChannelNr].ClkStatus == 1) && (PinStatus & CLK_PINS[ChannelNr])) || (((LowSpeedData[ChannelNr].ClkStatus == 0) && (!(PinStatus & CLK_PINS[ChannelNr]))))) + { + switch(LowSpeedData[ChannelNr].ChannelState) + { + case LOWSPEED_IDLE: + { + } + break; + + case LOWSPEED_TX_STOP_BIT: + { + SETDataHigh(ChannelNr); + LowSpeedData[ChannelNr].ChannelState = LOWSPEED_IDLE; //Now we have send a STOP sequence, disable this channel + } + break; + + case LOWSPEED_TRANSMITTING: + { + switch(LowSpeedData[ChannelNr].TxState) + { + case TX_DATA_MORE_DATA: + { + PinStatus |= CLK_PINS[ChannelNr]; + LowSpeedData[ChannelNr].TxState = TX_DATA_CLK_HIGH; + } + break; + + case TX_DATA_CLK_HIGH: + { + SETClkLow(ChannelNr); + if (LowSpeedData[ChannelNr].MaskBit == 0) //Is Byte Done, then we need a ack from receiver + { + SETDataToInput(ChannelNr); //Set datapin to input + LowSpeedData[ChannelNr].TxState = TX_DATA_READ_ACK_CLK_LOW; + } + else + { + if (*LowSpeedData[ChannelNr].pComOutBuffer & LowSpeedData[ChannelNr].MaskBit) //Setup data pin in relation to the data + { + SETDataHigh(ChannelNr); //Set data output high + } + else + { + SETDataLow(ChannelNr); //Set data output low + } + LowSpeedData[ChannelNr].TxState = TX_DATA_CLK_LOW; + } + } + break; + + case TX_EVALUATE_ACK_CLK_HIGH: + { + SETClkLow(ChannelNr); + if (LowSpeedData[ChannelNr].AckStatus == 1) + { + LowSpeedData[ChannelNr].TxByteCnt--; + if (LowSpeedData[ChannelNr].TxByteCnt > 0) //Here initialise to send next byte + { + LowSpeedData[ChannelNr].MaskBit = MASK_BIT_8; + LowSpeedData[ChannelNr].pComOutBuffer++; + } + LowSpeedData[ChannelNr].TxState = TX_ACK_EVALUATED_CLK_LOW; //Received ack, now make a stop sequence or send next byte + } + else + { //Data communication error ! + LowSpeedData[ChannelNr].TxByteCnt = 0; + SETClkHigh(ChannelNr); + LowSpeedData[ChannelNr].ChannelState = LOWSPEED_TX_STOP_BIT; //Received ack, now make a stop sequence or send next byte. + } + } + break; + + case TX_DATA_READ_ACK_CLK_LOW: + { + if (!(PinStatus & DATA_PINS[ChannelNr])) + { + LowSpeedData[ChannelNr].AckStatus = 1; //Read ack signal from receiver + } + SETDataToOutput(ChannelNr); + SETDataLow(ChannelNr); + LowSpeedData[ChannelNr].TxState = TX_EVALUATE_ACK_CLK_HIGH; + SETClkHigh(ChannelNr); + } + break; + + case TX_DATA_CLK_LOW: + { + LowSpeedData[ChannelNr].MaskBit = LowSpeedData[ChannelNr].MaskBit >> 1; //Get ready for the next bit which should be clk out next time + SETClkHigh(ChannelNr); //Clk goes high = The reciever reads the data + LowSpeedData[ChannelNr].TxState = TX_DATA_CLK_HIGH; + } + break; + + case TX_ACK_EVALUATED_CLK_LOW: + { + if (LowSpeedData[ChannelNr].MaskBit != 0) + { + LowSpeedData[ChannelNr].TxState = TX_DATA_MORE_DATA; + } + else + { + if (LowSpeedData[ChannelNr].ReStartBit != 0) + { + LowSpeedData[ChannelNr].ChannelState = LOWSPEED_RESTART_CONDITION; + LowSpeedData[ChannelNr].ReStartState = RESTART_STATE_ONE; + SETDataLow(ChannelNr); + SETClkHigh(ChannelNr); //Clk goes high = The reciever reads the data + } + else + { + if (LowSpeedData[ChannelNr].RxByteCnt != 0) + { + LowSpeedData[ChannelNr].ChannelState = LOWSPEED_WAIT_BEFORE_RX; + } + else + { + LowSpeedData[ChannelNr].ChannelState = LOWSPEED_TX_STOP_BIT; + SETClkHigh(ChannelNr); //Clk goes high = The reciever reads the data + } + } + LowSpeedData[ChannelNr].TxState = TX_IDLE; + } + } + break; + } + } + break; + + case LOWSPEED_RESTART_CONDITION: + { + switch(LowSpeedData[ChannelNr].ReStartState) + { + case RESTART_STATE_ONE: + { + LowSpeedData[ChannelNr].ReStartState = RESTART_STATE_TWO; + } + break; + + case RESTART_STATE_TWO: + { + SETDataHigh(ChannelNr); + LowSpeedData[ChannelNr].ReStartState = RESTART_STATE_THREE; + } + break; + + case RESTART_STATE_THREE: + { + SETClkLow(ChannelNr); + LowSpeedData[ChannelNr].ReStartState = RESTART_STATE_FOUR; + } + break; + + case RESTART_STATE_FOUR: + { + SETClkHigh(ChannelNr); + LowSpeedData[ChannelNr].ReStartState = RESTART_STATE_FIVE; + } + break; + + case RESTART_STATE_FIVE: + { + SETDataLow(ChannelNr); + LowSpeedData[ChannelNr].ReStartState = RESTART_STATE_SIX; + } + break; + + case RESTART_STATE_SIX: + { + LowSpeedData[ChannelNr].ReStartState = RESTART_STATE_SEVEN; + } + break; + + case RESTART_STATE_SEVEN: + { + SETClkLow(ChannelNr); + LowSpeedData[ChannelNr].ReStartState = RESTART_STATE_IDLE; + LowSpeedData[ChannelNr].ReStartBit = 0; + LowSpeedData[ChannelNr].pComOutBuffer = &LowSpeedData[ChannelNr].ComDeviceAddress; + *LowSpeedData[ChannelNr].pComOutBuffer += 0x01; + LowSpeedData[ChannelNr].ChannelState = LOWSPEED_TRANSMITTING; + LowSpeedData[ChannelNr].MaskBit = MASK_BIT_8; + LowSpeedData[ChannelNr].TxByteCnt = 0x01; + LowSpeedData[ChannelNr].TxState = TX_DATA_CLK_HIGH; + LowSpeedData[ChannelNr].AckStatus = 0; + } + break; + } + } + break; + + case LOWSPEED_WAIT_BEFORE_RX: + { + LowSpeedData[ChannelNr].RxWaitCnt++; + if (LowSpeedData[ChannelNr].RxWaitCnt > 5) + { + LowSpeedData[ChannelNr].ChannelState = LOWSPEED_RECEIVING; + SETDataToInput(ChannelNr); + } + } + break; + + case LOWSPEED_RECEIVING: + { + switch(LowSpeedData[ChannelNr].RxState) + { + case RX_START_BIT_CLK_HIGH: + { + SETClkLow(ChannelNr); + LowSpeedData[ChannelNr].RxState = RX_DATA_CLK_LOW; + } + break; + + case RX_DATA_CLK_HIGH: + { + LowSpeedData[ChannelNr].RxBitCnt++; + if(PinStatus & DATA_PINS[ChannelNr]) + { + *LowSpeedData[ChannelNr].pComInBuffer |= 0x01; + } + SETClkLow(ChannelNr); + if (LowSpeedData[ChannelNr].RxBitCnt < 8) + { + *LowSpeedData[ChannelNr].pComInBuffer = *LowSpeedData[ChannelNr].pComInBuffer << 1; + } + else + { + if (LowSpeedData[ChannelNr].RxByteCnt > 1) + { + SETDataToOutput(ChannelNr); + SETDataLow(ChannelNr); + } + } + LowSpeedData[ChannelNr].RxState = RX_DATA_CLK_LOW; + } + break; + + case RX_ACK_TX_CLK_HIGH: + { + SETClkLow(ChannelNr); + SETDataToInput(ChannelNr); + LowSpeedData[ChannelNr].pComInBuffer++; + LowSpeedData[ChannelNr].RxByteCnt--; + LowSpeedData[ChannelNr].RxBitCnt = 0; + LowSpeedData[ChannelNr].RxState = RX_DONE_OR_NOT_CLK_LOW; + } + break; + + case RX_DATA_CLK_LOW: + { + SETClkHigh(ChannelNr); + if (LowSpeedData[ChannelNr].RxBitCnt == 8) + { + LowSpeedData[ChannelNr].RxState = RX_ACK_TX_CLK_HIGH; + } + else + { + LowSpeedData[ChannelNr].RxState = RX_DATA_CLK_HIGH; + } + } + break; + + case RX_DONE_OR_NOT_CLK_LOW: + { + if (LowSpeedData[ChannelNr].RxByteCnt == 0) + { + LowSpeedData[ChannelNr].ChannelState = LOWSPEED_IDLE; + LowSpeedData[ChannelNr].RxState = RX_IDLE; + SETClkHigh(ChannelNr); + } + else + { + LowSpeedData[ChannelNr].RxState = RX_START_BIT_CLK_HIGH; + } + } + break; + } + } + break; + + default: + break; + } + } + else + { + + if (LOWSPEED_IDLE != LowSpeedData[ChannelNr].ChannelState) + { + //Data communication error ! + LowSpeedData[ChannelNr].TxByteCnt = 0; + SETClkHigh(ChannelNr); + LowSpeedData[ChannelNr].ChannelState = LOWSPEED_TX_STOP_BIT; + } + } + } +} + +#define ENABLETxPins(ChannelNumber) {\ + ULONG Tmp = CLK_PINS[ChannelNumber] | DATA_PINS[ChannelNumber];\ + *AT91C_PIOA_PER = Tmp; /* Enable PIO */\ + *AT91C_PIOA_PPUDR = Tmp; /* Disable Pull-up resistor */\ + *AT91C_PIOA_ODR = Tmp; /* PIO set to Input */\ +} + +#define TxData(ChannelNumber, Status, DataOutBuffer, NumberOfByte) {\ + if ((GetDataPinLevel(ChannelNumber) && GetClkPinLevel(ChannelNumber)) && (LowSpeedData[ChannelNumber].ChannelState == LOWSPEED_IDLE))\ + {\ + ULONG Tmp = CLK_PINS[ChannelNumber] | DATA_PINS[ChannelNumber];\ + *AT91C_PIOA_PER = Tmp; /* Enable PIO */\ + *AT91C_PIOA_OER = Tmp; /* POI set to Output */\ + *AT91C_PIOA_PPUDR = Tmp; /* Disable Pull-up resistor */\ + SETClkHigh(ChannelNumber);\ + SETDataLow(ChannelNumber);\ + LowSpeedData[ChannelNumber].ClkStatus = 1;\ + LowSpeedData[ChannelNumber].pComOutBuffer = DataOutBuffer;\ + LowSpeedData[ChannelNumber].ComDeviceAddress = *LowSpeedData[ChannelNumber].pComOutBuffer;\ + LowSpeedData[ChannelNumber].MaskBit = MASK_BIT_8;\ + LowSpeedData[ChannelNumber].TxByteCnt = NumberOfByte;\ + LowSpeedData[ChannelNumber].TxState = TX_DATA_CLK_HIGH;\ + LowSpeedData[ChannelNumber].AckStatus = 0;\ + LowSpeedData[ChannelNumber].ChannelState = LOWSPEED_TRANSMITTING;\ + Status = 1;\ + }\ + else\ + {\ + Status = 0;\ + }\ +} + +#define RxData(ChannelNumber, DataInBuffer, RxBytes) {\ + LowSpeedData[ChannelNumber].pComInBuffer = DataInBuffer;\ + LowSpeedData[ChannelNumber].RxBitCnt = 0;\ + LowSpeedData[ChannelNumber].RxByteCnt = RxBytes;\ + LowSpeedData[ChannelNumber].RxState = RX_DATA_CLK_LOW;\ + LowSpeedData[ChannelNumber].ReStartBit = 1;\ + LowSpeedData[ChannelNumber].RxWaitCnt = 0;\ + } + + +#define STATUSTxCom(ChannelNumber, Status) {\ + if (LowSpeedData[ChannelNumber].ChannelState != 0)\ + {\ + if ((LowSpeedData[ChannelNumber].TxByteCnt == 0) && (LowSpeedData[ChannelNumber].ChannelState != LOWSPEED_RESTART_CONDITION))\ + {\ + if (LowSpeedData[ChannelNumber].MaskBit == 0)\ + {\ + if (LowSpeedData[ChannelNumber].AckStatus == 1)\ + {\ + Status = 0x01; /* TX SUCCESS */\ + }\ + else\ + {\ + Status = 0xFF; /* TX ERROR */\ + }\ + }\ + else\ + {\ + Status = 0;\ + }\ + }\ + else\ + {\ + Status = 0;\ + }\ + }\ + else\ + {\ + if (LowSpeedData[ChannelNumber].RxByteCnt == 0)\ + {\ + if (LowSpeedData[ChannelNumber].AckStatus == 1)\ + {\ + Status = 0x01; /* TX SUCCESS */\ + }\ + else\ + {\ + Status = 0xFF; /* TX ERROR */\ + }\ + }\ + else\ + {\ + Status = 0xFF; /* TX ERROR */\ + }\ + }\ + } + +#define STATUSRxCom(ChannelNumber, Status) {\ + if (LowSpeedData[ChannelNumber].ChannelState == LOWSPEED_IDLE)\ + {\ + if (LowSpeedData[ChannelNumber].RxByteCnt == 0)\ + {\ + Status = 0x01; /* RX SUCCESS */\ + }\ + else\ + {\ + Status = 0xFF; /* RX ERROR */\ + }\ + }\ + else\ + {\ + Status = 0;\ + }\ + } + + +#endif + +#ifdef PCWIN + +#endif diff --git a/src/d_output.c b/src/d_output.c new file mode 100644 index 0000000..326f6f8 --- /dev/null +++ b/src/d_output.c @@ -0,0 +1,1415 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 3-02-09 14:46 $ +// +// Filename $Workfile:: d_output.c $ +// +// Version $Revision:: 2 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_outp $ +// +// Platform C +// + +#include "stdconst.h" +#include "m_sched.h" +#include "d_output.h" +#include "d_output.r" + +#include + +#define MAXIMUM_SPEED_FW 100 +#define MAXIMUM_SPEED_RW -100 + +#define INPUT_SCALE_FACTOR 100 +#define SPEED_TIME 100 + +#define MAX_COUNT_TO_RUN 10000000 + +#define REG_MAX_VALUE 100 + +#define RAMP_TIME_INTERVAL 25 // Measured in 1 mS => 25 mS interval + +#define RAMPDOWN_STATE_RAMPDOWN 0 +#define RAMPDOWN_STATE_CONTINIUE 1 + +#define COAST_MOTOR_MODE 0 + +void dOutputRampDownSynch(UBYTE MotorNr); +SLONG dOutputBound(SLONG In, SLONG Limit); +SLONG dOutputPIDRegulation(UBYTE MotorNr, SLONG PositionError); +SLONG dOutputFractionalChange(SLONG Value, SWORD *FracError); +void dOutputSpeedFilter(UBYTE MotorNr, SLONG PositionDiff); + +#define ABS(a) (((a) < 0) ? -(a) : (a)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + +typedef struct +{ + SBYTE MotorSetSpeed; // Motor setpoint in speed + SBYTE MotorTargetSpeed; // Speed order for the movement + SBYTE MotorActualSpeed; // Actual speed for motor (Calculated within the PID regulation) + SBYTE TurnParameter; // Tell the turning parameter used + UBYTE RegPParameter; // Current P parameter used within the regulation + UBYTE RegIParameter; // Current I parameter used within the regulation + UBYTE RegDParameter; // Current D parameter used within the regulation + UBYTE RegulationTimeCount; // Time counter used to evaluate when the regulation should run again (100 mS) + UBYTE MotorRunState; // Hold current motor state (Ramp-up, Running, Ramp-Down, Idle) + UBYTE RegulationMode; // Hold current regulation mode (Position control, Synchronization mode) + UBYTE MotorOverloaded; // Set if the motor speed in regulation is calculated to be above maximum + UBYTE MotorRunForever; // Tell that the motor is set to run forever + UWORD MotorRampDownCount; // Counter to tell if the ramp-down can reach it gaol and therefor need some additional help + SWORD MotorRampDownIncrement; // Tell the number of count between each speed adjustment during Ramp-Down + UWORD MotorRampUpCount; // Used to speedup Ramp-Up if position regulation is not enabled + SWORD MotorRampUpIncrement; // Tell the number of count between each speed adjustment during Ramp-up + SWORD AccError; // Accumulated Error, used within the integrator of the PID regulation + SWORD OldPositionError; // Used within position regulation + SWORD PositionFracError; // Fractionnal position error of last position update + SLONG DeltaCaptureCount; // Counts within last regulation time-periode + SLONG CurrentCaptureCount; // Total counts since motor counts has been reset + SLONG MotorTachoCountToRun; // Holds number of counts to run. 0 = Run forever + SLONG MotorBlockTachoCount; // Hold CaptureCount for current movement + SLONG MotorRampTachoCountOld; // Used to hold old position during Ramp-Up + SLONG MotorRampTachoCountStart; // Used to hold position when Ramp-up started + SLONG RotationCaptureCount; // Counter for additional rotation counter + SLONG MotorTachoCountTarget; // For absolute regulation, position on which regulation is done + SWORD SpeedFracError; // Fractionnal speed error of last speed update + SBYTE MotorMaxSpeed; // For absolute regulation, maximum motor speed + SBYTE MotorMaxAcceleration; // For absolute regulation, maximum motor acceleration +}MOTORDATA; + +typedef struct +{ + SLONG SyncTachoDif; + SLONG SyncTurnParameter; + SWORD SyncOldError; + SWORD SyncAccError; +}SYNCMOTORDATA; + +static MOTORDATA MotorData[3]; +static SYNCMOTORDATA SyncData; +static UBYTE RegulationTime; +static UBYTE RegulationOptions; + +void dOutputInit(void) +{ + UBYTE Temp; + + OUTPUTInit; + ENABLECaptureMotorA; + ENABLECaptureMotorB; + ENABLECaptureMotorC; + + for (Temp = 0; Temp < 3; Temp++) + { + MOTORDATA * pMD = &(MotorData[Temp]); + pMD->MotorSetSpeed = 0; + pMD->MotorTargetSpeed = 0; + pMD->MotorActualSpeed = 0; + pMD->MotorRampUpCount = 0; + pMD->MotorRampDownCount = 0; + pMD->MotorRunState = 0; + pMD->MotorTachoCountToRun = 0; + pMD->MotorRunForever = 1; + pMD->AccError = 0; + pMD->PositionFracError = 0; + pMD->RegulationTimeCount = 0; + pMD->RegPParameter = DEFAULT_P_GAIN_FACTOR; + pMD->RegIParameter = DEFAULT_I_GAIN_FACTOR; + pMD->RegDParameter = DEFAULT_D_GAIN_FACTOR; + pMD->MotorMaxSpeed = DEFAULT_MAX_SPEED; + pMD->MotorMaxAcceleration = DEFAULT_MAX_ACCELERATION; + pMD->RegulationMode = 0; + pMD->MotorOverloaded = 0; + INSERTMode(Temp, COAST_MOTOR_MODE); + INSERTSpeed(Temp, pMD->MotorSetSpeed); + } +} + +/* This function is called every 1 mS and will go through all the motors and there dependencies */ +/* Actual motor speed is only passed (updated) to the AVR controller form this function */ +/* DeltacaptureCount used to count number of Tachocount within last 100 mS. Used with position control regulation */ +/* CurrentCaptureCount used to tell total current position. Used to tell when movement has been obtained */ +/* MotorBlockTachoCount tell current position within current movement. Reset when a new block is started from the VM */ +/* RotationCaptureCount is additional counter for the rotationsensor. Uses it own value so it does conflict with other CaptureCount */ +void dOutputCtrl(void) +{ + UBYTE MotorNr; + SLONG NewTachoCount[3]; + + TACHOCaptureReadResetAll(NewTachoCount[MOTOR_A], NewTachoCount[MOTOR_B], NewTachoCount[MOTOR_C]); + + for (MotorNr = 0; MotorNr < 3; MotorNr++) + { + MOTORDATA * pMD = &(MotorData[MotorNr]); + pMD->DeltaCaptureCount += NewTachoCount[MotorNr]; + pMD->CurrentCaptureCount += NewTachoCount[MotorNr]; + pMD->MotorBlockTachoCount += NewTachoCount[MotorNr]; + pMD->RotationCaptureCount += NewTachoCount[MotorNr]; + pMD->RegulationTimeCount++; + + if (pMD->MotorRunState == MOTOR_RUN_STATE_RAMPUP) + { + dOutputRampUpFunction(MotorNr); + } + if (pMD->MotorRunState == MOTOR_RUN_STATE_RAMPDOWN) + { + dOutputRampDownFunction(MotorNr); + } + if (pMD->MotorRunState == MOTOR_RUN_STATE_RUNNING) + { + dOutputTachoLimitControl(MotorNr); + } + if (pMD->MotorRunState == MOTOR_RUN_STATE_IDLE) + { + dOutputMotorIdleControl(MotorNr); + } + if (pMD->MotorRunState == MOTOR_RUN_STATE_HOLD) + { + pMD->MotorSetSpeed = 0; + pMD->MotorActualSpeed = 0; + pMD->MotorTargetSpeed = 0; + pMD->PositionFracError = 0; + pMD->RegulationTimeCount = 0; + pMD->DeltaCaptureCount = 0; + pMD->MotorRunState = MOTOR_RUN_STATE_RUNNING; + + } + if (pMD->RegulationTimeCount > RegulationTime) + { + pMD->RegulationTimeCount = 0; + dOutputRegulateMotor(MotorNr); + pMD->DeltaCaptureCount = 0; + } + } + INSERTSpeed(MOTOR_A, MotorData[MOTOR_A].MotorActualSpeed); + INSERTSpeed(MOTOR_B, MotorData[MOTOR_B].MotorActualSpeed); + INSERTSpeed(MOTOR_C, MotorData[MOTOR_C].MotorActualSpeed); +} + +void dOutputExit(void) +{ + OUTPUTExit; +} + +/* Called eveyr 1 mS */ +/* Data mapping for controller (IO-Map is updated with these values) */ +void dOutputGetMotorParameters(UBYTE *CurrentMotorSpeed, SLONG *TachoCount, SLONG *BlockTachoCount, UBYTE *RunState, UBYTE *MotorOverloaded, SLONG *RotationCount) +{ + UBYTE Tmp; + + for (Tmp = 0; Tmp < 3; Tmp++) + { + MOTORDATA * pMD = &(MotorData[Tmp]); + CurrentMotorSpeed[Tmp] = pMD->MotorActualSpeed; + TachoCount[Tmp] = pMD->CurrentCaptureCount; + BlockTachoCount[Tmp] = pMD->MotorBlockTachoCount; + RotationCount[Tmp] = pMD->RotationCaptureCount; + RunState[Tmp] = pMD->MotorRunState; + MotorOverloaded[Tmp] = pMD->MotorOverloaded; + } +} + +void dOutputSetMode(UBYTE MotorNr, UBYTE Mode) //Set motor mode (break, Float) +{ + INSERTMode(MotorNr, Mode); +} + +/* Update the regulation state for the motor */ +/* Need to reset regulation parameter depending on current status of the motor */ +/* AccError & OldPositionError used for position regulation and Sync Parameter are used for synchronization regulation */ +void dOutputEnableRegulation(UBYTE MotorNr, UBYTE RegulationMode) +{ + MOTORDATA * pMD = &(MotorData[MotorNr]); + pMD->RegulationMode = RegulationMode; + + if ((pMD->RegulationMode & REGSTATE_REGULATED) && (pMD->MotorSetSpeed == 0) && (pMD->MotorRunState != MOTOR_RUN_STATE_RAMPDOWN)) + { + pMD->AccError = 0; + pMD->OldPositionError = 0; + pMD->PositionFracError = 0; + } + + if (pMD->RegulationMode & REGSTATE_SYNCHRONE) + { + if (((pMD->MotorActualSpeed == 0) || (pMD->TurnParameter != 0) || (pMD->TurnParameter == 0)) && (pMD->MotorRunState != MOTOR_RUN_STATE_RAMPDOWN)) + { + SyncData.SyncTachoDif = 0; + + SyncData.SyncAccError = 0; + SyncData.SyncOldError = 0; + SyncData.SyncTurnParameter = 0; + } + } +} + +/* Disable current regulation if enabled */ +void dOutputDisableRegulation(UBYTE MotorNr) +{ + MotorData[MotorNr].RegulationMode = REGSTATE_IDLE; +} + +/* Calling this function with reset count which tell current position and which is used to tell if the wanted position is obtained */ +/* Calling this function will reset current movement of the motor if it is running */ +void dOutputResetTachoLimit(UBYTE MotorNr) +{ + MOTORDATA * pMD = &(MotorData[MotorNr]); + pMD->CurrentCaptureCount = 0; + pMD->MotorTachoCountToRun = 0; + pMD->MotorTachoCountTarget = 0; + + if (pMD->RegulationMode & REGSTATE_SYNCHRONE) + { + dOutputResetSyncMotors(MotorNr); + } + + if (pMD->MotorRunForever == 1) + { + pMD->MotorRunForever = 0; // To ensure that we get the same functionality for all combination on motor durations + } +} + +/* MotorBlockTachoCount tells current position in current movement. */ +/* Used within the synchronization to compare current motor position. Reset on every new movement from the VM */ +void dOutputResetBlockTachoLimit(UBYTE MotorNr) +{ + MotorData[MotorNr].MotorBlockTachoCount = 0; +} + +/* Additional counter add to help the VM application keep track of number of rotation for the rotation sensor */ +/* This values can be reset independtly from the other tacho count values used with regulation and position control */ +void dOutputResetRotationCaptureCount(UBYTE MotorNr) +{ + MotorData[MotorNr].RotationCaptureCount = 0; +} + +/* Can be used to set new PID values */ +void dOutputSetPIDParameters(UBYTE MotorNr, UBYTE NewRegPParameter, UBYTE NewRegIParameter, UBYTE NewRegDParameter) +{ + MOTORDATA * pMD = &(MotorData[MotorNr]); + pMD->RegPParameter = NewRegPParameter; + pMD->RegIParameter = NewRegIParameter; + pMD->RegDParameter = NewRegDParameter; +} + +/* Set maximum speed and acceleration */ +void dOutputSetMax(UBYTE MotorNr, SBYTE NewMaxSpeed, SBYTE NewMaxAcceleration) +{ + MOTORDATA * pMD = &(MotorData[MotorNr]); + pMD->MotorMaxSpeed = NewMaxSpeed; + pMD->MotorMaxAcceleration = NewMaxAcceleration; +} + +/* Set new regulation time */ +void dOutputSetRegulationTime(UBYTE NewRegulationTime) +{ + RegulationTime = NewRegulationTime; +} + +/* Set new regulation options */ +void dOutputSetRegulationOptions(UBYTE NewRegulationOptions) +{ + RegulationOptions = NewRegulationOptions; +} + +/* Called to set TachoCountToRun which is used for position control for the model */ +/* Must be called before motor start */ +/* TachoCountToRun is calculated as a signed value */ +void dOutputSetTachoLimit(UBYTE MotorNr, ULONG BlockTachoCntToTravel) +{ + MOTORDATA * pMD = &(MotorData[MotorNr]); + if (pMD->RegulationMode & REGSTATE_POSITION) + { + pMD->MotorRunForever = 0; + pMD->MotorTachoCountToRun = BlockTachoCntToTravel; + } + else if (BlockTachoCntToTravel == 0) + { + pMD->MotorRunForever = 1; + } + else + { + pMD->MotorRunForever = 0; + + if (pMD->MotorSetSpeed == 0) + { + if (pMD->MotorTargetSpeed > 0) + { + pMD->MotorTachoCountToRun += BlockTachoCntToTravel; + } + else + { + pMD->MotorTachoCountToRun -= BlockTachoCntToTravel; + } + } + else + { + if (pMD->MotorSetSpeed > 0) + { + pMD->MotorTachoCountToRun += BlockTachoCntToTravel; + } + else + { + pMD->MotorTachoCountToRun -= BlockTachoCntToTravel; + } + } + } +} + +/* This function is used for setting up the motor mode and motor speed */ +void dOutputSetSpeed (UBYTE MotorNr, UBYTE NewMotorRunState, SBYTE Speed, SBYTE NewTurnParameter) +{ + MOTORDATA * pMD = &(MotorData[MotorNr]); + if ((pMD->MotorSetSpeed != Speed) || (pMD->MotorRunState != NewMotorRunState) || + (NewMotorRunState == MOTOR_RUN_STATE_IDLE) || (pMD->TurnParameter != NewTurnParameter)) + { + if (pMD->MotorTargetSpeed == 0) + { + pMD->AccError = 0; + pMD->OldPositionError = 0; + pMD->PositionFracError = 0; + pMD->RegulationTimeCount = 0; + pMD->DeltaCaptureCount = 0; + TACHOCountReset(MotorNr); + } + switch (NewMotorRunState) + { + case MOTOR_RUN_STATE_IDLE: + { + //pMD->MotorSetSpeed = 0; + //pMD->MotorTargetSpeed = 0; + //pMD->TurnParameter = 0; + pMD->RegulationMode = REGSTATE_IDLE; + } + break; + + case MOTOR_RUN_STATE_RAMPUP: + { + if (pMD->MotorSetSpeed == 0) + { + pMD->MotorSetSpeed = Speed; + pMD->TurnParameter = NewTurnParameter; + pMD->MotorRampUpIncrement = 0; + pMD->MotorRampTachoCountStart = pMD->CurrentCaptureCount; + pMD->MotorRampUpCount = 0; + } + else + { + if (Speed > 0) + { + if (pMD->MotorSetSpeed >= Speed) + { + NewMotorRunState = MOTOR_RUN_STATE_RUNNING; + } + else + { + pMD->MotorSetSpeed = Speed; + pMD->TurnParameter = NewTurnParameter; + pMD->MotorRampUpIncrement = 0; + pMD->MotorRampTachoCountStart = pMD->CurrentCaptureCount; + pMD->MotorRampUpCount = 0; + } + } + else + { + if (pMD->MotorSetSpeed <= Speed) + { + NewMotorRunState = MOTOR_RUN_STATE_RUNNING; + } + else + { + pMD->MotorSetSpeed = Speed; + pMD->TurnParameter = NewTurnParameter; + pMD->MotorRampUpIncrement = 0; + pMD->MotorRampTachoCountStart = pMD->CurrentCaptureCount; + pMD->MotorRampUpCount = 0; + } + } + } + } + break; + + case MOTOR_RUN_STATE_RUNNING: + { + pMD->MotorSetSpeed = Speed; + pMD->MotorTargetSpeed = Speed; + pMD->TurnParameter = NewTurnParameter; + + if (pMD->MotorSetSpeed == 0) + { + NewMotorRunState = MOTOR_RUN_STATE_HOLD; + } + } + break; + + case MOTOR_RUN_STATE_RAMPDOWN: + { + if (pMD->MotorTargetSpeed >= 0) + { + if (pMD->MotorSetSpeed <= Speed) + { + NewMotorRunState = MOTOR_RUN_STATE_RUNNING; + } + else + { + pMD->MotorSetSpeed = Speed; + pMD->TurnParameter = NewTurnParameter; + pMD->MotorRampDownIncrement = 0; + pMD->MotorRampTachoCountStart = pMD->CurrentCaptureCount; + pMD->MotorRampDownCount = 0; + } + } + else + { + if (pMD->MotorSetSpeed >= Speed) + { + NewMotorRunState = MOTOR_RUN_STATE_RUNNING; + } + else + { + pMD->MotorSetSpeed = Speed; + pMD->TurnParameter = NewTurnParameter; + pMD->MotorRampDownIncrement = 0; + pMD->MotorRampTachoCountStart = pMD->CurrentCaptureCount; + pMD->MotorRampDownCount = 0; + } + } + } + break; + } + pMD->MotorRunState = NewMotorRunState; + pMD->MotorOverloaded = 0; + } +} + +/* Function used for controlling the Ramp-up periode */ +/* Ramp-up is done with 1 increment in speed every X number of TachoCount, where X depend on duration of the periode and the wanted speed */ +void dOutputRampUpFunction(UBYTE MotorNr) +{ + MOTORDATA * pMD = &(MotorData[MotorNr]); + if (pMD->MotorTargetSpeed == 0) + { + if (pMD->MotorSetSpeed > 0) + { + pMD->MotorTargetSpeed = MIN_MOVEMENT_POWER; + } + else + { + pMD->MotorTargetSpeed = -MIN_MOVEMENT_POWER; + } + } + else + { + if (pMD->MotorRampUpIncrement == 0) + { + SWORD delta = (SWORD)((pMD->MotorTachoCountToRun - pMD->MotorRampTachoCountStart) / (pMD->MotorSetSpeed - pMD->MotorTargetSpeed)); + if (pMD->MotorSetSpeed > 0) + { + pMD->MotorRampUpIncrement = delta; + } + else + { + pMD->MotorRampUpIncrement = -delta; + } + pMD->MotorRampTachoCountOld = pMD->CurrentCaptureCount; + } + if (pMD->MotorSetSpeed > 0) + { + if (pMD->CurrentCaptureCount > (pMD->MotorRampTachoCountOld + pMD->MotorRampUpIncrement)) + { + pMD->MotorTargetSpeed += 1; + pMD->MotorRampTachoCountOld = pMD->CurrentCaptureCount; + pMD->MotorRampUpCount = 0; + } + else + { + if (!(pMD->RegulationMode & REGSTATE_REGULATED)) + { + pMD->MotorRampUpCount++; + if (pMD->MotorRampUpCount > 100) + { + pMD->MotorRampUpCount = 0; + pMD->MotorTargetSpeed++; + } + } + } + } + else + { + if (pMD->CurrentCaptureCount < (pMD->MotorRampTachoCountOld + pMD->MotorRampUpIncrement)) + { + pMD->MotorTargetSpeed -= 1; + pMD->MotorRampTachoCountOld = pMD->CurrentCaptureCount; + pMD->MotorRampUpCount = 0; + } + else + { + if (!(pMD->RegulationMode & REGSTATE_REGULATED)) + { + pMD->MotorRampUpCount++; + if (pMD->MotorRampUpCount > 100) + { + pMD->MotorRampUpCount = 0; + pMD->MotorTargetSpeed--; + } + } + } + } + } + if (pMD->MotorSetSpeed > 0) + { + if ((pMD->CurrentCaptureCount - pMD->MotorRampTachoCountStart) >= (pMD->MotorTachoCountToRun - pMD->MotorRampTachoCountStart)) + { + pMD->MotorTargetSpeed = pMD->MotorSetSpeed; + pMD->MotorRunState = MOTOR_RUN_STATE_IDLE; + } + } + else + { + if ((pMD->CurrentCaptureCount + pMD->MotorRampTachoCountStart) <= (pMD->MotorTachoCountToRun + pMD->MotorRampTachoCountStart)) + { + pMD->MotorTargetSpeed = pMD->MotorSetSpeed; + pMD->MotorRunState = MOTOR_RUN_STATE_IDLE; + } + } + if (pMD->MotorSetSpeed > 0) + { + if (pMD->MotorTargetSpeed > pMD->MotorSetSpeed) + { + pMD->MotorTargetSpeed = pMD->MotorSetSpeed; + } + } + else + { + if (pMD->MotorTargetSpeed < pMD->MotorSetSpeed) + { + pMD->MotorTargetSpeed = pMD->MotorSetSpeed; + } + } + if (pMD->RegulationMode == REGSTATE_IDLE) + { + pMD->MotorActualSpeed = pMD->MotorTargetSpeed; + } +} + +/* Function used for controlling the Ramp-down periode */ +/* Ramp-down is done with 1 decrement in speed every X number of TachoCount, where X depend on duration of the periode and the wanted speed */ +void dOutputRampDownFunction(UBYTE MotorNr) +{ + MOTORDATA * pMD = &(MotorData[MotorNr]); + if (pMD->MotorRampDownIncrement == 0) + { + if (pMD->MotorTargetSpeed > 0) + { + if ((pMD->MotorTargetSpeed > MIN_MOVEMENT_POWER) && (pMD->MotorSetSpeed == 0)) + { + pMD->MotorRampDownIncrement = ((pMD->MotorTachoCountToRun - pMD->CurrentCaptureCount) / ((pMD->MotorTargetSpeed - pMD->MotorSetSpeed) - MIN_MOVEMENT_POWER)); + } + else + { + pMD->MotorRampDownIncrement = ((pMD->MotorTachoCountToRun - pMD->CurrentCaptureCount) / (pMD->MotorTargetSpeed - pMD->MotorSetSpeed)); + } + } + else + { + if ((pMD->MotorTargetSpeed < -MIN_MOVEMENT_POWER) && (pMD->MotorSetSpeed == 0)) + { + pMD->MotorRampDownIncrement = (-((pMD->MotorTachoCountToRun - pMD->CurrentCaptureCount) / ((pMD->MotorTargetSpeed - pMD->MotorSetSpeed) + MIN_MOVEMENT_POWER))); + } + else + { + pMD->MotorRampDownIncrement = (-((pMD->MotorTachoCountToRun - pMD->CurrentCaptureCount) / (pMD->MotorTargetSpeed - pMD->MotorSetSpeed))); + } + } + pMD->MotorRampTachoCountOld = pMD->CurrentCaptureCount; + } + if (pMD->MotorTargetSpeed > 0) + { + if (pMD->CurrentCaptureCount > (pMD->MotorRampTachoCountOld + (SLONG)pMD->MotorRampDownIncrement)) + { + pMD->MotorTargetSpeed--; + if (pMD->MotorTargetSpeed < MIN_MOVEMENT_POWER) + { + pMD->MotorTargetSpeed = MIN_MOVEMENT_POWER; + } + pMD->MotorRampTachoCountOld = pMD->CurrentCaptureCount; + pMD->MotorRampDownCount = 0; + dOutputRampDownSynch(MotorNr); + } + else + { + if (!(pMD->RegulationMode & REGSTATE_REGULATED)) + { + pMD->MotorRampDownCount++; + if (pMD->MotorRampDownCount > (UWORD)(30 * pMD->MotorRampDownIncrement)) + { + pMD->MotorRampDownCount = (UWORD)(20 * pMD->MotorRampDownIncrement); + pMD->MotorTargetSpeed++; + } + } + } + } + else + { + if (pMD->CurrentCaptureCount < (pMD->MotorRampTachoCountOld + (SLONG)pMD->MotorRampDownIncrement)) + { + pMD->MotorTargetSpeed++; + if (pMD->MotorTargetSpeed > -MIN_MOVEMENT_POWER) + { + pMD->MotorTargetSpeed = -MIN_MOVEMENT_POWER; + } + pMD->MotorRampTachoCountOld = pMD->CurrentCaptureCount; + pMD->MotorRampDownCount = 0; + dOutputRampDownSynch(MotorNr); + } + else + { + if (!(pMD->RegulationMode & REGSTATE_REGULATED)) + { + pMD->MotorRampDownCount++; + if (pMD->MotorRampDownCount > (UWORD)(30 * (-pMD->MotorRampDownIncrement))) + { + pMD->MotorRampDownCount = (UWORD)(20 * (-pMD->MotorRampDownIncrement)); + pMD->MotorTargetSpeed--; + } + } + } + } + if ((pMD->RegulationMode & REGSTATE_SYNCHRONE) && (pMD->TurnParameter != 0)) + { + dOutputSyncTachoLimitControl(MotorNr); + if (pMD->MotorRunState == MOTOR_RUN_STATE_IDLE) + { + dOutputMotorReachedTachoLimit(MotorNr); + } + } + else + { + if (pMD->MotorTargetSpeed > 0) + { + if (pMD->CurrentCaptureCount >= pMD->MotorTachoCountToRun) + { + dOutputMotorReachedTachoLimit(MotorNr); + } + } + else + { + if (pMD->CurrentCaptureCount <= pMD->MotorTachoCountToRun) + { + dOutputMotorReachedTachoLimit(MotorNr); + } + } + } + if (pMD->RegulationMode == REGSTATE_IDLE) + { + pMD->MotorActualSpeed = pMD->MotorTargetSpeed; + } +} + +/* Function used to tell whether the wanted position is obtained */ +void dOutputTachoLimitControl(UBYTE MotorNr) +{ + MOTORDATA * pMD = &(MotorData[MotorNr]); + if (pMD->RegulationMode & REGSTATE_POSITION) + { + /* No limit when doing absolute position regulation. */ + return; + } + if (pMD->MotorRunForever == 0) + { + if (pMD->RegulationMode & REGSTATE_SYNCHRONE) + { + dOutputSyncTachoLimitControl(MotorNr); + } + else + { + if (pMD->MotorSetSpeed > 0) + { + if ((pMD->CurrentCaptureCount >= pMD->MotorTachoCountToRun)) + { + pMD->MotorRunState = MOTOR_RUN_STATE_IDLE; + pMD->RegulationMode = REGSTATE_IDLE; + } + } + else + { + if (pMD->MotorSetSpeed < 0) + { + if (pMD->CurrentCaptureCount <= pMD->MotorTachoCountToRun) + { + pMD->MotorRunState = MOTOR_RUN_STATE_IDLE; + pMD->RegulationMode = REGSTATE_IDLE; + } + } + } + } + } + else + { + if (pMD->CurrentCaptureCount > MAX_COUNT_TO_RUN) + { + pMD->CurrentCaptureCount = 0; + } + if (pMD->MotorTargetSpeed != 0) + { + pMD->MotorTachoCountToRun = pMD->CurrentCaptureCount; + } + } + if (pMD->RegulationMode == REGSTATE_IDLE) + { + pMD->MotorActualSpeed = pMD->MotorTargetSpeed; + } +} + +/* Function used to decrease speed slowly when the motor is set to idle */ +void dOutputMotorIdleControl(UBYTE MotorNr) +{ + INSERTMode(MotorNr, COAST_MOTOR_MODE); + + MOTORDATA * pMD = &(MotorData[MotorNr]); + + if (pMD->MotorActualSpeed != 0) + { + if (pMD->MotorActualSpeed > 0) + { + pMD->MotorActualSpeed--; + } + else + { + pMD->MotorActualSpeed++; + } + } + + if (pMD->MotorTargetSpeed != 0) + { + if (pMD->MotorTargetSpeed > 0) + { + pMD->MotorTargetSpeed--; + } + else + { + pMD->MotorTargetSpeed++; + } + } + + if (pMD->MotorSetSpeed != 0) + { + if (pMD->MotorSetSpeed > 0) + { + pMD->MotorSetSpeed--; + } + else + { + pMD->MotorSetSpeed++; + } + } +} + +/* Check if Value is between [-Limit:Limit], and change it if it is not the case. */ +SLONG dOutputBound(SLONG Value, SLONG Limit) +{ + if (Value > Limit) + return Limit; + else if (Value < -Limit) + return -Limit; + else + return Value; +} + +/* Function called to evaluate which regulation princip that need to run and which MotorNr to use (I.E.: Which motors are synched together)*/ +void dOutputRegulateMotor(UBYTE MotorNr) +{ + UBYTE SyncMotorOne; + UBYTE SyncMotorTwo; + + MOTORDATA * pMD = &(MotorData[MotorNr]); + if (pMD->RegulationMode & REGSTATE_POSITION) + { + dOutputAbsolutePositionRegulation(MotorNr); + } + else if (pMD->RegulationMode & REGSTATE_REGULATED) + { + dOutputCalculateMotorPosition(MotorNr); + } + else + { + if (pMD->RegulationMode & REGSTATE_SYNCHRONE) + { + dOutputMotorSyncStatus(MotorNr, &SyncMotorOne, &SyncMotorTwo); + + if ((SyncMotorOne != 0xFF) &&(SyncMotorTwo != 0xFF)) + { + dOutputSyncMotorPosition(SyncMotorOne, SyncMotorTwo); + } + } + } +} + +/* Compute PID regulation result for a given error. */ +SLONG dOutputPIDRegulation(UBYTE MotorNr, SLONG PositionError) +{ + SLONG PValue, DValue, IValue, TotalRegValue; + + MOTORDATA *pMD = &MotorData[MotorNr]; + + PositionError = dOutputBound (PositionError, 32000); + + PValue = PositionError * (pMD->RegPParameter/REG_CONST_DIV); + + DValue = (PositionError - pMD->OldPositionError) * (pMD->RegDParameter/REG_CONST_DIV); + pMD->OldPositionError = PositionError; + + pMD->AccError = (pMD->AccError * 3 + PositionError) / 4; + pMD->AccError = dOutputBound (pMD->AccError, 800); + + IValue = pMD->AccError * (pMD->RegIParameter/REG_CONST_DIV); + + if (!(RegulationOptions & REGOPTION_NO_SATURATION)) + { + PValue = dOutputBound (PValue, REG_MAX_VALUE); + IValue = dOutputBound (IValue, REG_MAX_VALUE); + } + + TotalRegValue = (PValue + IValue + DValue) / 2; + + if (TotalRegValue > MAXIMUM_SPEED_FW) + { + TotalRegValue = MAXIMUM_SPEED_FW; + pMD->MotorOverloaded = 1; + } + else if (TotalRegValue < MAXIMUM_SPEED_RW) + { + TotalRegValue = MAXIMUM_SPEED_RW; + pMD->MotorOverloaded = 1; + } + + return TotalRegValue; +} + +/* Compute integer change for this regulation step, according to value and + * previous fractional error. + * Used for values which are expressed as "per SPEED_TIME" to translate them + * in "per RegulationTime".*/ +SLONG dOutputFractionalChange(SLONG Value, SWORD *FracError) +{ + SLONG IntegerChange; + + /* Apply fractional change in case RegulationTime is different from + * SPEED_TIME. In this case, fractional part is accumulated until it reach + * one half (with "one" being SPEED_TIME). This is use the same principle + * as the Bresenham algorithm. */ + IntegerChange = Value * RegulationTime / SPEED_TIME; + *FracError += Value * RegulationTime % SPEED_TIME; + if (*FracError > SPEED_TIME / 2) + { + *FracError -= SPEED_TIME; + IntegerChange++; + } + else if (*FracError < -SPEED_TIME / 2) + { + *FracError += SPEED_TIME; + IntegerChange--; + } + + return IntegerChange; +} + +/* Filter speed according to motor maximum speed and acceleration. */ +void dOutputSpeedFilter(UBYTE MotorNr, SLONG PositionDiff) +{ + /* Inputs: + * - PositionDiff: difference between current position and position to reach. + * - MotorMaxAcceleration: maximum speed change per regulation period (or 0 for unlimited). + * - MotorMaxSpeed: maximum motor speed (can not be zero, or do not call this function). + * Output: + * - MotorTargetSpeed: speed to regulate on motor. + */ + MOTORDATA *pMD = &MotorData[MotorNr]; + SLONG IdealSpeed; + SLONG PositionDiffAbs = ABS (PositionDiff); + /* Should be able to brake on time. */ + if (pMD->MotorMaxAcceleration + && PositionDiffAbs < MAXIMUM_SPEED_FW * MAXIMUM_SPEED_FW / 2) + { + IdealSpeed = sqrtf (2 * PositionDiffAbs * pMD->MotorMaxAcceleration); + IdealSpeed = dOutputBound (IdealSpeed, pMD->MotorMaxSpeed); + } + else + { + /* Do not go past consign. */ + IdealSpeed = MIN (PositionDiffAbs, pMD->MotorMaxSpeed); + } + /* Apply sign. */ + if (PositionDiff < 0) + { + IdealSpeed = -IdealSpeed; + } + /* Check max acceleration. */ + SLONG SpeedDiff = IdealSpeed - pMD->MotorTargetSpeed; + if (pMD->MotorMaxAcceleration) + { + SLONG MaxSpeedChange = dOutputFractionalChange (pMD->MotorMaxAcceleration, &pMD->SpeedFracError); + SpeedDiff = dOutputBound (SpeedDiff, MaxSpeedChange); + } + pMD->MotorTargetSpeed += SpeedDiff; +} + +/* Absolute position regulation. */ +void dOutputAbsolutePositionRegulation(UBYTE MotorNr) +{ + /* Inputs: + * - CurrentCaptureCount: current motor position. + * - MotorTachoCountToRun: wanted position, filtered with speed and acceleration. + * + * Outputs: + * - MotorActualSpeed: power to be applied to motor. + * - MotorOverloaded: set if MotorActualSpeed reached maximum. + */ + SLONG PositionChange; + SLONG PositionError; + SLONG TotalRegValue; + + MOTORDATA *pMD = &MotorData[MotorNr]; + + /* Position update. */ + if (pMD->MotorMaxSpeed) + { + dOutputSpeedFilter (MotorNr, pMD->MotorTachoCountToRun - pMD->MotorTachoCountTarget); + PositionChange = dOutputFractionalChange (pMD->MotorTargetSpeed * MAX_CAPTURE_COUNT / INPUT_SCALE_FACTOR, &pMD->PositionFracError); + pMD->MotorTachoCountTarget += PositionChange; + } + else + { + pMD->MotorTachoCountTarget = pMD->MotorTachoCountToRun; + } + + /* Regulation. */ + PositionError = pMD->MotorTachoCountTarget - pMD->CurrentCaptureCount; + TotalRegValue = dOutputPIDRegulation (MotorNr, PositionError); + + pMD->MotorActualSpeed = TotalRegValue; +} + +/* Regulation function used when Position regulation is enabled */ +/* The regulation form only control one motor at a time */ +void dOutputCalculateMotorPosition(UBYTE MotorNr) +{ + SLONG PositionError; + SLONG TotalRegValue; + SLONG PositionChange; + + MOTORDATA * pMD = &(MotorData[MotorNr]); + + PositionChange = dOutputFractionalChange (pMD->MotorTargetSpeed * MAX_CAPTURE_COUNT / INPUT_SCALE_FACTOR, &pMD->PositionFracError); + + PositionError = (pMD->OldPositionError - pMD->DeltaCaptureCount) + PositionChange; + + TotalRegValue = dOutputPIDRegulation (MotorNr, PositionError); + + pMD->MotorActualSpeed = (SBYTE)TotalRegValue; +} + +/* Regulation function used when syncrhonization regulation is enabled */ +/* The regulation form controls two motors at a time */ +void dOutputSyncMotorPosition(UBYTE MotorOne, UBYTE MotorTwo) +{ + SLONG TempTurnParameter; + SLONG PValue; + SLONG IValue; + SLONG DValue; + SLONG CorrectionValue; + SLONG MotorSpeed; + + MOTORDATA * pOne = &(MotorData[MotorOne]); + MOTORDATA * pTwo = &(MotorData[MotorTwo]); + SyncData.SyncTachoDif = (SLONG)((pOne->MotorBlockTachoCount) - (pTwo->MotorBlockTachoCount)); + + if (pOne->TurnParameter != 0) + { + if ((pOne->MotorBlockTachoCount != 0) || (pTwo->MotorBlockTachoCount != 0)) + { + if (pOne->MotorTargetSpeed >= 0) + { + if (pOne->TurnParameter > 0) + { + TempTurnParameter = (SLONG)(((SLONG)pTwo->TurnParameter * (SLONG)pTwo->MotorTargetSpeed)/100); + } + else + { + TempTurnParameter = (SLONG)(((SLONG)pOne->TurnParameter * (SLONG)pOne->MotorTargetSpeed)/100); + } + } + else + { + if (pOne->TurnParameter > 0) + { + TempTurnParameter = (SLONG)(((SLONG)pOne->TurnParameter * (-(SLONG)pOne->MotorTargetSpeed))/100); + } + else + { + TempTurnParameter = (SLONG)(((SLONG)pTwo->TurnParameter * (-(SLONG)pTwo->MotorTargetSpeed))/100); + } + } + } + else + { + TempTurnParameter = pOne->TurnParameter; + } + } + else + { + TempTurnParameter = 0; + } + + SyncData.SyncTurnParameter += (SLONG)(((TempTurnParameter * (MAX_CAPTURE_COUNT))/INPUT_SCALE_FACTOR)*2); + //SyncTurnParameter should ophold difference between the two motors. + + SyncData.SyncTachoDif += SyncData.SyncTurnParameter; + SyncData.SyncTachoDif = dOutputBound (SyncData.SyncTachoDif, 500); + + PValue = SyncData.SyncTachoDif * (pOne->RegPParameter/REG_CONST_DIV); + + DValue = (SyncData.SyncTachoDif - SyncData.SyncOldError) * (pOne->RegDParameter/REG_CONST_DIV); + SyncData.SyncOldError = (SWORD)SyncData.SyncTachoDif; + + SyncData.SyncAccError += (SWORD)SyncData.SyncTachoDif; + SyncData.SyncAccError = dOutputBound (SyncData.SyncAccError, 900); + + IValue = SyncData.SyncAccError * (pOne->RegIParameter/REG_CONST_DIV); + + CorrectionValue = (PValue + IValue + DValue) / 4; + + MotorSpeed = pOne->MotorTargetSpeed - CorrectionValue; + MotorSpeed = dOutputBound (MotorSpeed, MAXIMUM_SPEED_FW); + + if (pOne->TurnParameter != 0) + { + if (pOne->MotorTargetSpeed > 0) + { + MotorSpeed = dOutputBound (MotorSpeed, pOne->MotorTargetSpeed); + } + else + { + MotorSpeed = dOutputBound (MotorSpeed, -pOne->MotorTargetSpeed); + } + } + pOne->MotorActualSpeed = (SBYTE)MotorSpeed; + + MotorSpeed = pTwo->MotorTargetSpeed + CorrectionValue; + MotorSpeed = dOutputBound (MotorSpeed, MAXIMUM_SPEED_FW); + + if (pOne->TurnParameter != 0) + { + if (pTwo->MotorTargetSpeed > 0) + { + MotorSpeed = dOutputBound (MotorSpeed, pTwo->MotorTargetSpeed); + } + else + { + MotorSpeed = dOutputBound (MotorSpeed, -pTwo->MotorTargetSpeed); + } + } + pTwo->MotorActualSpeed = (SBYTE)MotorSpeed; +} + +//Called when the motor is ramping down +void dOutputMotorReachedTachoLimit(UBYTE MotorNr) +{ + MOTORDATA * pOne = &(MotorData[MotorNr]); + if (pOne->RegulationMode & REGSTATE_SYNCHRONE) + { + UBYTE MotorOne, MotorTwo; + MotorOne = MotorNr; + MotorTwo = 0xFF; + UBYTE i; + for(i = MOTOR_A; i <= MOTOR_C; i++) { + if (i == MotorOne) + continue; + if (MotorData[i].RegulationMode & REGSTATE_SYNCHRONE) { + MotorTwo = i; + break; + } + } + pOne->MotorSetSpeed = 0; + pOne->MotorTargetSpeed = 0; + pOne->MotorActualSpeed = 0; + pOne->MotorRunState = MOTOR_RUN_STATE_IDLE; + pOne->RegulationMode = REGSTATE_IDLE; + if (MotorTwo != 0xFF) { + MOTORDATA * pTwo = &(MotorData[MotorTwo]); + pTwo->MotorSetSpeed = 0; + pTwo->MotorTargetSpeed = 0; + pTwo->MotorActualSpeed = 0; + pTwo->MotorRunState = MOTOR_RUN_STATE_IDLE; + pTwo->RegulationMode = REGSTATE_IDLE; + } + } + else + { + if (pOne->MotorSetSpeed == 0) + { + pOne->MotorTargetSpeed = 0; + pOne->MotorActualSpeed = 0; + } + pOne->MotorRunState = MOTOR_RUN_STATE_IDLE; + pOne->RegulationMode = REGSTATE_IDLE; + } +} + +/* Function used for control tacho limit when motors are synchronised */ +/* Special control is needed when the motor are turning */ +void dOutputSyncTachoLimitControl(UBYTE MotorNr) +{ + UBYTE MotorOne, MotorTwo; + + MotorOne = MotorNr; + MotorTwo = 0xFF; + // Synchronisation is done two times, as this function is called for each + // motor. This is the same behaviour as previous code. + UBYTE i; + for(i = MOTOR_A; i <= MOTOR_C; i++) { + if (i == MotorOne) + continue; + if (MotorData[i].RegulationMode & REGSTATE_SYNCHRONE) { + MotorTwo = i; + break; + } + } + if (MotorTwo == 0xFF) + MotorOne = 0xFF; + + if ((MotorOne != 0xFF) && (MotorTwo != 0xFF)) + { + MOTORDATA * pOne = &(MotorData[MotorOne]); + MOTORDATA * pTwo = &(MotorData[MotorTwo]); + if (pOne->TurnParameter != 0) + { + if (pOne->TurnParameter > 0) + { + if (pTwo->MotorTargetSpeed >= 0) + { + if ((SLONG)(pTwo->CurrentCaptureCount >= pTwo->MotorTachoCountToRun)) + { + pOne->MotorRunState = MOTOR_RUN_STATE_IDLE; + pTwo->MotorRunState = MOTOR_RUN_STATE_IDLE; + + pOne->CurrentCaptureCount = pTwo->CurrentCaptureCount; + pOne->MotorTachoCountToRun = pTwo->MotorTachoCountToRun; + } + } + else + { + if ((SLONG)(pOne->CurrentCaptureCount <= pOne->MotorTachoCountToRun)) + { + pOne->MotorRunState = MOTOR_RUN_STATE_IDLE; + pTwo->MotorRunState = MOTOR_RUN_STATE_IDLE; + + pTwo->CurrentCaptureCount = pOne->CurrentCaptureCount; + pTwo->MotorTachoCountToRun = pOne->MotorTachoCountToRun; + } + } + } + else + { + if (pOne->MotorTargetSpeed >= 0) + { + if ((SLONG)(pOne->CurrentCaptureCount >= pOne->MotorTachoCountToRun)) + { + pOne->MotorRunState = MOTOR_RUN_STATE_IDLE; + pTwo->MotorRunState = MOTOR_RUN_STATE_IDLE; + + pTwo->CurrentCaptureCount = pOne->CurrentCaptureCount; + pTwo->MotorTachoCountToRun = pOne->MotorTachoCountToRun; + } + } + else + { + if ((SLONG)(pTwo->CurrentCaptureCount <= pTwo->MotorTachoCountToRun)) + { + pOne->MotorRunState = MOTOR_RUN_STATE_IDLE; + pTwo->MotorRunState = MOTOR_RUN_STATE_IDLE; + + pOne->CurrentCaptureCount = pTwo->CurrentCaptureCount; + pOne->MotorTachoCountToRun = pTwo->MotorTachoCountToRun; + } + } + } + } + else + { + if (pOne->MotorSetSpeed > 0) + { + if ((pOne->CurrentCaptureCount >= pOne->MotorTachoCountToRun) || (pTwo->CurrentCaptureCount >= pTwo->MotorTachoCountToRun)) + { + pOne->MotorRunState = MOTOR_RUN_STATE_IDLE; + pTwo->MotorRunState = MOTOR_RUN_STATE_IDLE; + } + } + else + { + if (pOne->MotorSetSpeed < 0) + { + if ((pOne->CurrentCaptureCount <= pOne->MotorTachoCountToRun) || (pTwo->CurrentCaptureCount <= pTwo->MotorTachoCountToRun)) + { + pOne->MotorRunState = MOTOR_RUN_STATE_IDLE; + pTwo->MotorRunState = MOTOR_RUN_STATE_IDLE; + } + } + } + } + } +} + +/* Function which can evaluate which motor are synched */ +void dOutputMotorSyncStatus(UBYTE MotorNr, UBYTE *SyncMotorOne, UBYTE *SyncMotorTwo) +{ + if (MotorNr < MOTOR_C) + { + if (MotorNr == MOTOR_A) + { + *SyncMotorOne = MotorNr; + *SyncMotorTwo = *SyncMotorOne + 1; + if (MotorData[*SyncMotorTwo].RegulationMode & REGSTATE_SYNCHRONE) + { + //Synchronise motor A & B + } + else + { + *SyncMotorTwo = *SyncMotorOne + 2; + if (MotorData[*SyncMotorTwo].RegulationMode & REGSTATE_SYNCHRONE) + { + //Synchronise motor A & C + } + else + { + //Only Motor A has Sync setting => Do nothing, treat motor as motor without regulation + *SyncMotorTwo = 0xFF; + } + } + } + if (MotorNr == MOTOR_B) + { + *SyncMotorOne = MotorNr; + *SyncMotorTwo = *SyncMotorOne + 1; + if (MotorData[*SyncMotorTwo].RegulationMode & REGSTATE_SYNCHRONE) + { + if (!(MotorData[MOTOR_A].RegulationMode & REGSTATE_SYNCHRONE)) + { + //Synchronise motor B & C + } + } + else + { + //Only Motor B has Sync settings or Motor is sync. with Motor A and has therefore already been called + *SyncMotorTwo = 0xFF; + } + } + } + else + { + *SyncMotorOne = 0xFF; + *SyncMotorTwo = 0xFF; + } +} +/* Function which is called when motors are synchronized and the motor position is reset */ +void dOutputResetSyncMotors(UBYTE MotorNr) +{ + UBYTE MotorOne, MotorTwo; + + MotorOne = MotorNr; + MotorTwo = 0xFF; + UBYTE i; + for(i = MOTOR_A; i <= MOTOR_C; i++) { + if (i == MotorOne) + continue; + if (MotorData[i].RegulationMode & REGSTATE_SYNCHRONE) { + MotorTwo = i; + break; + } + } + if (MotorTwo == 0xFF) + MotorOne = 0xFF; + + MOTORDATA * pMD = &(MotorData[MotorNr]); + if ((MotorOne != 0xFF) && (MotorTwo != 0xFF)) + { + MOTORDATA * pTwo = &(MotorData[MotorTwo]); + pMD->CurrentCaptureCount = 0; + pMD->MotorTachoCountToRun = 0; + pMD->MotorTachoCountTarget = 0; + pTwo->CurrentCaptureCount = 0; + pTwo->MotorTachoCountToRun = 0; + pTwo->MotorTachoCountTarget = 0; + } + else + { + pMD->CurrentCaptureCount = 0; + pMD->MotorTachoCountToRun = 0; + pMD->MotorTachoCountTarget = 0; + } +} + +/* Function which is called when motors are synchronized and motor is ramping down */ +void dOutputRampDownSynch(UBYTE MotorNr) +{ + UBYTE MotorOne, MotorTwo; + + MotorOne = MotorNr; + MotorTwo = 0xFF; + UBYTE i; + for(i = MOTOR_A; i <= MOTOR_C; i++) { + if (i == MotorOne) + continue; + if (MotorData[i].RegulationMode & REGSTATE_SYNCHRONE) { + MotorTwo = i; + break; + } + } + if (MotorTwo == 0xFF) + MotorOne = 0xFF; + + if ((MotorOne != 0xFF) && (MotorTwo != 0xFF)) + { + MOTORDATA * pOne = &(MotorData[MotorOne]); + MOTORDATA * pTwo = &(MotorData[MotorTwo]); + if (pOne->TurnParameter != 0) + { + if (pOne->TurnParameter > 0) + { + if (pOne->MotorTargetSpeed >= 0) + { + if (pTwo->MotorActualSpeed < 0) + { + pTwo->MotorTargetSpeed--; + } + } + else + { + if (pTwo->MotorActualSpeed > 0) + { + pTwo->MotorTargetSpeed++; + } + } + } + else + { + if (pOne->MotorTargetSpeed >= 0) + { + if (pTwo->MotorActualSpeed < 0) + { + pTwo->MotorTargetSpeed--; + } + } + else + { + if (pTwo->MotorActualSpeed > 0) + { + pTwo->MotorTargetSpeed++; + } + } + } + } + } +} + diff --git a/src/d_output.h b/src/d_output.h new file mode 100644 index 0000000..4d5189b --- /dev/null +++ b/src/d_output.h @@ -0,0 +1,103 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: d_output.h $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_outp $ +// +// Platform C +// + +#ifndef D_OUTPUT +#define D_OUTPUT + +#define NEW_MOTOR + +#ifdef NEW_MOTOR + +//Constant reffering to new motor +#define REG_CONST_DIV 32 // Constant which the PID constants value will be divided with +#define DEFAULT_P_GAIN_FACTOR 96//3 +#define DEFAULT_I_GAIN_FACTOR 32//1 +#define DEFAULT_D_GAIN_FACTOR 32//1 +#define MIN_MOVEMENT_POWER 10 +#define MAX_CAPTURE_COUNT 100 + +#else + +//Constant reffering to Old motor +#define REG_CONST_DIV 1 // Constant which the PID constants value will be divided with +#define DEFAULT_P_GAIN_FACTOR 3 +#define DEFAULT_I_GAIN_FACTOR 1 +#define DEFAULT_D_GAIN_FACTOR 1 +#define MIN_MOVEMENT_POWER 30 +#define MAX_CAPTURE_COUNT 80 + +#endif + +#define DEFAULT_MAX_SPEED 80 +#define DEFAULT_MAX_ACCELERATION 20 + +#define REGULATION_TIME 100 // Measured in 1 mS, regulation interval + +//Constant reffering to RegMode parameter +#define REGSTATE_IDLE 0x00 +#define REGSTATE_REGULATED 0x01 +#define REGSTATE_SYNCHRONE 0x02 +#define REGSTATE_POSITION 0x04 + +//Constant reffering to RunState parameter +#define MOTOR_RUN_STATE_IDLE 0x00 +#define MOTOR_RUN_STATE_RAMPUP 0x10 +#define MOTOR_RUN_STATE_RUNNING 0x20 +#define MOTOR_RUN_STATE_RAMPDOWN 0x40 +#define MOTOR_RUN_STATE_HOLD 0x60 + +// Constants related to Regulation Options +#define REGOPTION_NO_SATURATION 0x01 // Do not limit intermediary regulation results + + +enum +{ + MOTOR_A, + MOTOR_B, + MOTOR_C +}; + +void dOutputInit(void); +void dOutputExit(void); + +void dOutputCtrl(void); +void dOutputGetMotorParameters(UBYTE *CurrentMotorSpeed, SLONG *TachoCount, SLONG *BlockTachoCount, UBYTE *RunState, UBYTE *MotorOverloaded, SLONG *RotationCount); +void dOutputSetMode(UBYTE MotorNr, UBYTE Mode); +void dOutputSetSpeed (UBYTE MotorNr, UBYTE NewMotorRunState, SBYTE Speed, SBYTE TurnParameter); +void dOutputEnableRegulation(UBYTE MotorNr, UBYTE RegulationMode); +void dOutputDisableRegulation(UBYTE MotorNr); +void dOutputSetTachoLimit(UBYTE MotorNr, ULONG TachoCntToTravel); +void dOutputResetTachoLimit(UBYTE MotorNr); +void dOutputResetBlockTachoLimit(UBYTE MotorNr); +void dOutputResetRotationCaptureCount(UBYTE MotorNr); +void dOutputSetPIDParameters(UBYTE MotorNr, UBYTE NewRegPParameter, UBYTE NewRegIParameter, UBYTE NewRegDParameter); +void dOutputSetMax(UBYTE MotorNr, SBYTE NewMaxSpeed, SBYTE NewMaxAcceleration); +void dOutputSetRegulationTime(UBYTE NewRegulationTime); +void dOutputSetRegulationOptions(UBYTE NewRegulationOptions); + +void dOutputRegulateMotor(UBYTE MotorNr); +void dOutputCalculateRampUpParameter(UBYTE MotorNr, ULONG NewTachoLimit); +void dOutputRampDownFunction(UBYTE MotorNr); +void dOutputRampUpFunction(UBYTE MotorNr); +void dOutputTachoLimitControl(UBYTE MotorNr); +void dOutputAbsolutePositionRegulation(UBYTE MotorNr); +void dOutputCalculateMotorPosition(UBYTE MotorNr); +void dOutputSyncMotorPosition(UBYTE MotorOne, UBYTE MotorTwo); +void dOutputMotorReachedTachoLimit(UBYTE MotorNr); +void dOutputMotorIdleControl(UBYTE MotorNr); +void dOutputSyncTachoLimitControl(UBYTE MotorNr); +void dOutputMotorSyncStatus(UBYTE MotorNr, UBYTE *SyncMotorOne, UBYTE *SyncMotorTwo); +void dOutputResetSyncMotors(UBYTE MotorNr); + +#endif diff --git a/src/d_output.r b/src/d_output.r new file mode 100644 index 0000000..1a30c5f --- /dev/null +++ b/src/d_output.r @@ -0,0 +1,306 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: d_output.r $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_outp $ +// +// Platform C +// + +#ifdef SAM7S256 + +#if defined (PROTOTYPE_PCB_3) || (PROTOTYPE_PCB_4) + +#define MOTOR_A_DIR AT91C_PIO_PA1 +#define MOTOR_A_INT AT91C_PIO_PA15 + +#define MOTOR_B_DIR AT91C_PIO_PA9 +#define MOTOR_B_INT AT91C_PIO_PA26 + +#define MOTOR_C_DIR AT91C_PIO_PA8 +#define MOTOR_C_INT AT91C_PIO_PA0 + +#else + +#define MOTOR_A_DIR AT91C_PIO_PA1 +#define MOTOR_A_INT AT91C_PIO_PA15 + +#define MOTOR_B_DIR AT91C_PIO_PA9 +#define MOTOR_B_INT AT91C_PIO_PA26 + +#define MOTOR_C_DIR AT91C_PIO_PA8 +#define MOTOR_C_INT AT91C_PIO_PA27 + +#endif + +#define FORWARD 0x01 +#define REVERSE -0x01 + +#define TIMER_0_ID12 (1L << AT91C_ID_TC0) +#define TIMER_1_ID13 (1L << AT91C_ID_TC1) +#define TIMER_2_ID14 (1L << AT91C_ID_TC2) + +typedef struct +{ + SLONG TachoCountTable; + SLONG TachoCountTableOld; + SBYTE MotorDirection; +}TACHOPARAMETERS; + +static TACHOPARAMETERS MotorTachoValue[3]; + +#define OUTPUTInit {\ + UBYTE Tmp;\ + for (Tmp = 0; Tmp < NOS_OF_AVR_OUTPUTS; Tmp++)\ + {\ + IoToAvr.PwmValue[Tmp] = 0;\ + }\ + IoToAvr.OutputMode = 0x00;\ + IoToAvr.PwmFreq = 8;\ + } + +#define INSERTSpeed(Motor, Speed) IoToAvr.PwmValue[Motor] = Speed + +#define INSERTMode(Motor, Mode) if (Mode & 0x02)\ + {\ + IoToAvr.OutputMode |= (0x01 << Motor);\ + }\ + else\ + {\ + IoToAvr.OutputMode &= ~(0x01 << Motor);\ + } + +#define ENABLEDebugOutput {\ + *AT91C_PIOA_PER = 0x20000000; /* Enable PIO on PA029 */\ + *AT91C_PIOA_OER = 0x20000000; /* PA029 set to Output */\ + } + +#define SETDebugOutputHigh *AT91C_PIOA_SODR = 0x20000000 + +#define SETDebugOutputLow *AT91C_PIOA_CODR = 0x20000000 + +#define ENABLECaptureMotorA {\ + *AT91C_PIOA_PDR = MOTOR_A_INT; /* Disable PIO on PA15 */\ + *AT91C_PIOA_BSR = MOTOR_A_INT; /* Enable Peripheral B on PA15 */\ + *AT91C_PIOA_PPUDR = MOTOR_A_INT | MOTOR_A_DIR; /* Disable Pull Up resistor on PA15 & PA1 */\ + *AT91C_PIOA_PER = MOTOR_A_DIR; /* Enable PIO on PA1 */\ + *AT91C_PIOA_ODR = MOTOR_A_DIR; /* PA1 set to input */\ + *AT91C_PIOA_IFER = MOTOR_A_INT | MOTOR_A_DIR; /* Enable filter on PA15 & PA1 */\ + *AT91C_PMC_PCER = TIMER_1_ID13; /* Enable clock for TC1*/\ + *AT91C_TCB_BMR = AT91C_TCB_TC1XC1S_NONE; /* No external clock signal XC2 */\ + *AT91C_TCB_BCR = 0x0; /* Clear SYNC */\ + *AT91C_TC1_CMR = *AT91C_TC1_CMR & 0X00000000; /* Clear all bits in TC1_CMR */\ + *AT91C_TC1_CMR = *AT91C_TC1_CMR & 0xFFFF7FFF; /* Enable capture mode */\ + *AT91C_TC1_CMR = *AT91C_TC1_CMR | AT91C_TC_CLKS_TIMER_DIV5_CLOCK; /* Set clock for timer to Clock5 = div 1024*/\ + *AT91C_TC1_CMR = *AT91C_TC1_CMR | AT91C_TC_ABETRG; /* Use external trigger for TIO1*/\ + *AT91C_TC1_CMR = *AT91C_TC1_CMR | AT91C_TC_EEVTEDG_BOTH; /* Trigger on both edges */\ + *AT91C_TC1_CMR = *AT91C_TC1_CMR | AT91C_TC_LDRA_RISING; /* RA loading register set */\ + *AT91C_AIC_IDCR = TIMER_1_ID13; /* Irq controller setup */\ + AT91C_AIC_SVR[13] = (unsigned int)CaptureAInt; \ + AT91C_AIC_SMR[13] = 0x05; /* Enable trigger on level */\ + *AT91C_AIC_ICCR = TIMER_1_ID13; /* Clear interrupt register PID13*/\ + *AT91C_TC1_IDR = 0xFF; /* Disable all interrupt from TC1 */\ + *AT91C_TC1_IER = 0x80; /* Enable interrupt from external trigger */\ + *AT91C_AIC_IECR = TIMER_1_ID13; /* Enable interrupt from TC1 */\ + *AT91C_TC1_CCR = 0x00; /* Clear registers before setting */\ + *AT91C_TC1_CCR = AT91C_TC_CLKEN; /* Enable clock */\ + } + +#define ENABLECaptureMotorB {\ + *AT91C_PIOA_PDR = MOTOR_B_INT; /* Disable PIO on PA26 */\ + *AT91C_PIOA_BSR = MOTOR_B_INT; /* Enable Peripheral B on PA26 */\ + *AT91C_PIOA_PER = MOTOR_B_DIR; /* Enable PIO on PA09 */\ + *AT91C_PIOA_PPUDR = MOTOR_B_INT | MOTOR_B_DIR; /* Disable Pull Up resistor on PA26 & PA09 */\ + *AT91C_PIOA_ODR = MOTOR_B_DIR; /* PA09 set to input */\ + *AT91C_PIOA_IFER = MOTOR_B_INT | MOTOR_B_DIR; /* Enable filter on PA26 & PA09 */\ + *AT91C_PMC_PCER = TIMER_2_ID14; /* Enable clock for TC2*/\ + *AT91C_TCB_BMR = AT91C_TCB_TC2XC2S_NONE; /* No external clock signal */\ + *AT91C_TCB_BCR = 0x0; /* Clear SYNC */\ + *AT91C_TC2_CMR = *AT91C_TC2_CMR & 0X00000000; /* Clear all bits in TC1_CMR */\ + *AT91C_TC2_CMR = *AT91C_TC2_CMR & 0xFFFF7FFF; /* Enable capture mode */\ + *AT91C_TC2_CMR = *AT91C_TC2_CMR | AT91C_TC_CLKS_TIMER_DIV5_CLOCK; /* Set clock for timer to Clock5 = div 1024*/\ + *AT91C_TC2_CMR = *AT91C_TC2_CMR | AT91C_TC_ABETRG; /* Use external trigger for TIO2*/\ + *AT91C_TC2_CMR = *AT91C_TC2_CMR | AT91C_TC_EEVTEDG_BOTH; /* Trigger on both edges */\ + *AT91C_TC2_CMR = *AT91C_TC2_CMR | AT91C_TC_LDRA_RISING; /* RA loading register set */\ + *AT91C_AIC_IDCR = TIMER_2_ID14; /* Irq controller setup */\ + AT91C_AIC_SVR[14] = (unsigned int)CaptureBInt; \ + AT91C_AIC_SMR[14] = 0x05; /* Enable trigger on level */\ + *AT91C_AIC_ICCR = TIMER_2_ID14; /* Clear interrupt register PID14*/\ + *AT91C_TC2_IDR = 0xFF; /* Disable all interrupt from TC2 */\ + *AT91C_TC2_IER = 0x80; /* Enable interrupts from external trigger */\ + *AT91C_AIC_IECR = TIMER_2_ID14; /* Enable interrupt from TC2 */\ + *AT91C_TC2_CCR = 0x00; /* Clear registers before setting */\ + *AT91C_TC2_CCR = AT91C_TC_CLKEN; /* Enable clock */\ + } + + #define ENABLECaptureMotorC {\ + *AT91C_PIOA_PDR = MOTOR_C_INT; /* Disable PIO on PA0 */\ + *AT91C_PIOA_BSR = MOTOR_C_INT; /* Enable Peripheral B on PA0 */\ + *AT91C_PIOA_PER = MOTOR_C_DIR; /* Enable PIO on PA08 */\ + *AT91C_PIOA_PPUDR = MOTOR_C_INT | MOTOR_C_DIR; /* Disable Pull Up resistor on PA0 & PA08 */\ + *AT91C_PIOA_ODR = MOTOR_C_DIR; /* PA08 set to input */\ + *AT91C_PIOA_IFER = MOTOR_C_INT | MOTOR_C_DIR; /* Enable filter on PA26 & PA09 */\ + *AT91C_PMC_PCER = TIMER_0_ID12; /* Enable clock for TC0*/\ + *AT91C_TCB_BMR = AT91C_TCB_TC0XC0S_NONE; /* No external clock signal */\ + *AT91C_TC0_CMR = *AT91C_TC0_CMR & 0X00000000; /* Clear all bits in TC0_CMR */\ + *AT91C_TC0_CMR = *AT91C_TC0_CMR & 0xFFFF7FFF; /* Enable capture mode */\ + *AT91C_TC0_CMR = *AT91C_TC0_CMR | AT91C_TC_CLKS_TIMER_DIV5_CLOCK; /* Set clock for timer to Clock5 = div 1024*/\ + *AT91C_TC0_CMR = *AT91C_TC0_CMR | AT91C_TC_ABETRG; /* Use external trigger for TI0*/\ + *AT91C_TC0_CMR = *AT91C_TC0_CMR | AT91C_TC_EEVTEDG_BOTH; /* Trigger on both edges */\ + *AT91C_TC0_CMR = *AT91C_TC0_CMR | AT91C_TC_LDRA_RISING; /* RA loading register set */\ + *AT91C_AIC_IDCR = TIMER_0_ID12; /* Disable interrupt */\ + AT91C_AIC_SVR[12] = (unsigned int)CaptureCInt; \ + AT91C_AIC_SMR[12] = 0x05; /* Enable trigger on level */\ + *AT91C_AIC_ICCR = TIMER_0_ID12; /* Clear interrupt register PID12*/\ + *AT91C_TC0_IDR = 0xFF; /* Disable all interrupt from TC0 */\ + *AT91C_TC0_IER = 0x80; /* Enable interrupts from external trigger */\ + *AT91C_AIC_IECR = TIMER_0_ID12; /* Enable interrupt from TC0 */\ + *AT91C_TC0_CCR = 0x00; /* Clear registers before setting */\ + *AT91C_TC0_CCR = AT91C_TC_CLKEN; /* Enable clock */\ + } + +__ramfunc void CaptureAInt(void) +{ + if (*AT91C_TC1_SR & AT91C_TC_MTIOA) + { + if (*AT91C_PIOA_PDSR & MOTOR_A_DIR) + { + MotorTachoValue[0].MotorDirection = REVERSE; //Motor is running reverse + MotorTachoValue[0].TachoCountTable--; + } + else + { + MotorTachoValue[0].MotorDirection = FORWARD; //Motor is running forward + MotorTachoValue[0].TachoCountTable++; + } + } + else + { + if (*AT91C_PIOA_PDSR & MOTOR_A_DIR) + { + MotorTachoValue[0].MotorDirection = FORWARD; + MotorTachoValue[0].TachoCountTable++; + } + else + { + MotorTachoValue[0].MotorDirection = REVERSE; + MotorTachoValue[0].TachoCountTable--; + } + } +} + +__ramfunc void CaptureBInt(void) +{ + if (*AT91C_TC2_SR & AT91C_TC_MTIOA) + { + if (*AT91C_PIOA_PDSR & MOTOR_B_DIR) + { + MotorTachoValue[1].MotorDirection = REVERSE; //Motor is running reverse + MotorTachoValue[1].TachoCountTable--; + } + else + { + MotorTachoValue[1].MotorDirection = FORWARD; //Motor is running forward + MotorTachoValue[1].TachoCountTable++; + } + } + else + { + if (*AT91C_PIOA_PDSR & MOTOR_B_DIR) + { + MotorTachoValue[1].MotorDirection = FORWARD; + MotorTachoValue[1].TachoCountTable++; + } + else + { + MotorTachoValue[1].MotorDirection = REVERSE; + MotorTachoValue[1].TachoCountTable--; + } + } +} + + +//__ramfunc void CaptureBInt(void) +//{ +// if (((bool)(*AT91C_TC2_SR & AT91C_TC_MTIOA))==((bool)(*AT91C_PIOA_PDSR & MOTOR_B_DIR))) +// { +// MotorTachoValue[1].MotorDirection = REVERSE; //Motor is running reverse +// MotorTachoValue[1].TachoCountTable--; +// } +// else +// { +// MotorTachoValue[1].MotorDirection = FORWARD; //Motor is running reverse +// MotorTachoValue[1].TachoCountTable++; +// } +//} + + +__ramfunc void CaptureCInt(void) +{ + if (*AT91C_TC0_SR & AT91C_TC_MTIOA) + { + if (*AT91C_PIOA_PDSR & MOTOR_C_DIR) + { + MotorTachoValue[2].MotorDirection = REVERSE; //Motor is running reverse + MotorTachoValue[2].TachoCountTable--; + } + else + { + MotorTachoValue[2].MotorDirection = FORWARD; //Motor is running forward + MotorTachoValue[2].TachoCountTable++; + } + } + else + { + if (*AT91C_PIOA_PDSR & MOTOR_C_DIR) + { + MotorTachoValue[2].MotorDirection = FORWARD; + MotorTachoValue[2].TachoCountTable++; + } + else + { + MotorTachoValue[2].MotorDirection = REVERSE; + MotorTachoValue[2].TachoCountTable--; + } + } +} + +#define OUTPUTExit {\ + *AT91C_AIC_IDCR = TIMER_0_ID12 | TIMER_1_ID13 | TIMER_2_ID14; /* Disable interrupts for the timers */\ + *AT91C_AIC_ICCR = TIMER_0_ID12 | TIMER_1_ID13 | TIMER_2_ID14; /* Clear penting interrupt register for timers*/\ + *AT91C_PMC_PCDR = TIMER_0_ID12 | TIMER_1_ID13 | TIMER_2_ID14; /* Disable the clock for each of the timers*/\ + *AT91C_PIOA_PER = MOTOR_A_DIR | MOTOR_A_INT | MOTOR_B_DIR | MOTOR_B_INT | MOTOR_C_DIR | MOTOR_C_INT; /* Enable PIO on PA15, PA11, PA26, PA09, PA27 & PA08 */\ + *AT91C_PIOA_ODR = MOTOR_A_DIR | MOTOR_A_INT | MOTOR_B_DIR | MOTOR_B_INT | MOTOR_C_DIR | MOTOR_C_INT; /* Set to input PA15, PA11, PA26, PA09, PA27 & PA08 */\ + *AT91C_PIOA_PPUDR = MOTOR_A_DIR | MOTOR_A_INT | MOTOR_B_DIR | MOTOR_B_INT | MOTOR_C_DIR | MOTOR_C_INT; /* Enable Pullup on PA15, PA11, PA26, PA09, PA27 & PA08 */\ + } + + +#define TACHOCountReset(MotorNr) {\ + MotorTachoValue[MotorNr].TachoCountTable = 0;\ + MotorTachoValue[MotorNr].TachoCountTableOld = 0;\ + } + +#define TACHOCaptureReadResetAll(MotorDataA,MotorDataB,MotorDataC){\ + MotorDataA = (MotorTachoValue[MOTOR_A].TachoCountTable - MotorTachoValue[MOTOR_A].TachoCountTableOld);\ + MotorTachoValue[MOTOR_A].TachoCountTableOld = MotorTachoValue[MOTOR_A].TachoCountTable;\ + MotorDataB = (MotorTachoValue[MOTOR_B].TachoCountTable - MotorTachoValue[MOTOR_B].TachoCountTableOld);\ + MotorTachoValue[MOTOR_B].TachoCountTableOld = MotorTachoValue[MOTOR_B].TachoCountTable;\ + MotorDataC = (MotorTachoValue[MOTOR_C].TachoCountTable - MotorTachoValue[MOTOR_C].TachoCountTableOld);\ + MotorTachoValue[MOTOR_C].TachoCountTableOld = MotorTachoValue[MOTOR_C].TachoCountTable;\ + } + + + + +#define GetMotorDirection(MotorNr) MotorTachoValue[MotorNr].MotorDirection + +#endif + +#ifdef PCWIN + +#endif diff --git a/src/d_sound.c b/src/d_sound.c new file mode 100644 index 0000000..72dfb60 --- /dev/null +++ b/src/d_sound.c @@ -0,0 +1,70 @@ +// +// Programmer +// +// Date init 14.12.2004 +// +// Reviser $Author:: Dkandlun $ +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: d_sound.c $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_soun $ +// +// Platform C +// + +#include "stdconst.h" +#include "m_sched.h" +#include "d_sound.h" +#include "d_sound.r" + + +void dSoundInit(void) +{ + SOUNDInit; +} + + +void dSoundVolume(UBYTE Step) +{ + SOUNDVolume(Step); +} + + +UBYTE dSoundReady(void) +{ + return (SOUNDReady); +} + + +UBYTE dSoundStart(UBYTE *pSound,UWORD Length,UWORD SampleRate, UBYTE FileType) +{ + return (SOUNDStart(pSound,Length,SampleRate,FileType)); +} + + +UBYTE dSoundStop(void) +{ + return (SOUNDStop); +} + + +UBYTE dSoundTone(UBYTE *pMelody,UWORD Length,UBYTE Volume) +{ + return (SOUNDTone(pMelody,Length,Volume)); +} + + +void dSoundFreq(UWORD Hz,UWORD mS,UBYTE Volume) +{ + SOUNDFreq(Hz,mS,Volume); +} + + +void dSoundExit(void) +{ + SOUNDExit; +} diff --git a/src/d_sound.h b/src/d_sound.h new file mode 100644 index 0000000..c580342 --- /dev/null +++ b/src/d_sound.h @@ -0,0 +1,42 @@ +// +// Programmer +// +// Date init 14.12.2004 +// +// Reviser $Author:: Dkandlun $ +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: d_sound.h $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_soun $ +// +// Platform C +// + + +#ifndef D_SOUND +#define D_SOUND + +void dSoundInit(void); +void dSoundVolume(UBYTE Step); +UBYTE dSoundReady(void); +UBYTE dSoundStart(UBYTE *pSound,UWORD Length,UWORD SampleRate, UBYTE FileFormat); +UBYTE dSoundStop(void); +UBYTE dSoundTone(UBYTE *pMelody,UWORD Length,UBYTE Volume); +void dSoundFreq(UWORD Hz,UWORD mS,UBYTE Volume); +void dSoundExit(void); + +#define SOUNDVOLUMESTEPS 4 + +#define DURATION_MIN 10 // [mS] +#define FREQUENCY_MIN 220 // [Hz] +#define FREQUENCY_MAX 14080 // [Hz] + +#define SAMPLERATE_MIN 2000 // Min sample rate [sps] +#define SAMPLERATE_DEFAULT 8000 // Default sample rate [sps] +#define SAMPLERATE_MAX 16000 // Max sample rate [sps] + +#endif diff --git a/src/d_sound.r b/src/d_sound.r new file mode 100644 index 0000000..4851253 --- /dev/null +++ b/src/d_sound.r @@ -0,0 +1,515 @@ +// +// Programmer +// +// Date init 14.12.2004 +// +// Reviser $Author:: Dkandlun $ +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: d_sound.r $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_soun $ +// +// Platform C +// + +#include "d_sound_adpcm.r" + +#ifdef SAM7S256 + +#define SAMPLEMIN 0 // Must be zero (no pwm/interrupt) +#define SAMPLEMAX 256 // Must be 256 (8 bit wave format) +#define SAMPLECENTER (((SAMPLEMAX - SAMPLEMIN) / 2) + SAMPLEMIN) + +#define SAMPLEWORD ULONG +#define SAMPLEWORDS 8 +#define SAMPLEWORDBITS (sizeof(SAMPLEWORD) * 8) +#define SAMPLEBITS (SAMPLEWORDS * SAMPLEWORDBITS) +#define SAMPLECONSTANT 3 // >> == (SAMPLEMAX / SAMPLEWORDBITS) + +#define SAMPLETONENO 16 // No of tone samples + +#define SAMPLEBUFFERS 2 + +#define INIT_PREV_VAL_ADPCM 0x7F +#define INIT_INDEX_ADPCM 20 + +SAMPLEWORD SampleBuffer[SAMPLEBUFFERS][SAMPLEWORDS]; +SAMPLEWORD ToneBuffer[SAMPLETONENO]; + +const SAMPLEWORD TonePattern[SOUNDVOLUMESTEPS + 1][SAMPLETONENO] = +{ + { + 0xF0F0F0F0,0xF0F0F0F0, // Step 0 = silence + 0xF0F0F0F0,0xF0F0F0F0, + 0xF0F0F0F0,0xF0F0F0F0, + 0xF0F0F0F0,0xF0F0F0F0, + 0xF0F0F0F0,0xF0F0F0F0, + 0xF0F0F0F0,0xF0F0F0F0, + 0xF0F0F0F0,0xF0F0F0F0, + 0xF0F0F0F0,0xF0F0F0F0 + }, + { + 0xF0F0F0F0,0xF0F0F0F0, // Step 1 = 1/512 + 0xF0F0F0F0,0xF0F0F0F0, + 0xF0F0F0F0,0xF0F0F0F8, + 0xF0F0F0F0,0xF0F0F0F0, + 0xF0F0F0F0,0xF0F0F0F0, + 0xF0F0F0F0,0xF0F0F0F0, + 0xF0F0F0F0,0xF0F0F0F0, + 0xF0F0F0F0,0xF0F0F0F0 + }, + { + 0xF0F0F0F0,0xF0F0F0F0, // Step 2 = 0,+3,+4,+3,0,-3,-4,-3 + 0xF0F0F0F0,0xF0F8F8F8, + 0xF0F0F8F8,0xF8F8F0F0, + 0xF8F8F8F0,0xF0F0F0F0, + 0xF0F0F0F0,0xF0F0F0F0, + 0xF0F0F0F0,0xF0E0E0E0, + 0xF0F0E0E0,0xE0E0F0F0, + 0xE0E0E0F0,0xF0F0F0F0 + }, + { + 0xF0F0F0F0,0xF0F0F0F0, // Step 3 = 0,+10,+14,+10,0,-10,-14,-10 + 0xF8F8F8F8,0xF8F8FCFC, + 0xF8F8FCFC,0xFCFCFCFC, + 0xFCFCF8F8,0xF8F8F8F8, + 0xF0F0F0F0,0xF0F0F0F0, + 0xE0E0E0E0,0xE0E0C0C0, + 0xE0E0C0C0,0xC0C0C0C0, + 0xC0C0E0E0,0xE0E0E0E0 + }, + { + 0xF0F0F0F0,0xF0F0F0F0, // Step 4 = 0,+22,+32,+22,0,-22,-32,-22 + 0xFCFCFCFC,0xFCFCFDFD, + 0xFFFFFFFF,0xFFFFFFFF, + 0xFDFDFCFC,0xFCFCFCFC, + 0xF0F0F0F0,0xF0F0F0F0, + 0xC0C0C0C0,0xC0C08080, + 0x00000000,0x00000000, + 0x8080C0C0,0xC0C0C0C0 + } +}; + +__ramdata +UBYTE FractionPattern[SAMPLEWORDS] = +{ + 0x00, // 0 -> 00000000 + 0x10, // 1 -> 00010000 + 0x22, // 2 -> 00100010 + 0x4A, // 3 -> 01001010 + 0x55, // 4 -> 01010101 + 0x6D, // 5 -> 01101101 + 0x77, // 6 -> 01110111 + 0x7F, // 7 -> 01111111 +}; + +typedef struct +{ + SWORD Valprev; // Previous output value + SWORD Index; // Index into stepsize table +}ADPCM_State; + +ULONG ToneCycles; // No of tone cycles +ULONG ToneCyclesReady; // No of tone cycles for ready +ULONG ClockNext; // Serial clock for next buffer + +UBYTE *pSoundPointer; // Pointer to sample in actual sound buffer +UBYTE *pSoundPointerNext; // Pointer to sample in next sound buffer + +UWORD SoundSamplesLeft; // Number of samples left on actual sound buffer +UWORD SoundSamplesLeftNext; // Number of samples left on next sound buffer + +UBYTE SampleBufferNo; // Sample buffer no in use + +UBYTE SoundReady; // Sound channel ready (idle) +UBYTE SoundDivider; // Volume + +UWORD MelodyPointer; +UBYTE CurrentFileFormat; // Hold current playing file type + +UBYTE Outdata[2]; // Output buffer used within the ADPCM algorithm +ADPCM_State State; // Struct holding ADPCM state + +#define SOUNDIntEnable {\ + *AT91C_SSC_IER = AT91C_SSC_ENDTX;\ + } + +#define SOUNDIntDisable {\ + *AT91C_SSC_IDR = AT91C_SSC_ENDTX;\ + } + +#define SOUNDEnable {\ + *AT91C_PIOA_PDR = AT91C_PA17_TD; /* Enable TD on PA17 */\ + } + +#define SOUNDDisable {\ + *AT91C_PIOA_PER = AT91C_PA17_TD; /* Disable TD on PA17 */\ + } + +ULONG SoundSampleRate(UWORD Rate) +{ + ULONG Result; + + if (Rate > SAMPLERATE_MAX) + { + Rate = SAMPLERATE_MAX; + } + if (Rate < SAMPLERATE_MIN) + { + Rate = SAMPLERATE_MIN; + } + Result = ((OSC / (2 * SAMPLEBITS)) / Rate) + 1; + + return (Result); +} + +__ramfunc void CalculateBitstream(SAMPLEWORD *pSampleBuffer,UBYTE Sample) +{ + ULONG IntegerMask; + ULONG FractionMask; + UBYTE Integer; + UBYTE Fraction; + UBYTE Mask; + UBYTE Tmp; + SWORD STmp; + + if (SoundDivider) + { + STmp = Sample; + STmp &= 0xFF; + STmp -= SAMPLECENTER; + STmp >>= (SOUNDVOLUMESTEPS - SoundDivider); + STmp += SAMPLECENTER; + Sample = (UBYTE)STmp; + SOUNDEnable; + } + else + { + SOUNDDisable; + } + + Tmp = 0; + IntegerMask = 0xFFFF0000; + Integer = Sample >> SAMPLECONSTANT; + Fraction = Sample - (Integer << SAMPLECONSTANT); + IntegerMask = 0xFFFFFFFF << (SAMPLEWORDBITS - Integer); + FractionMask = (IntegerMask >> 1) | IntegerMask; + Mask = FractionPattern[Fraction]; + while (Tmp < SAMPLEWORDS) + { + if ((Mask & (0x01 << Tmp))) + { + *pSampleBuffer = FractionMask; + } + else + { + *pSampleBuffer = IntegerMask; + } + pSampleBuffer++; + Tmp++; + } +} + +__ramfunc void SscHandler(void) +{ + static UBYTE ByteCnt = 0; + + if (SoundSamplesLeft) + { + if (0 == CurrentFileFormat) + { + CalculateBitstream(SampleBuffer[SampleBufferNo],*pSoundPointer); + *AT91C_SSC_TNPR = (unsigned int)SampleBuffer[SampleBufferNo]; + *AT91C_SSC_TNCR = SAMPLEWORDS; + + pSoundPointer++; + SoundSamplesLeft--; + if (!SoundSamplesLeft) + { + pSoundPointer = pSoundPointerNext; + SoundSamplesLeft = SoundSamplesLeftNext; + *AT91C_SSC_CMR = ClockNext; + SoundSamplesLeftNext = 0; + } + + if (++SampleBufferNo >= SAMPLEBUFFERS) + { + SampleBufferNo = 0; + } + } + else + { + if (0 == ByteCnt) + { + SoundADPCMDecoder(*pSoundPointer, Outdata, &State.Valprev, &State.Index); + CalculateBitstream(SampleBuffer[SampleBufferNo],Outdata[0]); + *AT91C_SSC_TNPR = (unsigned int)SampleBuffer[SampleBufferNo]; + *AT91C_SSC_TNCR = SAMPLEWORDS; + + if (++SampleBufferNo >= SAMPLEBUFFERS) + { + SampleBufferNo = 0; + } + + ByteCnt++; + } + else + { + CalculateBitstream(SampleBuffer[SampleBufferNo],Outdata[1]); + *AT91C_SSC_TNPR = (unsigned int)SampleBuffer[SampleBufferNo]; + *AT91C_SSC_TNCR = SAMPLEWORDS; + + pSoundPointer++; + SoundSamplesLeft--; + if (!SoundSamplesLeft) + { + pSoundPointer = pSoundPointerNext; + SoundSamplesLeft = SoundSamplesLeftNext; + *AT91C_SSC_CMR = ClockNext; + SoundSamplesLeftNext = 0; + } + + if (++SampleBufferNo >= SAMPLEBUFFERS) + { + SampleBufferNo = 0; + } + ByteCnt = 0; + } + } + } + else + { + if (ToneCycles) + { + ToneCycles--; + if (ToneCycles < ToneCyclesReady) + { + SoundReady = TRUE; + } + *AT91C_SSC_TNPR = (unsigned int)ToneBuffer; + *AT91C_SSC_TNCR = SAMPLETONENO; + if (SoundDivider) + { + SOUNDEnable; + } + else + { + SOUNDDisable; + } + } + else + { + SoundReady = TRUE; + SOUNDDisable; + SOUNDIntDisable; + } + } +} + +UBYTE SoundStart(UBYTE *Sound,UWORD Length,UWORD SampleRate, UBYTE NewFileFormat) +{ + UBYTE Result = FALSE; + + if (SoundReady == TRUE) + { + if (Length > 1) + { + CurrentFileFormat = NewFileFormat; + *AT91C_SSC_CMR = SoundSampleRate(SampleRate); + pSoundPointer = Sound; + SoundSamplesLeft = Length; + + if (0 == CurrentFileFormat) + { + CalculateBitstream(SampleBuffer[0],*pSoundPointer); + *AT91C_SSC_TPR = (unsigned int)SampleBuffer[0]; + *AT91C_SSC_TCR = SAMPLEWORDS; + pSoundPointer++; + SoundSamplesLeft--; + CalculateBitstream(SampleBuffer[1],*pSoundPointer); + *AT91C_SSC_TNPR = (unsigned int)SampleBuffer[1]; + *AT91C_SSC_TNCR = SAMPLEWORDS; + pSoundPointer++; + SoundSamplesLeft--; + } + else + { + State.Valprev = INIT_PREV_VAL_ADPCM; + State.Index = INIT_INDEX_ADPCM; + SoundADPCMDecoder(*pSoundPointer, Outdata, &State.Valprev, &State.Index); + CalculateBitstream(SampleBuffer[0],Outdata[0]); + *AT91C_SSC_TPR = (unsigned int)SampleBuffer[0]; + *AT91C_SSC_TCR = SAMPLEWORDS; + pSoundPointer++; + SoundSamplesLeft--; + CalculateBitstream(SampleBuffer[1],Outdata[1]); + *AT91C_SSC_TNPR = (unsigned int)SampleBuffer[1]; + *AT91C_SSC_TNCR = SAMPLEWORDS; + } + SampleBufferNo = 0; + SoundReady = FALSE; + SOUNDIntEnable; + *AT91C_SSC_PTCR = AT91C_PDC_TXTEN; + } + Result = TRUE; + } + else + { + if (!ToneCycles) + { + if (!SoundSamplesLeftNext) + { + CurrentFileFormat = NewFileFormat; + ClockNext = SoundSampleRate(SampleRate); + pSoundPointerNext = Sound; + SoundSamplesLeftNext = Length; + Result = TRUE; + } + } + } + + return (Result); +} + +UBYTE SoundStop(void) +{ + ToneCycles = 0; + SOUNDIntDisable; + SOUNDDisable; + SoundReady = TRUE; + SoundSamplesLeft = 0; + SoundSamplesLeftNext = 0; + MelodyPointer = 0; + + return (TRUE); +} + +void SoundVolume(UBYTE Step) +{ + if (Step > SOUNDVOLUMESTEPS) + { + Step = SOUNDVOLUMESTEPS; + } + SoundDivider = Step; +} + +void SoundFreq(UWORD Freq,UWORD mS,UBYTE Step) +{ + UBYTE Tmp; + + if (mS < DURATION_MIN) + { + mS = DURATION_MIN; + } + if (Freq) + { + if (Freq < FREQUENCY_MIN) + { + Freq = FREQUENCY_MIN; + } + if (Freq > FREQUENCY_MAX) + { + Freq = FREQUENCY_MAX; + } + if (Step > SOUNDVOLUMESTEPS) + { + Step = SOUNDVOLUMESTEPS; + } + } + else + { + Step = 0; + Freq = 1000; + } + SoundDivider = Step; + SoundSamplesLeft = 0; + SoundSamplesLeftNext = 0; + for (Tmp = 0;Tmp < SAMPLETONENO;Tmp++) + { + ToneBuffer[Tmp] = TonePattern[Step][Tmp]; + } + + *AT91C_SSC_CMR = (((ULONG)OSC / (2L * 512L)) / ((ULONG)Freq)) + 1L; + ToneCycles = ((ULONG)Freq * (ULONG)mS) / 1000L - 1L; + ToneCyclesReady = ((ULONG)Freq * (ULONG)2L) / 1000L + 1L; + + *AT91C_SSC_TNPR = (unsigned int)ToneBuffer; + *AT91C_SSC_TNCR = SAMPLETONENO; + *AT91C_SSC_PTCR = AT91C_PDC_TXTEN; + SoundReady = FALSE; + SOUNDIntEnable; +} + +UBYTE SoundTone(UBYTE *pMel,UWORD Length,UBYTE Step) +{ + UBYTE Result = FALSE; + UWORD Freq; + UWORD mS; + + if ((SoundReady == TRUE)) + { + if (MelodyPointer <= (Length - 4)) + { + Freq = (UWORD)pMel[MelodyPointer++] << 8; + Freq += (UWORD)pMel[MelodyPointer++]; + mS = (UWORD)pMel[MelodyPointer++] << 8; + mS += (UWORD)pMel[MelodyPointer++]; + SoundFreq(Freq,mS,Step); + } + else + { + MelodyPointer = 0; + Result = TRUE; + } + } + + return (Result); +} + +#define SOUNDInit {\ + SOUNDIntDisable;\ + SoundReady = TRUE;\ + MelodyPointer = 0;\ + *AT91C_PMC_PCER = (1L << AT91C_ID_SSC); /* Enable MCK clock */\ + *AT91C_PIOA_PER = AT91C_PA17_TD; /* Disable TD on PA17 */\ + *AT91C_PIOA_ODR = AT91C_PA17_TD;\ + *AT91C_PIOA_OWDR = AT91C_PA17_TD;\ + *AT91C_PIOA_MDDR = AT91C_PA17_TD;\ + *AT91C_PIOA_PPUDR = AT91C_PA17_TD;\ + *AT91C_PIOA_IFDR = AT91C_PA17_TD;\ + *AT91C_PIOA_CODR = AT91C_PA17_TD;\ + *AT91C_PIOA_IDR = AT91C_PA17_TD;\ + *AT91C_SSC_CR = AT91C_SSC_SWRST;\ + AT91C_AIC_SVR[AT91C_ID_SSC] = (unsigned int)SscHandler;\ + AT91C_AIC_SMR[AT91C_ID_SSC] = AT91C_AIC_PRIOR_LOWEST | AT91C_AIC_SRCTYPE_INT_EDGE_TRIGGERED; /* Set priority */\ + *AT91C_SSC_TCMR = AT91C_SSC_CKS_DIV + AT91C_SSC_CKO_CONTINOUS + AT91C_SSC_START_CONTINOUS;\ + *AT91C_SSC_TFMR = (SAMPLEWORDBITS - 1) + ((SAMPLEWORDS & 0xF) << 8) + AT91C_SSC_MSBF;\ + *AT91C_SSC_CR = AT91C_SSC_TXEN; /* TX enable */\ + *AT91C_AIC_ICCR = (1L << AT91C_ID_SSC); /* Clear interrupt */\ + *AT91C_AIC_IECR = (1L << AT91C_ID_SSC); /* Enable int. controller */\ + } + +#define SOUNDVolume(V) SoundVolume((UBYTE)V) + +#define SOUNDReady SoundReady + +#define SOUNDStart(pSnd,Lng,SR,FT) SoundStart(pSnd,Lng,SR,FT) + +#define SOUNDStop SoundStop() + +#define SOUNDTone(pMel,Lng,Vol) SoundTone(pMel,Lng,Vol) + +#define SOUNDFreq(Freq,Duration,Vol) SoundFreq(Freq,Duration,Vol) + +#define SOUNDExit {\ + SOUNDIntDisable;\ + SOUNDDisable;\ + *AT91C_AIC_IDCR = (1L << AT91C_ID_SSC);\ + } + + +#endif diff --git a/src/d_sound_adpcm.r b/src/d_sound_adpcm.r new file mode 100644 index 0000000..f04a760 --- /dev/null +++ b/src/d_sound_adpcm.r @@ -0,0 +1,158 @@ +//Playback of compressed sound files. This additional feature is being brought to you under the following license. +//Please adhere to its terms. +//The original code includes minor changes to function correctly within the LEGO MINDSTORMS NXT embedded system, +//but the main architecture are implemented as within the original code. + +//*********************************************************** +//Copyright 1992 by Stichting Mathematisch Centrum, Amsterdam, The +//Netherlands. +// +// All Rights Reserved +// +//Permission to use, copy, modify, and distribute this software and its +//documentation for any purpose and without fee is hereby granted, +//provided that the above copyright notice appear in all copies and that +//both that copyright notice and this permission notice appear in +//supporting documentation, and that the names of Stichting Mathematisch +//Centrum or CWI not be used in advertising or publicity pertaining to +//distribution of the software without specific, written prior permission. +// +//STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO +//THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +//FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE +//FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +//WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +//ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +//OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// +//******************************************************************/ + +// +// Programmer +// +// Date init 14.12.2004 +// +// Reviser $Author:: Dkandlun $ +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: d_sound_adpcm.r $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_sound_adpc $ +// +// Platform C +// + +#ifdef SAM7S256 + +__ramdata +static SWORD IndexTable[16] = +{ + -1, -1, -1, -1, 2, 4, 6, 8, + -1, -1, -1, -1, 2, 4, 6, 8, +}; + +__ramdata +static SWORD StepsizeTable[89] = +{ + 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, + 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, + 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, + 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, + 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, + 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, + 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, + 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, + 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 +}; + +__ramfunc void SoundADPCMDecoder(UBYTE Indata, UBYTE *Outdata, SWORD *pStateValprev, SWORD *pStateIndex) +{ + SWORD Step; // Stepsize + SWORD Valprev; // Virtual previous output value + SWORD Vpdiff; // Current change to valprev + SWORD Index; // Current step change index + UBYTE *pOut; // Output buffer pointer + UBYTE Sign; // Current adpcm sign bit + UBYTE Delta; // Current adpcm output value + UBYTE Bufferstep; // Toggle between High og Low nibble + UBYTE Len; // Nibble Counter + + pOut = Outdata; + + Valprev = *pStateValprev; + Index = *pStateIndex; + Step = StepsizeTable[Index]; + + Bufferstep = 0; + Len = 2; + + for (; Len > 0 ; Len--) //Step 1 - get the delta value and compute next index + { + if(Bufferstep) + { + Delta = Indata & 0x0F; + } + else + { + Delta = (Indata >> 4) & 0x0F; + } + Bufferstep = !Bufferstep; + + Index += IndexTable[Delta]; //Step 2 - Find new index value (for later) + if (Index < 0) + { + Index = 0; + } + else + { + if (Index > 88) + { + Index = 88; + } + } + + Sign = Delta & 8; //Step 3 - Separate sign and magnitude + Delta = Delta & 7; + + Vpdiff = Step >> 3; //Step 4 - Compute difference and new predicted value + + if (Delta & 4) + { + Vpdiff += Step; + } + if (Delta & 2) + { + Vpdiff += Step>>1; + } + if (Delta & 1) + { + Vpdiff += Step>>2; + } + + if (Sign) + Valprev -= Vpdiff; + else + Valprev += Vpdiff; + + if (Valprev > 255) //Step 5 - clamp output value + { + Valprev = 255; + } + else + { + if (Valprev < 0) + { + Valprev = 0; + } + } + Step = StepsizeTable[Index]; //Step 6 - Update step value + *pOut++ = (UBYTE)Valprev; //Step 7 - Output value + } + *pStateValprev = Valprev; //State.Valprev = Valprev; + *pStateIndex = Index; //State.Index = Index; +} + +#endif diff --git a/src/d_timer.c b/src/d_timer.c new file mode 100644 index 0000000..cba73d0 --- /dev/null +++ b/src/d_timer.c @@ -0,0 +1,62 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date: 23-04-08 11:15 $ +// +// Filename $Workfile:: d_timer.c $ +// +// Version $Revision: 2 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_time $ +// +// Platform C +// + + +#include "stdconst.h" +#include "m_sched.h" +#include "d_timer.h" +#include "d_timer.r" + + +void dTimerInit(void) +{ + TIMERInit; +} + + +ULONG dTimerRead(void) +{ + ULONG V; + + TIMERReadAlt(V) + return (V); +} + +ULONG dTimerReadNoPoll(void) +{ + return (Timer1mS); +} + +ULONG dTimerReadHiRes(void) +{ + +// return ((*AT91C_PITC_PIIR)/3); following code is equivalent and about five times faster, see Hacker's Delight or exact division + ULONG tmp= ((*AT91C_PITC_PIIR)*2863311531); + if(tmp > 2863311531) + return tmp - 2863311531; + else if(tmp > 1431655766) + return tmp - 1431655766; + else + return tmp; +} + +ULONG dTimerGetNextMSTickCnt(void) { + return NextTimerValue; +} + +void dTimerExit(void) +{ + TIMERExit; +} + diff --git a/src/d_timer.h b/src/d_timer.h new file mode 100644 index 0000000..9d7eadb --- /dev/null +++ b/src/d_timer.h @@ -0,0 +1,32 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date: 23-04-08 11:15 $ +// +// Filename $Workfile:: d_timer.h $ +// +// Version $Revision: 2 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_time $ +// +// Platform C +// + + +#ifndef D_TIMER +#define D_TIMER + +void dTimerInit(void); +ULONG dTimerRead(void); +ULONG dTimerReadNoPoll(void); +ULONG dTimerReadHiRes(void); + +ULONG dTimerGetNextMSTickCnt(void); +#define dTimerReadTicks() (*AT91C_PITC_PIIR) + +void dTimerExit(void); + +#endif + + + diff --git a/src/d_timer.r b/src/d_timer.r new file mode 100644 index 0000000..93c3a3b --- /dev/null +++ b/src/d_timer.r @@ -0,0 +1,76 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 23-04-08 11:15 $ +// +// Filename $Workfile:: d_timer.r $ +// +// Version $Revision:: 2 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_time $ +// +// Platform C +// + + +#ifdef SAM7S256 + + +#define MS_1_TIME ((OSC/16)/1000) + +static ULONG TimerValue; +static ULONG NextTimerValue; +static ULONG Timer1mS; + +/* PIT timer is used as main timer - timer interval is 1mS */ + +#define TIMERInit TimerValue = ((*AT91C_PITC_PIIR) & AT91C_PITC_CPIV);\ + NextTimerValue = (((*AT91C_PITC_PIIR) + MS_1_TIME) & AT91C_PITC_CPIV);\ + Timer1mS = 0 + +#define TIMERRead(V) if (MS_1_TIME < ((((*AT91C_PITC_PIIR) & AT91C_PITC_CPIV) - TimerValue) & AT91C_PITC_CPIV))\ + {\ + TimerValue += MS_1_TIME;\ + TimerValue &= AT91C_PITC_CPIV;\ + Timer1mS++;\ + }\ + V = Timer1mS + +#define TIMERReadAlt(V) if((SLONG)((*AT91C_PITC_PIIR) - NextTimerValue) >= 0)\ + {\ + Timer1mS ++;\ + NextTimerValue += MS_1_TIME;\ + }\ + V = Timer1mS;\ + +#define TIMERReadSkip(V) diff= (((*AT91C_PITC_PIIR)) - NextTimerValue);\ + if (diff >= 0)\ + {\ + diff /= MS_1_TIME;\ + diff += 1;\ + Timer1mS += diff;\ + diff *= MS_1_TIME;\ + NextTimerValue += diff;\ + }\ + V = Timer1mS;\ + +#define TIMERExit + + + +#endif //SAM7S256 + + + +#ifdef _WINDOWS + +#include +#include + +#define TIMERInit timeBeginPeriod(1); + +#define TIMERRead(V) (V) = timeGetTime(); + +#define TIMERExit timeEndPeriod(1); + +#endif //_WINDOWS diff --git a/src/d_usb.c b/src/d_usb.c new file mode 100644 index 0000000..0caf317 --- /dev/null +++ b/src/d_usb.c @@ -0,0 +1,946 @@ +// +// Programmer +// +// Date init 14.12.2004 +// +// Reviser $Author:: Dkandlun $ +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: d_usb.c $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_usb. $ +// +// Platform C +// + +#include "stdconst.h" +#include "m_sched.h" +#include "d_usb.h" +#include "d_usb.r" + +#define ENDPOINT_OUT 1 // HOST write +#define ENDPOINT_OUT_SIZE 64 +#define ENDPOINT_IN 2 // HOST read +#define ENDPOINT_IN_SIZE 64 + +#define AT91C_UDP_ISR ((AT91_REG *) 0xFFFB001C) // (UDP) Interrupt Status Register +#define AT91C_RSTC_URSTEN ((unsigned int) 0x1 << 0) // (RSTC) User Reset Enable + + // Endpoint Control and Status Registers +#define AT91C_UDP_CSR0 ((AT91_REG *) 0xFFFB0030) // Endpoint 0 Control and Status Register +#define AT91C_UDP_CSR1 ((AT91_REG *) 0xFFFB0034) // Endpoint 1 Control and Status Register +#define AT91C_UDP_CSR2 ((AT91_REG *) 0xFFFB0038) // Endpoint 2 Control and Status Register +#define AT91C_UDP_CSR3 ((AT91_REG *) 0xFFFB003C) // Endpoint 3 Control and Status Register + + // Endpoint FIFO Data Registers +#define AT91C_UDP_FDR0 ((AT91_REG *) 0xFFFB0050) // Endpoint 0 FIFO Data Register +#define AT91C_UDP_FDR1 ((AT91_REG *) 0xFFFB0054) // Endpoint 1 FIFO Data Register +#define AT91C_UDP_FDR2 ((AT91_REG *) 0xFFFB0058) // Endpoint 2 FIFO Data Register +#define AT91C_UDP_FDR3 ((AT91_REG *) 0xFFFB005C) // Endpoint 3 FIFO Data Register + +const UBYTE DeviceDescriptor[] = { + /* Device descriptor */ + 0x12, // bLength, size of this descriptor = 18 entries + 0x01, // bDescriptorType = 1 = DEVICE + 0x00, // bcdUSBL, USB spec. vers. 2.0 + 0x02, // bcdUSBH, - + 0x00, // bDeviceClass + 0x00, // bDeviceSubclass + 0x00, // bDeviceProtocol + 0x08, // bMaxPacketSize0, EndPointZero packet size = 8 + 0x94, // idVendorL, LEGO Group + 0x06, // idVendorH, - + 0x02, // idProductL, LEGO USB IR Tower = 0x01 + 0x00, // idProductH, - + 0x00, // bcdDeviceL, device is version (zero) + 0x00, // bcdDeviceH, - + 0x00, // iManufacturer, index of string descriptor describing manufacturer + 0x00, // iProduct, index of string descriptor describing product + 0x01, // iSerialNumber, index of string descriptor describing the device's + // serial no. + 0x01 // bNumConfigs, number of possible configurations (only one) +}; + +/* USB standard request codes */ + +#define STD_GET_STATUS_ZERO 0x0080 +#define STD_GET_STATUS_INTERFACE 0x0081 +#define STD_GET_STATUS_ENDPOINT 0x0082 + +#define STD_CLEAR_FEATURE_ZERO 0x0100 +#define STD_CLEAR_FEATURE_INTERFACE 0x0101 +#define STD_CLEAR_FEATURE_ENDPOINT 0x0102 + +#define STD_SET_FEATURE_ZERO 0x0300 +#define STD_SET_FEATURE_INTERFACE 0x0301 +#define STD_SET_FEATURE_ENDPOINT 0x0302 + +#define STD_SET_ADDRESS 0x0500 +#define STD_GET_DESCRIPTOR 0x0680 +#define STD_SET_DESCRIPTOR 0x0700 +#define STD_GET_CONFIGURATION 0x0880 +#define STD_SET_CONFIGURATION 0x0900 +#define STD_GET_INTERFACE 0x0A81 +#define STD_SET_INTERFACE 0x0B01 +#define STD_SYNCH_FRAME 0x0C82 + +/* USB constants, masks etc. */ + +#define END_OF_BUS_RESET ((unsigned int) 0x1 << 12) +#define SUSPEND_INT ((unsigned int) 0x1 << 8) +#define SUSPEND_RESUME ((unsigned int) 0x1 << 9) +#define WAKEUP ((unsigned int) 0x1 << 13) + +//USB spec allows 500ms for control transfers +#define USB_MAX_TIMEOUT 500 + +static UBYTE UsbHandleList[MAX_HANDLES]; +static UBYTE UsbHandleCnt; +static UWORD RequestedData; +static UBYTE BrickNameKnown; +enum +{ + USB_NOT_CONFIGURED, + USB_CONFIGURED, + USB_CONFIGURED_BUT_SUSPENDED +}; +static UBYTE UsbConnectionStates; + + +const UBYTE ConfigurationDescriptor[] = { + /* ============== CONFIGURATION 1 =========== */ + /* Configuration 1 descriptor */ + 0x09, // bLength, descriptor size in bytes + 0x02, // bDescriptorType, The constant Configuration + 0x20, // wTotalLengthL for 2 EP + Control + 0x00, // wTotalLengthH - + 0x01, // bNumInterfaces, Number of interfaces in the configuration + 0x01, // bConfigurationValue, Identifier for + // Set_Configuration and Get_Configuration requests + 0x00, // iConfiguration, Index of string descriptor for the configuration + 0xC0, // bmAttributes, Bit 7 shall always be set. See e.g. page 108 in the book: + // "USB Complete" by Jan Axelson. June 2001 + // Self powered only bit 6 = 1 (zero = buspowered USB 1.1 and up) + 0x00, // MaxPower, power required (mA./2) We're SELF-POWERED, so ZERO + + /* Interface Descriptor */ + 0x09, // bLength, descriptor size in bytes + 0x04, // bDescriptorType, the constant 0x04 = "INTERFACE" + 0x00, // bInterfaceNumber, No. identifying this interface + 0x00, // bAlternateSetting, value used to get an alternative interface + 0x02, // bNumEndpoints, No. of supported endpoints in addition to endpoint 0 + 0xFF, // bInterfaceClass, Specifies the class code = VENDOR Specific + 0xFF, // bInterfaceSubclass, Specifies the subclass code = VENDOR Specific + 0xFF, // bInterfaceProtocol, protocol code = VENDOR Specific + 0x00, // iInterface, index of string descriptor for the interface + + /* Endpoint 1 descriptor */ + 0x07, // bLength, descriptor length incl. this = 7 + 0x05, // bDescriptorType + 0x01, // bEndpointAddress, Endpoint 01 - OUT + 0x02, // bmAttributes BULK + ENDPOINT_OUT_SIZE, // wMaxPacketSize + 0x00, // - + 0x00, // bInterval + + /* Endpoint 2 descriptor */ + 0x07, // bLength, descriptor length incl. this = 7 + 0x05, // bDescriptorType + 0x82, // bEndpointAddress, Endpoint 02 - IN + 0x02, // bmAttributes BULK + ENDPOINT_IN_SIZE, // wMaxPacketSize + 0x00, // - + 0x00 // bInterval +}; + +UBYTE SerialNumberDescriptor[] = +{ + 0x1A, // bLength, descriptor length incl. this = 16 bytes + 0x03, // bDescriptorType + + 0x31, 0x00, // MSD of Lap (Lap[2,3]) in UNICode + 0x32, 0x00, // Lap[4,5] + 0x33, 0x00, // Lap[6,7] + 0x34, 0x00, // Lap[8,9] + 0x35, 0x00, // Lap[10,11] + 0x36, 0x00, // Lap[12,13] + 0x37, 0x00, // Lap[14,15] + 0x38, 0x00, // LSD of Lap (Lap[16,17]) in UNICode + + 0x30, 0x00, // MSD of Nap (Nap[18,19]) in UNICode + 0x30, 0x00, // LSD of Nap (Nap[20,21]) in UNICode + + 0x39, 0x00, // MSD of Uap in UNICode + 0x30, 0x00 // LSD of Uap in UNICode +}; + +const UBYTE LangIdDescriptor[] = +{ + 0x04, // Length + 0x03, // Type, 3 = CONSTANT String + 0x09, // English + 0x04 // subcode = U.S. English +}; + +static UCHAR CurrentConfiguration; // Configured or not. We've only 1 conf. so... Boolean +static ULONG CurrentReceiveBank; // Used for keep track of the PING-PONG buffers + +ULONG g_UsbTimeoutCounter; + +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) + +void dUsbDisconnect(void) +{ + USBDisconnect; +} + +void dUsbConnect(void) +{ + USBConnect; +} + +void dUsbStartTimeoutTimer(void) +{ + g_UsbTimeoutCounter = 0; + + USBGetActualTime; +} + +// A longer version of the USB timer. +// Table 7-14 of the USB 2.0 spec allows up to 500ms for standard request completion. +UBYTE dUsbTimedOut(void) +{ + if(USBTimedOut) + { + g_UsbTimeoutCounter++; + + USBGetActualTime; + } + + return (g_UsbTimeoutCounter >= USB_MAX_TIMEOUT) ? TRUE : FALSE; +} + + +UBYTE ConvertHighToHex(UBYTE TempChar) +{ + TempChar = (TempChar >> 4) & 0x0F; + if (TempChar > 0x09) + TempChar += 0x37; + else + TempChar += 0x30; + return TempChar; +} + +UBYTE ConvertLowToHex(UBYTE TempChar) +{ + TempChar &= 0x0F; + if (TempChar > 0x09) + TempChar += 0x37; + else + TempChar += 0x30; + return TempChar; +} + +void dUsbStoreBtAddress(UBYTE *pBtAddress) +{ + UBYTE NoToConvert; + + // make the Lap human readable (hmmm Hexadecimal) + NoToConvert = *pBtAddress++; + SerialNumberDescriptor[2] = ConvertHighToHex(NoToConvert); + SerialNumberDescriptor[4] = ConvertLowToHex(NoToConvert); + + NoToConvert = *pBtAddress++; + SerialNumberDescriptor[6] = ConvertHighToHex(NoToConvert); + SerialNumberDescriptor[8] = ConvertLowToHex(NoToConvert); + + NoToConvert = *pBtAddress++; + SerialNumberDescriptor[10] = ConvertHighToHex(NoToConvert); + SerialNumberDescriptor[12] = ConvertLowToHex(NoToConvert); + + NoToConvert = *pBtAddress++; + SerialNumberDescriptor[14] = ConvertHighToHex(NoToConvert); + SerialNumberDescriptor[16] = ConvertLowToHex(NoToConvert); + + // make the Uap human readable (hmmm Hexadecimal) + NoToConvert = *pBtAddress++; + SerialNumberDescriptor[18] = ConvertHighToHex(NoToConvert); + SerialNumberDescriptor[20] = ConvertLowToHex(NoToConvert); + + // make the Nap human readable (hmmm Hexadecimal) + NoToConvert = *pBtAddress++; + SerialNumberDescriptor[22] = ConvertHighToHex(NoToConvert); + SerialNumberDescriptor[24] = ConvertLowToHex(NoToConvert); + + USBConnect; // We're ready to participate in the real world + BrickNameKnown = TRUE; // OK for referencing :-) +} + + +ULONG dUsbRead(UBYTE *pData, ULONG Length) +{ + ULONG PacketSize, NumberOfBytesReceived; + + NumberOfBytesReceived = 0; + + while (Length) // Wished read size from user (Max length) + { + if ( !(BrickNameKnown)) // Right Brick??? + break; + + if ( !(dUsbIsConfigured()) ) + break; // Not configured - no time to waste + + if ( (*AT91C_UDP_CSR1) & CurrentReceiveBank ) // Data packet rx'ed in Current bank? + { + + PacketSize = MIN((*AT91C_UDP_CSR1) >> 16, Length); // Normalize number of bytes available in FIFO + Length -= PacketSize; // Rest of data to receive + + if (PacketSize < ENDPOINT_OUT_SIZE) // If data less, we only have one loop + Length = 0; + + while(PacketSize--) // While more data in this very packet... + pData[NumberOfBytesReceived++] = *AT91C_UDP_FDR1; // Fill in buffer + + *AT91C_UDP_CSR1 &= ~(CurrentReceiveBank); // Reset current bank pointer + + if (CurrentReceiveBank == AT91C_UDP_RX_DATA_BK0) // Current Receive Bank 0? + CurrentReceiveBank = AT91C_UDP_RX_DATA_BK1; // We better use Bank 1 + else + CurrentReceiveBank = AT91C_UDP_RX_DATA_BK0; // Okay, go for Bank 0 :-) + + } + + else Length = 0; // Leave and let's use the CPU cycles in a better way + + } + + return NumberOfBytesReceived; // Size of actually received stuff + +} + +ULONG dUsbWrite( const UBYTE *pData, ULONG Length) +{ + ULONG CharsEachTx = 0; + + // Send the very first (or only) packet + CharsEachTx = MIN(Length, ENDPOINT_IN_SIZE); // First transmission size + Length -= CharsEachTx; // Adjust the rest of transmission size + + while (CharsEachTx--) // While more chars in this chunk + *AT91C_UDP_FDR2 = *pData++; // Get rid off it one by one + // Pushing the data into the UDP TX-fifo + *AT91C_UDP_CSR2 |= AT91C_UDP_TXPKTRDY; // Signal "DO THE TX" the stuff is delivered... + + while (Length) // While more bytes (I.e. packets) ín total transmission + { // Start filling the second bank + + CharsEachTx = MIN(Length, ENDPOINT_IN_SIZE); + Length -= CharsEachTx; // Adjust total length + + while (CharsEachTx--) // While more chars in this chunk + *AT91C_UDP_FDR2 = *pData++; + + dUsbStartTimeoutTimer(); + while ( !((*AT91C_UDP_CSR2) & AT91C_UDP_TXCOMP) ) // Wait for the the first bank to be sent + if (dUsbTimedOut() || !(dUsbIsConfigured()) ) // Communication down..... Bail out + return Length; // Invalid function - return job length not done + + (*AT91C_UDP_CSR2) &= ~(AT91C_UDP_TXCOMP); // Reset transmit interrupt flag + + while ((*AT91C_UDP_CSR2) & AT91C_UDP_TXCOMP); // Wait until flag (H/W) is reset + + (*AT91C_UDP_CSR2) |= AT91C_UDP_TXPKTRDY; // We're ready to send next bank + + } // Loop while bytes to tx + + dUsbStartTimeoutTimer(); // Arm the timeout timing + while ( !((*AT91C_UDP_CSR2) & AT91C_UDP_TXCOMP) ) // Wait for transmission to complete + if ( !(dUsbIsConfigured()) || dUsbTimedOut()) // Communication down..... Bail out + return Length; // Invalid function - return job length not done + + (*AT91C_UDP_CSR2) &= ~(AT91C_UDP_TXCOMP); // Reset Interrupt flag + + while ((*AT91C_UDP_CSR2) & AT91C_UDP_TXCOMP); // Wait for H/W to settle..... + + return Length; // Return byte count NOT x-ferred + +} + +static void dUsbSendStall(void) +{ + (*AT91C_UDP_CSR0) |= AT91C_UDP_FORCESTALL; // Set STALL condition + while ( !((*AT91C_UDP_CSR0) & AT91C_UDP_ISOERROR) ); // Wait until stall ack'ed + + (*AT91C_UDP_CSR0) &= ~(AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR); // Reset again + while ((*AT91C_UDP_CSR0) & (AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR)); // Wait until H/W really reset +} + +static void dUsbSendZeroLengthPackage(void) +{ + // Signal that buffer is ready to send + (*AT91C_UDP_CSR0) |= AT91C_UDP_TXPKTRDY; + + dUsbStartTimeoutTimer(); + + // Wait for ACK handshake from host + while ( !((*AT91C_UDP_CSR0) & AT91C_UDP_TXCOMP) && !dUsbTimedOut()); + // Clear handshake flag + (*AT91C_UDP_CSR0) &= ~(AT91C_UDP_TXCOMP); + while ((*AT91C_UDP_CSR0) & AT91C_UDP_TXCOMP); +} + +static void dUsbSendViaControl(const UBYTE *pData, ULONG Length) +{ + ULONG BytesToTx = 0; + AT91_REG Temp_Csr; + UBYTE HaveToTxZeroLength = FALSE; + UBYTE ZeroCouldBeNeeded = FALSE; + + // If the amount of data requested is more than what can be sent, a 0-length + // packet may be required + if (RequestedData > Length) + { + ZeroCouldBeNeeded = TRUE; // Exact same size would be interpreted as EOP @ host + } + + do + { + // The endpoint size is 8 bytes. Limit each data phase to 8 bytes. + + BytesToTx = MIN(Length, 8); + Length -= BytesToTx; + + // If this is the last data phase containing data, but the host requested + // more, a 0-byte packet will be needed to terminate the data phase. + if(ZeroCouldBeNeeded && (Length == 0) && (BytesToTx == 8)) + { + HaveToTxZeroLength = TRUE; + } + + // Copy data to endpoint buffer + while (BytesToTx--) + { + (*AT91C_UDP_FDR0) = *pData++; + } + + // Signal that buffer is ready to send + (*AT91C_UDP_CSR0) |= AT91C_UDP_TXPKTRDY; + + dUsbStartTimeoutTimer(); + + // Wait for ACK handshake from host + do + { + Temp_Csr = (*AT91C_UDP_CSR0); + + // Return if the status phase occurs before the packet is accepted + if (Temp_Csr & AT91C_UDP_RX_DATA_BK0) + { + // Clear the PKTRDY flag + (*AT91C_UDP_CSR0) &= ~(AT91C_UDP_TXPKTRDY); + // Clear the status phase flag + (*AT91C_UDP_CSR0) &= ~(AT91C_UDP_RX_DATA_BK0); + return; + } + } + while (!(Temp_Csr & AT91C_UDP_TXCOMP) && !dUsbTimedOut()); + + // Clear handshake flag + (*AT91C_UDP_CSR0) &= ~(AT91C_UDP_TXCOMP); + + while ((*AT91C_UDP_CSR0) & AT91C_UDP_TXCOMP); + + } while (Length); + + if(HaveToTxZeroLength) + { + dUsbSendZeroLengthPackage(); + } + + dUsbStartTimeoutTimer(); + + // Wait for Status Phase + while(!((*AT91C_UDP_CSR0) & AT91C_UDP_RX_DATA_BK0) && !dUsbTimedOut()); + // Clear flag + (*AT91C_UDP_CSR0) &= ~(AT91C_UDP_RX_DATA_BK0); +} + +static void dUsbEnumerate(void) +{ + UBYTE bmRequestType, bRequest; + UWORD wValue, wIndex, wLength, wStatus; + + if ( !((*AT91C_UDP_CSR0) & AT91C_UDP_RXSETUP) ) // No setup package available + return; + // Bytes are popped from the FIFO one by one + + bmRequestType = *AT91C_UDP_FDR0; + bRequest = *AT91C_UDP_FDR0; + wValue = ((*AT91C_UDP_FDR0) & 0xFF); + wValue |= ((*AT91C_UDP_FDR0) << 8); + wIndex = ((*AT91C_UDP_FDR0) & 0xFF); + wIndex |= ((*AT91C_UDP_FDR0) << 8); + wLength = ((*AT91C_UDP_FDR0) & 0xFF); + wLength |= ((*AT91C_UDP_FDR0) << 8); + + if (bmRequestType & 0x80) // If a DEVICE-TO-HOST request + { + *AT91C_UDP_CSR0 |= AT91C_UDP_DIR; // Enables data IN transaction in the control data stage + while ( !((*AT91C_UDP_CSR0) & AT91C_UDP_DIR) ); // Repeat until the DIR bit is set + } + + *AT91C_UDP_CSR0 &= ~AT91C_UDP_RXSETUP; // Device firmware has read the setup data in FIFO + while ( ((*AT91C_UDP_CSR0) & AT91C_UDP_RXSETUP) ); // Wait until bit cleared + + // Handle supported standard device request from Table 9-3 in USB specification Rev 2.0 + + switch ((bRequest << 8) | bmRequestType) + { + case STD_GET_DESCRIPTOR: + + RequestedData = wLength; + + if (wValue == 0x100) // Return Device Descriptor + { + if (sizeof(DeviceDescriptor) > wLength) + { + dUsbSendViaControl(DeviceDescriptor, wLength); + } + else + { + dUsbSendViaControl(DeviceDescriptor, sizeof(DeviceDescriptor)); + } + } + else if (wValue == 0x200) // Return Configuration Descriptor + { + if (sizeof(ConfigurationDescriptor) > wLength) + { + dUsbSendViaControl(ConfigurationDescriptor, wLength); + } + else + { + dUsbSendViaControl(ConfigurationDescriptor, sizeof(ConfigurationDescriptor)); + } + } + else if ((wValue & 0xF00) == 0x300) + { + switch(wValue & 0xFF) + { + case 0x00: + if ((sizeof(LangIdDescriptor)) > wLength) + { + dUsbSendViaControl(LangIdDescriptor, wLength); + } + else + { + dUsbSendViaControl(LangIdDescriptor, sizeof(LangIdDescriptor)); + } + break; + + case 0x01: + if ((sizeof(SerialNumberDescriptor)) > wLength) + { + dUsbSendViaControl(SerialNumberDescriptor, wLength); + } + else + { + dUsbSendViaControl(SerialNumberDescriptor, sizeof(SerialNumberDescriptor)); + } + break; + + default: + dUsbSendStall(); // Illegal request :-( + break; + } + } + else + dUsbSendStall(); // Illegal request :-( + + break; + + case STD_SET_ADDRESS: + + // Status IN transfer + (*AT91C_UDP_CSR0) |= AT91C_UDP_TXPKTRDY; + + dUsbStartTimeoutTimer(); + + while((*AT91C_UDP_CSR0) & AT91C_UDP_TXPKTRDY && !dUsbTimedOut()); + + *AT91C_UDP_FADDR = (AT91C_UDP_FEN | wValue); // Set device address. No check for invalid address. + // Function endpoint enabled. + *AT91C_UDP_GLBSTATE = (wValue) ? AT91C_UDP_FADDEN : 0; // If Device address != 0 then flag device + // in ADDRESS STATE + break; + + case STD_SET_CONFIGURATION: + + CurrentConfiguration = wValue; // Low byte of wValue = wanted configuration + UsbConnectionStates = USB_CONFIGURED; + dUsbSendZeroLengthPackage(); // Signal request processed OK + + *AT91C_UDP_GLBSTATE = (wValue) ? AT91C_UDP_CONFG : AT91C_UDP_FADDEN; // If wanted configuration != 0 + + *AT91C_UDP_CSR1 = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT) : 0; // Endpoint 1 enabled and set as BULK OUT + *AT91C_UDP_CSR2 = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN) : 0; // Endpoint 2 enabled and set as BULK IN + *AT91C_UDP_CSR3 = (wValue) ? (AT91C_UDP_EPTYPE_INT_IN) : 0; // Endpoint 3 disabled and set as INTERRUPT IN + + break; + + case STD_GET_CONFIGURATION: // The actual configuration value is sent to HOST + + RequestedData = sizeof(CurrentConfiguration); + + dUsbSendViaControl((UBYTE *) &(CurrentConfiguration), sizeof(CurrentConfiguration)); + + break; + + case STD_GET_STATUS_ZERO: + + wStatus = 0x01; // Atmel has a 0x00, but we're not BUS-powered + RequestedData = sizeof(wStatus); + + dUsbSendViaControl((UBYTE *) &wStatus, sizeof(wStatus)); + + break; + + case STD_GET_STATUS_INTERFACE: // Everything reset to zero (reserved) + + wStatus = 0; + RequestedData = sizeof(wStatus); + + dUsbSendViaControl((UBYTE *) &wStatus, sizeof(wStatus)); + + break; + + case STD_GET_STATUS_ENDPOINT: + + wStatus = 0; + RequestedData = sizeof(wStatus); + wIndex &= 0x0F; // Mask the endpoint # + + if (((*AT91C_UDP_GLBSTATE) & AT91C_UDP_CONFG) && (wIndex <= 3)) // If device in CONFIGURED state + { // and ENDPOINT selected in valid range + + switch (wIndex) + { + + case 1: wStatus = ((*AT91C_UDP_CSR1) & AT91C_UDP_EPEDS) ? 0 : 1; // If an endpoint is halted, the HALT + // feature is set to 1, else reset + break; + + case 2: wStatus = ((*AT91C_UDP_CSR2) & AT91C_UDP_EPEDS) ? 0 : 1; + + break; + + case 3: wStatus = ((*AT91C_UDP_CSR3) & AT91C_UDP_EPEDS) ? 0 : 1; + + break; + default: + // We'll never come here, but we'll never say never....... + break; + } + + dUsbSendViaControl((UBYTE *) &wStatus, sizeof(wStatus)); + + } + + else if (((*AT91C_UDP_GLBSTATE) & AT91C_UDP_FADDEN) && (wIndex == 0)) + { + wStatus = ((*AT91C_UDP_CSR0) & AT91C_UDP_EPEDS) ? 0 : 1; // Return 1 if device in ADRESSED state + + dUsbSendViaControl((UBYTE *) &wStatus, sizeof(wStatus)); + } + else + + dUsbSendStall(); // Illegal request :-( + + break; + + case STD_SET_FEATURE_ZERO: + + dUsbSendStall(); // Illegal request :-( + + break; + + case STD_SET_FEATURE_INTERFACE: + + dUsbSendZeroLengthPackage(); // TextBook + + break; + + case STD_SET_FEATURE_ENDPOINT: + + wIndex &= 0x0F; + + if ((wValue == 0) && wIndex && (wIndex <= 3)) // Feature Selector = 0 ENDPOINT HALT and + { // endpoint isolated and validated + + switch (wIndex) + { + + case 1: (*AT91C_UDP_CSR1) = 0; + + break; + + case 2: (*AT91C_UDP_CSR2) = 0; + + break; + + case 3: (*AT91C_UDP_CSR3) = 0; + + break; + + default: + // We'll never come here, but we'll never say never....... + break; + + } + + dUsbSendZeroLengthPackage(); + + } + else + + dUsbSendStall(); // Illegal request :-( + + break; + + case STD_CLEAR_FEATURE_ZERO: + + dUsbSendStall(); // Illegal request :-( + + break; + + case STD_CLEAR_FEATURE_INTERFACE: + + dUsbSendZeroLengthPackage(); // No special + + break; + + case STD_CLEAR_FEATURE_ENDPOINT: + + wIndex &= 0x0F; + + if ((wValue == 0) && wIndex && (wIndex <= 3)) // Feature Selector = 0 => ENABLE A HALTED endpoint + { // and endpoint isolated and validated + + if (wIndex == 1) + (*AT91C_UDP_CSR1) = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT); // On duty again + else if (wIndex == 2) + (*AT91C_UDP_CSR2) = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN); // - + else if (wIndex == 3) + (*AT91C_UDP_CSR3) = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_INT_IN); // - + + dUsbSendZeroLengthPackage(); + + } + else + + dUsbSendStall(); // Illegal request :-( + + break; + + default: + + dUsbSendStall(); // Illegal request :-( + + break; + } +} + +UBYTE dUsbIsConfigured(void) +{ + + if (*AT91C_UDP_ISR & END_OF_BUS_RESET) // If "End Of Bus Reset Interrupt" + { // Somebody fallen in the wire? ;-) + + + *AT91C_UDP_ICR = END_OF_BUS_RESET; // Reset "End Of Bus Reset Interrupt" + *AT91C_UDP_ICR = SUSPEND_RESUME; // State unknown after reset, so we better clear + *AT91C_UDP_ICR = WAKEUP; // As above + + CurrentConfiguration = 0; // We're new and ready + UsbConnectionStates = USB_NOT_CONFIGURED; + + *AT91C_UDP_RSTEP = 0xFFFFFFFF; // Reset all implemented endpoints "and a few more" + *AT91C_UDP_RSTEP = 0x0; // Restored as zeroes + // Below our main crash thing, if it is missing ;-) + CurrentReceiveBank = AT91C_UDP_RX_DATA_BK0; // Start the PING-PONG buffers at a known state and order + + *AT91C_UDP_FADDR = AT91C_UDP_FEN; // Set FEN in the Function Address Register + // USB device is able to receive and transfer data + + *AT91C_UDP_CSR0 = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL); // Configure endpoint 0 + // AT91C_UDP_EPEDS = Endpoint enable + // AT91C_UDP_EPTYPE_CTRL = Endpoint type CONTROL + } + + else if (*AT91C_UDP_ISR & SUSPEND_INT) + { + if (UsbConnectionStates == USB_CONFIGURED) + { + UsbConnectionStates = USB_CONFIGURED_BUT_SUSPENDED; + } + else + { + UsbConnectionStates = USB_NOT_CONFIGURED; + } + + *AT91C_UDP_ICR = SUSPEND_INT; + CurrentReceiveBank = AT91C_UDP_RX_DATA_BK0; // Start the PING-PONG buffers at a known state and order + } + + else if (*AT91C_UDP_ISR & SUSPEND_RESUME) + { + if (UsbConnectionStates == USB_CONFIGURED_BUT_SUSPENDED) + { + UsbConnectionStates = USB_CONFIGURED; + } + else + { + UsbConnectionStates = USB_NOT_CONFIGURED; + } + + *AT91C_UDP_ICR = WAKEUP; + *AT91C_UDP_ICR = SUSPEND_RESUME; + } + + else if (*AT91C_UDP_ISR & AT91C_UDP_EPINT0) // If "Endpoint 0 Interrupt" + { + *AT91C_UDP_ICR = AT91C_UDP_EPINT0; // Reset "Endpoint 0 Interrupt" + if (BrickNameKnown) + dUsbEnumerate(); // Let's date & exchange "personal data" + } + + if (UsbConnectionStates == USB_CONFIGURED) + { + return TRUE; + } + else + { + return FALSE; + } + +} + + +void dUsbInsertHandle(UBYTE Handle) +{ + UBYTE Tmp; + + Tmp = 0; + while((UsbHandleList[Tmp] != MAX_HANDLES) && (Tmp < MAX_HANDLES)) + { + Tmp++; + } + UsbHandleList[Tmp] = Handle; +} + +void dUsbRemoveHandle(UBYTE Handle) +{ + UBYTE Tmp; + + Tmp = 0; + while (Tmp < MAX_HANDLES) + { + if (Handle == UsbHandleList[Tmp]) + { + UsbHandleList[Tmp] = MAX_HANDLES; + } + Tmp++; + } +} + +UWORD dUsbGetFirstHandle(void) +{ + UWORD RtnVal; + + UsbHandleCnt = 0; + RtnVal = dUsbGetNextHandle(); + + return(RtnVal); +} + +UWORD dUsbGetNextHandle(void) +{ + UBYTE Tmp; + UWORD RtnVal; + + RtnVal = 0; + Tmp = UsbHandleCnt; + while((Tmp < MAX_HANDLES) && (MAX_HANDLES == UsbHandleList[Tmp])) + { + Tmp++; + } + UsbHandleCnt = Tmp + 1; + + if (Tmp < MAX_HANDLES) + { + RtnVal |= UsbHandleList[Tmp]; + } + else + { + RtnVal = 0x8100; + } + + return(RtnVal); +} + +UWORD dUsbCheckConnection(void) +{ + UWORD ADValue; + UWORD Return; + + Return = FALSE; + USBReadADCValue(&ADValue); + + if (ADValue > 512) + { + Return = TRUE; + } + return(Return); +} + +void dUsbInit(void) +{ + UBYTE Tmp; + + // We could come from a SAMBA session and then we need + // to "introduce ourself in a polite way for the PNP manager + // We will pull the carpet and start a new session by removing + // the pull up of the D+ wire + + BrickNameKnown = FALSE; + dUsbStartTimeoutTimer(); // Let H/W settle + dUsbDisconnect(); // Pull the carpet + while(!USBTimedOut); // wait 1 mS. + + USBHwInit; // New session + + CurrentConfiguration = 0; // We're new born + UsbConnectionStates = USB_NOT_CONFIGURED; + CurrentReceiveBank = AT91C_UDP_RX_DATA_BK0; // Always start from Bank 0 + RequestedData = 0; + + for(Tmp = 0; Tmp < MAX_HANDLES; Tmp++) + { + UsbHandleList[Tmp] = MAX_HANDLES; + } +} + +void dUsbResetConfig(void) +{ + CurrentConfiguration = 0; // We've lost the connection + UsbConnectionStates = USB_NOT_CONFIGURED; +} + +void dUsbExit(void) +{ +// USBExit; +} diff --git a/src/d_usb.h b/src/d_usb.h new file mode 100644 index 0000000..b8e78c4 --- /dev/null +++ b/src/d_usb.h @@ -0,0 +1,51 @@ +// +// Programmer +// +// Date init 14.12.2004 +// +// Reviser $Author:: Dkandlun $ +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: d_usb.h $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_usb. $ +// +// Platform C +// + +#ifndef D_USB +#define D_USB + +//* public constants + +// LOW level commands + +#define OPENFILEWRITE 0x01 +#define OPENFILEREAD 0x02 +#define WRITEFILE 0x03 +#define CLOSEFILE 0x04 + +// Low level direct command escape + +#define DIRECTCOMMAND 0x80 // Escape sent to the Loader +#define USB_TIMEOUT 0x0BB8 // Equals approx. 1 mS. Used for recover a "broken" cable situation + +//* external function description + +void dUsbInit(void); +void dUsbExit(void); +ULONG dUsbRead(UBYTE *pData, ULONG Length); +ULONG dUsbWrite( const UBYTE *pData, ULONG Length); +UBYTE dUsbIsConfigured(void); + +void dUsbInsertHandle(UBYTE Handle); +void dUsbRemoveHandle(UBYTE Handle); +UWORD dUsbGetFirstHandle(void); +UWORD dUsbGetNextHandle(void); +UWORD dUsbCheckConnection(void); +void dUsbResetConfig(void); +void dUsbStoreBtAddress(UBYTE *pBtAddress); +#endif diff --git a/src/d_usb.r b/src/d_usb.r new file mode 100644 index 0000000..6c7a0c3 --- /dev/null +++ b/src/d_usb.r @@ -0,0 +1,65 @@ +// +// Programmer +// +// Date init 14.12.2004 +// +// Reviser $Author:: Dkandlun $ +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: d_usb.r $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_usb. $ +// +// Platform C +// + +#ifdef SAM7S256 + +#ifdef PROTOTYPE_PCB_3 +#define ENABLEUsbPU *AT91C_PIOA_PER = AT91C_PIO_PA16; /* PIO allowed to control bit 16 */\ + *AT91C_PIOA_OER = AT91C_PIO_PA16; /* Output pin 16 enabled */\ + *AT91C_PIOA_SODR = AT91C_PIO_PA16 /* Pin 16 set = enable USB pull-up */ +#endif + +#ifdef PROTOTYPE_PCB_4 +#define ENABLEUsbPU *AT91C_PIOA_PER = AT91C_PIO_PA16; /* PIO allowed to control bit 16 */\ + *AT91C_PIOA_OER = AT91C_PIO_PA16; /* Output pin 16 enabled */\ + *AT91C_PIOA_CODR = AT91C_PIO_PA16 /* Pin 16 clear = enable USB pull-up */ + +#define DISABLEUsbPU *AT91C_PIOA_PER = AT91C_PIO_PA16; /* PIO allowed to control bit 16 */\ + *AT91C_PIOA_OER = AT91C_PIO_PA16; /* Output pin 16 enabled */\ + *AT91C_PIOA_SODR = AT91C_PIO_PA16 /* Pin 16 set = disable USB pull-up */ +#endif + + +#define USBHwInit *AT91C_CKGR_PLLR |= AT91C_CKGR_USBDIV_1; /* Set the PLL USB Divider (96MHz/2) */\ + *AT91C_PMC_SCER = AT91C_PMC_UDP; /* WRITE-ONLY REG! Enables the 48MHz USB clock UDPCK (SysClk) */\ + *AT91C_PMC_PCER = (1 << AT91C_ID_UDP); /* WRITE-ONLY REG! Enable USB clock (Peripheral Clock) */\ + \ + /* Enable UDP PullUp (USB_DP_PUP) : enable & Clear of the corresponding PIO */ \ + \ + /* Removed 22022006 14:20 pc ENABLEUsbPU BlueCore delay , No pull up before OK serial-no rec. from B.C.*/ + + +static ULONG USBTimeOut; + +#define USBTimedOut (USB_TIMEOUT < ((((*AT91C_PITC_PIIR) & AT91C_PITC_CPIV) - USBTimeOut) & AT91C_PITC_CPIV)) + +#define USBGetActualTime USBTimeOut = ((*AT91C_PITC_PIIR) & AT91C_PITC_CPIV) + +#define USBReadADCValue(ADValue) *ADValue = *AT91C_ADC_CDR4 + +#define USBExit + +#define USBDisconnect DISABLEUsbPU + +#define USBConnect ENABLEUsbPU + +#endif + +#ifdef PCWIN + +#endif diff --git a/src/m_sched.c b/src/m_sched.c new file mode 100644 index 0000000..7c69551 --- /dev/null +++ b/src/m_sched.c @@ -0,0 +1,94 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: m_sched.c $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/m_sche $ +// +// Platform C +// + + +#define INCLUDE_OS + +#define MODULEHEADERS 32 + +#include "stdconst.h" +#include "modules.h" +#include "m_sched.h" + +#include "c_comm.h" +#include "c_input.h" +#include "c_button.h" +#include "c_loader.h" +#include "c_sound.h" +#include "c_display.h" +#include "c_lowspeed.h" +#include "c_output.h" +#include "c_cmd.h" +#include "c_cmd.iom" +#include "c_ioctrl.h" +#include "c_ui.h" + + +static const HEADER* pModuleHeaders[MODULEHEADERS] = +{ + &cComm, + &cInput, + &cButton, + &cDisplay, + &cLoader, + &cLowSpeed, + &cOutput, + &cSound, + &cIOCtrl, + &cCmd, + &cUi, + 0 +}; + + +void mSchedInit(void) +{ + UWORD Tmp; + + Tmp = 0; + while(pModuleHeaders[Tmp]) + { + (*pModuleHeaders[Tmp]).cInit((void*) pModuleHeaders); + Tmp++; + } +} + + +UBYTE mSchedCtrl(void) +{ + UWORD Tmp; + + Tmp = 0; + while(pModuleHeaders[Tmp]) + { + (*pModuleHeaders[Tmp]).cCtrl(); + Tmp++; + } + + return(((IOMAPCMD*)(pModuleHeaders[ENTRY_CMD]->pIOMap))->Awake); +} + + +void mSchedExit(void) +{ + UWORD Tmp; + + Tmp = 0; + while(pModuleHeaders[Tmp]) + { + (*pModuleHeaders[Tmp]).cExit(); + Tmp++; + } +} + diff --git a/src/m_sched.h b/src/m_sched.h new file mode 100644 index 0000000..00794ee --- /dev/null +++ b/src/m_sched.h @@ -0,0 +1,135 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 14-11-07 12:40 $ +// +// Filename $Workfile:: m_sched.h $ +// +// Version $Revision:: 1 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/m_sche $ +// +// Platform C +// + + + +#define APPNAME "LMS01" + +#define COPYRIGHTSTRING "Let's samba nxt arm in arm, (c)LEGO System A/S" + +#define COPYRIGHTSTRINGLENGTH 46 /* Number of bytes checked in COPYRIGHTSTRING */ + + +#ifndef _WINDOWS + +#define SAM7SXX + +#ifdef SAM7SXX + + // + // Platform ATMEL ARM7 + // + // + +#define OSC 48054850L +#define SYSFREQ 1000 + + +#include "sam7s256.h" + +#if defined (PROTOTYPE_PCB_3) || (PROTOTYPE_PCB_4) + +#define TSTPin AT91C_PIO_PA27 + +#else + +#define TSTPin AT91C_PIO_PA31 + +#endif + +#define TSTInit {\ + *AT91C_PIOA_PER = TSTPin;\ + *AT91C_PIOA_OER = TSTPin;\ + } + +#define TSTOn {\ + *AT91C_PIOA_SODR = TSTPin;\ + } + +#define TSTOff {\ + *AT91C_PIOA_CODR = TSTPin;\ + } + +#define TSTExit {\ + *AT91C_PIOA_ODR = TSTPin;\ + *AT91C_PIOA_CODR = TSTPin;\ + } + +/* Defines related to loader */ +#define MAX_HANDLES 16 + + +/* Defines related to I2c */ +#define BYTES_TO_TX 8 +#define BYTES_TO_RX 12 + +enum +{ + NOS_OF_AVR_OUTPUTS = 4, + NOS_OF_AVR_BTNS = 4, + NOS_OF_AVR_INPUTS = 4 +}; + +typedef struct +{ + UWORD AdValue[NOS_OF_AVR_INPUTS]; + UWORD Buttons; + UWORD Battery; +}IOFROMAVR; + +typedef struct +{ + UBYTE Power; + UBYTE PwmFreq; + SBYTE PwmValue[NOS_OF_AVR_OUTPUTS]; + UBYTE OutputMode; + UBYTE InputPower; +}IOTOAVR; + +extern IOTOAVR IoToAvr; +extern IOFROMAVR IoFromAvr; + +#ifdef INCLUDE_OS + +#include "sam7s256.c" + +IOTOAVR IoToAvr; +IOFROMAVR IoFromAvr; + +#endif + +#endif + +#else + + // + // Platform PCWIN + // + // + +#define OSC 1192000L +#define SYSFREQ 1000 + +#include "Pcwin.h" + +#ifdef INCLUDE_OS + +#include "Pcwin.c" + +#endif + +#endif + + + diff --git a/src/modules.h b/src/modules.h new file mode 100644 index 0000000..a5f3bb1 --- /dev/null +++ b/src/modules.h @@ -0,0 +1,338 @@ +// +// Programmer +// +// Date init 14.12.2004 +// +// Reviser $Author:: Dktochpe $ +// +// Revision date $Date:: 19-02-08 8:15 $ +// +// Filename $Workfile:: modules.h $ +// +// Version $Revision:: 4 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/module $ +// +// Platform C +// + +#ifndef MODULE_HEADER +#define MODULE_HEADER + +#define FILENAME_LENGTH 19 // zero termination not included +#define FILEHEADER_LENGTH 8 // all simple file headers +#define DISPLAYLINE_LENGTH 16 // zero termination not included +#define ON_BRICK_PROGRAMSTEPS 5 // no of on brick program steps +#define STATUSTEXT_SIZE 8 // zero termination not included + +#define TXT_SOUND_EXT "rso" // Sound filename extension +#define TXT_LMS_EXT "rxe" // Mindstorms program filename extension +#define TXT_NXT_EXT "rpg" // Program filename extension +#define TXT_TRYME_EXT "rtm" // Try me program filename extension +#define TXT_DATA_EXT "log" // Datalog filename extension +#define TXT_SYS_EXT "sys" // System filename extension (hidden) +#define TXT_TMP_EXT "tmp" // Temporary filename extension (hidden) + + +/* Error codes from then Loader */ +enum +{ + SUCCESS = 0x0000, + INPROGRESS = 0x0001, + REQPIN = 0x0002, + NOMOREHANDLES = 0x8100, + NOSPACE = 0x8200, + NOMOREFILES = 0x8300, + EOFEXSPECTED = 0x8400, + ENDOFFILE = 0x8500, + NOTLINEARFILE = 0x8600, + FILENOTFOUND = 0x8700, + HANDLEALREADYCLOSED = 0x8800, + NOLINEARSPACE = 0x8900, + UNDEFINEDERROR = 0x8A00, + FILEISBUSY = 0x8B00, + NOWRITEBUFFERS = 0x8C00, + APPENDNOTPOSSIBLE = 0x8D00, + FILEISFULL = 0x8E00, + FILEEXISTS = 0x8F00, + MODULENOTFOUND = 0x9000, + OUTOFBOUNDERY = 0x9100, + ILLEGALFILENAME = 0x9200, + ILLEGALHANDLE = 0x9300, + BTBUSY = 0x9400, + BTCONNECTFAIL = 0x9500, + BTTIMEOUT = 0x9600, + FILETX_TIMEOUT = 0x9700, + FILETX_DSTEXISTS = 0x9800, + FILETX_SRCMISSING = 0x9900, + FILETX_STREAMERROR = 0x9A00, + FILETX_CLOSEERROR = 0x9B00 +}; + + +/* interface between comm and BC4 */ +enum +{ + MSG_BEGIN_INQUIRY, + MSG_CANCEL_INQUIRY, + MSG_CONNECT, + MSG_OPEN_PORT, + MSG_LOOKUP_NAME, + MSG_ADD_DEVICE, + MSG_REMOVE_DEVICE, + MSG_DUMP_LIST, + MSG_CLOSE_CONNECTION, + MSG_ACCEPT_CONNECTION, + MSG_PIN_CODE, + MSG_OPEN_STREAM, + MSG_START_HEART, + MSG_HEARTBEAT, + MSG_INQUIRY_RUNNING, + MSG_INQUIRY_RESULT, + MSG_INQUIRY_STOPPED, + MSG_LOOKUP_NAME_RESULT, + MSG_LOOKUP_NAME_FAILURE, + MSG_CONNECT_RESULT, + MSG_RESET_INDICATION, + MSG_REQUEST_PIN_CODE, + MSG_REQUEST_CONNECTION, + MSG_LIST_RESULT, + MSG_LIST_ITEM, + MSG_LIST_DUMP_STOPPED, + MSG_CLOSE_CONNECTION_RESULT, + MSG_PORT_OPEN_RESULT, + MSG_SET_DISCOVERABLE, + MSG_CLOSE_PORT, + MSG_CLOSE_PORT_RESULT, + MSG_PIN_CODE_ACK, + MSG_DISCOVERABLE_ACK, + MSG_SET_FRIENDLY_NAME, + MSG_SET_FRIENDLY_NAME_ACK, + MSG_GET_LINK_QUALITY, + MSG_LINK_QUALITY_RESULT, + MSG_SET_FACTORY_SETTINGS, + MSG_SET_FACTORY_SETTINGS_ACK, + MSG_GET_LOCAL_ADDR, + MSG_GET_LOCAL_ADDR_RESULT, + MSG_GET_FRIENDLY_NAME, + MSG_GET_DISCOVERABLE, + MSG_GET_PORT_OPEN, + MSG_GET_FRIENDLY_NAME_RESULT, + MSG_GET_DISCOVERABLE_RESULT, + MSG_GET_PORT_OPEN_RESULT, + MSG_GET_VERSION, + MSG_GET_VERSION_RESULT, + MSG_GET_BRICK_STATUSBYTE_RESULT, + MSG_SET_BRICK_STATUSBYTE_RESULT, + MSG_GET_BRICK_STATUSBYTE, + MSG_SET_BRICK_STATUSBYTE +}; + +#define SIZE_OF_BT_NAME 16 +#define SIZE_OF_BRICK_NAME 8 +#define SIZE_OF_CLASS_OF_DEVICE 4 +#define SIZE_OF_BT_PINCODE 16 +#define SIZE_OF_BDADDR 7 + + +enum +{ + ENTRY_COMM, + ENTRY_INPUT, + ENTRY_BUTTON, + ENTRY_DISPLAY, + ENTRY_LOADER, + ENTRY_LOWSPEED, + ENTRY_OUTPUT, + ENTRY_SOUND, + ENTRY_IOCTRL, + ENTRY_CMD, + ENTRY_UI, + ENTRY_FREE2, + ENTRY_FREE3, + ENTRY_FREE4, + ENTRY_FREE5 +}; + +typedef struct +{ + ULONG ModuleID; + UBYTE ModuleName[FILENAME_LENGTH + 1]; + void (*cInit)(void* pHeader); + void (*cCtrl)(void); + void (*cExit)(void); + void *pIOMap; + void *pVars; + UWORD IOMapSize; + UWORD VarsSize; + UWORD ModuleSize; +}HEADER; + +enum +{ + FILEFORMAT_SOUND = 0x0100, // rso + FILEFORMAT_SOUND_COMPRESSED = 0x0101, // rso + FILEFORMAT_BITMAP = 0x0200, + FILEFORMAT_FONT = 0x0300, + FILEFORMAT_ICON = 0x0400, + FILEFORMAT_TEXT = 0x0500, + FILEFORMAT_MELODY = 0x0600, + FILEFORMAT_MENU = 0x0700, // rms + FILEFORMAT_PROGRAM = 0x0800, // rpg + FILEFORMAT_DATALOG = 0x0900 // rdt +}; + +typedef struct +{ + UBYTE FormatMsb; + UBYTE FormatLsb; + UBYTE DateBytesMsb; + UBYTE DataBytesLsb; + UBYTE SampleRateMsb; + UBYTE SampleRateLsb; + UBYTE PlayModeMsb; + UBYTE PlayModeLsb; + UBYTE Data[]; +} +SOUND; + +typedef struct +{ + UBYTE FormatMsb; + UBYTE FormatLsb; + UBYTE DateBytesMsb; + UBYTE DataBytesLsb; + UBYTE StartX; + UBYTE StartY; + UBYTE PixelsX; + UBYTE PixelsY; + UBYTE Data[]; +} +BMPMAP; + +typedef struct +{ + UBYTE FormatMsb; + UBYTE FormatLsb; + UBYTE DataBytesMsb; + UBYTE DataBytesLsb; + UBYTE ItemsX; + UBYTE ItemsY; + UBYTE ItemPixelsX; + UBYTE ItemPixelsY; + UBYTE Data[]; +} +FONT; + +typedef struct +{ + UBYTE FormatMsb; + UBYTE FormatLsb; + UBYTE DataBytesMsb; + UBYTE DataBytesLsb; + UBYTE ItemsX; + UBYTE ItemsY; + UBYTE ItemPixelsX; + UBYTE ItemPixelsY; + UBYTE Data[]; +} +ICON; + +typedef struct +{ + UBYTE FormatMsb; + UBYTE FormatLsb; + UBYTE DataBytesMsb; + UBYTE DataBytesLsb; + UBYTE ItemsX; + UBYTE ItemsY; + UBYTE ItemCharsX; + UBYTE ItemCharsY; + UBYTE Data[]; +} +TXT; + +typedef struct +{ + UBYTE FormatMsb; + UBYTE FormatLsb; + UBYTE DateBytesMsb; + UBYTE DataBytesLsb; + UBYTE TonesMsb; + UBYTE TonesLsb; + UBYTE PlayModeMsb; + UBYTE PlayModeLsb; + UBYTE Data[]; // Data[0] = FreqMsb, Data[1] = FreqLsb, Data[2] = DurationMsb, Data[3] = DurationLsb .... +} +MELODY; + +typedef struct +{ + UBYTE FormatMsb; + UBYTE FormatLsb; + UBYTE DataBytesMsb; + UBYTE DataBytesLsb; + UBYTE Steps; + UBYTE NotUsed1; + UBYTE NotUsed2; + UBYTE NotUsed3; + UBYTE Data[]; +} +PROGRAM; + +typedef struct +{ + UBYTE FormatMsb; + UBYTE FormatLsb; + UBYTE DataBytesMsb; + UBYTE DataBytesLsb; + UBYTE TotalTime3; + UBYTE TotalTime2; + UBYTE TotalTime1; + UBYTE TotalTime0; + UBYTE Data[]; +} +DATALOG; + +#define ICON_TEXTLNG 15 // 15 characters +#define ICON_IMAGESIZE 72 // 24 x 24 pixels +#define MAX_MENUITEMS 256 + +typedef struct +{ + UBYTE ItemId67; // Menu item id + UBYTE ItemId45; // Menu item id + UBYTE ItemId23; // Menu item id + UBYTE ItemId01; // Menu item id + UBYTE SpecialMask3; // Menu item special mask (TBD) + UBYTE SpecialMask2; // Menu item special mask (TBD) + UBYTE SpecialMask1; // Menu item special mask (TBD) + UBYTE SpecialMask0; // Menu item special mask (TBD) + UBYTE FunctionIndex; // Menu item enter function call index + UBYTE FunctionParameter; // Menu item enter function parameter + UBYTE FileLoadNo; // Menu item enter menu file load no + UBYTE NextMenu; // Menu item enter next level menu no + UBYTE IconText[ICON_TEXTLNG + 1]; // Menu item icon text string + UBYTE IconImageNo; // Menu item icon image number +}MENUITEM; + +typedef struct +{ + UBYTE FormatMsb; + UBYTE FormatLsb; + UBYTE DataBytesMsb; + UBYTE DataBytesLsb; + UBYTE ItemSize; + UBYTE Items; + UBYTE ItemPixelsX; + UBYTE ItemPixelsY; + MENUITEM Data[MAX_MENUITEMS]; +} +MENU; + +typedef UBYTE (*FUNCTION)(UBYTE); // Menu function type + +#endif + + + diff --git a/src/sam7s256.c b/src/sam7s256.c new file mode 100644 index 0000000..b2657d5 --- /dev/null +++ b/src/sam7s256.c @@ -0,0 +1,34 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 10-12-07 14:29 $ +// +// Filename $Workfile:: sam7s256.c $ +// +// Version $Revision:: 3 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Sam7s256/Incl $ +// +// Platform C +// +#ifdef ARMDEBUG +#include "debug_stub.h" +#endif + +void main(void) +{ + while(TRUE) + { + HARDWAREInit; + mSchedInit(); +#ifdef ARMDEBUG + dbg__bkpt_init(); +#endif + while(TRUE == mSchedCtrl()) + { + OSWatchdogWrite; + } + mSchedExit(); + HARDWAREExit; + } +} diff --git a/src/sam7s256.h b/src/sam7s256.h new file mode 100644 index 0000000..0118c40 --- /dev/null +++ b/src/sam7s256.h @@ -0,0 +1,64 @@ +// +// Date init 14.12.2004 +// +// Revision date $Date:: 24-04-08 14:33 $ +// +// Filename $Workfile:: sam7s256.h $ +// +// Version $Revision:: 5 $ +// +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Sam7s256/Incl $ +// +// Platform C +// + +#ifndef SAM7S256_H +#define SAM7S256_H + +#ifdef __IAR_SYSTEMS_ICC__ +#include "ioat91sam7s256.h" +#else +#include "AT91SAM7S256.h" +#endif + +#define SAM7S256 + +#define HARDWAREInit {\ + ULONG TmpReset;\ + *AT91C_RSTC_RMR = 0xA5000401;\ + *AT91C_AIC_DCR = 1;\ + *AT91C_PITC_PIMR = (0x000FFFFF | 0x01000000);\ + TmpReset = *AT91C_PITC_PIVR;\ + TmpReset = TmpReset;/* Suppress warning*/\ + *AT91C_PMC_PCER = (1L< .data" +.section .vectmapped, "ax" +.else +.print "Vectors in section .vectorg -> .text" +.section .vectorg, "ax" +.endif + + LDR PC,Reset_Addr /* 0x00 Reset handler */ + LDR PC,Undef_Addr /* 0x04 Undefined Instruction */ + LDR PC,SWI_Addr /* 0x08 Software Interrupt */ + LDR PC,PAbt_Addr /* 0x0C Prefetch Abort */ + LDR PC,DAbt_Addr /* 0x10 Data Abort */ + NOP /* 0x14 reserved */ + LDR PC,IRQ_Addr /* 0x18 IRQ */ +fiqvec: /* 0x1c FIQ */ +/*------------------------------------------------------------------------------ +//*- Function : FIQ_Handler_Entry +//*- Treatments : FIQ Controller Interrupt Handler. +//*- Called Functions : AIC_FVR[interrupt] +//*------------------------------------------------------------------------------*/ + +FIQ_Handler_Entry: + +/*- Switch in SVC/User Mode to allow User Stack access for C code */ +/* because the FIQ is not yet acknowledged*/ + +/*- Save and r0 in FIQ_Register */ + mov r9,r0 + ldr r0 , [r8, #AIC_FVR] + msr CPSR_c,#I_BIT | F_BIT | ARM_MODE_SVC + +/*- Save scratch/used registers and LR in User Stack */ + stmfd sp!, { r1-r3, r12, lr} + +/*- Branch to the routine pointed by the AIC_FVR */ + mov r14, pc + bx r0 + +/*- Restore scratch/used registers and LR from User Stack */ + ldmia sp!, { r1-r3, r12, lr} + +/*- Leave Interrupts disabled and switch back in FIQ mode */ + msr CPSR_c, #I_BIT | F_BIT | ARM_MODE_FIQ + +/*- Restore the R0 ARM_MODE_SVC register */ + mov r0,r9 + +/*- Restore the Program Counter using the LR_fiq directly in the PC */ + subs pc,lr,#4 + +/* end of fiqhandler */ + +Reset_Addr: .word InitReset +#ifdef ARMDEBUG +Undef_Addr: .word undef_handler /* BKPT instruction trap */ +#else +Undef_Addr: .word Undef_Handler +#endif +SWI_Addr: .word SWI_Handler +/*SWI_Addr: .word SoftwareInterruptASM*/ /*in swi_handler.S */ +#ifdef ARMDEBUG +PAbt_Addr: .word prefetch_abort_handler +DAbt_Addr: .word data_abort_handler +#else +PAbt_Addr: .word PAbt_Handler +DAbt_Addr: .word DAbt_Handler +#endif +IRQ_Addr: .word IRQ_Handler_Entry + + .global default_undef_handler +default_undef_handler: +Undef_Handler: B Undef_Handler +SWI_Handler: B SWI_Handler + .global default_prefetch_abort_handler +default_prefetch_abort_handler: +PAbt_Handler: B PAbt_Handler + .global default_data_abort_handler +default_data_abort_handler: +DAbt_Handler: B DAbt_Handler + + + .arm + .section .init, "ax" + .global _startup + .func _startup +_startup: +reset: + +.if (VECTREMAPPED) +/* mthomas: Dummy used during startup */ + LDR PC, Reset_Addr_F + NOP + NOP + NOP + NOP + NOP /*.word 0xdeadbeef*/ /* Reserved Address */ + NOP + NOP +Reset_Addr_F: .word InitReset +.endif + +.RAM_TOP: + .word __TOP_STACK + +InitReset: + +/*------------------------------------------------------------------------------ +/*- Remapping +/*------------------------------------------------------------------------------*/ +.if (VECTREMAPPED) + .print "RCR setting for remapping enabled" + .equ MC_BASE,0xFFFFFF00 /* MC Base Address */ + .equ MC_RCR, 0x00 /* MC_RCR Offset */ + + +.if (VECTREMAPPED_AUTODETECT) + /* store first word in RAM into r4 */ + ldr r0,=__FIRST_IN_RAM + ldr r4,[r0] + /* load value at address 0 into R2 */ + ldr r1,=0x00000000 + ldr r2,[r1] + /* xor value from address 0 (flip all bits), store in R3 */ + ldr r3,=0xffffffff + eor r3, r2, r3 + /* write xored value to first word in RAM + if already remapped this will also change + the value at 0 */ + str r3,[r0] + /* load from address 0 again into R3 */ + ldr r3,[r1] + /* restore first value in RAM */ + str r4,[r0] + + /* compare */ + cmp r3, r2 + bne already_remapped +.endif + + /* if both values have been equal the change of the + RAM-value had no effect on the value at 0x00000000 + so we are not remapping yet -> remap now: */ + LDR R0, =MC_BASE + MOV R1, #1 + STR R1, [R0, #MC_RCR] + +already_remapped: +.endif + + +/*------------------------------------------------------------------------------ +/*- Low level Init (PMC, AIC, ? ....) by C function AT91F_LowLevelInit +/*------------------------------------------------------------------------------*/ + .extern AT91F_LowLevelInit +/*- minumum C initialization */ +/*- call AT91F_LowLevelInit( void) */ + + ldr sp, .RAM_TOP /* temporary stack in internal RAM (**) */ +/*--Call Low level init function in ABSOLUTE through the Interworking */ + ldr r0,=AT91F_LowLevelInit + mov lr, pc + bx r0 +/*------------------------------------------------------------------------------ +//*- Stack Sizes Definition +//*------------------------ +//*- Interrupt Stack requires 2 words x 8 priority level x 4 bytes when using +//*- the vectoring. This assume that the IRQ management. +//*- The Interrupt Stack must be adjusted depending on the interrupt handlers. +//*- Fast Interrupt not requires stack If in your application it required you must +//*- be definehere. +//*- The System stack size is not defined and is limited by the free internal +//*- SRAM. +//*------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------------ +//*- Top of Stack Definition +//*------------------------- +//*- Interrupt and Supervisor Stack are located at the top of internal memory in +//*- order to speed the exception handling context saving and restoring. +//*- ARM_MODE_SVC (Application, C) Stack is located at the top of the external memory. +//*------------------------------------------------------------------------------*/ + + .EQU IRQ_STACK_SIZE, (3*8*4) + .EQU FIQ_STACK_SIZE, (3*8*4) + .EQU ARM_MODE_FIQ, 0x11 + .EQU ARM_MODE_IRQ, 0x12 + .EQU ARM_MODE_SVC, 0x13 + .EQU ARM_MODE_ABT, 0x17 + + .EQU I_BIT, 0x80 + .EQU F_BIT, 0x40 + +/*------------------------------------------------------------------------------ +//*- Setup the stack for each mode +//*-------------------------------*/ + mov r0, sp /* see (**) */ + +#ifdef ARMDEBUG +/*- Set up Abort Mode Stack for Debugger*/ + msr CPSR_c, #ARM_MODE_ABT | I_BIT | F_BIT + ldr sp, =__abort_stack_top__ +#endif + +/*- Set up Fast Interrupt Mode and set FIQ Mode Stack*/ + msr CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT + mov sp, r0 + sub r0, r0, #FIQ_STACK_SIZE +/*- Init the FIQ register*/ + ldr r8, =AT91C_BASE_AIC + +/*- Set up Interrupt Mode and set IRQ Mode Stack*/ + msr CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT + mov sp, r0 /* Init stack IRQ */ + sub r0, r0, #IRQ_STACK_SIZE + +/*- Set up Supervisor Mode and set Supervisor Mode Stack*/ +// /* start with INT and FIQ enabled */ + msr CPSR_c, #ARM_MODE_SVC + + /* start with INT and FIQ disabled */ +// msr CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT + + mov sp, r0 /* Init stack Sup */ + + +/*- Enable interrupt & Set up Supervisor Mode and set Supervisor Mode Stack*/ + +/* Relocate .data section (Copy from ROM to RAM) + This will also copy the .vectmapped and .fastrun */ + LDR R1, =_etext + LDR R2, =_data + LDR R3, =_edata +LoopRel: CMP R2, R3 + LDRLO R0, [R1], #4 + STRLO R0, [R2], #4 + BLO LoopRel + +/* Clear .bss section (Zero init) */ + MOV R0, #0 + LDR R1, =__bss_start__ + LDR R2, =__bss_end__ +LoopZI: CMP R1, R2 + STRLO R0, [R1], #4 + BLO LoopZI + + +.if (CPP_CONSTRUCTORS) +/* call C++ constructors of global objects */ + LDR r0, =__ctors_start__ + LDR r1, =__ctors_end__ +ctor_loop: + CMP r0, r1 + BEQ ctor_end + LDR r2, [r0], #4 + STMFD sp!, {r0-r1} + MOV lr, pc +/* MOV pc, r2 */ + BX r2 /* mthomas 8/2006 */ + LDMFD sp!, {r0-r1} + B ctor_loop +ctor_end: +.endif + + +/* call main() */ + ldr lr,=exit + ldr r0,=main + bx r0 + + .size _startup, . - _startup + .endfunc + +/* "exit" dummy added by mthomas to avoid sbrk write read etc. needed + by the newlib default "exit" */ + .global exit + .func exit +exit: + b . + .size exit, . - exit + .endfunc + + + + +/*------------------------------------------------------------------------------ +//*- Manage exception +//*--------------- +//*- This module The exception must be ensure in ARM mode +//*------------------------------------------------------------------------------ +//*------------------------------------------------------------------------------ +//*- Function : IRQ_Handler_Entry +//*- Treatments : IRQ Controller Interrupt Handler. +//*- Called Functions : AIC_IVR[interrupt] +//*------------------------------------------------------------------------------*/ + +.if (VECTREMAPPED) +.print "IRQ_Handler_Entry in section .fastrun -> .data" +.section .fastrun, "ax" +.else +.print "IRQ_Handler_Entry in section .init -> .text" +.section .init, "ax" +.endif + + .global IRQ_Handler_Entry + .func IRQ_Handler_Entry +IRQ_Handler_Entry: +/*---- Adjust and save return address on the stack */ + sub lr, lr, #4 + stmfd sp!, {lr} + +/*---- Save r0 and SPSR on the stack */ + mrs r14, SPSR + stmfd sp!, {r0, r14} + +/*---- Write in the IVR to support Protect mode */ +/*---- No effect in Normal Mode */ +/*---- De-assert NIRQ and clear the source in Protect mode */ + ldr r14, =AT91C_BASE_AIC + ldr r0, [r14, #AIC_IVR] + str r14, [r14, #AIC_IVR] + +/*---- Enable nested interrupts and switch to Supervisor mode */ + msr CPSR_c, #ARM_MODE_SVC + +/*---- Save scratch/used registers and LR on the stack */ + stmfd sp!, {r1-r3, r12, r14} + +/*---- Branch to the routine pointed by AIC_IVR */ + mov r14, pc + bx r0 + +/*---- Restore scratch/used registers and LR from the stack */ + ldmia sp!, {r1-r3, r12, r14} + +/*---- Disable nested interrupts and switch back to IRQ mode */ + msr CPSR_c, #I_BIT | ARM_MODE_IRQ + +/*---- Acknowledge interrupt by writing AIC_EOICR */ + ldr r14, =AT91C_BASE_AIC + str r14, [r14, #AIC_EOICR] + +/*---- Restore SPSR and r0 from the stack */ + ldmia sp!, {r0, r14} + msr SPSR_cxsf, r14 + +/*---- Return from interrupt handler */ + ldmia sp!, {pc}^ + + .size IRQ_Handler_Entry, . - IRQ_Handler_Entry + .endfunc + + +/*--------------------------------------------------------------- +//* ?EXEPTION_VECTOR +//* This module is only linked if needed for closing files. +//*---------------------------------------------------------------*/ + .global AT91F_Default_FIQ_handler + .func AT91F_Default_FIQ_handler +AT91F_Default_FIQ_handler: + b AT91F_Default_FIQ_handler + .size AT91F_Default_FIQ_handler, . - AT91F_Default_FIQ_handler + .endfunc + + .global AT91F_Default_IRQ_handler + .func AT91F_Default_IRQ_handler +AT91F_Default_IRQ_handler: + b AT91F_Default_IRQ_handler + .size AT91F_Default_IRQ_handler, . - AT91F_Default_IRQ_handler + .endfunc + + .global AT91F_Spurious_handler + .func AT91F_Spurious_handler +AT91F_Spurious_handler: + b AT91F_Spurious_handler + .size AT91F_Spurious_handler, . - AT91F_Spurious_handler + .endfunc + +/*------------------------------------------------------------------------------ +//*- Various debugger stacks. +//*-------------------------------*/ + +#ifdef ARMDEBUG +.section .stack.abort, "aw", %nobits + .space 0x80; /* 128 byte abort mode stack. */ +.section .stack.debugger, "aw", %nobits + .space 0x48; /* 16 user mode registers + SPSR + UNDEF Next Instruction Address */ +.section .breakpoints, "aw", %nobits + .space 0x40; /* Single Stepping Breakpoint + 7 Breakpoints */ +#endif + + .end + diff --git a/startup/Cstartup_SAM7.c b/startup/Cstartup_SAM7.c new file mode 100644 index 0000000..c0a7da4 --- /dev/null +++ b/startup/Cstartup_SAM7.c @@ -0,0 +1,93 @@ +//*---------------------------------------------------------------------------- +//* ATMEL Microcontroller Software Support - ROUSSET - +//*---------------------------------------------------------------------------- +//* The software is delivered "AS IS" without warranty or condition of any +//* kind, either express, implied or statutory. This includes without +//* limitation any warranty or condition with respect to merchantability or +//* fitness for any particular purpose, or against the infringements of +//* intellectual property rights of others. +//*---------------------------------------------------------------------------- +//* File Name : Cstartup_SAM7.c +//* Object : Low level initializations written in C for IAR Tools +//* Creation : 12/Jun/04 +//* 1.2 28/Feb/05 JPP : LIB change AT91C_WDTC_WDDIS & PLL +//* 1.3 21/Mar/05 JPP : Change PLL Wait time +//*---------------------------------------------------------------------------- + +// Include the board file description +#include "AT91SAM7S256.h" + +// The following functions must be write in ARM mode this function called directly +// by exception vector +extern void AT91F_Spurious_handler(void); +extern void AT91F_Default_IRQ_handler(void); +extern void AT91F_Default_FIQ_handler(void); + +#ifdef __IAR_SYSTEMS_ICC__ +# define SECTION_ICODE @ "ICODE" +#else +# define SECTION_ICODE +#endif +//*---------------------------------------------------------------------------- +//* \fn AT91F_LowLevelInit +//* \brief This function performs very low level HW initialization +//* this function can be use a Stack, depending the compilation +//* optimization mode +//*---------------------------------------------------------------------------- +void AT91F_LowLevelInit( void) SECTION_ICODE +{ + int i; + AT91PS_PMC pPMC = AT91C_BASE_PMC; + + //* Set Flash Waite sate + // Single Cycle Access at Up to 30 MHz, or 40 + // if MCK = 47923200 I have 72 Cycle for 1,5 usecond ( flied MC_FMR->FMCN + AT91C_BASE_MC->MC_FMR = ((AT91C_MC_FMCN)&(72 <<16)) | AT91C_MC_FWS_1FWS ; + + //* Watchdog Disable + AT91C_BASE_WDTC->WDTC_WDMR= AT91C_WDTC_WDDIS; + + //* Set MCK at 47 923 200 + // 1 Enabling the Main Oscillator: + // SCK = 1/32768 = 30.51 uSecond + // Start up time = 8 * 6 / SCK = 56 * 30.51 = 1,46484375 ms + pPMC->PMC_MOR = (( AT91C_CKGR_OSCOUNT & (0x06 <<8) | AT91C_CKGR_MOSCEN )); + + // Wait the startup time + while(!(pPMC->PMC_SR & AT91C_PMC_MOSCS)); + + // 2 Checking the Main Oscillator Frequency (Optional) + // 3 Setting PLL and divider: + // - div by 14 Fin = 1.3165 =(18,432 / 14) + // - Mul 72+1: Fout = 96.1097 =(3,6864 *73) + // for 96 MHz the erroe is 0.11% + // Field out NOT USED = 0 + // PLLCOUNT pll startup time estimate at : 0.844 ms + // PLLCOUNT 28 = 0.000844 /(1/32768) + pPMC->PMC_PLLR = ((AT91C_CKGR_DIV & 14) | + (AT91C_CKGR_PLLCOUNT & (28<<8)) | + (AT91C_CKGR_MUL & (72<<16))); + + // Wait the startup time + while(!(pPMC->PMC_SR & AT91C_PMC_LOCK)); + while(!(pPMC->PMC_SR & AT91C_PMC_MCKRDY)); + + // 4. Selection of Master Clock and Processor Clock + // select the PLL clock divided by 2 + pPMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2 ; + while(!(pPMC->PMC_SR & AT91C_PMC_MCKRDY)); + + pPMC->PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK ; + while(!(pPMC->PMC_SR & AT91C_PMC_MCKRDY)); + + // Set up the default interrupts handler vectors + AT91C_BASE_AIC->AIC_SVR[0] = (int) AT91F_Default_FIQ_handler ; + for (i=1;i < 31; i++) + { + AT91C_BASE_AIC->AIC_SVR[i] = (int) AT91F_Default_IRQ_handler ; + } + AT91C_BASE_AIC->AIC_SPU = (int) AT91F_Spurious_handler ; +} + + + -- cgit v1.2.3