From f508189682b6fba62e08feeb1596f682bad5fff9 Mon Sep 17 00:00:00 2001 From: tpearson Date: Wed, 24 Feb 2010 18:42:24 +0000 Subject: Added KDE3 version of PikLab git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/piklab@1095639 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- src/Makefile.am | 10 + src/coff/Makefile.am | 1 + src/coff/base/Makefile.am | 13 + src/coff/base/base.pro | 6 + src/coff/base/cdb_parser.cpp | 417 + src/coff/base/cdb_parser.h | 166 + src/coff/base/coff.cpp | 97 + src/coff/base/coff.h | 64 + src/coff/base/coff.xml | 342 + src/coff/base/coff_archive.cpp | 129 + src/coff/base/coff_archive.h | 53 + src/coff/base/coff_data.h | 22 + src/coff/base/coff_object.cpp | 658 + src/coff/base/coff_object.h | 322 + src/coff/base/disassembler.cpp | 289 + src/coff/base/disassembler.h | 80 + src/coff/base/gpdis.cpp | 349 + src/coff/base/gpopcode.cpp | 348 + src/coff/base/gpopcode.h | 107 + src/coff/base/text_coff.cpp | 262 + src/coff/base/text_coff.h | 45 + src/coff/coff.pro | 2 + src/coff/xml/Makefile.am | 14 + src/coff/xml/gpprocessor.cpp | 340 + src/coff/xml/gpprocessor.h | 371 + src/coff/xml/xml.pro | 17 + src/coff/xml/xml_coff_parser.cpp | 116 + src/common/Makefile.am | 4 + src/common/cli/Makefile.am | 7 + src/common/cli/cli.pro | 6 + src/common/cli/cli_global.cpp | 37 + src/common/cli/cli_global.h | 33 + src/common/cli/cli_log.cpp | 74 + src/common/cli/cli_log.h | 33 + src/common/cli/cli_main.cpp | 208 + src/common/cli/cli_main.h | 82 + src/common/cli/cli_pfile.cpp | 47 + src/common/cli/cli_purl.cpp | 9 + src/common/common.pro | 2 + src/common/common/Makefile.am | 9 + src/common/common/bitvalue.cpp | 30 + src/common/common/bitvalue.h | 129 + src/common/common/common.pro | 6 + src/common/common/group.cpp | 71 + src/common/common/group.h | 82 + src/common/common/key_enum.h | 107 + src/common/common/lister.h | 71 + src/common/common/misc.cpp | 72 + src/common/common/misc.h | 39 + src/common/common/number.cpp | 201 + src/common/common/number.h | 92 + src/common/common/purl_base.cpp | 133 + src/common/common/purl_base.h | 79 + src/common/common/qflags.h | 81 + src/common/common/range.h | 61 + src/common/common/storage.cpp | 42 + src/common/common/storage.h | 85 + src/common/common/streamer.h | 59 + src/common/common/synchronous.cpp | 58 + src/common/common/synchronous.h | 32 + src/common/common/version_data.cpp | 55 + src/common/common/version_data.h | 47 + src/common/global/Makefile.am | 8 + src/common/global/about.cpp | 94 + src/common/global/about.h | 43 + src/common/global/generic_config.cpp | 241 + src/common/global/generic_config.h | 84 + src/common/global/global.h | 61 + src/common/global/global.pro | 8 + src/common/global/log.cpp | 154 + src/common/global/log.h | 134 + src/common/global/pfile.cpp | 89 + src/common/global/pfile.h | 66 + src/common/global/process.cpp | 193 + src/common/global/process.h | 138 + src/common/global/progress_monitor.cpp | 84 + src/common/global/progress_monitor.h | 46 + src/common/global/purl.cpp | 428 + src/common/global/purl.h | 136 + src/common/global/svn_revision/Makefile.am | 5 + src/common/global/svn_revision/svn_revision.sh | 20 + src/common/global/xml_data_file.cpp | 160 + src/common/global/xml_data_file.h | 45 + src/common/gui/Makefile.am | 7 + src/common/gui/config_widget.h | 107 + src/common/gui/container.cpp | 80 + src/common/gui/container.h | 58 + src/common/gui/dialog.cpp | 199 + src/common/gui/dialog.h | 77 + src/common/gui/editlistbox.cpp | 340 + src/common/gui/editlistbox.h | 95 + src/common/gui/hexword_gui.cpp | 136 + src/common/gui/hexword_gui.h | 88 + src/common/gui/key_gui.h | 125 + src/common/gui/list_container.cpp | 95 + src/common/gui/list_container.h | 55 + src/common/gui/list_view.cpp | 221 + src/common/gui/list_view.h | 93 + src/common/gui/misc_gui.cpp | 234 + src/common/gui/misc_gui.h | 164 + src/common/gui/number_gui.cpp | 72 + src/common/gui/number_gui.h | 40 + src/common/gui/pfile_ext.cpp | 114 + src/common/gui/pfile_ext.h | 29 + src/common/gui/purl_ext.cpp | 111 + src/common/gui/purl_gui.cpp | 151 + src/common/gui/purl_gui.h | 120 + src/common/nokde/nokde.pro | 8 + src/common/nokde/nokde_kaboutdata.cpp | 469 + src/common/nokde/nokde_kaboutdata.h | 571 + src/common/nokde/nokde_kcmdlineargs.cpp | 1329 + src/common/nokde/nokde_kcmdlineargs.h | 701 + src/common/nokde/nokde_klocale.cpp | 4 + src/common/nokde/nokde_klocale.h | 17 + src/common/nokde/nokde_kprocess.cpp | 100 + src/common/nokde/nokde_kprocess.h | 51 + src/common/nokde/nokde_kurl.h | 32 + src/common/nokde/win32_utils.c | 81 + src/common/nokde/win32_utils.h | 97 + src/common/port/Makefile.am | 7 + src/common/port/parallel.cpp | 247 + src/common/port/parallel.h | 70 + src/common/port/port.cpp | 98 + src/common/port/port.h | 56 + src/common/port/port.pro | 10 + src/common/port/port_base.cpp | 127 + src/common/port/port_base.h | 59 + src/common/port/serial.cpp | 523 + src/common/port/serial.h | 113 + src/common/port/usb_port.cpp | 411 + src/common/port/usb_port.h | 70 + src/data/Makefile.am | 17 + src/data/app_data/Makefile.am | 9 + src/data/app_data/hexeditorpartui.rc | 21 + src/data/app_data/hi16-app-piklab.png | Bin 0 -> 220 bytes src/data/app_data/hi32-app-piklab.png | Bin 0 -> 861 bytes src/data/app_data/hi32-mime-piklab_project.png | Bin 0 -> 861 bytes src/data/app_data/hi64-app-piklab.png | Bin 0 -> 9976 bytes src/data/app_data/piklab.desktop | 13 + src/data/app_data/piklabui.rc | 203 + src/data/app_data/x-piklab.desktop | 8 + src/data/coff-c-pic.xml | 127 + src/data/hi16-action-piklab_addcurrentfile.png | Bin 0 -> 748 bytes src/data/hi16-action-piklab_addfile.png | Bin 0 -> 657 bytes src/data/hi16-action-piklab_blankcheck.png | Bin 0 -> 499 bytes src/data/hi16-action-piklab_burnchip.png | Bin 0 -> 844 bytes src/data/hi16-action-piklab_chip.png | Bin 0 -> 796 bytes src/data/hi16-action-piklab_closeproject.png | Bin 0 -> 715 bytes src/data/hi16-action-piklab_compile.png | Bin 0 -> 832 bytes src/data/hi16-action-piklab_createproject.png | Bin 0 -> 722 bytes src/data/hi16-action-piklab_decompile.png | Bin 0 -> 854 bytes src/data/hi16-action-piklab_editproject.png | Bin 0 -> 515 bytes src/data/hi16-action-piklab_erasechip.png | Bin 0 -> 808 bytes src/data/hi16-action-piklab_find_next.png | Bin 0 -> 254 bytes src/data/hi16-action-piklab_find_previous.png | Bin 0 -> 286 bytes src/data/hi16-action-piklab_openproject.png | Bin 0 -> 554 bytes src/data/hi16-action-piklab_readchip.png | Bin 0 -> 884 bytes src/data/hi16-action-piklab_verifychip.png | Bin 0 -> 821 bytes src/data/hi22-action-piklab_addcurrentfile.png | Bin 0 -> 753 bytes src/data/hi22-action-piklab_addfile.png | Bin 0 -> 613 bytes src/data/hi22-action-piklab_blankcheck.png | Bin 0 -> 621 bytes src/data/hi22-action-piklab_breakpoint_active.png | Bin 0 -> 1329 bytes .../hi22-action-piklab_breakpoint_disabled.png | Bin 0 -> 1117 bytes src/data/hi22-action-piklab_breakpoint_invalid.png | Bin 0 -> 1003 bytes src/data/hi22-action-piklab_breakpoint_reached.png | Bin 0 -> 1190 bytes src/data/hi22-action-piklab_burnchip.png | Bin 0 -> 1047 bytes src/data/hi22-action-piklab_chip.png | Bin 0 -> 1058 bytes src/data/hi22-action-piklab_closeproject.png | Bin 0 -> 1049 bytes src/data/hi22-action-piklab_compile.png | Bin 0 -> 871 bytes src/data/hi22-action-piklab_createproject.png | Bin 0 -> 689 bytes src/data/hi22-action-piklab_debug_step.png | Bin 0 -> 236 bytes src/data/hi22-action-piklab_debug_stepin.png | Bin 0 -> 181 bytes src/data/hi22-action-piklab_debug_stepout.png | Bin 0 -> 203 bytes src/data/hi22-action-piklab_debug_stepover.png | Bin 0 -> 186 bytes src/data/hi22-action-piklab_debughalt.png | Bin 0 -> 1190 bytes src/data/hi22-action-piklab_decompile.png | Bin 0 -> 884 bytes src/data/hi22-action-piklab_editproject.png | Bin 0 -> 446 bytes src/data/hi22-action-piklab_erasechip.png | Bin 0 -> 1060 bytes src/data/hi22-action-piklab_find_next.png | Bin 0 -> 402 bytes src/data/hi22-action-piklab_find_previous.png | Bin 0 -> 416 bytes src/data/hi22-action-piklab_openproject.png | Bin 0 -> 728 bytes src/data/hi22-action-piklab_power.png | Bin 0 -> 1315 bytes src/data/hi22-action-piklab_program_counter.png | Bin 0 -> 1278 bytes ...hi22-action-piklab_program_counter_disabled.png | Bin 0 -> 733 bytes src/data/hi22-action-piklab_readchip.png | Bin 0 -> 1063 bytes src/data/hi22-action-piklab_restart.png | Bin 0 -> 1419 bytes src/data/hi22-action-piklab_run.png | Bin 0 -> 1262 bytes src/data/hi22-action-piklab_stop.png | Bin 0 -> 1121 bytes src/data/hi22-action-piklab_verifychip.png | Bin 0 -> 1055 bytes src/data/hi32-action-piklab_config_assembler.png | Bin 0 -> 2258 bytes .../hi32-action-piklab_config_disassembler.png | Bin 0 -> 2346 bytes src/data/hi32-action-piklab_config_programmer.png | Bin 0 -> 861 bytes src/data/jal-pic.xml | 104 + src/data/likeback/Makefile.am | 2 + src/data/likeback/cr16-action-likeback_dislike.png | Bin 0 -> 824 bytes src/data/likeback/cr16-action-likeback_like.png | Bin 0 -> 846 bytes src/data/likeback/hi16-action-likeback_bug.png | Bin 0 -> 1106 bytes src/data/syntax_xml_generator.cpp | 231 + src/data/xpms/csourcefile.xpm | 24 + src/data/xpms/includefile.xpm | 25 + src/data/xpms/objectfile.xpm | 24 + src/data/xpms/project.xpm | 29 + src/data/xpms/sourcefile.xpm | 24 + src/devices/Makefile.am | 1 + src/devices/base/Makefile.am | 9 + src/devices/base/base.pro | 6 + src/devices/base/device_group.cpp | 362 + src/devices/base/device_group.h | 87 + src/devices/base/generic_device.cpp | 216 + src/devices/base/generic_device.h | 171 + src/devices/base/generic_memory.cpp | 48 + src/devices/base/generic_memory.h | 47 + src/devices/base/hex_buffer.cpp | 290 + src/devices/base/hex_buffer.h | 51 + src/devices/base/register.cpp | 156 + src/devices/base/register.h | 130 + src/devices/devices.pro | 2 + src/devices/gui/Makefile.am | 7 + src/devices/gui/device_group_ui.cpp | 9 + src/devices/gui/device_group_ui.h | 45 + src/devices/gui/hex_view.cpp | 23 + src/devices/gui/hex_view.h | 39 + src/devices/gui/hex_word_editor.cpp | 42 + src/devices/gui/hex_word_editor.h | 64 + src/devices/gui/memory_editor.cpp | 369 + src/devices/gui/memory_editor.h | 156 + src/devices/gui/register_view.cpp | 208 + src/devices/gui/register_view.h | 105 + src/devices/list/Makefile.am | 11 + src/devices/list/device_list.cpp | 40 + src/devices/list/device_list.h | 34 + src/devices/list/device_list_noui.cpp | 18 + src/devices/list/device_list_ui.cpp | 20 + src/devices/list/list.pro | 6 + src/devices/mem24/Makefile.am | 3 + src/devices/mem24/base/Makefile.am | 6 + src/devices/mem24/base/base.pro | 6 + src/devices/mem24/base/mem24.cpp | 22 + src/devices/mem24/base/mem24.h | 47 + src/devices/mem24/gui/Makefile.am | 7 + src/devices/mem24/gui/mem24_group_ui.cpp | 16 + src/devices/mem24/gui/mem24_group_ui.h | 28 + src/devices/mem24/gui/mem24_hex_view.cpp | 38 + src/devices/mem24/gui/mem24_hex_view.h | 33 + src/devices/mem24/gui/mem24_memory_editor.cpp | 80 + src/devices/mem24/gui/mem24_memory_editor.h | 77 + src/devices/mem24/mem24.pro | 2 + src/devices/mem24/mem24/Makefile.am | 6 + src/devices/mem24/mem24/mem24.pro | 6 + src/devices/mem24/mem24/mem24_group.cpp | 43 + src/devices/mem24/mem24/mem24_group.h | 39 + src/devices/mem24/mem24/mem24_memory.cpp | 92 + src/devices/mem24/mem24/mem24_memory.h | 45 + src/devices/mem24/prog/Makefile.am | 5 + src/devices/mem24/prog/mem24_prog.cpp | 88 + src/devices/mem24/prog/mem24_prog.h | 63 + src/devices/mem24/prog/prog.pro | 6 + src/devices/mem24/xml/Makefile.am | 12 + src/devices/mem24/xml/mem24_xml_to_data.cpp | 60 + src/devices/mem24/xml/xml.pro | 13 + src/devices/mem24/xml_data/24AA00.xml | 41 + src/devices/mem24/xml_data/24AA01.xml | 41 + src/devices/mem24/xml_data/24AA014.xml | 33 + src/devices/mem24/xml_data/24AA02.xml | 41 + src/devices/mem24/xml_data/24AA024.xml | 33 + src/devices/mem24/xml_data/24AA025.xml | 33 + src/devices/mem24/xml_data/24AA04.xml | 41 + src/devices/mem24/xml_data/24AA08.xml | 41 + src/devices/mem24/xml_data/24AA1025.xml | 33 + src/devices/mem24/xml_data/24AA128.xml | 44 + src/devices/mem24/xml_data/24AA16.xml | 41 + src/devices/mem24/xml_data/24AA164.xml | 33 + src/devices/mem24/xml_data/24AA256.xml | 44 + src/devices/mem24/xml_data/24AA32A.xml | 33 + src/devices/mem24/xml_data/24AA512.xml | 50 + src/devices/mem24/xml_data/24AA515.xml | 33 + src/devices/mem24/xml_data/24AA64.xml | 33 + src/devices/mem24/xml_data/24AA65.xml | 33 + src/devices/mem24/xml_data/24C00.xml | 43 + src/devices/mem24/xml_data/24C01C.xml | 35 + src/devices/mem24/xml_data/24C02C.xml | 35 + src/devices/mem24/xml_data/24C65.xml | 32 + src/devices/mem24/xml_data/24FC1025.xml | 32 + src/devices/mem24/xml_data/24FC128.xml | 44 + src/devices/mem24/xml_data/24FC256.xml | 44 + src/devices/mem24/xml_data/24FC512.xml | 49 + src/devices/mem24/xml_data/24FC515.xml | 32 + src/devices/mem24/xml_data/24LC00.xml | 41 + src/devices/mem24/xml_data/24LC014.xml | 32 + src/devices/mem24/xml_data/24LC01B.xml | 40 + src/devices/mem24/xml_data/24LC024.xml | 32 + src/devices/mem24/xml_data/24LC025.xml | 32 + src/devices/mem24/xml_data/24LC02B.xml | 40 + src/devices/mem24/xml_data/24LC04B.xml | 40 + src/devices/mem24/xml_data/24LC08B.xml | 40 + src/devices/mem24/xml_data/24LC1025.xml | 32 + src/devices/mem24/xml_data/24LC128.xml | 43 + src/devices/mem24/xml_data/24LC16B.xml | 40 + src/devices/mem24/xml_data/24LC21A.xml | 33 + src/devices/mem24/xml_data/24LC22A.xml | 33 + src/devices/mem24/xml_data/24LC256.xml | 43 + src/devices/mem24/xml_data/24LC32A.xml | 32 + src/devices/mem24/xml_data/24LC512.xml | 49 + src/devices/mem24/xml_data/24LC515.xml | 32 + src/devices/mem24/xml_data/24LC64.xml | 32 + src/devices/mem24/xml_data/24LC65.xml | 33 + src/devices/mem24/xml_data/24LCS21A.xml | 33 + src/devices/mem24/xml_data/Makefile.am | 12 + src/devices/mem24/xml_data/deps.mak | 6 + src/devices/mem24/xml_data/xml_data.pro | 5 + src/devices/pic/Makefile.am | 3 + src/devices/pic/base/Makefile.am | 6 + src/devices/pic/base/base.pro | 6 + src/devices/pic/base/pic.cpp | 426 + src/devices/pic/base/pic.h | 179 + src/devices/pic/base/pic_config.cpp | 456 + src/devices/pic/base/pic_config.h | 107 + src/devices/pic/base/pic_protection.cpp | 361 + src/devices/pic/base/pic_protection.h | 60 + src/devices/pic/base/pic_register.cpp | 287 + src/devices/pic/base/pic_register.h | 115 + src/devices/pic/gui/Makefile.am | 9 + src/devices/pic/gui/pic_config_editor.cpp | 68 + src/devices/pic/gui/pic_config_editor.h | 37 + src/devices/pic/gui/pic_config_word_editor.cpp | 196 + src/devices/pic/gui/pic_config_word_editor.h | 70 + src/devices/pic/gui/pic_group_ui.cpp | 87 + src/devices/pic/gui/pic_group_ui.h | 29 + src/devices/pic/gui/pic_hex_view.cpp | 60 + src/devices/pic/gui/pic_hex_view.h | 39 + src/devices/pic/gui/pic_memory_editor.cpp | 404 + src/devices/pic/gui/pic_memory_editor.h | 189 + src/devices/pic/gui/pic_prog_group_ui.cpp | 41 + src/devices/pic/gui/pic_prog_group_ui.h | 31 + src/devices/pic/gui/pic_register_view.cpp | 329 + src/devices/pic/gui/pic_register_view.h | 88 + src/devices/pic/pic.pro | 2 + src/devices/pic/pic/Makefile.am | 5 + src/devices/pic/pic/pic.pro | 6 + src/devices/pic/pic/pic_group.cpp | 87 + src/devices/pic/pic/pic_group.h | 39 + src/devices/pic/pic/pic_memory.cpp | 560 + src/devices/pic/pic/pic_memory.h | 80 + src/devices/pic/prog/Makefile.am | 5 + src/devices/pic/prog/pic_debug.cpp | 118 + src/devices/pic/prog/pic_debug.h | 65 + src/devices/pic/prog/pic_prog.cpp | 751 + src/devices/pic/prog/pic_prog.h | 110 + src/devices/pic/prog/pic_prog_specific.cpp | 121 + src/devices/pic/prog/pic_prog_specific.h | 86 + src/devices/pic/prog/prog.pro | 6 + src/devices/pic/xml/Makefile.am | 12 + src/devices/pic/xml/pic_xml_to_data.cpp | 718 + src/devices/pic/xml/xml.pro | 13 + src/devices/pic/xml_data/10F200.xml | 76 + src/devices/pic/xml_data/10F202.xml | 76 + src/devices/pic/xml_data/10F204.xml | 76 + src/devices/pic/xml_data/10F206.xml | 76 + src/devices/pic/xml_data/10F220.xml | 81 + src/devices/pic/xml_data/10F222.xml | 81 + src/devices/pic/xml_data/12C508.xml | 71 + src/devices/pic/xml_data/12C508A.xml | 68 + src/devices/pic/xml_data/12C509.xml | 71 + src/devices/pic/xml_data/12C509A.xml | 68 + src/devices/pic/xml_data/12C671.xml | 85 + src/devices/pic/xml_data/12C672.xml | 87 + src/devices/pic/xml_data/12CE518.xml | 69 + src/devices/pic/xml_data/12CE519.xml | 69 + src/devices/pic/xml_data/12CE673.xml | 86 + src/devices/pic/xml_data/12CE674.xml | 88 + src/devices/pic/xml_data/12CR509A.xml | 68 + src/devices/pic/xml_data/12F508.xml | 71 + src/devices/pic/xml_data/12F509.xml | 71 + src/devices/pic/xml_data/12F510.xml | 74 + src/devices/pic/xml_data/12F519.xml | 82 + src/devices/pic/xml_data/12F609.xml | 99 + src/devices/pic/xml_data/12F615.xml | 99 + src/devices/pic/xml_data/12F629.xml | 102 + src/devices/pic/xml_data/12F635.xml | 104 + src/devices/pic/xml_data/12F675.xml | 102 + src/devices/pic/xml_data/12F683.xml | 100 + src/devices/pic/xml_data/14000.xml | 99 + src/devices/pic/xml_data/16C432.xml | 88 + src/devices/pic/xml_data/16C433.xml | 91 + src/devices/pic/xml_data/16C505.xml | 87 + src/devices/pic/xml_data/16C52.xml | 90 + src/devices/pic/xml_data/16C54.xml | 105 + src/devices/pic/xml_data/16C54A.xml | 115 + src/devices/pic/xml_data/16C54B.xml | 110 + src/devices/pic/xml_data/16C54C.xml | 110 + src/devices/pic/xml_data/16C55.xml | 123 + src/devices/pic/xml_data/16C554.xml | 112 + src/devices/pic/xml_data/16C557.xml | 137 + src/devices/pic/xml_data/16C558.xml | 116 + src/devices/pic/xml_data/16C55A.xml | 128 + src/devices/pic/xml_data/16C56.xml | 105 + src/devices/pic/xml_data/16C56A.xml | 110 + src/devices/pic/xml_data/16C57.xml | 123 + src/devices/pic/xml_data/16C57C.xml | 128 + src/devices/pic/xml_data/16C58A.xml | 114 + src/devices/pic/xml_data/16C58B.xml | 110 + src/devices/pic/xml_data/16C61.xml | 84 + src/devices/pic/xml_data/16C62.xml | 95 + src/devices/pic/xml_data/16C620.xml | 113 + src/devices/pic/xml_data/16C620A.xml | 117 + src/devices/pic/xml_data/16C621.xml | 115 + src/devices/pic/xml_data/16C621A.xml | 119 + src/devices/pic/xml_data/16C622.xml | 117 + src/devices/pic/xml_data/16C622A.xml | 121 + src/devices/pic/xml_data/16C62A.xml | 100 + src/devices/pic/xml_data/16C62B.xml | 100 + src/devices/pic/xml_data/16C63.xml | 100 + src/devices/pic/xml_data/16C63A.xml | 101 + src/devices/pic/xml_data/16C64.xml | 201 + src/devices/pic/xml_data/16C641.xml | 99 + src/devices/pic/xml_data/16C642.xml | 104 + src/devices/pic/xml_data/16C64A.xml | 253 + src/devices/pic/xml_data/16C65.xml | 201 + src/devices/pic/xml_data/16C65A.xml | 253 + src/devices/pic/xml_data/16C65B.xml | 207 + src/devices/pic/xml_data/16C66.xml | 100 + src/devices/pic/xml_data/16C661.xml | 111 + src/devices/pic/xml_data/16C662.xml | 116 + src/devices/pic/xml_data/16C67.xml | 253 + src/devices/pic/xml_data/16C71.xml | 81 + src/devices/pic/xml_data/16C710.xml | 112 + src/devices/pic/xml_data/16C711.xml | 112 + src/devices/pic/xml_data/16C712.xml | 108 + src/devices/pic/xml_data/16C715.xml | 117 + src/devices/pic/xml_data/16C716.xml | 112 + src/devices/pic/xml_data/16C717.xml | 129 + src/devices/pic/xml_data/16C72.xml | 100 + src/devices/pic/xml_data/16C72A.xml | 100 + src/devices/pic/xml_data/16C73.xml | 95 + src/devices/pic/xml_data/16C73A.xml | 100 + src/devices/pic/xml_data/16C73B.xml | 101 + src/devices/pic/xml_data/16C74.xml | 201 + src/devices/pic/xml_data/16C745.xml | 92 + src/devices/pic/xml_data/16C74A.xml | 206 + src/devices/pic/xml_data/16C74B.xml | 207 + src/devices/pic/xml_data/16C76.xml | 100 + src/devices/pic/xml_data/16C765.xml | 198 + src/devices/pic/xml_data/16C77.xml | 206 + src/devices/pic/xml_data/16C770.xml | 108 + src/devices/pic/xml_data/16C771.xml | 108 + src/devices/pic/xml_data/16C773.xml | 106 + src/devices/pic/xml_data/16C774.xml | 259 + src/devices/pic/xml_data/16C781.xml | 104 + src/devices/pic/xml_data/16C782.xml | 104 + src/devices/pic/xml_data/16C84.xml | 99 + src/devices/pic/xml_data/16C923.xml | 270 + src/devices/pic/xml_data/16C924.xml | 270 + src/devices/pic/xml_data/16C925.xml | 199 + src/devices/pic/xml_data/16C926.xml | 199 + src/devices/pic/xml_data/16CE623.xml | 114 + src/devices/pic/xml_data/16CE624.xml | 116 + src/devices/pic/xml_data/16CE625.xml | 117 + src/devices/pic/xml_data/16CR54.xml_broken | 87 + src/devices/pic/xml_data/16CR54A.xml | 107 + src/devices/pic/xml_data/16CR54B.xml | 110 + src/devices/pic/xml_data/16CR54C.xml | 110 + src/devices/pic/xml_data/16CR56A.xml | 110 + src/devices/pic/xml_data/16CR57B.xml | 125 + src/devices/pic/xml_data/16CR57C.xml | 128 + src/devices/pic/xml_data/16CR58A.xml | 107 + src/devices/pic/xml_data/16CR58B.xml | 110 + src/devices/pic/xml_data/16CR62.xml | 100 + src/devices/pic/xml_data/16CR620A.xml | 113 + src/devices/pic/xml_data/16CR63.xml | 100 + src/devices/pic/xml_data/16CR64.xml | 206 + src/devices/pic/xml_data/16CR65.xml | 253 + src/devices/pic/xml_data/16CR72.xml | 100 + src/devices/pic/xml_data/16CR73.xml | 127 + src/devices/pic/xml_data/16CR74.xml | 202 + src/devices/pic/xml_data/16CR76.xml | 127 + src/devices/pic/xml_data/16CR77.xml | 202 + src/devices/pic/xml_data/16CR83.xml | 110 + src/devices/pic/xml_data/16CR84.xml | 110 + src/devices/pic/xml_data/16F505.xml | 81 + src/devices/pic/xml_data/16F506.xml | 86 + src/devices/pic/xml_data/16F54.xml | 98 + src/devices/pic/xml_data/16F57.xml | 116 + src/devices/pic/xml_data/16F59.xml | 144 + src/devices/pic/xml_data/16F610.xml | 123 + src/devices/pic/xml_data/16F616.xml | 124 + src/devices/pic/xml_data/16F627.xml | 143 + src/devices/pic/xml_data/16F627A.xml | 164 + src/devices/pic/xml_data/16F628.xml | 145 + src/devices/pic/xml_data/16F628A.xml | 164 + src/devices/pic/xml_data/16F630.xml | 108 + src/devices/pic/xml_data/16F631.xml | 135 + src/devices/pic/xml_data/16F636.xml | 110 + src/devices/pic/xml_data/16F639.xml | 116 + src/devices/pic/xml_data/16F648A.xml | 164 + src/devices/pic/xml_data/16F676.xml | 108 + src/devices/pic/xml_data/16F677.xml | 135 + src/devices/pic/xml_data/16F684.xml | 106 + src/devices/pic/xml_data/16F685.xml | 135 + src/devices/pic/xml_data/16F687.xml | 135 + src/devices/pic/xml_data/16F688.xml | 106 + src/devices/pic/xml_data/16F689.xml | 135 + src/devices/pic/xml_data/16F690.xml | 135 + src/devices/pic/xml_data/16F716.xml | 119 + src/devices/pic/xml_data/16F72.xml | 130 + src/devices/pic/xml_data/16F73.xml | 121 + src/devices/pic/xml_data/16F737.xml | 215 + src/devices/pic/xml_data/16F74.xml | 196 + src/devices/pic/xml_data/16F747.xml | 196 + src/devices/pic/xml_data/16F76.xml | 121 + src/devices/pic/xml_data/16F767.xml | 215 + src/devices/pic/xml_data/16F77.xml | 196 + src/devices/pic/xml_data/16F777.xml | 196 + src/devices/pic/xml_data/16F785.xml | 120 + src/devices/pic/xml_data/16F818.xml | 176 + src/devices/pic/xml_data/16F819.xml | 176 + src/devices/pic/xml_data/16F83.xml | 106 + src/devices/pic/xml_data/16F84.xml | 106 + src/devices/pic/xml_data/16F84A.xml | 108 + src/devices/pic/xml_data/16F87.xml | 186 + src/devices/pic/xml_data/16F870.xml | 120 + src/devices/pic/xml_data/16F871.xml | 226 + src/devices/pic/xml_data/16F872.xml | 120 + src/devices/pic/xml_data/16F873.xml | 127 + src/devices/pic/xml_data/16F873A.xml | 151 + src/devices/pic/xml_data/16F874.xml | 233 + src/devices/pic/xml_data/16F874A.xml | 273 + src/devices/pic/xml_data/16F876.xml | 127 + src/devices/pic/xml_data/16F876A.xml | 151 + src/devices/pic/xml_data/16F877.xml | 233 + src/devices/pic/xml_data/16F877A.xml | 273 + src/devices/pic/xml_data/16F88.xml | 184 + src/devices/pic/xml_data/16F882.xml | 175 + src/devices/pic/xml_data/16F883.xml | 175 + src/devices/pic/xml_data/16F884.xml | 250 + src/devices/pic/xml_data/16F886.xml | 175 + src/devices/pic/xml_data/16F887.xml | 250 + src/devices/pic/xml_data/16F913.xml | 156 + src/devices/pic/xml_data/16F914.xml | 188 + src/devices/pic/xml_data/16F916.xml | 156 + src/devices/pic/xml_data/16F917.xml | 188 + src/devices/pic/xml_data/16F946.xml | 161 + src/devices/pic/xml_data/16HV540.xml | 97 + src/devices/pic/xml_data/17C42.xml | 192 + src/devices/pic/xml_data/17C42A.xml | 196 + src/devices/pic/xml_data/17C43.xml | 196 + src/devices/pic/xml_data/17C44.xml | 196 + src/devices/pic/xml_data/17C752.xml | 201 + src/devices/pic/xml_data/17C756.xml | 201 + src/devices/pic/xml_data/17C756A.xml | 201 + src/devices/pic/xml_data/17C762.xml | 233 + src/devices/pic/xml_data/17C766.xml | 233 + src/devices/pic/xml_data/17CR42.xml | 196 + src/devices/pic/xml_data/17CR43.xml | 196 + src/devices/pic/xml_data/18C242.xml | 146 + src/devices/pic/xml_data/18C252.xml | 146 + src/devices/pic/xml_data/18C442.xml | 252 + src/devices/pic/xml_data/18C452.xml | 252 + src/devices/pic/xml_data/18C601.xml | 225 + src/devices/pic/xml_data/18C658.xml | 248 + src/devices/pic/xml_data/18C801.xml | 257 + src/devices/pic/xml_data/18C858.xml | 280 + src/devices/pic/xml_data/18F1220.xml | 279 + src/devices/pic/xml_data/18F1230.xml | 311 + src/devices/pic/xml_data/18F1320.xml | 280 + src/devices/pic/xml_data/18F1330.xml | 313 + src/devices/pic/xml_data/18F2220.xml | 244 + src/devices/pic/xml_data/18F2221.xml | 281 + src/devices/pic/xml_data/18F2320.xml | 271 + src/devices/pic/xml_data/18F2321.xml | 282 + src/devices/pic/xml_data/18F2331.xml | 256 + src/devices/pic/xml_data/18F2410.xml | 268 + src/devices/pic/xml_data/18F242.xml | 221 + src/devices/pic/xml_data/18F2420.xml | 277 + src/devices/pic/xml_data/18F2423.xml | 274 + src/devices/pic/xml_data/18F2431.xml | 257 + src/devices/pic/xml_data/18F2439.xml | 210 + src/devices/pic/xml_data/18F2450.xml | 299 + src/devices/pic/xml_data/18F2455.xml | 288 + src/devices/pic/xml_data/18F248.xml | 216 + src/devices/pic/xml_data/18F2480.xml | 283 + src/devices/pic/xml_data/18F24J10.xml | 182 + src/devices/pic/xml_data/18F2510.xml | 298 + src/devices/pic/xml_data/18F2515.xml | 255 + src/devices/pic/xml_data/18F252.xml | 246 + src/devices/pic/xml_data/18F2520.xml | 307 + src/devices/pic/xml_data/18F2523.xml | 298 + src/devices/pic/xml_data/18F2525.xml | 264 + src/devices/pic/xml_data/18F2539.xml | 222 + src/devices/pic/xml_data/18F2550.xml | 292 + src/devices/pic/xml_data/18F258.xml | 241 + src/devices/pic/xml_data/18F2580.xml | 307 + src/devices/pic/xml_data/18F2585.xml | 266 + src/devices/pic/xml_data/18F25J10.xml | 182 + src/devices/pic/xml_data/18F2610.xml | 267 + src/devices/pic/xml_data/18F2620.xml | 265 + src/devices/pic/xml_data/18F2680.xml | 278 + src/devices/pic/xml_data/18F2682.xml | 284 + src/devices/pic/xml_data/18F2685.xml | 296 + src/devices/pic/xml_data/18F4220.xml | 351 + src/devices/pic/xml_data/18F4221.xml | 368 + src/devices/pic/xml_data/18F4320.xml | 377 + src/devices/pic/xml_data/18F4321.xml | 368 + src/devices/pic/xml_data/18F4331.xml | 384 + src/devices/pic/xml_data/18F4410.xml | 349 + src/devices/pic/xml_data/18F442.xml | 327 + src/devices/pic/xml_data/18F4420.xml | 358 + src/devices/pic/xml_data/18F4423.xml | 349 + src/devices/pic/xml_data/18F4431.xml | 409 + src/devices/pic/xml_data/18F4439.xml | 316 + src/devices/pic/xml_data/18F4450.xml | 378 + src/devices/pic/xml_data/18F4455.xml | 398 + src/devices/pic/xml_data/18F448.xml | 322 + src/devices/pic/xml_data/18F4480.xml | 358 + src/devices/pic/xml_data/18F44J10.xml | 129 + src/devices/pic/xml_data/18F4510.xml | 373 + src/devices/pic/xml_data/18F4515.xml | 361 + src/devices/pic/xml_data/18F452.xml | 352 + src/devices/pic/xml_data/18F4520.xml | 382 + src/devices/pic/xml_data/18F4523.xml | 379 + src/devices/pic/xml_data/18F4525.xml | 370 + src/devices/pic/xml_data/18F4539.xml | 328 + src/devices/pic/xml_data/18F4550.xml | 402 + src/devices/pic/xml_data/18F458.xml | 347 + src/devices/pic/xml_data/18F4580.xml | 382 + src/devices/pic/xml_data/18F4585.xml | 372 + src/devices/pic/xml_data/18F45J10.xml | 129 + src/devices/pic/xml_data/18F4610.xml | 373 + src/devices/pic/xml_data/18F4620.xml | 371 + src/devices/pic/xml_data/18F4680.xml | 384 + src/devices/pic/xml_data/18F4682.xml | 390 + src/devices/pic/xml_data/18F4685.xml | 402 + src/devices/pic/xml_data/18F6310.xml | 250 + src/devices/pic/xml_data/18F6390.xml | 250 + src/devices/pic/xml_data/18F6393.xml | 253 + src/devices/pic/xml_data/18F63J11.xml | 185 + src/devices/pic/xml_data/18F63J90.xml | 184 + src/devices/pic/xml_data/18F6410.xml | 250 + src/devices/pic/xml_data/18F6490.xml | 250 + src/devices/pic/xml_data/18F6493.xml | 253 + src/devices/pic/xml_data/18F64J11.xml | 185 + src/devices/pic/xml_data/18F64J90.xml | 185 + src/devices/pic/xml_data/18F6520.xml | 283 + src/devices/pic/xml_data/18F6525.xml | 287 + src/devices/pic/xml_data/18F6527.xml | 302 + src/devices/pic/xml_data/18F6585.xml | 350 + src/devices/pic/xml_data/18F65J10.xml | 185 + src/devices/pic/xml_data/18F65J11.xml | 185 + src/devices/pic/xml_data/18F65J15.xml | 185 + src/devices/pic/xml_data/18F65J50.xml | 199 + src/devices/pic/xml_data/18F65J90.xml | 185 + src/devices/pic/xml_data/18F6620.xml | 285 + src/devices/pic/xml_data/18F6621.xml | 299 + src/devices/pic/xml_data/18F6622.xml | 314 + src/devices/pic/xml_data/18F6627.xml | 332 + src/devices/pic/xml_data/18F6680.xml | 362 + src/devices/pic/xml_data/18F66J10.xml | 185 + src/devices/pic/xml_data/18F66J11.xml | 190 + src/devices/pic/xml_data/18F66J15.xml | 185 + src/devices/pic/xml_data/18F66J16.xml | 189 + src/devices/pic/xml_data/18F66J50.xml | 199 + src/devices/pic/xml_data/18F66J55.xml | 199 + src/devices/pic/xml_data/18F66J60.xml | 185 + src/devices/pic/xml_data/18F66J65.xml | 185 + src/devices/pic/xml_data/18F6720.xml | 330 + src/devices/pic/xml_data/18F6722.xml | 356 + src/devices/pic/xml_data/18F67J10.xml | 185 + src/devices/pic/xml_data/18F67J11.xml | 190 + src/devices/pic/xml_data/18F67J50.xml | 199 + src/devices/pic/xml_data/18F67J60.xml | 185 + src/devices/pic/xml_data/18F8310.xml | 266 + src/devices/pic/xml_data/18F8390.xml | 266 + src/devices/pic/xml_data/18F8393.xml | 254 + src/devices/pic/xml_data/18F83J11.xml | 143 + src/devices/pic/xml_data/18F83J90.xml | 143 + src/devices/pic/xml_data/18F8410.xml | 251 + src/devices/pic/xml_data/18F8490.xml | 251 + src/devices/pic/xml_data/18F8493.xml | 254 + src/devices/pic/xml_data/18F84J11.xml | 143 + src/devices/pic/xml_data/18F84J90.xml | 143 + src/devices/pic/xml_data/18F8520.xml | 311 + src/devices/pic/xml_data/18F8525.xml | 312 + src/devices/pic/xml_data/18F8527.xml | 346 + src/devices/pic/xml_data/18F8585.xml | 312 + src/devices/pic/xml_data/18F85J10.xml | 143 + src/devices/pic/xml_data/18F85J11.xml | 143 + src/devices/pic/xml_data/18F85J15.xml | 143 + src/devices/pic/xml_data/18F85J50.xml | 161 + src/devices/pic/xml_data/18F85J90.xml | 142 + src/devices/pic/xml_data/18F8620.xml | 311 + src/devices/pic/xml_data/18F8621.xml | 324 + src/devices/pic/xml_data/18F8622.xml | 358 + src/devices/pic/xml_data/18F8627.xml | 376 + src/devices/pic/xml_data/18F8680.xml | 324 + src/devices/pic/xml_data/18F86J10.xml | 143 + src/devices/pic/xml_data/18F86J11.xml | 152 + src/devices/pic/xml_data/18F86J15.xml | 143 + src/devices/pic/xml_data/18F86J16.xml | 151 + src/devices/pic/xml_data/18F86J50.xml | 161 + src/devices/pic/xml_data/18F86J55.xml | 161 + src/devices/pic/xml_data/18F86J60.xml | 196 + src/devices/pic/xml_data/18F86J65.xml | 193 + src/devices/pic/xml_data/18F8720.xml | 359 + src/devices/pic/xml_data/18F8722.xml | 400 + src/devices/pic/xml_data/18F87J10.xml | 143 + src/devices/pic/xml_data/18F87J11.xml | 151 + src/devices/pic/xml_data/18F87J50.xml | 161 + src/devices/pic/xml_data/18F87J60.xml | 193 + src/devices/pic/xml_data/18F96J60.xml | 211 + src/devices/pic/xml_data/18F96J65.xml | 211 + src/devices/pic/xml_data/18F97J60.xml | 211 + src/devices/pic/xml_data/24FJ128GA006.xml | 122 + src/devices/pic/xml_data/24FJ128GA008.xml | 122 + src/devices/pic/xml_data/24FJ128GA010.xml | 122 + src/devices/pic/xml_data/24FJ64GA002.xml | 132 + src/devices/pic/xml_data/24FJ64GA004.xml | 132 + src/devices/pic/xml_data/24FJ64GA006.xml | 122 + src/devices/pic/xml_data/24FJ64GA008.xml | 122 + src/devices/pic/xml_data/24FJ64GA010.xml | 122 + src/devices/pic/xml_data/24FJ96GA006.xml | 122 + src/devices/pic/xml_data/24FJ96GA008.xml | 122 + src/devices/pic/xml_data/24FJ96GA010.xml | 122 + src/devices/pic/xml_data/24HJ128GP206.xml | 199 + src/devices/pic/xml_data/24HJ128GP210.xml | 199 + src/devices/pic/xml_data/24HJ128GP306.xml | 199 + src/devices/pic/xml_data/24HJ128GP310.xml | 199 + src/devices/pic/xml_data/24HJ128GP506.xml | 199 + src/devices/pic/xml_data/24HJ128GP510.xml | 199 + src/devices/pic/xml_data/24HJ12GP201.xml | 177 + src/devices/pic/xml_data/24HJ12GP202.xml | 177 + src/devices/pic/xml_data/24HJ16GP304.xml | 180 + src/devices/pic/xml_data/24HJ256GP206.xml | 199 + src/devices/pic/xml_data/24HJ256GP210.xml | 199 + src/devices/pic/xml_data/24HJ256GP610.xml | 199 + src/devices/pic/xml_data/24HJ32GP202.xml | 180 + src/devices/pic/xml_data/24HJ32GP204.xml | 180 + src/devices/pic/xml_data/24HJ64GP206.xml | 199 + src/devices/pic/xml_data/24HJ64GP210.xml | 199 + src/devices/pic/xml_data/24HJ64GP506.xml | 199 + src/devices/pic/xml_data/24HJ64GP510.xml | 199 + src/devices/pic/xml_data/30F1010.xml | 221 + src/devices/pic/xml_data/30F2010.xml | 237 + src/devices/pic/xml_data/30F2011.xml | 203 + src/devices/pic/xml_data/30F2012.xml | 213 + src/devices/pic/xml_data/30F2020.xml | 221 + src/devices/pic/xml_data/30F2023.xml | 162 + src/devices/pic/xml_data/30F3010.xml | 242 + src/devices/pic/xml_data/30F3011.xml | 302 + src/devices/pic/xml_data/30F3012.xml | 220 + src/devices/pic/xml_data/30F3013.xml | 230 + src/devices/pic/xml_data/30F3014.xml | 289 + src/devices/pic/xml_data/30F4011.xml | 305 + src/devices/pic/xml_data/30F4012.xml | 246 + src/devices/pic/xml_data/30F4013.xml | 290 + src/devices/pic/xml_data/30F5011.xml | 276 + src/devices/pic/xml_data/30F5013.xml | 292 + src/devices/pic/xml_data/30F5015.xml | 232 + src/devices/pic/xml_data/30F5016.xml | 248 + src/devices/pic/xml_data/30F6010.xml | 252 + src/devices/pic/xml_data/30F6010A.xml | 308 + src/devices/pic/xml_data/30F6011.xml | 224 + src/devices/pic/xml_data/30F6011A.xml | 273 + src/devices/pic/xml_data/30F6012.xml | 224 + src/devices/pic/xml_data/30F6012A.xml | 273 + src/devices/pic/xml_data/30F6013.xml | 240 + src/devices/pic/xml_data/30F6013A.xml | 289 + src/devices/pic/xml_data/30F6014.xml | 240 + src/devices/pic/xml_data/30F6014A.xml | 289 + src/devices/pic/xml_data/30F6015.xml | 285 + src/devices/pic/xml_data/Makefile.am | 12 + src/devices/pic/xml_data/deps.mak | 43 + src/devices/pic/xml_data/pic.xsd | 295 + src/devices/pic/xml_data/registers/registers.xml | 57694 +++++++++++++++++++ .../pic/xml_data/registers/registers_missing.xml | 59 + src/devices/pic/xml_data/validate.sh | 5 + src/devices/pic/xml_data/validate/Makefile | 4 + src/devices/pic/xml_data/validate/validate.cpp | 72 + src/devices/pic/xml_data/xml_data.pro | 5 + src/libgui/Makefile.am | 12 + src/libgui/breakpoint_view.cpp | 94 + src/libgui/breakpoint_view.h | 48 + src/libgui/config_center.cpp | 132 + src/libgui/config_center.h | 85 + src/libgui/config_gen.cpp | 189 + src/libgui/config_gen.h | 82 + src/libgui/console.cpp | 42 + src/libgui/console.h | 27 + src/libgui/device_editor.cpp | 141 + src/libgui/device_editor.h | 47 + src/libgui/device_gui.cpp | 463 + src/libgui/device_gui.h | 205 + src/libgui/editor.cpp | 91 + src/libgui/editor.h | 68 + src/libgui/editor_manager.cpp | 506 + src/libgui/editor_manager.h | 128 + src/libgui/global_config.cpp | 106 + src/libgui/global_config.h | 39 + src/libgui/gui_debug_manager.cpp | 249 + src/libgui/gui_debug_manager.h | 61 + src/libgui/gui_prog_manager.cpp | 72 + src/libgui/gui_prog_manager.h | 37 + src/libgui/hex_editor.cpp | 192 + src/libgui/hex_editor.h | 83 + src/libgui/likeback.cpp | 668 + src/libgui/likeback.h | 120 + src/libgui/log_view.cpp | 135 + src/libgui/log_view.h | 51 + src/libgui/main_global.cpp | 81 + src/libgui/main_global.h | 70 + src/libgui/new_dialogs.cpp | 83 + src/libgui/new_dialogs.h | 59 + src/libgui/object_view.cpp | 145 + src/libgui/object_view.h | 99 + src/libgui/project.cpp | 226 + src/libgui/project.h | 49 + src/libgui/project_editor.cpp | 72 + src/libgui/project_editor.h | 47 + src/libgui/project_manager.cpp | 651 + src/libgui/project_manager.h | 106 + src/libgui/project_manager_ui.cpp | 185 + src/libgui/project_manager_ui.h | 121 + src/libgui/project_wizard.cpp | 283 + src/libgui/project_wizard.h | 91 + src/libgui/register_view.cpp | 51 + src/libgui/register_view.h | 42 + src/libgui/text_editor.cpp | 346 + src/libgui/text_editor.h | 103 + src/libgui/toplevel.cpp | 993 + src/libgui/toplevel.h | 132 + src/libgui/toplevel_ui.cpp | 79 + src/libgui/toplevel_ui.h | 77 + src/libgui/watch_view.cpp | 225 + src/libgui/watch_view.h | 94 + src/piklab-coff/Makefile.am | 16 + src/piklab-coff/main.cpp | 282 + src/piklab-coff/main.h | 52 + src/piklab-coff/piklab-coff.pro | 15 + src/piklab-hex/Makefile.am | 15 + src/piklab-hex/main.cpp | 291 + src/piklab-hex/main.h | 65 + src/piklab-hex/piklab-hex.pro | 14 + src/piklab-prog/Makefile.am | 31 + src/piklab-prog/cli_debug_manager.cpp | 18 + src/piklab-prog/cli_debug_manager.h | 34 + src/piklab-prog/cli_interactive.cpp | 347 + src/piklab-prog/cli_interactive.h | 53 + src/piklab-prog/cli_prog_manager.cpp | 65 + src/piklab-prog/cli_prog_manager.h | 38 + src/piklab-prog/cli_purl.cpp | 29 + src/piklab-prog/cmdline.cpp | 457 + src/piklab-prog/cmdline.h | 59 + src/piklab-prog/piklab-prog.pro | 32 + src/piklab-test/Makefile.am | 3 + src/piklab-test/base/Makefile.am | 5 + src/piklab-test/base/device_test.cpp | 54 + src/piklab-test/base/device_test.h | 32 + src/piklab-test/base/generator_check.cpp | 288 + src/piklab-test/base/generator_check.h | 102 + src/piklab-test/base/main_test.cpp | 32 + src/piklab-test/base/main_test.h | 51 + src/piklab-test/checksum/Makefile.am | 18 + src/piklab-test/checksum/checksum_check.cpp | 116 + src/piklab-test/checksum/checksum_check.h | 35 + src/piklab-test/generators/Makefile.am | 31 + .../generators/gputils_config_generator_check.cpp | 11 + .../generators/gputils_config_generator_check.h | 20 + .../gputils_template_generator_check.cpp | 11 + .../generators/gputils_template_generator_check.h | 20 + .../generators/sdcc_config_generator_check.cpp | 11 + .../generators/sdcc_config_generator_check.h | 20 + src/piklab-test/misc/Makefile.am | 10 + src/piklab-test/misc/misc_check.cpp | 99 + src/piklab-test/misc/misc_check.h | 20 + src/piklab-test/save_load_memory/Makefile.am | 18 + .../save_load_memory/save_load_memory_check.cpp | 64 + .../save_load_memory/save_load_memory_check.h | 32 + src/piklab/Makefile.am | 63 + src/piklab/main.cpp | 32 + src/progs/Makefile.am | 2 + src/progs/base/Makefile.am | 10 + src/progs/base/base.pro | 8 + src/progs/base/debug_config.cpp | 14 + src/progs/base/debug_config.h | 24 + src/progs/base/generic_debug.cpp | 111 + src/progs/base/generic_debug.h | 90 + src/progs/base/generic_prog.cpp | 402 + src/progs/base/generic_prog.h | 163 + src/progs/base/hardware_config.cpp | 97 + src/progs/base/hardware_config.h | 61 + src/progs/base/prog_config.cpp | 78 + src/progs/base/prog_config.h | 42 + src/progs/base/prog_group.cpp | 62 + src/progs/base/prog_group.h | 69 + src/progs/base/prog_specific.cpp | 51 + src/progs/base/prog_specific.h | 61 + src/progs/bootloader/Makefile.am | 3 + src/progs/bootloader/base/Makefile.am | 5 + src/progs/bootloader/base/base.pro | 6 + src/progs/bootloader/base/bootloader.cpp | 9 + src/progs/bootloader/base/bootloader.h | 42 + src/progs/bootloader/base/bootloader_prog.cpp | 25 + src/progs/bootloader/base/bootloader_prog.h | 37 + src/progs/bootloader/bootloader.pro | 2 + src/progs/bootloader/gui/Makefile.am | 6 + src/progs/bootloader/gui/bootloader_ui.cpp | 9 + src/progs/bootloader/gui/bootloader_ui.h | 30 + src/progs/direct/Makefile.am | 3 + src/progs/direct/base/Makefile.am | 13 + src/progs/direct/base/base.pro | 10 + src/progs/direct/base/direct.cpp | 394 + src/progs/direct/base/direct.h | 90 + src/progs/direct/base/direct.xml | 291 + src/progs/direct/base/direct_16.cpp | 150 + src/progs/direct/base/direct_16.h | 46 + src/progs/direct/base/direct_16F.cpp | 275 + src/progs/direct/base/direct_16F.h | 162 + src/progs/direct/base/direct_18.cpp | 109 + src/progs/direct/base/direct_18.h | 34 + src/progs/direct/base/direct_18F.cpp | 318 + src/progs/direct/base/direct_18F.h | 107 + src/progs/direct/base/direct_30.cpp | 261 + src/progs/direct/base/direct_30.h | 44 + src/progs/direct/base/direct_baseline.cpp | 88 + src/progs/direct/base/direct_baseline.h | 68 + src/progs/direct/base/direct_data.h | 21 + src/progs/direct/base/direct_mem24.cpp | 207 + src/progs/direct/base/direct_mem24.h | 47 + src/progs/direct/base/direct_pic.cpp | 187 + src/progs/direct/base/direct_pic.h | 68 + src/progs/direct/base/direct_prog.cpp | 62 + src/progs/direct/base/direct_prog.h | 74 + src/progs/direct/base/direct_prog_config.cpp | 145 + src/progs/direct/base/direct_prog_config.h | 42 + src/progs/direct/direct.pro | 2 + src/progs/direct/gui/Makefile.am | 5 + src/progs/direct/gui/direct_config_widget.cpp | 249 + src/progs/direct/gui/direct_config_widget.h | 74 + src/progs/direct/xml/Makefile.am | 14 + src/progs/direct/xml/xml.pro | 17 + src/progs/direct/xml/xml_direct_parser.cpp | 60 + src/progs/gpsim/Makefile.am | 3 + src/progs/gpsim/base/Makefile.am | 6 + src/progs/gpsim/base/base.pro | 6 + src/progs/gpsim/base/gpsim.cpp | 155 + src/progs/gpsim/base/gpsim.h | 85 + src/progs/gpsim/base/gpsim_debug.cpp | 282 + src/progs/gpsim/base/gpsim_debug.h | 95 + src/progs/gpsim/gpsim.pro | 2 + src/progs/gpsim/gui/Makefile.am | 5 + src/progs/gpsim/gui/gpsim_group_ui.cpp | 42 + src/progs/gpsim/gui/gpsim_group_ui.h | 42 + src/progs/gui/Makefile.am | 6 + src/progs/gui/debug_config_center.cpp | 17 + src/progs/gui/debug_config_center.h | 28 + src/progs/gui/hardware_config_widget.cpp | 204 + src/progs/gui/hardware_config_widget.h | 102 + src/progs/gui/port_selector.cpp | 144 + src/progs/gui/port_selector.h | 52 + src/progs/gui/prog_config_center.cpp | 122 + src/progs/gui/prog_config_center.h | 56 + src/progs/gui/prog_config_widget.cpp | 46 + src/progs/gui/prog_config_widget.h | 45 + src/progs/gui/prog_group_ui.cpp | 182 + src/progs/gui/prog_group_ui.h | 89 + src/progs/icd1/Makefile.am | 3 + src/progs/icd1/base/Makefile.am | 11 + src/progs/icd1/base/base.pro | 6 + src/progs/icd1/base/icd1.cpp | 197 + src/progs/icd1/base/icd1.h | 58 + src/progs/icd1/base/icd1.xml | 25 + src/progs/icd1/base/icd1_data.h | 22 + src/progs/icd1/base/icd1_prog.cpp | 51 + src/progs/icd1/base/icd1_prog.h | 60 + src/progs/icd1/base/icd1_serial.cpp | 76 + src/progs/icd1/base/icd1_serial.h | 31 + src/progs/icd1/gui/Makefile.am | 6 + src/progs/icd1/gui/icd1_group_ui.cpp | 41 + src/progs/icd1/gui/icd1_group_ui.h | 43 + src/progs/icd1/icd1.pro | 2 + src/progs/icd1/xml/Makefile.am | 14 + src/progs/icd1/xml/xml.pro | 18 + src/progs/icd1/xml/xml_icd1_parser.cpp | 41 + src/progs/icd2/Makefile.am | 3 + src/progs/icd2/base/Makefile.am | 13 + src/progs/icd2/base/base.pro | 8 + src/progs/icd2/base/icd.cpp | 94 + src/progs/icd2/base/icd.h | 74 + src/progs/icd2/base/icd2.cpp | 517 + src/progs/icd2/base/icd2.h | 95 + src/progs/icd2/base/icd2.xml | 214 + src/progs/icd2/base/icd2_data.h | 42 + src/progs/icd2/base/icd2_debug.cpp | 348 + src/progs/icd2/base/icd2_debug.h | 89 + src/progs/icd2/base/icd2_debug_specific.cpp | 255 + src/progs/icd2/base/icd2_debug_specific.h | 98 + src/progs/icd2/base/icd2_prog.cpp | 142 + src/progs/icd2/base/icd2_prog.h | 84 + src/progs/icd2/base/icd2_serial.cpp | 66 + src/progs/icd2/base/icd2_serial.h | 41 + src/progs/icd2/base/icd2_usb.cpp | 174 + src/progs/icd2/base/icd2_usb.h | 63 + src/progs/icd2/base/icd2_usb_firmware.cpp | 613 + src/progs/icd2/base/icd_prog.cpp | 39 + src/progs/icd2/base/icd_prog.h | 40 + src/progs/icd2/base/microchip.cpp | 11 + src/progs/icd2/base/microchip.h | 19 + src/progs/icd2/base/promate2.xml | 235 + src/progs/icd2/gui/Makefile.am | 6 + src/progs/icd2/gui/icd2_group_ui.cpp | 81 + src/progs/icd2/gui/icd2_group_ui.h | 48 + src/progs/icd2/icd2.pro | 2 + src/progs/icd2/icd2_data/Makefile.am | 5 + src/progs/icd2/icd2_data/icd2_data.cpp | 84 + src/progs/icd2/icd2_data/icd2_data.pro | 5 + src/progs/icd2/xml/Makefile.am | 15 + src/progs/icd2/xml/xml.pro | 17 + src/progs/icd2/xml/xml_icd2_parser.cpp | 53 + src/progs/list/Makefile.am | 8 + src/progs/list/list.pro | 6 + src/progs/list/prog_list.cpp | 15 + src/progs/list/prog_list.h | 28 + src/progs/list/prog_list_noui.cpp | 38 + src/progs/list/prog_list_ui.cpp | 49 + src/progs/manager/Makefile.am | 5 + src/progs/manager/breakpoint.cpp | 74 + src/progs/manager/breakpoint.h | 70 + src/progs/manager/debug_manager.cpp | 392 + src/progs/manager/debug_manager.h | 99 + src/progs/manager/manager.pro | 6 + src/progs/manager/prog_manager.cpp | 217 + src/progs/manager/prog_manager.h | 74 + src/progs/picdem_bootloader/Makefile.am | 3 + src/progs/picdem_bootloader/base/Makefile.am | 11 + src/progs/picdem_bootloader/base/base.pro | 6 + .../picdem_bootloader/base/picdem_bootloader.cpp | 184 + .../picdem_bootloader/base/picdem_bootloader.h | 72 + .../picdem_bootloader/base/picdem_bootloader.xml | 16 + .../base/picdem_bootloader_data.h | 19 + .../base/picdem_bootloader_prog.cpp | 14 + .../base/picdem_bootloader_prog.h | 46 + src/progs/picdem_bootloader/gui/Makefile.am | 6 + .../picdem_bootloader/gui/picdem_bootloader_ui.cpp | 48 + .../picdem_bootloader/gui/picdem_bootloader_ui.h | 37 + src/progs/picdem_bootloader/picdem_bootloader.pro | 2 + src/progs/picdem_bootloader/xml/Makefile.am | 14 + src/progs/picdem_bootloader/xml/xml.pro | 17 + .../xml/xml_picdem_bootloader_parser.cpp | 39 + src/progs/pickit1/Makefile.am | 3 + src/progs/pickit1/base/Makefile.am | 11 + src/progs/pickit1/base/base.pro | 6 + src/progs/pickit1/base/pickit1.cpp | 102 + src/progs/pickit1/base/pickit1.h | 73 + src/progs/pickit1/base/pickit1.xml | 52 + src/progs/pickit1/base/pickit1_data.h | 23 + src/progs/pickit1/base/pickit1_prog.cpp | 28 + src/progs/pickit1/base/pickit1_prog.h | 47 + src/progs/pickit1/gui/Makefile.am | 6 + src/progs/pickit1/gui/pickit1_group_ui.cpp | 23 + src/progs/pickit1/gui/pickit1_group_ui.h | 27 + src/progs/pickit1/pickit1.pro | 2 + src/progs/pickit1/xml/Makefile.am | 14 + src/progs/pickit1/xml/xml.pro | 18 + src/progs/pickit1/xml/xml_pickit1_parser.cpp | 61 + src/progs/pickit2/Makefile.am | 3 + src/progs/pickit2/base/Makefile.am | 12 + src/progs/pickit2/base/base.pro | 6 + src/progs/pickit2/base/pickit.cpp | 337 + src/progs/pickit2/base/pickit.h | 137 + src/progs/pickit2/base/pickit2.cpp | 447 + src/progs/pickit2/base/pickit2.h | 123 + src/progs/pickit2/base/pickit2.xml | 114 + src/progs/pickit2/base/pickit2_data.h | 24 + src/progs/pickit2/base/pickit2_prog.cpp | 78 + src/progs/pickit2/base/pickit2_prog.h | 50 + src/progs/pickit2/base/pickit_prog.cpp | 54 + src/progs/pickit2/base/pickit_prog.h | 45 + src/progs/pickit2/gui/Makefile.am | 6 + src/progs/pickit2/gui/pickit2_group_ui.cpp | 52 + src/progs/pickit2/gui/pickit2_group_ui.h | 42 + src/progs/pickit2/pickit2.pro | 2 + src/progs/pickit2/xml/Makefile.am | 14 + src/progs/pickit2/xml/xml.pro | 17 + src/progs/pickit2/xml/xml_pickit2_parser.cpp | 75 + src/progs/pickit2_bootloader/Makefile.am | 3 + src/progs/pickit2_bootloader/base/Makefile.am | 11 + src/progs/pickit2_bootloader/base/base.pro | 6 + .../pickit2_bootloader/base/pickit2_bootloader.cpp | 73 + .../pickit2_bootloader/base/pickit2_bootloader.h | 43 + .../pickit2_bootloader/base/pickit2_bootloader.xml | 16 + .../base/pickit2_bootloader_data.h | 19 + .../base/pickit2_bootloader_prog.cpp | 14 + .../base/pickit2_bootloader_prog.h | 47 + src/progs/pickit2_bootloader/gui/Makefile.am | 6 + .../gui/pickit2_bootloader_ui.cpp | 20 + .../pickit2_bootloader/gui/pickit2_bootloader_ui.h | 36 + .../pickit2_bootloader/pickit2_bootloader.pro | 2 + src/progs/pickit2_bootloader/xml/Makefile.am | 14 + src/progs/pickit2_bootloader/xml/xml.pro | 17 + .../xml/xml_pickit2_bootloader_parser.cpp | 39 + src/progs/pickit2v2/Makefile.am | 3 + src/progs/pickit2v2/base/Makefile.am | 6 + src/progs/pickit2v2/base/base.pro | 6 + src/progs/pickit2v2/base/pickit2v2.cpp | 432 + src/progs/pickit2v2/base/pickit2v2.h | 145 + src/progs/pickit2v2/base/pickit2v2_data.cpp | 951 + src/progs/pickit2v2/base/pickit2v2_data.h | 103 + src/progs/pickit2v2/base/pickit2v2_prog.cpp | 117 + src/progs/pickit2v2/base/pickit2v2_prog.h | 54 + src/progs/pickit2v2/gui/Makefile.am | 6 + src/progs/pickit2v2/gui/pickit2v2_group_ui.cpp | 22 + src/progs/pickit2v2/gui/pickit2v2_group_ui.h | 25 + src/progs/pickit2v2/pickit2v2.pro | 2 + src/progs/progs.pro | 3 + src/progs/psp/Makefile.am | 3 + src/progs/psp/base/Makefile.am | 11 + src/progs/psp/base/base.pro | 6 + src/progs/psp/base/psp.cpp | 346 + src/progs/psp/base/psp.h | 63 + src/progs/psp/base/psp.xml | 195 + src/progs/psp/base/psp_data.h | 23 + src/progs/psp/base/psp_prog.cpp | 31 + src/progs/psp/base/psp_prog.h | 53 + src/progs/psp/base/psp_serial.cpp | 110 + src/progs/psp/base/psp_serial.h | 37 + src/progs/psp/gui/Makefile.am | 6 + src/progs/psp/gui/psp_group_ui.cpp | 22 + src/progs/psp/gui/psp_group_ui.h | 28 + src/progs/psp/psp.pro | 2 + src/progs/psp/xml/Makefile.am | 14 + src/progs/psp/xml/xml.pro | 17 + src/progs/psp/xml/xml_psp_parser.cpp | 45 + src/progs/sdcdb/Makefile | 733 + src/progs/sdcdb/Makefile.am | 3 + src/progs/sdcdb/base/Makefile | 724 + src/progs/sdcdb/base/Makefile.am | 6 + src/progs/sdcdb/base/base.pro | 6 + src/progs/sdcdb/base/sdcdb_debug.cpp | 281 + src/progs/sdcdb/base/sdcdb_debug.h | 95 + src/progs/sdcdb/sdcdb.pro | 2 + src/progs/tbl_bootloader/Makefile.am | 3 + src/progs/tbl_bootloader/base/Makefile.am | 11 + src/progs/tbl_bootloader/base/base.pro | 6 + src/progs/tbl_bootloader/base/tbl_bootloader.cpp | 327 + src/progs/tbl_bootloader/base/tbl_bootloader.h | 74 + src/progs/tbl_bootloader/base/tbl_bootloader.xml | 70 + .../tbl_bootloader/base/tbl_bootloader_data.h | 21 + .../tbl_bootloader/base/tbl_bootloader_prog.cpp | 14 + .../tbl_bootloader/base/tbl_bootloader_prog.h | 46 + src/progs/tbl_bootloader/gui/Makefile.am | 6 + src/progs/tbl_bootloader/gui/tbl_bootloader_ui.cpp | 80 + src/progs/tbl_bootloader/gui/tbl_bootloader_ui.h | 42 + src/progs/tbl_bootloader/tbl_bootloader.pro | 2 + src/progs/tbl_bootloader/xml/Makefile.am | 14 + src/progs/tbl_bootloader/xml/xml.pro | 17 + .../xml/xml_tbl_bootloader_parser.cpp | 48 + src/src.pro | 2 + src/tools/Makefile.am | 3 + src/tools/base/Makefile.am | 6 + src/tools/base/generic_tool.cpp | 60 + src/tools/base/generic_tool.h | 104 + src/tools/base/tool_group.cpp | 140 + src/tools/base/tool_group.h | 85 + src/tools/boost/Makefile.am | 9 + src/tools/boost/boost.cpp | 102 + src/tools/boost/boost.h | 74 + src/tools/boost/boost_config.cpp | 9 + src/tools/boost/boost_config.h | 24 + src/tools/boost/boost_generator.cpp | 81 + src/tools/boost/boost_generator.h | 37 + src/tools/boost/boostbasic.cpp | 42 + src/tools/boost/boostbasic.h | 72 + src/tools/boost/boostc.cpp | 42 + src/tools/boost/boostc.h | 72 + src/tools/boost/boostc_compile.cpp | 56 + src/tools/boost/boostc_compile.h | 46 + src/tools/boost/boostcpp.cpp | 43 + src/tools/boost/boostcpp.h | 71 + src/tools/boost/gui/Makefile.am | 6 + src/tools/boost/gui/boost_ui.cpp | 19 + src/tools/boost/gui/boost_ui.h | 35 + src/tools/c18/Makefile.am | 8 + src/tools/c18/c18.cpp | 86 + src/tools/c18/c18.h | 62 + src/tools/c18/c18_compile.cpp | 65 + src/tools/c18/c18_compile.h | 46 + src/tools/c18/c18_config.cpp | 13 + src/tools/c18/c18_config.h | 29 + src/tools/c18/gui/Makefile.am | 6 + src/tools/c18/gui/c18_ui.cpp | 50 + src/tools/c18/gui/c18_ui.h | 40 + src/tools/cc5x/Makefile.am | 8 + src/tools/cc5x/cc5x.cpp | 62 + src/tools/cc5x/cc5x.h | 50 + src/tools/cc5x/cc5x_compile.cpp | 37 + src/tools/cc5x/cc5x_compile.h | 29 + src/tools/cc5x/cc5x_config.cpp | 9 + src/tools/cc5x/cc5x_config.h | 25 + src/tools/cc5x/gui/Makefile.am | 6 + src/tools/cc5x/gui/cc5x_ui.cpp | 19 + src/tools/cc5x/gui/cc5x_ui.h | 35 + src/tools/ccsc/Makefile.am | 8 + src/tools/ccsc/ccsc.cpp | 106 + src/tools/ccsc/ccsc.h | 57 + src/tools/ccsc/ccsc_compile.cpp | 107 + src/tools/ccsc/ccsc_compile.h | 37 + src/tools/ccsc/ccsc_config.cpp | 9 + src/tools/ccsc/ccsc_config.h | 25 + src/tools/ccsc/gui/Makefile.am | 6 + src/tools/ccsc/gui/ccsc_ui.cpp | 19 + src/tools/ccsc/gui/ccsc_ui.h | 35 + src/tools/custom/Makefile.am | 6 + src/tools/custom/custom.cpp | 23 + src/tools/custom/custom.h | 38 + src/tools/gputils/Makefile.am | 9 + src/tools/gputils/gputils.cpp | 107 + src/tools/gputils/gputils.h | 54 + src/tools/gputils/gputils_compile.cpp | 109 + src/tools/gputils/gputils_compile.h | 73 + src/tools/gputils/gputils_config.cpp | 19 + src/tools/gputils/gputils_config.h | 30 + src/tools/gputils/gputils_generator.cpp | 256 + src/tools/gputils/gputils_generator.h | 29 + src/tools/gputils/gui/Makefile.am | 6 + src/tools/gputils/gui/gputils_ui.cpp | 53 + src/tools/gputils/gui/gputils_ui.h | 41 + src/tools/gui/Makefile.am | 7 + src/tools/gui/tool_config_widget.cpp | 181 + src/tools/gui/tool_config_widget.h | 79 + src/tools/gui/tool_group_ui.cpp | 25 + src/tools/gui/tool_group_ui.h | 32 + src/tools/gui/toolchain_config_center.cpp | 111 + src/tools/gui/toolchain_config_center.h | 45 + src/tools/gui/toolchain_config_widget.cpp | 301 + src/tools/gui/toolchain_config_widget.h | 85 + src/tools/jal/Makefile.am | 8 + src/tools/jal/gui/Makefile.am | 6 + src/tools/jal/gui/jal_ui.cpp | 14 + src/tools/jal/gui/jal_ui.h | 35 + src/tools/jal/jal.cpp | 72 + src/tools/jal/jal.h | 49 + src/tools/jal/jal_compile.cpp | 26 + src/tools/jal/jal_compile.h | 29 + src/tools/jal/jal_config.cpp | 9 + src/tools/jal/jal_config.h | 25 + src/tools/jal/jal_generator.cpp | 35 + src/tools/jal/jal_generator.h | 27 + src/tools/jalv2/Makefile.am | 8 + src/tools/jalv2/gui/Makefile.am | 6 + src/tools/jalv2/gui/jalv2_ui.cpp | 19 + src/tools/jalv2/gui/jalv2_ui.h | 35 + src/tools/jalv2/jalv2.cpp | 77 + src/tools/jalv2/jalv2.h | 50 + src/tools/jalv2/jalv2_compile.cpp | 43 + src/tools/jalv2/jalv2_compile.h | 28 + src/tools/jalv2/jalv2_config.cpp | 9 + src/tools/jalv2/jalv2_config.h | 25 + src/tools/list/Makefile.am | 7 + src/tools/list/compile_config.cpp | 189 + src/tools/list/compile_config.h | 84 + src/tools/list/compile_manager.cpp | 292 + src/tools/list/compile_manager.h | 74 + src/tools/list/compile_process.cpp | 376 + src/tools/list/compile_process.h | 179 + src/tools/list/device_info.cpp | 63 + src/tools/list/device_info.h | 22 + src/tools/list/tool_list.cpp | 69 + src/tools/list/tool_list.h | 28 + src/tools/list/tools_config_widget.cpp | 144 + src/tools/list/tools_config_widget.h | 60 + src/tools/mpc/Makefile.am | 8 + src/tools/mpc/gui/Makefile.am | 6 + src/tools/mpc/gui/mpc_ui.cpp | 14 + src/tools/mpc/gui/mpc_ui.h | 35 + src/tools/mpc/mpc.cpp | 57 + src/tools/mpc/mpc.h | 49 + src/tools/mpc/mpc_compile.cpp | 51 + src/tools/mpc/mpc_compile.h | 35 + src/tools/mpc/mpc_config.cpp | 9 + src/tools/mpc/mpc_config.h | 25 + src/tools/pic30/Makefile.am | 9 + src/tools/pic30/gui/Makefile.am | 6 + src/tools/pic30/gui/pic30_ui.cpp | 26 + src/tools/pic30/gui/pic30_ui.h | 36 + src/tools/pic30/pic30.cpp | 137 + src/tools/pic30/pic30.h | 54 + src/tools/pic30/pic30_compile.cpp | 196 + src/tools/pic30/pic30_compile.h | 128 + src/tools/pic30/pic30_config.cpp | 9 + src/tools/pic30/pic30_config.h | 25 + src/tools/pic30/pic30_generator.cpp | 111 + src/tools/pic30/pic30_generator.h | 27 + src/tools/picc/Makefile.am | 8 + src/tools/picc/gui/Makefile.am | 6 + src/tools/picc/gui/picc_ui.cpp | 20 + src/tools/picc/gui/picc_ui.h | 35 + src/tools/picc/picc.cpp | 127 + src/tools/picc/picc.h | 97 + src/tools/picc/picc_compile.cpp | 136 + src/tools/picc/picc_compile.h | 83 + src/tools/picc/picc_config.cpp | 9 + src/tools/picc/picc_config.h | 25 + src/tools/sdcc/Makefile.am | 9 + src/tools/sdcc/gui/Makefile.am | 6 + src/tools/sdcc/gui/sdcc_ui.cpp | 29 + src/tools/sdcc/gui/sdcc_ui.h | 35 + src/tools/sdcc/sdcc.cpp | 115 + src/tools/sdcc/sdcc.h | 63 + src/tools/sdcc/sdcc_compile.cpp | 103 + src/tools/sdcc/sdcc_compile.h | 58 + src/tools/sdcc/sdcc_config.cpp | 9 + src/tools/sdcc/sdcc_config.h | 25 + src/tools/sdcc/sdcc_generator.cpp | 117 + src/tools/sdcc/sdcc_generator.h | 45 + src/xml_to_data/Makefile.am | 7 + src/xml_to_data/device_xml_to_data.cpp | 260 + src/xml_to_data/device_xml_to_data.h | 88 + src/xml_to_data/prog_xml_to_data.h | 218 + src/xml_to_data/xml_to_data.cpp | 71 + src/xml_to_data/xml_to_data.h | 47 + src/xml_to_data/xml_to_data.pro | 6 + 1319 files changed, 210815 insertions(+) create mode 100644 src/Makefile.am create mode 100644 src/coff/Makefile.am create mode 100644 src/coff/base/Makefile.am create mode 100644 src/coff/base/base.pro create mode 100644 src/coff/base/cdb_parser.cpp create mode 100644 src/coff/base/cdb_parser.h create mode 100644 src/coff/base/coff.cpp create mode 100644 src/coff/base/coff.h create mode 100644 src/coff/base/coff.xml create mode 100644 src/coff/base/coff_archive.cpp create mode 100644 src/coff/base/coff_archive.h create mode 100644 src/coff/base/coff_data.h create mode 100644 src/coff/base/coff_object.cpp create mode 100644 src/coff/base/coff_object.h create mode 100644 src/coff/base/disassembler.cpp create mode 100644 src/coff/base/disassembler.h create mode 100644 src/coff/base/gpdis.cpp create mode 100644 src/coff/base/gpopcode.cpp create mode 100644 src/coff/base/gpopcode.h create mode 100644 src/coff/base/text_coff.cpp create mode 100644 src/coff/base/text_coff.h create mode 100644 src/coff/coff.pro create mode 100644 src/coff/xml/Makefile.am create mode 100644 src/coff/xml/gpprocessor.cpp create mode 100644 src/coff/xml/gpprocessor.h create mode 100644 src/coff/xml/xml.pro create mode 100644 src/coff/xml/xml_coff_parser.cpp create mode 100644 src/common/Makefile.am create mode 100644 src/common/cli/Makefile.am create mode 100644 src/common/cli/cli.pro create mode 100644 src/common/cli/cli_global.cpp create mode 100644 src/common/cli/cli_global.h create mode 100644 src/common/cli/cli_log.cpp create mode 100644 src/common/cli/cli_log.h create mode 100644 src/common/cli/cli_main.cpp create mode 100644 src/common/cli/cli_main.h create mode 100644 src/common/cli/cli_pfile.cpp create mode 100644 src/common/cli/cli_purl.cpp create mode 100644 src/common/common.pro create mode 100644 src/common/common/Makefile.am create mode 100644 src/common/common/bitvalue.cpp create mode 100644 src/common/common/bitvalue.h create mode 100644 src/common/common/common.pro create mode 100644 src/common/common/group.cpp create mode 100644 src/common/common/group.h create mode 100644 src/common/common/key_enum.h create mode 100644 src/common/common/lister.h create mode 100644 src/common/common/misc.cpp create mode 100644 src/common/common/misc.h create mode 100644 src/common/common/number.cpp create mode 100644 src/common/common/number.h create mode 100644 src/common/common/purl_base.cpp create mode 100644 src/common/common/purl_base.h create mode 100644 src/common/common/qflags.h create mode 100644 src/common/common/range.h create mode 100644 src/common/common/storage.cpp create mode 100644 src/common/common/storage.h create mode 100644 src/common/common/streamer.h create mode 100644 src/common/common/synchronous.cpp create mode 100644 src/common/common/synchronous.h create mode 100644 src/common/common/version_data.cpp create mode 100644 src/common/common/version_data.h create mode 100644 src/common/global/Makefile.am create mode 100644 src/common/global/about.cpp create mode 100644 src/common/global/about.h create mode 100644 src/common/global/generic_config.cpp create mode 100644 src/common/global/generic_config.h create mode 100644 src/common/global/global.h create mode 100644 src/common/global/global.pro create mode 100644 src/common/global/log.cpp create mode 100644 src/common/global/log.h create mode 100644 src/common/global/pfile.cpp create mode 100644 src/common/global/pfile.h create mode 100644 src/common/global/process.cpp create mode 100644 src/common/global/process.h create mode 100644 src/common/global/progress_monitor.cpp create mode 100644 src/common/global/progress_monitor.h create mode 100644 src/common/global/purl.cpp create mode 100644 src/common/global/purl.h create mode 100644 src/common/global/svn_revision/Makefile.am create mode 100755 src/common/global/svn_revision/svn_revision.sh create mode 100644 src/common/global/xml_data_file.cpp create mode 100644 src/common/global/xml_data_file.h create mode 100644 src/common/gui/Makefile.am create mode 100644 src/common/gui/config_widget.h create mode 100644 src/common/gui/container.cpp create mode 100644 src/common/gui/container.h create mode 100644 src/common/gui/dialog.cpp create mode 100644 src/common/gui/dialog.h create mode 100644 src/common/gui/editlistbox.cpp create mode 100644 src/common/gui/editlistbox.h create mode 100644 src/common/gui/hexword_gui.cpp create mode 100644 src/common/gui/hexword_gui.h create mode 100644 src/common/gui/key_gui.h create mode 100644 src/common/gui/list_container.cpp create mode 100644 src/common/gui/list_container.h create mode 100644 src/common/gui/list_view.cpp create mode 100644 src/common/gui/list_view.h create mode 100644 src/common/gui/misc_gui.cpp create mode 100644 src/common/gui/misc_gui.h create mode 100644 src/common/gui/number_gui.cpp create mode 100644 src/common/gui/number_gui.h create mode 100644 src/common/gui/pfile_ext.cpp create mode 100644 src/common/gui/pfile_ext.h create mode 100644 src/common/gui/purl_ext.cpp create mode 100644 src/common/gui/purl_gui.cpp create mode 100644 src/common/gui/purl_gui.h create mode 100644 src/common/nokde/nokde.pro create mode 100644 src/common/nokde/nokde_kaboutdata.cpp create mode 100644 src/common/nokde/nokde_kaboutdata.h create mode 100644 src/common/nokde/nokde_kcmdlineargs.cpp create mode 100644 src/common/nokde/nokde_kcmdlineargs.h create mode 100644 src/common/nokde/nokde_klocale.cpp create mode 100644 src/common/nokde/nokde_klocale.h create mode 100644 src/common/nokde/nokde_kprocess.cpp create mode 100644 src/common/nokde/nokde_kprocess.h create mode 100644 src/common/nokde/nokde_kurl.h create mode 100644 src/common/nokde/win32_utils.c create mode 100644 src/common/nokde/win32_utils.h create mode 100644 src/common/port/Makefile.am create mode 100644 src/common/port/parallel.cpp create mode 100644 src/common/port/parallel.h create mode 100644 src/common/port/port.cpp create mode 100644 src/common/port/port.h create mode 100644 src/common/port/port.pro create mode 100644 src/common/port/port_base.cpp create mode 100644 src/common/port/port_base.h create mode 100644 src/common/port/serial.cpp create mode 100644 src/common/port/serial.h create mode 100644 src/common/port/usb_port.cpp create mode 100644 src/common/port/usb_port.h create mode 100644 src/data/Makefile.am create mode 100644 src/data/app_data/Makefile.am create mode 100644 src/data/app_data/hexeditorpartui.rc create mode 100644 src/data/app_data/hi16-app-piklab.png create mode 100644 src/data/app_data/hi32-app-piklab.png create mode 100644 src/data/app_data/hi32-mime-piklab_project.png create mode 100644 src/data/app_data/hi64-app-piklab.png create mode 100644 src/data/app_data/piklab.desktop create mode 100644 src/data/app_data/piklabui.rc create mode 100644 src/data/app_data/x-piklab.desktop create mode 100644 src/data/coff-c-pic.xml create mode 100644 src/data/hi16-action-piklab_addcurrentfile.png create mode 100644 src/data/hi16-action-piklab_addfile.png create mode 100644 src/data/hi16-action-piklab_blankcheck.png create mode 100644 src/data/hi16-action-piklab_burnchip.png create mode 100644 src/data/hi16-action-piklab_chip.png create mode 100644 src/data/hi16-action-piklab_closeproject.png create mode 100644 src/data/hi16-action-piklab_compile.png create mode 100644 src/data/hi16-action-piklab_createproject.png create mode 100644 src/data/hi16-action-piklab_decompile.png create mode 100644 src/data/hi16-action-piklab_editproject.png create mode 100644 src/data/hi16-action-piklab_erasechip.png create mode 100644 src/data/hi16-action-piklab_find_next.png create mode 100644 src/data/hi16-action-piklab_find_previous.png create mode 100644 src/data/hi16-action-piklab_openproject.png create mode 100644 src/data/hi16-action-piklab_readchip.png create mode 100644 src/data/hi16-action-piklab_verifychip.png create mode 100644 src/data/hi22-action-piklab_addcurrentfile.png create mode 100644 src/data/hi22-action-piklab_addfile.png create mode 100644 src/data/hi22-action-piklab_blankcheck.png create mode 100644 src/data/hi22-action-piklab_breakpoint_active.png create mode 100644 src/data/hi22-action-piklab_breakpoint_disabled.png create mode 100644 src/data/hi22-action-piklab_breakpoint_invalid.png create mode 100644 src/data/hi22-action-piklab_breakpoint_reached.png create mode 100644 src/data/hi22-action-piklab_burnchip.png create mode 100644 src/data/hi22-action-piklab_chip.png create mode 100644 src/data/hi22-action-piklab_closeproject.png create mode 100644 src/data/hi22-action-piklab_compile.png create mode 100644 src/data/hi22-action-piklab_createproject.png create mode 100644 src/data/hi22-action-piklab_debug_step.png create mode 100644 src/data/hi22-action-piklab_debug_stepin.png create mode 100644 src/data/hi22-action-piklab_debug_stepout.png create mode 100644 src/data/hi22-action-piklab_debug_stepover.png create mode 100644 src/data/hi22-action-piklab_debughalt.png create mode 100644 src/data/hi22-action-piklab_decompile.png create mode 100644 src/data/hi22-action-piklab_editproject.png create mode 100644 src/data/hi22-action-piklab_erasechip.png create mode 100644 src/data/hi22-action-piklab_find_next.png create mode 100644 src/data/hi22-action-piklab_find_previous.png create mode 100644 src/data/hi22-action-piklab_openproject.png create mode 100644 src/data/hi22-action-piklab_power.png create mode 100644 src/data/hi22-action-piklab_program_counter.png create mode 100644 src/data/hi22-action-piklab_program_counter_disabled.png create mode 100644 src/data/hi22-action-piklab_readchip.png create mode 100644 src/data/hi22-action-piklab_restart.png create mode 100644 src/data/hi22-action-piklab_run.png create mode 100644 src/data/hi22-action-piklab_stop.png create mode 100644 src/data/hi22-action-piklab_verifychip.png create mode 100644 src/data/hi32-action-piklab_config_assembler.png create mode 100644 src/data/hi32-action-piklab_config_disassembler.png create mode 100644 src/data/hi32-action-piklab_config_programmer.png create mode 100644 src/data/jal-pic.xml create mode 100644 src/data/likeback/Makefile.am create mode 100644 src/data/likeback/cr16-action-likeback_dislike.png create mode 100644 src/data/likeback/cr16-action-likeback_like.png create mode 100644 src/data/likeback/hi16-action-likeback_bug.png create mode 100644 src/data/syntax_xml_generator.cpp create mode 100644 src/data/xpms/csourcefile.xpm create mode 100644 src/data/xpms/includefile.xpm create mode 100644 src/data/xpms/objectfile.xpm create mode 100644 src/data/xpms/project.xpm create mode 100644 src/data/xpms/sourcefile.xpm create mode 100644 src/devices/Makefile.am create mode 100644 src/devices/base/Makefile.am create mode 100644 src/devices/base/base.pro create mode 100644 src/devices/base/device_group.cpp create mode 100644 src/devices/base/device_group.h create mode 100644 src/devices/base/generic_device.cpp create mode 100644 src/devices/base/generic_device.h create mode 100644 src/devices/base/generic_memory.cpp create mode 100644 src/devices/base/generic_memory.h create mode 100644 src/devices/base/hex_buffer.cpp create mode 100644 src/devices/base/hex_buffer.h create mode 100644 src/devices/base/register.cpp create mode 100644 src/devices/base/register.h create mode 100644 src/devices/devices.pro create mode 100644 src/devices/gui/Makefile.am create mode 100644 src/devices/gui/device_group_ui.cpp create mode 100644 src/devices/gui/device_group_ui.h create mode 100644 src/devices/gui/hex_view.cpp create mode 100644 src/devices/gui/hex_view.h create mode 100644 src/devices/gui/hex_word_editor.cpp create mode 100644 src/devices/gui/hex_word_editor.h create mode 100644 src/devices/gui/memory_editor.cpp create mode 100644 src/devices/gui/memory_editor.h create mode 100644 src/devices/gui/register_view.cpp create mode 100644 src/devices/gui/register_view.h create mode 100644 src/devices/list/Makefile.am create mode 100644 src/devices/list/device_list.cpp create mode 100644 src/devices/list/device_list.h create mode 100644 src/devices/list/device_list_noui.cpp create mode 100644 src/devices/list/device_list_ui.cpp create mode 100644 src/devices/list/list.pro create mode 100644 src/devices/mem24/Makefile.am create mode 100644 src/devices/mem24/base/Makefile.am create mode 100644 src/devices/mem24/base/base.pro create mode 100644 src/devices/mem24/base/mem24.cpp create mode 100644 src/devices/mem24/base/mem24.h create mode 100644 src/devices/mem24/gui/Makefile.am create mode 100644 src/devices/mem24/gui/mem24_group_ui.cpp create mode 100644 src/devices/mem24/gui/mem24_group_ui.h create mode 100644 src/devices/mem24/gui/mem24_hex_view.cpp create mode 100644 src/devices/mem24/gui/mem24_hex_view.h create mode 100644 src/devices/mem24/gui/mem24_memory_editor.cpp create mode 100644 src/devices/mem24/gui/mem24_memory_editor.h create mode 100644 src/devices/mem24/mem24.pro create mode 100644 src/devices/mem24/mem24/Makefile.am create mode 100644 src/devices/mem24/mem24/mem24.pro create mode 100644 src/devices/mem24/mem24/mem24_group.cpp create mode 100644 src/devices/mem24/mem24/mem24_group.h create mode 100644 src/devices/mem24/mem24/mem24_memory.cpp create mode 100644 src/devices/mem24/mem24/mem24_memory.h create mode 100644 src/devices/mem24/prog/Makefile.am create mode 100644 src/devices/mem24/prog/mem24_prog.cpp create mode 100644 src/devices/mem24/prog/mem24_prog.h create mode 100644 src/devices/mem24/prog/prog.pro create mode 100644 src/devices/mem24/xml/Makefile.am create mode 100644 src/devices/mem24/xml/mem24_xml_to_data.cpp create mode 100644 src/devices/mem24/xml/xml.pro create mode 100644 src/devices/mem24/xml_data/24AA00.xml create mode 100644 src/devices/mem24/xml_data/24AA01.xml create mode 100644 src/devices/mem24/xml_data/24AA014.xml create mode 100644 src/devices/mem24/xml_data/24AA02.xml create mode 100644 src/devices/mem24/xml_data/24AA024.xml create mode 100644 src/devices/mem24/xml_data/24AA025.xml create mode 100644 src/devices/mem24/xml_data/24AA04.xml create mode 100644 src/devices/mem24/xml_data/24AA08.xml create mode 100644 src/devices/mem24/xml_data/24AA1025.xml create mode 100644 src/devices/mem24/xml_data/24AA128.xml create mode 100644 src/devices/mem24/xml_data/24AA16.xml create mode 100644 src/devices/mem24/xml_data/24AA164.xml create mode 100644 src/devices/mem24/xml_data/24AA256.xml create mode 100644 src/devices/mem24/xml_data/24AA32A.xml create mode 100644 src/devices/mem24/xml_data/24AA512.xml create mode 100644 src/devices/mem24/xml_data/24AA515.xml create mode 100644 src/devices/mem24/xml_data/24AA64.xml create mode 100644 src/devices/mem24/xml_data/24AA65.xml create mode 100644 src/devices/mem24/xml_data/24C00.xml create mode 100644 src/devices/mem24/xml_data/24C01C.xml create mode 100644 src/devices/mem24/xml_data/24C02C.xml create mode 100644 src/devices/mem24/xml_data/24C65.xml create mode 100644 src/devices/mem24/xml_data/24FC1025.xml create mode 100644 src/devices/mem24/xml_data/24FC128.xml create mode 100644 src/devices/mem24/xml_data/24FC256.xml create mode 100644 src/devices/mem24/xml_data/24FC512.xml create mode 100644 src/devices/mem24/xml_data/24FC515.xml create mode 100644 src/devices/mem24/xml_data/24LC00.xml create mode 100644 src/devices/mem24/xml_data/24LC014.xml create mode 100644 src/devices/mem24/xml_data/24LC01B.xml create mode 100644 src/devices/mem24/xml_data/24LC024.xml create mode 100644 src/devices/mem24/xml_data/24LC025.xml create mode 100644 src/devices/mem24/xml_data/24LC02B.xml create mode 100644 src/devices/mem24/xml_data/24LC04B.xml create mode 100644 src/devices/mem24/xml_data/24LC08B.xml create mode 100644 src/devices/mem24/xml_data/24LC1025.xml create mode 100644 src/devices/mem24/xml_data/24LC128.xml create mode 100644 src/devices/mem24/xml_data/24LC16B.xml create mode 100644 src/devices/mem24/xml_data/24LC21A.xml create mode 100644 src/devices/mem24/xml_data/24LC22A.xml create mode 100644 src/devices/mem24/xml_data/24LC256.xml create mode 100644 src/devices/mem24/xml_data/24LC32A.xml create mode 100644 src/devices/mem24/xml_data/24LC512.xml create mode 100644 src/devices/mem24/xml_data/24LC515.xml create mode 100644 src/devices/mem24/xml_data/24LC64.xml create mode 100644 src/devices/mem24/xml_data/24LC65.xml create mode 100644 src/devices/mem24/xml_data/24LCS21A.xml create mode 100644 src/devices/mem24/xml_data/Makefile.am create mode 100644 src/devices/mem24/xml_data/deps.mak create mode 100644 src/devices/mem24/xml_data/xml_data.pro create mode 100644 src/devices/pic/Makefile.am create mode 100644 src/devices/pic/base/Makefile.am create mode 100644 src/devices/pic/base/base.pro create mode 100644 src/devices/pic/base/pic.cpp create mode 100644 src/devices/pic/base/pic.h create mode 100644 src/devices/pic/base/pic_config.cpp create mode 100644 src/devices/pic/base/pic_config.h create mode 100644 src/devices/pic/base/pic_protection.cpp create mode 100644 src/devices/pic/base/pic_protection.h create mode 100644 src/devices/pic/base/pic_register.cpp create mode 100644 src/devices/pic/base/pic_register.h create mode 100644 src/devices/pic/gui/Makefile.am create mode 100644 src/devices/pic/gui/pic_config_editor.cpp create mode 100644 src/devices/pic/gui/pic_config_editor.h create mode 100644 src/devices/pic/gui/pic_config_word_editor.cpp create mode 100644 src/devices/pic/gui/pic_config_word_editor.h create mode 100644 src/devices/pic/gui/pic_group_ui.cpp create mode 100644 src/devices/pic/gui/pic_group_ui.h create mode 100644 src/devices/pic/gui/pic_hex_view.cpp create mode 100644 src/devices/pic/gui/pic_hex_view.h create mode 100644 src/devices/pic/gui/pic_memory_editor.cpp create mode 100644 src/devices/pic/gui/pic_memory_editor.h create mode 100644 src/devices/pic/gui/pic_prog_group_ui.cpp create mode 100644 src/devices/pic/gui/pic_prog_group_ui.h create mode 100644 src/devices/pic/gui/pic_register_view.cpp create mode 100644 src/devices/pic/gui/pic_register_view.h create mode 100644 src/devices/pic/pic.pro create mode 100644 src/devices/pic/pic/Makefile.am create mode 100644 src/devices/pic/pic/pic.pro create mode 100644 src/devices/pic/pic/pic_group.cpp create mode 100644 src/devices/pic/pic/pic_group.h create mode 100644 src/devices/pic/pic/pic_memory.cpp create mode 100644 src/devices/pic/pic/pic_memory.h create mode 100644 src/devices/pic/prog/Makefile.am create mode 100644 src/devices/pic/prog/pic_debug.cpp create mode 100644 src/devices/pic/prog/pic_debug.h create mode 100644 src/devices/pic/prog/pic_prog.cpp create mode 100644 src/devices/pic/prog/pic_prog.h create mode 100644 src/devices/pic/prog/pic_prog_specific.cpp create mode 100644 src/devices/pic/prog/pic_prog_specific.h create mode 100644 src/devices/pic/prog/prog.pro create mode 100644 src/devices/pic/xml/Makefile.am create mode 100644 src/devices/pic/xml/pic_xml_to_data.cpp create mode 100644 src/devices/pic/xml/xml.pro create mode 100644 src/devices/pic/xml_data/10F200.xml create mode 100644 src/devices/pic/xml_data/10F202.xml create mode 100644 src/devices/pic/xml_data/10F204.xml create mode 100644 src/devices/pic/xml_data/10F206.xml create mode 100644 src/devices/pic/xml_data/10F220.xml create mode 100644 src/devices/pic/xml_data/10F222.xml create mode 100644 src/devices/pic/xml_data/12C508.xml create mode 100644 src/devices/pic/xml_data/12C508A.xml create mode 100644 src/devices/pic/xml_data/12C509.xml create mode 100644 src/devices/pic/xml_data/12C509A.xml create mode 100644 src/devices/pic/xml_data/12C671.xml create mode 100644 src/devices/pic/xml_data/12C672.xml create mode 100644 src/devices/pic/xml_data/12CE518.xml create mode 100644 src/devices/pic/xml_data/12CE519.xml create mode 100644 src/devices/pic/xml_data/12CE673.xml create mode 100644 src/devices/pic/xml_data/12CE674.xml create mode 100644 src/devices/pic/xml_data/12CR509A.xml create mode 100644 src/devices/pic/xml_data/12F508.xml create mode 100644 src/devices/pic/xml_data/12F509.xml create mode 100644 src/devices/pic/xml_data/12F510.xml create mode 100644 src/devices/pic/xml_data/12F519.xml create mode 100644 src/devices/pic/xml_data/12F609.xml create mode 100644 src/devices/pic/xml_data/12F615.xml create mode 100644 src/devices/pic/xml_data/12F629.xml create mode 100644 src/devices/pic/xml_data/12F635.xml create mode 100644 src/devices/pic/xml_data/12F675.xml create mode 100644 src/devices/pic/xml_data/12F683.xml create mode 100644 src/devices/pic/xml_data/14000.xml create mode 100644 src/devices/pic/xml_data/16C432.xml create mode 100644 src/devices/pic/xml_data/16C433.xml create mode 100644 src/devices/pic/xml_data/16C505.xml create mode 100644 src/devices/pic/xml_data/16C52.xml create mode 100644 src/devices/pic/xml_data/16C54.xml create mode 100644 src/devices/pic/xml_data/16C54A.xml create mode 100644 src/devices/pic/xml_data/16C54B.xml create mode 100644 src/devices/pic/xml_data/16C54C.xml create mode 100644 src/devices/pic/xml_data/16C55.xml create mode 100644 src/devices/pic/xml_data/16C554.xml create mode 100644 src/devices/pic/xml_data/16C557.xml create mode 100644 src/devices/pic/xml_data/16C558.xml create mode 100644 src/devices/pic/xml_data/16C55A.xml create mode 100644 src/devices/pic/xml_data/16C56.xml create mode 100644 src/devices/pic/xml_data/16C56A.xml create mode 100644 src/devices/pic/xml_data/16C57.xml create mode 100644 src/devices/pic/xml_data/16C57C.xml create mode 100644 src/devices/pic/xml_data/16C58A.xml create mode 100644 src/devices/pic/xml_data/16C58B.xml create mode 100644 src/devices/pic/xml_data/16C61.xml create mode 100644 src/devices/pic/xml_data/16C62.xml create mode 100644 src/devices/pic/xml_data/16C620.xml create mode 100644 src/devices/pic/xml_data/16C620A.xml create mode 100644 src/devices/pic/xml_data/16C621.xml create mode 100644 src/devices/pic/xml_data/16C621A.xml create mode 100644 src/devices/pic/xml_data/16C622.xml create mode 100644 src/devices/pic/xml_data/16C622A.xml create mode 100644 src/devices/pic/xml_data/16C62A.xml create mode 100644 src/devices/pic/xml_data/16C62B.xml create mode 100644 src/devices/pic/xml_data/16C63.xml create mode 100644 src/devices/pic/xml_data/16C63A.xml create mode 100644 src/devices/pic/xml_data/16C64.xml create mode 100644 src/devices/pic/xml_data/16C641.xml create mode 100644 src/devices/pic/xml_data/16C642.xml create mode 100644 src/devices/pic/xml_data/16C64A.xml create mode 100644 src/devices/pic/xml_data/16C65.xml create mode 100644 src/devices/pic/xml_data/16C65A.xml create mode 100644 src/devices/pic/xml_data/16C65B.xml create mode 100644 src/devices/pic/xml_data/16C66.xml create mode 100644 src/devices/pic/xml_data/16C661.xml create mode 100644 src/devices/pic/xml_data/16C662.xml create mode 100644 src/devices/pic/xml_data/16C67.xml create mode 100644 src/devices/pic/xml_data/16C71.xml create mode 100644 src/devices/pic/xml_data/16C710.xml create mode 100644 src/devices/pic/xml_data/16C711.xml create mode 100644 src/devices/pic/xml_data/16C712.xml create mode 100644 src/devices/pic/xml_data/16C715.xml create mode 100644 src/devices/pic/xml_data/16C716.xml create mode 100644 src/devices/pic/xml_data/16C717.xml create mode 100644 src/devices/pic/xml_data/16C72.xml create mode 100644 src/devices/pic/xml_data/16C72A.xml create mode 100644 src/devices/pic/xml_data/16C73.xml create mode 100644 src/devices/pic/xml_data/16C73A.xml create mode 100644 src/devices/pic/xml_data/16C73B.xml create mode 100644 src/devices/pic/xml_data/16C74.xml create mode 100644 src/devices/pic/xml_data/16C745.xml create mode 100644 src/devices/pic/xml_data/16C74A.xml create mode 100644 src/devices/pic/xml_data/16C74B.xml create mode 100644 src/devices/pic/xml_data/16C76.xml create mode 100644 src/devices/pic/xml_data/16C765.xml create mode 100644 src/devices/pic/xml_data/16C77.xml create mode 100644 src/devices/pic/xml_data/16C770.xml create mode 100644 src/devices/pic/xml_data/16C771.xml create mode 100644 src/devices/pic/xml_data/16C773.xml create mode 100644 src/devices/pic/xml_data/16C774.xml create mode 100644 src/devices/pic/xml_data/16C781.xml create mode 100644 src/devices/pic/xml_data/16C782.xml create mode 100644 src/devices/pic/xml_data/16C84.xml create mode 100644 src/devices/pic/xml_data/16C923.xml create mode 100644 src/devices/pic/xml_data/16C924.xml create mode 100644 src/devices/pic/xml_data/16C925.xml create mode 100644 src/devices/pic/xml_data/16C926.xml create mode 100644 src/devices/pic/xml_data/16CE623.xml create mode 100644 src/devices/pic/xml_data/16CE624.xml create mode 100644 src/devices/pic/xml_data/16CE625.xml create mode 100644 src/devices/pic/xml_data/16CR54.xml_broken create mode 100644 src/devices/pic/xml_data/16CR54A.xml create mode 100644 src/devices/pic/xml_data/16CR54B.xml create mode 100644 src/devices/pic/xml_data/16CR54C.xml create mode 100644 src/devices/pic/xml_data/16CR56A.xml create mode 100644 src/devices/pic/xml_data/16CR57B.xml create mode 100644 src/devices/pic/xml_data/16CR57C.xml create mode 100644 src/devices/pic/xml_data/16CR58A.xml create mode 100644 src/devices/pic/xml_data/16CR58B.xml create mode 100644 src/devices/pic/xml_data/16CR62.xml create mode 100644 src/devices/pic/xml_data/16CR620A.xml create mode 100644 src/devices/pic/xml_data/16CR63.xml create mode 100644 src/devices/pic/xml_data/16CR64.xml create mode 100644 src/devices/pic/xml_data/16CR65.xml create mode 100644 src/devices/pic/xml_data/16CR72.xml create mode 100644 src/devices/pic/xml_data/16CR73.xml create mode 100644 src/devices/pic/xml_data/16CR74.xml create mode 100644 src/devices/pic/xml_data/16CR76.xml create mode 100644 src/devices/pic/xml_data/16CR77.xml create mode 100644 src/devices/pic/xml_data/16CR83.xml create mode 100644 src/devices/pic/xml_data/16CR84.xml create mode 100644 src/devices/pic/xml_data/16F505.xml create mode 100644 src/devices/pic/xml_data/16F506.xml create mode 100644 src/devices/pic/xml_data/16F54.xml create mode 100644 src/devices/pic/xml_data/16F57.xml create mode 100644 src/devices/pic/xml_data/16F59.xml create mode 100644 src/devices/pic/xml_data/16F610.xml create mode 100644 src/devices/pic/xml_data/16F616.xml create mode 100644 src/devices/pic/xml_data/16F627.xml create mode 100644 src/devices/pic/xml_data/16F627A.xml create mode 100644 src/devices/pic/xml_data/16F628.xml create mode 100644 src/devices/pic/xml_data/16F628A.xml create mode 100644 src/devices/pic/xml_data/16F630.xml create mode 100644 src/devices/pic/xml_data/16F631.xml create mode 100644 src/devices/pic/xml_data/16F636.xml create mode 100644 src/devices/pic/xml_data/16F639.xml create mode 100644 src/devices/pic/xml_data/16F648A.xml create mode 100644 src/devices/pic/xml_data/16F676.xml create mode 100644 src/devices/pic/xml_data/16F677.xml create mode 100644 src/devices/pic/xml_data/16F684.xml create mode 100644 src/devices/pic/xml_data/16F685.xml create mode 100644 src/devices/pic/xml_data/16F687.xml create mode 100644 src/devices/pic/xml_data/16F688.xml create mode 100644 src/devices/pic/xml_data/16F689.xml create mode 100644 src/devices/pic/xml_data/16F690.xml create mode 100644 src/devices/pic/xml_data/16F716.xml create mode 100644 src/devices/pic/xml_data/16F72.xml create mode 100644 src/devices/pic/xml_data/16F73.xml create mode 100644 src/devices/pic/xml_data/16F737.xml create mode 100644 src/devices/pic/xml_data/16F74.xml create mode 100644 src/devices/pic/xml_data/16F747.xml create mode 100644 src/devices/pic/xml_data/16F76.xml create mode 100644 src/devices/pic/xml_data/16F767.xml create mode 100644 src/devices/pic/xml_data/16F77.xml create mode 100644 src/devices/pic/xml_data/16F777.xml create mode 100644 src/devices/pic/xml_data/16F785.xml create mode 100644 src/devices/pic/xml_data/16F818.xml create mode 100644 src/devices/pic/xml_data/16F819.xml create mode 100644 src/devices/pic/xml_data/16F83.xml create mode 100644 src/devices/pic/xml_data/16F84.xml create mode 100644 src/devices/pic/xml_data/16F84A.xml create mode 100644 src/devices/pic/xml_data/16F87.xml create mode 100644 src/devices/pic/xml_data/16F870.xml create mode 100644 src/devices/pic/xml_data/16F871.xml create mode 100644 src/devices/pic/xml_data/16F872.xml create mode 100644 src/devices/pic/xml_data/16F873.xml create mode 100644 src/devices/pic/xml_data/16F873A.xml create mode 100644 src/devices/pic/xml_data/16F874.xml create mode 100644 src/devices/pic/xml_data/16F874A.xml create mode 100644 src/devices/pic/xml_data/16F876.xml create mode 100644 src/devices/pic/xml_data/16F876A.xml create mode 100644 src/devices/pic/xml_data/16F877.xml create mode 100644 src/devices/pic/xml_data/16F877A.xml create mode 100644 src/devices/pic/xml_data/16F88.xml create mode 100644 src/devices/pic/xml_data/16F882.xml create mode 100644 src/devices/pic/xml_data/16F883.xml create mode 100644 src/devices/pic/xml_data/16F884.xml create mode 100644 src/devices/pic/xml_data/16F886.xml create mode 100644 src/devices/pic/xml_data/16F887.xml create mode 100644 src/devices/pic/xml_data/16F913.xml create mode 100644 src/devices/pic/xml_data/16F914.xml create mode 100644 src/devices/pic/xml_data/16F916.xml create mode 100644 src/devices/pic/xml_data/16F917.xml create mode 100644 src/devices/pic/xml_data/16F946.xml create mode 100644 src/devices/pic/xml_data/16HV540.xml create mode 100644 src/devices/pic/xml_data/17C42.xml create mode 100644 src/devices/pic/xml_data/17C42A.xml create mode 100644 src/devices/pic/xml_data/17C43.xml create mode 100644 src/devices/pic/xml_data/17C44.xml create mode 100644 src/devices/pic/xml_data/17C752.xml create mode 100644 src/devices/pic/xml_data/17C756.xml create mode 100644 src/devices/pic/xml_data/17C756A.xml create mode 100644 src/devices/pic/xml_data/17C762.xml create mode 100644 src/devices/pic/xml_data/17C766.xml create mode 100644 src/devices/pic/xml_data/17CR42.xml create mode 100644 src/devices/pic/xml_data/17CR43.xml create mode 100644 src/devices/pic/xml_data/18C242.xml create mode 100644 src/devices/pic/xml_data/18C252.xml create mode 100644 src/devices/pic/xml_data/18C442.xml create mode 100644 src/devices/pic/xml_data/18C452.xml create mode 100644 src/devices/pic/xml_data/18C601.xml create mode 100644 src/devices/pic/xml_data/18C658.xml create mode 100644 src/devices/pic/xml_data/18C801.xml create mode 100644 src/devices/pic/xml_data/18C858.xml create mode 100644 src/devices/pic/xml_data/18F1220.xml create mode 100644 src/devices/pic/xml_data/18F1230.xml create mode 100644 src/devices/pic/xml_data/18F1320.xml create mode 100644 src/devices/pic/xml_data/18F1330.xml create mode 100644 src/devices/pic/xml_data/18F2220.xml create mode 100644 src/devices/pic/xml_data/18F2221.xml create mode 100644 src/devices/pic/xml_data/18F2320.xml create mode 100644 src/devices/pic/xml_data/18F2321.xml create mode 100644 src/devices/pic/xml_data/18F2331.xml create mode 100644 src/devices/pic/xml_data/18F2410.xml create mode 100644 src/devices/pic/xml_data/18F242.xml create mode 100644 src/devices/pic/xml_data/18F2420.xml create mode 100644 src/devices/pic/xml_data/18F2423.xml create mode 100644 src/devices/pic/xml_data/18F2431.xml create mode 100644 src/devices/pic/xml_data/18F2439.xml create mode 100644 src/devices/pic/xml_data/18F2450.xml create mode 100644 src/devices/pic/xml_data/18F2455.xml create mode 100644 src/devices/pic/xml_data/18F248.xml create mode 100644 src/devices/pic/xml_data/18F2480.xml create mode 100644 src/devices/pic/xml_data/18F24J10.xml create mode 100644 src/devices/pic/xml_data/18F2510.xml create mode 100644 src/devices/pic/xml_data/18F2515.xml create mode 100644 src/devices/pic/xml_data/18F252.xml create mode 100644 src/devices/pic/xml_data/18F2520.xml create mode 100644 src/devices/pic/xml_data/18F2523.xml create mode 100644 src/devices/pic/xml_data/18F2525.xml create mode 100644 src/devices/pic/xml_data/18F2539.xml create mode 100644 src/devices/pic/xml_data/18F2550.xml create mode 100644 src/devices/pic/xml_data/18F258.xml create mode 100644 src/devices/pic/xml_data/18F2580.xml create mode 100644 src/devices/pic/xml_data/18F2585.xml create mode 100644 src/devices/pic/xml_data/18F25J10.xml create mode 100644 src/devices/pic/xml_data/18F2610.xml create mode 100644 src/devices/pic/xml_data/18F2620.xml create mode 100644 src/devices/pic/xml_data/18F2680.xml create mode 100644 src/devices/pic/xml_data/18F2682.xml create mode 100644 src/devices/pic/xml_data/18F2685.xml create mode 100644 src/devices/pic/xml_data/18F4220.xml create mode 100644 src/devices/pic/xml_data/18F4221.xml create mode 100644 src/devices/pic/xml_data/18F4320.xml create mode 100644 src/devices/pic/xml_data/18F4321.xml create mode 100644 src/devices/pic/xml_data/18F4331.xml create mode 100644 src/devices/pic/xml_data/18F4410.xml create mode 100644 src/devices/pic/xml_data/18F442.xml create mode 100644 src/devices/pic/xml_data/18F4420.xml create mode 100644 src/devices/pic/xml_data/18F4423.xml create mode 100644 src/devices/pic/xml_data/18F4431.xml create mode 100644 src/devices/pic/xml_data/18F4439.xml create mode 100644 src/devices/pic/xml_data/18F4450.xml create mode 100644 src/devices/pic/xml_data/18F4455.xml create mode 100644 src/devices/pic/xml_data/18F448.xml create mode 100644 src/devices/pic/xml_data/18F4480.xml create mode 100644 src/devices/pic/xml_data/18F44J10.xml create mode 100644 src/devices/pic/xml_data/18F4510.xml create mode 100644 src/devices/pic/xml_data/18F4515.xml create mode 100644 src/devices/pic/xml_data/18F452.xml create mode 100644 src/devices/pic/xml_data/18F4520.xml create mode 100644 src/devices/pic/xml_data/18F4523.xml create mode 100644 src/devices/pic/xml_data/18F4525.xml create mode 100644 src/devices/pic/xml_data/18F4539.xml create mode 100644 src/devices/pic/xml_data/18F4550.xml create mode 100644 src/devices/pic/xml_data/18F458.xml create mode 100644 src/devices/pic/xml_data/18F4580.xml create mode 100644 src/devices/pic/xml_data/18F4585.xml create mode 100644 src/devices/pic/xml_data/18F45J10.xml create mode 100644 src/devices/pic/xml_data/18F4610.xml create mode 100644 src/devices/pic/xml_data/18F4620.xml create mode 100644 src/devices/pic/xml_data/18F4680.xml create mode 100644 src/devices/pic/xml_data/18F4682.xml create mode 100644 src/devices/pic/xml_data/18F4685.xml create mode 100644 src/devices/pic/xml_data/18F6310.xml create mode 100644 src/devices/pic/xml_data/18F6390.xml create mode 100644 src/devices/pic/xml_data/18F6393.xml create mode 100644 src/devices/pic/xml_data/18F63J11.xml create mode 100644 src/devices/pic/xml_data/18F63J90.xml create mode 100644 src/devices/pic/xml_data/18F6410.xml create mode 100644 src/devices/pic/xml_data/18F6490.xml create mode 100644 src/devices/pic/xml_data/18F6493.xml create mode 100644 src/devices/pic/xml_data/18F64J11.xml create mode 100644 src/devices/pic/xml_data/18F64J90.xml create mode 100644 src/devices/pic/xml_data/18F6520.xml create mode 100644 src/devices/pic/xml_data/18F6525.xml create mode 100644 src/devices/pic/xml_data/18F6527.xml create mode 100644 src/devices/pic/xml_data/18F6585.xml create mode 100644 src/devices/pic/xml_data/18F65J10.xml create mode 100644 src/devices/pic/xml_data/18F65J11.xml create mode 100644 src/devices/pic/xml_data/18F65J15.xml create mode 100644 src/devices/pic/xml_data/18F65J50.xml create mode 100644 src/devices/pic/xml_data/18F65J90.xml create mode 100644 src/devices/pic/xml_data/18F6620.xml create mode 100644 src/devices/pic/xml_data/18F6621.xml create mode 100644 src/devices/pic/xml_data/18F6622.xml create mode 100644 src/devices/pic/xml_data/18F6627.xml create mode 100644 src/devices/pic/xml_data/18F6680.xml create mode 100644 src/devices/pic/xml_data/18F66J10.xml create mode 100644 src/devices/pic/xml_data/18F66J11.xml create mode 100644 src/devices/pic/xml_data/18F66J15.xml create mode 100644 src/devices/pic/xml_data/18F66J16.xml create mode 100644 src/devices/pic/xml_data/18F66J50.xml create mode 100644 src/devices/pic/xml_data/18F66J55.xml create mode 100644 src/devices/pic/xml_data/18F66J60.xml create mode 100644 src/devices/pic/xml_data/18F66J65.xml create mode 100644 src/devices/pic/xml_data/18F6720.xml create mode 100644 src/devices/pic/xml_data/18F6722.xml create mode 100644 src/devices/pic/xml_data/18F67J10.xml create mode 100644 src/devices/pic/xml_data/18F67J11.xml create mode 100644 src/devices/pic/xml_data/18F67J50.xml create mode 100644 src/devices/pic/xml_data/18F67J60.xml create mode 100644 src/devices/pic/xml_data/18F8310.xml create mode 100644 src/devices/pic/xml_data/18F8390.xml create mode 100644 src/devices/pic/xml_data/18F8393.xml create mode 100644 src/devices/pic/xml_data/18F83J11.xml create mode 100644 src/devices/pic/xml_data/18F83J90.xml create mode 100644 src/devices/pic/xml_data/18F8410.xml create mode 100644 src/devices/pic/xml_data/18F8490.xml create mode 100644 src/devices/pic/xml_data/18F8493.xml create mode 100644 src/devices/pic/xml_data/18F84J11.xml create mode 100644 src/devices/pic/xml_data/18F84J90.xml create mode 100644 src/devices/pic/xml_data/18F8520.xml create mode 100644 src/devices/pic/xml_data/18F8525.xml create mode 100644 src/devices/pic/xml_data/18F8527.xml create mode 100644 src/devices/pic/xml_data/18F8585.xml create mode 100644 src/devices/pic/xml_data/18F85J10.xml create mode 100644 src/devices/pic/xml_data/18F85J11.xml create mode 100644 src/devices/pic/xml_data/18F85J15.xml create mode 100644 src/devices/pic/xml_data/18F85J50.xml create mode 100644 src/devices/pic/xml_data/18F85J90.xml create mode 100644 src/devices/pic/xml_data/18F8620.xml create mode 100644 src/devices/pic/xml_data/18F8621.xml create mode 100644 src/devices/pic/xml_data/18F8622.xml create mode 100644 src/devices/pic/xml_data/18F8627.xml create mode 100644 src/devices/pic/xml_data/18F8680.xml create mode 100644 src/devices/pic/xml_data/18F86J10.xml create mode 100644 src/devices/pic/xml_data/18F86J11.xml create mode 100644 src/devices/pic/xml_data/18F86J15.xml create mode 100644 src/devices/pic/xml_data/18F86J16.xml create mode 100644 src/devices/pic/xml_data/18F86J50.xml create mode 100644 src/devices/pic/xml_data/18F86J55.xml create mode 100644 src/devices/pic/xml_data/18F86J60.xml create mode 100644 src/devices/pic/xml_data/18F86J65.xml create mode 100644 src/devices/pic/xml_data/18F8720.xml create mode 100644 src/devices/pic/xml_data/18F8722.xml create mode 100644 src/devices/pic/xml_data/18F87J10.xml create mode 100644 src/devices/pic/xml_data/18F87J11.xml create mode 100644 src/devices/pic/xml_data/18F87J50.xml create mode 100644 src/devices/pic/xml_data/18F87J60.xml create mode 100644 src/devices/pic/xml_data/18F96J60.xml create mode 100644 src/devices/pic/xml_data/18F96J65.xml create mode 100644 src/devices/pic/xml_data/18F97J60.xml create mode 100644 src/devices/pic/xml_data/24FJ128GA006.xml create mode 100644 src/devices/pic/xml_data/24FJ128GA008.xml create mode 100644 src/devices/pic/xml_data/24FJ128GA010.xml create mode 100644 src/devices/pic/xml_data/24FJ64GA002.xml create mode 100644 src/devices/pic/xml_data/24FJ64GA004.xml create mode 100644 src/devices/pic/xml_data/24FJ64GA006.xml create mode 100644 src/devices/pic/xml_data/24FJ64GA008.xml create mode 100644 src/devices/pic/xml_data/24FJ64GA010.xml create mode 100644 src/devices/pic/xml_data/24FJ96GA006.xml create mode 100644 src/devices/pic/xml_data/24FJ96GA008.xml create mode 100644 src/devices/pic/xml_data/24FJ96GA010.xml create mode 100644 src/devices/pic/xml_data/24HJ128GP206.xml create mode 100644 src/devices/pic/xml_data/24HJ128GP210.xml create mode 100644 src/devices/pic/xml_data/24HJ128GP306.xml create mode 100644 src/devices/pic/xml_data/24HJ128GP310.xml create mode 100644 src/devices/pic/xml_data/24HJ128GP506.xml create mode 100644 src/devices/pic/xml_data/24HJ128GP510.xml create mode 100644 src/devices/pic/xml_data/24HJ12GP201.xml create mode 100644 src/devices/pic/xml_data/24HJ12GP202.xml create mode 100644 src/devices/pic/xml_data/24HJ16GP304.xml create mode 100644 src/devices/pic/xml_data/24HJ256GP206.xml create mode 100644 src/devices/pic/xml_data/24HJ256GP210.xml create mode 100644 src/devices/pic/xml_data/24HJ256GP610.xml create mode 100644 src/devices/pic/xml_data/24HJ32GP202.xml create mode 100644 src/devices/pic/xml_data/24HJ32GP204.xml create mode 100644 src/devices/pic/xml_data/24HJ64GP206.xml create mode 100644 src/devices/pic/xml_data/24HJ64GP210.xml create mode 100644 src/devices/pic/xml_data/24HJ64GP506.xml create mode 100644 src/devices/pic/xml_data/24HJ64GP510.xml create mode 100644 src/devices/pic/xml_data/30F1010.xml create mode 100644 src/devices/pic/xml_data/30F2010.xml create mode 100644 src/devices/pic/xml_data/30F2011.xml create mode 100644 src/devices/pic/xml_data/30F2012.xml create mode 100644 src/devices/pic/xml_data/30F2020.xml create mode 100644 src/devices/pic/xml_data/30F2023.xml create mode 100644 src/devices/pic/xml_data/30F3010.xml create mode 100644 src/devices/pic/xml_data/30F3011.xml create mode 100644 src/devices/pic/xml_data/30F3012.xml create mode 100644 src/devices/pic/xml_data/30F3013.xml create mode 100644 src/devices/pic/xml_data/30F3014.xml create mode 100644 src/devices/pic/xml_data/30F4011.xml create mode 100644 src/devices/pic/xml_data/30F4012.xml create mode 100644 src/devices/pic/xml_data/30F4013.xml create mode 100644 src/devices/pic/xml_data/30F5011.xml create mode 100644 src/devices/pic/xml_data/30F5013.xml create mode 100644 src/devices/pic/xml_data/30F5015.xml create mode 100644 src/devices/pic/xml_data/30F5016.xml create mode 100644 src/devices/pic/xml_data/30F6010.xml create mode 100644 src/devices/pic/xml_data/30F6010A.xml create mode 100644 src/devices/pic/xml_data/30F6011.xml create mode 100644 src/devices/pic/xml_data/30F6011A.xml create mode 100644 src/devices/pic/xml_data/30F6012.xml create mode 100644 src/devices/pic/xml_data/30F6012A.xml create mode 100644 src/devices/pic/xml_data/30F6013.xml create mode 100644 src/devices/pic/xml_data/30F6013A.xml create mode 100644 src/devices/pic/xml_data/30F6014.xml create mode 100644 src/devices/pic/xml_data/30F6014A.xml create mode 100644 src/devices/pic/xml_data/30F6015.xml create mode 100644 src/devices/pic/xml_data/Makefile.am create mode 100644 src/devices/pic/xml_data/deps.mak create mode 100644 src/devices/pic/xml_data/pic.xsd create mode 100644 src/devices/pic/xml_data/registers/registers.xml create mode 100644 src/devices/pic/xml_data/registers/registers_missing.xml create mode 100755 src/devices/pic/xml_data/validate.sh create mode 100644 src/devices/pic/xml_data/validate/Makefile create mode 100644 src/devices/pic/xml_data/validate/validate.cpp create mode 100644 src/devices/pic/xml_data/xml_data.pro create mode 100644 src/libgui/Makefile.am create mode 100644 src/libgui/breakpoint_view.cpp create mode 100644 src/libgui/breakpoint_view.h create mode 100644 src/libgui/config_center.cpp create mode 100644 src/libgui/config_center.h create mode 100644 src/libgui/config_gen.cpp create mode 100644 src/libgui/config_gen.h create mode 100644 src/libgui/console.cpp create mode 100644 src/libgui/console.h create mode 100644 src/libgui/device_editor.cpp create mode 100644 src/libgui/device_editor.h create mode 100644 src/libgui/device_gui.cpp create mode 100644 src/libgui/device_gui.h create mode 100644 src/libgui/editor.cpp create mode 100644 src/libgui/editor.h create mode 100644 src/libgui/editor_manager.cpp create mode 100644 src/libgui/editor_manager.h create mode 100644 src/libgui/global_config.cpp create mode 100644 src/libgui/global_config.h create mode 100644 src/libgui/gui_debug_manager.cpp create mode 100644 src/libgui/gui_debug_manager.h create mode 100644 src/libgui/gui_prog_manager.cpp create mode 100644 src/libgui/gui_prog_manager.h create mode 100644 src/libgui/hex_editor.cpp create mode 100644 src/libgui/hex_editor.h create mode 100644 src/libgui/likeback.cpp create mode 100644 src/libgui/likeback.h create mode 100644 src/libgui/log_view.cpp create mode 100644 src/libgui/log_view.h create mode 100644 src/libgui/main_global.cpp create mode 100644 src/libgui/main_global.h create mode 100644 src/libgui/new_dialogs.cpp create mode 100644 src/libgui/new_dialogs.h create mode 100644 src/libgui/object_view.cpp create mode 100644 src/libgui/object_view.h create mode 100644 src/libgui/project.cpp create mode 100644 src/libgui/project.h create mode 100644 src/libgui/project_editor.cpp create mode 100644 src/libgui/project_editor.h create mode 100644 src/libgui/project_manager.cpp create mode 100644 src/libgui/project_manager.h create mode 100644 src/libgui/project_manager_ui.cpp create mode 100644 src/libgui/project_manager_ui.h create mode 100644 src/libgui/project_wizard.cpp create mode 100644 src/libgui/project_wizard.h create mode 100644 src/libgui/register_view.cpp create mode 100644 src/libgui/register_view.h create mode 100644 src/libgui/text_editor.cpp create mode 100644 src/libgui/text_editor.h create mode 100644 src/libgui/toplevel.cpp create mode 100644 src/libgui/toplevel.h create mode 100644 src/libgui/toplevel_ui.cpp create mode 100644 src/libgui/toplevel_ui.h create mode 100644 src/libgui/watch_view.cpp create mode 100644 src/libgui/watch_view.h create mode 100644 src/piklab-coff/Makefile.am create mode 100644 src/piklab-coff/main.cpp create mode 100644 src/piklab-coff/main.h create mode 100644 src/piklab-coff/piklab-coff.pro create mode 100644 src/piklab-hex/Makefile.am create mode 100644 src/piklab-hex/main.cpp create mode 100644 src/piklab-hex/main.h create mode 100644 src/piklab-hex/piklab-hex.pro create mode 100644 src/piklab-prog/Makefile.am create mode 100644 src/piklab-prog/cli_debug_manager.cpp create mode 100644 src/piklab-prog/cli_debug_manager.h create mode 100644 src/piklab-prog/cli_interactive.cpp create mode 100644 src/piklab-prog/cli_interactive.h create mode 100644 src/piklab-prog/cli_prog_manager.cpp create mode 100644 src/piklab-prog/cli_prog_manager.h create mode 100644 src/piklab-prog/cli_purl.cpp create mode 100644 src/piklab-prog/cmdline.cpp create mode 100644 src/piklab-prog/cmdline.h create mode 100644 src/piklab-prog/piklab-prog.pro create mode 100644 src/piklab-test/Makefile.am create mode 100644 src/piklab-test/base/Makefile.am create mode 100644 src/piklab-test/base/device_test.cpp create mode 100644 src/piklab-test/base/device_test.h create mode 100644 src/piklab-test/base/generator_check.cpp create mode 100644 src/piklab-test/base/generator_check.h create mode 100644 src/piklab-test/base/main_test.cpp create mode 100644 src/piklab-test/base/main_test.h create mode 100644 src/piklab-test/checksum/Makefile.am create mode 100644 src/piklab-test/checksum/checksum_check.cpp create mode 100644 src/piklab-test/checksum/checksum_check.h create mode 100644 src/piklab-test/generators/Makefile.am create mode 100644 src/piklab-test/generators/gputils_config_generator_check.cpp create mode 100644 src/piklab-test/generators/gputils_config_generator_check.h create mode 100644 src/piklab-test/generators/gputils_template_generator_check.cpp create mode 100644 src/piklab-test/generators/gputils_template_generator_check.h create mode 100644 src/piklab-test/generators/sdcc_config_generator_check.cpp create mode 100644 src/piklab-test/generators/sdcc_config_generator_check.h create mode 100644 src/piklab-test/misc/Makefile.am create mode 100644 src/piklab-test/misc/misc_check.cpp create mode 100644 src/piklab-test/misc/misc_check.h create mode 100644 src/piklab-test/save_load_memory/Makefile.am create mode 100644 src/piklab-test/save_load_memory/save_load_memory_check.cpp create mode 100644 src/piklab-test/save_load_memory/save_load_memory_check.h create mode 100644 src/piklab/Makefile.am create mode 100644 src/piklab/main.cpp create mode 100644 src/progs/Makefile.am create mode 100644 src/progs/base/Makefile.am create mode 100644 src/progs/base/base.pro create mode 100644 src/progs/base/debug_config.cpp create mode 100644 src/progs/base/debug_config.h create mode 100644 src/progs/base/generic_debug.cpp create mode 100644 src/progs/base/generic_debug.h create mode 100644 src/progs/base/generic_prog.cpp create mode 100644 src/progs/base/generic_prog.h create mode 100644 src/progs/base/hardware_config.cpp create mode 100644 src/progs/base/hardware_config.h create mode 100644 src/progs/base/prog_config.cpp create mode 100644 src/progs/base/prog_config.h create mode 100644 src/progs/base/prog_group.cpp create mode 100644 src/progs/base/prog_group.h create mode 100644 src/progs/base/prog_specific.cpp create mode 100644 src/progs/base/prog_specific.h create mode 100644 src/progs/bootloader/Makefile.am create mode 100644 src/progs/bootloader/base/Makefile.am create mode 100644 src/progs/bootloader/base/base.pro create mode 100644 src/progs/bootloader/base/bootloader.cpp create mode 100644 src/progs/bootloader/base/bootloader.h create mode 100644 src/progs/bootloader/base/bootloader_prog.cpp create mode 100644 src/progs/bootloader/base/bootloader_prog.h create mode 100644 src/progs/bootloader/bootloader.pro create mode 100644 src/progs/bootloader/gui/Makefile.am create mode 100644 src/progs/bootloader/gui/bootloader_ui.cpp create mode 100644 src/progs/bootloader/gui/bootloader_ui.h create mode 100644 src/progs/direct/Makefile.am create mode 100644 src/progs/direct/base/Makefile.am create mode 100644 src/progs/direct/base/base.pro create mode 100644 src/progs/direct/base/direct.cpp create mode 100644 src/progs/direct/base/direct.h create mode 100644 src/progs/direct/base/direct.xml create mode 100644 src/progs/direct/base/direct_16.cpp create mode 100644 src/progs/direct/base/direct_16.h create mode 100644 src/progs/direct/base/direct_16F.cpp create mode 100644 src/progs/direct/base/direct_16F.h create mode 100644 src/progs/direct/base/direct_18.cpp create mode 100644 src/progs/direct/base/direct_18.h create mode 100644 src/progs/direct/base/direct_18F.cpp create mode 100644 src/progs/direct/base/direct_18F.h create mode 100644 src/progs/direct/base/direct_30.cpp create mode 100644 src/progs/direct/base/direct_30.h create mode 100644 src/progs/direct/base/direct_baseline.cpp create mode 100644 src/progs/direct/base/direct_baseline.h create mode 100644 src/progs/direct/base/direct_data.h create mode 100644 src/progs/direct/base/direct_mem24.cpp create mode 100644 src/progs/direct/base/direct_mem24.h create mode 100644 src/progs/direct/base/direct_pic.cpp create mode 100644 src/progs/direct/base/direct_pic.h create mode 100644 src/progs/direct/base/direct_prog.cpp create mode 100644 src/progs/direct/base/direct_prog.h create mode 100644 src/progs/direct/base/direct_prog_config.cpp create mode 100644 src/progs/direct/base/direct_prog_config.h create mode 100644 src/progs/direct/direct.pro create mode 100644 src/progs/direct/gui/Makefile.am create mode 100644 src/progs/direct/gui/direct_config_widget.cpp create mode 100644 src/progs/direct/gui/direct_config_widget.h create mode 100644 src/progs/direct/xml/Makefile.am create mode 100644 src/progs/direct/xml/xml.pro create mode 100644 src/progs/direct/xml/xml_direct_parser.cpp create mode 100644 src/progs/gpsim/Makefile.am create mode 100644 src/progs/gpsim/base/Makefile.am create mode 100644 src/progs/gpsim/base/base.pro create mode 100644 src/progs/gpsim/base/gpsim.cpp create mode 100644 src/progs/gpsim/base/gpsim.h create mode 100644 src/progs/gpsim/base/gpsim_debug.cpp create mode 100644 src/progs/gpsim/base/gpsim_debug.h create mode 100644 src/progs/gpsim/gpsim.pro create mode 100644 src/progs/gpsim/gui/Makefile.am create mode 100644 src/progs/gpsim/gui/gpsim_group_ui.cpp create mode 100644 src/progs/gpsim/gui/gpsim_group_ui.h create mode 100644 src/progs/gui/Makefile.am create mode 100644 src/progs/gui/debug_config_center.cpp create mode 100644 src/progs/gui/debug_config_center.h create mode 100644 src/progs/gui/hardware_config_widget.cpp create mode 100644 src/progs/gui/hardware_config_widget.h create mode 100644 src/progs/gui/port_selector.cpp create mode 100644 src/progs/gui/port_selector.h create mode 100644 src/progs/gui/prog_config_center.cpp create mode 100644 src/progs/gui/prog_config_center.h create mode 100644 src/progs/gui/prog_config_widget.cpp create mode 100644 src/progs/gui/prog_config_widget.h create mode 100644 src/progs/gui/prog_group_ui.cpp create mode 100644 src/progs/gui/prog_group_ui.h create mode 100644 src/progs/icd1/Makefile.am create mode 100644 src/progs/icd1/base/Makefile.am create mode 100644 src/progs/icd1/base/base.pro create mode 100644 src/progs/icd1/base/icd1.cpp create mode 100644 src/progs/icd1/base/icd1.h create mode 100644 src/progs/icd1/base/icd1.xml create mode 100644 src/progs/icd1/base/icd1_data.h create mode 100644 src/progs/icd1/base/icd1_prog.cpp create mode 100644 src/progs/icd1/base/icd1_prog.h create mode 100644 src/progs/icd1/base/icd1_serial.cpp create mode 100644 src/progs/icd1/base/icd1_serial.h create mode 100644 src/progs/icd1/gui/Makefile.am create mode 100644 src/progs/icd1/gui/icd1_group_ui.cpp create mode 100644 src/progs/icd1/gui/icd1_group_ui.h create mode 100644 src/progs/icd1/icd1.pro create mode 100644 src/progs/icd1/xml/Makefile.am create mode 100644 src/progs/icd1/xml/xml.pro create mode 100644 src/progs/icd1/xml/xml_icd1_parser.cpp create mode 100644 src/progs/icd2/Makefile.am create mode 100644 src/progs/icd2/base/Makefile.am create mode 100644 src/progs/icd2/base/base.pro create mode 100644 src/progs/icd2/base/icd.cpp create mode 100644 src/progs/icd2/base/icd.h create mode 100644 src/progs/icd2/base/icd2.cpp create mode 100644 src/progs/icd2/base/icd2.h create mode 100644 src/progs/icd2/base/icd2.xml create mode 100644 src/progs/icd2/base/icd2_data.h create mode 100644 src/progs/icd2/base/icd2_debug.cpp create mode 100644 src/progs/icd2/base/icd2_debug.h create mode 100644 src/progs/icd2/base/icd2_debug_specific.cpp create mode 100644 src/progs/icd2/base/icd2_debug_specific.h create mode 100644 src/progs/icd2/base/icd2_prog.cpp create mode 100644 src/progs/icd2/base/icd2_prog.h create mode 100644 src/progs/icd2/base/icd2_serial.cpp create mode 100644 src/progs/icd2/base/icd2_serial.h create mode 100644 src/progs/icd2/base/icd2_usb.cpp create mode 100644 src/progs/icd2/base/icd2_usb.h create mode 100644 src/progs/icd2/base/icd2_usb_firmware.cpp create mode 100644 src/progs/icd2/base/icd_prog.cpp create mode 100644 src/progs/icd2/base/icd_prog.h create mode 100644 src/progs/icd2/base/microchip.cpp create mode 100644 src/progs/icd2/base/microchip.h create mode 100644 src/progs/icd2/base/promate2.xml create mode 100644 src/progs/icd2/gui/Makefile.am create mode 100644 src/progs/icd2/gui/icd2_group_ui.cpp create mode 100644 src/progs/icd2/gui/icd2_group_ui.h create mode 100644 src/progs/icd2/icd2.pro create mode 100644 src/progs/icd2/icd2_data/Makefile.am create mode 100644 src/progs/icd2/icd2_data/icd2_data.cpp create mode 100644 src/progs/icd2/icd2_data/icd2_data.pro create mode 100644 src/progs/icd2/xml/Makefile.am create mode 100644 src/progs/icd2/xml/xml.pro create mode 100644 src/progs/icd2/xml/xml_icd2_parser.cpp create mode 100644 src/progs/list/Makefile.am create mode 100644 src/progs/list/list.pro create mode 100644 src/progs/list/prog_list.cpp create mode 100644 src/progs/list/prog_list.h create mode 100644 src/progs/list/prog_list_noui.cpp create mode 100644 src/progs/list/prog_list_ui.cpp create mode 100644 src/progs/manager/Makefile.am create mode 100644 src/progs/manager/breakpoint.cpp create mode 100644 src/progs/manager/breakpoint.h create mode 100644 src/progs/manager/debug_manager.cpp create mode 100644 src/progs/manager/debug_manager.h create mode 100644 src/progs/manager/manager.pro create mode 100644 src/progs/manager/prog_manager.cpp create mode 100644 src/progs/manager/prog_manager.h create mode 100644 src/progs/picdem_bootloader/Makefile.am create mode 100644 src/progs/picdem_bootloader/base/Makefile.am create mode 100644 src/progs/picdem_bootloader/base/base.pro create mode 100644 src/progs/picdem_bootloader/base/picdem_bootloader.cpp create mode 100644 src/progs/picdem_bootloader/base/picdem_bootloader.h create mode 100644 src/progs/picdem_bootloader/base/picdem_bootloader.xml create mode 100644 src/progs/picdem_bootloader/base/picdem_bootloader_data.h create mode 100644 src/progs/picdem_bootloader/base/picdem_bootloader_prog.cpp create mode 100644 src/progs/picdem_bootloader/base/picdem_bootloader_prog.h create mode 100644 src/progs/picdem_bootloader/gui/Makefile.am create mode 100644 src/progs/picdem_bootloader/gui/picdem_bootloader_ui.cpp create mode 100644 src/progs/picdem_bootloader/gui/picdem_bootloader_ui.h create mode 100644 src/progs/picdem_bootloader/picdem_bootloader.pro create mode 100644 src/progs/picdem_bootloader/xml/Makefile.am create mode 100644 src/progs/picdem_bootloader/xml/xml.pro create mode 100644 src/progs/picdem_bootloader/xml/xml_picdem_bootloader_parser.cpp create mode 100644 src/progs/pickit1/Makefile.am create mode 100644 src/progs/pickit1/base/Makefile.am create mode 100644 src/progs/pickit1/base/base.pro create mode 100644 src/progs/pickit1/base/pickit1.cpp create mode 100644 src/progs/pickit1/base/pickit1.h create mode 100644 src/progs/pickit1/base/pickit1.xml create mode 100644 src/progs/pickit1/base/pickit1_data.h create mode 100644 src/progs/pickit1/base/pickit1_prog.cpp create mode 100644 src/progs/pickit1/base/pickit1_prog.h create mode 100644 src/progs/pickit1/gui/Makefile.am create mode 100644 src/progs/pickit1/gui/pickit1_group_ui.cpp create mode 100644 src/progs/pickit1/gui/pickit1_group_ui.h create mode 100644 src/progs/pickit1/pickit1.pro create mode 100644 src/progs/pickit1/xml/Makefile.am create mode 100644 src/progs/pickit1/xml/xml.pro create mode 100644 src/progs/pickit1/xml/xml_pickit1_parser.cpp create mode 100644 src/progs/pickit2/Makefile.am create mode 100644 src/progs/pickit2/base/Makefile.am create mode 100644 src/progs/pickit2/base/base.pro create mode 100644 src/progs/pickit2/base/pickit.cpp create mode 100644 src/progs/pickit2/base/pickit.h create mode 100644 src/progs/pickit2/base/pickit2.cpp create mode 100644 src/progs/pickit2/base/pickit2.h create mode 100644 src/progs/pickit2/base/pickit2.xml create mode 100644 src/progs/pickit2/base/pickit2_data.h create mode 100644 src/progs/pickit2/base/pickit2_prog.cpp create mode 100644 src/progs/pickit2/base/pickit2_prog.h create mode 100644 src/progs/pickit2/base/pickit_prog.cpp create mode 100644 src/progs/pickit2/base/pickit_prog.h create mode 100644 src/progs/pickit2/gui/Makefile.am create mode 100644 src/progs/pickit2/gui/pickit2_group_ui.cpp create mode 100644 src/progs/pickit2/gui/pickit2_group_ui.h create mode 100644 src/progs/pickit2/pickit2.pro create mode 100644 src/progs/pickit2/xml/Makefile.am create mode 100644 src/progs/pickit2/xml/xml.pro create mode 100644 src/progs/pickit2/xml/xml_pickit2_parser.cpp create mode 100644 src/progs/pickit2_bootloader/Makefile.am create mode 100644 src/progs/pickit2_bootloader/base/Makefile.am create mode 100644 src/progs/pickit2_bootloader/base/base.pro create mode 100644 src/progs/pickit2_bootloader/base/pickit2_bootloader.cpp create mode 100644 src/progs/pickit2_bootloader/base/pickit2_bootloader.h create mode 100644 src/progs/pickit2_bootloader/base/pickit2_bootloader.xml create mode 100644 src/progs/pickit2_bootloader/base/pickit2_bootloader_data.h create mode 100644 src/progs/pickit2_bootloader/base/pickit2_bootloader_prog.cpp create mode 100644 src/progs/pickit2_bootloader/base/pickit2_bootloader_prog.h create mode 100644 src/progs/pickit2_bootloader/gui/Makefile.am create mode 100644 src/progs/pickit2_bootloader/gui/pickit2_bootloader_ui.cpp create mode 100644 src/progs/pickit2_bootloader/gui/pickit2_bootloader_ui.h create mode 100644 src/progs/pickit2_bootloader/pickit2_bootloader.pro create mode 100644 src/progs/pickit2_bootloader/xml/Makefile.am create mode 100644 src/progs/pickit2_bootloader/xml/xml.pro create mode 100644 src/progs/pickit2_bootloader/xml/xml_pickit2_bootloader_parser.cpp create mode 100644 src/progs/pickit2v2/Makefile.am create mode 100644 src/progs/pickit2v2/base/Makefile.am create mode 100644 src/progs/pickit2v2/base/base.pro create mode 100644 src/progs/pickit2v2/base/pickit2v2.cpp create mode 100644 src/progs/pickit2v2/base/pickit2v2.h create mode 100644 src/progs/pickit2v2/base/pickit2v2_data.cpp create mode 100644 src/progs/pickit2v2/base/pickit2v2_data.h create mode 100644 src/progs/pickit2v2/base/pickit2v2_prog.cpp create mode 100644 src/progs/pickit2v2/base/pickit2v2_prog.h create mode 100644 src/progs/pickit2v2/gui/Makefile.am create mode 100644 src/progs/pickit2v2/gui/pickit2v2_group_ui.cpp create mode 100644 src/progs/pickit2v2/gui/pickit2v2_group_ui.h create mode 100644 src/progs/pickit2v2/pickit2v2.pro create mode 100644 src/progs/progs.pro create mode 100644 src/progs/psp/Makefile.am create mode 100644 src/progs/psp/base/Makefile.am create mode 100644 src/progs/psp/base/base.pro create mode 100644 src/progs/psp/base/psp.cpp create mode 100644 src/progs/psp/base/psp.h create mode 100644 src/progs/psp/base/psp.xml create mode 100644 src/progs/psp/base/psp_data.h create mode 100644 src/progs/psp/base/psp_prog.cpp create mode 100644 src/progs/psp/base/psp_prog.h create mode 100644 src/progs/psp/base/psp_serial.cpp create mode 100644 src/progs/psp/base/psp_serial.h create mode 100644 src/progs/psp/gui/Makefile.am create mode 100644 src/progs/psp/gui/psp_group_ui.cpp create mode 100644 src/progs/psp/gui/psp_group_ui.h create mode 100644 src/progs/psp/psp.pro create mode 100644 src/progs/psp/xml/Makefile.am create mode 100644 src/progs/psp/xml/xml.pro create mode 100644 src/progs/psp/xml/xml_psp_parser.cpp create mode 100644 src/progs/sdcdb/Makefile create mode 100644 src/progs/sdcdb/Makefile.am create mode 100644 src/progs/sdcdb/base/Makefile create mode 100644 src/progs/sdcdb/base/Makefile.am create mode 100644 src/progs/sdcdb/base/base.pro create mode 100644 src/progs/sdcdb/base/sdcdb_debug.cpp create mode 100644 src/progs/sdcdb/base/sdcdb_debug.h create mode 100644 src/progs/sdcdb/sdcdb.pro create mode 100644 src/progs/tbl_bootloader/Makefile.am create mode 100644 src/progs/tbl_bootloader/base/Makefile.am create mode 100644 src/progs/tbl_bootloader/base/base.pro create mode 100644 src/progs/tbl_bootloader/base/tbl_bootloader.cpp create mode 100644 src/progs/tbl_bootloader/base/tbl_bootloader.h create mode 100644 src/progs/tbl_bootloader/base/tbl_bootloader.xml create mode 100644 src/progs/tbl_bootloader/base/tbl_bootloader_data.h create mode 100644 src/progs/tbl_bootloader/base/tbl_bootloader_prog.cpp create mode 100644 src/progs/tbl_bootloader/base/tbl_bootloader_prog.h create mode 100644 src/progs/tbl_bootloader/gui/Makefile.am create mode 100644 src/progs/tbl_bootloader/gui/tbl_bootloader_ui.cpp create mode 100644 src/progs/tbl_bootloader/gui/tbl_bootloader_ui.h create mode 100644 src/progs/tbl_bootloader/tbl_bootloader.pro create mode 100644 src/progs/tbl_bootloader/xml/Makefile.am create mode 100644 src/progs/tbl_bootloader/xml/xml.pro create mode 100644 src/progs/tbl_bootloader/xml/xml_tbl_bootloader_parser.cpp create mode 100644 src/src.pro create mode 100644 src/tools/Makefile.am create mode 100644 src/tools/base/Makefile.am create mode 100644 src/tools/base/generic_tool.cpp create mode 100644 src/tools/base/generic_tool.h create mode 100644 src/tools/base/tool_group.cpp create mode 100644 src/tools/base/tool_group.h create mode 100644 src/tools/boost/Makefile.am create mode 100644 src/tools/boost/boost.cpp create mode 100644 src/tools/boost/boost.h create mode 100644 src/tools/boost/boost_config.cpp create mode 100644 src/tools/boost/boost_config.h create mode 100644 src/tools/boost/boost_generator.cpp create mode 100644 src/tools/boost/boost_generator.h create mode 100644 src/tools/boost/boostbasic.cpp create mode 100644 src/tools/boost/boostbasic.h create mode 100644 src/tools/boost/boostc.cpp create mode 100644 src/tools/boost/boostc.h create mode 100644 src/tools/boost/boostc_compile.cpp create mode 100644 src/tools/boost/boostc_compile.h create mode 100644 src/tools/boost/boostcpp.cpp create mode 100644 src/tools/boost/boostcpp.h create mode 100644 src/tools/boost/gui/Makefile.am create mode 100644 src/tools/boost/gui/boost_ui.cpp create mode 100644 src/tools/boost/gui/boost_ui.h create mode 100644 src/tools/c18/Makefile.am create mode 100644 src/tools/c18/c18.cpp create mode 100644 src/tools/c18/c18.h create mode 100644 src/tools/c18/c18_compile.cpp create mode 100644 src/tools/c18/c18_compile.h create mode 100644 src/tools/c18/c18_config.cpp create mode 100644 src/tools/c18/c18_config.h create mode 100644 src/tools/c18/gui/Makefile.am create mode 100644 src/tools/c18/gui/c18_ui.cpp create mode 100644 src/tools/c18/gui/c18_ui.h create mode 100644 src/tools/cc5x/Makefile.am create mode 100644 src/tools/cc5x/cc5x.cpp create mode 100644 src/tools/cc5x/cc5x.h create mode 100644 src/tools/cc5x/cc5x_compile.cpp create mode 100644 src/tools/cc5x/cc5x_compile.h create mode 100644 src/tools/cc5x/cc5x_config.cpp create mode 100644 src/tools/cc5x/cc5x_config.h create mode 100644 src/tools/cc5x/gui/Makefile.am create mode 100644 src/tools/cc5x/gui/cc5x_ui.cpp create mode 100644 src/tools/cc5x/gui/cc5x_ui.h create mode 100644 src/tools/ccsc/Makefile.am create mode 100644 src/tools/ccsc/ccsc.cpp create mode 100644 src/tools/ccsc/ccsc.h create mode 100644 src/tools/ccsc/ccsc_compile.cpp create mode 100644 src/tools/ccsc/ccsc_compile.h create mode 100644 src/tools/ccsc/ccsc_config.cpp create mode 100644 src/tools/ccsc/ccsc_config.h create mode 100644 src/tools/ccsc/gui/Makefile.am create mode 100644 src/tools/ccsc/gui/ccsc_ui.cpp create mode 100644 src/tools/ccsc/gui/ccsc_ui.h create mode 100644 src/tools/custom/Makefile.am create mode 100644 src/tools/custom/custom.cpp create mode 100644 src/tools/custom/custom.h create mode 100644 src/tools/gputils/Makefile.am create mode 100644 src/tools/gputils/gputils.cpp create mode 100644 src/tools/gputils/gputils.h create mode 100644 src/tools/gputils/gputils_compile.cpp create mode 100644 src/tools/gputils/gputils_compile.h create mode 100644 src/tools/gputils/gputils_config.cpp create mode 100644 src/tools/gputils/gputils_config.h create mode 100644 src/tools/gputils/gputils_generator.cpp create mode 100644 src/tools/gputils/gputils_generator.h create mode 100644 src/tools/gputils/gui/Makefile.am create mode 100644 src/tools/gputils/gui/gputils_ui.cpp create mode 100644 src/tools/gputils/gui/gputils_ui.h create mode 100644 src/tools/gui/Makefile.am create mode 100644 src/tools/gui/tool_config_widget.cpp create mode 100644 src/tools/gui/tool_config_widget.h create mode 100644 src/tools/gui/tool_group_ui.cpp create mode 100644 src/tools/gui/tool_group_ui.h create mode 100644 src/tools/gui/toolchain_config_center.cpp create mode 100644 src/tools/gui/toolchain_config_center.h create mode 100644 src/tools/gui/toolchain_config_widget.cpp create mode 100644 src/tools/gui/toolchain_config_widget.h create mode 100644 src/tools/jal/Makefile.am create mode 100644 src/tools/jal/gui/Makefile.am create mode 100644 src/tools/jal/gui/jal_ui.cpp create mode 100644 src/tools/jal/gui/jal_ui.h create mode 100644 src/tools/jal/jal.cpp create mode 100644 src/tools/jal/jal.h create mode 100644 src/tools/jal/jal_compile.cpp create mode 100644 src/tools/jal/jal_compile.h create mode 100644 src/tools/jal/jal_config.cpp create mode 100644 src/tools/jal/jal_config.h create mode 100644 src/tools/jal/jal_generator.cpp create mode 100644 src/tools/jal/jal_generator.h create mode 100644 src/tools/jalv2/Makefile.am create mode 100644 src/tools/jalv2/gui/Makefile.am create mode 100644 src/tools/jalv2/gui/jalv2_ui.cpp create mode 100644 src/tools/jalv2/gui/jalv2_ui.h create mode 100644 src/tools/jalv2/jalv2.cpp create mode 100644 src/tools/jalv2/jalv2.h create mode 100644 src/tools/jalv2/jalv2_compile.cpp create mode 100644 src/tools/jalv2/jalv2_compile.h create mode 100644 src/tools/jalv2/jalv2_config.cpp create mode 100644 src/tools/jalv2/jalv2_config.h create mode 100644 src/tools/list/Makefile.am create mode 100644 src/tools/list/compile_config.cpp create mode 100644 src/tools/list/compile_config.h create mode 100644 src/tools/list/compile_manager.cpp create mode 100644 src/tools/list/compile_manager.h create mode 100644 src/tools/list/compile_process.cpp create mode 100644 src/tools/list/compile_process.h create mode 100644 src/tools/list/device_info.cpp create mode 100644 src/tools/list/device_info.h create mode 100644 src/tools/list/tool_list.cpp create mode 100644 src/tools/list/tool_list.h create mode 100644 src/tools/list/tools_config_widget.cpp create mode 100644 src/tools/list/tools_config_widget.h create mode 100644 src/tools/mpc/Makefile.am create mode 100644 src/tools/mpc/gui/Makefile.am create mode 100644 src/tools/mpc/gui/mpc_ui.cpp create mode 100644 src/tools/mpc/gui/mpc_ui.h create mode 100644 src/tools/mpc/mpc.cpp create mode 100644 src/tools/mpc/mpc.h create mode 100644 src/tools/mpc/mpc_compile.cpp create mode 100644 src/tools/mpc/mpc_compile.h create mode 100644 src/tools/mpc/mpc_config.cpp create mode 100644 src/tools/mpc/mpc_config.h create mode 100644 src/tools/pic30/Makefile.am create mode 100644 src/tools/pic30/gui/Makefile.am create mode 100644 src/tools/pic30/gui/pic30_ui.cpp create mode 100644 src/tools/pic30/gui/pic30_ui.h create mode 100644 src/tools/pic30/pic30.cpp create mode 100644 src/tools/pic30/pic30.h create mode 100644 src/tools/pic30/pic30_compile.cpp create mode 100644 src/tools/pic30/pic30_compile.h create mode 100644 src/tools/pic30/pic30_config.cpp create mode 100644 src/tools/pic30/pic30_config.h create mode 100644 src/tools/pic30/pic30_generator.cpp create mode 100644 src/tools/pic30/pic30_generator.h create mode 100644 src/tools/picc/Makefile.am create mode 100644 src/tools/picc/gui/Makefile.am create mode 100644 src/tools/picc/gui/picc_ui.cpp create mode 100644 src/tools/picc/gui/picc_ui.h create mode 100644 src/tools/picc/picc.cpp create mode 100644 src/tools/picc/picc.h create mode 100644 src/tools/picc/picc_compile.cpp create mode 100644 src/tools/picc/picc_compile.h create mode 100644 src/tools/picc/picc_config.cpp create mode 100644 src/tools/picc/picc_config.h create mode 100644 src/tools/sdcc/Makefile.am create mode 100644 src/tools/sdcc/gui/Makefile.am create mode 100644 src/tools/sdcc/gui/sdcc_ui.cpp create mode 100644 src/tools/sdcc/gui/sdcc_ui.h create mode 100644 src/tools/sdcc/sdcc.cpp create mode 100644 src/tools/sdcc/sdcc.h create mode 100644 src/tools/sdcc/sdcc_compile.cpp create mode 100644 src/tools/sdcc/sdcc_compile.h create mode 100644 src/tools/sdcc/sdcc_config.cpp create mode 100644 src/tools/sdcc/sdcc_config.h create mode 100644 src/tools/sdcc/sdcc_generator.cpp create mode 100644 src/tools/sdcc/sdcc_generator.h create mode 100644 src/xml_to_data/Makefile.am create mode 100644 src/xml_to_data/device_xml_to_data.cpp create mode 100644 src/xml_to_data/device_xml_to_data.h create mode 100644 src/xml_to_data/prog_xml_to_data.h create mode 100644 src/xml_to_data/xml_to_data.cpp create mode 100644 src/xml_to_data/xml_to_data.h create mode 100644 src/xml_to_data/xml_to_data.pro (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..a0c7233 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,10 @@ +INCLUDES = $(all_includes) +METASOURCES = AUTO +SUBDIRS = common xml_to_data devices piklab-hex coff piklab-coff progs piklab-prog tools data libgui piklab piklab-test + +messages: + $(EXTRACTRC) `find . -name \*.ui -o -name \*.rc` > rc.cpp + LIST=`find . -name \*.h -o -name \*.cpp -o -name \*.c`; \ + if test -n "$$LIST"; then \ + $(XGETTEXT) $$LIST --from-code=UTF-8 -o $(podir)/piklab.pot; \ + fi diff --git a/src/coff/Makefile.am b/src/coff/Makefile.am new file mode 100644 index 0000000..4e5921f --- /dev/null +++ b/src/coff/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = xml base diff --git a/src/coff/base/Makefile.am b/src/coff/base/Makefile.am new file mode 100644 index 0000000..c6ffbab --- /dev/null +++ b/src/coff/base/Makefile.am @@ -0,0 +1,13 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libcoff.la +libcoff_la_LDFLAGS = $(all_libraries) +libcoff_la_SOURCES = coff.cpp gpdis.cpp gpopcode.cpp disassembler.cpp \ + coff_data.cpp text_coff.cpp cdb_parser.cpp coff_archive.cpp coff_object.cpp +libcoff_la_DEPENDENCIES = coff_data.cpp + +noinst_DATA = coff.xml +coff_data.cpp: ../xml/xml_coff_parser coff.xml + ../xml/xml_coff_parser +CLEANFILES = coff_data.cpp diff --git a/src/coff/base/base.pro b/src/coff/base/base.pro new file mode 100644 index 0000000..4b4986c --- /dev/null +++ b/src/coff/base/base.pro @@ -0,0 +1,6 @@ +STOPDIR = ../../.. +include($${STOPDIR}/lib.pro) + +TARGET = coff +HEADERS += gpopcode.h disassembler.h coff.h coff_object.h coff_archive.h text_coff.h coff_data.h cdb_parser.h +SOURCES += gpopcode.cpp gpdis.cpp disassembler.cpp coff.cpp coff_object.cpp coff_archive.cpp text_coff.cpp coff_data.cpp cdb_parser.cpp diff --git a/src/coff/base/cdb_parser.cpp b/src/coff/base/cdb_parser.cpp new file mode 100644 index 0000000..2e38b84 --- /dev/null +++ b/src/coff/base/cdb_parser.cpp @@ -0,0 +1,417 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "cdb_parser.h" + +#include +#include "common/global/pfile.h" + +//---------------------------------------------------------------------------- +const CDB::ScopeType::Data CDB::ScopeType::DATA[Nb_Types] = { + { "G", I18N_NOOP("Global") }, + { "F", I18N_NOOP("File") }, + { "L", I18N_NOOP("Local") }, + { "S", I18N_NOOP("Structure") } // ?? +}; + +const CDB::VarType::Data CDB::VarType::DATA[Nb_Types] = { + { "DA", I18N_NOOP("Array") }, + { "DF", I18N_NOOP("Function") }, + { "DG", I18N_NOOP("Generic Pointer") }, + { "DC", I18N_NOOP("Code Pointer") }, + { "DX", I18N_NOOP("External RAM Pointer") }, + { "DD", I18N_NOOP("Internal RAM Pointer") }, + { "DP", I18N_NOOP("Paged Pointer") }, + { "DI", I18N_NOOP("Upper-128-byte Pointer") }, + { "SL", I18N_NOOP("Long") }, + { "SI", I18N_NOOP("Int") }, + { "SC", I18N_NOOP("Char") }, + { "SS", I18N_NOOP("Short") }, + { "SV", I18N_NOOP("Void") }, + { "SF", I18N_NOOP("Float") }, + { "ST", I18N_NOOP("Structure") }, + { "SX", I18N_NOOP("SBIT") }, + { "SB", I18N_NOOP("Bit Field") } +}; + +const CDB::Sign::Data CDB::Sign::DATA[Nb_Types] = { + { "S", I18N_NOOP("Signed") }, + { "U", I18N_NOOP("Unsigned") } +}; + +const CDB::AddressSpaceType::Data CDB::AddressSpaceType::DATA[Nb_Types] = { + { "A", I18N_NOOP("External Stack") }, + { "B", I18N_NOOP("Internal Stack") }, + { "C", I18N_NOOP("Code") }, + { "D", I18N_NOOP("Code / Static Segment") }, + { "E", I18N_NOOP("Lower-128-byte Internal RAM") }, + { "F", I18N_NOOP("External RAM") }, + { "G", I18N_NOOP("Internal RAM") }, + { "H", I18N_NOOP("Bit Addressable") }, + { "I", I18N_NOOP("SFR Space") }, + { "J", I18N_NOOP("SBIT Space") }, + { "R", I18N_NOOP("Register Space") }, + { "Z", I18N_NOOP("Function or Undefined Space") }, +}; + +//---------------------------------------------------------------------------- +CDB::Object::Object(const PURL::Url &url, Log::Base &log) + : _log(log) +{ + PURL::File file(url, log); + if ( !file.openForRead() ) return; + QStringList lines = file.readLines(); + + for (_line=0; _linefilename, 0); +} + +bool CDB::Object::parse(Scope &scope, QString &name) +{ + QString s; + if ( !readFixedLengthString(s, 1) ) return false; + scope.type = ScopeType::fromKey(s); + switch (scope.type.type()) { + case ScopeType::Structure: + case ScopeType::Global: break; + case ScopeType::File: + case ScopeType::Local: + if ( !readStoppedString(scope.name, '$') ) return false; + break; + case ScopeType::Nb_Types: + logMalformed(i18n("unknown ScopeType")); + return false; + } + if ( !readAndCheckChar('$') ) return false; + if ( !readStoppedString(name, '$') ) return false; + if ( !readAndCheckChar('$') ) return false; + if ( !readUInt(scope.level) ) return false; + if ( !readAndCheckChar('$') ) return false; + if ( !readUInt(scope.block) ) return false; + return true; +} + +bool CDB::Object::parse(TypeChain &typeChain) +{ + uint nb; + if ( !readAndCheckChar('{') ) return false; + if ( !readUInt(nb) ) return false; + if ( !readAndCheckChar('}') ) return false; + QString s; + if ( !readStoppedString(s, ':') ) return false; + QStringList list = QStringList::split(',', s, true); + for (uint i=0; iisInterruptHandler) ) return false; + if ( !readAndCheckChar(',') ) return false; + if ( !readUInt(fr->interruptHandler) ) return false; + if ( !readAndCheckChar(',') ) return false; + if ( !readUInt(fr->registerBank) ) return false; + return true; +} + +bool CDB::Object::parseTypeRecord(Record * &record) +{ + TypeRecord *tr = new TypeRecord; + record = tr; + if ( !readAndCheckChar('F') ) return false; + if ( !readStoppedString(tr->filename, '$') ) return false; + if ( !readAndCheckChar('$') ) return false; + if ( !readStoppedString(tr->name, '[') ) return false; + if ( !readAndCheckChar('[') ) return false; + for (;;) { + TypeMember tm; + if ( !parse(tm) ) return false; + tr->members.append(tm); + if ( _current[_col]==']' ) break; + } + if ( !readAndCheckChar(']') ) return false; + return true; +} + +bool CDB::Object::parseLinkerRecord(Record * &record) +{ + LinkerRecord *lr = new LinkerRecord; + record = lr; + char c; + if ( !readChar(c) ) return false; + switch (c) { + case 'A': + lr->type = LinkerRecord::AsmLine; + if ( !readAndCheckChar('$') ) return false; + if ( !readStoppedString(lr->filename, '$') ) return false; + if ( !readAndCheckChar('$') ) return false; + if ( !readUInt(lr->line) ) return false; + break; + case 'C': + lr->type = LinkerRecord::CLine; + if ( !readAndCheckChar('$') ) return false; + if ( !readStoppedString(lr->filename, '$') ) return false; + if ( !readAndCheckChar('$') ) return false; + if ( !readUInt(lr->line) ) return false; + if ( !readAndCheckChar('$') ) return false; + if ( !readUInt(lr->level) ) return false; + if ( !readAndCheckChar('$') ) return false; + if ( !readUInt(lr->block) ) return false; + break; + case 'X': + lr->type = LinkerRecord::EndAddress; + if ( !parse(lr->scope, lr->name) ) return false; + break; + default: + lr->type = LinkerRecord::Address; + if ( !parse(lr->scope, lr->name) ) return false; + break; + } + if ( !readAndCheckChar(':') ) return false; + if ( !readHex(lr->address) ) return false; + return true; +} diff --git a/src/coff/base/cdb_parser.h b/src/coff/base/cdb_parser.h new file mode 100644 index 0000000..42572ab --- /dev/null +++ b/src/coff/base/cdb_parser.h @@ -0,0 +1,166 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef SDCC_CDB_PARSER_H +#define SDCC_CDB_PARSER_H + +#include "common/common/key_enum.h" +#include "common/global/log.h" +#include "common/global/purl.h" + +namespace CDB +{ + +//---------------------------------------------------------------------------- +class Record +{ +public: +}; + +class ModuleRecord : public Record +{ +public: + QString filename; +}; + +BEGIN_DECLARE_ENUM(ScopeType) + Global = 0, File, Local, Structure +END_DECLARE_ENUM_STD(ScopeType) + +class Scope +{ +public: + ScopeType type; + QString name; // file or function name + uint level, block; +}; + +BEGIN_DECLARE_ENUM(VarType) + Array = 0, Function, GenericPointer, CodePointer, ExternalRamPointer, + InternalRamPointer, PagedPointer, Upper128bytesPointer, Long, Int, Char, + Short, Void, Float, Structure, Sbit, BitField +END_DECLARE_ENUM_STD(VarType) + +class DCLType +{ +public: + VarType type; + uint nb; // for Array and BitField + QString name; // for Structure +}; + +BEGIN_DECLARE_ENUM(Sign) + Signed = 0, Unsigned +END_DECLARE_ENUM_STD(Sign) + +class TypeChain +{ +public: + QValueVector types; + Sign sign; +}; + +BEGIN_DECLARE_ENUM(AddressSpaceType) + ExternalStack = 0, InternalStack, Code, CodeStaticSegment, + Lower128bytesInternalRam, ExternalRam, InternalRam, BitAddressable, + SFR, SBIT, Register, FunctionOrUndefined +END_DECLARE_ENUM_STD(AddressSpaceType) + +class AddressSpace { +public: + AddressSpaceType type; + bool onStack; + uint stackOffset; // valid if onStack is true + QStringList registers; // for Register type +}; + +class SymbolRecord : public Record +{ +public: + QString name; + Scope scope; + TypeChain typeChain; + AddressSpace addressSpace; +}; + +class FunctionRecord : public SymbolRecord +{ +public: + bool isInterruptHandler; + uint interruptHandler, registerBank; // if isInterruptHandler is true +}; + +class TypeMember +{ +public: + uint offset; + SymbolRecord symbol; +}; + +class TypeRecord : public Record +{ +public: + QString filename, name; + QValueVector members; +}; + +class LinkerRecord : public Record +{ +public: + enum Type { Address = 0, EndAddress, AsmLine, CLine, Nb_Types }; + Type type; + Scope scope; // for Address and EndAddress + QString name; // for Address and EndAddress + uint address; + uint line; // for AsmLine and CLine + QString filename; // for AsmLine and CLine + uint block, level; // for CLine +}; + +//---------------------------------------------------------------------------- +class Object +{ +public: + Object(const PURL::Url &url, Log::Base &log); + virtual ~Object(); + +private: + Log::Base &_log; + QString _current; + uint _line, _col; + QValueVector _records; + + void log(Log::LineType type, const QString &message); + void logMalformed(const QString &detail); + bool readBool(bool &b); + bool getUInt(const QString &s, uint &r); + bool readUInt(uint &v); + bool readChar(char &c); + bool readAndCheckChar(char c); + bool getString(const QString &s, QString &r); + bool readStoppedString(QString &s, char stop); + bool readFixedLengthString(QString &s, uint size); + bool readHex(uint &v); + + bool parse(Scope &scope, QString &name); + bool parse(TypeChain &typeChain); + bool parse(TypeRecord &typeRecord); + bool parse(SymbolRecord &sr); + bool parse(AddressSpace &addressSpace); + bool parse(TypeMember &typeMember); + + bool parseModuleRecord(Record * &record); + bool parseFunctionRecord(Record * &record); + bool parseSymbolRecord(Record * &record); + bool parseTypeRecord(Record * &record); + bool parseLinkerRecord(Record * &record); +}; + +} // namespace + +#endif diff --git a/src/coff/base/coff.cpp b/src/coff/base/coff.cpp new file mode 100644 index 0000000..5eaad84 --- /dev/null +++ b/src/coff/base/coff.cpp @@ -0,0 +1,97 @@ +/*************************************************************************** + * Copyright (C) 2006-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "coff.h" + +#include + +#include "common/common/misc.h" +#include "devices/list/device_list.h" +#include "devices/base/device_group.h" +#include "devices/pic/base/pic_register.h" +#include "coff_data.h" +#include "common/global/pfile.h" + +//---------------------------------------------------------------------------- +const CoffType::Data CoffType::DATA[Nb_Types] = { + { "archive", I18N_NOOP("Archive") }, + { "object", I18N_NOOP("Object") } +}; + +const Coff::Format::Data Coff::Format::DATA[Nb_Types] = { + { 0, I18N_NOOP("Old Microchip"), 0x1234, { 20, 16, 40, 18, 16, 12 } }, + { 0, I18N_NOOP("PIC30"), 0x1236, { 20, 28, 40, 18, 8, 10 } }, // from PIC30 binutils "coff.h" file + { 0, I18N_NOOP("New Microchip"), 0x1240, { 20, 18, 40, 20, 16, 12 } } // (C18 >= 3.0) +}; + +CoffType Coff::identify(const PURL::Url &url, Log::Base &log) +{ + PURL::File file(url, log); + if ( !file.openForRead() ) return CoffType::Nb_Types; + QByteArray data = file.readAll(); + if ( log.hasError() ) return CoffType::Nb_Types; + uint offset = 0; + Format format; + Q_UINT32 magic; + return identify(data, offset, log, format, magic); +} + +CoffType Coff::identify(const QByteArray &data, uint &offset, Log::Base &log, Format &format, Q_UINT32 &magic) +{ + QString id = "!\012"; + if ( data.count()>=id.length() ) { + QString s = QString::fromAscii(data.data(), id.length()); + if ( s==id ) { + offset += id.length(); + return CoffType::Archive; + } + } + if ( !getULong(data, offset, 2, log, magic) ) return CoffType::Nb_Types; + log.log(Log::DebugLevel::Extra, QString("COFF format: %1").arg(toHexLabel(magic, 4))); + format = Format::Nb_Types; + FOR_EACH(Format, f) if ( magic==f.data().magic ) format = f; + return CoffType::Object; +} + +//---------------------------------------------------------------------------- +bool Coff::getULong(const QByteArray &data, uint &offset, uint nbBytes, Log::Base &log, Q_UINT32 &v) +{ + bool ok; + v = ::getULong(data, offset, nbBytes, &ok); + if ( !ok ) { + log.log(Log::LineType::Error, i18n("COFF file is truncated (offset: %1 nbBytes: %2 size:%3).").arg(offset).arg(nbBytes).arg(data.count())); + return false; + } + offset += nbBytes; + return true; +} + +bool Coff::getString(const QByteArray &data, uint &offset, uint nbChars, Log::Base &log, QString &name) +{ + if ( !checkAvailable(data, offset, nbChars) ) { + log.log(Log::LineType::Error, i18n("COFF file is truncated (offset: %1 nbBytes: %2 size:%3).").arg(offset).arg(nbChars).arg(data.count())); + return false; + } + name = QString::fromAscii(data.data()+offset, nbChars); + offset += nbChars; + return true; +} + +//---------------------------------------------------------------------------- +bool Coff::Base::initParse(CoffType type, QByteArray &data, uint &offset, Log::Base &log) +{ + PURL::File file(_url, log); + if ( !file.openForRead() ) return false; + data = file.readAll(); + if ( log.hasError() ) return false; + if ( identify(data, offset, log, _format, _magic)!=type ) { + log.log(Log::LineType::Error, i18n("Could not recognize file (magic number is %1).").arg(toHexLabel(_magic, 4))); + return false; + } + return true; +} diff --git a/src/coff/base/coff.h b/src/coff/base/coff.h new file mode 100644 index 0000000..edd0ae5 --- /dev/null +++ b/src/coff/base/coff.h @@ -0,0 +1,64 @@ +/*************************************************************************** + * Copyright (C) 2006-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef COFF_H +#define COFF_H + +#include "common/global/global.h" +#include "devices/pic/base/pic.h" +#include "common/global/purl.h" +#include "common/global/log.h" + +BEGIN_DECLARE_ENUM(CoffType) + Archive = 0, Object +END_DECLARE_ENUM_STD(CoffType) + +//---------------------------------------------------------------------------- +namespace Coff +{ +extern bool getString(const QByteArray &data, uint &offset, uint nbChars, Log::Base &log, QString &name); +extern bool getULong(const QByteArray &data, uint &offset, uint nbBytes, Log::Base &log, Q_UINT32 &v); + +//---------------------------------------------------------------------------- +enum SizeType { HeaderSize = 0, OptHeaderSize, SectionHeaderSize, SymbolSize, + LineNumberSize, RelocationSize, Nb_SizeTypes }; +struct FormatData { + const char *key, *label; + uint magic; + uint sizes[Nb_SizeTypes]; +}; +BEGIN_DECLARE_ENUM(Format) + OldMicrochip = 0, PIC30, NewMicrochip +END_DECLARE_ENUM(Format, FormatData) + +extern CoffType identify(const PURL::Url &url, Log::Base &log); +extern CoffType identify(const QByteArray &data, uint &offset, Log::Base &log, Format &format, Q_UINT32 &magic); + +//---------------------------------------------------------------------------- +class Base +{ +public: + Base(const PURL::Url &url) : _url(url) {} + virtual ~Base() {} + virtual bool parse(Log::Base &log) = 0; + PURL::Url url() const { return _url; } + uint magic() const { return _magic; } + + virtual Log::KeyList information() const = 0; + +protected: + PURL::Url _url; + Format _format; + Q_UINT32 _magic; + + bool initParse(CoffType type, QByteArray &data, uint &offset, Log::Base &log); +}; + +} // namespace + +#endif diff --git a/src/coff/base/coff.xml b/src/coff/base/coff.xml new file mode 100644 index 0000000..229d11a --- /dev/null +++ b/src/coff/base/coff.xml @@ -0,0 +1,342 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/coff/base/coff_archive.cpp b/src/coff/base/coff_archive.cpp new file mode 100644 index 0000000..72a8883 --- /dev/null +++ b/src/coff/base/coff_archive.cpp @@ -0,0 +1,129 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "coff_archive.h" + +//---------------------------------------------------------------------------- +Coff::Member::Member(const QByteArray &data, uint &offset, Log::Base &log) +{ + // parse header + QString s; + if ( !getString(data, offset, 256, log, s) ) return; + int i = s.find('/'); + if ( i==-1 ) { + log.log(Log::LineType::Error, i18n("Member name not terminated by '/' (\"%1\").").arg(s)); + return; + } + _name = s.mid(0, i); + if ( !getString(data, offset, 12, log, s) ) return; // mtime + if ( !getString(data, offset, 10, log, s) ) return; + i = s.find('l'); + if ( i==-1 ) { + log.log(Log::LineType::Error, i18n("File size not terminated by 'l' (\"%1\").").arg(s)); + return; + } + bool ok; + _nbBytes = s.mid(0, i).toUInt(&ok); + if ( !ok ) { + log.log(Log::LineType::Error, i18n("Wrong format for file size \"%1\".").arg(s)); + return; + } + Q_UINT32 v; + if ( !getULong(data, offset, 2, log, v) ) return; + log.log(Log::DebugLevel::Extra, i18n("Magic number: %1").arg(toHexLabel(v, 4))); +// if ( v!=0x600A ) { +// log.log(Log::LineType::Error, i18n("Wrong magic for Microchip archive (\"%1\").").arg(toHexLabel(v, 4))); +// return; +// } + offset += _nbBytes; +} + +//---------------------------------------------------------------------------- +Coff::Archive::Archive(const PURL::Url &url) + : Base(url) +{} + +bool Coff::Archive::parse(Log::Base &log) +{ + QByteArray data; + uint offset = 0, symbolEnd = 0; + Member *symbol = 0; + if ( !initParse(CoffType::Archive, data, offset, log) ) return false; + for (;;) { + if ( offset==uint(data.count()) ) break; // end of archive + uint start = offset; + Member *member = new Member(data, offset, log); + if ( log.hasError() ) return false; + if ( member->name().isEmpty() ) { + symbolEnd = offset; + symbol = member; + } else { + _members[member->name()] = member; + _offsets[start] = member; + } + } + if (symbol) { + if ( !readSymbols(data, symbolEnd - symbol->nbBytes(), log) ) return false; + delete symbol; + } + return true; +} + +Coff::Archive::~Archive() +{ + QMap::const_iterator it; + for (it=_members.begin(); it!=_members.end(); ++it) delete it.data(); +} + +bool Coff::Archive::readSymbols(const QByteArray &data, uint offset, Log::Base &log) +{ + Q_UINT32 nb; + if ( !getULong(data, offset, 4, log, nb) ) return false; + QValueVector members(nb); + for (uint i=0; i::const_iterator it; + for (it=members().begin(); it!=members().end(); ++it) + keys.append(it.key(), i18n("size: %1 bytes").arg(it.data()->nbBytes())); + return keys; +} + +Log::KeyList Coff::Archive::symbolsInformation() const +{ + Log::KeyList keys(i18n("Symbols:")); + QMap::const_iterator it; + for (it=symbols().begin(); it!=symbols().end(); ++it) + keys.append(it.key(), it.data()->name()); + return keys; +} diff --git a/src/coff/base/coff_archive.h b/src/coff/base/coff_archive.h new file mode 100644 index 0000000..ba43a38 --- /dev/null +++ b/src/coff/base/coff_archive.h @@ -0,0 +1,53 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef COFF_ARCHIVE_H +#define COFF_ARCHIVE_H + +#include "coff.h" + +namespace Coff +{ +//---------------------------------------------------------------------------- +class Member +{ +public: + Member(const QByteArray &data, uint &offset, Log::Base &log); + QString name() const { return _name; } + uint nbBytes() const { return _nbBytes; } + +private: + QString _name; + uint _nbBytes; +}; + +//---------------------------------------------------------------------------- +class Archive : public Base +{ +public: + Archive(const PURL::Url &url); + virtual ~Archive(); + virtual bool parse(Log::Base &log); + const QMapmembers() const { return _members; } + const QMapsymbols() const { return _symbols; } + + virtual Log::KeyList information() const; + Log::KeyList membersInformation() const; + Log::KeyList symbolsInformation() const; + +private: + QMap _members; // name -> Member * + QMap _offsets; // offset -> Member * + QMap _symbols; // name -> Member * + + bool readSymbols(const QByteArray &data, uint offset, Log::Base &log); +}; + +} // namespace + +#endif diff --git a/src/coff/base/coff_data.h b/src/coff/base/coff_data.h new file mode 100644 index 0000000..9676e42 --- /dev/null +++ b/src/coff/base/coff_data.h @@ -0,0 +1,22 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef COFF_DATA_H +#define COFF_DATA_H + +namespace Coff +{ + enum { MAX_NB_IDS = 2 }; + struct Data { + uint ids[MAX_NB_IDS]; + }; + extern QString findId(uint id); + +} // namespace + +#endif diff --git a/src/coff/base/coff_object.cpp b/src/coff/base/coff_object.cpp new file mode 100644 index 0000000..f4109f9 --- /dev/null +++ b/src/coff/base/coff_object.cpp @@ -0,0 +1,658 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "coff_object.h" + +#include "common/common/misc.h" +#include "devices/list/device_list.h" +#include "devices/base/device_group.h" +#include "devices/pic/base/pic_register.h" +#include "coff_data.h" +#include "common/global/pfile.h" + +//---------------------------------------------------------------------------- +bool Coff::getName(const QByteArray &data, uint &offset, uint nbChars, uint stringTableOffset, + Log::Base &log, QString &name) +{ + Q_UINT32 v; + if ( !getULong(data, offset, 4, log, v) ) return false; + if ( v!=0 ) { // name is not in string table + offset -= 4; + return getString(data, offset, nbChars, log, name); + } + if ( !getULong(data, offset, 4, log, v) ) return false; + // ### do a sanity check here + name = QString(data.data()+stringTableOffset+v); + return true; +} + +const Coff::OptHeaderFormat::Data Coff::OptHeaderFormat::DATA[Nb_Types] = { + { 0, I18N_NOOP("Old Microchip") }, + { 0, I18N_NOOP("New Microchip") }, + { 0, I18N_NOOP("PICC Compiler") }, + { 0, I18N_NOOP("CCS Compiler") } +}; + +const Coff::OptHeaderData Coff::OPT_HEADER_DATA[] = { + { 0x5678, OptHeaderFormat::OldMicrochip, true }, + { 0x0000, OptHeaderFormat::NewMicrochip, true }, + { 0x0001, OptHeaderFormat::NewMicrochip, true }, // PIC30 with debug + { 0x1388, OptHeaderFormat::Picc, false }, // PICC + { 0x1B78, OptHeaderFormat::Ccsc, false }, // CCSC + { 0x0000, OptHeaderFormat::Nb_Types, false } +}; + +//---------------------------------------------------------------------------- +const Coff::AuxSymbolType::Data Coff::AuxSymbolType::DATA[Nb_Types] = { + { 0, I18N_NOOP("Direct") }, + { 0, I18N_NOOP("File") }, + { 0, I18N_NOOP("Indentifier") }, + { 0, I18N_NOOP("Section") } +}; + +Coff::AuxSymbol *Coff::AuxSymbol::factory(const Object &object, AuxSymbolType type, const QByteArray &data, uint offset, uint stringTableOffset, Log::Base &log) +{ + switch (type.type()) { + case AuxSymbolType::Direct: return new AuxSymbolDirect(object, data, offset, stringTableOffset, log); + case AuxSymbolType::File: return new AuxSymbolFile(object, data, offset, stringTableOffset, log); + case AuxSymbolType::Identifier: return new AuxSymbolIdentifier(object, data, offset, stringTableOffset, log); + case AuxSymbolType::Section: return new AuxSymbolSection(object, data, offset, stringTableOffset, log); + case AuxSymbolType::Nb_Types: return new AuxSymbolUnknown(object); + } + Q_ASSERT(false); + return 0; +} + +Coff::AuxSymbolDirect::AuxSymbolDirect(const Object &object, const QByteArray &data, uint start, uint stringTableOffset, Log::Base &log) + : AuxSymbol(object) +{ + uint offset = start; + Q_UINT32 v; + if ( !getULong(data, offset, 1, log, v) ) return; + _command = v; + if ( !getULong(data, offset, 4, log, v) ) return; + _string = QString(data.data()+stringTableOffset+v); +} + +Coff::AuxSymbolFile::AuxSymbolFile(const Object &object, const QByteArray &data, uint start, uint stringTableOffset, Log::Base &log) + : AuxSymbol(object) +{ + uint offset = start; + Q_UINT32 v; + if ( object.format()==Format::PIC30 ) { + if ( !getName(data, offset, 14, stringTableOffset, log, _filename) ) return; + _line = 0; + } else { + if ( !getULong(data, offset, 4, log, v) ) return; + _filename = QString(data.data()+stringTableOffset+v); + if ( !getULong(data, offset, 4, log, v) ) return; + _line = v; + } +} + +Coff::AuxSymbolIdentifier::AuxSymbolIdentifier(const Object &object, const QByteArray &data, uint start, uint stringTableOffset, Log::Base &log) + : AuxSymbol(object) +{ + uint offset = start; + Q_UINT32 v; + if ( !getULong(data, offset, 4, log, v) ) return; + _string = QString(data.data()+stringTableOffset+v); +} + +Coff::AuxSymbolSection::AuxSymbolSection(const Object &object, const QByteArray &data, uint start, uint, Log::Base &log) + : AuxSymbol(object) +{ + uint offset = start; + Q_UINT32 v; + if ( !getULong(data, offset, 4, log, v) ) return; + _length = v; + if ( !getULong(data, offset, 2, log, v) ) return; + _nbRelocations = v; + if ( !getULong(data, offset, 2, log, v) ) return; + _nbLineNumbers = v; +} + +//---------------------------------------------------------------------------- +const Coff::SymbolSectionType::Data Coff::SymbolSectionType::DATA[Nb_Types] = { + { 0, I18N_NOOP("Inside Section") }, + { 0, I18N_NOOP("Undefined Section") }, + { 0, I18N_NOOP("Absolute Value") }, + { 0, I18N_NOOP("Debug Symbol") } +}; + +const Coff::SymbolClass::Data Coff::SymbolClass::DATA[Nb_Types] = { + { 0, I18N_NOOP("Automatic Variable"), 1 }, + { 0, I18N_NOOP("External Symbol"), 2 }, + { 0, I18N_NOOP("Static Symbol"), 3 }, + { 0, I18N_NOOP("Register Variable"), 4 }, + { 0, I18N_NOOP("External Definition"), 5 }, + { 0, I18N_NOOP("Label"), 6 }, + { 0, I18N_NOOP("Undefined Label"), 7 }, + { 0, I18N_NOOP("Member of Structure"), 8 }, + { 0, I18N_NOOP("Function Argument"), 9 }, + { 0, I18N_NOOP("Structure Tag"), 10 }, + { 0, I18N_NOOP("Member of Union"), 11 }, + { 0, I18N_NOOP("Union Tag"), 12 }, + { 0, I18N_NOOP("Type Definition"), 13 }, + { 0, I18N_NOOP("Undefined Static"), 14 }, + { 0, I18N_NOOP("Enumeration Tag"), 15 }, + { 0, I18N_NOOP("Member of Enumeration"), 16 }, + { 0, I18N_NOOP("Register Parameter"), 17 }, + { 0, I18N_NOOP("Bit Field"), 18 }, + { 0, I18N_NOOP("Auto Argument"), 19 }, + { 0, I18N_NOOP("Dummy Entry (end of block)"), 20 }, + { 0, I18N_NOOP("Beginning or End of Block"), 100 }, + { 0, I18N_NOOP("Beginning or End of Function"), 101 }, + { 0, I18N_NOOP("End of Structure"), 102 }, + { 0, I18N_NOOP("Filename"), 103 }, + { 0, I18N_NOOP("Line Number"), 104 }, + { 0, I18N_NOOP("Duplicate Tag"), 105 }, + { 0, I18N_NOOP("Section"), 109 } +}; + +const Coff::SymbolType::Data Coff::SymbolType::DATA[Nb_Types] = { + { 0, I18N_NOOP("Void"), 0x0001 }, + { 0, I18N_NOOP("Char"), 0x0010 }, + { 0, I18N_NOOP("Short"), 0x0011 }, + { 0, I18N_NOOP("Int"), 0x0100 }, + { 0, I18N_NOOP("Long"), 0x0101 }, + { 0, I18N_NOOP("Float"), 0x0110 }, + { 0, I18N_NOOP("Double"), 0x0111 }, + { 0, I18N_NOOP("Structure"), 0x1000 }, + { 0, I18N_NOOP("Union"), 0x1001 }, + { 0, I18N_NOOP("Enumeration"), 0x1010 }, + { 0, I18N_NOOP("Member Of Enumeration"), 0x1011 }, + { 0, I18N_NOOP("Unsigned Char"), 0x1100 }, + { 0, I18N_NOOP("Unsigned Short"), 0x1101 }, + { 0, I18N_NOOP("Unsigned Int"), 0x1110 }, + { 0, I18N_NOOP("Unsigned Long"), 0x1111 }, + { 0, I18N_NOOP("Long Double"), 0x10000 } +}; + +const Coff::SymbolDerivedType::Data Coff::SymbolDerivedType::DATA[Nb_Types] = { + { 0, I18N_NOOP("Pointer"), 0x010000 }, + { 0, I18N_NOOP("Function"), 0x100000 }, + { 0, I18N_NOOP("Array"), 0x110000 } +}; + +Coff::Symbol::Symbol(const Object &object, const QByteArray &data, uint start, + uint stringTableOffset, const QString &lastFilename, Log::Base &log) + : BaseSymbol(object) +{ + uint offset = start; + Q_UINT32 v; + if ( !getName(data, offset, 8, stringTableOffset, log, _name) ) return; + if ( !getULong(data, offset, 4, log, v) ) return; + _value = v; + if ( !getULong(data, offset, 2, log, v) ) return; + _section = v; + uint nb = (object.format()==Format::NewMicrochip ? 4 : 2); + if ( !getULong(data, offset, nb, log, v) ) return; + _type = SymbolType::Nb_Types; + FOR_EACH(SymbolType, type) + if ( (v & 0x001111)==type.data().id ) { _type = type; break; } + _dtype = SymbolDerivedType::Nb_Types; + FOR_EACH(SymbolDerivedType, dtype) + if ( (v & 0x110000)==dtype.data().id ) { _dtype = dtype; break; } + if ( !getULong(data, offset, 1, log, v) ) return; + _sclass = SymbolClass::Nb_Types; + FOR_EACH(SymbolClass, sclass) + if ( v==sclass.data().id ) { _sclass = sclass; break; } + if ( !getULong(data, offset, 1, log, v) ) return; + uint nbAux = v; + //qDebug("symbol: %s value=%s type=%i dtype=%i class=%i nbAux=%i section=%i", _name.latin1(), toHexLabel(_value, 4).latin1(), _type, _dtype, _class, nbAux, _section); + + AuxSymbolType auxType = AuxSymbolType::Nb_Types; + if ( _name==".direct" ) auxType = AuxSymbolType::Direct; + else if ( _name==".ident" ) auxType = AuxSymbolType::Identifier; + else if ( _sclass==SymbolClass::Filename ) auxType = AuxSymbolType::File; + else if ( _sclass==SymbolClass::Section ) auxType = AuxSymbolType::Section; + if ( auxType!=AuxSymbolType::Nb_Types && nbAux==0 ) log.log(Log::LineType::Warning, i18n("Symbol without needed auxilliary symbol (type=%1)").arg(auxType.type())); + Q_ASSERT( (offset-start)==object.size(SymbolSize) ); + _aux.resize(nbAux); + for (uint i=0; itype()==AuxSymbolType::File ) _filename = static_cast(_aux[i])->filename(); +} + +Coff::SymbolSectionType Coff::Symbol::sectionType() const +{ + switch (_section) { + case 0x0000: return SymbolSectionType::UndefinedSection; + case 0xFFFF: return SymbolSectionType::AbsoluteValue; + case 0xFFFE: return SymbolSectionType::DebugSymbol; + } + return SymbolSectionType::InsideSection; +} + +//---------------------------------------------------------------------------- +Coff::Relocation::Relocation(const Object &object, const Section §ion, + const QByteArray &data, uint start, Log::Base &log) + : Element(object), _symbol(0) +{ + uint offset = start; + Q_UINT32 v; + if ( !getULong(data, offset, 4, log, v) ) return; + _address = v; + if ( _address>section.size() ) log.log(Log::LineType::Warning, i18n("Relocation address beyong section size: %1/%2").arg(v).arg(section.size())); + if ( !getULong(data, offset, 4, log, v) ) return; + if ( v>=object.nbSymbols() ) { + log.log(Log::LineType::Error, i18n("Relocation has unknown symbol: %1").arg(v)); + return; + } + if ( object.symbol(v)->isAuxSymbol() ) { + log.log(Log::LineType::Error, i18n("Relocation is an auxiliary symbol: %1").arg(v)); + return; + } + _symbol = static_cast(object.symbol(v)); + if ( object.format()!=Format::PIC30 ) { + if ( !getULong(data, offset, 2, log, v) ) return; + _offset = short(v); + } + if ( !getULong(data, offset, 2, log, v) ) return; + _type = v; + //qDebug("reloc %s: address=%s offset=%i type=%i", _symbol->_name.latin1(), toHexLabel(_address, 4).latin1(), _offset, _type); +} + +//---------------------------------------------------------------------------- +Coff::CodeLine::CodeLine(const Object &object, const Section §ion, + const QByteArray &data, uint start, const QString &lastFilename, Log::Base &log) + : Element(object), _section(section), _symbol(0) +{ + uint offset = start; + Q_UINT32 v; + if ( !getULong(data, offset, 4, log, v) ) return; + uint tmp = v; + if ( object.format()==Format::PIC30 ) { + if ( !getULong(data, offset, 4, log, v) ) return; + _line = v; + if ( _line!=0 ) { + _address = tmp; + _filename = lastFilename; + //qDebug("code line %i: %s", _line, toHexLabel(_address, nbChars(_address)).latin1()); + } else { + if ( tmp>=object.nbSymbols() ) { + log.log(Log::LineType::Error, i18n("Codeline has unknown symbol: %1").arg(tmp)); + return; + } + if ( object.symbol(tmp)->isAuxSymbol() ) { + log.log(Log::LineType::Error, i18n("Codeline is an auxiliary symbol: %1").arg(tmp)); + return; + } + _symbol = static_cast(object.symbol(tmp)); + _filename = _symbol->filename(); + //qDebug("code line %i: %s", _line, _symbol->_name.latin1()); + } + } else { + if ( tmp>=object.nbSymbols() ) { + log.log(Log::LineType::Error, i18n("Codeline has unknown symbol: %1").arg(tmp)); + return; + } + if ( object.symbol(tmp)->isAuxSymbol() ) { + log.log(Log::LineType::Error, i18n("Codeline is an auxiliary symbol: %1").arg(tmp)); + return; + } + _symbol = static_cast(object.symbol(tmp)); + _filename = _symbol->filename(); + if ( !getULong(data, offset, 2, log, v) ) return; + _line = v; + if ( object.optHeaderFormat()==OptHeaderFormat::Picc && _line>=2 ) _line -= 2; // #### ?? + if ( !getULong(data, offset, 4, log, v) ) return; + _address = v; + if ( !getULong(data, offset, 2, log, v) ) return; + // flags + if ( !getULong(data, offset, 4, log, v) ) return; + // function index + //qDebug("code line %i: %s", _line, toHexLabel(_address, nbChars(_address)).latin1()); + } +// if ( _symbol && _symbol->_class!=Symbol::CFile ) +// log.log(Log::LineType::Warning, i18n("Line without file symbol associated (%1:%2 %3).") +// .arg(_section._name).arg(toHexLabel(_address, nbChars(_address))).arg(_symbol->_class)); +} + +//---------------------------------------------------------------------------- +const Coff::SectionType::Data Coff::SectionType::DATA[Nb_Types] = { + { 0, I18N_NOOP("Config") }, + { 0, I18N_NOOP("Device ID") }, + { 0, I18N_NOOP("User IDs") }, + { 0, I18N_NOOP("Uninitialized Data") }, + { 0, I18N_NOOP("Initialized Data") }, + { 0, I18N_NOOP("Rom Data") }, + { 0, I18N_NOOP("Code") } +}; + +Coff::Section::Section(const Device::Data &device, const Object &object, + const QByteArray &data, uint start, uint stringTableOffset, Log::Base &log) + : Element(object) +{ + uint offset = start; + Q_UINT32 v; + if ( !getName(data, offset, 8, stringTableOffset, log, _name) ) return; + if ( !getULong(data, offset, 4, log, v) ) return; + _address = v; + if ( !getULong(data, offset, 4, log, v) ) return; + //if ( _address!=v ) log.log(Log::LineType::Warning, i18n("Virtual address (%1) does not match physical address (%2) in %3.") + // .arg(toHexLabel(v, 4)).arg(toHexLabel(_address, 4)).arg(_name)); + if ( !getULong(data, offset, 4, log, v) ) return; + _size = v; + if ( !getULong(data, offset, 4, log, v) ) return; + uint dataOffset = v; + if ( !getULong(data, offset, 4, log, v) ) return; + uint relocationOffset = v; + if ( !getULong(data, offset, 4, log, v) ) return; + uint lineNumberOffset = v; + if ( !getULong(data, offset, 2, log, v) ) return; + uint nbRelocations = v; + if ( !getULong(data, offset, 2, log, v) ) return; + uint nbLineNumbers = v; + if ( !getULong(data, offset, 4, log, v) ) return; + _flags = v; + + // read data + Q_ASSERT ( device.group().name()=="pic" ); + const Pic::Data &pdata = static_cast(device); + //qDebug("section %s: address=%s size=%i flags=%i", _name.data(), toHexLabel(_address, 4).latin1(), _size, int(_flags)); + if ( _size!=0 && dataOffset!=0 ) { + uint inc = 1; + uint nbWords = _size; + uint nbBytesWord = 1; + bool b = ( (_flags & FText) || (_flags & FDataRom) ); + if (b) { + nbBytesWord = pdata.nbBytesWord(Pic::MemoryRangeType::Code); + nbWords /= nbBytesWord; + inc = pdata.addressIncrement(Pic::MemoryRangeType::Code); + } + for (uint i=0; ifilename(); + lineNumberOffset += object.size(LineNumberSize); + if ( log.hasError() ) return; + } + } +} + +Coff::Section::~Section() +{ + for (uint i=0; ifilename().isEmpty() ) lastFilename = s->filename(); + _symbols[i] = s; + _msymbols[s->name()] = s; + _symbolOffset += size(SymbolSize); + for (uint k=0; kauxSymbols().count()); k++) { + i++; + _symbols[i] = s->auxSymbols()[k]; + _symbolOffset += size(SymbolSize); + } + } + + // parse sections + Q_ASSERT( offset==(size(HeaderSize) + size(OptHeaderSize)) ); + _sections.resize(_nbSections); + for (uint i=0; i<_nbSections; i++) { + _sections[i] = new Section(*_device, *this, data, offset, stringTableOffset, log); + offset += size(SectionHeaderSize); + if ( log.hasError() ) return false; + } + + // extract filenames + for (uint i=0; i<_nbSymbols; i++) { + if ( _symbols[i]==0 || _symbols[i]->isAuxSymbol() ) continue; + QString s = static_cast(_symbols[i])->filename(); + if ( s.isEmpty() || s=="fake" || _filenames.contains(s) ) continue; + _filenames.append(s); + } + + // extract variables + for (uint i=0; iisAuxSymbol() ) continue; + const Symbol *sym = static_cast(_symbols[i]); + if ( sym->symbolClass()!=SymbolClass::Static ) continue; + if ( sym->sectionType()!=SymbolSectionType::InsideSection ) continue; + QString name = sym->name(); + if ( name.startsWith("_$_") || name.startsWith("__") || name.startsWith(".") ) continue; // special variables (?) + _variables[name] = sym->value() & 0xFFF; // #### ?? + } + + return true; +} + +bool Coff::Object::parseHeader(const QByteArray &data, uint &offset, Log::Base &log) +{ + Q_UINT32 v; + if ( !getULong(data, offset, 2, log, v) ) return false; + _nbSections = v; + if ( !getULong(data, offset, 4, log, v) ) return false; +// time_t time = v; + if ( !getULong(data, offset, 4, log, v) ) return false; + _symbolOffset = v; + if ( !getULong(data, offset, 4, log, v) ) return false; + _nbSymbols = v; + if ( !getULong(data, offset, 2, log, v) ) return false; + if ( v!=size(OptHeaderSize) ) { + log.log(Log::LineType::Error, i18n("Optionnal header size is not %1: %2").arg(size(OptHeaderSize)).arg(v)); + return false; + } + if ( !getULong(data, offset, 2, log, v) ) return false; + _flags = Flags(v); + return true; +} + +bool Coff::Object::parseOptionnalHeader(const QByteArray &data, uint &offset, Log::Base &log) +{ + Q_UINT32 v; + int nb = (_format==Format::NewMicrochip ? 4 : 2); + if ( !getULong(data, offset, nb, log, v) ) return false; // version stamp + if ( _format==Format::PIC30 ) { + if ( !getULong(data, offset, 4, log, v) ) return false; // text size in bytes, padded to firmware boundary + if ( !getULong(data, offset, 4, log, v) ) return false; // initialized data " + if ( !getULong(data, offset, 4, log, v) ) return false; // uninitialized data " + if ( !getULong(data, offset, 4, log, v) ) return false; // entry point + if ( !getULong(data, offset, 4, log, v) ) return false; // offset of text + if ( !getULong(data, offset, 4, log, v) ) return false; // offset of data + if ( _device==0 ) _device = Device::lister().data("30F2010"); // for e.g. + } else { + if ( !getULong(data, offset, 4, log, v) ) return false; + // #### at least for C18 compiler, it can be compiled for generic processor: in such case + // the pic type will be 18C452 in non-extended mode and 18F4620 for extended mode... + QString name = Coff::findId(v); + log.log(Log::DebugLevel::Normal, QString("Device name: \"%1\"").arg(name)); + if ( name.isEmpty() ) { + log.log(Log::DebugLevel::Normal, QString("Unknown processor type: %1").arg(toHexLabel(v, 4))); + log.log(Log::LineType::Error, i18n("Could not determine processor (%1).").arg(toHexLabel(v, 4))); + return false; + } else if ( _device==0 ) _device = Device::lister().data(name); + else if ( name!=_device->name() ) log.log(Log::DebugLevel::Normal, QString("Different processor name: %1").arg(name)); + if ( !getULong(data, offset, 4, log, v) ) return false; + const Pic::Data *pdata = static_cast(_device); + if (pdata) { + uint nbBits = pdata->nbBitsWord(Pic::MemoryRangeType::Code) / pdata->addressIncrement(Pic::MemoryRangeType::Code); + if ( v!=nbBits ) log.log(Log::DebugLevel::Normal, QString("Rom width is not %1: %2").arg(nbBits).arg(v)); + } + if ( !getULong(data, offset, 4, log, v) ) return false; + if (pdata) { + uint nbBits = pdata->registersData().nbBits(); + if ( v!=nbBits ) log.log(Log::DebugLevel::Normal, QString("Ram width is not %1: %2").arg(nbBits).arg(v)); + } + } + return true; +} + +Coff::Object::~Object() +{ + for (uint i=0; i::const_iterator it; + for (it=_variables.begin(); it!=_variables.end(); ++it) + if ( it.data()==address ) return it.key(); + return QString::null; +} + +//---------------------------------------------------------------------------- +QValueVector Pic::sfrList(const Pic::Data &data) +{ + QValueVector list; + const Pic::RegistersData &rdata = data.registersData(); + for (uint i=0; i::const_iterator it; + for (it=rdata.combined.begin(); it!=rdata.combined.end(); ++it) { + Register::TypeData td(it.key(), it.data().address, it.data().nbChars); + list.append(Pic::RegisterNameData(it.key(), td)); + } + if ( data.architecture()==Pic::Architecture::P16X ) + list.append(Pic::RegisterNameData("WREG", Register::TypeData("WREG", rdata.nbChars()))); + qHeapSort(list); + return list; +} + +QValueVector Pic::gprList(const Pic::Data &data, const Coff::Object *coff) +{ + QValueVector list; + const Pic::RegistersData &rdata = data.registersData(); + for (uint i=0; ivariableName(address); + if ( !name.isEmpty() ) s += " (" + name + ")"; + } + Register::TypeData rtd(address, rdata.nbChars()); + list.append(Pic::RegisterNameData(s, rtd)); + } + } + return list; +} + +QValueVector Pic::variableList(const Pic::Data &data, const Coff::Object &coff) +{ + QValueVector list; + const Pic::RegistersData &rdata = data.registersData(); + QMap variables = coff.variables(); + QMap::const_iterator vit; + for (vit=variables.begin(); vit!=variables.end(); ++vit) { + Register::TypeData rtd(vit.data(), rdata.nbChars()); + list.append(Pic::RegisterNameData(vit.key() + " (" + toHexLabel(vit.data(), rdata.nbCharsAddress()) + ")", rtd)); + } + qHeapSort(list); + return list; +} diff --git a/src/coff/base/coff_object.h b/src/coff/base/coff_object.h new file mode 100644 index 0000000..8b98129 --- /dev/null +++ b/src/coff/base/coff_object.h @@ -0,0 +1,322 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef COFF_OBJECT_H +#define COFF_OBJECT_H + +#include "coff.h" +#include "devices/base/register.h" + +namespace Coff +{ +//---------------------------------------------------------------------------- +extern bool getName(const QByteArray &data, uint &offset, uint nbChars, uint stringTableOffset, Log::Base &log, QString &name); +extern int disassemble(long int opcode, long int opcode2, int org, Pic::Architecture architecture, char *buffer, size_t sizeof_buffer); + +BEGIN_DECLARE_ENUM(OptHeaderFormat) + OldMicrochip = 0, NewMicrochip, Picc, Ccsc +END_DECLARE_ENUM_STD(OptHeaderFormat) + +struct OptHeaderData { + uint magic; + OptHeaderFormat optHeaderFormat; + bool parsed; +}; +extern const OptHeaderData OPT_HEADER_DATA[]; + +class Object; +class Section; + +//---------------------------------------------------------------------------- +class Element +{ +public: + Element(const Object &object) : _object(object) {} + virtual ~Element() {} + +protected: + const Object &_object; +}; + +//---------------------------------------------------------------------------- +class BaseSymbol : public Element +{ +public: + BaseSymbol(const Object &object) : Element(object) {} + virtual bool isAuxSymbol() const = 0; +}; + +BEGIN_DECLARE_ENUM(AuxSymbolType) + Direct = 0, File, Identifier, Section +END_DECLARE_ENUM_STD(AuxSymbolType) + +class AuxSymbol : public BaseSymbol +{ +public: + virtual bool isAuxSymbol() const { return true; } + static AuxSymbol *factory(const Object &object, AuxSymbolType type, const QByteArray &data, + uint offset, uint stringTableOffset, Log::Base &log); + +public: + AuxSymbol(const Object &object) : BaseSymbol(object) {} + virtual AuxSymbolType type() const = 0; +}; + +class AuxSymbolDirect : public AuxSymbol +{ +public: + AuxSymbolDirect(const Object &object, const QByteArray &data, uint offset, uint stringTableOffset, Log::Base &log); + virtual AuxSymbolType type() const { return AuxSymbolType::Direct; } + +private: + uchar _command; + QString _string; +}; + +class AuxSymbolFile : public AuxSymbol +{ +public: + AuxSymbolFile(const Object &object, const QByteArray &data, uint offset, uint stringTableOffset, Log::Base &log); + virtual AuxSymbolType type() const { return AuxSymbolType::File; } + QString filename() const { return _filename; } + uint line() const { return _line; } + +private: + uint _line; + QString _filename; +}; + +class AuxSymbolIdentifier : public AuxSymbol +{ +public: + AuxSymbolIdentifier(const Object &object, const QByteArray &data, uint offset, uint stringTableOffset, Log::Base &log); + virtual AuxSymbolType type() const { return AuxSymbolType::Identifier; } + QString string() const { return _string; } + +private: + QString _string; +}; + +class AuxSymbolSection : public AuxSymbol +{ +public: + AuxSymbolSection(const Object &object, const QByteArray &data, uint offset, uint stringTableOffset, Log::Base &log); + virtual AuxSymbolType type() const { return AuxSymbolType::Section; } + +private: + uint _length, _nbRelocations, _nbLineNumbers; +}; + +class AuxSymbolUnknown : public AuxSymbol +{ +public: + AuxSymbolUnknown(const Object &object) : AuxSymbol(object) {} + virtual AuxSymbolType type() const { return AuxSymbolType::Nb_Types; } +}; + +//---------------------------------------------------------------------------- +BEGIN_DECLARE_ENUM(SymbolSectionType) + InsideSection = 0, UndefinedSection, AbsoluteValue, DebugSymbol +END_DECLARE_ENUM_STD(SymbolSectionType) + +struct SymbolClassData { + const char *key, *label; + uint id; +}; +BEGIN_DECLARE_ENUM(SymbolClass) + Automatic = 0, External, Static, Register, ExternalDefinition, + Label, UndefinedLabel, MemberOfStructure, FunctionArgument, StructureTag, + MemberOfUnion, UnionTag, TypeDefinition, UndefinedStatic, EnumerationTag, + MemberOfEnumeration, RegisterParameter, BitField, AutoArgument, EndOfBlock, + BeginEndOfBlock, BeginEndOfFunction, EndOfStructure, Filename, LineNumber, + DuplicateTag, Section +END_DECLARE_ENUM(SymbolClass, SymbolClassData) + +struct SymbolTypeData { + const char *key, *label; + uint id; +}; +BEGIN_DECLARE_ENUM(SymbolType) + Void = 0, Char, Short, Int, Long, Float, Double, Struct, Union, + Enum, MemberOfEnum, UChar, UShort, UInt, ULong, LongDouble +END_DECLARE_ENUM(SymbolType, SymbolTypeData) + +struct SymbolDerivedTypeData { + const char *key, *label; + uint id; +}; +BEGIN_DECLARE_ENUM(SymbolDerivedType) + Pointer = 0, Function, Array +END_DECLARE_ENUM(SymbolDerivedType, SymbolDerivedTypeData) + +class Symbol : public BaseSymbol +{ +public: + Symbol(const Object &object, const QByteArray &data, uint offset, uint stringTableOffset, + const QString &lastFilename, Log::Base &log); + virtual bool isAuxSymbol() const { return false; } + QString name() const { return _name; } + QString filename() const { return _filename; } + const QValueVector &auxSymbols() const { return _aux; } + SymbolClass symbolClass() const { return _sclass; } + SymbolSectionType sectionType() const; + SymbolType type() const { return _type; } + SymbolDerivedType derivedType() const { return _dtype; } + uint value() const { return _value; } + uint section() const { Q_ASSERT( sectionType()==SymbolSectionType::InsideSection ); return _section; } + +private: + QString _name, _filename; + uint _value, _section; + SymbolClass _sclass; + SymbolType _type; + SymbolDerivedType _dtype; + QValueVector _aux; +}; + +//---------------------------------------------------------------------------- +class Relocation : public Element +{ +public: + Relocation(const Object &object, const Section §ion, const QByteArray &data, + uint offset, Log::Base &log); + +private: + ulong _address, _type; + short _offset; + const Symbol *_symbol; +}; + +//---------------------------------------------------------------------------- +class CodeLine : public Element +{ +public: + CodeLine(const Object &object, const Section §ion, const QByteArray &data, + uint offset, const QString &lastFilename, Log::Base &log); + const Section §ion() const { return _section; } + QString filename() const { return _filename; } + uint line() const { return _line; } + Address address() const { return _address; } + const Symbol *symbol() const { return _symbol; } + +private: + const Section &_section; + uint _line; + Address _address; + QString _filename; + const Symbol *_symbol; +}; + +//---------------------------------------------------------------------------- +BEGIN_DECLARE_ENUM(SectionType) + Config = 0, DeviceId, UserIds, UninitializedData, InitializedData, DataRom, Code +END_DECLARE_ENUM_STD(SectionType) + +class Section : public Element +{ +public: + class InstructionData { + public: + BitValue value; + QString opcode, disasm; + }; + +public: + Section(const Device::Data &device, const Object &object, const QByteArray &data, uint offset, + uint stringTableOffset, Log::Base &log); + ~Section(); + SectionType type() const; + QString name() const { return _name; } + Address address() const { return _address; } + uint size() const { return _size; } + uint flags() const { return _flags; } + const QMap &instructions() const { return _instructions; } + const QValueVector &relocations() const { return _relocations; } + const QValueVector &lines() const { return _lines; } + +private: + QString _name; + Address _address; + uint _size, _flags; + QMap _instructions; + QValueVector _relocations; + QValueVector _lines; + + enum Flag { FText = 0x00020, FData = 0x00040, FBSS = 0x00080, FDataRom = 0x00100, + FAbs = 0x01000, FShared = 0x02000, FOverlay = 0x04000, FAccess = 0x08000, + FActivationRecord = 0x10000 }; +}; + +//---------------------------------------------------------------------------- +class Object : public Base +{ +public: + Object(const Device::Data *device, const PURL::Url &url); + virtual ~Object(); + virtual bool parse(Log::Base &log); + Format format() const { return _format; } + const Device::Data *device() const { return _device; } + uint size(SizeType stype) const { return _format.data().sizes[stype]; } + OptHeaderFormat optHeaderFormat() const { return _optHeaderFormat; } + uint optHeaderMagic() const { return _optHeaderMagic; } + uint nbSymbols() const { return _symbols.count(); } + const BaseSymbol *symbol(uint i) const { return _symbols[i]; } + const Symbol *symbol(const QString &name) const { return (_msymbols.contains(name) ? _msymbols[name] : 0); } + uint nbSections() const { return _sections.count(); } + const Section *section(uint i) const { return _sections[i]; } + const QStringList &filenames() const { return _filenames; } + const QMap &variables() const { return _variables; } + QString variableName(Address address) const; + + enum Flag { RelocationStripped = 0x0001, Executable = 0x0002, LineNumberStripped = 0x0004, + SymbolStripped = 0x0080, Extended18 = 0x4000, Generic = 0x8000 }; + Q_DECLARE_FLAGS(Flags, Flag) + +protected: + Q_UINT32 _optHeaderMagic; + OptHeaderFormat _optHeaderFormat; + const Device::Data *_device; + uint _nbSections, _nbSymbols, _symbolOffset; + Flags _flags; + QValueVector _symbols; + QMap _msymbols; // name -> Symbol * + QValueVector
_sections; + QStringList _filenames; + QMap _variables; // name -> address + + virtual bool parseHeader(const QByteArray &data, uint &offset, Log::Base &log); + virtual bool parseOptionnalHeader(const QByteArray &data, uint &offset, Log::Base &log); +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(Object::Flags) + +} // namespace + +//---------------------------------------------------------------------------- +namespace Pic +{ + +class RegisterNameData +{ +public: + RegisterNameData() {} + RegisterNameData(const QString &label, const Register::TypeData &data) : _label(label), _data(data) {} + QString label() const { return _label; } + const Register::TypeData &data() const { return _data; } + bool operator <(const RegisterNameData &rnd) const { return _label sfrList(const Pic::Data &data); +extern QValueVector gprList(const Pic::Data &data, const Coff::Object *coff); +extern QValueVector variableList(const Pic::Data &data, const Coff::Object &coff); + +} // namespace + +#endif diff --git a/src/coff/base/disassembler.cpp b/src/coff/base/disassembler.cpp new file mode 100644 index 0000000..663c163 --- /dev/null +++ b/src/coff/base/disassembler.cpp @@ -0,0 +1,289 @@ +/*************************************************************************** + * Copyright (C) 2006-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "disassembler.h" + +#include + +#include "devices/base/device_group.h" +#include "devices/pic/pic/pic_memory.h" +#include "coff_object.h" + +//----------------------------------------------------------------------------- +QString SourceLine::comment(PURL::SourceFamily family, const QString &text) +{ + switch (family.type()) { + case PURL::SourceFamily::Asm: return "; " + text; + case PURL::SourceFamily::C: return "/* " + text + " */"; + case PURL::SourceFamily::JAL: return "-- " + text; + case PURL::SourceFamily::Cpp: return "// " + text; + case PURL::SourceFamily::Basic: return "' " + text; + case PURL::SourceFamily::Nb_Types: break; + } + Q_ASSERT(false); + return QString::null; +} + +namespace SourceLine +{ +class LineData { +public: + LineData() : group(-1) {} + QString text, comment; + int group; +}; +} // namespace + +QStringList SourceLine::lines(PURL::SourceFamily family, const List &list, uint nbSpaces) +{ + QValueList lines; + QValueList groupCommentColumn; + groupCommentColumn.append(0); + List::const_iterator it; + for (it=list.begin(); it!=list.end(); ++it) { + LineData data; + switch((*it).type) { + case Indented: + data.text = repeat(" ", nbSpaces); + case NotIndented: + if ( (*it).code.isEmpty() && !(*it).comment.isEmpty() ) data.text += comment(family, (*it).comment); + else { + data.text += (*it).code; + data.comment = (*it).comment; + data.group = groupCommentColumn.count() - 1; + groupCommentColumn[data.group] = qMax(groupCommentColumn[data.group], uint(data.text.length())); + } + break; + case Separator: + data.text = comment(family, "-----------------------------------------------------------------------"); + groupCommentColumn.append(0); + break; + case Empty: + break; + case Title: + data.text = comment(family, (*it).comment); + break; + } + lines += data; + } + QStringList slines; + QValueList::const_iterator lit; + for (lit=lines.begin(); lit!=lines.end(); ++lit) { + if ( (*lit).group==-1 || (*lit).comment.isEmpty() ) slines += (*lit).text; + else { + uint col = groupCommentColumn[(*lit).group] + 1; + slines += (*lit).text.leftJustify(col, ' ') + comment(family, (*lit).comment); + } + } + return slines; +} + +QString SourceLine::text(PURL::SourceFamily family, const List &list, uint nbSpaces) +{ + return lines(family, list, nbSpaces).join("\n") + "\n"; +} + +QString SourceLine::transformConfigName(const Pic::Data &data, uint wordIndex, const QString &name) +{ + if ( !data.is18Family() ) return name; + bool ok; + (void)fromHexLabel(name, &ok); + if (ok) return name; + QString s = name + '_'; + if ( data.name()=="18C601" || data.name()=="18C801" || data.name().startsWith("18F" ) ) + s += QString::number(wordIndex/2+1) + (wordIndex%2==0 ? 'L' : 'H'); + else s += QString::number(wordIndex); + return s; +} + +QStringList SourceLine::ignoredConfigNames(const Pic::Data &data, uint wordIndex) +{ + QStringList cnames; + const QStringList &names = data.config()._words[wordIndex].ignoredCNames; + for (uint i=0; i=0; l--) { + const Pic::Config::Value &cvalue = cmask.values[l]; + if ( !cvalue.value.isInside(v) ) continue; + QStringList vcnames = cvalue.configNames[type]; + if ( vcnames.isEmpty() && type!=Pic::ConfigNameType::Default ) vcnames = cvalue.configNames[Pic::ConfigNameType::Default]; + for (uint i=0; i"); + return lines; +} + +SourceLine::List GPUtils::generateConfigLines(const Pic::Memory &memory, bool &ok) +{ + SourceLine::List lines; + const Pic::Data &data = memory.device(); + const Pic::Config &config = data.config(); + for (uint i=0; i * + * * + * 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. * + ***************************************************************************/ +#ifndef DISASSEMBLER_H +#define DISASSEMBLER_H + +#include "common/common/purl_base.h" +#include "devices/pic/base/pic_config.h" +namespace Device { class Data; class Memory; } +namespace Pic { class Data; class Memory; } + +//----------------------------------------------------------------------------- +namespace SourceLine +{ + +enum Type { Indented, NotIndented, Title, Separator, Empty }; + +class Data { +public: + Data(Type _type = Empty, const QString &_code = QString::null, const QString &_comment = QString::null) + : type(_type), code(_code), comment(_comment) {} + Type type; + QString code, comment; +}; + +class List : public QValueList +{ +public: + List() {} + void appendSeparator() { append(Separator); } + void appendEmpty() { append(Empty); } + void appendTitle(const QString &text) { append(Data(Title, QString::null, text)); } + void appendIndentedCode(const QString &code, const QString &comment = QString::null) { append(Data(Indented, code, comment)); } + void appendNotIndentedCode(const QString &code, const QString &comment = QString::null) { append(Data(NotIndented, code, comment)); } +}; + +extern QString comment(PURL::SourceFamily family, const QString &text); +extern QStringList lines(PURL::SourceFamily family, const List &list, uint nbSpaces); +extern QString text(PURL::SourceFamily family, const List &list, uint nbSpaces); +extern QString transformConfigName(const Pic::Data &data, uint wordIndex, const QString &name); +extern QStringList ignoredConfigNames(const Pic::Data &data, uint wordIndex); +extern QStringList extraConfigNames(const Pic::Data &data, uint wordIndex, const Pic::Config::Value &value); +extern QStringList configNames(Pic::ConfigNameType type, const Pic::Memory &memory, uint word, bool &ok); + +} // namespace + +//----------------------------------------------------------------------------- +namespace GPUtils +{ + +extern QString toDeviceName(const QString &device); +extern SourceLine::List includeLines(const Device::Data &data); +extern SourceLine::List generateConfigLines(const Pic::Memory &memory, bool &ok); +extern SourceLine::List disassemble(const Pic::Memory &memory); + +} // namespace + +//----------------------------------------------------------------------------- +namespace Tool +{ + +class SourceGenerator +{ +public: + SourceGenerator() {} + virtual ~SourceGenerator() {} + virtual SourceLine::List configLines(PURL::ToolType type, const Device::Memory &memory, bool &ok) const = 0; + SourceLine::List templateSourceFile(PURL::ToolType type, const Device::Data &data, bool &ok) const; + virtual SourceLine::List sourceFileContent(PURL::ToolType type, const Device::Data &data, bool &ok) const = 0; + virtual SourceLine::List includeLines(PURL::ToolType type, const Device::Data &data) const = 0; +}; + +} // namespace + +#endif diff --git a/src/coff/base/gpdis.cpp b/src/coff/base/gpdis.cpp new file mode 100644 index 0000000..2df4f24 --- /dev/null +++ b/src/coff/base/gpdis.cpp @@ -0,0 +1,349 @@ +/* Disassemble memory + Copyright (C) 2001, 2002, 2003, 2004, 2005 + Craig Franklin + +This file is part of gputils. + +gputils 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, or (at your option) +any later version. + +gputils 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 gputils; see the file COPYING. If not, write to +the Free Software Foundation, 51 Franklin Street, Fifth Floor, +Boston, MA 02110-1301, USA. */ + +#include +#include "devices/pic/base/pic.h" +#include "coff_object.h" +#include "gpopcode.h" + +#define DECODE_ARG0 snprintf(buffer, sizeof_buffer, "%s", instruction->name) + +#define DECODE_ARG1(ARG1) snprintf(buffer, sizeof_buffer, "%s\t%#lx", \ + instruction->name,\ + ARG1) + +#define DECODE_ARG1WF(ARG1, ARG2) snprintf(buffer, sizeof_buffer, "%s\t%#lx, %s", \ + instruction->name,\ + ARG1, \ + (ARG2 ? "f" : "w")) + +#define DECODE_ARG2(ARG1, ARG2) snprintf(buffer, sizeof_buffer, "%s\t%#lx, %#lx", \ + instruction->name,\ + ARG1, \ + ARG2) + +#define DECODE_ARG3(ARG1, ARG2, ARG3) snprintf(buffer, sizeof_buffer, "%s\t%#lx, %#lx, %#lx", \ + instruction->name,\ + ARG1, \ + ARG2, \ + ARG3) + +bool gp_decode_mnemonics = false; +bool gp_decode_extended = false; + +int Coff::disassemble(long int opcode, long int opcode2, + int org, + Pic::Architecture architecture, + char *buffer, + size_t sizeof_buffer) +{ + int i; + int value; + struct insn *instruction = NULL; + int num_words = 1; + + switch (architecture.type()) { + case Pic::Architecture::P24F: + case Pic::Architecture::P24H: + case Pic::Architecture::P30F: + case Pic::Architecture::P33F: + snprintf(buffer, sizeof_buffer, "--"); + return 0; + case Pic::Architecture::P10X: + for(i = 0; i < num_op_12c5xx; i++) { + if((op_12c5xx[i].mask & opcode) == op_12c5xx[i].opcode) { + instruction = &op_12c5xx[i]; + break; + } + } + break; +/* case PROC_CLASS_SX: + for(i = 0; i < num_op_sx; i++) { + if((op_sx[i].mask & opcode) == op_sx[i].opcode) { + instruction = &op_sx[i]; + break; + } + } + break; +*/ + case Pic::Architecture::P16X: + for(i = 0; i < num_op_16cxx; i++) { + if((op_16cxx[i].mask & opcode) == op_16cxx[i].opcode) { + instruction = &op_16cxx[i]; + break; + } + } + break; + case Pic::Architecture::P17C: + for(i = 0; i < num_op_17cxx; i++) { + if((op_17cxx[i].mask & opcode) == op_17cxx[i].opcode) { + instruction = &op_17cxx[i]; + break; + } + } + break; + case Pic::Architecture::P18C: + case Pic::Architecture::P18F: + case Pic::Architecture::P18J: + if (gp_decode_mnemonics) { + for(i = 0; i < num_op_18cxx_sp; i++) { + if((op_18cxx_sp[i].mask & opcode) == op_18cxx_sp[i].opcode) { + instruction = &op_18cxx_sp[i]; + break; + } + } + } + if (instruction == NULL) { + for(i = 0; i < num_op_18cxx; i++) { + if((op_18cxx[i].mask & opcode) == op_18cxx[i].opcode) { + instruction = &op_18cxx[i]; + break; + } + } + } + if ((instruction == NULL) && (gp_decode_extended)) { + /* might be from the extended instruction set */ + for(i = 0; i < num_op_18cxx_ext; i++) { + if((op_18cxx_ext[i].mask & opcode) == op_18cxx_ext[i].opcode) { + instruction = &op_18cxx_ext[i]; + break; + } + } + } + break; + default: + assert(0); + } + + if (instruction == NULL) { + snprintf(buffer, sizeof_buffer, "dw\t%#lx ;unknown opcode", opcode); + return num_words; + } + + switch (instruction->classType) + { + case INSN_CLASS_LIT3_BANK: + DECODE_ARG1((opcode & 0x7) << 5); + break; + case INSN_CLASS_LIT3_PAGE: + DECODE_ARG1((opcode & 0x7) << 9); + break; + case INSN_CLASS_LIT1: + DECODE_ARG1(opcode & 1); + break; + case INSN_CLASS_LIT4: + DECODE_ARG1(opcode & 0xf); + break; + case INSN_CLASS_LIT4S: + DECODE_ARG1((opcode & 0xf0) >> 4); + break; + case INSN_CLASS_LIT6: + DECODE_ARG1(opcode & 0x3f); + break; + case INSN_CLASS_LIT8: + case INSN_CLASS_LIT8C12: + case INSN_CLASS_LIT8C16: + DECODE_ARG1(opcode & 0xff); + break; + case INSN_CLASS_LIT9: + DECODE_ARG1(opcode & 0x1ff); + break; + case INSN_CLASS_LIT11: + DECODE_ARG1(opcode & 0x7ff); + break; + case INSN_CLASS_LIT13: + DECODE_ARG1(opcode & 0x1fff); + break; + case INSN_CLASS_LITFSR: + DECODE_ARG2(((opcode >> 6) & 0x3), (opcode & 0x3f)); + break; + case INSN_CLASS_RBRA8: + value = opcode & 0xff; + /* twos complement number */ + if (value & 0x80) { + value = -((value ^ 0xff) + 1); + } + DECODE_ARG1((unsigned long)(org + value + 1) * 2); + break; + case INSN_CLASS_RBRA11: + value = opcode & 0x7ff; + /* twos complement number */ + if (value & 0x400) { + value = -((value ^ 0x7ff) + 1); + } + DECODE_ARG1((unsigned long)(org + value + 1) * 2); + break; + case INSN_CLASS_LIT20: + { + long int dest; + + num_words = 2; + dest = (opcode2 & 0xfff) << 8; + dest |= opcode & 0xff; + DECODE_ARG1(dest * 2); + } + break; + case INSN_CLASS_CALL20: + { + long int dest; + + num_words = 2; + dest = (opcode2 & 0xfff) << 8; + dest |= opcode & 0xff; + snprintf(buffer, sizeof_buffer, "%s\t%#lx, %#lx", + instruction->name, + dest * 2, + (opcode >> 8) & 1); + } + break; + case INSN_CLASS_FLIT12: + { + long int k; + long int file; + + num_words = 2; + k = opcode2 & 0xff; + k |= ((opcode & 0xf) << 8); + file = (opcode >> 4) & 0x3; + DECODE_ARG2(file, k); + } + break; + case INSN_CLASS_FF: + { + long int file1; + long int file2; + + num_words = 2; + file1 = opcode & 0xfff; + file2 = opcode2 & 0xfff; + DECODE_ARG2(file1, file2); + } + break; + case INSN_CLASS_FP: + DECODE_ARG2((opcode & 0xff), ((opcode >> 8) & 0x1f)); + break; + case INSN_CLASS_PF: + DECODE_ARG2(((opcode >> 8) & 0x1f), (opcode & 0xff)); + break; + case INSN_CLASS_SF: + { + long int offset; + long int file; + + num_words = 2; + offset = opcode & 0x7f; + file = opcode2 & 0xfff; + DECODE_ARG2(offset, file); + } + break; + case INSN_CLASS_SS: + { + long int offset1; + long int offset2; + + num_words = 2; + offset1 = opcode & 0x7f; + offset2 = opcode2 & 0x7f; + DECODE_ARG2(offset1, offset2); + } + break; + case INSN_CLASS_OPF5: + DECODE_ARG1(opcode & 0x1f); + break; + case INSN_CLASS_OPWF5: + DECODE_ARG1WF((opcode & 0x1f), ((opcode >> 5) & 1)); + break; + case INSN_CLASS_B5: + DECODE_ARG2((opcode & 0x1f), ((opcode >> 5) & 7)); + break; + case INSN_CLASS_B8: + DECODE_ARG2((opcode & 0xff), ((opcode >> 8) & 7)); + break; + case INSN_CLASS_OPF7: + DECODE_ARG1(opcode & 0x7f); + break; + case INSN_CLASS_OPF8: + DECODE_ARG1(opcode & 0xff); + break; + case INSN_CLASS_OPWF7: + DECODE_ARG1WF((opcode & 0x7f), ((opcode >> 7) & 1)); + break; + case INSN_CLASS_OPWF8: + DECODE_ARG1WF((opcode & 0xff), ((opcode >> 8) & 1)); + break; + case INSN_CLASS_B7: + DECODE_ARG2((opcode & 0x7f), ((opcode >> 7) & 7)); + break; + case INSN_CLASS_OPFA8: + DECODE_ARG2((opcode & 0xff), ((opcode >> 8) & 1)); + break; + case INSN_CLASS_BA8: + DECODE_ARG3((opcode & 0xff), ((opcode >> 9) & 7), ((opcode >> 8) & 1)); + break; + case INSN_CLASS_OPWFA8: + DECODE_ARG3((opcode & 0xff), ((opcode >> 9) & 1), ((opcode >> 8) & 1)); + break; + case INSN_CLASS_IMPLICIT: + DECODE_ARG0; + break; + case INSN_CLASS_TBL: + { + char op[5]; + + switch(opcode & 0x3) + { + case 0: + strncpy(op, "*", sizeof(op)); + break; + case 1: + strncpy(op, "*+", sizeof(op)); + break; + case 2: + strncpy(op, "*-", sizeof(op)); + break; + case 3: + strncpy(op, "+*", sizeof(op)); + break; + default: + assert(0); + } + + snprintf(buffer, + sizeof_buffer, + "%s\t%s", + instruction->name, + op); + } + break; + case INSN_CLASS_TBL2: + DECODE_ARG2(((opcode >> 9) & 1), (opcode & 0xff)); + break; + case INSN_CLASS_TBL3: + DECODE_ARG3(((opcode >> 9) & 1), + ((opcode >> 8) & 1), + (opcode & 0xff)); + break; + default: + assert(0); + } + + return num_words; +} diff --git a/src/coff/base/gpopcode.cpp b/src/coff/base/gpopcode.cpp new file mode 100644 index 0000000..87cb3b4 --- /dev/null +++ b/src/coff/base/gpopcode.cpp @@ -0,0 +1,348 @@ +/* GNU PIC opcode definitions + Copyright (C) 2001, 2002, 2003, 2004, 2005 + Craig Franklin + +This file is part of gputils. + +gputils 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, or (at your option) +any later version. + +gputils 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 gputils; see the file COPYING. If not, write to +the Free Software Foundation, 51 Franklin Street, Fifth Floor, +Boston, MA 02110-1301, USA. */ + +#include "gpopcode.h" + +/* FIXME: use const struct */ + +/* PIC 12-bit instruction set */ +struct insn op_12c5xx[] = { + { "addwf", 0xfc0, 0x1c0, INSN_CLASS_OPWF5 }, + { "andlw", 0xf00, 0xe00, INSN_CLASS_LIT8 }, + { "andwf", 0xfc0, 0x140, INSN_CLASS_OPWF5 }, + { "bcf", 0xf00, 0x400, INSN_CLASS_B5 }, + { "bsf", 0xf00, 0x500, INSN_CLASS_B5 }, + { "btfsc", 0xf00, 0x600, INSN_CLASS_B5 }, + { "btfss", 0xf00, 0x700, INSN_CLASS_B5 }, + { "call", 0xf00, 0x900, INSN_CLASS_LIT8C12 }, + { "clrf", 0xfe0, 0x060, INSN_CLASS_OPF5 }, + { "clrw", 0xfff, 0x040, INSN_CLASS_IMPLICIT }, + { "clrwdt", 0xfff, 0x004, INSN_CLASS_IMPLICIT }, + { "comf", 0xfc0, 0x240, INSN_CLASS_OPWF5 }, + { "decf", 0xfc0, 0x0c0, INSN_CLASS_OPWF5 }, + { "decfsz", 0xfc0, 0x2c0, INSN_CLASS_OPWF5 }, + { "goto", 0xe00, 0xa00, INSN_CLASS_LIT9 }, + { "incf", 0xfc0, 0x280, INSN_CLASS_OPWF5 }, + { "incfsz", 0xfc0, 0x3c0, INSN_CLASS_OPWF5 }, + { "iorlw", 0xf00, 0xd00, INSN_CLASS_LIT8 }, + { "iorwf", 0xfc0, 0x100, INSN_CLASS_OPWF5 }, + { "movf", 0xfc0, 0x200, INSN_CLASS_OPWF5 }, + { "movlw", 0xf00, 0xc00, INSN_CLASS_LIT8 }, + { "movwf", 0xfe0, 0x020, INSN_CLASS_OPF5 }, + { "nop", 0xfff, 0x000, INSN_CLASS_IMPLICIT }, + { "option", 0xfff, 0x002, INSN_CLASS_IMPLICIT }, + { "retlw", 0xf00, 0x800, INSN_CLASS_LIT8 }, + { "return", 0xfff, 0x800, INSN_CLASS_IMPLICIT }, /* FIXME: special mnemonic */ + { "rlf", 0xfc0, 0x340, INSN_CLASS_OPWF5 }, + { "rrf", 0xfc0, 0x300, INSN_CLASS_OPWF5 }, + { "sleep", 0xfff, 0x003, INSN_CLASS_IMPLICIT }, + { "subwf", 0xfc0, 0x080, INSN_CLASS_OPWF5 }, + { "swapf", 0xfc0, 0x380, INSN_CLASS_OPWF5 }, + { "tris", 0xff8, 0x000, INSN_CLASS_OPF5 }, + { "xorlw", 0xf00, 0xf00, INSN_CLASS_LIT8 }, + { "xorwf", 0xfc0, 0x180, INSN_CLASS_OPWF5 } +}; + +const int num_op_12c5xx = TABLE_SIZE(op_12c5xx); + +/* Scenix SX has a superset of the PIC 12-bit instruction set */ +/* + * It would be nice if there was a more elegant way to do this, + * either by adding a flags field to struct insn, or by allowing a + * processor to have more than one associated table. + */ +struct insn op_sx[] = { + { "addwf", 0xfc0, 0x1c0, INSN_CLASS_OPWF5 }, + { "andlw", 0xf00, 0xe00, INSN_CLASS_LIT8 }, + { "andwf", 0xfc0, 0x140, INSN_CLASS_OPWF5 }, + { "bank", 0xff8, 0x018, INSN_CLASS_LIT3_BANK }, /* SX only */ + { "bcf", 0xf00, 0x400, INSN_CLASS_B5 }, + { "bsf", 0xf00, 0x500, INSN_CLASS_B5 }, + { "btfsc", 0xf00, 0x600, INSN_CLASS_B5 }, + { "btfss", 0xf00, 0x700, INSN_CLASS_B5 }, + { "call", 0xf00, 0x900, INSN_CLASS_LIT8C12 }, + { "clrf", 0xfe0, 0x060, INSN_CLASS_OPF5 }, + { "clrw", 0xfff, 0x040, INSN_CLASS_IMPLICIT }, + { "clrwdt", 0xfff, 0x004, INSN_CLASS_IMPLICIT }, + { "comf", 0xfc0, 0x240, INSN_CLASS_OPWF5 }, + { "decf", 0xfc0, 0x0c0, INSN_CLASS_OPWF5 }, + { "decfsz", 0xfc0, 0x2c0, INSN_CLASS_OPWF5 }, + { "goto", 0xe00, 0xa00, INSN_CLASS_LIT9 }, + { "incf", 0xfc0, 0x280, INSN_CLASS_OPWF5 }, + { "incfsz", 0xfc0, 0x3c0, INSN_CLASS_OPWF5 }, + { "iorlw", 0xf00, 0xd00, INSN_CLASS_LIT8 }, + { "iorwf", 0xfc0, 0x100, INSN_CLASS_OPWF5 }, + { "iread", 0xfff, 0x041, INSN_CLASS_IMPLICIT }, /* SX only */ + { "mode", 0xff0, 0x050, INSN_CLASS_LIT4 }, /* SX only */ + { "movf", 0xfc0, 0x200, INSN_CLASS_OPWF5 }, + { "movlw", 0xf00, 0xc00, INSN_CLASS_LIT8 }, + { "movmw", 0xfff, 0x042, INSN_CLASS_IMPLICIT }, /* SX only */ + { "movwf", 0xfe0, 0x020, INSN_CLASS_OPF5 }, + { "movwm", 0xfff, 0x043, INSN_CLASS_IMPLICIT }, /* SX only */ + { "nop", 0xfff, 0x000, INSN_CLASS_IMPLICIT }, + { "option", 0xfff, 0x002, INSN_CLASS_IMPLICIT }, + { "page", 0xff8, 0x010, INSN_CLASS_LIT3_PAGE }, /* SX only */ + { "reti", 0xfff, 0x00e, INSN_CLASS_IMPLICIT }, /* SX only */ + { "retiw", 0xfff, 0x00f, INSN_CLASS_IMPLICIT }, /* SX only */ + { "retlw", 0xf00, 0x800, INSN_CLASS_LIT8 }, + { "retp", 0xfff, 0x00d, INSN_CLASS_IMPLICIT }, /* SX only */ + { "return", 0xfff, 0x00c, INSN_CLASS_IMPLICIT }, /* SX only */ + { "rlf", 0xfc0, 0x340, INSN_CLASS_OPWF5 }, + { "rrf", 0xfc0, 0x300, INSN_CLASS_OPWF5 }, + { "sleep", 0xfff, 0x003, INSN_CLASS_IMPLICIT }, + { "subwf", 0xfc0, 0x080, INSN_CLASS_OPWF5 }, + { "swapf", 0xfc0, 0x380, INSN_CLASS_OPWF5 }, + { "tris", 0xff8, 0x000, INSN_CLASS_OPF5 }, + { "xorlw", 0xf00, 0xf00, INSN_CLASS_LIT8 }, + { "xorwf", 0xfc0, 0x180, INSN_CLASS_OPWF5 } +}; + +const int num_op_sx = TABLE_SIZE(op_sx); + +/* PIC 14-bit instruction set */ +struct insn op_16cxx[] = { + { "addlw", 0x3e00, 0x3e00, INSN_CLASS_LIT8 }, + { "addwf", 0x3f00, 0x0700, INSN_CLASS_OPWF7 }, + { "andlw", 0x3f00, 0x3900, INSN_CLASS_LIT8 }, + { "andwf", 0x3f00, 0x0500, INSN_CLASS_OPWF7 }, + { "bcf", 0x3c00, 0x1000, INSN_CLASS_B7 }, + { "bsf", 0x3c00, 0x1400, INSN_CLASS_B7 }, + { "btfsc", 0x3c00, 0x1800, INSN_CLASS_B7 }, + { "btfss", 0x3c00, 0x1c00, INSN_CLASS_B7 }, + { "call", 0x3800, 0x2000, INSN_CLASS_LIT11 }, + { "clrf", 0x3f80, 0x0180, INSN_CLASS_OPF7 }, + { "clrw", 0x3fff, 0x0103, INSN_CLASS_IMPLICIT }, + { "clrwdt", 0x3fff, 0x0064, INSN_CLASS_IMPLICIT }, + { "comf", 0x3f00, 0x0900, INSN_CLASS_OPWF7 }, + { "decf", 0x3f00, 0x0300, INSN_CLASS_OPWF7 }, + { "decfsz", 0x3f00, 0x0b00, INSN_CLASS_OPWF7 }, + { "goto", 0x3800, 0x2800, INSN_CLASS_LIT11 }, + { "incf", 0x3f00, 0x0a00, INSN_CLASS_OPWF7 }, + { "incfsz", 0x3f00, 0x0f00, INSN_CLASS_OPWF7 }, + { "iorlw", 0x3f00, 0x3800, INSN_CLASS_LIT8 }, + { "iorwf", 0x3f00, 0x0400, INSN_CLASS_OPWF7 }, + { "movf", 0x3f00, 0x0800, INSN_CLASS_OPWF7 }, + { "movlw", 0x3c00, 0x3000, INSN_CLASS_LIT8 }, + { "movwf", 0x3f80, 0x0080, INSN_CLASS_OPF7 }, + { "nop", 0x3f9f, 0x0000, INSN_CLASS_IMPLICIT }, + { "option", 0x3fff, 0x0062, INSN_CLASS_IMPLICIT }, + { "retfie", 0x3fff, 0x0009, INSN_CLASS_IMPLICIT }, + { "retlw", 0x3c00, 0x3400, INSN_CLASS_LIT8 }, + { "return", 0x3fff, 0x0008, INSN_CLASS_IMPLICIT }, + { "rlf", 0x3f00, 0x0d00, INSN_CLASS_OPWF7 }, + { "rrf", 0x3f00, 0x0c00, INSN_CLASS_OPWF7 }, + { "sleep", 0x3fff, 0x0063, INSN_CLASS_IMPLICIT }, + { "sublw", 0x3e00, 0x3c00, INSN_CLASS_LIT8 }, + { "subwf", 0x3f00, 0x0200, INSN_CLASS_OPWF7 }, + { "swapf", 0x3f00, 0x0e00, INSN_CLASS_OPWF7 }, + { "tris", 0x3ff8, 0x0060, INSN_CLASS_OPF7 }, + { "xorlw", 0x3f00, 0x3a00, INSN_CLASS_LIT8 }, + { "xorwf", 0x3f00, 0x0600, INSN_CLASS_OPWF7 } +}; + +const int num_op_16cxx = TABLE_SIZE(op_16cxx); + +/* PIC 16-bit instruction set */ +struct insn op_17cxx[] = { + { "addlw", 0xff00, 0xb100, INSN_CLASS_LIT8 }, + { "addwf", 0xfe00, 0x0e00, INSN_CLASS_OPWF8 }, + { "addwfc", 0xfe00, 0x1000, INSN_CLASS_OPWF8 }, + { "andlw", 0xff00, 0xb500, INSN_CLASS_LIT8 }, + { "andwf", 0xfe00, 0x0a00, INSN_CLASS_OPWF8 }, + { "bcf", 0xf800, 0x8800, INSN_CLASS_B8 }, + { "bsf", 0xf800, 0x8000, INSN_CLASS_B8 }, + { "btfsc", 0xf800, 0x9800, INSN_CLASS_B8 }, + { "btfss", 0xf800, 0x9000, INSN_CLASS_B8 }, + { "btg", 0xf800, 0x3800, INSN_CLASS_B8 }, + { "call", 0xe000, 0xe000, INSN_CLASS_LIT13 }, + { "clrf", 0xfe00, 0x2800, INSN_CLASS_OPWF8 }, + { "clrwdt", 0xffff, 0x0004, INSN_CLASS_IMPLICIT }, + { "comf", 0xfe00, 0x1200, INSN_CLASS_OPWF8 }, + { "cpfseq", 0xff00, 0x3100, INSN_CLASS_OPF8 }, + { "cpfsgt", 0xff00, 0x3200, INSN_CLASS_OPF8 }, + { "cpfslt", 0xff00, 0x3000, INSN_CLASS_OPF8 }, + { "daw", 0xfe00, 0x2e00, INSN_CLASS_OPWF8 }, + { "decf", 0xfe00, 0x0600, INSN_CLASS_OPWF8 }, + { "decfsz", 0xfe00, 0x1600, INSN_CLASS_OPWF8 }, + { "dcfsnz", 0xfe00, 0x2600, INSN_CLASS_OPWF8 }, + { "goto", 0xe000, 0xc000, INSN_CLASS_LIT13 }, + { "incf", 0xfe00, 0x1400, INSN_CLASS_OPWF8 }, + { "incfsz", 0xfe00, 0x1e00, INSN_CLASS_OPWF8 }, + { "infsnz", 0xfe00, 0x2400, INSN_CLASS_OPWF8 }, + { "iorlw", 0xff00, 0xb300, INSN_CLASS_LIT8 }, + { "iorwf", 0xfe00, 0x0800, INSN_CLASS_OPWF8 }, + { "lcall", 0xff00, 0xb700, INSN_CLASS_LIT8C16 }, + { "movfp", 0xe000, 0x6000, INSN_CLASS_FP }, + { "movpf", 0xe000, 0x4000, INSN_CLASS_PF }, + { "movlb", 0xff00, 0xb800, INSN_CLASS_LIT8 }, + { "movlr", 0xfe00, 0xba00, INSN_CLASS_LIT4S }, + { "movlw", 0xff00, 0xb000, INSN_CLASS_LIT8 }, + { "movwf", 0xff00, 0x0100, INSN_CLASS_OPF8 }, + { "mullw", 0xff00, 0xbc00, INSN_CLASS_LIT8 }, + { "mulwf", 0xff00, 0x3400, INSN_CLASS_OPF8 }, + { "negw", 0xfe00, 0x2c00, INSN_CLASS_OPWF8 }, + { "nop", 0xffff, 0x0000, INSN_CLASS_IMPLICIT }, + { "retfie", 0xffff, 0x0005, INSN_CLASS_IMPLICIT }, + { "retlw", 0xff00, 0xb600, INSN_CLASS_LIT8 }, + { "return", 0xffff, 0x0002, INSN_CLASS_IMPLICIT }, + { "rlcf", 0xfe00, 0x1a00, INSN_CLASS_OPWF8 }, + { "rlncf", 0xfe00, 0x2200, INSN_CLASS_OPWF8 }, + { "rrcf", 0xfe00, 0x1800, INSN_CLASS_OPWF8 }, + { "rrncf", 0xfe00, 0x2000, INSN_CLASS_OPWF8 }, + { "setf", 0xfe00, 0x2a00, INSN_CLASS_OPWF8 }, + { "sleep", 0xffff, 0x0003, INSN_CLASS_IMPLICIT }, + { "sublw", 0xff00, 0xb200, INSN_CLASS_LIT8 }, + { "subwf", 0xfe00, 0x0400, INSN_CLASS_OPWF8 }, + { "subwfb", 0xfe00, 0x0200, INSN_CLASS_OPWF8 }, + { "swapf", 0xfe00, 0x1c00, INSN_CLASS_OPWF8 }, + { "tablrd", 0xfc00, 0xa800, INSN_CLASS_TBL3 }, + { "tablwt", 0xfc00, 0xac00, INSN_CLASS_TBL3 }, + { "tlrd", 0xfc00, 0xa000, INSN_CLASS_TBL2 }, + { "tlwt", 0xfc00, 0xa400, INSN_CLASS_TBL2 }, + { "tstfsz", 0xff00, 0x3300, INSN_CLASS_OPF8 }, + { "xorlw", 0xff00, 0xb400, INSN_CLASS_LIT8 }, + { "xorwf", 0xfe00, 0x0c00, INSN_CLASS_OPWF8 } +}; + +const int num_op_17cxx = TABLE_SIZE(op_17cxx); + +struct insn op_18cxx[] = { + { "addlw", 0xff00, 0x0f00, INSN_CLASS_LIT8 }, + { "addwf", 0xfc00, 0x2400, INSN_CLASS_OPWFA8 }, + { "addwfc", 0xfc00, 0x2000, INSN_CLASS_OPWFA8 }, + { "andlw", 0xff00, 0x0b00, INSN_CLASS_LIT8 }, + { "andwf", 0xfc00, 0x1400, INSN_CLASS_OPWFA8 }, + { "bc", 0xff00, 0xe200, INSN_CLASS_RBRA8 }, + { "bcf", 0xf000, 0x9000, INSN_CLASS_BA8 }, + { "bn", 0xff00, 0xe600, INSN_CLASS_RBRA8 }, + { "bnc", 0xff00, 0xe300, INSN_CLASS_RBRA8 }, + { "bnn", 0xff00, 0xe700, INSN_CLASS_RBRA8 }, + { "bnov", 0xff00, 0xe500, INSN_CLASS_RBRA8 }, + { "bnz", 0xff00, 0xe100, INSN_CLASS_RBRA8 }, + { "bov", 0xff00, 0xe400, INSN_CLASS_RBRA8 }, + { "bra", 0xf800, 0xd000, INSN_CLASS_RBRA11 }, + { "bsf", 0xf000, 0x8000, INSN_CLASS_BA8 }, + { "btfsc", 0xf000, 0xb000, INSN_CLASS_BA8 }, + { "btfss", 0xf000, 0xa000, INSN_CLASS_BA8 }, + { "btg", 0xf000, 0x7000, INSN_CLASS_BA8 }, + { "bz", 0xff00, 0xe000, INSN_CLASS_RBRA8 }, + { "call", 0xfe00, 0xec00, INSN_CLASS_CALL20 }, + { "clrf", 0xfe00, 0x6a00, INSN_CLASS_OPFA8 }, + { "clrwdt", 0xffff, 0x0004, INSN_CLASS_IMPLICIT }, + { "comf", 0xfc00, 0x1c00, INSN_CLASS_OPWFA8 }, + { "cpfseq", 0xfe00, 0x6200, INSN_CLASS_OPFA8 }, + { "cpfsgt", 0xfe00, 0x6400, INSN_CLASS_OPFA8 }, + { "cpfslt", 0xfe00, 0x6000, INSN_CLASS_OPFA8 }, + { "daw", 0xffff, 0x0007, INSN_CLASS_IMPLICIT }, + { "decf", 0xfc00, 0x0400, INSN_CLASS_OPWFA8 }, + { "decfsz", 0xfc00, 0x2c00, INSN_CLASS_OPWFA8 }, + { "dcfsnz", 0xfc00, 0x4c00, INSN_CLASS_OPWFA8 }, + { "goto", 0xff00, 0xef00, INSN_CLASS_LIT20 }, + { "incf", 0xfc00, 0x2800, INSN_CLASS_OPWFA8 }, + { "incfsz", 0xfc00, 0x3c00, INSN_CLASS_OPWFA8 }, + { "infsnz", 0xfc00, 0x4800, INSN_CLASS_OPWFA8 }, + { "iorlw", 0xff00, 0x0900, INSN_CLASS_LIT8 }, + { "iorwf", 0xfc00, 0x1000, INSN_CLASS_OPWFA8 }, + { "lfsr", 0xffc0, 0xee00, INSN_CLASS_FLIT12 }, + { "movf", 0xfc00, 0x5000, INSN_CLASS_OPWFA8 }, + { "movff", 0xf000, 0xc000, INSN_CLASS_FF }, + { "movlb", 0xff00, 0x0100, INSN_CLASS_LIT8 }, + { "movlw", 0xff00, 0x0e00, INSN_CLASS_LIT8 }, + { "movwf", 0xfe00, 0x6e00, INSN_CLASS_OPFA8 }, + { "mullw", 0xff00, 0x0d00, INSN_CLASS_LIT8 }, + { "mulwf", 0xfe00, 0x0200, INSN_CLASS_OPFA8 }, + { "negf", 0xfe00, 0x6c00, INSN_CLASS_OPFA8 }, + { "nop", 0xffff, 0x0000, INSN_CLASS_IMPLICIT }, + { "pop", 0xffff, 0x0006, INSN_CLASS_IMPLICIT }, + { "push", 0xffff, 0x0005, INSN_CLASS_IMPLICIT }, + { "rcall", 0xf800, 0xd800, INSN_CLASS_RBRA11 }, + { "reset", 0xffff, 0x00ff, INSN_CLASS_IMPLICIT }, + { "retfie", 0xfffe, 0x0010, INSN_CLASS_LIT1 }, + { "retlw", 0xff00, 0x0c00, INSN_CLASS_LIT8 }, + { "return", 0xfffe, 0x0012, INSN_CLASS_LIT1 }, + { "rlcf", 0xfc00, 0x3400, INSN_CLASS_OPWFA8 }, + { "rlncf", 0xfc00, 0x4400, INSN_CLASS_OPWFA8 }, + { "rrcf", 0xfc00, 0x3000, INSN_CLASS_OPWFA8 }, + { "rrncf", 0xfc00, 0x4000, INSN_CLASS_OPWFA8 }, + { "setf", 0xfe00, 0x6800, INSN_CLASS_OPFA8 }, + { "sleep", 0xffff, 0x0003, INSN_CLASS_IMPLICIT }, + { "subfwb", 0xfc00, 0x5400, INSN_CLASS_OPWFA8 }, + { "sublw", 0xff00, 0x0800, INSN_CLASS_LIT8 }, + { "subwf", 0xfc00, 0x5c00, INSN_CLASS_OPWFA8 }, + { "subwfb", 0xfc00, 0x5800, INSN_CLASS_OPWFA8 }, + { "swapf", 0xfc00, 0x3800, INSN_CLASS_OPWFA8 }, + { "tblrd", 0xfffc, 0x0008, INSN_CLASS_TBL }, + { "tblwt", 0xfffc, 0x000c, INSN_CLASS_TBL }, + { "tstfsz", 0xfe00, 0x6600, INSN_CLASS_OPFA8 }, + { "xorlw", 0xff00, 0x0a00, INSN_CLASS_LIT8 }, + { "xorwf", 0xfc00, 0x1800, INSN_CLASS_OPWFA8 } +}; + +const int num_op_18cxx = TABLE_SIZE(op_18cxx); + +/* PIC 16-bit "Special" instruction set */ +struct insn op_18cxx_sp[] = { + { "clrc", 0xffff, 0x90d8, INSN_CLASS_IMPLICIT }, + { "clrdc", 0xffff, 0x92d8, INSN_CLASS_IMPLICIT }, + { "clrn", 0xffff, 0x98d8, INSN_CLASS_IMPLICIT }, + { "clrov", 0xffff, 0x96d8, INSN_CLASS_IMPLICIT }, + { "clrw", 0xffff, 0x6ae8, INSN_CLASS_IMPLICIT }, + { "clrz", 0xffff, 0x94d8, INSN_CLASS_IMPLICIT }, + { "setc", 0xffff, 0x80d8, INSN_CLASS_IMPLICIT }, + { "setdc", 0xffff, 0x82d8, INSN_CLASS_IMPLICIT }, + { "setn", 0xffff, 0x88d8, INSN_CLASS_IMPLICIT }, + { "setov", 0xffff, 0x86d8, INSN_CLASS_IMPLICIT }, + { "setz", 0xffff, 0x84d8, INSN_CLASS_IMPLICIT }, + { "skpc", 0xffff, 0xa0d8, INSN_CLASS_IMPLICIT }, + { "skpdc", 0xffff, 0xa2d8, INSN_CLASS_IMPLICIT }, + { "skpn", 0xffff, 0xa8d8, INSN_CLASS_IMPLICIT }, + { "skpov", 0xffff, 0xa6d8, INSN_CLASS_IMPLICIT }, + { "skpz", 0xffff, 0xa4d8, INSN_CLASS_IMPLICIT }, + { "skpnc", 0xffff, 0xb0d8, INSN_CLASS_IMPLICIT }, + { "skpndc", 0xffff, 0xb2d8, INSN_CLASS_IMPLICIT }, + { "skpnn", 0xffff, 0xb8d8, INSN_CLASS_IMPLICIT }, + { "skpnov", 0xffff, 0xb6d8, INSN_CLASS_IMPLICIT }, + { "skpnz", 0xffff, 0xb4d8, INSN_CLASS_IMPLICIT }, + { "tgc", 0xffff, 0x70d8, INSN_CLASS_IMPLICIT }, + { "tgdc", 0xffff, 0x72d8, INSN_CLASS_IMPLICIT }, + { "tgn", 0xffff, 0x78d8, INSN_CLASS_IMPLICIT }, + { "tgov", 0xffff, 0x76d8, INSN_CLASS_IMPLICIT }, + { "tgz", 0xffff, 0x74d8, INSN_CLASS_IMPLICIT } + +}; + +const int num_op_18cxx_sp = TABLE_SIZE(op_18cxx_sp); + +/* PIC 16-bit Extended instruction set */ +struct insn op_18cxx_ext[] = { + { "addfsr", 0xff00, 0xe800, INSN_CLASS_LITFSR }, + { "addulnk", 0xffc0, 0xe8c0, INSN_CLASS_LIT6 }, + { "callw", 0xffff, 0x0014, INSN_CLASS_IMPLICIT }, + { "movsf", 0xff80, 0xeb00, INSN_CLASS_SF }, + { "movss", 0xff80, 0xeb80, INSN_CLASS_SS }, + { "pushl", 0xff00, 0xea00, INSN_CLASS_LIT8 }, + { "subfsr", 0xff00, 0xe900, INSN_CLASS_LITFSR }, + { "subulnk", 0xffc0, 0xe9c0, INSN_CLASS_LIT6 } + +}; + +const int num_op_18cxx_ext = TABLE_SIZE(op_18cxx_ext); + diff --git a/src/coff/base/gpopcode.h b/src/coff/base/gpopcode.h new file mode 100644 index 0000000..aed25f9 --- /dev/null +++ b/src/coff/base/gpopcode.h @@ -0,0 +1,107 @@ +/* GNU PIC opcode definitions + Copyright (C) 2001, 2002, 2003, 2004, 2005 + Craig Franklin + +This file is part of gputils. + +gputils 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, or (at your option) +any later version. + +gputils 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 gputils; see the file COPYING. If not, write to +the Free Software Foundation, 51 Franklin Street, Fifth Floor, +Boston, MA 02110-1301, USA. */ + +#ifndef __GPOPCODE_H__ +#define __GPOPCODE_H__ + +enum insn_class { + INSN_CLASS_LIT1, /* bit 0 contains a 1 bit literal */ + INSN_CLASS_LIT4S, /* Bits 7:4 contain a 4 bit literal, bits 3:0 are unused */ + INSN_CLASS_LIT6, /* bits 5:0 contain an 6 bit literal */ + INSN_CLASS_LIT8, /* bits 7:0 contain an 8 bit literal */ + INSN_CLASS_LIT8C12, /* bits 7:0 contain an 8 bit literal, 12 bit CALL */ + INSN_CLASS_LIT8C16, /* bits 7:0 contain an 8 bit literal, 16 bit CALL */ + INSN_CLASS_LIT9, /* bits 8:0 contain a 9 bit literal */ + INSN_CLASS_LIT11, /* bits 10:0 contain an 11 bit literal */ + INSN_CLASS_LIT13, /* bits 12:0 contain an 11 bit literal */ + INSN_CLASS_LITFSR, /* bits 5:0 contain an 6 bit literal for fsr 7:6 */ + INSN_CLASS_IMPLICIT, /* instruction has no variable bits at all */ + INSN_CLASS_OPF5, /* bits 4:0 contain a register address */ + INSN_CLASS_OPWF5, /* as above, but bit 5 has a destination flag */ + INSN_CLASS_B5, /* as for OPF5, but bits 7:5 have bit number */ + INSN_CLASS_OPF7, /* bits 6:0 contain a register address */ + INSN_CLASS_OPWF7, /* as above, but bit 7 has destination flag */ + INSN_CLASS_B7, /* as for OPF7, but bits 9:7 have bit number */ + + INSN_CLASS_OPF8, /* bits 7:0 contain a register address */ + INSN_CLASS_OPFA8, /* bits 7:0 contain a register address & bit has access flag */ + INSN_CLASS_OPWF8, /* as above, but bit 8 has dest flag */ + INSN_CLASS_OPWFA8, /* as above, but bit 9 has dest flag & bit 8 has access flag */ + INSN_CLASS_B8, /* like OPF7, but bits 9:11 have bit number */ + INSN_CLASS_BA8, /* like OPF7, but bits 9:11 have bit number & bit 8 has access flag */ + INSN_CLASS_LIT20, /* 20bit lit, bits 7:0 in first word bits 19:8 in second */ + INSN_CLASS_CALL20, /* Like LIT20, but bit 8 has fast push flag */ + INSN_CLASS_RBRA8, /* Bits 7:0 contain a relative branch address */ + INSN_CLASS_RBRA11, /* Bits 10:0 contain a relative branch address */ + INSN_CLASS_FLIT12, /* LFSR, 12bit lit loaded into 1 of 4 FSRs */ + INSN_CLASS_FF, /* two 12bit file addresses */ + INSN_CLASS_FP, /* Bits 7:0 contain a register address, bits 12:8 contains a peripheral address */ + INSN_CLASS_PF, /* Bits 7:0 contain a register address, bits 12:8 contains a peripheral address */ + + INSN_CLASS_SF, /* 7 bit offset added to FSR2, fetched memory placed at 12 bit address */ + INSN_CLASS_SS, /* two 7 bit offsets, memory moved using FSR2 */ + + INSN_CLASS_TBL, /* a table read or write instruction */ + INSN_CLASS_TBL2, /* a table read or write instruction. + Bits 7:0 contains a register address; Bit 8 is unused; + Bit 9, table byte select. (0:lower ; 1:upper) */ + INSN_CLASS_TBL3, /* a table read or write instruction. + Bits 7:0 contains a register address; + Bit 8, 1 if increment pointer, 0 otherwise; + Bit 9, table byte select. (0:lower ; 1:upper) */ + INSN_CLASS_FUNC, /* instruction is an assembler function */ + INSN_CLASS_LIT3_BANK, /* SX: bits 3:0 contain a 3 bit literal, shifted 5 bits */ + INSN_CLASS_LIT3_PAGE, /* SX: bits 3:0 contain a 3 bit literal, shifted 9 bits */ + INSN_CLASS_LIT4 /* SX: bits 3:0 contain a 4 bit literal */ +}; + +struct insn { + const char *name; + long int mask; + long int opcode; + enum insn_class classType; + //int attribs; +}; + +#define TABLE_SIZE(X) (sizeof(X) / sizeof(X[0])) + +extern struct insn op_12c5xx[]; +extern const int num_op_12c5xx; + +extern struct insn op_sx[]; +extern const int num_op_sx; + +extern struct insn op_16cxx[]; +extern const int num_op_16cxx; + +extern struct insn op_17cxx[]; +extern const int num_op_17cxx; + +extern struct insn op_18cxx[]; +extern const int num_op_18cxx; + +extern struct insn op_18cxx_sp[]; +extern const int num_op_18cxx_sp; + +extern struct insn op_18cxx_ext[]; +extern const int num_op_18cxx_ext; + +#endif diff --git a/src/coff/base/text_coff.cpp b/src/coff/base/text_coff.cpp new file mode 100644 index 0000000..0d0862e --- /dev/null +++ b/src/coff/base/text_coff.cpp @@ -0,0 +1,262 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "text_coff.h" + +#include "common/global/pfile.h" + +namespace Coff +{ +class CodeData { +public: + QString address, opcode, disasm1, disasm2; +}; +class LineData { +public: + QValueVector codes; + QString lineNumber, lineText; +}; +class FileData { +public: + PURL::Url url; + bool read; + QValueVector lines; +}; +} + +Coff::TextObject::TextObject(const Device::Data *device, const PURL::Url &url) + : Object(device, url), _initialized(true) +{} + +bool Coff::TextObject::parse(Log::Base &log) +{ + bool ok = Object::parse(log); + _initialized = !ok; + return ok; +} + +PURL::Url Coff::TextObject::urlForFilename(const QString &filename) const +{ + PURL::Url rurl = PURL::Url::fromPathOrUrl(filename); + return rurl.toAbsolute(url().directory()); +} + +const Coff::Section *Coff::TextObject::section(const CodeLine &cline) const +{ + if ( cline.section().instructions().contains(cline.address()) ) return &cline.section(); + // possible for coff generated by picc... + for (uint i=0; itype()!=SectionType::Code ) continue; + if ( _sections[i]->instructions().contains(cline.address()) ) return _sections[i]; + } + return 0; +} + +void Coff::TextObject::init() const +{ + if (_initialized) return; + _initialized = true; + + // open and read files + QMap fd; + for (uint i=0; itype()!=SectionType::Code ) continue; + for (uint k=0; klines().count()); k++) { + QString filename = _sections[i]->lines()[k]->filename(); + if ( filename.isEmpty() || fd.contains(filename) ) continue; + _filenames.append(filename); + FileData fdata; + fdata.url = urlForFilename(filename); + Log::StringView sview; + PURL::File file(fdata.url, sview); + fdata.read = file.openForRead(); + if (fdata.read) { + QStringList lines = file.readLines(); + fdata.lines.resize(lines.count()); + for (uint i=0; inbCharsAddress(); + uint opcodeWidth = 0, disasm1Width = 0, disasm2Width = 0, lineNumberWidth = 0, lineTextWidth = 0; + QMap::iterator it; + for (it=fd.begin(); it!=fd.end(); ++it) { + for (uint i=0; i lines = findCodeLines(it.key(), i); + ldata.codes.resize(lines.count()); + for (uint k=0; kaddress(); + ldata.codes[k].address = toHex(address, addressWidth).upper(); + const Section *sec = section(*lines[k]); + if (sec) { + ldata.codes[k].opcode = "0x" + sec->instructions()[address].opcode.upper(); + //qDebug("%s: %s", ldata.codes[k].address.latin1(), ldata.codes[k].opcode.latin1()); + opcodeWidth = qMax(opcodeWidth, uint(ldata.codes[k].opcode.length())); + QString s = sec->instructions()[address].disasm; + int j = s.find('\t'); + if ( j!=-1 ) { + ldata.codes[k].disasm2 = s.mid(j+1); + disasm2Width = qMax(disasm2Width, uint(ldata.codes[k].disasm2.length())); + } + ldata.codes[k].disasm1 = (j==-1 ? s : s.mid(0, j)); + disasm1Width = qMax(disasm1Width, uint(ldata.codes[k].disasm1.length())); + } + } + ldata.lineNumber = QString::number(i+1); + lineNumberWidth = qMax(lineNumberWidth, uint(ldata.lineNumber.length())); + lineTextWidth = qMax(lineTextWidth, uint(ldata.lineText.length())); + } + } + uint asmWidth = addressWidth + 4 + opcodeWidth + 4 + disasm1Width + 2 + disasm2Width; + uint totalWidth = asmWidth + 4 + lineNumberWidth + 2 + lineTextWidth; + + // create text + for (it = fd.begin(); it!=fd.end(); ++it) { + QString s = QString("--- ") + it.data().url.pretty() + " "; + _list += s.leftJustify(totalWidth, '-'); + if ( !it.data().read ) { + s = QString("--- ") + i18n("File could not be read") + " "; + _list += s.leftJustify(totalWidth, '-'); + } + for (uint i=0; itype()!=SectionType::Code ) continue; + for (uint k=0; klines().count()); k++) { + const CodeLine *cl = _sections[i]->lines()[k]; + if ( cl->filename()==filename ) nb = qMax(nb, cl->line()); + } + } + return nb; +} + +QValueVector Coff::TextObject::findCodeLines(const QString &filename, uint line) const +{ + init(); + QValueVector list; + for (uint i=0; itype()!=SectionType::Code ) continue; + for (uint k=0; klines().count()); k++) { + const CodeLine *cl = _sections[i]->lines()[k]; + if ( (cl->line()-1)==line && cl->filename()==filename ) list.append(cl); + } + } + return list; +} + +int Coff::TextObject::lineForAddress(const PURL::Url &url, Address address) const +{ + init(); + if ( url==_url && _lines.contains(address) ) return _lines[address]-1; + for (uint i=0; itype()!=SectionType::Code ) continue; + for (uint k=0; klines().count()); k++) { + const CodeLine *cl = _sections[i]->lines()[k]; + if ( cl->address()!=address ) continue; + QString filename = cl->filename(); + if ( filename.isEmpty() || urlForFilename(filename)!=url ) continue; + return cl->line()-1; + } + } + return -1; +} + +QMap Coff::TextObject::sourceLinesForAddress(Address address) const +{ + QMap slines; + init(); + for (uint i=0; itype()!=SectionType::Code ) continue; + for (uint k=0; klines().count()); k++) { + const CodeLine *cl = _sections[i]->lines()[k]; + if ( cl->address()!=address ) continue; + QString filename = cl->filename(); + if ( filename.isEmpty() ) continue; + slines[urlForFilename(filename)] = cl->line()-1; + } + } + if ( _lines.contains(address) ) slines[_url] = _lines[address] - 1; + return slines; +} + +QValueVector
Coff::TextObject::addresses(const PURL::Url &url, uint line) const +{ + init(); + QValueVector
ad; + if ( url==_url ) { + QMap::const_iterator it; + for (it=_lines.begin(); it!=_lines.end(); ++it) + if ( line==(it.data()-1) ) ad.append(it.key()); + return ad; + } + for (uint i=0; itype()!=SectionType::Code ) continue; + for (uint k=0; klines().count()); k++) { + const CodeLine *cl = _sections[i]->lines()[k]; + if ( line!=(cl->line()-1) ) continue; + QString filename = cl->filename(); + if ( filename.isEmpty() || urlForFilename(filename)!=url ) continue; + ad.append(cl->address()); + } + } + return ad; +} + +const QStringList &Coff::TextObject::filenames() const +{ + init(); + return _filenames; +} + +QString Coff::TextObject::disassembly() const +{ + init(); + if ( _list.isEmpty() ) return i18n("Parsing COFF file is not supported for this device or an error occured."); + return _list.join("\n"); +} + +Log::KeyList Coff::TextObject::information() const +{ + Log::KeyList keys; + keys.append(i18n("Format:"), i18n("%1 (magic id: %2)").arg(format().label()).arg(toHexLabel(format().data().magic, 4))); + QString name = (format()==Format::PIC30 || device()==0 ? "?" : device()->name()); + keys.append(i18n("Device:"), name); + OptHeaderFormat ohf = optHeaderFormat(); + QString label = (ohf==OptHeaderFormat::Nb_Types ? i18n("Unknown") : ohf.label()); + keys.append(i18n("Option header:"), i18n("%1 (magic id: %2)").arg(label).arg(toHexLabel(optHeaderMagic(), 4))); + keys.append(i18n("No. of sections:"), QString::number(nbSections())); + keys.append(i18n("No. of symbols:"), QString::number(nbSymbols())); + keys.append(i18n("No. of variables:"), QString::number(variables().count())); + return keys; +} diff --git a/src/coff/base/text_coff.h b/src/coff/base/text_coff.h new file mode 100644 index 0000000..7b6e673 --- /dev/null +++ b/src/coff/base/text_coff.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef TEXT_COFF_H +#define TEXT_COFF_H + +#include "coff_object.h" + +namespace Coff +{ + +class TextObject : public Object +{ +public: + TextObject(const Device::Data *device, const PURL::Url &url); + virtual bool parse(Log::Base &log); + int lineForAddress(const PURL::Url &url, Address address) const; + QMap sourceLinesForAddress(Address address) const; // url -> line + QValueVector
addresses(const PURL::Url &url, uint line) const; + const QStringList &filenames() const; + + QString disassembly() const; + virtual Log::KeyList information() const; + +private: + mutable bool _initialized; + mutable QMap _lines; // address -> line in disassembly listing + mutable QStringList _list; + mutable QStringList _filenames; + + uint nbLines(const QString &filename) const; + QValueVector findCodeLines(const QString &filename, uint line) const; + PURL::Url urlForFilename(const QString &filename) const; + void init() const; + const Section *section(const CodeLine &cline) const; +}; + +} // namespace + +#endif diff --git a/src/coff/coff.pro b/src/coff/coff.pro new file mode 100644 index 0000000..262f5c8 --- /dev/null +++ b/src/coff/coff.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = xml base \ No newline at end of file diff --git a/src/coff/xml/Makefile.am b/src/coff/xml/Makefile.am new file mode 100644 index 0000000..368e2e7 --- /dev/null +++ b/src/coff/xml/Makefile.am @@ -0,0 +1,14 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_PROGRAMS = xml_coff_parser +xml_coff_parser_SOURCES = xml_coff_parser.cpp gpprocessor.cpp +OBJECTS = $(top_builddir)/src/devices/list/libdevicelistnoui.la \ + $(top_builddir)/src/devices/pic/pic/libpic.la $(top_builddir)/src/devices/pic/base/libpicbase.la \ + $(top_builddir)/src/devices/pic/xml_data/libpicxml.la \ + $(top_builddir)/src/devices/mem24/mem24/libmem24.la $(top_builddir)/src/devices/mem24/base/libmem24base.la \ + $(top_builddir)/src/devices/mem24/xml_data/libmem24xml.la \ + $(top_builddir)/src/xml_to_data/libxmltodata.la $(top_builddir)/src/devices/base/libdevicebase.la \ + $(top_builddir)/src/common/common/libcommon.la +xml_coff_parser_LDADD = $(OBJECTS) $(LIB_KDECORE) +xml_coff_parser_DEPENDENCIES = $(OBJECTS) diff --git a/src/coff/xml/gpprocessor.cpp b/src/coff/xml/gpprocessor.cpp new file mode 100644 index 0000000..85477e9 --- /dev/null +++ b/src/coff/xml/gpprocessor.cpp @@ -0,0 +1,340 @@ +/* GNU PIC processor definitions + Copyright (C) 2001, 2002, 2003, 2004, 2005 + Craig Franklin + +This file is part of gputils. + +gputils 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, or (at your option) +any later version. + +gputils 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 gputils; see the file COPYING. If not, write to +the Free Software Foundation, 51 Franklin Street, Fifth Floor, +Boston, MA 02110-1301, USA. */ + +#include "gpprocessor.h" + +/* XXXPRO: Need to add a line here for any extra processors. Please + keep this list sorted! */ + +const struct px pics[] = { + { eeprom8, PROC_CLASS_EEPROM8, "__EEPROM8", { "eeprom8", "eeprom8", "eeprom8" }, 0x0, 0, 0, -1, NULL }, + { generic, PROC_CLASS_GENERIC, "__GEN", { "generic", "gen", "unknown" }, 0x0, 0, 0, -1, NULL }, + { pic10f200, PROC_CLASS_PIC12, "__10F200", { "pic10f200", "p10f200", "10f200" }, 0xf200, 1, 1, 0xff, "10f200.lkr" }, + { pic10f202, PROC_CLASS_PIC12, "__10F202", { "pic10f202", "p10f202", "10f202" }, 0xf202, 1, 1, 0x1ff, "10f202.lkr" }, + { pic10f204, PROC_CLASS_PIC12, "__10F204", { "pic10f204", "p10f204", "10f204" }, 0xf204, 1, 1, 0xff, "10f204.lkr" }, + { pic10f206, PROC_CLASS_PIC12, "__10F206", { "pic10f206", "p10f206", "10f206" }, 0xf206, 1, 1, 0x1ff, "10f206.lkr" }, + { pic10f220, PROC_CLASS_PIC12, "__10F220", { "pic10f220", "p10f220", "10f220" }, 0xf220, 1, 1, 0xff, "10f220.lkr" }, + { pic10f222, PROC_CLASS_PIC12, "__10F222", { "pic10f222", "p10f222", "10f222" }, 0xf222, 1, 1, 0x1ff, "10f222.lkr" }, + { pic12c508, PROC_CLASS_PIC12, "__12C508", { "pic12c508", "p12c508", "12c508" }, 0x2508, 1, 1, 0x1ff, "12c508.lkr" }, + { pic12c508a, PROC_CLASS_PIC12, "__12C508A", { "pic12c508a", "p12c508a", "12c508a" }, 0x508a, 1, 1, 0x1ff, "12c508a.lkr" }, + { pic12c509, PROC_CLASS_PIC12, "__12C509", { "pic12c509", "p12c509", "12c509" }, 0x2509, 1, 2, 0x3ff, "12c509.lkr" }, + { pic12c509a, PROC_CLASS_PIC12, "__12C509A", { "pic12c509a", "p12c509a", "12c509a" }, 0x509a, 1, 2, 0x3ff, "12c509a.lkr" }, + { pic12c671, PROC_CLASS_PIC14, "__12C671", { "pic12c671", "p12c671", "12c671" }, 0x2671, 1, 2, 0x3ff, "12c671.lkr" }, + { pic12c672, PROC_CLASS_PIC14, "__12C672", { "pic12c672", "p12c672", "12c672" }, 0x2672, 1, 2, 0x7ff, "12c672.lkr" }, + { pic12ce518, PROC_CLASS_PIC12, "__12CE518", { "pic12ce518", "p12ce518", "12ce518" }, 0x2518, 1, 1, 0x1ff, "12ce518.lkr" }, + { pic12ce519, PROC_CLASS_PIC12, "__12CE519", { "pic12ce519", "p12ce519", "12ce519" }, 0x2519, 1, 2, 0x3ff, "12ce519.lkr" }, + { pic12ce673, PROC_CLASS_PIC14, "__12CE673", { "pic12ce673", "p12ce673", "12ce673" }, 0x2673, 1, 2, 0x3ff, "12ce673.lkr" }, + { pic12ce674, PROC_CLASS_PIC14, "__12CE674", { "pic12ce674", "p12ce674", "12ce674" }, 0x2674, 1, 2, 0x7ff, "12ce674.lkr" }, + { pic12cr509a, PROC_CLASS_PIC12, "__12CR509A", { "pic12cr509a", "p12cr509a", "12cr509a" }, 0xd09a, 1, 2, 0x3ff, "12cr509a.lkr" }, + { pic12f508, PROC_CLASS_PIC12, "__12F508", { "pic12f508", "p12f508", "12f508" }, 0x2508, 1, 1, 0x1ff, "12f508.lkr" }, + { pic12f509, PROC_CLASS_PIC12, "__12F509", { "pic12f509", "p12f509", "12f509" }, 0x2509, 2, 2, 0x3ff, "12f509.lkr" }, + { pic12f510, PROC_CLASS_PIC12, "__12F510", { "pic12f510", "p12f510", "12f510" }, 0x2510, 1, 2, 0x3ff, "12f510.lkr" }, + { pic12f629, PROC_CLASS_PIC14, "__12F629", { "pic12f629", "p12f629", "12f629" }, 0x2629, 1, 2, 0x3fe, "12f629.lkr" }, + { pic12f635, PROC_CLASS_PIC14, "__12F635", { "pic12f635", "p12f635", "12f635" }, 0x2635, 1, 4, 0x3ff, "12f635.lkr" }, + { pic12f675, PROC_CLASS_PIC14, "__12F675", { "pic12f675", "p12f675", "12f675" }, 0x2675, 1, 2, 0x3fe, "12f675.lkr" }, + { pic12f683, PROC_CLASS_PIC14, "__12F683", { "pic12f683", "p12f683", "12f683" }, 0x2683, 1, 2, 0x7ff, "12f683.lkr" }, + { pic14000, PROC_CLASS_PIC14, "__14000", { "pic14000", "p14000", "14000" }, 0x4000, 2, 2, 0xfbf, "14000.lkr" }, + { pic16c5x, PROC_CLASS_PIC12, "__16C5X", { "pic16c5x", "p16c5x", "16c5x" }, 0x658a, 4, 4, -1, NULL }, + { pic16cxx, PROC_CLASS_PIC14, "__16CXX", { "pic16cxx", "p16cxx", "16cxx" }, 0x6c77, 4, 4, -1, NULL }, + { pic16c432, PROC_CLASS_PIC14, "__16C432", { "pic16c432", "p16c432", "16c432" }, 0x6432, 1, 2, 0x7ff, "16c432.lkr" }, + { pic16c433, PROC_CLASS_PIC14, "__16C433", { "pic16c433", "p16c433", "16c433" }, 0x6433, 1, 2, 0x7ff, "16c433.lkr" }, + { pic16c505, PROC_CLASS_PIC12, "__16C505", { "pic16c505", "p16c505", "16c505" }, 0x2505, 1, 4, 0x3ff, "16c505.lkr" }, + { pic16c52, PROC_CLASS_PIC12, "__16C52", { "pic16c52", "p16c52", "16c52" }, 0x6c52, 1, 1, 0x17f, "16c52.lkr" }, + { pic16c54, PROC_CLASS_PIC12, "__16C54", { "pic16c54", "p16c54", "16c54" }, 0x6c54, 1, 1, 0x1ff, "16c54.lkr" }, + { pic16c54a, PROC_CLASS_PIC12, "__16C54A", { "pic16c54a", "p16c54a", "16c54a" }, 0x654a, 1, 1, 0x1ff, "16c54a.lkr" }, + { pic16c54b, PROC_CLASS_PIC12, "__16C54B", { "pic16c54b", "p16c54b", "16c54b" }, 0x654b, 1, 1, 0x1ff, "16c54b.lkr" }, + { pic16c54c, PROC_CLASS_PIC12, "__16C54C", { "pic16c54c", "p16c54c", "16c54c" }, 0x654c, 1, 1, 0x1ff, "16c54c.lkr" }, + { pic16c55, PROC_CLASS_PIC12, "__16C55", { "pic16c55", "p16c55", "16c55" }, 0x6c55, 1, 1, 0x1ff, "16c55.lkr" }, + { pic16c55a, PROC_CLASS_PIC12, "__16C55A", { "pic16c55a", "p16c55a", "16c55a" }, 0x655a, 1, 1, 0x1ff, "16c55a.lkr" }, + { pic16c554, PROC_CLASS_PIC14, "__16C554", { "pic16c554", "p16c554", "16c554" }, 0x6554, 1, 2, 0x1ff, "16c554.lkr" }, + { pic16c557, PROC_CLASS_PIC14, "__16C557", { "pic16c557", "p16c557", "16c557" }, 0x6557, 1, 2, 0x7ff, "16c557.lkr" }, + { pic16c558, PROC_CLASS_PIC14, "__16C558", { "pic16c558", "p16c558", "16c558" }, 0x6558, 1, 2, 0x7ff, "16c558.lkr" }, + { pic16c56, PROC_CLASS_PIC12, "__16C56", { "pic16c56", "p16c56", "16c56" }, 0x6c56, 2, 1, 0x3ff, "16c56.lkr" }, + { pic16c56a, PROC_CLASS_PIC12, "__16C56A", { "pic16c56a", "p16c56a", "16c56a" }, 0x656a, 2, 1, 0x3ff, "16c56a.lkr" }, + { pic16c57, PROC_CLASS_PIC12, "__16C57", { "pic16c57", "p16c57", "16c57" }, 0x6c57, 4, 4, 0x7ff, "16c57.lkr" }, + { pic16c57c, PROC_CLASS_PIC12, "__16C57C", { "pic16c57c", "p16c57c", "16c57c" }, 0x657c, 4, 4, 0x7ff, "16c57c.lkr" }, + { pic16c58a, PROC_CLASS_PIC12, "__16C58A", { "pic16c58a", "p16c58a", "16c58a" }, 0x658a, 4, 4, 0x7ff, "16c58a.lkr" }, + { pic16c58b, PROC_CLASS_PIC12, "__16C58B", { "pic16c58b", "p16c58b", "16c58b" }, 0x658b, 4, 4, 0x7ff, "16c58b.lkr" }, + { pic16c61, PROC_CLASS_PIC14, "__16C61", { "pic16c61", "p16c61", "16c61" }, 0x6c61, 1, 2, 0x3ff, "16c61.lkr" }, + { pic16c62, PROC_CLASS_PIC14, "__16C62", { "pic16c62", "p16c62", "16c62" }, 0x6c62, 1, 2, 0x7ff, "16c62.lkr" }, + { pic16c62a, PROC_CLASS_PIC14, "__16C62A", { "pic16c62a", "p16c62a", "16c62a" }, 0x662a, 1, 2, 0x7ff, "16c62a.lkr" }, + { pic16c62b, PROC_CLASS_PIC14, "__16C62B", { "pic16c62b", "p16c62b", "16c62b" }, 0x662b, 1, 2, 0x7ff, "16c62b.lkr" }, + { pic16c620, PROC_CLASS_PIC14, "__16C620", { "pic16c620", "p16c620", "16c620" }, 0x6620, 1, 2, 0x1ff, "16c620.lkr" }, + { pic16c620a, PROC_CLASS_PIC14, "__16C620A", { "pic16c620a", "p16c620a", "16c620a" }, 0x620a, 1, 2, 0x1ff, "16c620a.lkr" }, + { pic16c621, PROC_CLASS_PIC14, "__16C621", { "pic16c621", "p16c621", "16c621" }, 0x6621, 1, 2, 0x3ff, "16c621.lkr" }, + { pic16c621a, PROC_CLASS_PIC14, "__16C621A", { "pic16c621a", "p16c621a", "16c621a" }, 0x621a, 1, 2, 0x3ff, "16c621a.lkr" }, + { pic16c622, PROC_CLASS_PIC14, "__16C622", { "pic16c622", "p16c622", "16c622" }, 0x6622, 1, 2, 0x7ff, "16c622.lkr" }, + { pic16c622a, PROC_CLASS_PIC14, "__16C622A", { "pic16c622a", "p16c622a", "16c622a" }, 0x622a, 1, 2, 0x7ff, "16c622a.lkr" }, + { pic16c63, PROC_CLASS_PIC14, "__16C63", { "pic16c63", "p16c63", "16c63" }, 0x6c63, 2, 2, 0xfff, "16c63.lkr" }, + { pic16c63a, PROC_CLASS_PIC14, "__16C63A", { "pic16c63a", "p16c63a", "16c63a" }, 0x663a, 2, 2, 0xfff, "16c63a.lkr" }, + { pic16c64, PROC_CLASS_PIC14, "__16C64", { "pic16c64", "p16c64", "16c64" }, 0x6c64, 1, 2, 0x7ff, "16c64.lkr" }, + { pic16c64a, PROC_CLASS_PIC14, "__16C64A", { "pic16c64a", "p16c64a", "16c64a" }, 0x664a, 1, 2, 0x7ff, "16c64a.lkr" }, + { pic16c642, PROC_CLASS_PIC14, "__16C642", { "pic16c642", "p16c642", "16c642" }, 0x6642, 2, 2, 0xfff, "16c642.lkr" }, + { pic16c65, PROC_CLASS_PIC14, "__16C65", { "pic16c65", "p16c65", "16c65" }, 0x6c65, 2, 2, 0xfff, "16c65.lkr" }, + { pic16c65a, PROC_CLASS_PIC14, "__16C65A", { "pic16c65a", "p16c65a", "16c65a" }, 0x665a, 2, 2, 0xfff, "16c65a.lkr" }, + { pic16c65b, PROC_CLASS_PIC14, "__16C65B", { "pic16c65b", "p16c65b", "16c65b" }, 0x665b, 2, 2, 0xfff, "16c65b.lkr" }, + { pic16c66, PROC_CLASS_PIC14, "__16C66", { "pic16c66", "p16c66", "16c66" }, 0x6c66, 4, 4, 0x1fff, "16c66.lkr" }, + { pic16c662, PROC_CLASS_PIC14, "__16C662", { "pic16c662", "p16c662", "16c662" }, 0x6662, 2, 2, 0xfff, "16c662.lkr" }, + { pic16c67, PROC_CLASS_PIC14, "__16C67", { "pic16c67", "p16c67", "16c67" }, 0x6c67, 4, 4, 0x1fff, "16c67.lkr" }, + { pic16c71, PROC_CLASS_PIC14, "__16C71", { "pic16c71", "p16c71", "16c71" }, 0x6c71, 1, 2, 0x3ff, "16c71.lkr" }, + { pic16c710, PROC_CLASS_PIC14, "__16C710", { "pic16c710", "p16c710", "16c710" }, 0x6710, 1, 2, 0x1ff, "16c710.lkr" }, + { pic16c711, PROC_CLASS_PIC14, "__16C711", { "pic16c711", "p16c711", "16c711" }, 0x6711, 1, 2, 0x3ff, "16c711.lkr" }, + { pic16c712, PROC_CLASS_PIC14, "__16C712", { "pic16c712", "p16c712", "16c712" }, 0x6712, 1, 2, 0x3ff, "16c712.lkr" }, + { pic16c715, PROC_CLASS_PIC14, "__16C715", { "pic16c715", "p16c715", "16c715" }, 0x6715, 1, 2, 0x7ff, "16c715.lkr" }, + { pic16c716, PROC_CLASS_PIC14, "__16C716", { "pic16c716", "p16c716", "16c716" }, 0x6716, 1, 2, 0x7ff, "16c716.lkr" }, + { pic16c717, PROC_CLASS_PIC14, "__16C717", { "pic16c717", "p16c717", "16c717" }, 0x6717, 1, 4, 0x7ff, "16c717.lkr" }, + { pic16c72, PROC_CLASS_PIC14, "__16C72", { "pic16c72", "p16c72", "16c72" }, 0x6c72, 1, 2, 0x7ff, "16c72.lkr" }, + { pic16c72a, PROC_CLASS_PIC14, "__16C72A", { "pic16c72a", "p16c72a", "16c72a" }, 0x672a, 1, 2, 0x7ff, "16c72a.lkr" }, + { pic16c73, PROC_CLASS_PIC14, "__16C73", { "pic16c73", "p16c73", "16c73" }, 0x673a, 2, 2, 0xfff, "16c73.lkr" }, + { pic16c73a, PROC_CLASS_PIC14, "__16C73A", { "pic16c73a", "p16c73a", "16c73a" }, 0x673a, 2, 2, 0xfff, "16c73a.lkr" }, + { pic16c73b, PROC_CLASS_PIC14, "__16C73B", { "pic16c73b", "p16c73b", "16c73b" }, 0x673b, 2, 2, 0xfff, "16c73b.lkr" }, + { pic16c74, PROC_CLASS_PIC14, "__16C74", { "pic16c74", "p16c74", "16c74" }, 0x6c74, 2, 2, 0xfff, "16c74.lkr" }, + { pic16c745, PROC_CLASS_PIC14, "__16C745", { "pic16c745", "p16c745", "16c745" }, 0x6745, 4, 4, 0x1fff, "16c745.lkr" }, + { pic16c74a, PROC_CLASS_PIC14, "__16C74A", { "pic16c74a", "p16c74a", "16c74a" }, 0x674a, 2, 2, 0xfff, "16c74a.lkr" }, + { pic16c74b, PROC_CLASS_PIC14, "__16C74B", { "pic16c74b", "p16c74b", "16c74b" }, 0x674b, 2, 2, 0xfff, "16c74b.lkr" }, + { pic16c76, PROC_CLASS_PIC14, "__16C76", { "pic16c76", "p16c76", "16c76" }, 0x6c76, 4, 4, 0x1fff, "16c76.lkr" }, + { pic16c765, PROC_CLASS_PIC14, "__16C765", { "pic16c765", "p16c765", "16c765" }, 0x6765, 4, 4, 0x1fff, "16c765.lkr" }, + { pic16c77, PROC_CLASS_PIC14, "__16C77", { "pic16c77", "p16c77", "16c77" }, 0x6c77, 4, 4, 0x1fff, "16c77.lkr" }, + { pic16c770, PROC_CLASS_PIC14, "__16C770", { "pic16c770", "p16c770", "16c770" }, 0x6770, 1, 4, 0x7ff, "16c770.lkr" }, + { pic16c771, PROC_CLASS_PIC14, "__16C771", { "pic16c771", "p16c771", "16c771" }, 0x6771, 2, 4, 0xfff, "16c771.lkr" }, + { pic16c773, PROC_CLASS_PIC14, "__16C773", { "pic16c773", "p16c773", "16c773" }, 0x6773, 2, 4, 0xfff, "16c773.lkr" }, + { pic16c774, PROC_CLASS_PIC14, "__16C774", { "pic16c774", "p16c774", "16c774" }, 0x6774, 2, 4, 0xfff, "16c774.lkr" }, + { pic16c781, PROC_CLASS_PIC14, "__16C781", { "pic16c781", "p16c781", "16c781" }, 0x6781, 1, 4, 0x3ff, "16c781.lkr" }, + { pic16c782, PROC_CLASS_PIC14, "__16C782", { "pic16c782", "p16c782", "16c782" }, 0x6782, 1, 4, 0x7ff, "16c782.lkr" }, + { pic16c84, PROC_CLASS_PIC14, "__16C84", { "pic16c84", "p16c84", "16c84" }, 0x6c84, 1, 2, 0x3ff, "16c84.lkr" }, + { pic16c923, PROC_CLASS_PIC14, "__16C923", { "pic16c923", "p16c923", "16c923" }, 0x6923, 2, 4, 0xfff, "16c923.lkr" }, + { pic16c924, PROC_CLASS_PIC14, "__16C924", { "pic16c924", "p16c924", "16c924" }, 0x6924, 2, 4, 0xfff, "16c924.lkr" }, + { pic16c925, PROC_CLASS_PIC14, "__16C925", { "pic16c925", "p16c925", "16c925" }, 0x6925, 2, 4, 0xfff, "16c925.lkr" }, + { pic16c926, PROC_CLASS_PIC14, "__16C926", { "pic16c926", "p16c926", "16c926" }, 0x6926, 4, 4, 0x1fff, "16c926.lkr" }, + { pic16ce623, PROC_CLASS_PIC14, "__16CE623", { "pic16ce623", "p16ce623", "16ce623" }, 0x6623, 1, 2, 0x1ff, "16ce623.lkr" }, + { pic16ce624, PROC_CLASS_PIC14, "__16CE624", { "pic16ce624", "p16ce624", "16ce624" }, 0x6624, 1, 2, 0x3ff, "16ce624.lkr" }, + { pic16ce625, PROC_CLASS_PIC14, "__16CE625", { "pic16ce625", "p16ce625", "16ce625" }, 0x6625, 1, 2, 0x7ff, "16ce625.lkr" }, + { pic16cr54, PROC_CLASS_PIC12, "__16CR54", { "pic16cr54", "p16cr54", "16cr54" }, 0xdc54, 1, 1, 0x1ff, "16cr54.lkr" }, + { pic16cr54a, PROC_CLASS_PIC12, "__16CR54A", { "pic16cr54a", "p16cr54a", "16cr54a" }, 0xd54a, 1, 1, 0x1ff, "16cr54a.lkr" }, + { pic16cr54b, PROC_CLASS_PIC12, "__16CR54B", { "pic16cr54b", "p16cr54b", "16cr54b" }, 0xd54b, 1, 1, 0x1ff, "16cr54b.lkr" }, + { pic16cr54c, PROC_CLASS_PIC12, "__16CR54C", { "pic16cr54c", "p16cr54c", "16cr54c" }, 0xdc54, 1, 1, 0x1ff, "16cr54c.lkr" }, + { pic16cr56a, PROC_CLASS_PIC12, "__16CR56A", { "pic16cr56a", "p16cr56a", "16cr56a" }, 0xd56a, 2, 1, 0x3ff, "16cr56a.lkr" }, + { pic16cr57a, PROC_CLASS_PIC12, "__16CR57A", { "pic16cr57a", "p16cr57a", "16cr57a" }, 0xd57a, 4, 4, 0x7ff, "16cr57a.lkr" }, + { pic16cr57b, PROC_CLASS_PIC12, "__16CR57B", { "pic16cr57b", "p16cr57b", "16cr57b" }, 0xd57b, 4, 4, 0x7ff, "16cr57b.lkr" }, + { pic16cr57c, PROC_CLASS_PIC12, "__16CR57C", { "pic16cr57c", "p16cr57c", "16cr57c" }, 0xd57c, 4, 4, 0x7ff, "16cr57c.lkr" }, + { pic16cr58a, PROC_CLASS_PIC12, "__16CR58A", { "pic16cr58a", "p16cr58a", "16cr58a" }, 0xd58a, 4, 4, 0x7ff, "16cr58a.lkr" }, + { pic16cr58b, PROC_CLASS_PIC12, "__16CR58B", { "pic16cr58b", "p16cr58b", "16cr58b" }, 0xd58b, 4, 4, 0x7ff, "16cr58b.lkr" }, + { pic16cr62, PROC_CLASS_PIC14, "__16CR62", { "pic16cr62", "p16cr62", "16cr62" }, 0xdc62, 1, 2, 0x7ff, "16cr62.lkr" }, + { pic16cr620a, PROC_CLASS_PIC14, "__16CR620A", { "pic16cr620a", "p16cr620a", "16cr620a" }, 0xd20a, 1, 2, 0x1ff, "16cr620a.lkr" }, + { pic16cr63, PROC_CLASS_PIC14, "__16CR63", { "pic16cr63", "p16cr63", "16cr63" }, 0x6d63, 2, 2, 0xfff, "16cr63.lkr" }, + { pic16cr64, PROC_CLASS_PIC14, "__16CR64", { "pic16cr64", "p16cr64", "16cr64" }, 0xdc64, 1, 2, 0x7ff, "16cr64.lkr" }, + { pic16cr65, PROC_CLASS_PIC14, "__16CR65", { "pic16cr65", "p16cr65", "16cr65" }, 0x6d65, 2, 2, 0xfff, "16cr65.lkr" }, + { pic16cr72, PROC_CLASS_PIC14, "__16CR72", { "pic16cr72", "p16cr72", "16cr72" }, 0x6d72, 1, 2, 0x7ff, "16cr72.lkr" }, + { pic16cr83, PROC_CLASS_PIC14, "__16CR83", { "pic16cr83", "p16cr83", "16cr83" }, 0xdc83, 1, 2, 0x1ff, "16cr83.lkr" }, + { pic16cr84, PROC_CLASS_PIC14, "__16CR84", { "pic16cr84", "p16cr84", "16cr84" }, 0xdc84, 1, 2, 0x3ff, "16cr84.lkr" }, + { pic16f505, PROC_CLASS_PIC12, "__16F505", { "pic16f505", "p16f505", "16f505" }, 0x654f, 2, 4, 0x3ff, "16f505.lkr" }, + { pic16f54, PROC_CLASS_PIC12, "__16F54", { "pic16f54", "p16f54", "16f54" }, 0x654f, 1, 1, 0x1ff, "16f54.lkr" }, + { pic16f57, PROC_CLASS_PIC12, "__16F57", { "pic16f57", "p16f57", "16f57" }, 0x657f, 4, 4, 0x7ff, "16f57.lkr" }, + { pic16f59, PROC_CLASS_PIC12, "__16F59", { "pic16f59", "p16f59", "16f59" }, 0x659f, 4, 4, 0x7ff, "16f59.lkr" }, + { pic16f610, PROC_CLASS_PIC14, "__16F610", { "pic16f610", "p16f610", "16f610" }, 0x6610, 1, 4, 0x3ff, "16f610.lkr" }, + { pic16f627, PROC_CLASS_PIC14, "__16F627", { "pic16f627", "p16f627", "16f627" }, 0x6627, 1, 4, 0x3ff, "16f627.lkr" }, + { pic16f627a, PROC_CLASS_PIC14, "__16F627A", { "pic16f627a", "p16f627a", "16f627a" }, 0x627a, 1, 4, 0x3ff, "16f627a.lkr" }, + { pic16f628, PROC_CLASS_PIC14, "__16F628", { "pic16f628", "p16f628", "16f628" }, 0x6628, 1, 4, 0x7ff, "16f628.lkr" }, + { pic16f628a, PROC_CLASS_PIC14, "__16F628A", { "pic16f628a", "p16f628a", "16f628a" }, 0x628a, 1, 4, 0x7ff, "16f628a.lkr" }, + { pic16f630, PROC_CLASS_PIC14, "__16F630", { "pic16f630", "p16f630", "16f630" }, 0x6630, 1, 2, 0x3fe, "16f630.lkr" }, + { pic16f636, PROC_CLASS_PIC14, "__16F636", { "pic16f636", "p16f636", "16f636" }, 0x6636, 1, 4, 0x7ff, "16f636.lkr" }, + { pic16f639, PROC_CLASS_PIC14, "__16F639", { "pic16f639", "p16f639", "16f639" }, 0x6639, 1, 4, 0x7ff, "16f639.lkr" }, + { pic16f648a, PROC_CLASS_PIC14, "__16F648A", { "pic16f648a", "p16f648a", "16f648a" }, 0x648a, 2, 4, 0xfff, "16f648a.lkr" }, + { pic16f676, PROC_CLASS_PIC14, "__16F676", { "pic16f676", "p16f676", "16f676" }, 0x6676, 1, 2, 0x3fe, "16f676.lkr" }, + { pic16f684, PROC_CLASS_PIC14, "__16F684", { "pic16f684", "p16f684", "16f684" }, 0x6684, 1, 2, 0x7ff, "16f684.lkr" }, + { pic16f685, PROC_CLASS_PIC14, "__16F685", { "pic16f685", "p16f685", "16f685" }, 0x6685, 2, 4, 0xfff, "16f685.lkr" }, + { pic16f687, PROC_CLASS_PIC14, "__16F687", { "pic16f687", "p16f687", "16f687" }, 0x6687, 1, 4, 0x7ff, "16f687.lkr" }, + { pic16f688, PROC_CLASS_PIC14, "__16F688", { "pic16f688", "p16f688", "16f688" }, 0x6688, 2, 4, 0xfff, "16f688.lkr" }, + { pic16f689, PROC_CLASS_PIC14, "__16F689", { "pic16f689", "p16f689", "16f689" }, 0x6689, 2, 4, 0xfff, "16f689.lkr" }, + { pic16f690, PROC_CLASS_PIC14, "__16F690", { "pic16f690", "p16f690", "16f690" }, 0x6690, 2, 4, 0xfff, "16f690.lkr" }, + { pic16f716, PROC_CLASS_PIC14, "__16F716", { "pic16f716", "p16f716", "16f716" }, 0x716f, 1, 2, 0x7ff, "16f716.lkr" }, + { pic16f72, PROC_CLASS_PIC14, "__16F72", { "pic16f72", "p16f72", "16f72" }, 0x672f, 1, 4, 0x7ff, "16f72.lkr" }, + { pic16f73, PROC_CLASS_PIC14, "__16F73", { "pic16f73", "p16f73", "16f73" }, 0x673f, 2, 4, 0xfff, "16f73.lkr" }, + { pic16f737, PROC_CLASS_PIC14, "__16F737", { "pic16f737", "p16f737", "16f737" }, 0x737f, 2, 4, 0xfff, "16f737.lkr" }, + { pic16f74, PROC_CLASS_PIC14, "__16F74", { "pic16f74", "p16f74", "16f74" }, 0x674f, 2, 4, 0xfff, "16f74.lkr" }, + { pic16f747, PROC_CLASS_PIC14, "__16F747", { "pic16f747", "p16f747", "16f747" }, 0x6747, 2, 4, 0xfff, "16f747.lkr" }, + { pic16f76, PROC_CLASS_PIC14, "__16F76", { "pic16f76", "p16f76", "16f76" }, 0x676f, 4, 4, 0x1fff, "16f76.lkr" }, + { pic16f767, PROC_CLASS_PIC14, "__16F767", { "pic16f767", "p16f767", "16f767" }, 0x767f, 4, 4, 0x1fff, "16f767.lkr" }, + { pic16f77, PROC_CLASS_PIC14, "__16F77", { "pic16f77", "p16f77", "16f77" }, 0x677f, 4, 4, 0x1fff, "16f77.lkr" }, + { pic16f777, PROC_CLASS_PIC14, "__16F777", { "pic16f777", "p16f777", "16f777" }, 0x777f, 4, 4, 0x1fff, "16f777.lkr" }, + { pic16f785, PROC_CLASS_PIC14, "__16F785", { "pic16f785", "p16f785", "16f785" }, 0x785f, 1, 4, 0x7ff, "16f785.lkr" }, + { pic16f818, PROC_CLASS_PIC14, "__16F818", { "pic16f818", "p16f818", "16f818" }, 0x818f, 1, 4, 0x3ff, "16f818.lkr" }, + { pic16f819, PROC_CLASS_PIC14, "__16F819", { "pic16f819", "p16f819", "16f819" }, 0x819f, 1, 4, 0x7ff, "16f819.lkr" }, + { pic16f83, PROC_CLASS_PIC14, "__16F83", { "pic16f83", "p16f83", "16f83" }, 0x6c83, 1, 2, 0x1ff, "16f83.lkr" }, + { pic16f84, PROC_CLASS_PIC14, "__16F84", { "pic16f84", "p16f84", "16f84" }, 0x6f84, 1, 2, 0x3ff, "16f84.lkr" }, + { pic16f84a, PROC_CLASS_PIC14, "__16F84A", { "pic16f84a", "p16f84a", "16f84a" }, 0x684a, 1, 2, 0x3ff, "16f84a.lkr" }, + { pic16f87, PROC_CLASS_PIC14, "__16F87", { "pic16f87", "p16f87", "16f87" }, 0x687f, 2, 4, 0xfff, "16f87.lkr" }, + { pic16f870, PROC_CLASS_PIC14, "__16F870", { "pic16f870", "p16f870", "16f870" }, 0x870f, 1, 4, 0x7ff, "16f870.lkr" }, + { pic16f871, PROC_CLASS_PIC14, "__16F871", { "pic16f871", "p16f871", "16f871" }, 0x871f, 1, 4, 0x7ff, "16f871.lkr" }, + { pic16f872, PROC_CLASS_PIC14, "__16F872", { "pic16f872", "p16f872", "16f872" }, 0x872f, 1, 4, 0x7ff, "16f872.lkr" }, + { pic16f873, PROC_CLASS_PIC14, "__16F873", { "pic16f873", "p16f873", "16f873" }, 0x873f, 2, 4, 0xfff, "16f873.lkr" }, + { pic16f873a, PROC_CLASS_PIC14, "__16F873A", { "pic16f873a", "p16f873a", "16f873a" }, 0x873a, 2, 4, 0xfff, "16f873a.lkr" }, + { pic16f874, PROC_CLASS_PIC14, "__16F874", { "pic16f874", "p16f874", "16f874" }, 0x874f, 2, 4, 0xfff, "16f874.lkr" }, + { pic16f874a, PROC_CLASS_PIC14, "__16F874A", { "pic16f874a", "p16f874a", "16f874a" }, 0x874a, 2, 4, 0xfff, "16f874a.lkr" }, + { pic16f876, PROC_CLASS_PIC14, "__16F876", { "pic16f876", "p16f876", "16f876" }, 0x876f, 4, 4, 0x1fff, "16f876.lkr" }, + { pic16f876a, PROC_CLASS_PIC14, "__16F876A", { "pic16f876a", "p16f876a", "16f876a" }, 0x876a, 4, 4, 0x1fff, "16f876a.lkr" }, + { pic16f877, PROC_CLASS_PIC14, "__16F877", { "pic16f877", "p16f877", "16f877" }, 0x877f, 4, 4, 0x1fff, "16f877.lkr" }, + { pic16f877a, PROC_CLASS_PIC14, "__16F877A", { "pic16f877a", "p16f877a", "16f877a" }, 0x877a, 4, 4, 0x1fff, "16f877a.lkr" }, + { pic16f88, PROC_CLASS_PIC14, "__16F88", { "pic16f88", "p16f88", "16f88" }, 0x688f, 4, 4, 0xfff, "16f88.lkr" }, + { pic16f882, PROC_CLASS_PIC14, "__16F882", { "pic16f882", "p16f882", "16f882" }, 0x882f, 4, 4, 0x7ff, "16f882.lkr" }, + { pic16f883, PROC_CLASS_PIC14, "__16F883", { "pic16f883", "p16f883", "16f883" }, 0x883f, 4, 4, 0xfff, "16f883.lkr" }, + { pic16f884, PROC_CLASS_PIC14, "__16F884", { "pic16f884", "p16f884", "16f884" }, 0x884f, 4, 4, 0xfff, "16f884.lkr" }, + { pic16f886, PROC_CLASS_PIC14, "__16F886", { "pic16f886", "p16f886", "16f886" }, 0x886f, 4, 4, 0x1fff, "16f886.lkr" }, + { pic16f887, PROC_CLASS_PIC14, "__16F887", { "pic16f887", "p16f887", "16f887" }, 0x887f, 4, 4, 0x1fff, "16f887.lkr" }, + { pic16f913, PROC_CLASS_PIC14, "__16F913", { "pic16f913", "p16f913", "16f913" }, 0x913f, 2, 4, 0xfff, "16f913.lkr" }, + { pic16f914, PROC_CLASS_PIC14, "__16F914", { "pic16f914", "p16f914", "16f914" }, 0x914f, 4, 4, 0xfff, "16f914.lkr" }, + { pic16f916, PROC_CLASS_PIC14, "__16F916", { "pic16f916", "p16f916", "16f916" }, 0x916f, 2, 4, 0x1fff, "16f916.lkr" }, + { pic16f917, PROC_CLASS_PIC14, "__16F917", { "pic16f917", "p16f917", "16f917" }, 0x917f, 4, 4, 0x1fff, "16f917.lkr" }, + { pic16hv540, PROC_CLASS_PIC12, "__16HV540", { "pic16hv540", "p16hv540", "16hv540" }, 0x6540, 1, 1, 0x1ff, "16hv540.lkr" }, + { pic17cxx, PROC_CLASS_PIC16, "__17CXX", { "pic17cxx", "p17cxx", "17cxx" }, 0x7756, 0, 0, -1, NULL }, + { pic17c42, PROC_CLASS_PIC16, "__17C42", { "pic17c42", "p17c42", "17c42" }, 0x7c42, 0, 0, 0x7ff, "17c42.lkr" }, + { pic17c42a, PROC_CLASS_PIC16, "__17C42A", { "pic17c42a", "p17c42a", "17c42a" }, 0x742a, 0, 0, 0x7ff, "17c42a.lkr" }, + { pic17c43, PROC_CLASS_PIC16, "__17C43", { "pic17c43", "p17c43", "17c43" }, 0x7c43, 0, 0, 0xfff, "17c43.lkr" }, + { pic17c44, PROC_CLASS_PIC16, "__17C44", { "pic17c44", "p17c44", "17c44" }, 0x7c44, 0, 0, 0x1fff, "17c44.lkr" }, + { pic17c752, PROC_CLASS_PIC16, "__17C752", { "pic17c752", "p17c752", "17c752" }, 0x7752, 0, 0, 0x1fff, "17c752.lkr" }, + { pic17c756, PROC_CLASS_PIC16, "__17C756", { "pic17c756", "p17c756", "17c756" }, 0x7756, 0, 0, 0x3fff, "17c756.lkr" }, + { pic17c756a, PROC_CLASS_PIC16, "__17C756A", { "pic17c756a", "p17c756a", "17c756a" }, 0x756a, 0, 0, 0x3fff, "17c756a.lkr" }, + { pic17c762, PROC_CLASS_PIC16, "__17C762", { "pic17c762", "p17c762", "17c762" }, 0x7762, 0, 0, 0x1fff, "17c762.lkr" }, + { pic17c766, PROC_CLASS_PIC16, "__17C766", { "pic17c766", "p17c766", "17c766" }, 0x7766, 0, 0, 0x3fff, "17c766.lkr" }, + { pic17cr42, PROC_CLASS_PIC16, "__17CR42", { "pic17cr42", "p17cr42", "17cr42" }, 0xe42a, 0, 0, 0x7ff, "17cr42.lkr" }, + { pic17cr43, PROC_CLASS_PIC16, "__17CR43", { "pic17cr43", "p17cr43", "17cr43" }, 0xec43, 0, 0, 0xfff, "17cr43.lkr" }, + { pic18cxx, PROC_CLASS_PIC16E, "__18CXX", { "pic18cxx", "p18cxx", "18cxx" }, 0x8452, 0, 0, -1, NULL }, + { pic18c242, PROC_CLASS_PIC16E, "__18C242", { "pic18c242", "p18c242", "18c242" }, 0x8242, 0, 0, 0x3fff, "18c242.lkr" }, + { pic18c252, PROC_CLASS_PIC16E, "__18C252", { "pic18c252", "p18c252", "18c252" }, 0x8252, 0, 0, 0x7fff, "18c252.lkr" }, + { pic18c442, PROC_CLASS_PIC16E, "__18C442", { "pic18c442", "p18c442", "18c442" }, 0x8442, 0, 0, 0x3fff, "18c442.lkr" }, + { pic18c452, PROC_CLASS_PIC16E, "__18C452", { "pic18c452", "p18c452", "18c452" }, 0x8452, 0, 0, 0x7fff, "18c452.lkr" }, + { pic18c601, PROC_CLASS_PIC16E, "__18C601", { "pic18c601", "p18c601", "18c601" }, 0x8601, 0, 0, 0x3ffff, "18c601.lkr" }, + { pic18c658, PROC_CLASS_PIC16E, "__18C658", { "pic18c658", "p18c658", "18c658" }, 0x8658, 0, 0, 0x7fff, "18c658.lkr" }, + { pic18c801, PROC_CLASS_PIC16E, "__18C801", { "pic18c801", "p18c801", "18c801" }, 0x8801, 0, 0, 0x1fffff, "18c801.lkr" }, + { pic18c858, PROC_CLASS_PIC16E, "__18C858", { "pic18c858", "p18c858", "18c858" }, 0x8858, 0, 0, 0x7fff, "18c858.lkr" }, + { pic18f1220, PROC_CLASS_PIC16E, "__18F1220", { "pic18f1220", "p18f1220", "18f1220" }, 0xa122, 0, 0, 0xfff, "18f1220.lkr" }, + { pic18f1230, PROC_CLASS_PIC16E, "__18F1230", { "pic18f1230", "p18f1230", "18f1230" }, 0xa123, 0, 0, 0xfff, "18f1230.lkr" }, + { pic18f1320, PROC_CLASS_PIC16E, "__18F1320", { "pic18f1320", "p18f1320", "18f1320" }, 0xa132, 0, 0, 0x1fff, "18f1320.lkr" }, + { pic18f1330, PROC_CLASS_PIC16E, "__18F1330", { "pic18f1330", "p18f1330", "18f1330" }, 0xa133, 0, 0, 0x1fff, "18f1330.lkr" }, + { pic18f2220, PROC_CLASS_PIC16E, "__18F2220", { "pic18f2220", "p18f2220", "18f2220" }, 0xa222, 0, 0, 0xfff, "18f2220.lkr" }, + { pic18f2320, PROC_CLASS_PIC16E, "__18F2320", { "pic18f2320", "p18f2320", "18f2320" }, 0xa232, 0, 0, 0x1fff, "18f2320.lkr" }, + { pic18f2331, PROC_CLASS_PIC16E, "__18F2331", { "pic18f2331", "p18f2331", "18f2331" }, 0x2331, 0, 0, 0x1fff, "18f2331.lkr" }, + { pic18f2410, PROC_CLASS_PIC16E, "__18F2410", { "pic18f2410", "p18f2410", "18f2410" }, 0x2410, 0, 0, 0x3fff, "18f2410.lkr" }, + { pic18f242, PROC_CLASS_PIC16E, "__18F242", { "pic18f242", "p18f242", "18f242" }, 0x242f, 0, 0, 0x3fff, "18f242.lkr" }, + { pic18f2420, PROC_CLASS_PIC16E, "__18F2420", { "pic18f2420", "p18f2420", "18f2420" }, 0x2420, 0, 0, 0x3fff, "18f2420.lkr" }, + { pic18f2431, PROC_CLASS_PIC16E, "__18F2431", { "pic18f2431", "p18f2431", "18f2431" }, 0x2431, 0, 0, 0x3fff, "18f2431.lkr" }, + { pic18f2439, PROC_CLASS_PIC16E, "__18F2439", { "pic18f2439", "p18f2439", "18f2439" }, 0x2439, 0, 0, 0x2fff, "18f2439.lkr" }, + { pic18f2455, PROC_CLASS_PIC16E, "__18F2455", { "pic18f2455", "p18f2455", "18f2455" }, 0x2455, 0, 0, 0x5fff, "18f2455.lkr" }, + { pic18f248, PROC_CLASS_PIC16E, "__18F248", { "pic18f248", "p18f248", "18f248" }, 0x8248, 0, 0, 0x3fff, "18f248.lkr" }, + { pic18f2480, PROC_CLASS_PIC16E, "__18F2480", { "pic18f2480", "p18f2480", "18f2480" }, 0x2480, 0, 0, 0x3fff, "18f2480.lkr" }, + { pic18f24j10, PROC_CLASS_PIC16E, "__18F24J10", { "pic18f24j10", "p18f24j10", "18f24j10" }, 0xd410, 0, 0, 0x3ff7, "18f24j10.lkr" }, + { pic18f2510, PROC_CLASS_PIC16E, "__18F2510", { "pic18f2510", "p18f2510", "18f2510" }, 0x2510, 0, 0, 0x7fff, "18f2510.lkr" }, + { pic18f2515, PROC_CLASS_PIC16E, "__18F2515", { "pic18f2515", "p18f2515", "18f2515" }, 0x2515, 0, 0, 0xbfff, "18f2515.lkr" }, + { pic18f252, PROC_CLASS_PIC16E, "__18F252", { "pic18f252", "p18f252", "18f252" }, 0x252f, 0, 0, 0x7fff, "18f252.lkr" }, + { pic18f2520, PROC_CLASS_PIC16E, "__18F2520", { "pic18f2520", "p18f2520", "18f2520" }, 0x2520, 0, 0, 0x7fff, "18f2520.lkr" }, + { pic18f2525, PROC_CLASS_PIC16E, "__18F2525", { "pic18f2525", "p18f2525", "18f2525" }, 0x2525, 0, 0, 0xbfff, "18f2525.lkr" }, + { pic18f2539, PROC_CLASS_PIC16E, "__18F2539", { "pic18f2539", "p18f2539", "18f2539" }, 0x2539, 0, 0, 0x5fff, "18f2539.lkr" }, + { pic18f2550, PROC_CLASS_PIC16E, "__18F2550", { "pic18f2550", "p18f2550", "18f2550" }, 0x2550, 0, 0, 0x7fff, "18f2550.lkr" }, + { pic18f258, PROC_CLASS_PIC16E, "__18F258", { "pic18f258", "p18f258", "18f258" }, 0x8258, 0, 0, 0x7fff, "18f258.lkr" }, + { pic18f2580, PROC_CLASS_PIC16E, "__18F2580", { "pic18f2580", "p18f2580", "18f2580" }, 0x2580, 0, 0, 0x7fff, "18f2580.lkr" }, + { pic18f2585, PROC_CLASS_PIC16E, "__18F2585", { "pic18f2585", "p18f2585", "18f2585" }, 0x2585, 0, 0, 0xbfff, "18f2585.lkr" }, + { pic18f25j10, PROC_CLASS_PIC16E, "__18F25J10", { "pic18f25j10", "p18f25j10", "18f25j10" }, 0xd510, 0, 0, 0x7ff7, "18f25j10.lkr" }, + { pic18f2610, PROC_CLASS_PIC16E, "__18F2610", { "pic18f2610", "p18f2610", "18f2610" }, 0xa261, 0, 0, 0xffff, "18f2610.lkr" }, + { pic18f2620, PROC_CLASS_PIC16E, "__18F2620", { "pic18f2620", "p18f2620", "18f2620" }, 0xa262, 0, 0, 0xffff, "18f2620.lkr" }, + { pic18f2680, PROC_CLASS_PIC16E, "__18F2680", { "pic18f2680", "p18f2680", "18f2680" }, 0x2680, 0, 0, 0xffff, "18f2680.lkr" }, + { pic18f2681, PROC_CLASS_PIC16E, "__18F2681", { "pic18f2681", "p18f2681", "18f2681" }, 0x2681, 0, 0, -1, "18f2681.lkr" }, + { pic18f2682, PROC_CLASS_PIC16E, "__18F2682", { "pic18f2682", "p18f2682", "18f2682" }, 0x2682, 0, 0, 0x13fff, "18f2682.lkr" }, + { pic18f2685, PROC_CLASS_PIC16E, "__18F2685", { "pic18f2685", "p18f2685", "18f2685" }, 0x2685, 0, 0, 0x17fff, "18f2685.lkr" }, + { pic18f4220, PROC_CLASS_PIC16E, "__18F4220", { "pic18f4220", "p18f4220", "18f4220" }, 0xa422, 0, 0, 0xfff, "18f4220.lkr" }, + { pic18f4320, PROC_CLASS_PIC16E, "__18F4320", { "pic18f4320", "p18f4320", "18f4320" }, 0xa432, 0, 0, 0x1fff, "18f4320.lkr" }, + { pic18f4331, PROC_CLASS_PIC16E, "__18F4331", { "pic18f4331", "p18f4331", "18f4331" }, 0x4331, 0, 0, 0x1fff, "18f4331.lkr" }, + { pic18f4410, PROC_CLASS_PIC16E, "__18F4410", { "pic18f4410", "p18f4410", "18f4410" }, 0x4410, 0, 0, 0x3fff, "18f4410.lkr" }, + { pic18f442, PROC_CLASS_PIC16E, "__18F442", { "pic18f442", "p18f442", "18f442" }, 0x442f, 0, 0, 0x3fff, "18f442.lkr" }, + { pic18f4420, PROC_CLASS_PIC16E, "__18F4420", { "pic18f4420", "p18f4420", "18f4420" }, 0x4420, 0, 0, 0x3fff, "18f4420.lkr" }, + { pic18f4431, PROC_CLASS_PIC16E, "__18F4431", { "pic18f4431", "p18f4431", "18f4431" }, 0x4431, 0, 0, 0x1fff, "18f4431.lkr" }, + { pic18f4439, PROC_CLASS_PIC16E, "__18F4439", { "pic18f4439", "p18f4439", "18f4439" }, 0x4439, 0, 0, 0x2fff, "18f4439.lkr" }, + { pic18f4455, PROC_CLASS_PIC16E, "__18F4455", { "pic18f4455", "p18f4455", "18f4455" }, 0x4455, 0, 0, 0x5fff, "18f4455.lkr" }, + { pic18f448, PROC_CLASS_PIC16E, "__18F448", { "pic18f448", "p18f448", "18f448" }, 0x8448, 0, 0, 0x3fff, "18f448.lkr" }, + { pic18f4480, PROC_CLASS_PIC16E, "__18F4480", { "pic18f4480", "p18f4480", "18f4480" }, 0x4480, 0, 0, 0x3fff, "18f4480.lkr" }, + { pic18f44j10, PROC_CLASS_PIC16E, "__18F44J10", { "pic18f44j10", "p18f44j10", "18f44j10" }, 0xe410, 0, 0, 0x3ff7, "18f44j10.lkr" }, + { pic18f4510, PROC_CLASS_PIC16E, "__18F4510", { "pic18f4510", "p18f4510", "18f4510" }, 0x4510, 0, 0, 0x7fff, "18f4510.lkr" }, + { pic18f4515, PROC_CLASS_PIC16E, "__18F4515", { "pic18f4515", "p18f4515", "18f4515" }, 0x4515, 0, 0, 0xbfff, "18f4515.lkr" }, + { pic18f452, PROC_CLASS_PIC16E, "__18F452", { "pic18f452", "p18f452", "18f452" }, 0x452f, 0, 0, 0x7fff, "18f452.lkr" }, + { pic18f4520, PROC_CLASS_PIC16E, "__18F4520", { "pic18f4520", "p18f4520", "18f4520" }, 0x4520, 0, 0, 0x7fff, "18f4520.lkr" }, + { pic18f4525, PROC_CLASS_PIC16E, "__18F4525", { "pic18f4525", "p18f4525", "18f4525" }, 0x4525, 0, 0, 0xbfff, "18f4525.lkr" }, + { pic18f4539, PROC_CLASS_PIC16E, "__18F4539", { "pic18f4539", "p18f4539", "18f4539" }, 0x4539, 0, 0, 0x5fff, "18f4539.lkr" }, + { pic18f4550, PROC_CLASS_PIC16E, "__18F4550", { "pic18f4550", "p18f4550", "18f4550" }, 0x4550, 0, 0, 0x7fff, "18f4550.lkr" }, + { pic18f458, PROC_CLASS_PIC16E, "__18F458", { "pic18f458", "p18f458", "18f458" }, 0x8458, 0, 0, 0x7fff, "18f458.lkr" }, + { pic18f4580, PROC_CLASS_PIC16E, "__18F4580", { "pic18f4580", "p18f4580", "18f4580" }, 0x4580, 0, 0, 0x7fff, "18f4580.lkr" }, + { pic18f4585, PROC_CLASS_PIC16E, "__18F4585", { "pic18f4585", "p18f4585", "18f4585" }, 0x4585, 0, 0, 0xbfff, "18f4585.lkr" }, + { pic18f45j10, PROC_CLASS_PIC16E, "__18F45J10", { "pic18f45j10", "p18f45j10", "18f45j10" }, 0xe510, 0, 0, 0x7ff7, "18f45j10.lkr" }, + { pic18f4610, PROC_CLASS_PIC16E, "__18F4610", { "pic18f4610", "p18f4610", "18f4610" }, 0xa461, 0, 0, 0xffff, "18f4610.lkr" }, + { pic18f4620, PROC_CLASS_PIC16E, "__18F4620", { "pic18f4620", "p18f4620", "18f4620" }, 0xa462, 0, 0, 0xffff, "18f4620.lkr" }, + { pic18f4680, PROC_CLASS_PIC16E, "__18F4680", { "pic18f4680", "p18f4680", "18f4680" }, 0x4680, 0, 0, 0xffff, "18f4680.lkr" }, + { pic18f4681, PROC_CLASS_PIC16E, "__18F4681", { "pic18f4681", "p18f4681", "18f4681" }, 0x4681, 0, 0, -1, "18f4681.lkr" }, + { pic18f4682, PROC_CLASS_PIC16E, "__18F4682", { "pic18f4682", "p18f4682", "18f4682" }, 0x4682, 0, 0, 0x13fff, "18f4682.lkr" }, + { pic18f4685, PROC_CLASS_PIC16E, "__18F4685", { "pic18f4685", "p18f4685", "18f4685" }, 0x4685, 0, 0, 0x17fff, "18f4685.lkr" }, + { pic18f6310, PROC_CLASS_PIC16E, "__18F6310", { "pic18f6310", "p18f6310", "18f6310" }, 0xa631, 0, 0, 0x1fff, "18f6310.lkr" }, + { pic18f6390, PROC_CLASS_PIC16E, "__18F6390", { "pic18f6390", "p18f6390", "18f6390" }, 0xa639, 0, 0, 0x1fff, "18f6390.lkr" }, + { pic18f6410, PROC_CLASS_PIC16E, "__18F6410", { "pic18f6410", "p18f6410", "18f6410" }, 0xa641, 0, 0, 0x3fff, "18f6410.lkr" }, + { pic18f6490, PROC_CLASS_PIC16E, "__18F6490", { "pic18f6490", "p18f6490", "18f6490" }, 0xa649, 0, 0, 0x3fff, "18f6490.lkr" }, + { pic18f64j15, PROC_CLASS_PIC16E, "__18F64J15", { "pic18f64j15", "p18f64j15", "18f64j15" }, 0xb415, 0, 0, -1, "18f64j15.lkr" }, + { pic18f6520, PROC_CLASS_PIC16E, "__18F6520", { "pic18f6520", "p18f6520", "18f6520" }, 0xa652, 0, 0, 0x7fff, "18f6520.lkr" }, + { pic18f6525, PROC_CLASS_PIC16E, "__18F6525", { "pic18f6525", "p18f6525", "18f6525" }, 0x6525, 0, 0, 0xbfff, "18f6525.lkr" }, + { pic18f6585, PROC_CLASS_PIC16E, "__18F6585", { "pic18f6585", "p18f6585", "18f6585" }, 0x6585, 0, 0, 0xbfff, "18f6585.lkr" }, + { pic18f65j10, PROC_CLASS_PIC16E, "__18F65J10", { "pic18f65j10", "p18f65j10", "18f65j10" }, 0xb510, 0, 0, 0xbfff, "18f65j10.lkr" }, + { pic18f65j15, PROC_CLASS_PIC16E, "__18F65J15", { "pic18f65j15", "p18f65j15", "18f65j15" }, 0xb515, 0, 0, 0xbff7, "18f65j15.lkr" }, + { pic18f6620, PROC_CLASS_PIC16E, "__18F6620", { "pic18f6620", "p18f6620", "18f6620" }, 0xa662, 0, 0, 0xffff, "18f6620.lkr" }, + { pic18f6621, PROC_CLASS_PIC16E, "__18F6621", { "pic18f6621", "p18f6621", "18f6621" }, 0xa621, 0, 0, 0xffff, "18f6621.lkr" }, + { pic18f6627, PROC_CLASS_PIC16E, "__18F6627", { "pic18f6627", "p18f6627", "18f6627" }, 0xa627, 0, 0, 0x17fff, "18f6627.lkr" }, + { pic18f6680, PROC_CLASS_PIC16E, "__18F6680", { "pic18f6680", "p18f6680", "18f6680" }, 0x6680, 0, 0, 0xffff, "18f6680.lkr" }, + { pic18f66j10, PROC_CLASS_PIC16E, "__18F66J10", { "pic18f66j10", "p18f66j10", "18f66j10" }, 0xb610, 0, 0, 0xfff7, "18f66j10.lkr" }, + { pic18f66j15, PROC_CLASS_PIC16E, "__18F66J15", { "pic18f66j15", "p18f66j15", "18f66j15" }, 0xb615, 0, 0, 0x17ff7, "18f66j15.lkr" }, + { pic18f6720, PROC_CLASS_PIC16E, "__18F6720", { "pic18f6720", "p18f6720", "18f6720" }, 0xa672, 0, 0, 0x1ffff, "18f6720.lkr" }, + { pic18f6722, PROC_CLASS_PIC16E, "__18F6722", { "pic18f6722", "p18f6722", "18f6722" }, 0x6722, 0, 0, 0x1ffff, "18f6722.lkr" }, + { pic18f67j10, PROC_CLASS_PIC16E, "__18F67J10", { "pic18f67j10", "p18f67j10", "18f67j10" }, 0xb710, 0, 0, 0x1fff7, "18f67j10.lkr" }, + { pic18f8310, PROC_CLASS_PIC16E, "__18F8310", { "pic18f8310", "p18f8310", "18f8310" }, 0x8310, 0, 0, 0x1fff, "18f8310.lkr" }, + { pic18f8390, PROC_CLASS_PIC16E, "__18F8390", { "pic18f8390", "p18f8390", "18f8390" }, 0x8390, 0, 0, 0x1fff, "18f8390.lkr" }, + { pic18f8410, PROC_CLASS_PIC16E, "__18F8410", { "pic18f8410", "p18f8410", "18f8410" }, 0x8410, 0, 0, 0x3fff, "18f8410.lkr" }, + { pic18f8490, PROC_CLASS_PIC16E, "__18F8490", { "pic18f8490", "p18f8490", "18f8490" }, 0x8490, 0, 0, 0x3fff, "18f8490.lkr" }, + { pic18f84j15, PROC_CLASS_PIC16E, "__18F84J15", { "pic18f84j15", "p18f84j15", "18f84j15" }, 0xc415, 0, 0, -1, "18f84j15.lkr" }, + { pic18f8520, PROC_CLASS_PIC16E, "__18F8520", { "pic18f8520", "p18f8520", "18f8520" }, 0xa852, 0, 0, 0x7fff, "18f8520.lkr" }, + { pic18f8525, PROC_CLASS_PIC16E, "__18F8525", { "pic18f8525", "p18f8525", "18f8525" }, 0x8525, 0, 0, 0xbfff, "18f8525.lkr" }, + { pic18f8585, PROC_CLASS_PIC16E, "__18F8585", { "pic18f8585", "p18f8585", "18f8585" }, 0x8585, 0, 0, 0xbfff, "18f8585.lkr" }, + { pic18f85j10, PROC_CLASS_PIC16E, "__18F85J10", { "pic18f85j10", "p18f85j10", "18f85j10" }, 0xc510, 0, 0, 0x7ff7, "18f85j10.lkr" }, + { pic18f85j15, PROC_CLASS_PIC16E, "__18F85J15", { "pic18f85j15", "p18f85j15", "18f85j15" }, 0xc515, 0, 0, 0xbff7, "18f85j15.lkr" }, + { pic18f8620, PROC_CLASS_PIC16E, "__18F8620", { "pic18f8620", "p18f8620", "18f8620" }, 0xa862, 0, 0, 0xffff, "18f8620.lkr" }, + { pic18f8621, PROC_CLASS_PIC16E, "__18F8621", { "pic18f8621", "p18f8621", "18f8621" }, 0x8621, 0, 0, 0xffff, "18f8621.lkr" }, + { pic18f8627, PROC_CLASS_PIC16E, "__18F8627", { "pic18f8627", "p18f8627", "18f8627" }, 0x8627, 0, 0, 0x17fff, "18f8627.lkr" }, + { pic18f8680, PROC_CLASS_PIC16E, "__18F8680", { "pic18f8680", "p18f8680", "18f8680" }, 0x8680, 0, 0, 0xffff, "18f8680.lkr" }, + { pic18f86j10, PROC_CLASS_PIC16E, "__18F86J10", { "pic18f86j10", "p18f86j10", "18f86j10" }, 0xc610, 0, 0, 0xfff7, "18f86j10.lkr" }, + { pic18f86j15, PROC_CLASS_PIC16E, "__18F86J15", { "pic18f86j15", "p18f86j15", "18f86j15" }, 0xc615, 0, 0, 0x17ff7, "18f86j15.lkr" }, + { pic18f8720, PROC_CLASS_PIC16E, "__18F8720", { "pic18f8720", "p18f8720", "18f8720" }, 0xa872, 0, 0, 0x1ffff, "18f8720.lkr" }, + { pic18f8722, PROC_CLASS_PIC16E, "__18F8722", { "pic18f8722", "p18f8722", "18f8722" }, 0x8721, 0, 0, 0x1ffff, "18f8722.lkr" }, + { pic18f87j10, PROC_CLASS_PIC16E, "__18F87J10", { "pic18f87j10", "p18f87j10", "18f87j10" }, 0xc710, 0, 0, 0x1fff7, "18f87j10.lkr" }, + { rf509af, PROC_CLASS_PIC12, "__RF509AF", { "rf509af", "rf509af", "rf509af" }, 0x6509, 0, 0, 0x3ff, "rf509af.lkr" }, + { rf509ag, PROC_CLASS_PIC12, "__RF509AG", { "rf509ag", "rf509ag", "rf509ag" }, 0x7509, 0, 0, 0x3ff, "rf509ag.lkr" }, + { rf675f, PROC_CLASS_PIC14, "__RF675F", { "rf675f", "rf675f", "rf675f" }, 0x3675, 0, 0, 0x3fe, "rf675f.lkr" }, + { rf675h, PROC_CLASS_PIC14, "__RF675H", { "rf675h", "rf675h", "rf675h" }, 0x4675, 0, 0, 0x3fe, "rf675h.lkr" }, + { rf675k, PROC_CLASS_PIC14, "__RF675K", { "rf675k", "rf675k", "rf675k" }, 0x5675, 0, 0, 0x3fe, "rf675k.lkr" }, + { sx18, PROC_CLASS_SX, "__SX18", { "sx18ac", "sx18", "sx18" }, 0x0018, 0, 0, 0x7ff, NULL }, + { sx20, PROC_CLASS_SX, "__SX20", { "sx20ac", "sx20", "sx20" }, 0x0020, 0, 0, 0x7ff, NULL }, + { sx28, PROC_CLASS_SX, "__SX28", { "sx28ac", "sx28", "sx28" }, 0x0028, 0, 0, 0x7ff, NULL }, + { sx48, PROC_CLASS_SX, "__SX48", { "sx48bd", "sx48", "sx48" }, 0x0048, 0, 0, 0xfff, NULL }, + { sx52, PROC_CLASS_SX, "__SX52", { "sx52bd", "sx52", "sx52" }, 0x0052, 0, 0, 0xfff, NULL }, + + { no_processor,PROC_CLASS_UNKNOWN, 0, { 0, 0, 0, }, 0x0, 0, 0, 0x0, 0 } +}; diff --git a/src/coff/xml/gpprocessor.h b/src/coff/xml/gpprocessor.h new file mode 100644 index 0000000..5e0ad41 --- /dev/null +++ b/src/coff/xml/gpprocessor.h @@ -0,0 +1,371 @@ +/* GNU PIC processor definitions + Copyright (C) 2001, 2002, 2003, 2004, 2005 + Craig Franklin + +This file is part of gputils. + +gputils 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, or (at your option) +any later version. + +gputils 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 gputils; see the file COPYING. If not, write to +the Free Software Foundation, 51 Franklin Street, Fifth Floor, +Boston, MA 02110-1301, USA. */ + +#ifndef __GPPROCESSOR_H__ +#define __GPPROCESSOR_H__ + +enum proc_class { + PROC_CLASS_UNKNOWN, /* Unknown device */ + PROC_CLASS_EEPROM8, /* 8 bit EEPROM */ + PROC_CLASS_GENERIC, /* 12 bit device */ + PROC_CLASS_PIC12, /* 12 bit devices */ + PROC_CLASS_SX, /* 12 bit devices */ + PROC_CLASS_PIC14, /* 14 bit devices */ + PROC_CLASS_PIC16, /* 16 bit devices */ + PROC_CLASS_PIC16E /* enhanced 16 bit devices */ +}; + +/* XXXPRO: Need to add an entry for any extra processors. Please keep + this list sorted! */ + +enum pic_processor { + no_processor, + eeprom8, + generic, + pic10f200, + pic10f202, + pic10f204, + pic10f206, + pic10f220, + pic10f222, + pic12c508, + pic12c508a, + pic12c509, + pic12c509a, + pic12c671, + pic12c672, + pic12ce518, + pic12ce519, + pic12ce673, + pic12ce674, + pic12cr509a, + pic12f508, + pic12f509, + pic12f510, + pic12f629, + pic12f635, + pic12f675, + pic12f683, + pic14000, + pic16c5x, + pic16cxx, + pic16c432, + pic16c433, + pic16c505, + pic16c54, + pic16c52, + pic16c54a, + pic16c54b, + pic16c54c, + pic16c55, + pic16c55a, + pic16c554, + pic16c557, + pic16c558, + pic16c56, + pic16c56a, + pic16c57, + pic16c57c, + pic16c58a, + pic16c58b, + pic16c61, + pic16c62, + pic16c62a, + pic16c62b, + pic16c620, + pic16c620a, + pic16c621, + pic16c621a, + pic16c622, + pic16c622a, + pic16c63, + pic16c63a, + pic16c64, + pic16c64a, + pic16c642, + pic16c65, + pic16c65a, + pic16c65b, + pic16c66, + pic16c662, + pic16c67, + pic16c71, + pic16c710, + pic16c711, + pic16c712, + pic16c715, + pic16c716, + pic16c717, + pic16c72, + pic16c72a, + pic16c73, + pic16c73a, + pic16c73b, + pic16c74, + pic16c745, + pic16c74a, + pic16c74b, + pic16c76, + pic16c765, + pic16c77, + pic16c770, + pic16c771, + pic16c773, + pic16c774, + pic16c781, + pic16c782, + pic16c84, + pic16c923, + pic16c924, + pic16c925, + pic16c926, + pic16ce623, + pic16ce624, + pic16ce625, + pic16cr54, + pic16cr54a, + pic16cr54b, + pic16cr54c, + pic16cr56a, + pic16cr57a, + pic16cr57b, + pic16cr57c, + pic16cr58a, + pic16cr58b, + pic16cr62, + pic16cr620a, + pic16cr63, + pic16cr64, + pic16cr65, + pic16cr72, + pic16cr83, + pic16cr84, + pic16f505, + pic16f54, + pic16f57, + pic16f59, + pic16f610, + pic16f627, + pic16f627a, + pic16f628, + pic16f628a, + pic16f630, + pic16f636, + pic16f639, + pic16f648a, + pic16f676, + pic16f684, + pic16f685, + pic16f687, + pic16f688, + pic16f689, + pic16f690, + pic16f716, + pic16f72, + pic16f73, + pic16f737, + pic16f74, + pic16f747, + pic16f76, + pic16f767, + pic16f77, + pic16f777, + pic16f785, + pic16f818, + pic16f819, + pic16f83, + pic16f84, + pic16f87, + pic16f84a, + pic16f870, + pic16f871, + pic16f872, + pic16f873, + pic16f873a, + pic16f874, + pic16f874a, + pic16f876, + pic16f876a, + pic16f877, + pic16f877a, + pic16f88, + pic16f882, + pic16f883, + pic16f884, + pic16f886, + pic16f887, + pic16f913, + pic16f914, + pic16f916, + pic16f917, + pic16hv540, + pic17cxx, + pic17c42, + pic17c42a, + pic17c43, + pic17c44, + pic17c752, + pic17c756, + pic17c756a, + pic17c762, + pic17c766, + pic17cr42, + pic17cr43, + pic18cxx, + pic18c242, + pic18c252, + pic18c442, + pic18c452, + pic18c601, + pic18c658, + pic18c801, + pic18c858, + pic18f1220, + pic18f1230, + pic18f1320, + pic18f1330, + pic18f2220, + pic18f2320, + pic18f2331, + pic18f2410, + pic18f242, + pic18f2420, + pic18f2431, + pic18f2439, + pic18f2455, + pic18f248, + pic18f2480, + pic18f24j10, + pic18f2510, + pic18f2515, + pic18f252, + pic18f2525, + pic18f2539, + pic18f2550, + pic18f2520, + pic18f258, + pic18f2580, + pic18f2585, + pic18f25j10, + pic18f2610, + pic18f2620, + pic18f2680, + pic18f2681, + pic18f2682, + pic18f2685, + pic18f4220, + pic18f4320, + pic18f4331, + pic18f4410, + pic18f442, + pic18f4420, + pic18f4431, + pic18f4439, + pic18f4455, + pic18f448, + pic18f4480, + pic18f44j10, + pic18f4510, + pic18f4515, + pic18f452, + pic18f4520, + pic18f4525, + pic18f4539, + pic18f4550, + pic18f458, + pic18f4580, + pic18f4585, + pic18f45j10, + pic18f4610, + pic18f4620, + pic18f4680, + pic18f4681, + pic18f4682, + pic18f4685, + pic18f6310, + pic18f6390, + pic18f6410, + pic18f6490, + pic18f64j15, + pic18f6520, + pic18f6525, + pic18f6585, + pic18f65j10, + pic18f65j15, + pic18f6620, + pic18f6621, + pic18f6627, + pic18f6680, + pic18f66j10, + pic18f66j15, + pic18f6720, + pic18f6722, + pic18f67j10, + pic18f8310, + pic18f8390, + pic18f8410, + pic18f8490, + pic18f84j15, + pic18f8520, + pic18f8525, + pic18f8585, + pic18f85j10, + pic18f85j15, + pic18f8620, + pic18f8621, + pic18f8627, + pic18f8680, + pic18f86j10, + pic18f86j15, + pic18f8720, + pic18f8722, + pic18f87j10, + rf509af, + rf509ag, + rf675f, + rf675h, + rf675k, + sx18, + sx20, + sx28, + sx48, + sx52 +}; + +#define MAX_NAMES 3 /* Maximum number of names a processor can have */ +#if !defined(NULL) +# define NULL 0 +#endif + +struct px { + enum pic_processor tag; + enum proc_class pclass; + const char *defined_as; + const char *names[MAX_NAMES]; + unsigned long coff_type; + int num_pages; + int num_banks; + long maxrom; + const char *script; +}; +extern const px pics[]; + +#endif diff --git a/src/coff/xml/xml.pro b/src/coff/xml/xml.pro new file mode 100644 index 0000000..bf1dc3a --- /dev/null +++ b/src/coff/xml/xml.pro @@ -0,0 +1,17 @@ +STOPDIR = ../../.. +include($${STOPDIR}/app.pro) + +TARGET = xml_coff_parser +SOURCES += gpprocessor.cpp xml_coff_parser.cpp +LIBS += ../../devices/list/libdevicelist.a \ + ../../devices/mem24/mem24/libmem24.a ../../devices/mem24/xml_data/libmem24xml.a \ + ../../devices/mem24/base/libmem24base.a \ + ../../devices/pic/pic/libpic.a ../../devices/pic/xml_data/libpicxml.a \ + ../../devices/pic/base/libpicbase.a ../../xml_to_data/libxmltodata.a \ + ../../devices/base/libdevicebase.a ../../common/global/libglobal.a \ + ../../common/nokde/libnokde.a ../../common/common/libcommon.a + +unix:QMAKE_POST_LINK = cd ../base && ../xml/xml_coff_parser +unix:QMAKE_CLEAN += ../base/coff_data.cpp +win32:QMAKE_POST_LINK = cd ..\base && ..\xml\xml_coff_parser.exe +win32:QMAKE_CLEAN += ..\base\coff_data.cpp diff --git a/src/coff/xml/xml_coff_parser.cpp b/src/coff/xml/xml_coff_parser.cpp new file mode 100644 index 0000000..b6fa2d8 --- /dev/null +++ b/src/coff/xml/xml_coff_parser.cpp @@ -0,0 +1,116 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "xml_to_data/prog_xml_to_data.h" +#include "coff/base/coff_data.h" + +#include "devices/base/device_group.h" +#include "devices/pic/base/pic.h" +#include "devices/list/device_list.h" +#include "gpprocessor.h" + +//----------------------------------------------------------------------------- +namespace Coff +{ + +class XmlToData : public ExtXmlToData +{ +public: + XmlToData() : ExtXmlToData("coff", "Coff") {} + +private: + QMap _ids; + virtual bool hasFamilies() const { return false; } + virtual void parseData(QDomElement element, Data &data); + virtual void outputData(const Data &data, QTextStream &s) const; + virtual void outputFunctions(QTextStream &s) const; + virtual void parse(); +}; + +void Coff::XmlToData::parseData(QDomElement element, Data &data) +{ + QStringList list = QStringList::split(' ', element.attribute("id")); + if ( list.isEmpty() ) qFatal("Missing id"); + if ( list.count()>MAX_NB_IDS ) qFatal("Please raise MAX_NB_IDS"); + for (uint i=0; i::outputFunctions(s); + s << "QString findId(uint id)" << endl; + s << "{" << endl; + s << " for (uint i=0; DATA_LIST[i]; i++) {" << endl; + s << " for (uint k=0; kdata.ids[k]==id ) return DATA_LIST[i]->name;" << endl; + s << " }" << endl; + s << " return QString::null;" << endl; + s << "}" << endl; +} + +void Coff::XmlToData::parse() +{ + ExtXmlToData::parse(); + + // check what devices we are missing + const ::Group::Base *gpic = Device::lister().group("pic"); + ::Group::Base::ConstIterator it; + for (it=gpic->begin(); it!=gpic->end(); ++it) { + const Pic::Data *data = static_cast(it.data().data); + switch (data->architecture().type()) { + case Pic::Architecture::P10X: + case Pic::Architecture::P16X: + case Pic::Architecture::P17C: + case Pic::Architecture::P18C: + case Pic::Architecture::P18F: + case Pic::Architecture::P18J: break; + case Pic::Architecture::P24F: + case Pic::Architecture::P24H: + case Pic::Architecture::P30F: + case Pic::Architecture::P33F: continue; + case Pic::Architecture::Nb_Types: Q_ASSERT(false); continue; + } + if ( !hasDevice(data->name()) ) qWarning("No id for device %s", data->name().latin1()); + } + + // extract COFF id from gputils + for (uint i=0; pics[i].tag!=no_processor; i++) { + _current = QString(pics[i].names[2]).upper(); + if ( !Device::lister().isSupported(_current) ) continue; + if ( !hasDevice(_current) ) qDebug(">> add new id %s: %s", _current.latin1(), toHexLabel(pics[i].coff_type, 4).latin1()); + else { + bool ok = false; + for (uint k=0; k * + * * + * 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. * + ***************************************************************************/ +#include "cli_global.h" + +#include + +#include "common/global/purl.h" +#include "cli_log.h" + +bool CLI::_force = false; +bool CLI::_isInteractive = false; +CLI::View *CLI::_view = 0; +CLI::MainBase *CLI::_main = 0; + +CLI::ExitCode CLI::errorExit(const QString &message, ExitCode code) +{ + Q_ASSERT( code!=OK ); + _view->log(Log::LineType::SoftError, message); + return code; +} + +CLI::ExitCode CLI::okExit(const QString &message) +{ + _view->log(Log::LineType::Information, message); + return OK; +} + +PURL::Directory CLI::runDirectory() +{ + return PURL::Directory(QDir::currentDirPath()); +} diff --git a/src/common/cli/cli_global.h b/src/common/cli/cli_global.h new file mode 100644 index 0000000..b90f36e --- /dev/null +++ b/src/common/cli/cli_global.h @@ -0,0 +1,33 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef CLI_GLOBAL_H +#define CLI_GLOBAL_H + +#include +namespace PURL { class Directory; } + +namespace CLI +{ + +class View; +class MainBase; +enum ExitCode { EXITING = 1, OK = 0, ARG_ERROR = -1, NOT_SUPPORTED_ERROR = -2, + FILE_ERROR = -3, EXEC_ERROR = -4 }; +extern ExitCode errorExit(const QString &message, ExitCode code); +extern ExitCode okExit(const QString &message); +extern PURL::Directory runDirectory(); + +extern bool _force; +extern bool _isInteractive; +extern View *_view; +extern MainBase *_main; + +} // namespace + +#endif diff --git a/src/common/cli/cli_log.cpp b/src/common/cli/cli_log.cpp new file mode 100644 index 0000000..603d5f8 --- /dev/null +++ b/src/common/cli/cli_log.cpp @@ -0,0 +1,74 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "cli_log.h" + +#include "common/global/global.h" +#include "cli_global.h" + +void CLI::View::doLog(Log::LineType type, const QString &text, Log::Action) +{ + QString s = text + "\n"; + switch (type.type()) { + case Log::LineType::Error: + case Log::LineType::SoftError: s = "Error: " + s; break; + case Log::LineType::Warning: s = "Warning: " + s; break; + default: break; + } +#if QT_VERSION<0x040000 + if ( type==Log::LineType::Error || type==Log::LineType::SoftError ) fprintf(stderr, "%s", s.latin1()); + else fprintf(stdout, "%s", s.latin1()); +#else + QByteArray ba = s.toLatin1(); + if ( type==Log::LineType::Error || type==Log::LineType::SoftError ) fprintf(stderr, "%s", ba.constData()); + else fprintf(stdout, "%s", ba.constData()); +#endif +} + +void CLI::View::doLog(Log::DebugLevel, const QString &text, Log::Action) +{ + QString s = text + "\n"; +#if QT_VERSION<0x040000 + fprintf(stdout, "%s", s.latin1()); +#else + QByteArray ba = s.toLatin1(); + fprintf(stdout, "%s", ba.constData()); +#endif +} + +void CLI::View::appendToLastLine(const QString &text) +{ +#if QT_VERSION<0x040000 + fprintf(stdout, "%s", text.latin1()); +#else + QByteArray ba = text.toLatin1(); + fprintf(stdout, "%s", ba.constData()); +#endif +} + +void CLI::View::sorry(const QString &message, const QString &details) +{ + if ( details.isEmpty() ) log(Log::LineType::Error, message, Log::Immediate); + else log(Log::LineType::Error, message + " (" + details + ")", Log::Immediate); +} + +bool CLI::View::askContinue(const QString &message) +{ + log(Log::LineType::Warning, message + " " + (_force ? i18n("*yes*") : i18n("*no*")), Log::Immediate); + if (_force) return true; + if ( !_isInteractive ) return false; // always fail + // #### TODO + return false; +} + +void CLI::View::logUserAbort() +{ + if ( !_isInteractive ) return; + return; + //Log::View::logUserAbort(); +} diff --git a/src/common/cli/cli_log.h b/src/common/cli/cli_log.h new file mode 100644 index 0000000..2fa83dc --- /dev/null +++ b/src/common/cli/cli_log.h @@ -0,0 +1,33 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef CLI_LOG_H +#define CLI_LOG_H + +#include "common/global/log.h" + +namespace CLI +{ + +class View : public Log::View +{ +public: + virtual void appendToLastLine(const QString &text); + virtual void clear() {} + virtual void sorry(const QString &message, const QString &details); + virtual bool askContinue(const QString &message); + virtual void logUserAbort(); + +private: + virtual void doLog(Log::LineType type, const QString &text, Log::Action action); + virtual void doLog(Log::DebugLevel level, const QString &text, Log::Action action); +}; + +} // namespace + +#endif diff --git a/src/common/cli/cli_main.cpp b/src/common/cli/cli_main.cpp new file mode 100644 index 0000000..7d75dbb --- /dev/null +++ b/src/common/cli/cli_main.cpp @@ -0,0 +1,208 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "cli_main.h" + +#include "cli_log.h" +#include "common/global/about.h" + +//----------------------------------------------------------------------------- +const CLI::CommandData *CLI::findCommandData(const QString &command) +{ + for (uint i=0; NORMAL_COMMAND_DATA[i].name; i++) + if ( NORMAL_COMMAND_DATA[i].name==command ) return &NORMAL_COMMAND_DATA[i]; + if ( !_isInteractive) return 0; + for (uint i=0; INTERACTIVE_COMMAND_DATA[i].name; i++) + if ( INTERACTIVE_COMMAND_DATA[i].name==command ) return &INTERACTIVE_COMMAND_DATA[i]; + return 0; +} + +CLI::ExitCode CLI::findCommand(const QString &s) +{ + if ( s.isEmpty() ) return errorExit(i18n("No command specified"), ARG_ERROR); + const CommandData *data = findCommandData(s); + if ( data==0 ) return errorExit(i18n("Unknown command: %1").arg(s), ARG_ERROR); + return OK; +} + +//----------------------------------------------------------------------------- +bool CLI::isPropertyList(const QString &s) +{ + for (uint i=0; PROPERTY_DATA[i].name; i++) + if ( s==PROPERTY_DATA[i].list ) return true; + return false; +} + +bool CLI::isProperty(const QString &s) +{ + for (uint i=0; PROPERTY_DATA[i].name; i++) + if ( s==PROPERTY_DATA[i].name ) return true; + return false; +} + +//----------------------------------------------------------------------------- +const KCmdLineOptions STANDARD_OPTIONS[] = { + { "c", 0, 0 }, + { "command ", I18N_NOOP("Perform the requested command."), 0 }, + { "command-list", I18N_NOOP("Return the list of recognized commands."), 0 }, + { "debug", I18N_NOOP("Display debug messages."), 0 }, + { "extra-debug", I18N_NOOP("Display extra debug messages."), 0 }, + { "max-debug", I18N_NOOP("Display all debug messages."), 0 }, + { "lowlevel-debug", I18N_NOOP("Display low level debug messages."), 0 }, + { "quiet", I18N_NOOP("Do not display messages."), 0 }, + KCmdLineLastOption +}; + +const KCmdLineOptions FORCE_OPTIONS[] = { + { "f", 0, 0 }, + { "force", I18N_NOOP("Overwrite files and answer \"yes\" to questions."), 0 }, + KCmdLineLastOption +}; + +const KCmdLineOptions INTERACTIVE_OPTIONS[] = { + { "i", 0, 0 }, + { "cli", I18N_NOOP("Interactive mode"), 0 }, + KCmdLineLastOption +}; + +CLI::OptionList::OptionList(Properties properties) +{ + init(properties); +} + +CLI::OptionList::OptionList(Properties properties, const KCmdLineOptions *options) +{ + init(properties); + for (uint i=0; options[i].name; i++) append(options[i]); +} + +void CLI::OptionList::init(Properties properties) +{ + for (uint i=0; STANDARD_OPTIONS[i].name; i++) append(STANDARD_OPTIONS[i]); + if ( properties & HasForce ) for (uint i=0; FORCE_OPTIONS[i].name; i++) append(FORCE_OPTIONS[i]); + if ( properties & HasInteractiveMode ) for (uint i=0; INTERACTIVE_OPTIONS[i].name; i++) append(INTERACTIVE_OPTIONS[i]); +} + +CLI::ExitCode CLI::commandList() +{ + Log::KeyList keys(i18n("Supported commands:")); + for (uint i=0; NORMAL_COMMAND_DATA[i].name; i++) + keys.append(NORMAL_COMMAND_DATA[i].name, i18n(NORMAL_COMMAND_DATA[i].help)); + if (_isInteractive) { + for (uint i=0; INTERACTIVE_COMMAND_DATA[i].name; i++) + keys.append(INTERACTIVE_COMMAND_DATA[i].name, i18n(INTERACTIVE_COMMAND_DATA[i].help)); + } + keys.display(*_view); + return OK; +} + +CLI::ExitCode CLI::propertyList() +{ + Log::KeyList keys; + for (uint i=0; PROPERTY_DATA[i].name; i++) + keys.append(PROPERTY_DATA[i].name, i18n(PROPERTY_DATA[i].help)); + keys.display(*_view); + return OK; +} + +//----------------------------------------------------------------------------- +CLI::MainBase::MainBase(Properties properties) + : QObject(0, "main"), _properties(properties) +{ + Q_ASSERT( _main==0 ); + _main = this; + _view = new View; + setView(_view); +} + +void CLI::MainBase::init() +{ + _args = KCmdLineArgs::parsedArgs(); + if ( _properties & HasInteractiveMode ) _isInteractive = _args->isSet("cli"); + if ( _properties & HasForce ) _force = _args->isSet("force"); + FOR_EACH(Log::DebugLevel, level) if ( _args->isSet(level.key()) ) _view->setDebugLevel(level); +} + +CLI::OptionList CLI::MainBase::optionList(const char *fileDescription) const +{ + OptionList list(_properties, OPTIONS); + KCmdLineOptions opt; + for (uint i=0; PROPERTY_DATA[i].name; i++) { + opt.description = 0; + opt.def = 0; + if ( PROPERTY_DATA[i].help==0 ) { + Q_ASSERT( QString(PROPERTY_DATA[i].name)!=PROPERTY_DATA[i].optName ); + opt.name = PROPERTY_DATA[i].name; // alias + list.append(opt); + } else { + if ( PROPERTY_DATA[i].optName==0 ) continue; // interactive only + if ( PROPERTY_DATA[i].alias ) { + opt.name = PROPERTY_DATA[i].alias; + list.append(opt); + } + opt.name = PROPERTY_DATA[i].optName; + opt.description = PROPERTY_DATA[i].help; + list.append(opt); + if ( PROPERTY_DATA[i].list ) { + opt.name = PROPERTY_DATA[i].list; + opt.description = PROPERTY_DATA[i].listHelp; + list.append(opt); + } + } + } + if (fileDescription) { + opt.name = "+[file]"; + opt.description = fileDescription; + opt.def = 0; + } + list.append(opt); + return list; +} + +CLI::ExitCode CLI::MainBase::list(const QString &command) +{ + if ( command=="command-list" ) return commandList(); + if ( command=="property-list" ) return propertyList(); + return ARG_ERROR; +} + +CLI::ExitCode CLI::MainBase::doRun() +{ + init(); + + // process set options + for (uint i=0; PROPERTY_DATA[i].name; i++) { + if ( PROPERTY_DATA[i].optName==0 ) continue; // alias or interactive only + if ( !_args->isSet(PROPERTY_DATA[i].name) ) continue; + QString option = _args->getOption(PROPERTY_DATA[i].name); + ExitCode code = executeSetCommand(PROPERTY_DATA[i].name, option); + if ( code!=OK ) return code; + log(Log::LineType::Information, QString("%1: %2").arg(PROPERTY_DATA[i].name).arg(executeGetCommand(PROPERTY_DATA[i].name))); + } + + // process default lists + if ( _args->isSet("command-list") ) return list("command-list"); + for (uint i=0; PROPERTY_DATA[i].name; i++) { + if ( PROPERTY_DATA[i].list==0 ) continue; + if ( _args->isSet(PROPERTY_DATA[i].list) ) return list(PROPERTY_DATA[i].list); + } + + bool interactive; + ExitCode code = prepareRun(interactive); + if ( code!=OK || interactive ) return code; + + // find command + QString command = _args->getOption("command"); + code = findCommand(command); + if ( code!=OK ) return code; + + // execute command + code = prepareCommand(command); + if ( code!=OK ) return code; + return executeCommand(command); +} diff --git a/src/common/cli/cli_main.h b/src/common/cli/cli_main.h new file mode 100644 index 0000000..9b54c70 --- /dev/null +++ b/src/common/cli/cli_main.h @@ -0,0 +1,82 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef CLI_MAIN_H +#define CLI_MAIN_H + +#include "common/global/about.h" +#include "common/global/log.h" +#include "cli_global.h" + +namespace CLI +{ +//----------------------------------------------------------------------------- +enum Property { NoProperty = 0, HasForce = 1, HasInteractiveMode = 2 }; +Q_DECLARE_FLAGS(Properties, Property) +Q_DECLARE_OPERATORS_FOR_FLAGS(Properties) + +extern const KCmdLineOptions OPTIONS[]; +//----------------------------------------------------------------------------- +struct CommandData { + const char *name; + int properties; + const char *help; +}; +extern const CommandData NORMAL_COMMAND_DATA[]; +extern const CommandData INTERACTIVE_COMMAND_DATA[]; +extern const CommandData *findCommandData(const QString &command); +extern ExitCode findCommand(const QString &s); +extern ExitCode commandList(); + +//----------------------------------------------------------------------------- +struct PropertyData +{ + const char *name, *optName, *alias, *help, *list, *listHelp; +}; +extern const PropertyData PROPERTY_DATA[]; +extern bool isPropertyList(const QString &s); +extern bool isProperty(const QString &s); +extern ExitCode propertyList(); + +//----------------------------------------------------------------------------- +class OptionList : public Piklab::OptionList +{ +public: + OptionList(Properties properties); + OptionList(Properties properties, const KCmdLineOptions *options); + +private: + void init(Properties properties); +}; + +//----------------------------------------------------------------------------- +class MainBase : public QObject, public Log::Base +{ +Q_OBJECT +public: + MainBase(Properties properties); + virtual OptionList optionList(const char *fileDescription) const; + virtual ExitCode doRun(); + virtual ExitCode list(const QString &listName); + virtual ExitCode prepareCommand(const QString &command) = 0; + virtual ExitCode executeCommand(const QString &command) = 0; + virtual ExitCode executeSetCommand(const QString &property, const QString &value) = 0; + virtual QString executeGetCommand(const QString &property) = 0; + +protected: + Properties _properties; + KCmdLineArgs *_args; + +private: + virtual ExitCode prepareRun(bool &interactive) = 0; + virtual void init(); +}; + +} // namespace + +#endif diff --git a/src/common/cli/cli_pfile.cpp b/src/common/cli/cli_pfile.cpp new file mode 100644 index 0000000..96add3a --- /dev/null +++ b/src/common/cli/cli_pfile.cpp @@ -0,0 +1,47 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "common/global/pfile.h" + +#include + +//----------------------------------------------------------------------------- +bool PURL::File::openForWrite() +{ + close(); + _file->setName(url().filepath()); + if ( !_file->open(IO_WriteOnly) ) { + _error = i18n("Could not open file for writing."); + _log.sorry(_error, i18n("File: %1").arg(_file->name())); + return false; + } + return true; +} + +bool PURL::File::close() +{ + _file->close(); + return ( uint(_file->status())==IO_Ok ); +} + +bool PURL::File::openForRead() +{ + close(); + _file->setName(_url.filepath()); + if ( !_file->open(IO_ReadOnly) ) { + _error = i18n("Could not open file for reading."); + _log.sorry(_error, i18n("File: %1").arg(_file->name())); + return false; + } + return true; +} + +bool PURL::File::remove() +{ + return _file->remove(); +} diff --git a/src/common/cli/cli_purl.cpp b/src/common/cli/cli_purl.cpp new file mode 100644 index 0000000..e52c977 --- /dev/null +++ b/src/common/cli/cli_purl.cpp @@ -0,0 +1,9 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "common/global/purl.h" diff --git a/src/common/common.pro b/src/common/common.pro new file mode 100644 index 0000000..aa219c1 --- /dev/null +++ b/src/common/common.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = common nokde global port cli diff --git a/src/common/common/Makefile.am b/src/common/common/Makefile.am new file mode 100644 index 0000000..0f68067 --- /dev/null +++ b/src/common/common/Makefile.am @@ -0,0 +1,9 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libcommon.la +libcommon_la_SOURCES = bitvalue.cpp group.cpp misc.cpp number.cpp purl_base.cpp \ + storage.cpp synchronous.cpp version_data.cpp +libcommon_la_LDFLAGS = $(all_libraries) + + diff --git a/src/common/common/bitvalue.cpp b/src/common/common/bitvalue.cpp new file mode 100644 index 0000000..16d5ef0 --- /dev/null +++ b/src/common/common/bitvalue.cpp @@ -0,0 +1,30 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "bitvalue.h" + +const uint GenericValue::INVALID = 0xFFFFFFFFU; + +BitValue BitValue::XORn(uint n) const +{ + uint nb = nbBits(_value); + uint mask = maxValue(NumberBase::Bin, n); + uint res = 0x0; + for (uint i=0; i> i) & mask; + //qDebug("%i %s %s", i, toHexLabel((value>>i) & mask, 4).latin1(), toHexLabel(res, 4).latin1()); + } + return res; +} + +BitValue BitValue::XNORn(uint n) const +{ + BitValue res = XORn(n); + BitValue mask = maxValue(NumberBase::Bin, n); + return res.complementInMask(mask); +} diff --git a/src/common/common/bitvalue.h b/src/common/common/bitvalue.h new file mode 100644 index 0000000..d3ef9fe --- /dev/null +++ b/src/common/common/bitvalue.h @@ -0,0 +1,129 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef BITVALUE_H +#define BITVALUE_H + +#include "number.h" +#include "range.h" + +//---------------------------------------------------------------------------- +class GenericValue +{ +public: + GenericValue(uint value) : _value(value) {} + + bool operator <(GenericValue v) const { CRASH_ASSERT(_value!=INVALID); return _value(GenericValue v) const { CRASH_ASSERT(_value!=INVALID); return _value>v._value; } + bool operator <=(GenericValue v) const { CRASH_ASSERT(_value!=INVALID); return _value<=v._value; } + bool operator >=(GenericValue v) const { CRASH_ASSERT(_value!=INVALID); return _value>=v._value; } + bool operator ==(GenericValue v) const { return _value==v._value; } + bool operator !=(GenericValue v) const { return _value!=v._value; } + + bool bit(uint index) const { return (_value >> index) & 0x1; } + uchar nybble(uint index) const { return (_value >> (4*index)) & 0xF; } + uchar byte(uint index) const { return (_value >> (8*index)) & 0xFF; } + uint toUInt() const { return _value; } + +protected: + static const uint INVALID; + uint _value; + +private: + friend QDataStream &operator <<(QDataStream &s, GenericValue v); + friend QDataStream &operator >>(QDataStream &s, GenericValue &v); +}; + +inline QDataStream &operator <<(QDataStream &s, GenericValue v) { s << v._value; return s; } +inline QDataStream &operator >>(QDataStream &s, GenericValue &v) { s >> v._value; return s; } + +inline QString toLabel(GenericValue v) { return QString::number(v.toUInt()); } +inline QString toLabel(NumberBase base, GenericValue v, uint nbChars) { return toLabel(base, v.toUInt(), nbChars); } +inline QString toHexLabel(GenericValue v, uint nbChars) { return toHexLabel(v.toUInt(), nbChars); } +inline QString toHex(GenericValue v, uint nbChars) { return toHex(v.toUInt(), nbChars); } +inline QString toHexLabelAbs(GenericValue v) { return ::toHexLabelAbs(v.toUInt()); } + +//---------------------------------------------------------------------------- +class Address : public GenericValue +{ +public: + Address(uint value = INVALID) : GenericValue(value) {} + bool isValid() const { return ( _value!=INVALID ); } + + Address &operator ++() { CRASH_ASSERT(_value!=INVALID); _value++; return *this; } + Address &operator ++(int) { CRASH_ASSERT(_value!=INVALID); _value++; return *this; } + Address operator +(int dec) const { CRASH_ASSERT(_value!=INVALID); return _value + dec; } + Address &operator +=(int dec) { CRASH_ASSERT(_value!=INVALID);_value += dec; return *this; } + Address &operator --() { CRASH_ASSERT(_value!=INVALID); _value--; return *this; } + Address &operator --(int) { CRASH_ASSERT(_value!=INVALID); _value--; return *this; } + Address operator -(int dec) const { CRASH_ASSERT(_value!=INVALID);return _value - dec; } + Address &operator -=(int dec) { CRASH_ASSERT(_value!=INVALID);_value -= dec; return *this; } + int operator -(Address a) const { CRASH_ASSERT(_value!=INVALID && a._value!=INVALID); return _value - a._value; } +}; + +class AddressRange : public GenericRange
+{ +public: + AddressRange() {} + AddressRange(Address s, Address e) { start = s; end = e; } + virtual bool isEmpty() const { return !start.isValid() || !end.isValid() || end<=start; } +}; + +typedef GenericRangeVector AddressRangeVector; + +//---------------------------------------------------------------------------- +class BitValue : public GenericValue +{ +public: + BitValue(uint value = INVALID) : GenericValue(value) {} + bool isInitialized() const { return ( _value!=INVALID ); } + + BitValue operator |(BitValue v) const { return _value | v._value; } + BitValue operator <<(uint shift) const { return _value << shift; } + BitValue operator >>(uint shift) const { return _value >> shift; } + BitValue operator +(BitValue v) const { return _value + v._value; } + + BitValue &operator |=(BitValue v) { _value |= v._value; return *this; } + BitValue &operator <<=(uint shift) { _value <<= shift; return *this; } + BitValue &operator >>=(uint shift) { _value >>= shift; return *this; } + BitValue &operator +=(BitValue v) { _value += v._value; return *this; } + + BitValue XORn(uint n) const; // XOR between groups of n bits inside value + BitValue XNORn(uint n) const; // XORn then NOT on n bits + + BitValue maskWith(BitValue mask) const { return _value & mask._value; } + bool isInside(BitValue v) const { return ( (_value & v._value)==_value ); } + BitValue complementInMask(BitValue mask) const { return mask._value & ~_value; } + BitValue twoComplement() const { return -_value; } + BitValue clearMaskBits(BitValue mask) const { return _value & ~mask._value; } + bool isOverlapping(BitValue v) const { return ( _value & v._value ); } + + class const_iterator { + public: + const_iterator() {} + bool operator !=(const_iterator it) const { return ( _current!=it._current ); } + BitValue operator *() const { return BitValue(_current); } + const_iterator &operator ++() { + do { + if ( _current==_value+1 ) _current = INVALID; + if ( _current==INVALID ) break; + _current++; + } while ( (_current & _value)!=_current ); + return *this; + } + private: + const_iterator(uint value, uint current) : _value(value), _current(current) {} + uint _value, _current; + friend class BitValue; + }; + const_iterator begin() const { return const_iterator(_value, 0); } + const_iterator end() const { return const_iterator(_value, INVALID); } + +}; + +#endif diff --git a/src/common/common/common.pro b/src/common/common/common.pro new file mode 100644 index 0000000..3451c92 --- /dev/null +++ b/src/common/common/common.pro @@ -0,0 +1,6 @@ +STOPDIR = ../../.. +include($${STOPDIR}/lib.pro) + +TARGET = common +HEADERS += qflags.h misc.h group.h storage.h synchronous.h purl_base.h number.h bitvalue.h key_enum.h version_data.h +SOURCES += misc.cpp group.cpp storage.cpp synchronous.cpp purl_base.cpp number.cpp bitvalue.cpp version_data.cpp diff --git a/src/common/common/group.cpp b/src/common/common/group.cpp new file mode 100644 index 0000000..2a0610f --- /dev/null +++ b/src/common/common/group.cpp @@ -0,0 +1,71 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "group.h" + +//----------------------------------------------------------------------------- +const Group::Support::Data Group::Support::DATA[Nb_Types] = { + { "not_supported", I18N_NOOP("Not Supported") }, + { "untested", I18N_NOOP("Untested") }, + { "tested", I18N_NOOP("Tested") } +}; + +Group::Base::Base() + : _gui(0), _initialized(false) +{} + +Group::Base::ConstIterator Group::Base::begin() const +{ + const_cast(*this).checkInitSupported(); + return _devices.begin(); +} + +Group::Base::ConstIterator Group::Base::end() const +{ + const_cast(*this).checkInitSupported(); + return _devices.end(); +} + +void Group::Base::addDevice(const QString &name, const Device::Data *data, Support support) +{ + _devices[name].data = data; + _devices[name].support = support; +} + +Group::Base::Data Group::Base::deviceData(const QString &device) const +{ + const_cast(*this).checkInitSupported(); + return _devices[device]; +} + +QValueVector Group::Base::supportedDevices() const +{ + const_cast(*this).checkInitSupported(); + QValueVector names; + for (ConstIterator it=begin(); it!=end(); ++it) names.append(it.key()); + return names; +} + +uint Group::Base::count() const +{ + const_cast(*this).checkInitSupported(); + return _devices.count(); +} + +void Group::Base::init() +{ + _initialized = false; +} + +void Group::Base::checkInitSupported() +{ + if (_initialized) return; + _initialized = true; + _devices.clear(); + initSupported(); +} diff --git a/src/common/common/group.h b/src/common/common/group.h new file mode 100644 index 0000000..2a87674 --- /dev/null +++ b/src/common/common/group.h @@ -0,0 +1,82 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef GROUP_H +#define GROUP_H + +#include +#include + +#include "common/global/global.h" +#include "key_enum.h" +namespace Device { class Data; } + +namespace Group +{ +//----------------------------------------------------------------------------- +class BaseGui; +BEGIN_DECLARE_ENUM(Support) + None = 0, Untested, Tested +END_DECLARE_ENUM_STD(Support) + +//----------------------------------------------------------------------------- +class Base +{ +public: + class Data { + public: + Data() : data(0), support(Support::None) {} + const Device::Data *data; + Support support; + }; + typedef QMap::ConstIterator ConstIterator; + + Base(); + virtual ~Base() {} + virtual QString name() const = 0; + virtual QString label() const = 0; + ConstIterator begin() const; + ConstIterator end() const; + Data deviceData(const QString &device) const; + bool isSupported(const QString &device) const { return deviceData(device).support!=Support::None; } + QValueVector supportedDevices() const; + uint count() const; + const BaseGui *gui() const { return _gui; } + void checkInitSupported(); + +protected: + virtual void init(); + virtual void addDevice(const QString &name, const Device::Data *data, Support support); + virtual void initSupported() = 0; + + QMap _devices; + +private: + const BaseGui *_gui; + bool _initialized; + + template friend class Lister; +}; + +//----------------------------------------------------------------------------- +class BaseGui +{ +public: + BaseGui() : _group(0) {} + virtual ~BaseGui() {} + const Base &group() const { return *_group; } + +private: + const Base *_group; + + template friend class Lister; +}; + +} // namespace + +#endif diff --git a/src/common/common/key_enum.h b/src/common/common/key_enum.h new file mode 100644 index 0000000..504ca56 --- /dev/null +++ b/src/common/common/key_enum.h @@ -0,0 +1,107 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef KEY_ENUM_H +#define KEY_ENUM_H + +#include + +#include "misc.h" +#include "common/global/global.h" + +class GenericEnum +{ +public: + GenericEnum(uint value) : _value(value) {} + bool operator ==(GenericEnum e) const { return _value==e._value; } + bool operator !=(GenericEnum e) const { return _value!=e._value; } + bool operator <(GenericEnum e) const { return _value(GenericEnum e) const { return _value>e._value; } + bool operator >=(GenericEnum e) const { return _value>=e._value; } + GenericEnum &operator ++() { _value++; return *this; } + +protected: + uint _value; + +private: + friend QDataStream &operator >>(QDataStream &s, GenericEnum &e); + friend QDataStream &operator <<(QDataStream &s, const GenericEnum &e); +}; + +inline QDataStream &operator <<(QDataStream &s, const GenericEnum &e) +{ + s << e._value; + return s; +} +inline QDataStream &operator >>(QDataStream &s, GenericEnum &e) +{ + s >> e._value; + return s; +} + +#define BEGIN_DECLARE_ENUM(Enum) \ +class Enum : public GenericEnum \ +{ \ +public: \ + enum Type { + +#define DECLARE_DATA \ +public: \ + static Type fromKey(const QString &key) { \ + for (uint i=0; i=0 && value<=Type(Nb_Types)); } \ + Type type() const { return Type(_value); } \ +}; + +#define END_DECLARE_ENUM(Enum, EnumData) \ + , Nb_Types \ + }; \ + typedef EnumData Data; \ + DECLARE_DATA \ + DECLARE_ENUM_CLASS(Enum) \ + +#define END_DECLARE_ENUM_STD(Enum) \ + , Nb_Types \ + }; \ + struct Data { \ + const char *key, *label; \ + }; \ + DECLARE_DATA \ + DECLARE_ENUM_CLASS(Enum) + +#define END_DECLARE_ENUM_NO_DATA(Enum) \ + , Nb_Types \ + }; \ + DECLARE_ENUM_CLASS(Enum) + +#define FOR_EACH(Enum, e) for(Enum e; e * + * * + * 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. * + ***************************************************************************/ +#ifndef LISTER_H +#define LISTER_H + +#include "group.h" + +namespace Group +{ +//----------------------------------------------------------------------------- +template +class Lister +{ +public: + typedef typename QMap::ConstIterator ConstIterator; + ConstIterator begin() const { return ConstIterator(_groups.begin()); } + ConstIterator end() const { return ConstIterator(_groups.end()); } + + virtual ~Lister() { + for (ConstIterator it=begin(); it!=end(); ++it) delete it.data(); + } + + QValueVector supportedDevices() const { + QValueVector names; + for (ConstIterator it=begin(); it!=end(); ++it) { + QValueVector gnames = it.data()->supportedDevices(); + for (uint k=0; kcount(); + return nb; + } + + bool isSupported(const QString &device) const { + for (ConstIterator it=begin(); it!=end(); ++it) + if ( it.data()->isSupported(device) ) return true; + return false; + } + + const GroupType *group(const QString &name) const { + if ( _groups.contains(name) ) return _groups[name]; + return 0; + } + +protected: + void addGroup(GroupType *group, BaseGui *gui) { + Q_ASSERT(group); + group->_gui = gui; + if (gui) gui->_group = group; + group->init(); + Q_ASSERT( !_groups.contains(group->name()) ); + _groups.insert(group->name(), group); + } + +private: + QMap _groups; +}; + +} // namespace + +#endif diff --git a/src/common/common/misc.cpp b/src/common/common/misc.cpp new file mode 100644 index 0000000..1974024 --- /dev/null +++ b/src/common/common/misc.cpp @@ -0,0 +1,72 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "misc.h" + +#include + +#include +#include + +#include "number.h" + +//----------------------------------------------------------------------------- +uchar bin2bcd(uchar bin) +{ + char h = bin / 10; + char l = bin % 10; + return (h*16) + l; +} + +uchar bcd2bin(uchar bcd) +{ + char h = bcd / 16; + char l = bcd % 16; + return (h*10) + l; +} + +QString escapeXml(const QString &cs) +{ + QString s; + for (uint i=0; i' ) s += ">"; + else s += cs[i]; + } + return s; +} + +QString htmlTableRow(const QString &title, const QString &value) +{ + return "" + title + ":" + value + ""; +} + +void crash(const char *assert, const char *file, int line) +{ + qDebug("CRASH_ASSERT: \"%s\" in %s (%d)", assert, file, line); + int * ptr = 0; + (*ptr)++; +} + +bool checkAvailable(const QByteArray &data, uint offset, uint nbBytes) +{ + return ( offset+nbBytes<=uint(data.size()) ); +} + +Q_UINT32 getULong(const QByteArray &data, uint offset, uint nbBytes, bool *ok) +{ + Q_ASSERT( nbBytes<=8 ); + if ( !checkAvailable(data, offset, nbBytes) ) { + if (ok) *ok = false; + return 0; + } + if (ok) *ok = true; + Q_UINT32 r = 0; + for (uint i=0; i * + * * + * 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. * + ***************************************************************************/ +#ifndef MISC_H +#define MISC_H + +#include + +inline QString repeat(const char *r, uint nb) +{ + QString s; + for (uint i=0; i=0; k--) if ( s[k]!=' ' ) break; + return s.mid(0, k+1); +} + +extern uchar bin2bcd(uchar bin); +extern uchar bcd2bin(uchar bcd); +inline bool XOR(bool b1, bool b2) { return ( (!b1 && b2) || (b1 && !b2) ); } + +extern bool checkAvailable(const QByteArray &data, uint offset, uint nbBytes); +extern Q_UINT32 getULong(const QByteArray &data, uint offset, uint nbBytes, bool *ok); + +extern QString escapeXml(const QString &s); +extern QString htmlTableRow(const QString &title, const QString &value); +extern void crash(const char *assert, const char *file, int line); +#define CRASH_ASSERT(x) ((x) ? void(0) : crash(#x, __FILE__, __LINE__)) + +#endif diff --git a/src/common/common/number.cpp b/src/common/common/number.cpp new file mode 100644 index 0000000..12fcac0 --- /dev/null +++ b/src/common/common/number.cpp @@ -0,0 +1,201 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "number.h" + +#include "common/global/global.h" +#include "misc.h" +#if !defined(NO_KDE) +# include +#endif + +//----------------------------------------------------------------------------- +const NumberBase::Data NumberBase::DATA[Nb_Types] = { + { 10, "", I18N_NOOP("Decimal"), "dec" }, + { 16, "0x", I18N_NOOP("Hexadecimal"), "hex" }, + { 2, "0b", I18N_NOOP("Binary"), "bin" }, + { 8, "o", I18N_NOOP("Octal"), "oct" }, + { 256, "", I18N_NOOP("String"), "str" } +}; + +char toChar(NumberBase base, uint value) +{ + Q_ASSERT( value=base.data().base ) qDebug("toChar %u (%u)", value, base.data().base); + if ( base==NumberBase::String ) { + if ( !isprint(value) ) return '.'; + return value; + } + if ( value<=9 ) return '0' + value; + return 'A' + value - 10; +} + +QString toString(NumberBase base, ulong value, uint nbChars) +{ + ulong tmp = value; + QString s; + s.fill(0, nbChars); + for (uint i=0; i='0' && c<='9' ) v = c - '0'; + else if ( c>='A' && c<'Z' ) v = 10 + c - 'A'; + else if ( c>='a' && c<'z' ) v = 10 + c - 'a'; + else { + if (ok) *ok = false; + return 0; + } + if (ok) *ok = ( v &values, uint nbChars) +{ + QString s = "["; + for (uint i=0; iformatNumber(v, 0); +#endif +} + +QByteArray toAscii(const QString &s) +{ + QByteArray a(s.length()); + for (uint i=0; i * + * * + * 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. * + ***************************************************************************/ +#ifndef NUMBER_H +#define NUMBER_H + +#include + +#include "common/global/global.h" +#include "key_enum.h" + +//---------------------------------------------------------------------------- +struct NumberBaseData { + uint base; + const char *prefix, *label,* key; +}; + +BEGIN_DECLARE_ENUM(NumberBase) + Dec = 0, Hex, Bin, Oct, String +END_DECLARE_ENUM(NumberBase, NumberBaseData) + +extern uint nbChars(NumberBase base, ulong value); +extern ulong maxValue(NumberBase base, uint nbChars); +inline uint convertNbChars(uint nb, NumberBase from, NumberBase to) { return nbChars(to, maxValue(from, nb)); } + +extern char toChar(NumberBase base, uint value); +extern QString toString(NumberBase base, ulong value, uint nbChars); +extern QString toLabel(NumberBase base, ulong value, uint nbChars); +extern QString toLabels(NumberBase base, const QMemArray &values, uint nbChars); + +extern uint fromChar(NumberBase base, char c, bool *ok); +extern ulong fromString(NumberBase base, const char *s, uint size, bool *ok); +extern ulong fromString(NumberBase base, const QString &s, bool *ok); +extern ulong fromLabel(NumberBase base, const QString &s, bool *ok); +extern ulong fromLabel(NumberBase base, const QString &s, uint nbChars, bool *ok); +extern ulong fromLabel(NumberBase base, const char *s, uint size, bool *ok); + +extern ulong fromAnyLabel(const QString &s, bool *ok); + +//---------------------------------------------------------------------------- +inline QString toHex(ulong value, uint nbChars) { return toString(NumberBase::Hex, value, nbChars); } +inline QString toHexLabel(ulong value, uint nbChars) { return toLabel(NumberBase::Hex, value, nbChars); } +inline QString toHexLabelAbs(ulong value) { return toLabel(NumberBase::Hex, value, nbChars(NumberBase::Hex, value)); } + +inline uint fromHex(char c, bool *ok) { return fromChar(NumberBase::Hex, c, ok); } +inline uint fromHex(QChar c, bool *ok) { return fromChar(NumberBase::Hex, c.latin1(), ok); } +inline ulong fromHex(const char *s, uint size, bool *ok) { return fromString(NumberBase::Hex, s, size, ok); } +inline ulong fromHex(const QString &s, bool *ok) { return fromString(NumberBase::Hex, s, ok); } +inline ulong fromHexLabel(const QString &s, bool *ok) { return fromLabel(NumberBase::Hex, s, ok); } +inline ulong fromHexLabel(const QString &s, uint nbChars, bool *ok) { return fromLabel(NumberBase::Hex, s, nbChars, ok); } +inline ulong fromHexLabel(const char *s, uint size, bool *ok) { return fromLabel(NumberBase::Hex, s, size, ok); } + +//---------------------------------------------------------------------------- +inline uint nbBits(ulong value) { return nbChars(NumberBase::Bin, value); } +inline uint nbBitsToNbChars(uint nbBits) { return nbBits/4 + (nbBits%4 ? 1 : 0); } +inline uint nbBitsToNbBytes(uint nbBits) { return nbBits/8 + (nbBits%8 ? 1 : 0); } +inline uint nbChars(ulong value) { return nbBitsToNbChars(nbBits(value)); } +inline uint nbBytes(ulong value) { return nbBitsToNbBytes(nbBits(value)); } + +//---------------------------------------------------------------------------- +extern QString formatNumber(ulong v); +extern QByteArray toAscii(const QString &s); + +//---------------------------------------------------------------------------- +enum PrintMode { PrintAlphaNum, PrintEscapeAll }; +inline QString toPrintable(char c, PrintMode mode) +{ + if ( mode==PrintAlphaNum && isalnum(c) ) return QChar(c); + return "\\" + toHex(uchar(c), 2); +} +inline QString toPrintable(const char *data, uint size, PrintMode mode) +{ + QString s; + for (uint i=0; i &data, PrintMode mode) +{ + return toPrintable((const char *)data.data(), data.size(), mode); +} + +#endif diff --git a/src/common/common/purl_base.cpp b/src/common/common/purl_base.cpp new file mode 100644 index 0000000..2493322 --- /dev/null +++ b/src/common/common/purl_base.cpp @@ -0,0 +1,133 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "purl_base.h" + +#include "common/global/global.h" +#include + +#include "data/xpms/project.xpm" +#include "data/xpms/sourcefile.xpm" +#include "data/xpms/includefile.xpm" +#include "data/xpms/objectfile.xpm" + +const PURL::ToolType::Data PURL::ToolType::DATA[Nb_Types] = { + { "assembler", I18N_NOOP("Assembler") }, + { "compiler", I18N_NOOP("Compiler") } +}; + +const PURL::SourceFamily::Data PURL::SourceFamily::DATA[Nb_Types] = { + { ToolType::Assembler, "asm", I18N_NOOP("Assembler"), Inc }, + { ToolType::Compiler, "c", I18N_NOOP("C Compiler"), CHeader }, + { ToolType::Compiler, "jal", I18N_NOOP("JAL Compiler"), Nb_FileTypes }, + { ToolType::Compiler, "cpp", I18N_NOOP("C++ Compiler"), CHeader }, + { ToolType::Compiler, "basic", I18N_NOOP("Basic Compiler"), Nb_FileTypes } +}; + +const PURL::FileType::Data PURL::FileType::DATA[Nb_Types] = { + { "AsmGPAsm", Source, Editable, SourceFamily::Asm, I18N_NOOP("Assembler File"), { "asm", "src", "pic", 0 }, sourcefile_xpm, 0, "XPicAsm" }, + { "AsmPIC30", Source, Editable, SourceFamily::Asm, I18N_NOOP("Assembler File for PIC30"), { "s", 0 }, sourcefile_xpm, 0, "XPicAsm" }, + { "AsmPICC", Source, Editable, SourceFamily::Asm, I18N_NOOP("Assembler File for PICC"), { "as", 0 }, sourcefile_xpm, 0, "XPicAsm" }, + { "Inc", Header, Editable, SourceFamily::Asm, I18N_NOOP("Include File"), { "inc", 0 }, includefile_xpm, 0, "XPicAsm" }, + { "CSource", Source, Editable, SourceFamily::C, I18N_NOOP("C Source File"), { "c", 0 }, 0, "text/x-csrc", "C" }, + { "CppSource", Source, Editable, SourceFamily::C, I18N_NOOP("C++ Source File"), { "cpp", "cxx", 0 }, 0, "text/x-c++src", "C++" }, + { "CHeader", Header, Editable, SourceFamily::C, I18N_NOOP("C Header File"), { "h", 0 }, 0, "text/x-chdr", "C" }, + { "JalSource", Source, Editable, SourceFamily::JAL, I18N_NOOP("JAL File"), { "jal", 0}, sourcefile_xpm, 0, "XPicJal" }, + { "BasicSource", Source, Editable, SourceFamily::Basic, I18N_NOOP("Basic Source File"), { "bas", 0 }, sourcefile_xpm, 0, "FreeBASIC" }, + + { "Object", LinkerObject, Editable | ReadOnly, SourceFamily::Nb_Types, I18N_NOOP("Object File"), { "o", "obj", 0 }, objectfile_xpm, 0, 0 }, + { "Library", LinkerObject, Editable | ReadOnly, SourceFamily::Nb_Types, I18N_NOOP("Library File"), { "a", "lib", 0 }, objectfile_xpm, 0, 0 }, + + { "Lkr", LinkerScript, Editable, SourceFamily::Nb_Types, I18N_NOOP("Linker Script"), { "lkr", 0 }, includefile_xpm, 0, 0 }, + { "Gld", LinkerScript, Editable, SourceFamily::Nb_Types, I18N_NOOP("Linker Script for PIC30"), { "gld", 0 }, includefile_xpm, 0, 0 }, + + { "Hex", Nb_FileGroups, Editable, SourceFamily::Nb_Types, I18N_NOOP("Hex File"), { "hex", 0 }, 0, "text/x-hex", 0 }, + { "Elf", Nb_FileGroups, ReadOnly, SourceFamily::Nb_Types, I18N_NOOP("Elf File"), { "elf", 0 }, 0, 0, 0 }, + { "Project", Nb_FileGroups, NoProperty, SourceFamily::Nb_Types, I18N_NOOP("Project File"), { "piklab", 0 }, project_xpm, 0, 0 }, + { "Lst", Nb_FileGroups, Editable | ReadOnly, SourceFamily::Nb_Types, I18N_NOOP("List File"), { "lst", 0 }, 0, "text/plain", 0 }, + { "Map", Nb_FileGroups, Editable | ReadOnly, SourceFamily::Nb_Types, I18N_NOOP("Map File"), { "map", 0 }, 0, "text/plain", 0 }, + { "Cod", Nb_FileGroups, ReadOnly, SourceFamily::Nb_Types, I18N_NOOP("COD File"), { "cod", 0 }, 0, 0, 0 }, + { "Coff", Nb_FileGroups, Editable | ReadOnly, SourceFamily::Nb_Types, I18N_NOOP("COFF File"), { "cof", 0 }, 0, "application/x-object", "XCoffDisasm" }, + + { "", Nb_FileGroups, NoProperty, SourceFamily::Nb_Types, I18N_NOOP("Unknown File"), { 0 }, 0, 0, 0 }, + { "", Nb_FileGroups, NoProperty, SourceFamily::Nb_Types, I18N_NOOP("Pikdev Project File"), { "pikprj", 0 }, 0, 0, 0 } +}; + +QString PURL::addExtension(const QString &filename, FileType type) +{ + QFileInfo info(filename); + if ( !info.extension().isEmpty() ) return filename; + return filename + '.' + extension(type); +} + +QString PURL::extension(FileType type) +{ + return type.data().extensions[0]; +} + +QString PURL::extensions(FileType type) +{ + Q_ASSERT( type!=PURL::Nb_FileTypes ); + QString s; + for (uint i=0; type.data().extensions[i]; i++) { + if ( i!=0 ) s += ' '; + s += QString("*.") + type.data().extensions[i]; + } + return s; +} + +QString PURL::filter(FileType type) +{ + //if ( hasMimetype(type) ) return DATA[type].mimetype; // #### we cannot mix mimetype and regular filters in KFileDialog... + QString s = extensions(type); + return s + ' ' + s.upper() + '|' + type.label() + " (" + s + ")"; +} + +QString PURL::extensions(FileGroup group) +{ + QString e; + FOR_EACH(FileType, type) { + if ( type.data().group!=group ) continue; + if ( type!=FileType::Type(0) ) e += ' '; + QString s = extensions(type); + e += s + ' ' + s.upper(); + } + return e; +} + +QString PURL::sourceFilter(FilterType type) +{ + QString f = extensions(Source) + ' ' + extensions(Header) + '|' + i18n("All Source Files"); + if ( type==CompleteFilter) { + FOR_EACH(FileType, type) { + if ( !(type.data().properties & (Source | Header)) ) continue; + f += '\n' + filter(type); + } + } + return f; +} + +QString PURL::objectFilter(FilterType type) +{ + QString f = extensions(Object) + ' ' + extensions(Library) + '|' + i18n("All Object Files"); + if ( type==CompleteFilter ) { + f += '\n' + filter(Object); + f += '\n' + filter(Library); + } + return f; +} + +QString PURL::projectFilter(FilterType type) +{ + QString f = extensions(Project) + ' ' + extensions(PikdevProject) + '|' + i18n("Project Files"); + if ( type==CompleteFilter ) { + f += '\n' + filter(Project); + f += '\n' + filter(PikdevProject); + } + return f; +} diff --git a/src/common/common/purl_base.h b/src/common/common/purl_base.h new file mode 100644 index 0000000..7a7e4ea --- /dev/null +++ b/src/common/common/purl_base.h @@ -0,0 +1,79 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PURL_BASE_H +#define PURL_BASE_H + +#include "common/global/global.h" +#include "common/common/key_enum.h" + +//---------------------------------------------------------------------------- +namespace PURL +{ +BEGIN_DECLARE_ENUM(ToolType) + Assembler = 0, Compiler +END_DECLARE_ENUM_STD(ToolType) + +enum FileTypeEnum { + AsmGPAsm = 0, AsmPIC30, AsmPICC, Inc, CSource, CppSource, CHeader, JalSource, BasicSource, + Object, Library, Lkr, Gld, Hex, Elf, Project, Lst, Map, Cod, Coff, + Unknown, PikdevProject, + Nb_FileTypes +}; + +struct SourceFamilyData { + ToolType toolType; + const char *key, *label; + FileTypeEnum headerType; +}; +BEGIN_DECLARE_ENUM(SourceFamily) + Asm = 0, C, JAL, Cpp, Basic +END_DECLARE_ENUM(SourceFamily, SourceFamilyData) + +enum FileGroup { Source = 0, Header, LinkerScript, LinkerObject, Nb_FileGroups }; + +enum FileProperty { NoProperty = 0, Editable = 1, ReadOnly = 2 }; +Q_DECLARE_FLAGS(FileProperties, FileProperty) +Q_DECLARE_OPERATORS_FOR_FLAGS(FileProperties) + +struct FileTypeData { + const char *key; + FileGroup group; + FileProperties properties; + SourceFamily sourceFamily; + const char *label; + const char *extensions[10]; + const char **xpm_icon; + const char *mimetype; + const char *highlightModeName; +}; +#ifndef Q_MOC_RUN // needed because MOC does not expand defines... +class FileType : public GenericEnum +{ +public: + typedef FileTypeEnum Type; + enum { Nb_Types = Nb_FileTypes }; + typedef FileTypeData Data; +DECLARE_DATA +DECLARE_ENUM_CLASS(FileType) +#endif + +// add correct extension if filename has no extension +extern QString addExtension(const QString &filename, FileType type); +extern QString extension(FileType type); +extern QString extensions(FileType type); +extern QString filter(FileType type); +enum FilterType { SimpleFilter, CompleteFilter }; +extern QString sourceFilter(FilterType type); +extern QString objectFilter(FilterType type); +extern QString projectFilter(FilterType type); +extern QString extensions(FileGroup group); + +} // namespace + +#endif diff --git a/src/common/common/qflags.h b/src/common/common/qflags.h new file mode 100644 index 0000000..4858ce4 --- /dev/null +++ b/src/common/common/qflags.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2005 Trolltech AS. All rights reserved. +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** This file may be used under the terms of the GNU General Public +** License version 2.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of +** this file. Please review the following information to ensure GNU +** General Public Licensing requirements will be met: +** http://www.trolltech.com/products/qt/opensource.html +** +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://www.trolltech.com/products/qt/licensing.html or contact the +** sales department at sales@trolltech.com. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ +#ifndef QFLAGS_H +#define QFLAGS_H + +#include + +class QFlag +{ + int i; +public: + inline QFlag(int i); + inline operator int() const { return i; } +}; + +inline QFlag::QFlag(int ai) : i(ai) {} + +template +class QFlags +{ + typedef void **Zero; + int i; +public: + typedef Enum enum_type; + inline QFlags(const QFlags &f) : i(f.i) {} + inline QFlags(Enum f) : i(f) {} + inline QFlags(Zero = 0) : i(0) {} + inline QFlags(QFlag f) : i(f) {} + + inline QFlags &operator=(const QFlags &f) { i = f.i; return *this; } + inline QFlags &operator&=(int mask) { i &= mask; return *this; } + inline QFlags &operator&=(uint mask) { i &= mask; return *this; } + inline QFlags &operator|=(QFlags f) { i |= f.i; return *this; } + inline QFlags &operator|=(Enum f) { i |= f; return *this; } + inline QFlags &operator^=(QFlags f) { i ^= f.i; return *this; } + inline QFlags &operator^=(Enum f) { i ^= f; return *this; } + + + inline operator int() const { return i;} + + inline QFlags operator|(QFlags f) const { QFlags g; g.i = i | f.i; return g; } + inline QFlags operator|(Enum f) const { QFlags g; g.i = i | f; return g; } + inline QFlags operator^(QFlags f) const { QFlags g; g.i = i ^ f.i; return g; } + inline QFlags operator^(Enum f) const { QFlags g; g.i = i ^ f; return g; } + inline QFlags operator&(int mask) const { QFlags g; g.i = i & mask; return g; } + inline QFlags operator&(uint mask) const { QFlags g; g.i = i & mask; return g; } + inline QFlags operator&(Enum f) const { QFlags g; g.i = i & f; return g; } + inline QFlags operator~() const { QFlags g; g.i = ~i; return g; } + + inline bool operator!() const { return !i; } +}; + +#define Q_DECLARE_FLAGS(Flags, Enum)\ +typedef QFlags Flags; +#define Q_DECLARE_OPERATORS_FOR_FLAGS(Flags) \ +inline QFlags operator|(Flags::enum_type f1, Flags::enum_type f2) \ +{ return QFlags(f1) | f2; } \ +inline QFlags operator|(Flags::enum_type f1, QFlags f2) \ +{ return f2 | f1; } + +#endif diff --git a/src/common/common/range.h b/src/common/common/range.h new file mode 100644 index 0000000..e07cb68 --- /dev/null +++ b/src/common/common/range.h @@ -0,0 +1,61 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef RANGE_H +#define RANGE_H + +#include "common/global/global.h" + +//----------------------------------------------------------------------------- +template +class GenericRange +{ +public: + virtual ~GenericRange() {} + virtual bool isEmpty() const = 0; + bool contains(Type v) const { return !isEmpty() && v>=start && v<=end; } + + Type start, end; +}; + +class Range : public GenericRange +{ +public: + Range() { start = 0; end = 0; } + Range(uint s, uint e) { start = s; end = e; } + virtual bool isEmpty() const { return end<=start; } +}; + +template +inline QDataStream &operator >>(QDataStream &s, GenericRange &r) { s >> r.start >> r.end; return s; } +template +inline QDataStream &operator <<(QDataStream &s, const GenericRange &r) { s << r.start << r.end; return s; } +template +inline bool operator ==(const GenericRange &r1, const GenericRange &r2) { return ( r1.start==r2.start && r1.end==r2.end ); } + +template +class GenericRangeVector : public QValueVector +{ +public: + GenericRangeVector() {} + GenericRangeVector(const RangeType &range) { append(range); } + bool isEmpty() const { + uint nb = this->count(); + for (uint i=0; iat(i).isEmpty() ) return false; + return true; + } + bool contains(Type v) const { + uint nb = this->count(); + for (uint i=0; iat(i).contains(v) ) return true; + return false; + } +}; + +typedef GenericRangeVector RangeVector; + +#endif diff --git a/src/common/common/storage.cpp b/src/common/common/storage.cpp new file mode 100644 index 0000000..00137b8 --- /dev/null +++ b/src/common/common/storage.cpp @@ -0,0 +1,42 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "storage.h" + +#include + +//---------------------------------------------------------------------------- +void GenericStorage::delayedChanged() +{ + if (_dirty) return; + _dirty = true; + QTimer::singleShot(0, this, SLOT(changedSlot())); +} + +void GenericStorage::changedSlot() +{ + _dirty = false; + emit changed(); +} + +//---------------------------------------------------------------------------- +void GenericViewProxy::addStorage(GenericStorage &storage) +{ + connect(&storage, SIGNAL(changed()), SLOT(changed())); +} + +void GenericViewProxy::changed() +{ + _view.updateView(); +} + +GenericView::GenericView(GenericStorage &storage) +{ + _proxy = new GenericViewProxy(*this); + _proxy->addStorage(storage); +} diff --git a/src/common/common/storage.h b/src/common/common/storage.h new file mode 100644 index 0000000..b61123a --- /dev/null +++ b/src/common/common/storage.h @@ -0,0 +1,85 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef STORAGE_H +#define STORAGE_H + +#include "common/global/global.h" +#include + +//----------------------------------------------------------------------------- +template +class Fifo +{ +public: + Fifo() {} + void clear() { _list.clear(); } + uint count() const { return _list.count(); } + void put(Type type) { _list.append(type); } + Type get() { + Type t = _list.first(); + _list.pop_front(); + return t; + } + +private: + QValueList _list; +}; + +//---------------------------------------------------------------------------- +class GenericStorage : public QObject +{ +Q_OBJECT +public: + GenericStorage(QObject *parent = 0, const char *name = 0) : QObject(parent, name), _dirty(false) {} + +signals: + void changed(); + +protected: + // emit changed() only after a return to the GUI loop and only one time + void delayedChanged(); + +private slots: + void changedSlot(); + +private: + bool _dirty; +}; + +//---------------------------------------------------------------------------- +class GenericView; + +class GenericViewProxy : public QObject +{ +Q_OBJECT +public: + GenericViewProxy(GenericView &view) : _view(view) {} + void addStorage(GenericStorage &storage); + +private slots: + void changed(); + +private: + GenericView &_view; +}; + +class GenericView +{ +public: + GenericView(GenericStorage &storage); + virtual ~GenericView() { delete _proxy; } + virtual void updateView() = 0; + +private: + GenericViewProxy *_proxy; + + friend class GenericViewProxy; +}; + +#endif diff --git a/src/common/common/streamer.h b/src/common/common/streamer.h new file mode 100644 index 0000000..93d1421 --- /dev/null +++ b/src/common/common/streamer.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef STREAMER_H +#define STREAMER_H + +#include +#include + +#include "common/global/global.h" +#include "common/common/number.h" + +template +class DataStreamer +{ +public: + uint toCppString(const QValueList &list, QTextStream &s) { + QByteArray a; +#if QT_VERSION<0x040000 + QDataStream ds(a, IO_WriteOnly); +#else + QDataStream ds(&a, QIODevice::WriteOnly); +#endif + for (uint i=0; i fromCppString(const char *data, uint size) { + QByteArray a; + a.setRawData(data, size); +#if QT_VERSION<0x040000 + QDataStream ds(a, IO_ReadOnly); +#else + QDataStream ds(&a, QIODevice::ReadOnly); +#endif + QValueList list; + for (;;) { + if ( ds.atEnd() ) break; + DataType *data = new DataType; + ds >> *data; + list.append(data); + } + a.resetRawData(data, size); + return list; + } +}; + +#endif diff --git a/src/common/common/synchronous.cpp b/src/common/common/synchronous.cpp new file mode 100644 index 0000000..f392103 --- /dev/null +++ b/src/common/common/synchronous.cpp @@ -0,0 +1,58 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "synchronous.h" + +#include "common/global/global.h" +#if QT_VERSION<0x040000 +# include +#endif + +Synchronous::Synchronous(uint timeout) +{ + connect(&_timer, SIGNAL(timeout()), SLOT(done())); + if (timeout) _timer.start(timeout, true); +#if QT_VERSION>=0x040000 + _loop = new QEventLoop(this); +#endif +} + +#if QT_VERSION<0x040000 +// uplifted from kdelibs... +void qt_enter_modal(QWidget *widget); +void qt_leave_modal(QWidget *widget); +#endif + +bool Synchronous::enterLoop() +{ +#if QT_VERSION<0x040000 + QWidget *dummy = 0; + if ( qApp->type()!=QApplication::Tty ) { + dummy = new QWidget(0, 0, WType_Dialog | WShowModal); + dummy->setFocusPolicy(QWidget::NoFocus); + qt_enter_modal(dummy); + } + QApplication::eventLoop()->enterLoop(); + if ( qApp->type()!=QApplication::Tty ) { + qt_leave_modal(dummy); + delete dummy; + } +#else + _loop->exec(); +#endif + return _timer.isActive(); +} + +void Synchronous::done() +{ +#if QT_VERSION<0x040000 + QApplication::eventLoop()->exitLoop(); +#else + _loop->exit(); +#endif +} diff --git a/src/common/common/synchronous.h b/src/common/common/synchronous.h new file mode 100644 index 0000000..e855e38 --- /dev/null +++ b/src/common/common/synchronous.h @@ -0,0 +1,32 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef SYNCHRONOUS_H +#define SYNCHRONOUS_H + +#include +#include + +class Synchronous : public QObject +{ +Q_OBJECT +public: + Synchronous(uint timeout = 0); // timeout is ms (0 == no timeout) + bool enterLoop(); // return false on timeout + +public slots: + void done(); + +private: + QTimer _timer; +#if QT_VERSION>=0x040000 + QEventLoop *_loop; +#endif +}; + +#endif diff --git a/src/common/common/version_data.cpp b/src/common/common/version_data.cpp new file mode 100644 index 0000000..481ba1a --- /dev/null +++ b/src/common/common/version_data.cpp @@ -0,0 +1,55 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "version_data.h" + +#include + +#include "number.h" + +VersionData VersionData::fromString(const QString &s) +{ + VersionData vd; + QRegExp re("([0-9]+)\\.([0-9]+)\\.([0-9]+)(.*)"); + if ( !re.exactMatch(s) ) return vd; + vd._valid = true; + vd._majorNum = re.cap(1).toUInt(); + vd._minorNum = re.cap(2).toUInt(); + vd._dotNum = re.cap(3).toUInt(); + vd._sub = re.cap(4); + return vd; +} + +VersionData VersionData::fromHexString(const QString &s) +{ + VersionData vd; + if ( s.length()!=6 ) return vd; + vd._valid = true; + vd._majorNum = ::fromString(NumberBase::Hex, s.mid(0, 2), 0); + vd._minorNum = ::fromString(NumberBase::Hex, s.mid(2, 2), 0); + vd._dotNum = ::fromString(NumberBase::Hex, s.mid(4, 2), 0); + return vd; +} + +QString VersionData::pretty() const +{ + if ( !isValid() ) return "---"; + return QString::number(_majorNum) + '.' + QString::number(_minorNum) + '.' + QString::number(_dotNum) + _sub; +} + +QString VersionData::prettyWithoutDot() const +{ + if ( !isValid() ) return "---"; + return QString::number(_majorNum) + '.' + QString::number(_minorNum); +} + +uint VersionData::toUInt() const +{ + Q_ASSERT(_valid); + return (_majorNum << 16) | (_minorNum << 8) | _dotNum; +} diff --git a/src/common/common/version_data.h b/src/common/common/version_data.h new file mode 100644 index 0000000..2571631 --- /dev/null +++ b/src/common/common/version_data.h @@ -0,0 +1,47 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef VERSION_DATA_H +#define VERSION_DATA_H + +#include "common/global/global.h" + +class VersionData +{ +public: + static VersionData fromString(const QString &s); + static VersionData fromHexString(const QString &s); + +public: + VersionData() : _valid(false) {} + VersionData(uchar majorNum, uchar minorNum, uchar dotNum) + : _valid(true), _majorNum(majorNum), _minorNum(minorNum), _dotNum(dotNum) {} + bool isValid() const { return _valid; } + void clear() { _valid = false; } + uchar majorNum() const { return _majorNum; } + uchar minorNum() const { return _minorNum; } + uchar dotNum() const { return _dotNum; } + QString sub() const { return _sub; } + VersionData toWithoutDot() const { return VersionData(_majorNum, _minorNum, 0); } + QString pretty() const; + QString prettyWithoutDot() const; + uint toUInt() const; + bool operator <(const VersionData &vd) const { return toUInt()(const VersionData &vd) const { return toUInt()>vd.toUInt(); } + bool operator >=(const VersionData &vd) const { return toUInt()>=vd.toUInt(); } + bool operator ==(const VersionData &vd) const { return toUInt()==vd.toUInt(); } + bool operator !=(const VersionData &vd) const { return toUInt()!=vd.toUInt(); } + +private: + bool _valid; + uchar _majorNum, _minorNum, _dotNum; + QString _sub; +}; + +#endif diff --git a/src/common/global/Makefile.am b/src/common/global/Makefile.am new file mode 100644 index 0000000..a94b45c --- /dev/null +++ b/src/common/global/Makefile.am @@ -0,0 +1,8 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +SUBDIRS = svn_revision + +noinst_LTLIBRARIES = libglobal.la +libglobal_la_SOURCES = about.cpp generic_config.cpp log.cpp pfile.cpp \ + process.cpp progress_monitor.cpp purl.cpp xml_data_file.cpp +libglobal_la_LDFLAGS = $(all_libraries) diff --git a/src/common/global/about.cpp b/src/common/global/about.cpp new file mode 100644 index 0000000..33bfae9 --- /dev/null +++ b/src/common/global/about.cpp @@ -0,0 +1,94 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "about.h" + +#if defined(Q_WS_WIN) +# define SVN_REVISION "windows" +#else +# include "svn_revision/svn_revision.h" +#endif + +//--------------------------------------------------------------------------- +const char * const Piklab::URLS[Nb_UrlTypes] = { + "http://piklab.sourceforge.net", + "http://piklab.sourceforge.net/wiki/index.php/FAQ", + "http://sourceforge.net/tracker/?func=add&group_id=138852&atid=743140" +}; + +//----------------------------------------------------------------------------- +Piklab::OptionList::OptionList(const KCmdLineOptions *options) + : _options(0) +{ + for (uint i=0; options[i].name; i++) append(options[i]); +} + +const KCmdLineOptions *Piklab::OptionList::ptr() const +{ + delete[] _options; + _options = new KCmdLineOptions[count()+1]; + for (uint i=0; iappName(), VERSION); +# else + printf("%s \"qt-only\": version %s (rev. %s)\n", about->appName(), VERSION, SVN_REVISION); +# endif + Q_UNUSED(gui); + Q_ASSERT( !gui ); +#else + printf("%s: version %s (rev. %s)\n", about->appName(), VERSION, SVN_REVISION); + if ( !gui ) KApplication::disableAutoDcopRegistration(); +#endif + KCmdLineArgs::init(argc, argv, about); + KCmdLineArgs::addCmdLineOptions(options); +#if defined(NO_KDE) +# if QT_VERSION<0x040000 + (void)new QApplication(argc, argv, QApplication::Tty); +# else + (void)new QCoreApplication(argc, argv); +# endif +#else + (void)new KApplication(gui, gui); +#endif +} + +//--------------------------------------------------------------------------- +Piklab::AboutData::AboutData(const char *executable, const char *name, + const char *description) + : KAboutData(executable, name, VERSION, description, KAboutData::License_GPL, + "(c) 2005-2007 Nicolas Hadacek\n(c) 2002-2005 Alain Gibaud\n(c) 2003-2004 Stephen Landamore\n(c) 2005 Lorenz Möenlechner and Matthias Kranz\n(c) 2001-2005 Craig Franklin", + 0, URLS[Homepage], URLS[BugReport]) +{ + addAuthor("Nicolas Hadacek", I18N_NOOP("Author and maintainer."), "hadacek@kde.org"); + addAuthor("Alain Gibaud", I18N_NOOP("Original author of PiKdev."), "alain.gibaud@free.fr"); + addAuthor("Stephen Landamore", I18N_NOOP("LPLAB author (original microchip programmer support)."), "webmaster@landamore.com"); + addAuthor("Craig Franklin", I18N_NOOP("Author of gputils"), "craigfranklin@users.sourceforge.net"); + addAuthor("Sébastien Laoût", I18N_NOOP("Author of likeback"), "slaout@linux62.org"); + + addCredit("Brian C. Lane", I18N_NOOP("Original code for direct programming."), 0); + addCredit("Manwlis \"Manos\" Giannos", I18N_NOOP("Direct programming for PIC18F devices."), "mgiannos2000@yahoo.gr"); + addCredit("Sean A. Walberg", I18N_NOOP("Direct programming for 16F676/630."), "sean@ertw.com"); + addCredit("Mirko Panciri", I18N_NOOP("Support for direct programmers with bidirectionnal buffers."), "mirko.panciri@adept.it"); + addCredit("Keith Baker", I18N_NOOP("Direct programming for 16F73/74/76/77."), "susyzygy@pubnix.org" ); + addCredit("Lorenz Möenlechner and Matthias Kranz", I18N_NOOP("USB support for ICD2 programmer."), "icd2linux@hcilab.org"); + addCredit("Xiaofan Chen", I18N_NOOP("Test of PICkit2 and ICD2 programmer."), "xiaofanc@gmail.com"); + addCredit("Homer Reid", I18N_NOOP("Direct programming for dsPICs is inspired from his program \"dspicprg\"."), "homer@homerreid.com"); + addCredit("Frank Damgaard", I18N_NOOP("Direct programming for 24C EEPROM is inspired from his program \"prog84\"."), "frda@post3.tele.dk"); +} diff --git a/src/common/global/about.h b/src/common/global/about.h new file mode 100644 index 0000000..e20ee46 --- /dev/null +++ b/src/common/global/about.h @@ -0,0 +1,43 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef ABOUT_H +#define ABOUT_H + +#include "global.h" + +namespace Piklab +{ +//----------------------------------------------------------------------------- +class OptionList : public QValueList +{ +public: + OptionList() : _options(0) {} + OptionList(const KCmdLineOptions *options); + virtual ~OptionList() { delete[] _options; } + const KCmdLineOptions *ptr() const; + +private: + mutable KCmdLineOptions *_options; +}; + +//--------------------------------------------------------------------------- +enum UrlType { Homepage = 0, Support, BugReport, Nb_UrlTypes }; +extern const char * const URLS[Nb_UrlTypes]; +extern void init(KAboutData *about, int argc, char **argv, bool gui, const KCmdLineOptions *options); + +//--------------------------------------------------------------------------- +class AboutData : public KAboutData +{ +public: + AboutData(const char *executable, const char *name, const char *description); +}; + +} // namespace + +#endif diff --git a/src/common/global/generic_config.cpp b/src/common/global/generic_config.cpp new file mode 100644 index 0000000..841233b --- /dev/null +++ b/src/common/global/generic_config.cpp @@ -0,0 +1,241 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "generic_config.h" + +#include "global.h" + +#if defined(NO_KDE) +# include +class GenericConfigPrivate +{ +public: + GenericConfigPrivate(const QString &group) { _settings.beginGroup("/piklab/" + group); } + QSettings _settings; +}; +#else +# include +# include +class GenericConfigPrivate +{ +public: + GenericConfigPrivate(const QString &group) : _group(group) {} + ~GenericConfigPrivate() { kapp->config()->sync(); } + KConfig &config() { + KConfig *conf = kapp->config(); + conf->setGroup(_group); + return *conf; + } + +private: + QString _group; +}; +#endif + +GenericConfig::GenericConfig(const QString &group) + : _group(group) +{ + _d = new GenericConfigPrivate(group); +} + +GenericConfig::~GenericConfig() +{ + delete _d; +} + +void GenericConfig::rollback() +{ +#if defined(NO_KDE) + qWarning("Config rollback not supported"); +#else + _d->config().rollback(); +#endif +} + +QString GenericConfig::readEntry(const QString &key, const QString &def) const +{ +#if defined(NO_KDE) +# if QT_VERSION<0x040000 + return _d->_settings.readEntry(key, def); +# else + return _d->_settings.value(key, def).toString(); +# endif +#else + return _d->config().readEntry(key, def); +#endif +} +void GenericConfig::writeEntry(const QString &key, const QString &value) +{ +#if defined(NO_KDE) +# if QT_VERSION<0x040000 + _d->_settings.writeEntry(key, value); +# else + _d->_settings.setValue(key, value); +# endif +#else + _d->config().writeEntry(key, value); +#endif +} + +QStringList GenericConfig::readListEntry(const QString &key, const QStringList &defaultValues) const +{ +#if defined(NO_KDE) +# if QT_VERSION<0x040000 + if ( _d->_settings.readEntry(key).isNull() ) return defaultValues; + return _d->_settings.readListEntry(key); +# else + return _d->_settings.value(key, defaultValues).toStringList(); +# endif +#else + if ( !_d->config().hasKey(key) ) return defaultValues; + return _d->config().readListEntry(key); +#endif +} +void GenericConfig::writeEntry(const QString &key, const QStringList &value) +{ +#if defined(NO_KDE) +# if QT_VERSION<0x040000 + _d->_settings.writeEntry(key, value); +# else + _d->_settings.setValue(key, value); +# endif +#else + _d->config().writeEntry(key, value); +#endif +} + +QValueList GenericConfig::readIntListEntry(const QString &key) const +{ +#if defined(NO_KDE) + QValueList ilist; + QStringList list = readListEntry(key, QStringList()); + QStringList::const_iterator it; + for (it=list.begin(); it!=list.end(); ++it) { + bool ok; + int v = (*it).toInt(&ok); + if ( !ok ) return ilist; + ilist.append(v); + } + return ilist; +#else + return _d->config().readIntListEntry(key); +#endif +} +void GenericConfig::writeEntry(const QString &key, const QValueList &value) +{ +#if defined(NO_KDE) + QStringList list; + QValueList::const_iterator it; + for (it=value.begin(); it!=value.end(); ++it) list.append(QString::number(*it)); + writeEntry(key, list); +#else + _d->config().writeEntry(key, value); +#endif +} + +QSize GenericConfig::readSizeEntry(const QString &key, const QSize *def) const +{ +#if defined(NO_KDE) + QValueList list = readIntListEntry(key); + if ( list.count()!=2 ) return *def; + return QSize(list[0], list[1]); +#else + return _d->config().readSizeEntry(key, def); +#endif +} +void GenericConfig::writeEntry(const QString &key, const QSize &value) +{ +#if defined(NO_KDE) + QValueList ilist; + ilist.append(value.width()); + ilist.append(value.height()); + writeEntry(key, ilist); +#else + _d->config().writeEntry(key, value); +#endif +} + +bool GenericConfig::readBoolEntry(const QString &key, bool def) const +{ +#if defined(NO_KDE) +# if QT_VERSION<0x040000 + return _d->_settings.readBoolEntry(key, def); +# else + return _d->_settings.value(key, def).toBool(); +# endif +#else + return _d->config().readBoolEntry(key, def); +#endif +} +void GenericConfig::writeEntry(const QString &key, bool value) +{ +#if defined(NO_KDE) +# if QT_VERSION<0x040000 + _d->_settings.writeEntry(key, value); +# else + _d->_settings.setValue(key, value); +# endif +#else + _d->config().writeEntry(key, value); +#endif +} + +int GenericConfig::readIntEntry(const QString &key, int def) const +{ +#if defined(NO_KDE) +# if QT_VERSION<0x040000 + return _d->_settings.readNumEntry(key, def); +# else + return _d->_settings.value(key, def).toInt(); +# endif +#else + return _d->config().readNumEntry(key, def); +#endif +} +void GenericConfig::writeEntry(const QString &key, int value) +{ +#if defined(NO_KDE) +# if QT_VERSION<0x040000 + _d->_settings.writeEntry(key, value); +# else + _d->_settings.setValue(key, value); +# endif +#else + _d->config().writeEntry(key, value); +#endif +} + +void GenericConfig::deleteGroup(const QString &group) +{ +#if defined(NO_KDE) + Q_UNUSED(group); + // #### cannot do that... +#else + kapp->config()->deleteGroup(group); +#endif +} + +QVariant GenericConfig::readVariantEntry(const QString &key, const QVariant &defValue) const +{ + switch (defValue.type()) { + case QVariant::Bool: return QVariant(readBoolEntry(key, defValue.toBool()), 0); + case QVariant::UInt: return readUIntEntry(key, defValue.toUInt()); + default: break; + } + Q_ASSERT(false); + return QVariant(); +} + +void GenericConfig::writeEntry(const QString &key, const QVariant &v) +{ + switch (v.type()) { + case QVariant::Bool: writeEntry(key, v.toBool()); break; + case QVariant::UInt: writeEntry(key, v.toUInt()); break; + default: Q_ASSERT(false); break; + } +} diff --git a/src/common/global/generic_config.h b/src/common/global/generic_config.h new file mode 100644 index 0000000..70dfeaa --- /dev/null +++ b/src/common/global/generic_config.h @@ -0,0 +1,84 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef GENERIC_CONFIG_H +#define GENERIC_CONFIG_H + +#include +#include + +#include "global.h" +#include "common/common/misc.h" + +class GenericConfigPrivate; + +class GenericConfig +{ +public: + GenericConfig(const QString &group); + ~GenericConfig(); + QString group() const { return _group; } + void rollback(); + + QString readEntry(const QString &key, const QString &def = QString::null) const; + void writeEntry(const QString &key, const QString &value); + void writeEntry(const QString &key, const QCString &value) { writeEntry(key, QString(value)); } + void writeEntry(const QString &key, const char *value) { writeEntry(key, QString(value)); } + QStringList readListEntry(const QString &key, const QStringList &defaultValues) const; + void writeEntry(const QString &key, const QStringList &value); + QValueList readIntListEntry(const QString &key) const; + void writeEntry(const QString &key, const QValueList &value); + QSize readSizeEntry(const QString &key, const QSize *def = 0) const; + void writeEntry(const QString &key, const QSize &value); + bool readBoolEntry(const QString &key, bool def) const; + void writeEntry(const QString &key, bool value); + int readIntEntry(const QString &key, int def = 0) const; + void writeEntry(const QString &key, int value); + uint readUIntEntry(const QString &key, uint def = 0) const { return qMax(0, readIntEntry(key, def)); } + void writeEntry(const QString &key, uint value) { writeEntry(key, int(value)); } + template + Enum readEnumEntry(const QString &key, Enum def = Enum::Nb_Types) const { return Enum::fromKey(readEntry(key, def.key())); } + template + void writeEnumEntry(const QString &key, Enum v) { writeEntry(key, v.key()); } + QVariant readVariantEntry(const QString &key, const QVariant &defValue) const; + void writeEntry(const QString &key, const QVariant &value); + + static void deleteGroup(const QString &group); + + struct ItemData { + const char *key, *label; + QVariant defValue; + }; + template + QVariant readVariantEntry(Type type) const { return readVariantEntry(type.data().key, type.data().defValue); } + template + void writeVariantEntry(Type type, const QVariant &value) { + Q_ASSERT( value.type()==type.data().defValue.type() ); + writeEntry(type.data().key, value); + } + +private: + QString _group; + GenericConfigPrivate *_d; +}; + +#define BEGIN_DECLARE_CONFIG(Type) \ + BEGIN_DECLARE_ENUM(Type) + +#define END_DECLARE_CONFIG(Type, group) \ + END_DECLARE_ENUM(Type, GenericConfig::ItemData) \ + inline QVariant readConfigEntry(Type type) { \ + GenericConfig config(group); \ + return config.readVariantEntry(type); \ + } \ + inline void writeConfigEntry(Type type, const QVariant &v) { \ + GenericConfig config(group); \ + config.writeVariantEntry(type, v); \ + } + +#endif diff --git a/src/common/global/global.h b/src/common/global/global.h new file mode 100644 index 0000000..72dab0e --- /dev/null +++ b/src/common/global/global.h @@ -0,0 +1,61 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef GLOBAL_H +#define GLOBAL_H + +#include + +#if QT_VERSION<0x040000 +# include +# include +# include +# include +# include "common/common/qflags.h" +# define qMax QMAX +# define qMin QMIN +# include +# define Q3Url QUrl +# include +#else +# include +# include +# define QValueList Q3ValueList +# include +# define QValueVector Q3ValueVector +# include +# define QMemArray Q3MemArray +# define qHeapSort qSort +# include +# include +# define QMimeSourceFactory Q3MimeSourceFactory +# include +# define QGuardedPtr QPointer +#endif + +#if defined(NO_KDE) +# include "qt_config.h" +# include "common/nokde/nokde_kurl.h" +# include "common/nokde/nokde_klocale.h" +# include "common/nokde/nokde_kaboutdata.h" +# include "common/nokde/nokde_kcmdlineargs.h" +#else +# include "config.h" +# include +# include +# include +# include +# include +# include +#endif + +#if defined(Q_OS_WIN) +# include +#endif + +#endif diff --git a/src/common/global/global.pro b/src/common/global/global.pro new file mode 100644 index 0000000..3756177 --- /dev/null +++ b/src/common/global/global.pro @@ -0,0 +1,8 @@ +STOPDIR = ../../.. +include($${STOPDIR}/lib.pro) + +TARGET = global +HEADERS += about.h generic_config.h log.h process.h purl.h pfile.h progress_monitor.h +SOURCES += about.cpp generic_config.cpp log.cpp process.cpp purl.cpp pfile.cpp progress_monitor.cpp + +unix:system(cd svn_revision && sh svn_revision.sh) diff --git a/src/common/global/log.cpp b/src/common/global/log.cpp new file mode 100644 index 0000000..cf85303 --- /dev/null +++ b/src/common/global/log.cpp @@ -0,0 +1,154 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "log.h" + +#include +#include "global.h" + +//----------------------------------------------------------------------------- +const Log::LineType::Data Log::LineType::DATA[Nb_Types] = { + { 0, 0, "red", false }, // error + { 0, 0, "red", false }, // soft error + { 0, 0, "orange", false }, // warning + { 0, 0, "black", false }, // normal + { 0, 0, "blue", false }, // info + { 0, 0, "black", true }, // command +}; + +const Log::DebugLevel::Data Log::DebugLevel::DATA[Nb_Types] = { + { "quiet", I18N_NOOP("No debug message"), 0, false }, + { "debug", I18N_NOOP("Normal debug messages"), "darkGreen", false }, + { "extra-debug", I18N_NOOP("Extra debug messages"), "darkGreen", false }, + { "max-debug", I18N_NOOP("Max debug messages"), "darkGreen", false }, + { "lowlevel-debug", I18N_NOOP("All debug messages"), "darkGreen", false } +}; + +//----------------------------------------------------------------------------- +Log::View::View() +{ + setDebugLevel(DebugLevel::Normal); + FOR_EACH(LineType, type) _modes[type.type()] = Show; +} + +void Log::View::setDebugLevel(DebugLevel level) +{ + _debugLevel = level; +} + +void Log::View::log(LineType type, const QString &text, Action action) +{ + if ( _modes[type.type()]==Show ) doLog(type, text, action); +} + +void Log::View::log(DebugLevel level, const QString &text, Action action) +{ + Q_ASSERT( level!=DebugLevel::Quiet ); + updateDebugLevel(); + if ( level<=_debugLevel ) doLog(level, text, action); +} + +void Log::View::logUserAbort() +{ + doLog(LineType::SoftError, i18n("Operation aborted by user."), Immediate); +} + +//----------------------------------------------------------------------------- +void Log::StringView::sorry(const QString &message, const QString &details) +{ + if ( details.isEmpty() ) _s += message; + else _s += message + ": " + details; +} + +bool Log::StringView::askContinue(const QString &message) +{ + log(LineType::Warning, message, Immediate); + return false; // always fail +} + +//----------------------------------------------------------------------------- +Log::Base::Base(Base *parent) + : _parent(0), _data(0) +{ + setParent(parent); +} + +void Log::Base::setParent(Base *parent) +{ + delete _data; + _parent = parent; + _data = (parent ? 0 : new LogData); +} + +Log::Base::~Base() +{ + delete _data; +} + +void Log::Base::setView(View *view) +{ + Q_ASSERT(_data); + _data->view = view; +} + +void Log::Base::logUserAbort() +{ + if ( view() ) view()->logUserAbort(); +} + +void Log::Base::log(LineType type, const QString &message, Action action) +{ + if ( type==LineType::Error ) setError(message); + if ( view() ) view()->log(type, message, action); +} + +void Log::Base::log(DebugLevel level, const QString &message, Action action) +{ + if ( view() ) view()->log(level, message, action); +} + +void Log::Base::appendToLastLine(const QString &text) +{ + if ( view() ) view()->appendToLastLine(text); +} + +void Log::Base::sorry(const QString &message, const QString &details) +{ + if ( view() ) view()->sorry(message, details); +} + +bool Log::Base::askContinue(const QString &message) +{ + if ( view()==0 ) return false; + return view()->askContinue(message); +} + +void Log::Base::clear() +{ + resetError(); + if ( view() ) view()->clear(); +} + +//----------------------------------------------------------------------------- +QString Log::KeyList::text() const +{ + QString text; + if ( !_title.isEmpty() ) text += _title + "\n"; + uint nb = 0; + for (uint i=0; i * + * * + * 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. * + ***************************************************************************/ +#ifndef LOG_H +#define LOG_H + +#include + +#include "common/common/key_enum.h" + +namespace Log +{ + // immediat visibily by calling processEvent... BEWARE of side effects + enum Action { Immediate, Delayed }; + enum ShowMode { DontShow, Show }; + struct LogData { + const char *key, *label, *color; + bool bold; + }; + BEGIN_DECLARE_ENUM(DebugLevel) + Quiet = 0, Normal, Extra, Max, LowLevel + END_DECLARE_ENUM(DebugLevel, LogData) + BEGIN_DECLARE_ENUM(LineType) + Error = 0, SoftError, Warning, Normal, Information, Command + END_DECLARE_ENUM(LineType, LogData) + +//----------------------------------------------------------------------------- +class Generic +{ +public: + virtual ~Generic() {} + virtual void log(LineType type, const QString &text, Action action = Immediate) = 0; + virtual void log(DebugLevel level, const QString &text, Action action = Immediate) = 0; + virtual void appendToLastLine(const QString &text) = 0; + virtual void sorry(const QString &message, const QString &details) = 0; + virtual bool askContinue(const QString &message) = 0; + virtual void clear() = 0; + virtual void logUserAbort() = 0; +}; + +class View : public Generic +{ +public: + View(); + ShowMode showMode(LineType type) const { return _modes[type.type()]; } + void setShowMode(LineType type, ShowMode mode) { _modes[type.type()] = mode; } + void setDebugLevel(DebugLevel level); + virtual void log(LineType type, const QString &text, Action action = Immediate); + virtual void log(DebugLevel level, const QString &text, Action action = Immediate); + virtual void logUserAbort(); + +protected: + ShowMode _modes[LineType::Nb_Types]; + DebugLevel _debugLevel; + + virtual void updateDebugLevel() {} + virtual void doLog(LineType type, const QString &text, Action action) = 0; + virtual void doLog(DebugLevel level, const QString &text, Action action) = 0; +}; + +//----------------------------------------------------------------------------- +class StringView : public View +{ +public: + StringView() {} + QString string() const { return _s; } + virtual void appendToLastLine(const QString &text) { _s += text; } + virtual void clear() { _s = QString::null; } + virtual void sorry(const QString &message, const QString &details); + virtual bool askContinue(const QString &message); + +private: + QString _s; + + virtual void doLog(LineType, const QString &text, Action) { _s += text + "\n"; } + virtual void doLog(DebugLevel, const QString &text, Action) { _s += text + "\n"; } +}; + +//----------------------------------------------------------------------------- +class Base : public Generic +{ +public: + Base(Base *parent = 0); + virtual ~Base(); + void setParent(Base *parent); + void setView(View *view); + View *view() { return logData()->view; } + + virtual void log(LineType type, const QString &message, Action action = Immediate); + virtual void log(DebugLevel level, const QString &message, Action action = Immediate); + virtual void appendToLastLine(const QString &text); + void setError(const QString &error) { logData()->error = error; } + virtual bool hasError() const { return !logData()->error.isNull(); } + virtual QString error() const { return logData()->error; } + virtual void resetError() { logData()->error = QString::null; } + virtual void sorry(const QString &message, const QString &details = QString::null); + virtual bool askContinue(const QString &message); + virtual void clear(); + void logUserAbort(); + +protected: + Base *_parent; + class LogData { + public: + LogData() : view(0) {} + QString error; + View *view; + }; + LogData *_data; + LogData *logData() { return _parent ? _parent->logData() : _data; } + const LogData *logData() const { return _parent ? _parent->logData() : _data; } +}; + +class KeyList { +public: + KeyList(const QString &title = QString::null) : _title(title) {} + void setTitle(const QString &title) { _title = title; } + void append(const QString &key, const QString &label) { _keys += key; _labels += label; } + QString text() const; + void display(Generic &log) const; + +private: + QString _title; + QStringList _keys, _labels; +}; + +} // namespace + +#endif diff --git a/src/common/global/pfile.cpp b/src/common/global/pfile.cpp new file mode 100644 index 0000000..71cee16 --- /dev/null +++ b/src/common/global/pfile.cpp @@ -0,0 +1,89 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "pfile.h" + +#include + +//----------------------------------------------------------------------------- +PURL::FileBase::FileBase(Log::Generic &log, const QString &extension) + : _tmp(0), _file(0), _stream(0), _extension(extension), _log(log) +{} + +PURL::FileBase::~FileBase() +{ + delete _stream; + delete _file; + delete _tmp; +} + +const QFile *PURL::FileBase::qfile() const +{ + return (_tmp ? _tmp->file() : _file); +} + +QFile *PURL::FileBase::qfile() +{ + return (_tmp ? _tmp->file() : _file); +} + +void PURL::FileBase::flush() +{ + if ( qfile() ) qfile()->flush(); +} + +QTextStream &PURL::FileBase::stream() +{ + if ( _stream==0 ) _stream = new QTextStream(qfile()); + return *_stream; +} + +bool PURL::FileBase::hasError() const +{ + if ( qfile()==0 || !_error.isEmpty() ) return true; + return ( uint(qfile()->status())!=IO_Ok ); +} + +QString PURL::FileBase::errorString() const +{ + if ( _error.isEmpty() ) { + if ( qfile()==0 ) return i18n("File not open."); + else return qfile()->errorString(); + } + return _error; +} + +QStringList PURL::FileBase::readLines() +{ + QStringList lines; + for (;;) { + QString s = stream().readLine(); + if ( s.isNull() ) break; + lines.append(s); + } + return lines; +} + +QByteArray PURL::FileBase::readAll() +{ + if ( qfile() ) return qfile()->readAll(); + return QByteArray(); +} + +//----------------------------------------------------------------------------- +PURL::File::File(const Url &url, Log::Generic &log) + : FileBase(log, QString::null), _url(url) +{ + _file = new QFile; +} + +void PURL::File::setUrl(const Url &url) +{ + close(); + _url = url; +} diff --git a/src/common/global/pfile.h b/src/common/global/pfile.h new file mode 100644 index 0000000..d0955e7 --- /dev/null +++ b/src/common/global/pfile.h @@ -0,0 +1,66 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PFILE_H +#define PFILE_H + +#include +#include "purl.h" + +namespace PURL +{ +//----------------------------------------------------------------------------- +class FileBase +{ +public: + FileBase(Log::Generic &log, const QString &extension); + ~FileBase(); + QFile *qfile(); + const QFile *qfile() const; + QTextStream &stream(); + QString readText() { return stream().read(); } + QString readLine() { return stream().readLine(); } + QStringList readLines(); + QByteArray readAll(); + void appendText(const QString &text) { stream() << text; } + void flush(); + bool hasError() const; + QString errorString() const; + +protected: + KTempFile *_tmp; + QFile *_file; + QTextStream *_stream; + QString _error, _extension; + Log::Generic &_log; + +private: // disable copy constructor and operator = + FileBase(const FileBase &base); + FileBase &operator =(const FileBase &base); +}; + +//----------------------------------------------------------------------------- +class File : public FileBase +{ +public: + File(const Url &url, Log::Generic &log); + ~File() { close(); } + void setUrl(const Url &url); // close file too + Url url() const { return _url; } + bool openForWrite(); + bool openForRead(); + bool close(); + bool remove(); + +private: + Url _url; +}; + +} // namespace + +#endif diff --git a/src/common/global/process.cpp b/src/common/global/process.cpp new file mode 100644 index 0000000..7659eea --- /dev/null +++ b/src/common/global/process.cpp @@ -0,0 +1,193 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "process.h" + +#include + +#if defined(NO_KDE) +# include "common/nokde/nokde_kprocess.h" +#else +# include +#endif +#include "purl.h" +#include "common/common/synchronous.h" + +//---------------------------------------------------------------------------- +Process::State Process::runSynchronously(Base &process, RunActions actions, uint timeout) +{ + Synchronous sync(timeout); + QObject::connect(&process, SIGNAL(done(int)), &sync, SLOT(done())); + QObject::connect(&process, SIGNAL(requestSynchronousStop()), &sync, SLOT(done())); + if ( (actions & Start) && !process.start(0) ) return process.state(); + Q_ASSERT( process.isRunning() ); + if ( !sync.enterLoop() ) process.timeoutSlot(); + return process.state(); +} + +//---------------------------------------------------------------------------- +Process::Base::Base(QObject *parent, const char *name) + : QObject(parent, name), _state(Stopped) +{ + _process = new KProcess(this); + connect(_process, SIGNAL(processExited(KProcess *)), SLOT(exited())); + connect(_process, SIGNAL(receivedStdout(KProcess *, char *, int)), SLOT(receivedStdout(KProcess*, char *, int))); + connect(_process, SIGNAL(receivedStderr(KProcess *, char *, int)), SLOT(receivedStderr(KProcess*, char *, int))); + _timer = new QTimer(this); + connect(_timer, SIGNAL(timeout()), SLOT(timeoutSlot())); +} + +Process::Base::~Base() +{ + _process->kill(); +} + +QStringList Process::Base::arguments() const +{ + if ( _process==0 ) return QStringList(); +#if defined(NO_KDE) + return _process->args(); +#else + QStringList list; + const QValueList &args = _process->args(); + for (uint i=0; istop(); + _process->clearArguments(); + if (withWine) { + _process->setEnvironment("WINEDEBUG", "-all"); + *_process << QString("wine"); + } + *_process << executable; + *_process << options; +} + +bool Process::Base::start(uint timeout) +{ + _state = Stopped; + _timer->stop(); + _stdout = QString::null; + _stderr = QString::null; +#if defined(NO_KDE) + if ( !_process->start() ) { +#else + if ( !_process->start(KProcess::NotifyOnExit, KProcess::All) ) { +#endif + _state = StartFailed; + return false; + } + _state = Running; + if (timeout) _timer->start(timeout); + return true; +} + +void Process::Base::timeoutSlot() +{ + _state = Timedout; + _process->kill(); + emit timeout(); +} + +int Process::Base::exitCode() const +{ + return _process->exitStatus(); +} + +void Process::Base::exited() +{ + _state = Exited; + _timer->stop(); + emit done(exitCode()); +} + +bool Process::Base::isRunning() const +{ + return _process->isRunning(); +} + +void Process::Base::writeToStdin(const QString &s) +{ + QCString cs = s.latin1(); + _process->writeStdin(cs.data(), cs.length()); +} + +bool Process::Base::signal(int n) +{ + return _process->kill(n); +} + +void Process::Base::setWorkingDirectory(const PURL::Directory &dir) +{ + _process->setWorkingDirectory(dir.path()); +} + +void Process::Base::setUseShell(bool useShell) +{ + _process->setUseShell(useShell); +} + +bool Process::Base::isFilteredLine(const QString &line) +{ + // "wine" returns all those "libGL warning" that mess up the output... + return line.startsWith("libGL warning"); +} + +//---------------------------------------------------------------------------- +void Process::StringOutput::receivedStdout(KProcess*, char *data, int len) +{ + _stdout += QString::fromLatin1(data, len); + emit stdoutDataReceived(); +} + +void Process::StringOutput::receivedStderr(KProcess*, char *data, int len) +{ + _stderr += QString::fromLatin1(data, len); + emit stderrDataReceived(); +} + +//---------------------------------------------------------------------------- +void Process::LineBase::receivedStdout(KProcess*, char *data, int len) +{ + for (uint i=0; iisRunning() && !isFilteredLine(_stdout) ) addStdoutLine(_stdout); + emit stdoutDataReceived(); +} + +void Process::LineBase::receivedStderr(KProcess*, char *data, int len) +{ + for (uint i=0; iisRunning() && !isFilteredLine(_stderr) ) addStderrLine(_stderr); + emit stderrDataReceived(); +} + +//---------------------------------------------------------------------------- +bool Process::LineOutput::start(uint timeout) +{ + _stdoutLines.clear(); + _stderrLines.clear(); + return Process::LineBase::start(timeout); +} + diff --git a/src/common/global/process.h b/src/common/global/process.h new file mode 100644 index 0000000..9c67149 --- /dev/null +++ b/src/common/global/process.h @@ -0,0 +1,138 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PROCESS_H +#define PROCESS_H + +#include +#include +#include +#include +class KProcess; + +#include "global.h" +namespace PURL { class Directory; } + +namespace Process +{ +enum State { Stopped, StartFailed, Running, Exited, Timedout }; +class Base; +enum RunAction { NoRunAction = 0, Start = 1 }; +Q_DECLARE_FLAGS(RunActions, RunAction) +Q_DECLARE_OPERATORS_FOR_FLAGS(RunActions) +extern State runSynchronously(Base &process, RunActions actions, uint timeout); // in ms (0 == no timeout) + +//---------------------------------------------------------------------------- +class Base : public QObject +{ +Q_OBJECT +public: + Base(QObject *parent, const char *name); + virtual ~Base(); + void setup(const QString &executable, const QStringList &options, bool withWine); + QStringList arguments() const; + void setWorkingDirectory(const PURL::Directory &dir); + void setUseShell(bool useShell); + virtual bool start(uint timeout); // in ms (0 == no timeout) + QString prettyCommand() const { return arguments().join(" "); } + void writeToStdin(const QString &s); + bool signal(int n); + bool isRunning() const; + State state() const { return _state; } + int exitCode() const; + +signals: + void requestSynchronousStop(); + void done(int code); + void timeout(); + void stdoutDataReceived(); + void stderrDataReceived(); + +protected slots: + void exited(); + void timeoutSlot(); + virtual void receivedStdout(KProcess*, char *buffer, int len) = 0; + virtual void receivedStderr(KProcess*, char *buffer, int len) = 0; + + friend State runSynchronously(Base &, RunActions, uint); + +protected: + State _state; + KProcess *_process; + QTimer *_timer; + QString _stdout, _stderr; + + static bool isFilteredLine(const QString &line); +}; + +//---------------------------------------------------------------------------- +class StringOutput : public Base +{ +Q_OBJECT +public: + StringOutput(QObject *parent = 0, const char *name = 0) : Base(parent, name) {} + QString sout() const { return _stdout; } + QString serr() const { return _stderr; } + +private slots: + virtual void receivedStdout(KProcess *, char *buffer, int len); + virtual void receivedStderr(KProcess *, char *buffer, int len); +}; + +//---------------------------------------------------------------------------- +class LineBase : public Base +{ +Q_OBJECT +public: + LineBase(QObject *parent = 0, const char *name = 0) : Base(parent, name) {} + +private slots: + virtual void receivedStdout(KProcess *, char *buffer, int len); + virtual void receivedStderr(KProcess *, char *buffer, int len); + +private: + virtual void addStdoutLine(const QString &line) = 0; + virtual void addStderrLine(const QString &line) = 0; +}; + +//---------------------------------------------------------------------------- +class LineOutput : public LineBase +{ +Q_OBJECT +public: + LineOutput(QObject *parent = 0, const char *name = 0) : LineBase(parent, name) {} + virtual bool start(uint timeout); + QStringList sout() const { return _stdoutLines; } + QStringList serr() const { return _stderrLines; } + +protected: + QStringList _stdoutLines, _stderrLines; + + virtual void addStdoutLine(const QString &line) { _stdoutLines += line; } + virtual void addStderrLine(const QString &line) { _stderrLines += line; } +}; + +//---------------------------------------------------------------------------- +class LineSignal : public LineBase +{ +Q_OBJECT +public: + LineSignal(QObject *parent = 0, const char *name = 0) : LineBase(parent, name) {} + +signals: + void logStdoutLine(const QString &line); + void logStderrLine(const QString &line); + +private: + virtual void addStdoutLine(const QString &line) { emit logStdoutLine(line); } + virtual void addStderrLine(const QString &line) { emit logStderrLine(line); } +}; + +} // namespace + +#endif diff --git a/src/common/global/progress_monitor.cpp b/src/common/global/progress_monitor.cpp new file mode 100644 index 0000000..fcd0cec --- /dev/null +++ b/src/common/global/progress_monitor.cpp @@ -0,0 +1,84 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "progress_monitor.h" + +ProgressMonitor::ProgressMonitor(QObject* parent) + : QObject(parent, "progress_monitor") +{ + _current = _tasks.end(); +} + +void ProgressMonitor::clear() +{ + _tasks.clear(); + _current = _tasks.end(); + emit showProgress(false); +} + +void ProgressMonitor::appendTask(const QString &label, uint nbSteps) +{ + Task task; + task.label = label; + task.nbSteps = nbSteps; + task.nbDoneSteps = 0; + _tasks.append(task); +} + +void ProgressMonitor::insertTask(const QString &label, uint nbSteps) +{ + Task task; + task.label = label; + task.nbSteps = nbSteps; + task.nbDoneSteps = 0; + if ( _current==_tasks.end() ) _current = _tasks.prepend(task); + else _current = _tasks.insert(_current, task); + update(); +} + +uint ProgressMonitor::nbSteps() const +{ + uint nb = 0; + for (uint i=0; i(*_current).nbSteps ) qDebug("%s %i+%i > %i", (*_current).label.latin1(), (*_current).nbDoneSteps, nbSteps, (*_current).nbSteps); + (*_current).nbDoneSteps = QMIN(nb, (*_current).nbSteps); + update(); +} diff --git a/src/common/global/progress_monitor.h b/src/common/global/progress_monitor.h new file mode 100644 index 0000000..bb905f7 --- /dev/null +++ b/src/common/global/progress_monitor.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PROGRESS_MONITOR_H +#define PROGRESS_MONITOR_H + +#include "global.h" + +class ProgressMonitor : public QObject +{ +Q_OBJECT +public: + ProgressMonitor(QObject *parent = 0); + void clear(); + void appendTask(const QString &label, uint nbSteps); + void insertTask(const QString &label, uint nbSteps); + void startNextTask(); + void addTaskProgress(uint nbSteps); + uint nbSteps() const; + uint nbDoneSteps() const; + +public slots: + void update(); + +signals: + void showProgress(bool show); + void setLabel(const QString &label); + void setTotalProgress(uint nbSteps); + void setProgress(uint nbSteps); + +private: + class Task { + public: + QString label; + uint nbSteps, nbDoneSteps; + }; + QValueList _tasks; + QValueList::iterator _current; +}; + +#endif diff --git a/src/common/global/purl.cpp b/src/common/global/purl.cpp new file mode 100644 index 0000000..6db2914 --- /dev/null +++ b/src/common/global/purl.cpp @@ -0,0 +1,428 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "purl.h" + +#include +#include +#include +#include +#include +#if QT_VERSION<0x040000 +# include +#endif + +#include "common/common/synchronous.h" +#include "process.h" + +#if !defined(NO_KDE) +# include +# include +# include +#endif + +//----------------------------------------------------------------------------- +PURL::Http::Http(const QString &hostname) + : QHttp(hostname) +{ + connect(this, SIGNAL(responseHeaderReceived(const QHttpResponseHeader &)), + SLOT(responseHeaderReceivedSlot(const QHttpResponseHeader &))); +} + +//----------------------------------------------------------------------------- +class PURL::Private +{ +public: + QString convertWindowsFilepath(const QString &filepath); + +private: + QMap _winDrives; // drive -> unix path + QMap _winPaths; // windows path -> unix path + + QString getWindowsDrivePath(char drive); + bool checkCachedPath(QString &filepath) const; + QString cachePath(const QString &origin, const QString &filepath); + QString convertWindowsShortFilepath(const QString &filepath); + QString findName(const QString &path, const QString &name); + static QString findName(const QString &filepath); +}; + +QString PURL::Private::getWindowsDrivePath(char drive) +{ +#if defined(Q_OS_UNIX) + if ( !_winDrives.contains(drive) ) { + QStringList args; + args += "-u"; + QString s; + s += drive; + args += s + ":\\"; + ::Process::StringOutput process; + process.setup("winepath", args, false); + ::Process::State state = ::Process::runSynchronously(process, ::Process::Start, 3000); + if ( state!=::Process::Exited ) qWarning("Error running \"winepath\" with \"%s\" (%i)", args.join(" ").latin1(), state); + s = process.sout() + process.serr(); + QDir dir(s.stripWhiteSpace()); + _winDrives[drive] = dir.canonicalPath(); + } + return _winDrives[drive]; +#else + return QString("%1:\\").arg(drive); +#endif +} + +bool PURL::Private::checkCachedPath(QString &filepath) const +{ + if ( !_winPaths.contains(filepath) ) return false; + filepath = _winPaths[filepath]; + return true; +} + +QString PURL::Private::cachePath(const QString &origin, const QString &filepath) +{ + _winPaths[origin] = filepath; + return filepath; +} + +QString PURL::Private::convertWindowsFilepath(const QString &filepath) +{ + // appears to be an absolute windows path + if ( filepath[0]=='\\' ) { + QString tmp = filepath; + if ( checkCachedPath(tmp) ) return tmp; + return cachePath(filepath, convertWindowsShortFilepath(tmp.replace('\\', "/"))); + } + // appears to be a windows path with a drive + if ( (filepath.length()>=2 && filepath[0].isLetter() && filepath[1]==':') ) { + QString tmp = filepath; + if ( checkCachedPath(tmp) ) return tmp; +#if QT_VERSION<0x040000 + tmp = getWindowsDrivePath(filepath[0]) + tmp.mid(2).replace('\\', "/"); +#else + tmp = getWindowsDrivePath(filepath[0].toLatin1()) + tmp.mid(2).replace('\\', "/"); +#endif + return cachePath(filepath, convertWindowsShortFilepath(tmp)); + } + return filepath; +} + +QString PURL::Private::findName(const QString &path, const QString &name) +{ + QString filepath = path + '/' + name; + if ( checkCachedPath(filepath) ) return filepath; + return cachePath(filepath, findName(filepath)); +} + +QString PURL::Private::findName(const QString &filepath) +{ + QFileInfo finfo(filepath); + if ( finfo.exists() || !finfo.dir().exists() ) return finfo.filePath(); + QStringList list = finfo.dir().entryList(QDir::All, QDir::Name); + // find if name is just in a different case + for (uint j=0; jconvertWindowsFilepath(filepath); +#else + QString tmp = filepath; +#endif + if ( tmp.startsWith("~") ) tmp = QDir::homeDirPath() + tmp.mid(1); + _relative = Q3Url::isRelativeUrl(tmp); +#if defined(Q_OS_UNIX) + if ( !tmp.startsWith("/") ) tmp = '/' + tmp; +#endif +#if defined(NO_KDE) + _url.setPath(tmp); +#else + _url = KURL::fromPathOrURL(tmp); +#endif + _url.cleanPath(); + } +} + +PURL::Base::Base(const KURL &url) + : _relative(false), _url(url) +{ + _url.cleanPath(); +} + +bool PURL::Base::isLocal() const +{ + return ( _url.protocol().isEmpty() || _url.protocol()=="file" ); +} + +bool PURL::Base::operator ==(const Base &url) const +{ + if ( _url.isEmpty() ) return url._url.isEmpty(); + return _url==url._url; +} + +QString PURL::Base::path(SeparatorType type) const +{ +#if defined(NO_KDE) + QString s = _url.dirPath(); + if ( !s.isEmpty() && !s.endsWith("/") ) s += '/'; +#else + QString s = _url.directory(false, false); +#endif + if ( type==WindowsSeparator ) { + for (uint i=0; imainWidget()) ) return false; + KFileItem item(uds, _url); + lastModified->setTime_t(item.time(KIO::UDS_MODIFICATION_TIME)); + return true; + } else { + // assume file exists if ioslave cannot tell... + return KIO::NetAccess::exists(_url, true, qApp->mainWidget()); + } +#else + if (lastModified) lastModified->setTime_t(0); + // assume file exists + return true; +#endif +} + +//---------------------------------------------------------------------------- +PURL::Url PURL::Url::fromPathOrUrl(const QString &s) +{ + KURL kurl = KURL::fromPathOrURL(s); + if ( !kurl.protocol().isEmpty() && kurl.protocol()!="file" && kurl.protocol().length()!=1 ) return kurl; + return Url(s.startsWith("file://") ? s.mid(7) : s); +} + +PURL::Url::Url(const Directory &dir, const QString &filename, FileType type) + : Base(dir.path() + '/' + addExtension(filename, type)) +{} + +PURL::Url::Url(const Directory &dir, const QString &filepath) + : Base(dir.path() + '/' + filepath) +{} + +PURL::FileType PURL::Url::fileType() const +{ + QFileInfo info(filename()); + FOR_EACH(FileType, type) + for (uint i=0; type.data().extensions[i]; i++) + if ( info.extension(false).lower()==type.data().extensions[i] ) return type; + return Unknown; +} + +QString PURL::Url::basename() const +{ + QFileInfo info(_url.fileName(false)); + return info.baseName(true); +} + +QString PURL::Url::filename() const +{ + QFileInfo info(_url.fileName(false)); + return info.fileName(); +} + +QString PURL::Url::filepath(SeparatorType type) const +{ + return path(type) + filename(); +} + +PURL::Url PURL::Url::toExtension(const QString &extension) const +{ + QFileInfo info(filename()); + return Url(directory().path() + info.baseName(true) + '.' + extension); +} + +PURL::Url PURL::Url::appendExtension(const QString &extension) const +{ + QFileInfo info(filename()); + return Url(directory().path() + info.fileName() + '.' + extension); +} + +QString PURL::Url::relativeTo(const Directory &dir, SeparatorType type) const +{ + QString s = filepath(type); + if ( !isInto(dir) ) return s; + return s.right(s.length() - dir.path(type).length()); +} + +PURL::Url PURL::Url::toAbsolute(const Directory &dir) const +{ + if ( isRelative() ) return Url(dir, filepath()); + return *this; +} + +bool PURL::findExistingUrl(Url &url) +{ + if ( url.exists() ) return true; + QFileInfo info(url.filename()); + Url tmp = url.toExtension(info.extension(false).upper()); + if ( !tmp.exists() ) { + tmp = url.toExtension(info.extension(false).lower()); + if ( !tmp.exists() ) return false; + } + url = tmp; + return true; +} + +//----------------------------------------------------------------------------- +#if !defined(NO_KDE) +PURL::UrlList::UrlList(const KURL::List &list) +{ + KURL::List::const_iterator it; + for (it=list.begin(); it!=list.end(); ++it) append(*it); +} +#endif + +//----------------------------------------------------------------------------- +PURL::Directory::Directory(const QString &path) + : Base(path.isEmpty() ? QString::null : path + '/') +{} + +PURL::Directory PURL::Directory::up() const +{ + QDir dir(path()); + dir.cdUp(); + return PURL::Directory(dir.path()); +} + +PURL::Directory PURL::Directory::down(const QString &subPath) const +{ + Q_ASSERT( QDir::isRelativePath(subPath) ); + QDir dir(path()); + dir.cd(subPath); + return PURL::Directory(dir.path()); +} + +QStringList PURL::Directory::files(const QString &filter) const +{ + QDir dir(path()); + return dir.entryList(filter, QDir::Files); +} + +PURL::Url PURL::Directory::findMatchingFilename(const QString &filename) const +{ + QDir dir(path()); + QStringList files = dir.entryList(QDir::Files); + for (uint i=0; i * + * * + * 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. * + ***************************************************************************/ +#ifndef PURL_H +#define PURL_H + +#include "common/global/global.h" +#if QT_VERSION<0x040000 +# include +#else +# include +# include +#endif +#include "common/global/log.h" +#include "common/common/purl_base.h" + +namespace PURL +{ +//---------------------------------------------------------------------------- +class Http : public QHttp +{ +Q_OBJECT +public: + Http(const QString &hostname); + QHttpResponseHeader _header; + +private slots: + void responseHeaderReceivedSlot(const QHttpResponseHeader &rh) { _header = rh; } +}; + +class Url; +class Directory; +class Private; + +enum SeparatorType { UnixSeparator, WindowsSeparator }; + +//---------------------------------------------------------------------------- +class Base +{ +public: + Base(const QString &filepath = QString::null); + Base(const KURL &url); + bool operator <(const Base &url) const { return _url +{ +public: + UrlList() {} + UrlList(const Url &url) { append(url); } + UrlList(const QValueList &list) : QValueList(list) {} +#if !defined(NO_KDE) + UrlList(const KURL::List &list); +#endif +}; + +//---------------------------------------------------------------------------- +class Directory : public Base +{ +public: + Directory(const QString &path = QString::null); + QStringList files(const QString &filter) const; + Url findMatchingFilename(const QString &filename) const; + Directory up() const; + Directory down(const QString &path) const; + static Directory current(); +#if !defined(NO_KDE) + bool create(Log::Generic &log) const; +#endif +}; + +} // namespace + +#endif diff --git a/src/common/global/svn_revision/Makefile.am b/src/common/global/svn_revision/Makefile.am new file mode 100644 index 0000000..f3d4ee4 --- /dev/null +++ b/src/common/global/svn_revision/Makefile.am @@ -0,0 +1,5 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +all-local: + sh svn_revision.sh diff --git a/src/common/global/svn_revision/svn_revision.sh b/src/common/global/svn_revision/svn_revision.sh new file mode 100755 index 0000000..3590568 --- /dev/null +++ b/src/common/global/svn_revision/svn_revision.sh @@ -0,0 +1,20 @@ +if [ -d .svn ]; then + ( echo '// generated file'; + printf '#define SVN_REVISION "'; + (svnversion -n .); + echo '"' ) > svn_revision.h.new; + if [ ! -f svn_revision.h ]; then + mv -f svn_revision.h.new svn_revision.h; + else + if cmp svn_revision.h svn_revision.h.new; then + rm -f svn_revision.h.new; + else + mv -f svn_revision.h.new svn_revision.h; + fi + fi +fi +if [ ! -f svn_revision.h ]; then + ( echo '// generated file'; + echo '#define SVN_REVISION "distribution"'; ) > svn_revision.h; +fi + diff --git a/src/common/global/xml_data_file.cpp b/src/common/global/xml_data_file.cpp new file mode 100644 index 0000000..2464b34 --- /dev/null +++ b/src/common/global/xml_data_file.cpp @@ -0,0 +1,160 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "xml_data_file.h" + +#include +#include +#include +#include +#include "common/global/pfile.h" + +XmlDataFile::XmlDataFile(const PURL::Url &url, const QString &name) + : _url(url), _name(name), _document(name) +{ + QDomElement root = _document.createElement(name); + _document.appendChild(root); +} + +bool XmlDataFile::load(QString &error) +{ + Log::StringView sview; + PURL::File file(_url, sview); + if ( !file.openForRead() ) { + error = i18n("Error opening file: %1").arg(sview.string()); + return false; + } + if ( !_document.setContent(file.qfile(), false, &error) ) return false; + if ( _document.doctype().name()!=_name + || _document.documentElement().nodeName()!=_name ) { + error = i18n("File is not of correct type."); + return false; + } + return true; +} + +bool XmlDataFile::save(QString &error) const +{ + Log::StringView sview; + PURL::File file(_url, sview); + bool ok = file.openForWrite(); + if (ok) { + QString s = _document.toString(2); + file.appendText(s); + ok = file.close(); + } + if ( !ok ) error = i18n("Error saving file: %1").arg(sview.string()); + return ok; +} + +QDomElement XmlDataFile::findChildElement(QDomElement parent, const QString &name) const +{ + QDomNodeList list = parent.elementsByTagName(name); + return list.item(0).toElement(); +} + +QDomElement XmlDataFile::createChildElement(QDomElement parent, const QString &name) +{ + QDomNodeList list = parent.elementsByTagName(name); + if ( list.count()==0 ) { + QDomElement element = _document.createElement(name); + parent.appendChild(element); + return element; + } + return list.item(0).toElement(); +} + +void XmlDataFile::removeChilds(QDomNode parent) const +{ + QDomNodeList list = parent.childNodes(); + for (uint i=0; i * + * * + * 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. * + ***************************************************************************/ +#ifndef XML_DATA_FILE_H +#define XML_DATA_FILE_H + +#include + +#include "common/global/purl.h" + +class XmlDataFile +{ +public: + XmlDataFile(const PURL::Url &url, const QString &name); + virtual ~XmlDataFile() {} + PURL::Url url() const { return _url; } + virtual bool load(QString &error); + bool save(QString &error) const; + + QString value(const QString &group, const QString &key, const QString &defaultValue) const; + void setValue(const QString &group, const QString &key, const QString &value); + QStringList listValues(const QString &group, const QString &key, const QStringList &defaultValues) const; + void setListValues(const QString &group, const QString &key, const QStringList &values); + void appendListValue(const QString &group, const QString &key, const QString &value); + void removeListValue(const QString &group, const QString &key, const QString &value); + void clearList(const QString &group, const QString &key); + +protected: + PURL::Url _url; + +private: + QString _name; + QDomDocument _document; + + QDomElement findChildElement(QDomElement element, const QString &tag) const; + QDomElement createChildElement(QDomElement element, const QString &tag); + void removeChilds(QDomNode node) const; +}; + +#endif diff --git a/src/common/gui/Makefile.am b/src/common/gui/Makefile.am new file mode 100644 index 0000000..c4bb948 --- /dev/null +++ b/src/common/gui/Makefile.am @@ -0,0 +1,7 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +libcommonui_la_LDFLAGS = $(all_libraries) +noinst_LTLIBRARIES = libcommonui.la +libcommonui_la_SOURCES = container.cpp dialog.cpp editlistbox.cpp \ + hexword_gui.cpp list_view.cpp misc_gui.cpp number_gui.cpp pfile_ext.cpp purl_ext.cpp \ + purl_gui.cpp list_container.cpp diff --git a/src/common/gui/config_widget.h b/src/common/gui/config_widget.h new file mode 100644 index 0000000..abfafab --- /dev/null +++ b/src/common/gui/config_widget.h @@ -0,0 +1,107 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * Copyright (C) 2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#ifndef CONFIG_WIDGET_H +#define CONFIG_WIDGET_H + +#include +#include +#include +#include + +#include "container.h" + +//----------------------------------------------------------------------------- +class ConfigWidget : public Container +{ +Q_OBJECT +public: + ConfigWidget(QWidget *parent = 0) : Container(parent) {} + virtual QString title() const { return QString::null; } + virtual QString header() const { return QString::null; } + virtual QPixmap pixmap() const { return QPixmap(); } + +public slots: + virtual void loadConfig() = 0; + virtual void saveConfig() = 0; +}; + +//----------------------------------------------------------------------------- +template +class BaseConfigWidget +{ +public: + BaseConfigWidget(ConfigWidget *widget) { + _widgets.resize(Type::Nb_Types); + for(Type type; type _widgets; + + static QWidget *createWidget(Type type, ConfigWidget *widget) { + QWidget *w = 0; + uint row = widget->numRows(); + switch (type.data().defValue.type()) { + case QVariant::Bool: + w = new QCheckBox(type.label(), widget); + widget->addWidget(w, row,row, 0,1); + break; + default: Q_ASSERT(false); break; + } + return w; + } + void load(Type type, QWidget *widget) const { + switch (type.data().defValue.type()) { + case QVariant::Bool: + static_cast(widget)->setChecked(readConfigEntry(type).toBool()); + break; + default: Q_ASSERT(false); break; + } + } + void save(Type type, QWidget *widget) { + switch (type.data().defValue.type()) { + case QVariant::Bool: + writeConfigEntry(type, QVariant(static_cast(widget)->isChecked(), 0)); + break; + default: Q_ASSERT(false); break; + } + } + void setDefault(Type type, QWidget *widget) const { + switch (type.data().defValue.type()) { + case QVariant::Bool: + static_cast(widget)->setChecked(type.data().defValue.toBool()); + break; + default: Q_ASSERT(false); break; + } + } +}; + +//----------------------------------------------------------------------------- +#define BEGIN_DECLARE_CONFIG_WIDGET(ConfigType, ConfigWidgetType) \ +class ConfigWidgetType : public ::ConfigWidget, public BaseConfigWidget \ +{ \ +public: \ + ConfigWidgetType() : BaseConfigWidget(this) {} \ + virtual void loadConfig() { BaseConfigWidget::loadConfig(); } \ + virtual void saveConfig() { BaseConfigWidget::saveConfig(); } \ + +#define END_DECLARE_CONFIG_WIDGET \ +}; + +#endif diff --git a/src/common/gui/container.cpp b/src/common/gui/container.cpp new file mode 100644 index 0000000..881e265 --- /dev/null +++ b/src/common/gui/container.cpp @@ -0,0 +1,80 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "container.h" + +#include "misc_gui.h" + +//---------------------------------------------------------------------------- +Container::Container(QWidget *parent, Type type) + : QFrame(parent), _type(type) +{ + initLayout(); +} + +Container::Container(QWidgetStack *stack, uint index, Type type) + : QFrame(stack), _type(type) +{ + initLayout(); + stack->addWidget(this, index); +} + +Container::Container(QTabWidget *tabw, const QString &title, Type type) + : QFrame(tabw), _type(type) +{ + initLayout(); + tabw->addTab(this, title); +} + +void Container::setFrame(Type type) +{ + _type = type; + switch (type) { + case Flat: + setMargin(parent() && parent()->inherits("QTabWidget") ? 10 : 0); + setFrameStyle(QFrame::NoFrame); + break; + case Sunken: + setMargin(10); + setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); + break; + } +} + +void Container::initLayout() +{ + _topLayout = new QGridLayout(this, 1, 1, 0, 10); + _gridLayout = new QGridLayout(1, 1, 10); + _topLayout->addLayout(_gridLayout, 0, 0); + _topLayout->setRowStretch(1, 1); + setFrame(_type); +} + +void Container::addWidget(QWidget *w, uint startRow, uint endRow, uint startCol, uint endCol, int alignment) +{ + Q_ASSERT( startRow<=endRow ); + Q_ASSERT( startCol<=endCol ); + w->show(); + _gridLayout->addMultiCellWidget(w, startRow, endRow, startCol, endCol, alignment); +} + +void Container::addLayout(QLayout *l, uint startRow, uint endRow, uint startCol, uint endCol, int alignment) +{ + Q_ASSERT( startRow<=endRow ); + Q_ASSERT( startCol<=endCol ); + _gridLayout->addMultiCellLayout(l, startRow, endRow, startCol, endCol, alignment); +} + +//---------------------------------------------------------------------------- +ButtonContainer::ButtonContainer(const QString &title, QWidget *parent) + : Container(parent, Sunken) +{ + _button = new PopupButton(title, this); + addWidget(_button, 0,0, 0,1); + setColStretch(2, 1); +} diff --git a/src/common/gui/container.h b/src/common/gui/container.h new file mode 100644 index 0000000..d718c6f --- /dev/null +++ b/src/common/gui/container.h @@ -0,0 +1,58 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef CONTAINER_H +#define CONTAINER_H + +#include +#include +#include +#include + +class PopupButton; + +//---------------------------------------------------------------------------- +class Container : public QFrame +{ +Q_OBJECT +public: + enum Type { Flat, Sunken }; + Container(QWidget *parent = 0, Type type = Flat); + Container(QWidgetStack *stack, uint index, Type type = Flat); + Container(QTabWidget *tabw, const QString &title, Type type = Flat); + void addWidget(QWidget *widget, uint startRow, uint endRow, uint startCol, uint endCol, int alignment = 0); + void addLayout(QLayout *layout, uint startRow, uint endRow, uint startCol, uint endCol, int alignment = 0); + uint numRows() const { return _gridLayout->numRows(); } + uint numCols() const { return _gridLayout->numCols(); } + void setFrame(Type type); + void setMargin(uint margin) { _topLayout->setMargin(margin); } + void setRowSpacing(uint row, uint spacing) { _gridLayout->setRowSpacing(row, spacing); } + void setColSpacing(uint col, uint spacing) { _gridLayout->setColSpacing(col, spacing); } + void setRowStretch(uint row, uint stretch) { _gridLayout->setRowStretch(row, stretch); } + void setColStretch(uint col, uint stretch) { _gridLayout->setColStretch(col, stretch); } + +private: + Type _type; + QGridLayout *_topLayout, *_gridLayout; + + void initLayout(); +}; + +//---------------------------------------------------------------------------- +class ButtonContainer : public Container +{ +Q_OBJECT +public: + ButtonContainer(const QString &title, QWidget *parent); + PopupButton &button() { return *_button; } + +private: + PopupButton *_button; +}; + +#endif diff --git a/src/common/gui/dialog.cpp b/src/common/gui/dialog.cpp new file mode 100644 index 0000000..650b086 --- /dev/null +++ b/src/common/gui/dialog.cpp @@ -0,0 +1,199 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "dialog.h" + +#include +#include +#include +#include +#include + +#include "misc_gui.h" + +//----------------------------------------------------------------------------- +Dialog::Dialog(QWidget *parent, const char *name, bool modal, + const QString &caption, int buttonMask, ButtonCode defaultButton, + bool separator, const QSize &defaultSize) + : KDialogBase(parent, name, modal, caption, buttonMask, defaultButton, separator), + _defaultSize(defaultSize) +{ + BusyCursor::start(); + Q_ASSERT(name); + QWidget *main = new QWidget(this); + setMainWidget(main); + + QTimer::singleShot(0, this, SLOT(updateSize())); +} + +Dialog::Dialog(DialogType type, const QString &caption, int buttonMask, ButtonCode defaultButton, + QWidget *parent, const char *name, bool modal, bool separator, const QSize &defaultSize) + : KDialogBase(type, caption, buttonMask, defaultButton, parent, name, modal, separator), + _defaultSize(defaultSize) +{ + BusyCursor::start(); + Q_ASSERT(name); + QTimer::singleShot(0, this, SLOT(updateSize())); +} + +Dialog::~Dialog() +{ + GuiConfig gc; + gc.writeEntry(QString(name()) + "_size", size()); +} + +void Dialog::updateSize() +{ + GuiConfig gc; + resize(gc.readSizeEntry(QString(name()) + "_size", &_defaultSize)); + BusyCursor::stop(); +} + +//----------------------------------------------------------------------------- +TreeListDialog::Item::Item(const QString &label, QWidget *page, const QString &title, QListView *listview) + : KListViewItem(listview, label), _page(page), _title(title) +{} +TreeListDialog::Item::Item(const QString &label, QWidget *page, const QString &title, QListViewItem *item) + : KListViewItem(item, label), _page(page), _title(title) +{} + +TreeListDialog::TreeListDialog(QWidget *parent, const char *name, bool modal, + const QString &caption, int buttonMask, ButtonCode defaultButton, + bool separator) + : Dialog(parent, name, modal, caption, buttonMask, defaultButton, separator) +{ + QVBoxLayout *top = new QVBoxLayout(mainWidget(), 0, 10); + + // list view + QValueList widths; + widths += 80; + widths += 500; + Splitter *splitter = new Splitter(widths, Horizontal, mainWidget(), name); + top->addWidget(splitter); + _listView = new KListView(splitter); + connect(_listView, SIGNAL(currentChanged(QListViewItem *)), SLOT(currentChanged(QListViewItem *))); + _listView->setAllColumnsShowFocus(true); + _listView->setRootIsDecorated(true); + _listView->setSorting(0); + _listView->addColumn(QString::null); + _listView->header()->hide(); + _listView->setResizeMode(QListView::LastColumn); + + // pages + _frame = new QFrame(splitter); + QVBoxLayout *vbox = new QVBoxLayout(_frame, 10, 10); + _titleBox = new QHBoxLayout(vbox); + _label = new QLabel(_frame); + _titleBox->addWidget(_label); + _stack = new QWidgetStack(_frame); + connect(_stack, SIGNAL(aboutToShow(QWidget *)), SIGNAL(aboutToShowPage(QWidget *))); + vbox->addWidget(_stack); + vbox->addStretch(1); +} + +QWidget *TreeListDialog::addPage(const QStringList &labels) +{ + Q_ASSERT( !labels.isEmpty() ); + + QWidget *page = 0; + QListViewItem *item = 0; + QListViewItemIterator it(_listView); + for (; it.current(); ++it) { + if ( it.current()->text(0)==labels[0] ) { + item = it.current(); + break; + } + } + if ( item==0 ) { + page = new QWidget(_stack); + connect(page, SIGNAL(destroyed(QObject *)), SLOT(pageDestroyed(QObject *))); + _stack->addWidget(page); + item = new Item(labels[0], page, labels[0], _listView); + item->setOpen(true); + bool last = ( labels.count()==1 ); + item->setSelectable(last); + } + for (uint i=1; itext(0)==labels[i] ) { + item = it.current(); + break; + } + } + if ( item==0 ) { + page = new QWidget(_stack); + connect(page, SIGNAL(destroyed(QObject *)), SLOT(pageDestroyed(QObject *))); + _stack->addWidget(page); + item = new Item(labels[i], page, labels[i], parent); + item->setOpen(true); + bool last = ( labels.count()==i+1 ); + item->setSelectable(last); + } + } + + return page; +} + +void TreeListDialog::currentChanged(QListViewItem *lvitem) +{ + if ( lvitem==0 ) return; + Item *item = static_cast(lvitem); + _listView->ensureItemVisible(item); + _label->setText(item->_title); + _stack->raiseWidget(item->_page); +} + +void TreeListDialog::showPage(QWidget *page) +{ + QListViewItemIterator it(_listView); + for (; it.current(); ++it) { + Item *item = static_cast(it.current()); + if ( item->_page==page ) { + _listView->setCurrentItem(item); + currentChanged(item); + break; + } + } +} + +int TreeListDialog::pageIndex(QWidget *page) const +{ + return _stack->id(page); +} + +int TreeListDialog::activePageIndex() const +{ + const Item *item = static_cast(_listView->currentItem()); + if ( item==0 ) return -1; + return pageIndex(item->_page); +} + +void TreeListDialog::pageDestroyed(QObject *object) +{ + QListViewItemIterator it(_listView); + for (; it.current(); ++it) { + Item *item = static_cast(it.current()); + if ( item->_page!=object ) continue; + delete item; + break; + } +} + +//----------------------------------------------------------------------------- +TextEditorDialog::TextEditorDialog(const QString &text, const QString &caption, + bool wrapAtWidgetWidth, QWidget *parent) + : Dialog(parent, "text_editor_dialog", true, caption, Close, Close, false, QSize(200, 100)) +{ + KTextEdit *w = new KTextEdit(text, QString::null, this); + w->setReadOnly(true); + w->setWordWrap(wrapAtWidgetWidth ? QTextEdit::WidgetWidth : QTextEdit::NoWrap); + setMainWidget(w); +} diff --git a/src/common/gui/dialog.h b/src/common/gui/dialog.h new file mode 100644 index 0000000..1227a7d --- /dev/null +++ b/src/common/gui/dialog.h @@ -0,0 +1,77 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef DIALOG_H +#define DIALOG_H + +#include +#include +#include + +//----------------------------------------------------------------------------- +class Dialog : public KDialogBase +{ +Q_OBJECT +public: + Dialog(QWidget *parent, const char *name, bool modal, + const QString &caption, int buttonMask, ButtonCode defaultButton, bool separator, + const QSize &defaultSize = QSize()); + Dialog(DialogType type, const QString &caption, + int buttonMask, ButtonCode defaultButton, QWidget *parent, const char *name, + bool modal, bool separator, const QSize &defaultSize = QSize()); + virtual ~Dialog(); + +private slots: + void updateSize(); + +private: + QSize _defaultSize; +}; + +//----------------------------------------------------------------------------- +class TreeListDialog : public Dialog +{ +Q_OBJECT +public: + TreeListDialog(QWidget *parent, const char *name, bool modal, + const QString &caption, int buttonMask, ButtonCode defaultButton, bool separator); + QWidget *addPage(const QStringList &labels); + void showPage(QWidget *page); + int activePageIndex() const; + int pageIndex(QWidget *page) const; + +protected slots: + virtual void currentChanged(QListViewItem *item); + void pageDestroyed(QObject *page); + +protected: + QFrame *_frame; + KListView *_listView; + QHBoxLayout *_titleBox; + QLabel *_label; + QWidgetStack *_stack; + + class Item : public KListViewItem { + public: + Item(const QString &label, QWidget *page, const QString &title, QListView *listview); + Item(const QString &label, QWidget *page, const QString &title, QListViewItem *item); + QWidget *_page; + QString _title; + }; +}; + +//----------------------------------------------------------------------------- +class TextEditorDialog : public Dialog +{ +Q_OBJECT +public: + TextEditorDialog(const QString &text, const QString &caption, + bool wrapAtWidgetWidth, QWidget *parent); +}; + +#endif diff --git a/src/common/gui/editlistbox.cpp b/src/common/gui/editlistbox.cpp new file mode 100644 index 0000000..1d2916d --- /dev/null +++ b/src/common/gui/editlistbox.cpp @@ -0,0 +1,340 @@ +/* Copyright (C) 2000 David Faure , Alexander Neundorf + 2000, 2002 Carsten Pfeiffer + Copyright (C) 2006-2007 Nicolas Hadacek + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#include "editlistbox.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +EditListBox::EditListBox(uint nbColumns, QWidget *parent, const char *name, Mode mode, Buttons buttons) + : QFrame(parent, name), _mode(mode), _buttons(buttons) +{ + m_lineEdit = new KLineEdit; + init(nbColumns, m_lineEdit); +} + +EditListBox::EditListBox(uint nbColumns, QWidget *view, KLineEdit *lineEdit, QWidget *parent, const char *name, + Mode mode, Buttons buttons) + : QFrame(parent, name), _mode(mode), _buttons(buttons) +{ + m_lineEdit = lineEdit; + init(nbColumns, view); +} + +void EditListBox::init(uint nbColumns, QWidget *view) +{ + _addButton = 0; + _removeButton = 0; + _moveUpButton = 0; + _moveDownButton = 0; + _removeAllButton = 0; + _resetButton = 0; + setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding)); + + QGridLayout *grid = new QGridLayout(this, 1, 1, 0, KDialog::spacingHint()); + uint row = 0; + if (view) { + QHBoxLayout *hbox = new QHBoxLayout(KDialog::spacingHint()); + grid->addMultiCellLayout(hbox, row,row, 0,1); + if (m_lineEdit) { + KIconLoader loader; + QIconSet iconset = loader.loadIcon("locationbar_erase", KIcon::Toolbar); + KPushButton *button = new KPushButton(iconset, QString::null, this); + connect(button, SIGNAL(clicked()), SLOT(clearEdit())); + hbox->addWidget(button); + } + view->reparent( this, QPoint(0,0) ); + hbox->addWidget(view); + row++; + } + _listView= new KListView(this); + for (uint i=0; iaddColumn(QString::null); + _listView->header()->hide(); + _listView->setSorting(-1); + _listView->setResizeMode(KListView::LastColumn); + _listView->setColumnWidthMode(nbColumns-1, KListView::Maximum); + grid->addWidget(_listView, row, 0); + QVBoxLayout *vbox = new QVBoxLayout(10); + grid->addLayout(vbox, row, 1); + _buttonsLayout = new QVBoxLayout(10); + vbox->addLayout(_buttonsLayout); + vbox->addStretch(1); + + setButtons(_buttons); + + if (m_lineEdit) { + connect(m_lineEdit,SIGNAL(textChanged(const QString&)),this,SLOT(typedSomething(const QString&))); + m_lineEdit->setTrapReturnKey(true); + connect(m_lineEdit,SIGNAL(returnPressed()),this,SLOT(addItem())); + } + connect(_listView, SIGNAL(selectionChanged()), SLOT(selectionChanged())); + + // maybe supplied lineedit has some text already + typedSomething(m_lineEdit ? m_lineEdit->text() : QString::null); +} + +void EditListBox::setButtons(Buttons buttons) +{ + _buttons = buttons; + + delete _addButton; + _addButton = 0; + if ( buttons & Add ) { +#if KDE_VERSION < KDE_MAKE_VERSION(3,4,0) + _addButton = new KPushButton(KGuiItem(i18n("Add"), "edit_add"), this); +#else + _addButton = new KPushButton(KStdGuiItem::add(), this); +#endif + _addButton->setEnabled(false); + _addButton->show(); + connect(_addButton, SIGNAL(clicked()), SLOT(addItem())); + _buttonsLayout->addWidget(_addButton); + } + + delete _removeButton; + _removeButton = 0; + if ( buttons & Remove ) { + _removeButton = new KPushButton(KGuiItem(i18n("Remove"), "clear"), this); + _removeButton->setEnabled(false); + _removeButton->show(); + connect(_removeButton, SIGNAL(clicked()), SLOT(removeItem())); + _buttonsLayout->addWidget(_removeButton); + } + + delete _removeAllButton; + _removeAllButton = 0; + if ( buttons & RemoveAll ) { + _removeAllButton = new KPushButton(KGuiItem(i18n("Remove All"), "delete"), this); + _removeAllButton->show(); + connect(_removeAllButton, SIGNAL(clicked()), SLOT(clear())); + _buttonsLayout->addWidget(_removeAllButton); + } + + delete _moveUpButton; + _moveUpButton = 0; + delete _moveDownButton; + _moveDownButton = 0; + if ( buttons & UpDown ) { + _moveUpButton = new KPushButton(KGuiItem(i18n("Move &Up"), "up"), this); + _moveUpButton->setEnabled(false); + _moveUpButton->show(); + connect(_moveUpButton, SIGNAL(clicked()), SLOT(moveItemUp())); + _buttonsLayout->addWidget(_moveUpButton); + _moveDownButton = new KPushButton(KGuiItem(i18n("Move &Down"), "down"), this); + _moveDownButton->setEnabled(false); + _moveDownButton->show(); + connect(_moveDownButton, SIGNAL(clicked()), SLOT(moveItemDown())); + _buttonsLayout->addWidget(_moveDownButton); + } + + delete _resetButton; + _resetButton = 0; + if ( buttons & Reset ) { + _resetButton = new KPushButton(KStdGuiItem::reset(), this); + _resetButton->show(); + connect(_resetButton, SIGNAL(clicked()), SIGNAL(reset())); + _buttonsLayout->addWidget(_resetButton); + } +} + +void EditListBox::typedSomething(const QString& text) +{ + QListViewItem *item = _listView->selectedItem(); + if (item) { + if( selectedText()!=text ) { + item->setText(textColumn(), text); + emit changed(); + } + } + updateButtons(); +} + +void EditListBox::moveItemUp() +{ + QListViewItem *item = _listView->selectedItem(); + if ( item==0 || item->itemAbove()==0 ) return; + item->itemAbove()->moveItem(item); + updateButtons(); + emit changed(); +} + +void EditListBox::moveItemDown() +{ + QListViewItem *item = _listView->selectedItem(); + if ( item==0 || item->itemBelow()==0 ) return; + item->moveItem(item->itemBelow()); + updateButtons(); + emit changed(); +} + +void EditListBox::addItem() +{ + // when m_checkAtEntering is true, the add-button is disabled, but this + // slot can still be called through Key_Return/Key_Enter. So we guard + // against this. + if ( !_addButton || !_addButton->isEnabled() || m_lineEdit==0 ) return; + + addItem(m_lineEdit->text()); +} + +void EditListBox::addItem(const QString &text) +{ + bool alreadyInList(false); + //if we didn't check for dupes at the inserting we have to do it now + if ( _mode==DuplicatesDisallowed ) alreadyInList = _listView->findItem(text, textColumn()); + + if (m_lineEdit) { + bool block = m_lineEdit->signalsBlocked(); + m_lineEdit->blockSignals(true); + m_lineEdit->clear(); + m_lineEdit->blockSignals(block); + } + _listView->clearSelection(); + + if (!alreadyInList) { + QListViewItem *item = createItem(); + item->setText(textColumn(), text); + if ( _listView->lastItem() ) item->moveItem(_listView->lastItem()); + emit changed(); + emit added(text); + } + updateButtons(); +} + +void EditListBox::clearEdit() +{ + _listView->clearSelection(); + if (m_lineEdit) { + m_lineEdit->clear(); + m_lineEdit->setFocus(); + } + updateButtons(); +} + +void EditListBox::removeItem() +{ + QListViewItem *item = _listView->selectedItem(); + if (item) { + QString text = item->text(textColumn()); + delete item; + emit changed(); + emit removed(text); + updateButtons(); + } +} + +void EditListBox::selectionChanged() +{ + if (m_lineEdit) m_lineEdit->setText(selectedText()); + updateButtons(); +} + +void EditListBox::clear() +{ + _listView->clear(); + if (m_lineEdit) { + m_lineEdit->clear(); + m_lineEdit->setFocus(); + } + updateButtons(); + emit changed(); +} + +uint EditListBox::count() const +{ + uint nb = 0; + QListViewItemIterator it(_listView); + for (; it.current(); ++it) nb++; + return nb; +} + +const QListViewItem *EditListBox::item(uint i) const +{ + uint k = 0; + QListViewItemIterator it(_listView); + for (; it.current(); ++it) { + if ( k==i ) return it.current(); + k++; + } + return 0; +} + +QStringList EditListBox::texts() const +{ + QStringList list; + QListViewItemIterator it(_listView); + for (; it.current(); ++it) list.append(it.current()->text(textColumn())); + return list; +} + +void EditListBox::setTexts(const QStringList& items) +{ + _listView->clear(); + for (int i=items.count()-1; i>=0; i--) { + QListViewItem *item = createItem(); + item->setText(textColumn(), items[i]); + } + if (m_lineEdit) m_lineEdit->clear(); + updateButtons(); +} + +void EditListBox::updateButtons() +{ + QListViewItem *item = _listView->selectedItem(); + if (_addButton) { + if ( m_lineEdit==0 ) _addButton->setEnabled(true); + else { + QString text = m_lineEdit->text(); + if ( _mode!=DuplicatesCheckedAtEntering ) _addButton->setEnabled(!text.isEmpty()); + else if ( text.isEmpty() ) _addButton->setEnabled(false); + else _addButton->setEnabled(!_listView->findItem(text, textColumn())); + } + } + if (_removeButton) _removeButton->setEnabled(item); + if (_moveUpButton) _moveUpButton->setEnabled(item && item->itemAbove()); + if (_moveDownButton) _moveDownButton->setEnabled(item && item->itemBelow()); + if (_removeAllButton) _removeAllButton->setEnabled(_listView->firstChild()); +} + +void EditListBox::setEditText(const QString &text) +{ + _listView->clearSelection(); + if (m_lineEdit) m_lineEdit->setText(text); + updateButtons(); +} + +QListViewItem *EditListBox::createItem() +{ + return new KListViewItem(_listView); +} + +QString EditListBox::selectedText() const +{ + QListViewItem *item = _listView->selectedItem(); + if ( item==0 ) return QString::null; + return item->text(textColumn()); +} diff --git a/src/common/gui/editlistbox.h b/src/common/gui/editlistbox.h new file mode 100644 index 0000000..c259278 --- /dev/null +++ b/src/common/gui/editlistbox.h @@ -0,0 +1,95 @@ +/* Copyright (C) 2000 David Faure , Alexander Neundorf + Copyright (C) 2006-2007 Nicolas Hadacek + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#ifndef EDITLISTBOX_H +#define EDITLISTBOX_H + +#include +#include +#include +#include + +#include "common/common/qflags.h" + +//---------------------------------------------------------------------------- +// modified KEditListBox (beyond recognition) +// * support for duplicated items +// * use KStdGuiItem for buttons +// * support for New, Clear, Reset buttons +// * use KListView +class EditListBox : public QFrame +{ +Q_OBJECT + public: + enum Mode { DuplicatesDisallowed, DuplicatesAllowed, DuplicatesCheckedAtEntering }; + enum Button { Add = 1, Remove = 2, UpDown = 4, RemoveAll = 8, Reset = 16 }; + Q_DECLARE_FLAGS(Buttons, Button) + + EditListBox(uint nbColumns, QWidget *parent = 0, const char *name = 0, Mode mode = DuplicatesDisallowed, + Buttons buttons = Buttons(Add|Remove|RemoveAll|UpDown) ); + EditListBox(uint nbColumns, QWidget *view, KLineEdit *lineEdit, QWidget *parent = 0, const char *name = 0, + Mode mode = DuplicatesDisallowed, Buttons buttons = Buttons(Add|Remove|RemoveAll|UpDown) ); + void setTexts(const QStringList& items); + QStringList texts() const; + uint count() const; + QString text(uint i) const { return item(i)->text(textColumn()); } + const QListViewItem *item(uint i) const; + Buttons buttons() const { return _buttons; } + void setButtons(Buttons buttons); + void setEditText(const QString &text); + void addItem(const QString &text); + + signals: + void reset(); + void changed(); + void added( const QString & text ); + void removed( const QString & text ); + + public slots: + void clear(); + + protected slots: + virtual void moveItemUp(); + virtual void moveItemDown(); + virtual void clearEdit(); + virtual void addItem(); + virtual void removeItem(); + void selectionChanged(); + void typedSomething(const QString& text); + + protected: + KListView *_listView; + + virtual QListViewItem *createItem(); + virtual uint textColumn() const { return 0; } + QString selectedText() const; + + private: + Mode _mode; + Buttons _buttons; + QVBoxLayout *_buttonsLayout; + KLineEdit *m_lineEdit; + KPushButton *_addButton, *_removeButton, *_moveUpButton, *_moveDownButton, + *_removeAllButton, *_resetButton; + + void init(uint nbColumns, QWidget *view); + void updateButtons(); +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(EditListBox::Buttons) + +#endif diff --git a/src/common/gui/hexword_gui.cpp b/src/common/gui/hexword_gui.cpp new file mode 100644 index 0000000..d794a11 --- /dev/null +++ b/src/common/gui/hexword_gui.cpp @@ -0,0 +1,136 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "hexword_gui.h" + +#include + +#include "common/gui/number_gui.h" +#include "common/common/misc.h" + +//----------------------------------------------------------------------------- +HexValueValidator::HexValueValidator(uint nbChars, QObject *parent) + : QValidator(parent, "hex_value_validator"), _nbChars(nbChars) {} + +QValidator::State HexValueValidator::validate(QString &input, int &) const +{ + if ( input.length()==0 ) return Acceptable; + if ( input.length()>_nbChars ) return Invalid; + for (uint i=0; itype()) { + case QEvent::FocusOut: + changeValue(); + break; + case QEvent::FocusIn: + QTimer::singleShot(0, this, SLOT(selectAll())); // ugly but it works + break; + case QEvent::KeyPress: + switch ( static_cast(e)->key() ) { + case Key_Next: + emit moveNextPage(); + return true; + case Key_Tab: + case Key_Enter: + case Key_Return: + emit moveNext(); + return true; + case Key_Prior: + emit movePrevPage(); + return true; + case Key_BackTab: + emit movePrev(); + return true; + case Key_Down: + emit moveDown(); + return true; + case Key_Up: + emit moveUp(); + return true; + case Key_Home: + emit moveFirst(); + return true; + case Key_End: + emit moveLast(); + return true; + case Key_Right: + if ( cursorPosition()!=int(text().length()) ) break; + emit moveNext(); + return true; + case Key_Left: + if ( cursorPosition()!=0 ) break; + emit movePrev(); + return true; + } + default: break; + } + return QLineEdit::event(e); +} + +QSize GenericHexWordEditor::sizeHint() const +{ + return QSize(maxCharWidth(NumberBase::Hex, font()) * (_nbChars+1), fontMetrics().height()); +} + +QSize GenericHexWordEditor::minimumSizeHint() const +{ + return QSize(maxCharWidth(NumberBase::Hex, font()) * (_nbChars+1), fontMetrics().height()); +} diff --git a/src/common/gui/hexword_gui.h b/src/common/gui/hexword_gui.h new file mode 100644 index 0000000..5da6840 --- /dev/null +++ b/src/common/gui/hexword_gui.h @@ -0,0 +1,88 @@ +/*************************************************************************** + * Copyright (C) 2006-2007 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#ifndef HEXWORD_GUI_H +#define HEXWORD_GUI_H + +#include +#include + +#include "common/common/bitvalue.h" + +//----------------------------------------------------------------------------- +class HexValueValidator : public QValidator +{ +Q_OBJECT +public: + HexValueValidator(uint nbChars, QObject *parent); + virtual State validate(QString &input, int &pos) const; + +private: + uint _nbChars; +}; + +//----------------------------------------------------------------------------- +class GenericHexWordEditor : public KLineEdit +{ +Q_OBJECT +public: + GenericHexWordEditor(uint nbChars, bool hasBlankValue, QWidget *parent); + virtual QSize sizeHint() const; + virtual QSize minimumSizeHint() const; + +signals: + void modified(); + void moveNext(); + void movePrev(); + void moveUp(); + void moveDown(); + void moveFirst(); + void moveLast(); + void moveNextPage(); + void movePrevPage(); + +private slots: + bool changeValue(); + void slotTextChanged(); + +protected: + uint _nbChars; + bool _hasBlankValue; + + virtual bool isValid() const = 0; + virtual BitValue mask() const = 0; + virtual BitValue normalizeWord(BitValue value) const = 0; + virtual bool event(QEvent *e); + virtual void set(); + virtual BitValue word() const = 0; + virtual void setWord(BitValue value) = 0; + virtual BitValue blankValue() const = 0; +}; + +//----------------------------------------------------------------------------- +class HexWordEditor : public GenericHexWordEditor +{ +Q_OBJECT +public: + HexWordEditor(uint nbChars, QWidget *parent) : GenericHexWordEditor(nbChars, false, parent) {} + void setValue(BitValue word) { _word = word; set(); } + BitValue value() const { return _word; } + +protected: + BitValue _word; + + virtual bool isValid() const { return true; } + virtual BitValue mask() const { return maxValue(NumberBase::Hex, _nbChars); } + virtual BitValue normalizeWord(BitValue value) const { return value.maskWith(mask()); } + virtual BitValue word() const { return _word; } + virtual void setWord(BitValue value) { _word = value; } + virtual BitValue blankValue() const { return 0; } +}; + +#endif diff --git a/src/common/gui/key_gui.h b/src/common/gui/key_gui.h new file mode 100644 index 0000000..fb8a9f5 --- /dev/null +++ b/src/common/gui/key_gui.h @@ -0,0 +1,125 @@ +/*************************************************************************** + * Copyright (C) 2006-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef KEY_GUI_H +#define KEY_GUI_H + +#include +#include +#include + +#include "common/gui/misc_gui.h" +#include "common/common/misc.h" + +//----------------------------------------------------------------------------- +template +class KeyWidget +{ +public: + typedef QMapConstIterator ConstIterator; + +public: + KeyWidget(QWidget *parent) { _widget = new WidgetType(parent); } + virtual ~KeyWidget() { delete _widget; } + virtual WidgetType *widget() { return _widget; } + virtual void clear() { _ids.clear(); } + ConstIterator begin() const { return _ids.begin(); } + ConstIterator end() const { return _ids.end(); } + uint count() const { return _ids.count(); } + void appendItem(const KeyType &key, Type type) { + CRASH_ASSERT( !_ids.contains(key) ); + _ids[key] = append(type); + } + KeyType currentItem() const { return key(currentId()); } + void setCurrentItem(const KeyType &key) { + if ( _ids.contains(key) ) setCurrentId(_ids[key]); + } + bool contains(const KeyType &key) const { return _ids.contains(key); } + Type item(const KeyType &key) const { + CRASH_ASSERT( _ids.contains(key) ); + return get(_ids[key]); + } + Type item(ConstIterator it) const { + CRASH_ASSERT( it!=end() ); + return get(it.data()); + } + KeyType key(int id) const { + for (ConstIterator it=begin(); it!=end(); it++) + if ( it.data()==id ) return it.key(); + return KeyType(); + } + +protected: + virtual int append(Type type) = 0; + virtual int currentId() const = 0; + virtual void setCurrentId(int id) = 0; + virtual Type get(int id) const = 0; + + QWidget *_parent; + QMap _ids; + WidgetType *_widget; +}; + +//----------------------------------------------------------------------------- +template +class KeyComboBox : public KeyWidget +{ +public: + typedef KeyWidget ParentType; + KeyComboBox(QWidget *parent = 0) : ParentType(parent) {} + virtual void clear() { + ParentType::clear(); + ParentType::_widget->clear(); + } + void fixMinimumWidth() { + ParentType::_widget->setMinimumWidth(ParentType::_widget->sizeHint().width()); + } + +protected: + virtual int append(QString label) { ParentType::_widget->insertItem(label); return ParentType::_widget->count()-1; } + virtual int currentId() const { return ParentType::_widget->currentItem(); } + virtual void setCurrentId(int id) { ParentType::_widget->setCurrentItem(id); } + virtual QString get(int id) const { return ParentType::_widget->text(id); } +}; + +//----------------------------------------------------------------------------- +template +class KeyWidgetStack : public KeyWidget +{ +public: + typedef KeyWidget ParentType; + KeyWidgetStack(QWidget *parent = 0) : ParentType(parent) {} + +protected: + virtual int append(QWidget *widget) { return ParentType::_widget->addWidget(widget); } + virtual int currentId() const { return ParentType::_widget->id(ParentType::_widget->visibleWidget()); } + virtual void setCurrentId(int id) { ParentType::_widget->raiseWidget(id); } + virtual QWidget *get(int id) const { return ParentType::_widget->widget(id); } +}; + +//----------------------------------------------------------------------------- +template +class KeyPopupButton : public KeyWidget +{ +public: + typedef KeyWidget ParentType; + KeyPopupButton(QWidget *parent = 0) : ParentType(parent) {} + +protected: + virtual int append(QString label) { return ParentType::_widget->appendItem(label, QPixmap()); } + virtual QString get(int id) const { return ParentType::_widget->popup()->text(id); } + +private: + // disabled + QString currentItem() const; + void setCurrentItem(const QString &key); + virtual int currentId() const { return 0; } + virtual void setCurrentId(int) {} +}; + +#endif diff --git a/src/common/gui/list_container.cpp b/src/common/gui/list_container.cpp new file mode 100644 index 0000000..0103175 --- /dev/null +++ b/src/common/gui/list_container.cpp @@ -0,0 +1,95 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "list_container.h" + +//---------------------------------------------------------------------------- +PopupContainer::PopupContainer(const QString &title, QWidget *parent, const char *name) + : KPopupMenu(parent, name) +{ + if ( !title.isEmpty() ) insertTitle(title); +} + +ListContainer *PopupContainer::appendBranch(const QString &title) +{ + PopupContainer *branch = new PopupContainer(title, this); + insertItem(title, branch); + return branch; +} + +ListContainer *PopupContainer::appendBranch(const QPixmap &pixmap, const QString &title) +{ + PopupContainer *branch = new PopupContainer(title, this); + insertItem(pixmap, title, branch); + return branch; +} + +void PopupContainer::appendItem(const QPixmap &icon, const QString &label, uint id, ItemState state) +{ + insertItem(icon, label, id); + switch (state) { + case Normal: break; + case Checked: setItemChecked(id, true); break; + case UnChecked: setItemChecked(id, false); break; + case Disabled: setItemEnabled(id, false); break; + } +} + +//---------------------------------------------------------------------------- +ListViewItemContainer::ListViewItemContainer(const QString &title, KListView *parent) + : KListViewItem(parent, title), _parent(0), _column(0) +{ + _ids = new QMap; +} + +ListViewItemContainer::ListViewItemContainer(const QString &title, ListViewItemContainer *parent) + : KListViewItem(parent, title), _parent(parent), _column(0) +{ + _ids = parent->_ids; +} + +ListViewItemContainer::~ListViewItemContainer() +{ + if ( _parent==0 ) delete _ids; +} + +ListContainer *ListViewItemContainer::appendBranch(const QString &title) +{ + ListViewItemContainer *branch = new ListViewItemContainer(title, this); + branch->setColumn(_column); + branch->setSelectable(false); + // append instead of prepend + QListViewItem *litem=firstChild(); + while ( litem && litem->nextSibling() ) litem = litem->nextSibling(); + if (litem) branch->moveItem(litem); + return branch; +} + +void ListViewItemContainer::appendItem(const QPixmap &icon, const QString &title, uint id, ItemState state) +{ + QListViewItem *item = 0; + if ( state==Normal || state==Disabled ) { + item = new KListViewItem(this); + item->setText(_column, title); + } else { + item = new QCheckListItem(this, title, QCheckListItem::CheckBox); + static_cast(item)->setState(state==Checked ? QCheckListItem::On : QCheckListItem::Off); + } + item->setPixmap(_column, icon); + item->setSelectable(state==Normal); + // append instead of prepend + QListViewItem *litem=firstChild(); + while ( litem && litem->nextSibling() ) litem = litem->nextSibling(); + if (litem) item->moveItem(litem); + (*_ids)[item] = id; +} + +int ListViewItemContainer::id(const QListViewItem *item) const +{ + return (_ids->contains(item) ? int((*_ids)[item]) : -1); +} diff --git a/src/common/gui/list_container.h b/src/common/gui/list_container.h new file mode 100644 index 0000000..b70db57 --- /dev/null +++ b/src/common/gui/list_container.h @@ -0,0 +1,55 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef LIST_CONTAINER_H +#define LIST_CONTAINER_H + +#include +#include + +//---------------------------------------------------------------------------- +class ListContainer +{ +public: + virtual ~ListContainer() {} + virtual ListContainer *appendBranch(const QString &title) = 0; + enum ItemState { Normal, Checked, UnChecked, Disabled }; + void appendItem(const QString &label, uint id, ItemState state) { appendItem(QPixmap(), label, id, state); } + virtual void appendItem(const QPixmap &icon, const QString &label, uint id, ItemState state) = 0; +}; + +//---------------------------------------------------------------------------- +class PopupContainer : public KPopupMenu, public ListContainer +{ +Q_OBJECT +public: + PopupContainer(const QString &title, QWidget *parent = 0, const char *name = 0); + virtual ListContainer *appendBranch(const QString &title); + virtual ListContainer *appendBranch(const QPixmap &icon, const QString &title); + virtual void appendItem(const QPixmap &icon, const QString &label, uint id, ItemState state); +}; + +//---------------------------------------------------------------------------- +class ListViewItemContainer : public KListViewItem, public ListContainer +{ +public: + ListViewItemContainer(const QString &title, KListView *parent); + ListViewItemContainer(const QString &title, ListViewItemContainer *parent); + virtual ~ListViewItemContainer(); + void setColumn(uint column) { _column = column; } + virtual ListContainer *appendBranch(const QString &title); + virtual void appendItem(const QPixmap &icon, const QString &label, uint id, ItemState state); + int id(const QListViewItem* item) const; // -1 if not known + +private: + ListViewItemContainer *_parent; + uint _column; + QMap *_ids; +}; + +#endif diff --git a/src/common/gui/list_view.cpp b/src/common/gui/list_view.cpp new file mode 100644 index 0000000..c9434f3 --- /dev/null +++ b/src/common/gui/list_view.cpp @@ -0,0 +1,221 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * Copyright (C) 1992-2003 Trolltech AS. * + * * + * 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. * + ***************************************************************************/ +#include "list_view.h" + +#include +#include +#include +#include +#include +#include + +//---------------------------------------------------------------------------- +ListView::ListView(QWidget *parent, const char *name) + : KListView(parent, name) +{ + QToolTip::remove(this); + _tooltip = new ListViewToolTip(this); +} + +ListView::~ListView() +{ + delete _tooltip; +} + +QString ListView::tooltip(const QListViewItem &, int) const +{ + return QString::null; +} + +void ListView::clear() +{ + _editItems.clear(); + KListView::clear(); +} + +bool ListView::eventFilter(QObject *o, QEvent *e) +{ + QValueList::const_iterator it; + for (it=_editItems.begin(); it!=_editItems.end(); ++it) { + for (uint i=0; i<(*it)->_editWidgets.count(); i++) { + if ( (*it)->_editWidgets[i]==o ) { + //qDebug("event %i", e->type()); + switch (e->type()) { + case QEvent::KeyPress: { + QKeyEvent *ke = static_cast(e); + switch (ke->key()) { + case Key_Enter: + case Key_Return: + (*it)->renameDone(true); + return true; + case Key_Escape: + (*it)->removeEditBox(); + return true; + } + break; + } + case QEvent::FocusOut: { + //qDebug("focus out %i %i=%i", qApp->focusWidget(), focusWidget(), (*it)->_editWidgets[i]); + if ( qApp->focusWidget() && focusWidget()==(*it)->_editWidgets[i] ) break; + //qDebug("ext"); + QCustomEvent *e = new QCustomEvent(9999); + QApplication::postEvent(o, e); + return true; + } + case 9999: + (*it)->renameDone(false); + return true; + default: + //qDebug(" ignored"); + break; + } + } + } + } + return KListView::eventFilter(o, e); +} + +void ListView::stopRenaming(bool force) +{ + QValueList::const_iterator it; + for (it=_editItems.begin(); it!=_editItems.end(); ++it) + if ( (*it)->isRenaming() ) (*it)->renameDone(force); +} + +//---------------------------------------------------------------------------- +void ListViewToolTip::maybeTip(const QPoint &p) +{ + if ( _listView==0 ) return; + const QListViewItem* item = _listView->itemAt(p); + if ( item==0 ) return; + QRect rect = _listView->itemRect(item); + if ( !rect.isValid() ) return; + int col = _listView->header()->sectionAt(p.x()); + QString text = _listView->tooltip(*item, col); + if ( !text.isEmpty() ) { + int hpos = _listView->header()->sectionPos(col); + rect.setLeft(hpos); + rect.setRight(hpos + _listView->header()->sectionSize(col)); + tip(rect, text); + } +} + +//---------------------------------------------------------------------------- +EditListViewItem::EditListViewItem(ListView *list) + : KListViewItem(list), _renaming(false) +{ + setRenameEnabled(0, true); + list->_editItems.append(this); +} + +EditListViewItem::EditListViewItem(KListViewItem *item) + : KListViewItem(item), _renaming(false) +{ + setRenameEnabled(0, true); + static_cast(listView())->_editItems.append(this); +} + +EditListViewItem::~EditListViewItem() +{ + if ( listView() ) static_cast(listView())->_editItems.remove(this); + for (uint i=0; i<_editWidgets.count(); i++) delete _editWidgets[i]; +} + +void EditListViewItem::paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int align) +{ + if ( columnfillRect(0, 0, width, height(), cg.color(QColorGroup::Background)); + else KListViewItem::paintCell(p, cg, column, width, align); +} + +void EditListViewItem::startRename() +{ + if ( !renameEnabled(0) ) return; + QListView *lv = listView(); + if ( !lv ) return; + KListViewItem::startRename(0); + if (renameBox) { + renameBox->removeEventFilter(lv); + renameBox->hide(); + lv->removeChild(renameBox); + } + _renaming = true; + _editWidgets.resize(lv->columns()); + for (uint i=0; i<_editWidgets.count(); i++) { + QRect r = lv->itemRect(this); + r = QRect(lv->viewportToContents(r.topLeft()), r.size()); + r.setLeft(lv->header()->sectionPos(i)); + r.setWidth(lv->header()->sectionSize(i) - 1); + if ( i==0 ) r.setLeft(r.left() + lv->itemMargin() + (depth() + (lv->rootIsDecorated() ? 1 : 0)) * lv->treeStepSize() - 1); + if ( (lv->contentsX() + lv->visibleWidth())<(r.x() + r.width()) ) + lv->scrollBy((r.x() + r.width() ) - ( lv->contentsX() + lv->visibleWidth() ), 0); + if ( r.width()>lv->visibleWidth() ) r.setWidth(lv->visibleWidth()); + + _editWidgets[i] = editWidgetFactory(i); + if ( _editWidgets[i]==0 ) continue; + _editWidgets[i]->installEventFilter(lv); + lv->addChild(_editWidgets[i], r.x(), r.y()); + uint w = QMIN(r.width(), _editWidgets[i]->sizeHint().width()); + _editWidgets[i]->resize(w, r.height()); + lv->viewport()->setFocusProxy(_editWidgets[i]); + _editWidgets[i]->setFocus(); + _editWidgets[i]->show(); + } +} + +void EditListViewItem::removeEditBox() +{ + QListView *lv = listView(); + if ( !lv ) return; + _renaming = false; + bool resetFocus = false; + for (uint i=0; i<_editWidgets.count(); i++) { + if ( lv->viewport()->focusProxy()==_editWidgets[i] ) resetFocus = true; + delete _editWidgets[i]; + } + _editWidgets.clear(); + delete renameBox; + renameBox = 0; + if (resetFocus) { + lv->viewport()->setFocusProxy(lv); + lv->setFocus(); + } +} + +void EditListViewItem::editDone(int col, const QWidget *edit) +{ + if ( edit->metaObject()->findProperty("text", true)!=-1 ) + emit listView()->itemRenamed(this, col, edit->property("text").toString()); + else if ( edit->metaObject()->findProperty("currentText", true)!=-1 ) + emit listView()->itemRenamed(this, col, edit->property("currentText").toString()); +} + +void EditListViewItem::renameDone(bool force) +{ + QListView *lv = listView(); + if ( !lv || !_renaming ) return; + _renaming = false; + for (uint i=0; i<_editWidgets.count(); i++) { + if ( !force && !alwaysAcceptEdit(i) ) continue; + emit lv->itemRenamed(this, i); + if ( _editWidgets[i] ) editDone(i, _editWidgets[i]); + } + removeEditBox(); +} + +int EditListViewItem::width(const QFontMetrics &fm, const QListView *lv, int col) const +{ + int w = KListViewItem::width(fm, lv, col); + QWidget *edit = editWidgetFactory(col); + if ( edit==0 ) return w; + w = QMAX(w, edit->sizeHint().width()); + delete edit; + return w; +} diff --git a/src/common/gui/list_view.h b/src/common/gui/list_view.h new file mode 100644 index 0000000..09ca984 --- /dev/null +++ b/src/common/gui/list_view.h @@ -0,0 +1,93 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef LIST_VIEW_H +#define LIST_VIEW_H + +#include +#include +#define private public +#define protected public +#include +#undef private +#undef protected + +//----------------------------------------------------------------------------- +class EditListViewItem; +class ListViewToolTip; + +class ListView : public KListView +{ +Q_OBJECT +public: + ListView(QWidget *parent = 0, const char *name = 0); + virtual ~ListView(); + virtual void clear(); + void stopRenaming(bool force); + virtual QString tooltip(const QListViewItem &item, int column) const; + +public slots: + void cancelRenaming() { stopRenaming(false); } + void finishRenaming() { stopRenaming(true); } + +protected: + virtual bool eventFilter(QObject *o, QEvent *e); + +private: + ListViewToolTip *_tooltip; + QValueList _editItems; + + friend class EditListViewItem; +}; + +//----------------------------------------------------------------------------- +class ListViewToolTip : public QToolTip +{ +public: + ListViewToolTip(ListView *parent) + : QToolTip(parent->viewport()), _listView(parent) {} + +protected: + virtual void maybeTip(const QPoint &p); + +private: + ListView *_listView; +}; + +//----------------------------------------------------------------------------- +class EditListViewItem : public KListViewItem +{ +public: + EditListViewItem(ListView *list); + EditListViewItem(KListViewItem *item); + virtual ~EditListViewItem(); + void startRename(); + bool isRenaming() const { return _renaming; } + +protected: + virtual QWidget *editWidgetFactory(int col) const = 0; + virtual bool alwaysAcceptEdit(int col) const = 0; + virtual int width(const QFontMetrics &fm, const QListView *lv, int c) const; + virtual void editDone(int col, const QWidget *editWidget); + virtual void paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int align); + +private: + bool _renaming; + QValueVector _editWidgets; + + virtual void activate() { startRename(); } + virtual void startRename(int) { startRename(); } + virtual void okRename(int) { renameDone(true); } + virtual void cancelRename(int) { renameDone(false); } + void renameDone(bool force); + void removeEditBox(); + + friend class ListView; +}; + +#endif diff --git a/src/common/gui/misc_gui.cpp b/src/common/gui/misc_gui.cpp new file mode 100644 index 0000000..00f4997 --- /dev/null +++ b/src/common/gui/misc_gui.cpp @@ -0,0 +1,234 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "misc_gui.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "dialog.h" +#include "common/common/number.h" +#include "common/common/misc.h" +#include "common/gui/number_gui.h" + +//----------------------------------------------------------------------------- +bool BusyCursor::_overridePaused = false; + +void BusyCursor::start() +{ + QApplication::setOverrideCursor(KCursor::waitCursor(), true); +} + +void BusyCursor::stop() +{ + QApplication::restoreOverrideCursor(); +} + +void BusyCursor::pause() +{ + _overridePaused = QApplication::overrideCursor(); + stop(); +} + +void BusyCursor::restore() +{ + if (_overridePaused) start(); +} + +//----------------------------------------------------------------------------- +void MessageBox::information(const QString &text, Log::ShowMode show, const QString &dontShowAgainName) +{ + if ( show==Log::DontShow ) return; + BusyCursor::pause(); + KMessageBox::information(qApp->mainWidget(), text, QString::null, dontShowAgainName, KMessageBox::Notify | KMessageBox::AllowLink); + BusyCursor::restore(); +} + +void MessageBox::detailedSorry(const QString &text, const QString &details, Log::ShowMode show) +{ + if ( show==Log::DontShow ) return; + BusyCursor::pause(); + if ( details.isEmpty() ) KMessageBox::sorry(qApp->mainWidget(), text, QString::null, KMessageBox::Notify | KMessageBox::AllowLink); + else KMessageBox::detailedSorry(qApp->mainWidget(), text, details, QString::null, KMessageBox::Notify | KMessageBox::AllowLink); + BusyCursor::restore(); +} + +bool MessageBox::askContinue(const QString &text, const KGuiItem &buttonContinue, const QString &caption) +{ + ::BusyCursor::pause(); + int res = KMessageBox::warningContinueCancel(qApp->mainWidget(), text, caption, buttonContinue); + ::BusyCursor::restore(); + return ( res==KMessageBox::Continue ); +} + +bool MessageBox::questionYesNo(const QString &text, const KGuiItem &yesButton,const KGuiItem &noButton, const QString &caption) +{ + ::BusyCursor::pause(); + int res = KMessageBox::questionYesNo(qApp->mainWidget(), text, caption, yesButton, noButton); + ::BusyCursor::restore(); + return ( res==KMessageBox::Yes ); +} + +MessageBox::Result MessageBox::questionYesNoCancel(const QString &text, const KGuiItem &yesButton, const KGuiItem &noButton, + const QString &caption) +{ + ::BusyCursor::pause(); + int res = KMessageBox::questionYesNoCancel(qApp->mainWidget(), text, caption, yesButton, noButton); + ::BusyCursor::restore(); + if ( res==KMessageBox::Yes ) return Yes; + if ( res==KMessageBox::No ) return No; + return Cancel; +} + +void MessageBox::text(const QString &text, Log::ShowMode show) +{ + if ( show==Log::DontShow ) return; + BusyCursor::pause(); + TextEditorDialog dialog(text, QString::null, false, qApp->mainWidget()); + dialog.exec(); + BusyCursor::restore(); +} + +//---------------------------------------------------------------------------- +PopupButton::PopupButton(QWidget *parent, const char *name) + : KPushButton(parent, name) +{ + init(); +} + +PopupButton::PopupButton(const QString &text, QWidget *parent, const char *name) + : KPushButton(text, parent, name) +{ + init(); +} + +void PopupButton::init() +{ + _separator = false; + setFlat(true); + QPopupMenu *popup = new QPopupMenu(this); + connect(popup, SIGNAL(activated(int)), SIGNAL(activated(int))); + setPopup(popup); +} + +void PopupButton::appendAction(KAction *action) +{ + if ( _separator && popup()->count()!=0 ) popup()->insertSeparator(); + _separator = false; + action->plug(popup()); +} + +void PopupButton::appendAction(const QString &label, const QString &icon, + QObject *receiver, const char *slot) +{ + appendAction(new KAction(label, icon, 0, receiver, slot, (KActionCollection *)0)); +} + +int PopupButton::appendItem(const QString &label, const QString &icon, int id) +{ + KIconLoader loader; + QPixmap pixmap = loader.loadIcon(icon, KIcon::Small); + return appendItem(label, pixmap, id); +} + +int PopupButton::appendItem(const QString &label, const QPixmap &icon, int id) +{ + if ( _separator && popup()->count()!=0 ) popup()->insertSeparator(); + _separator = false; + return popup()->insertItem(icon, label, id); +} + +//----------------------------------------------------------------------------- +Splitter::Splitter(const QValueList &defaultSizes, Orientation o, QWidget *parent, const char *name) + : QSplitter(o, parent, name), _defaultSizes(defaultSizes) +{ + Q_ASSERT(name); + setOpaqueResize(true); + QTimer::singleShot(0, this, SLOT(updateSizes())); +} + +Splitter::~Splitter() +{ + GuiConfig gc; + gc.writeEntry(QString(name()) + "_sizes", sizes()); +} + +void Splitter::updateSizes() +{ + GuiConfig gc; + QValueList sizes = gc.readIntListEntry(QString(name()) + "_sizes"); + for (uint i=sizes.count(); i<_defaultSizes.count(); i++) sizes.append(_defaultSizes[i]); + setSizes(sizes); +} + +//----------------------------------------------------------------------------- +TabBar::TabBar(QWidget *parent, const char *name) + : KTabBar(parent, name), _ignoreWheelEvent(false) +{} + +void TabBar::wheelEvent(QWheelEvent *e) +{ + if (_ignoreWheelEvent) QApplication::sendEvent(parent(), e); // #### not sure why ignoring is not enough... + else KTabBar::wheelEvent(e); +} + +TabWidget::TabWidget(QWidget *parent, const char *name) + : KTabWidget(parent, name) +{ + setTabBar(new TabBar(this)); +} + +void TabWidget::setIgnoreWheelEvent(bool ignore) +{ + static_cast(tabBar())->_ignoreWheelEvent = ignore; +} + +void TabWidget::wheelEvent(QWheelEvent *e) +{ + if (static_cast(tabBar())->_ignoreWheelEvent) e->ignore(); + else KTabWidget::wheelEvent(e); +} + +void TabWidget::setTabBar(TabBar *tabbar) +{ + KTabWidget::setTabBar(tabbar); + connect(tabBar(), SIGNAL(contextMenu( int, const QPoint & )), SLOT(contextMenu( int, const QPoint & ))); + connect(tabBar(), SIGNAL(mouseDoubleClick( int )), SLOT(mouseDoubleClick( int ))); + connect(tabBar(), SIGNAL(mouseMiddleClick( int )), SLOT(mouseMiddleClick( int ))); + connect(tabBar(), SIGNAL(initiateDrag( int )), SLOT(initiateDrag( int ))); + connect(tabBar(), SIGNAL(testCanDecode(const QDragMoveEvent *, bool & )), SIGNAL(testCanDecode(const QDragMoveEvent *, bool & ))); + connect(tabBar(), SIGNAL(receivedDropEvent( int, QDropEvent * )), SLOT(receivedDropEvent( int, QDropEvent * ))); + connect(tabBar(), SIGNAL(moveTab( int, int )), SLOT(moveTab( int, int ))); + connect(tabBar(), SIGNAL(closeRequest( int )), SLOT(closeRequest( int ))); + connect(tabBar(), SIGNAL(wheelDelta( int )), SLOT(wheelDelta( int ))); +} + +//----------------------------------------------------------------------------- +ComboBox::ComboBox(QWidget *parent, const char *name) + : QComboBox(parent, name), _ignoreWheelEvent(false) +{} + +void ComboBox::wheelEvent(QWheelEvent *e) +{ + if (_ignoreWheelEvent) QApplication::sendEvent(parent(), e); // #### not sure why ignoring is not enough... + else QComboBox::wheelEvent(e); +} diff --git a/src/common/gui/misc_gui.h b/src/common/gui/misc_gui.h new file mode 100644 index 0000000..2d58569 --- /dev/null +++ b/src/common/gui/misc_gui.h @@ -0,0 +1,164 @@ +/*************************************************************************** + * Copyright (C) 2006-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef MISC_GUI_H +#define MISC_GUI_H + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +class KAction; + +#include "common/global/generic_config.h" +#include "common/global/log.h" +#include "common/common/number.h" + +//----------------------------------------------------------------------------- +class BusyCursor +{ +public: + BusyCursor() { start(); } + ~BusyCursor() { stop(); } + static void start(); + static void stop(); + static void pause(); + static void restore(); + +private: + static bool _overridePaused; +}; + +//----------------------------------------------------------------------------- +namespace MessageBox +{ +extern void information(const QString &text, Log::ShowMode show, const QString &dontShowAgainName = QString::null); +extern void detailedSorry(const QString &text, const QString &details, Log::ShowMode show); +inline void sorry(const QString &text, Log::ShowMode show) { detailedSorry(text, QString::null, show); } +extern bool askContinue(const QString &text, const KGuiItem &continueButton = KStdGuiItem::cont(), + const QString &caption = i18n("Warning")); +extern bool questionYesNo(const QString &text, const KGuiItem &yesButton, const KGuiItem &noButton, + const QString &caption = i18n("Warning")); +enum Result { Yes, No, Cancel }; +extern Result questionYesNoCancel(const QString &text, const KGuiItem &yesButton, const KGuiItem &noButton, + const QString &caption = i18n("Warning")); +extern void text(const QString &text, Log::ShowMode show); +} + +//---------------------------------------------------------------------------- +class PopupButton : public KPushButton +{ +Q_OBJECT +public: + PopupButton(QWidget *parent = 0, const char *name = 0); + PopupButton(const QString &text, QWidget *parent = 0, const char *name = 0); + void appendAction(KAction *action); + void appendAction(const QString &label, const QString &icon = QString::null, + QObject *receiver = 0, const char *slot = 0); + int appendItem(const QString &label, uint id) { return appendItem(label, QPixmap(), id); } + int appendItem(const QString &label, const QString &icon, int id = -1); + int appendItem(const QString &label, const QPixmap &icon, int id = -1); + void appendSeparator() { _separator = true; } + +signals: + void activated(int id); + +private: + bool _separator; + + void init(); +}; + +//----------------------------------------------------------------------------- +class Splitter : public QSplitter +{ +Q_OBJECT +public: + Splitter(const QValueList &defaultSizes, Orientation orientation, + QWidget *parent, const char *name); + virtual ~Splitter(); + +private slots: + void updateSizes(); + +private: + QValueList _defaultSizes; +}; + +//----------------------------------------------------------------------------- +class GuiConfig : public GenericConfig +{ +public: + GuiConfig() : GenericConfig("gui") {} +}; + +//----------------------------------------------------------------------------- +class SeparatorWidget : public QFrame +{ +Q_OBJECT +public: + SeparatorWidget(QWidget *parent) : QFrame(parent, "separator") { + setFrameStyle(QFrame::Panel | QFrame::Sunken); + setMargin(2); + setFixedHeight(2*2); + } +}; + +//----------------------------------------------------------------------------- +class TabBar : public KTabBar +{ +Q_OBJECT +public: + TabBar(QWidget *parent = 0, const char *name = 0); + +protected: + virtual void wheelEvent(QWheelEvent *e); + +private: + bool _ignoreWheelEvent; + + friend class TabWidget; +}; + +class TabWidget : public KTabWidget +{ +Q_OBJECT +public: + TabWidget(QWidget *parent = 0, const char *name = 0); + void setIgnoreWheelEvent(bool ignore); + +protected: + virtual void wheelEvent(QWheelEvent *e); + void setTabBar(TabBar *tabbar); +}; + +//----------------------------------------------------------------------------- +class ComboBox : public QComboBox +{ +Q_OBJECT +public: + ComboBox(QWidget *parent = 0, const char *name = 0); + void setIgnoreWheelEvent(bool ignore) { _ignoreWheelEvent = ignore; } + +protected: + virtual void wheelEvent(QWheelEvent *e); + +private: + bool _ignoreWheelEvent; +}; + +#endif diff --git a/src/common/gui/number_gui.cpp b/src/common/gui/number_gui.cpp new file mode 100644 index 0000000..d855407 --- /dev/null +++ b/src/common/gui/number_gui.cpp @@ -0,0 +1,72 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "number_gui.h" + +#include + +//----------------------------------------------------------------------------- +uint maxCharWidth(const QString &s, const QFont &font) +{ + QFontMetrics fm(font); + uint w = 0; + for (uint i=0; i * + * * + * 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. * + ***************************************************************************/ +#ifndef NUMBER_GUI_H +#define NUMBER_GUI_H + +#include +#include + +#include "common/common/number.h" + +//----------------------------------------------------------------------------- +extern uint maxCharWidth(const QString &s, const QFont &font); +extern uint maxCharWidth(NumberBase base, const QFont &font); +inline uint maxStringWidth(NumberBase base, uint nbChars, const QFont &font) { return nbChars * maxCharWidth(base, font); } +extern uint maxLabelWidth(NumberBase base, uint nbChars, const QFont &font); + +extern QValidator::State validateNumber(const QString &s); + +//----------------------------------------------------------------------------- +class NumberLineEdit : public KLineEdit +{ +Q_OBJECT +public: + NumberLineEdit(QWidget *parent = 0, const char *name = 0); + NumberLineEdit(const QString &text, QWidget *parent = 0, const char *name = 0); + uint value(bool *ok = 0) const { return fromAnyLabel(text(), ok); } + void setColor(const QColor &color) { setPaletteForegroundColor(color); } + void unsetColor() { unsetPalette(); } + +private slots: + void textChangedSlot(); +}; + +#endif diff --git a/src/common/gui/pfile_ext.cpp b/src/common/gui/pfile_ext.cpp new file mode 100644 index 0000000..d42de16 --- /dev/null +++ b/src/common/gui/pfile_ext.cpp @@ -0,0 +1,114 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "pfile_ext.h" + +#include +#include +#include +#include "common/gui/misc_gui.h" + +//----------------------------------------------------------------------------- +bool PURL::File::openForWrite() +{ + close(); + if (_tmp) delete _tmp; + _tmp = new KTempFile(QString::null, _extension); + _tmp->setAutoDelete(true); + if ( _tmp->status()!=0 ) { + _error = i18n("Could not create temporary file."); + _log.sorry(_error, i18n("File: %1").arg(_tmp->name())); + return false; + } + return true; +} + +bool PURL::File::close() +{ + if (_tmp) _tmp->close(); + else _file->close(); + bool ok = (_tmp ? _tmp->status() : _file->status())==IO_Ok; + if ( !_file->name().isEmpty() ) { + KIO::NetAccess::removeTempFile(_file->name()); + _file->setName(QString::null); + } + delete _stream; + _stream = 0; + if ( ok && _tmp && !_url.isEmpty() && !KIO::NetAccess::upload(_tmp->name(), _url.kurl(), qApp->mainWidget()) ) { + _error = KIO::NetAccess::lastErrorString(); + ok = false; + _log.sorry(i18n("Could not save file."), errorString()); + } + delete _tmp; + _tmp = 0; + return ok; +} + +bool PURL::File::openForRead() +{ + close(); + QString tmp; + if ( !KIO::NetAccess::download(_url.kurl(), tmp, qApp->mainWidget()) ) { + _error = KIO::NetAccess::lastErrorString(); + _log.sorry(i18n("Could not open file for reading."), errorString()); + return false; + } + _file->setName(tmp); + if ( !_file->open(IO_ReadOnly) ) { + _error = i18n("Could not open temporary file."); + _log.sorry(_error, i18n("File: %1").arg(_file->name())); + return false; + } + return true; +} + +bool PURL::File::remove() +{ + close(); + if ( !_url.isEmpty() ) return _url.del(_log); + return false; +} + +//----------------------------------------------------------------------------- +PURL::TempFile::TempFile(Log::Generic &log, const QString &extension) + : FileBase(log, extension) +{} + +PURL::Url PURL::TempFile::url() const +{ + return (_tmp ? Url::fromPathOrUrl(_tmp->name()) : Url()); +} + +bool PURL::TempFile::close() +{ + delete _stream; + _stream = 0; + if (_tmp) { + _tmp->close(); + if ( _tmp->status()!=IO_Ok ) { + _error = i18n("Could not write to temporary file."); + _log.sorry(_error, i18n("File: %1").arg(_tmp->name())); + return false; + } + } + return true; +} + +bool PURL::TempFile::openForWrite() +{ + close(); + if (_tmp) delete _tmp; + _tmp = new KTempFile(QString::null, _extension); + _tmp->setAutoDelete(true); + if ( _tmp->status()!=0 ) { + _error = i18n("Could not create temporary file."); + _log.sorry(_error, i18n("File: %1").arg(_tmp->name())); + return false; + } + return true; +} diff --git a/src/common/gui/pfile_ext.h b/src/common/gui/pfile_ext.h new file mode 100644 index 0000000..14c007a --- /dev/null +++ b/src/common/gui/pfile_ext.h @@ -0,0 +1,29 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PFILE_EXT_H +#define PFILE_EXT_H + +#include "common/global/pfile.h" + +namespace PURL +{ + +class TempFile : public FileBase +{ +public: + TempFile(Log::Generic &log, const QString &extension = QString::null); + ~TempFile() { close(); } + Url url() const; + bool close(); + bool openForWrite(); +}; + +} // namespace + +#endif diff --git a/src/common/gui/purl_ext.cpp b/src/common/gui/purl_ext.cpp new file mode 100644 index 0000000..5d69d05 --- /dev/null +++ b/src/common/gui/purl_ext.cpp @@ -0,0 +1,111 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "common/global/purl.h" + +#include +#include +#include +#include +#include +#include + +#include "common/global/pfile.h" + +bool PURL::Url::copyTo(const Url &destination, Log::Generic &log) const +{ +//#if defined(NO_KDE) +// Synchronous sync; +// if ( sync.op().copy(_url.filepath(), destination.filepath()) && sync.execute() ) { +// if ( show==Log::Show ) ConsoleView::sorry(i18n("Could not copy file"), sync.error()); +// return false; +// } +//#else + // do not overwrite + bool ok = KIO::NetAccess::file_copy(_url, destination._url, -1, false, false, qApp->mainWidget()); + if ( !ok ) log.sorry(i18n("Could not copy file"), KIO::NetAccess::lastErrorString()); + return ok; +//#endif +} + +bool PURL::Url::create(Log::Generic &log) const +{ +//#if defined(NO_KDE) +// QByteArray a; +// Synchronous sync; +// if ( sync.op().put(a, _url.filepath()) && sync.execute() ) { +// if ( show==Log::Show ) ConsoleView::sorry(i18n("Could not create file"), sync.error()); +// return false; +// } +//#else + // assume file do no exist if ioslave cannot tell... + if ( KIO::NetAccess::exists(_url, false, qApp->mainWidget()) ) return true; + KTempFile tmp; + tmp.setAutoDelete(true); + // do not overwrite + bool ok = KIO::NetAccess::file_copy(tmp.name(), _url, -1, false, false, qApp->mainWidget()); + if ( !ok ) log.sorry(i18n("Could not create file"), KIO::NetAccess::lastErrorString()); +//#endif + return ok; +} + +bool PURL::Url::write(const QString &text, Log::Generic &log) const +{ + File file(*this, log); + if ( !file.openForWrite() ) return false; + file.stream() << text; + return file.close(); +} + +bool PURL::Url::del(Log::Generic &log) const +{ +//#if defined(NO_KDE) +// Synchronous sync; +// if ( sync.op().remove(_url.filepath()) && sync.execute() ) { +// if ( show==Log::Show ) ConsoleView::sorry(i18n("Could not delete file"), sync.error()); +// return false; +// } +//#else + bool ok = KIO::NetAccess::del(_url, qApp->mainWidget()); + if ( !ok ) log.sorry(i18n("Could not delete file."), KIO::NetAccess::lastErrorString()); + return ok; +//#endif +} + +bool PURL::Url::isDosFile() const +{ + Log::Base log; + File file(*this, log); + if( !file.openForRead() ) return false; + int oldc = 0; + for (;;) { + int c = file.qfile()->getch(); + if ( c==-1 ) break; + if( c=='\n' && oldc=='\r' ) return true; + oldc = c; + } + return false; +} + +//----------------------------------------------------------------------------- +bool PURL::Directory::create(Log::Generic &log) const +{ +//#if defined(NO_KDE) +// Synchronous sync; +// if ( sync.op().mkdir(_url.filepath()) && sync.execute() ) { +// if ( show==Log::Show ) ConsoleView::sorry(i18n("Could not create directory"), sync.error()); +// return false; +// } +//#else + // assume dir do no exist if ioslave cannot tell... + if ( KIO::NetAccess::exists(_url, false, qApp->mainWidget()) ) return true; + bool ok = KIO::NetAccess::mkdir(_url, qApp->mainWidget()); + if ( !ok ) log.sorry(i18n("Could not create directory"), KIO::NetAccess::lastErrorString()); +//#endif + return ok; +} diff --git a/src/common/gui/purl_gui.cpp b/src/common/gui/purl_gui.cpp new file mode 100644 index 0000000..d81fdb6 --- /dev/null +++ b/src/common/gui/purl_gui.cpp @@ -0,0 +1,151 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "purl_gui.h" + +#include +#include +#include +#include +#include +#include + +#include "misc_gui.h" + +//----------------------------------------------------------------------------- +PURL::Url PURL::getOpenUrl(const QString &startDir, const QString &filter, + QWidget *widget, const QString &caption) +{ + return KFileDialog::getOpenURL(startDir, filter, widget, caption); +} + +PURL::UrlList PURL::getOpenUrls(const QString &startDir, const QString &filter, + QWidget *widget, const QString &caption) +{ + return KFileDialog::getOpenURLs(startDir, filter, widget, caption); +} + +PURL::Url PURL::getSaveUrl(const QString &startDir, const QString &filter, + QWidget *widget, const QString &caption, + SaveAction action) +{ + Url url = KFileDialog::getSaveURL(startDir, filter, widget, caption); + if ( url.isEmpty() ) return Url(); + switch (action) { + case NoSaveAction: break; + case AskOverwrite: + if ( url.exists() ) { + if ( !MessageBox::askContinue(i18n("File \"%1\" already exists. Overwrite ?").arg(url.pretty())) ) return Url(); + } + break; + case CancelIfExists: + if ( url.exists() ) return Url(); + break; + } + return url; +} + +PURL::Directory PURL::getExistingDirectory(const QString &startDir, QWidget *widget, + const QString &caption) +{ + KURL kurl = KDirSelectDialog::selectDirectory(startDir, false, widget, caption); + if ( kurl.isEmpty() ) return Directory(); + return Directory(kurl.path(1)); +} + +QPixmap PURL::icon(FileType type) +{ + if (type.data().xpm_icon) return QPixmap(type.data().xpm_icon); + if ( hasMimetype(type) ) return KMimeType::mimeType(type.data().mimetype)->pixmap(KIcon::Small); + return QPixmap(); +} + +bool PURL::hasMimetype(FileType type) +{ + if ( type.data().mimetype==0 ) return false; + KMimeType::Ptr ptr = KMimeType::mimeType(type.data().mimetype); + return ( ptr!=KMimeType::defaultMimeTypePtr() ); +} + +//----------------------------------------------------------------------------- +PURL::Label::Label(const QString &url, const QString &text, + QWidget *parent, const char *name) + : KURLLabel(url, text, parent, name) +{ + connect(this, SIGNAL(leftClickedURL()), SLOT(urlClickedSlot())); +} + +void PURL::Label::urlClickedSlot() +{ + (void)new KRun(url()); +} + +//----------------------------------------------------------------------------- +PURL::BaseWidget::BaseWidget(QWidget *parent, const char *name) + : QWidget(parent, name) +{ + init(); +} + +PURL::BaseWidget::BaseWidget(const QString &defaultDir, QWidget *parent, const char *name) + : QWidget(parent, name), _defaultDir(defaultDir) +{ + init(); +} + +void PURL::BaseWidget::init() +{ + QHBoxLayout *top = new QHBoxLayout(this, 0, 10); + + _edit = new KLineEdit(this); + connect(_edit, SIGNAL(textChanged(const QString &)), SIGNAL(changed())); + top->addWidget(_edit); + KIconLoader loader; + QIconSet iconset = loader.loadIcon("fileopen", KIcon::Toolbar); + QPushButton *button = new KPushButton(iconset, QString::null, this); + connect(button, SIGNAL(clicked()), SLOT(buttonClicked())); + top->addWidget(button); +} + +//---------------------------------------------------------------------------- +void PURL::DirectoryWidget::buttonClicked() +{ + Directory dir = getExistingDirectory(_defaultDir, this, i18n("Select Directory")); + if ( dir.isEmpty() ) return; + _edit->setText(dir.path()); + emit changed(); +} + +//---------------------------------------------------------------------------- +PURL::DirectoriesWidget::DirectoriesWidget(const QString &title, QWidget *parent, const char *name) + : QVGroupBox(title, parent, name) +{ + init(QString::null); +} + +PURL::DirectoriesWidget::DirectoriesWidget(const QString &title, const QString &defaultDir, QWidget *parent, const char *name) + : QVGroupBox(title, parent, name) +{ + init(defaultDir); +} + +void PURL::DirectoriesWidget::init(const QString &defaultDir) +{ + DirectoryWidget *edit = new DirectoryWidget(defaultDir); + _editListBox = new EditListBox(1, edit, edit->lineEdit(), this, "directories_editlistbox"); + connect(_editListBox, SIGNAL(changed()), SIGNAL(changed())); +} + +//---------------------------------------------------------------------------- +void PURL::UrlWidget::buttonClicked() +{ + Url url = getOpenUrl(_defaultDir, _filter, this, i18n("Select File")); + if ( url.isEmpty() ) return; + _edit->setText(url.filepath()); + emit changed(); +} diff --git a/src/common/gui/purl_gui.h b/src/common/gui/purl_gui.h new file mode 100644 index 0000000..a11bedf --- /dev/null +++ b/src/common/gui/purl_gui.h @@ -0,0 +1,120 @@ +/*************************************************************************** + * Copyright (C) 2006-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PURL_GUI_H +#define PURL_GUI_H + +#include +#include +#include +#include + +#include "common/global/purl.h" +#include "editlistbox.h" + +namespace PURL +{ +//----------------------------------------------------------------------------- +extern bool hasMimetype(FileType type); +extern QPixmap icon(FileType type); +extern Directory getExistingDirectory(const QString &startDir, QWidget *widget, const QString &caption); +extern Url getOpenUrl(const QString &startDir, const QString &filter, QWidget *widget, + const QString &caption); +extern UrlList getOpenUrls(const QString &startDir, const QString &filter, QWidget *widget, + const QString &caption); +enum SaveAction { NoSaveAction, AskOverwrite, CancelIfExists }; +extern Url getSaveUrl(const QString &startDir, const QString &filter, QWidget *widget, + const QString &caption, SaveAction action); + +//----------------------------------------------------------------------------- +class Label : public KURLLabel +{ +Q_OBJECT +public: + Label(const QString &url, const QString &text, QWidget *parent = 0, const char *name = 0); + +private slots: + void urlClickedSlot(); +}; + +//----------------------------------------------------------------------------- +class BaseWidget : public QWidget +{ +Q_OBJECT +public: + BaseWidget(QWidget *parent = 0, const char *name = 0); + BaseWidget(const QString &defaultDir, QWidget *parent = 0, const char *name = 0); + KLineEdit *lineEdit() { return _edit; } + +signals: + void changed(); + +protected slots: + virtual void buttonClicked() = 0; + +protected: + QString _defaultDir; + KLineEdit *_edit; + + void init(); +}; + +//----------------------------------------------------------------------------- +class DirectoryWidget : public BaseWidget +{ +Q_OBJECT +public: + DirectoryWidget(QWidget *parent = 0, const char *name = 0) : BaseWidget(parent, name) {} + DirectoryWidget(const QString &defaultDir, QWidget *parent = 0, const char *name = 0) : BaseWidget(defaultDir, parent, name) {} + void setDirectory(const Directory &dir) { _edit->setText(dir.path()); } + Directory directory() const { return _edit->text(); } + +protected slots: + virtual void buttonClicked(); +}; + +//----------------------------------------------------------------------------- +class DirectoriesWidget : public QVGroupBox +{ +Q_OBJECT +public: + DirectoriesWidget(const QString &title, QWidget *parent = 0, const char *name = 0); + DirectoriesWidget(const QString &title, const QString &defaultDir, QWidget *parent = 0, const char *name = 0); + void setDirectories(const QStringList &dirs) { _editListBox->setTexts(dirs); } + QStringList directories() const { return _editListBox->texts(); } + +signals: + void changed(); + +private: + EditListBox *_editListBox; + void init(const QString &defaultDir); +}; + +//----------------------------------------------------------------------------- +class UrlWidget : public BaseWidget +{ +Q_OBJECT +public: + UrlWidget(const QString &filter, QWidget *parent = 0, const char *name = 0) + : BaseWidget(parent, name), _filter(filter) {} + UrlWidget(const QString &defaultDir, const QString &filter, QWidget *parent = 0, const char *name = 0) + : BaseWidget(defaultDir, parent, name), _filter(filter) {} + Url url() const { return PURL::Url::fromPathOrUrl(_edit->text()); } + void setUrl(const Url &url) { _edit->setText(url.filepath()); } + +protected slots: + virtual void buttonClicked(); + +private: + QString _filter; +}; + +} // namespace + +#endif diff --git a/src/common/nokde/nokde.pro b/src/common/nokde/nokde.pro new file mode 100644 index 0000000..aa92599 --- /dev/null +++ b/src/common/nokde/nokde.pro @@ -0,0 +1,8 @@ +STOPDIR = ../../.. +include($${STOPDIR}/lib.pro) + +TARGET = nokde +HEADERS += nokde_klocale.h nokde_kaboutdata.h nokde_kcmdlineargs.h nokde_kprocess.h +SOURCES += nokde_klocale.cpp nokde_kaboutdata.cpp nokde_kcmdlineargs.cpp nokde_kprocess.cpp +win32:HEADERS += win32_utils.h +win32:SOURCES += win32_utils.c \ No newline at end of file diff --git a/src/common/nokde/nokde_kaboutdata.cpp b/src/common/nokde/nokde_kaboutdata.cpp new file mode 100644 index 0000000..21b6917 --- /dev/null +++ b/src/common/nokde/nokde_kaboutdata.cpp @@ -0,0 +1,469 @@ +// modified from KDE 3.4 for Windows port (Nicolas Hadacek) + +/* + * This file is part of the KDE Libraries + * Copyright (C) 2000 Espen Sand (espen@kde.org) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + + +#include "nokde_kaboutdata.h" +//#include +#include +#include +#include + +QString +KAboutPerson::name() const +{ + return QString::fromUtf8(mName); +} + +QString +KAboutPerson::task() const +{ + if (mTask && *mTask) + return i18n(mTask); + else + return QString::null; +} + +QString +KAboutPerson::emailAddress() const +{ + return QString::fromUtf8(mEmailAddress); +} + + +QString +KAboutPerson::webAddress() const +{ + return QString::fromUtf8(mWebAddress); +} + + +KAboutTranslator::KAboutTranslator(const QString & name, + const QString & emailAddress) +{ + mName=name; + mEmail=emailAddress; +} + +QString KAboutTranslator::name() const +{ + return mName; +} + +QString KAboutTranslator::emailAddress() const +{ + return mEmail; +} + +class KAboutDataPrivate +{ +public: + KAboutDataPrivate() + : translatorName("_: NAME OF TRANSLATORS\nYour names") + , translatorEmail("_: EMAIL OF TRANSLATORS\nYour emails") + , productName(0) +// , programLogo(0) + {} + ~KAboutDataPrivate() + { +// delete programLogo; + } + const char *translatorName; + const char *translatorEmail; + const char *productName; +// QImage* programLogo; +}; + + + +KAboutData::KAboutData( const char *appName, + const char *programName, + const char *version, + const char *shortDescription, + int licenseType, + const char *copyrightStatement, + const char *text, + const char *homePageAddress, + const char *bugsEmailAddress + ) : + mProgramName( programName ), + mVersion( version ), + mShortDescription( shortDescription ), + mLicenseKey( licenseType ), + mCopyrightStatement( copyrightStatement ), + mOtherText( text ), + mHomepageAddress( homePageAddress ), + mBugEmailAddress( bugsEmailAddress ), + mLicenseText (0) +{ + d = new KAboutDataPrivate; + + if( appName ) { + const char *p = strrchr(appName, '/'); + if( p ) + mAppName = p+1; + else + mAppName = appName; + } else + mAppName = 0; +} + +KAboutData::~KAboutData() +{ + if (mLicenseKey == License_File) + delete [] mLicenseText; + delete d; +} + +void +KAboutData::addAuthor( const char *name, const char *task, + const char *emailAddress, const char *webAddress ) +{ + mAuthorList.append(KAboutPerson(name,task,emailAddress,webAddress)); +} + +void +KAboutData::addCredit( const char *name, const char *task, + const char *emailAddress, const char *webAddress ) +{ + mCreditList.append(KAboutPerson(name,task,emailAddress,webAddress)); +} + +void +KAboutData::setTranslator( const char *name, const char *emailAddress) +{ + d->translatorName=name; + d->translatorEmail=emailAddress; +} + +void +KAboutData::setLicenseText( const char *licenseText ) +{ + mLicenseText = licenseText; + mLicenseKey = License_Custom; +} + +void +KAboutData::setLicenseTextFile( const QString &file ) +{ + mLicenseText = qstrdup(QFile::encodeName(file)); + mLicenseKey = License_File; +} + +void +KAboutData::setAppName( const char *appName ) +{ + mAppName = appName; +} + +void +KAboutData::setProgramName( const char* programName ) +{ + mProgramName = programName; +} + +void +KAboutData::setVersion( const char* version ) +{ + mVersion = version; +} + +void +KAboutData::setShortDescription( const char *shortDescription ) +{ + mShortDescription = shortDescription; +} + +void +KAboutData::setLicense( LicenseKey licenseKey) +{ + mLicenseKey = licenseKey; +} + +void +KAboutData::setCopyrightStatement( const char *copyrightStatement ) +{ + mCopyrightStatement = copyrightStatement; +} + +void +KAboutData::setOtherText( const char *otherText ) +{ + mOtherText = otherText; +} + +void +KAboutData::setHomepage( const char *homepage ) +{ + mHomepageAddress = homepage; +} + +void +KAboutData::setBugAddress( const char *bugAddress ) +{ + mBugEmailAddress = bugAddress; +} + +void +KAboutData::setProductName( const char *productName ) +{ + d->productName = productName; +} + +const char * +KAboutData::appName() const +{ + return mAppName; +} + +const char * +KAboutData::productName() const +{ + if (d->productName) + return d->productName; + else + return appName(); +} + +QString +KAboutData::programName() const +{ + if (mProgramName && *mProgramName) + return i18n(mProgramName); + else + return QString::null; +} +/* +QImage +KAboutData::programLogo() const +{ + return d->programLogo ? (*d->programLogo) : QImage(); +} + +void +KAboutData::setProgramLogo(const QImage& image) +{ + if (!d->programLogo) + d->programLogo = new QImage( image ); + else + *d->programLogo = image; +} +*/ +QString +KAboutData::version() const +{ + return QString::fromLatin1(mVersion); +} + +QString +KAboutData::shortDescription() const +{ + if (mShortDescription && *mShortDescription) + return i18n(mShortDescription); + else + return QString::null; +} + +QString +KAboutData::homepage() const +{ + return QString::fromLatin1(mHomepageAddress); +} + +QString +KAboutData::bugAddress() const +{ + return QString::fromLatin1(mBugEmailAddress); +} + +const QValueList +KAboutData::authors() const +{ + return mAuthorList; +} + +const QValueList +KAboutData::credits() const +{ + return mCreditList; +} + +const QValueList +KAboutData::translators() const +{ + QValueList personList; + + if(d->translatorName == 0) + return personList; + + QStringList nameList; + QStringList emailList; + + QString names = i18n(d->translatorName); + if(names != QString::fromUtf8(d->translatorName)) + { +#if QT_VERSION < 0x040000 + nameList = QStringList::split(',',names); +#else + nameList = names.split(',', QString::SkipEmptyParts); +#endif + } + + + if(d->translatorEmail) + { + QString emails = i18n(d->translatorEmail); + + if(emails != QString::fromUtf8(d->translatorEmail)) + { +#if QT_VERSION < 0x040000 + emailList = QStringList::split(',',emails,true); +#else + emailList = emails.split(','); +#endif + } + } + + + QStringList::Iterator nit; + QStringList::Iterator eit=emailList.begin(); + + for(nit = nameList.begin(); nit != nameList.end(); ++nit) + { + QString email; + if(eit != emailList.end()) + { + email=*eit; + ++eit; + } + + QString name=*nit; + +#if QT_VERSION < 0x040000 + personList.append(KAboutTranslator(name.stripWhiteSpace(), email.stripWhiteSpace())); +#else + personList.append(KAboutTranslator(name.trimmed(), email.trimmed())); +#endif + } + + return personList; +} + +QString +KAboutData::aboutTranslationTeam() +{ + return i18n("replace this with information about your translation team", + "

KDE is translated into many languages thanks to the work " + "of the translation teams all over the world.

" + "

For more information on KDE internationalization " + "visit http://i18n.kde.org

"); +} + +QString +KAboutData::otherText() const +{ + if (mOtherText && *mOtherText) + return i18n(mOtherText); + else + return QString::null; +} + + +QString +KAboutData::license() const +{ + QString result; + if (!copyrightStatement().isEmpty()) + result = copyrightStatement() + "\n\n"; + + QString l; + QString f; + switch ( mLicenseKey ) + { + case License_File: + f = QFile::decodeName(mLicenseText); + break; + case License_GPL_V2: + l = "GPL v2"; + f = locate("data", "LICENSES/GPL_V2"); + break; + case License_LGPL_V2: + l = "LGPL v2"; + f = locate("data", "LICENSES/LGPL_V2"); + break; + case License_BSD: + l = "BSD License"; + f = locate("data", "LICENSES/BSD"); + break; + case License_Artistic: + l = "Artistic License"; + f = locate("data", "LICENSES/ARTISTIC"); + break; + case License_QPL_V1_0: + l = "QPL v1.0"; + f = locate("data", "LICENSES/QPL_V1.0"); + break; + case License_Custom: + if (mLicenseText && *mLicenseText) + return( i18n(mLicenseText) ); + // fall through + default: + result += i18n("No licensing terms for this program have been specified.\n" + "Please check the documentation or the source for any\n" + "licensing terms.\n"); + return result; + } + + if (!l.isEmpty()) + result += i18n("This program is distributed under the terms of the %1.").arg( l ); + + if (!f.isEmpty()) + { + QFile file(f); +#if QT_VERSION < 0x040000 + if (file.open(IO_ReadOnly)) +#else + if (file.open(QIODevice::ReadOnly)) +#endif + { + result += '\n'; + result += '\n'; + QTextStream str(&file); +#if QT_VERSION < 0x040000 + result += str.read(); +#else + result += str.readAll(); +#endif + } + } + + return result; +} + +QString +KAboutData::copyrightStatement() const +{ + if (mCopyrightStatement && *mCopyrightStatement) + return i18n(mCopyrightStatement); + else + return QString::null; +} diff --git a/src/common/nokde/nokde_kaboutdata.h b/src/common/nokde/nokde_kaboutdata.h new file mode 100644 index 0000000..13076d4 --- /dev/null +++ b/src/common/nokde/nokde_kaboutdata.h @@ -0,0 +1,571 @@ +// modified from KDE 3.4 for Windows port (Nicolas Hadacek) + +/* + * This file is part of the KDE Libraries + * Copyright (C) 2000 Espen Sand (espen@kde.org) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include +#if QT_VERSION < 0x040000 +# include +#else +# include +# define QValueList Q3ValueList +# include +#endif +#include +//#include + +#include "nokde_klocale.h" + +#ifndef _KABOUTDATA_H_ +#define _KABOUTDATA_H_ + +class KAboutPersonPrivate; +class KAboutDataPrivate; + +/** + * This structure is used to store information about a person or developer. + * It can store the person's name, a task, an email address and a + * link to a home page. This class is intended for use in the + * KAboutData class, but it can be used elsewhere as well. + * Normally you should at least define the person's name. + * + * Example Usage within a main(): + * + * KAboutData about("khello", I18N_NOOP("KHello"), "0.1", + * I18N_NOOP("A KDE version of Hello, world!"), + * KAboutData::License_LGPL, + * I18N_NOOP("Copyright (c) 2003 Developer")); + * + * about.addAuthor("Joe Developer", I18N_NOOP("developer"), "joe@host.com", 0); + * about.addCredit("Joe User", I18N_NOOP("A lot of bug reports"), + * "joe.user@host.org", 0); + * KCmdLineArgs::init(argc, argv, &about); + */ +class KDECORE_EXPORT KAboutPerson +{ +public: + /** + * Convenience constructor + * + * @param name The name of the person. + * + * @param task The task of this person. This string should be + * marked for translation, e.g. + * I18N_NOOP("Task description....") + * + * @param emailAddress The email address of the person. + * + * @param webAddress Home page of the person. + */ + KAboutPerson( const char *name, const char *task, + const char *emailAddress, const char *webAddress ) + { + mName = name; + mTask = task; + mEmailAddress = emailAddress; + mWebAddress = webAddress; + } + /** + * @internal + * Don't use. Required by QValueList + */ + KAboutPerson() {} + + /** + * The person's name + * @return the person's name (can be QString::null, if it has been + * constructed with a null name) + */ + QString name() const; + + /** + * The person's task + * @return the person's task (can be QString::null, if it has been + * constructed with a null task) + */ + QString task() const; + + /** + * The person's email address + * @return the person's email address (can be QString::null, if it has been + * constructed with a null email) + */ + QString emailAddress() const; + + /** + * The home page or a relevant link + * @return the persons home page (can be QString::null, if it has been + * constructed with a null home page) + */ + QString webAddress() const; + +private: + const char *mName; + const char *mTask; + const char *mEmailAddress; + const char *mWebAddress; + + KAboutPersonPrivate *d; +}; + +class KAboutTranslatorPrivate; +/** + * This structure is used to store information about a translator. + * It can store the translator's name and an email address. + * This class is intended for use in the KAboutData class, + * but it can be used elsewhere as well. + * Normally you should at least define the translator's name. + * + * It's not possible to use KAboutPerson for this, because + * KAboutPerson stores internally only const char* pointers, but the + * translator information is generated dynamically from the translation + * of a dummy string. +*/ +class KDECORE_EXPORT KAboutTranslator +{ +public: + /** + * Convenience constructor + * + * @param name The name of the person. + * + * @param emailAddress The email address of the person. + */ + KAboutTranslator(const QString & name=QString::null, + const QString & emailAddress=QString::null); + + /** + * The translator's name + * @return the translators's name (can be QString::null, if it has been + * constructed with a null name) + */ + QString name() const; + + /** + * The translator's email + * @return the translator's email address (can be QString::null, if it has been + * constructed with a null email) + */ + QString emailAddress() const; + +private: + QString mName; + QString mEmail; + KAboutTranslatorPrivate* d; +}; + + +/** + * This class is used to store information about a program. It can store + * such values as version number, program name, home page, email address + * for bug reporting, multiple authors and contributors + * (using KAboutPerson), license and copyright information. + * + * Currently, the values set here are shown by the "About" box + * (see KAboutDialog), used by the bug report dialog (see KBugReport), + * and by the help shown on command line (see KCmdLineArgs). + * + * @short Holds information needed by the "About" box and other + * classes. + * @author Espen Sand (espen@kde.org), David Faure (faure@kde.org) + */ +class KDECORE_EXPORT KAboutData +{ + public: + /** + * Descibes the license of the software. + */ + enum LicenseKey + { + License_Custom = -2, + License_File = -1, + License_Unknown = 0, + License_GPL = 1, + License_GPL_V2 = 1, + License_LGPL = 2, + License_LGPL_V2 = 2, + License_BSD = 3, + License_Artistic = 4, + License_QPL = 5, + License_QPL_V1_0 = 5 + }; + + public: + /** + * Constructor. + * + * @param appName The program name used internally. Example: "kedit" + * + * @param programName A displayable program name string. This string + * should be marked for translation. Example: I18N_NOOP("KEdit") + * + * @param version The program version string. + * + * @param shortDescription A short description of what the program does. + * This string should be marked for translation. + * Example: I18N_NOOP("A simple text editor.") + * + * @param licenseType The license identifier. Use setLicenseText if + * you use a license not predefined here. + * + * @param copyrightStatement A copyright statement, that can look like this: + * "(c) 1999-2000, Name". The string specified here is not modified + * in any manner. The author information from addAuthor is not + * used. + * + * @param text Some free form text, that can contain any kind of + * information. The text can contain newlines. This string + * should be marked for translation. + * + * @param homePageAddress The program homepage string. + * Start the address with "http://". "http://some.domain" is + * is correct, "some.domain" is not. + * + * @param bugsEmailAddress The bug report email address string. + * This defaults to the kde.org bug system. + * + */ + KAboutData( const char *appName, + const char *programName, + const char *version, + const char *shortDescription = 0, + int licenseType = License_Unknown, + const char *copyrightStatement = 0, + const char *text = 0, + const char *homePageAddress = 0, + const char *bugsEmailAddress = "submit@bugs.kde.org" + ); + + ~KAboutData(); + + /** + * Defines an author. You can call this function as many times you + * need. Each entry is appended to a list. The person in the first entry + * is assumed to be the leader of the project. + * + * @param name The developer's name in UTF-8 encoding. + * + * @param task What the person is responsible for. This text can contain + * newlines. It should be marked for translation like this: + * I18N_NOOP("Task description..."). Can be 0. + * + * @param emailAddress An Email address where the person can be reached. + * Can be 0. + * + * @param webAddress The person's homepage or a relevant link. + * Start the address with "http://". "http://some.domain" is + * correct, "some.domain" is not. Can be 0. + * + */ + void addAuthor( const char *name, + const char *task=0, + const char *emailAddress=0, + const char *webAddress=0 ); + + /** + * Defines a person that deserves credit. You can call this function + * as many times you need. Each entry is appended to a list. + * + * @param name The person's name in UTF-8 encoding. + * + * @param task What the person has done to deserve the honor. The + * text can contain newlines. It should be marked for + * translation like this: I18N_NOOP("Task description...") + * Can be 0. + * + * @param emailAddress An Email address when the person can be reached. + * Can be 0. + * + * @param webAddress The person's homepage or a relevant link. + * Start the address with "http://". "http://some.domain" is + * is correct, "some.domain" is not. Can be 0. + * + */ + void addCredit( const char *name, + const char *task=0, + const char *emailAddress=0, + const char *webAddress=0 ); + + /** + * Sets the name of the translator of the gui. Since this depends + * on the language, just use a dummy text marked for translation. + * + * For example: + * \code + * setTranslator(I18N_NOOP("_: NAME OF TRANSLATORS\\nYour names") + * ,I18N_NOOP("_: EMAIL OF TRANSLATORS\\nYour emails")); + * \endcode + * + * The translator can then translate this dummy text with his name + * or with a list of names separated with ",". + * If there is no translation or the application is used with the + * default language, this function call is ignored. + * + * Note: If you are using the default KDE automake environment, + * there is no need to use this function, because the two + * default strings above are added to the applications po file + * automatically. + * + * @param name the name of the translator + * @param emailAddress the email address of the translator + * @see KAboutTranslator + */ + void setTranslator(const char* name, const char* emailAddress); + + /** + * Defines a license text. + * + * The text will be translated if it got marked for + * translations with the I18N_NOOP() macro. + * + * Example: + * \code + * setLicenseText( I18N_NOOP("This is my license")); + * \endcode + * + * NOTE: No copy of the text is made. + * + * @param license The license text in utf8 encoding. + */ + void setLicenseText( const char *license ); + + /** + * Defines a license text. + * + * @param file File containing the license text. + */ + void setLicenseTextFile( const QString &file ); + + /** + * Defines the program name used internally. + * + * @param appName The application name. Example: "kate". + */ + void setAppName( const char *appName ); + + /** + * Defines the displayable program name string. + * + * @param programName The program name. This string should be + * marked for translation. + * Example: I18N_NOOP("Advanced Text Editor"). + */ + void setProgramName( const char* programName ); + + /** + * Defines the program logo. + * Use this if you need to have application logo + * in AboutData other than application icon. + * + * @param image logo image. + * @see programLogo() + * @since 3.4 + */ +// void setProgramLogo(const QImage& image); + + /** + * Defines the program version string. + * + * @param version The program version. + */ + void setVersion( const char* version ); + + /** + * Defines a short description of what the program does. + * + * @param shortDescription The program description This string should be marked + * for translation. Example: I18N_NOOP("An advanced text editor + * with syntax highlithing support."). + */ + void setShortDescription( const char *shortDescription ); + + /** + * Defines the license identifier. + * + * @param licenseKey The license identifier. + */ + void setLicense( LicenseKey licenseKey); + + /** + * Defines the copyright statement to show when displaying the license. + * + * @param copyrightStatement A copyright statement, that can look like + * this: "(c) 1999-2000, Name". The string specified here is not + * modified in any manner. The author information from addAuthor + * is not used. + */ + void setCopyrightStatement( const char *copyrightStatement ); + + /** + * Defines the additional text to show in the about dialog. + * + * @param otherText Some free form text, that can contain any kind of + * information. The text can contain newlines. This string + * should be marked for translation. + */ + void setOtherText( const char *otherText ); + + /** + * Defines the program homepage. + * + * @param homepage The program homepage string. + * Start the address with "http://". "http://kate.kde.org" is + * is correct, "kde.kde.org" is not. + */ + void setHomepage( const char *homepage ); + + /** + * Defines the address where bug reports should be sent. + * + * @param bugAddress The bug report email address string. + * This defaults to the kde.org bug system. + */ + void setBugAddress( const char *bugAddress ); + + /** + * Defines the product name wich will be used in the KBugReport dialog. + * By default it's the appName, but you can overwrite it here to provide + * support for special components e.g. 'product/component' like + * 'kontact/summary'. + * + * @param name The name of product + */ + void setProductName( const char *name ); + + /** + * Returns the application's internal name. + * @return the internal program name. + */ + const char *appName() const; + + /** + * Returns the application's product name, which will be used in KBugReport + * dialog. By default it returns appName(), otherwise the one which is set + * with setProductName() + * + * @return the product name. + */ + const char *productName() const; + + /** + * Returns the translated program name. + * @return the program name (translated). + */ + QString programName() const; + + /** + * Returns the program logo image. + * @return the program logo data or null image if there is + * no custom application logo defined. + * @since 3.4 + */ +// QImage programLogo() const; + + /** + * Returns the program's version. + * @return the version string. + */ + QString version() const; + + /** + * Returns a short, translated description. + * @return the short description (translated). Can be + * QString::null if not set. + */ + QString shortDescription() const; + + /** + * Returns the application homepage. + * @return the application homepage URL. Can be QString::null if + * not set. + */ + QString homepage() const; + + /** + * Returns the email address for bugs. + * @return the email address where to report bugs. + */ + QString bugAddress() const; + + /** + * Returns a list of authors. + * @return author information (list of persons). + */ + const QValueList authors() const; + + /** + * Returns a list of persons who contributed. + * @return credit information (list of persons). + */ + const QValueList credits() const; + + /** + * Returns a list of translators. + * @return translators information (list of persons) + */ + const QValueList translators() const; + + /** + * Returns a message about the translation team. + * @return a message about the translation team + */ + static QString aboutTranslationTeam(); + + /** + * Returns a translated, free form text. + * @return the free form text (translated). Can be QString::null if not set. + */ + QString otherText() const; + + /** + * Returns the license. If the licenseType argument of the constructor has been + * used, any text defined by setLicenseText is ignored, + * and the standard text for the chosen license will be returned. + * + * @return The license text. + */ + QString license() const; + + /** + * Returns the copyright statement. + * @return the copyright statement. Can be QString::null if not set. + */ + QString copyrightStatement() const; + + private: + const char *mAppName; + const char *mProgramName; + const char *mVersion; + const char *mShortDescription; + int mLicenseKey; + const char *mCopyrightStatement; + const char *mOtherText; + const char *mHomepageAddress; + const char *mBugEmailAddress; + QValueList mAuthorList; + QValueList mCreditList; + const char *mLicenseText; + + KAboutDataPrivate *d; +}; + +#endif + diff --git a/src/common/nokde/nokde_kcmdlineargs.cpp b/src/common/nokde/nokde_kcmdlineargs.cpp new file mode 100644 index 0000000..7f026fe --- /dev/null +++ b/src/common/nokde/nokde_kcmdlineargs.cpp @@ -0,0 +1,1329 @@ +// modified from KDE 3.4 for Windows port (Nicolas Hadacek) + +/* + Copyright (C) 1999 Waldo Bastian + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +//#include + +#include + +#include +#include +#include +#include +#include + +#ifdef HAVE_LIMITS_H +#include +#endif + +#include +#include +#include + +#include +#if QT_VERSION<0x040000 +# include +# include +#else +# include +# define QGList Q3GList +# define QStrList Q3StrList +# include +# define QGDict Q3GDict +# define QAsciiDict Q3AsciiDict +# include +# define QPtrCollection Q3PtrCollection +#endif + + +#include "nokde_kcmdlineargs.h" +#include "nokde_kaboutdata.h" +#include "nokde_klocale.h" +//#include +//#include +//#include +//#include + +#ifdef Q_WS_X11 +#define DISPLAY "DISPLAY" +#elif defined(Q_WS_QWS) +#define DISPLAY "QWS_DISPLAY" +#endif + +#ifdef Q_WS_WIN +#include +#endif + +template class QAsciiDict; +template class QPtrList; + +class KCmdLineParsedOptions : public QAsciiDict +{ +public: + KCmdLineParsedOptions() + : QAsciiDict( 7 ) { } + + // WABA: Huh? + // The compiler doesn't find KCmdLineParsedOptions::write(s) by itself ??? + // WABA: No, because there is another write function that hides the + // write function in the base class even though this function has a + // different signature. (obscure C++ feature) + QDataStream& save( QDataStream &s) const + { return QGDict::write(s); } + + QDataStream& load( QDataStream &s) + { return QGDict::read(s); } + +protected: + virtual QDataStream& write( QDataStream &s, QPtrCollection::Item data) const + { + QCString *str = (QCString *) data; + s << (*str); + return s; + } + + virtual QDataStream& read( QDataStream &s, QPtrCollection::Item &item) + { + QCString *str = new QCString; + s >> (*str); + item = (void *)str; + return s; + } + +}; + +class KCmdLineParsedArgs : public QStrList +{ +public: + KCmdLineParsedArgs() + : QStrList( true ) { } + QDataStream& save( QDataStream &s) const + { return QGList::write(s); } + + QDataStream& load( QDataStream &s) + { return QGList::read(s); } +}; + + +class KCmdLineArgsList: public QPtrList +{ +public: + KCmdLineArgsList() { } +}; + +KCmdLineArgsList *KCmdLineArgs::argsList = 0; +int KCmdLineArgs::argc = 0; +char **KCmdLineArgs::argv = 0; +char *KCmdLineArgs::mCwd = 0; +//static KStaticDeleter mCwdd; +const KAboutData *KCmdLineArgs::about = 0; +bool KCmdLineArgs::parsed = false; +bool KCmdLineArgs::ignoreUnknown = false; + +// +// Static functions +// + +void +KCmdLineArgs::init(int _argc, char **_argv, const char *_appname, const char* programName, + const char *_description, const char *_version, bool noKApp) +{ + init(_argc, _argv, + new KAboutData(_appname, programName, _version, _description), + noKApp); +} + +void +KCmdLineArgs::init(int _argc, char **_argv, const char *_appname, + const char *_description, const char *_version, bool noKApp) +{ + init(_argc, _argv, + new KAboutData(_appname, _appname, _version, _description), + noKApp); +} + +void +KCmdLineArgs::initIgnore(int _argc, char **_argv, const char *_appname ) +{ + init(_argc, _argv, + new KAboutData(_appname, _appname, "unknown", "KDE Application", false)); + ignoreUnknown = true; +} + +void +KCmdLineArgs::init(const KAboutData* ab) +{ + char **_argv = (char **) malloc(sizeof(char *)); + _argv[0] = (char *) ab->appName(); + init(1,_argv,ab, true); +} + + +void +KCmdLineArgs::init(int _argc, char **_argv, const KAboutData *_about, bool /*noKApp*/) +{ + argc = _argc; + argv = _argv; + + if (!argv) + { + fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n"); + fprintf(stderr, "Passing null-pointer to 'argv' is not allowed.\n\n"); + + assert( 0 ); + exit(255); + } + + // Strip path from argv[0] + if (argc) { + char *p = strrchr( argv[0], '/'); + if (p) + argv[0] = p+1; + } + + about = _about; + parsed = false; + mCwd = /*mCwdd.setObject(mCwd, */new char [PATH_MAX+1];//, true); + getcwd(mCwd, PATH_MAX); +#ifdef Q_WS_WIN + win32_slashify(mCwd, PATH_MAX); +#endif +// if (!noKApp) +// KApplication::addCmdLineOptions(); +} + +QString KCmdLineArgs::cwd() +{ + return QFile::decodeName(QCString(mCwd)); +} + +const char * KCmdLineArgs::appName() +{ + if (!argc) return 0; + return argv[0]; +} + +void +KCmdLineArgs::addCmdLineOptions( const KCmdLineOptions *options, const char *name, + const char *id, const char *afterId) +{ + if (!argsList) + argsList = new KCmdLineArgsList(); + + int pos = argsList->count(); + + if (pos && id && argsList->last() && !argsList->last()->name) + pos--; + + KCmdLineArgs *args; + int i = 0; + for(args = argsList->first(); args; args = argsList->next(), i++) + { + if (!id && !args->id) + return; // Options already present. + + if (id && args->id && (::qstrcmp(id, args->id) == 0)) + return; // Options already present. + + if (afterId && args->id && (::qstrcmp(afterId, args->id) == 0)) + pos = i+1; + } + + assert( parsed == false ); // You must add _ALL_ cmd line options + // before accessing the arguments! + args = new KCmdLineArgs(options, name, id); + argsList->insert(pos, args); +} + +void +KCmdLineArgs::saveAppArgs( QDataStream &ds) +{ + if (!parsed) + parseAllArgs(); + + // Remove Qt and KDE options. + removeArgs("qt"); + removeArgs("kde"); + + QCString qCwd = mCwd; + ds << qCwd; + + uint count = argsList ? argsList->count() : 0; + ds << count; + + if (!count) return; + + KCmdLineArgs *args; + for(args = argsList->first(); args; args = argsList->next()) + { + ds << QCString(args->id); + args->save(ds); + } +} + +void +KCmdLineArgs::loadAppArgs( QDataStream &ds) +{ + // Remove Qt and KDE options. + removeArgs("qt"); + removeArgs("kde"); + + KCmdLineArgs *args; + if ( argsList ) { + for(args = argsList->first(); args; args = argsList->next()) + { + args->clear(); + } + } + + if (ds.atEnd()) + return; + + QCString qCwd; + ds >> qCwd; + delete [] mCwd; + + mCwd = /*mCwdd.setObject(mCwd, */new char[qCwd.length()+1];//, true); + strncpy(mCwd, qCwd.data(), qCwd.length()+1); + + uint count; + ds >> count; + + while(count--) + { + QCString id; + ds >> id; + assert( argsList ); + for(args = argsList->first(); args; args = argsList->next()) + { + if (args->id == id) + { + args->load(ds); + break; + } + } + } + parsed = true; +} + +KCmdLineArgs *KCmdLineArgs::parsedArgs(const char *id) +{ + KCmdLineArgs *args = argsList ? argsList->first() : 0; + while(args) + { + if ((id && ::qstrcmp(args->id, id) == 0) || (!id && !args->id)) + { + if (!parsed) + parseAllArgs(); + return args; + } + args = argsList->next(); + } + + return args; +} + +void KCmdLineArgs::removeArgs(const char *id) +{ + KCmdLineArgs *args = argsList ? argsList->first() : 0; + while(args) + { + if (args->id && id && ::qstrcmp(args->id, id) == 0) + { + if (!parsed) + parseAllArgs(); + break; + } + args = argsList->next(); + } + + if (args) + delete args; +} + +/* + * @return: + * 0 - option not found. + * 1 - option found // -fork + * 2 - inverse option found ('no') // -nofork + * 3 - option + arg found // -fork now + * + * +4 - no more options follow // !fork + */ +static int +findOption(const KCmdLineOptions *options, QCString &opt, + const char *&opt_name, const char *&def, bool &enabled) +{ + int result; + bool inverse; + int len = opt.length(); + while(options && options->name) + { + result = 0; + inverse = false; + opt_name = options->name; + if ((opt_name[0] == ':') || (opt_name[0] == 0)) + { + options++; + continue; + } + + if (opt_name[0] == '!') + { + opt_name++; + result = 4; + } + if ((opt_name[0] == 'n') && (opt_name[1] == 'o')) + { + opt_name += 2; + inverse = true; + } + if (strncmp(opt.data(), opt_name, len) == 0) + { + opt_name += len; + if (!opt_name[0]) + { + if (inverse) + return result+2; + + if (!options->description) + { + options++; + if (!options->name) + return result+0; + QCString nextOption = options->name; +# if QT_VERSION<0x040000 + int p = nextOption.find(' '); +#else + int p = QString(nextOption).indexOf(' '); +#endif + if (p > 0) + nextOption = nextOption.left(p); + if (strncmp(nextOption.data(), "no", 2) == 0) + { + nextOption = nextOption.mid(2); + enabled = !enabled; + } + result = findOption(options, nextOption, opt_name, def, enabled); + assert(result); + opt = nextOption; + return result; + } + + return 1; + } + if (opt_name[0] == ' ') + { + opt_name++; + def = options->def; + return result+3; + } + } + + options++; + } + return 0; +} + + +void +KCmdLineArgs::findOption(const char *_opt, QCString opt, int &i, bool _enabled, bool &moreOptions) +{ + KCmdLineArgs *args = argsList->first(); + const char *opt_name; + const char *def; + QCString argument; +# if QT_VERSION<0x040000 + int j = opt.find('='); +#else + int j = QString(opt).indexOf('='); +#endif + if (j != -1) + { + argument = opt.mid(j+1); + opt = opt.left(j); + } + + bool enabled = true; + int result = 0; + while (args) + { + enabled = _enabled; + result = ::findOption(args->options, opt, opt_name, def, enabled); + if (result) break; + args = argsList->next(); + } + if (!args && (_opt[0] == '-') && _opt[1] && (_opt[1] != '-')) + { + // Option not found check if it is a valid option + // in the style of -Pprinter1 or ps -aux + int p = 1; + while (true) + { + QCString singleCharOption = " "; + singleCharOption[0] = _opt[p]; + args = argsList->first(); + while (args) + { + enabled = _enabled; + result = ::findOption(args->options, singleCharOption, opt_name, def, enabled); + if (result) break; + args = argsList->next(); + } + if (!args) + break; // Unknown argument + + p++; + if (result == 1) // Single option + { + args->setOption(singleCharOption, enabled); + if (_opt[p]) + continue; // Next option + else + return; // Finished + } + else if (result == 3) // This option takes an argument + { + if (argument.isEmpty()) + { + argument = _opt+p; + } + args->setOption(singleCharOption, argument.data()); + return; + } + break; // Unknown argument + } + args = 0; + result = 0; + } + + if (!args || !result) + { + if (ignoreUnknown) + return; + enable_i18n(); + usage( i18n("Unknown option '%1'.").arg(QString::fromLocal8Bit(_opt))); + } + + if ((result & 4) != 0) + { + result &= ~4; + moreOptions = false; + } + + if (result == 3) // This option takes an argument + { + if (!enabled) + { + if (ignoreUnknown) + return; + enable_i18n(); + usage( i18n("Unknown option '%1'.").arg(QString::fromLocal8Bit(_opt))); + } + if (argument.isEmpty()) + { + i++; + if (i >= argc) + { + enable_i18n(); + usage( i18n("'%1' missing.").arg( opt_name)); + } + argument = argv[i]; + } + args->setOption(opt, argument.data()); + } + else + { + args->setOption(opt, enabled); + } +} + +void +KCmdLineArgs::printQ(const QString &msg) +{ +# if QT_VERSION<0x040000 + QCString localMsg = msg.local8Bit(); +#else + QCString localMsg = msg.toLocal8Bit(); +#endif + fprintf(stdout, "%s", localMsg.data()); +} + +void +KCmdLineArgs::parseAllArgs() +{ + bool allowArgs = false; + bool inOptions = true; + bool everythingAfterArgIsArgs = false; + KCmdLineArgs *appOptions = argsList->last(); + if (!appOptions->id) + { + const KCmdLineOptions *option = appOptions->options; + while(option && option->name) + { + if (option->name[0] == '+') + allowArgs = true; + if ( option->name[0] == '!' && option->name[1] == '+' ) + { + allowArgs = true; + everythingAfterArgIsArgs = true; + } + option++; + } + } + for(int i = 1; i < argc; i++) + { + if (!argv[i]) + continue; + + if ((argv[i][0] == '-') && argv[i][1] && inOptions) + { + bool enabled = true; + const char *option = &argv[i][1]; + const char *orig = argv[i]; + if (option[0] == '-') + { + option++; + argv[i]++; + if (!option[0]) + { + inOptions = false; + continue; + } + } + if (::qstrcmp(option, "help") == 0) + { + usage(0); + } + else if (strncmp(option, "help-",5) == 0) + { + usage(option+5); + } + else if ( (::qstrcmp(option, "version") == 0) || + (::qstrcmp(option, "v") == 0)) + { + printQ( QString("Qt: %1\n").arg(qVersion())); +// printQ( QString("KDE: %1\n").arg(KDE_VERSION_STRING)); + printQ( QString("%1: %2\n"). + arg(about->programName()).arg(about->version())); + exit(0); + } else if ( (::qstrcmp(option, "license") == 0) ) + { + enable_i18n(); + printQ( about->license() ); + printQ( "\n" ); + exit(0); + } else if ( ::qstrcmp( option, "author") == 0 ) { + enable_i18n(); + if ( about ) { + const QValueList authors = about->authors(); + if ( !authors.isEmpty() ) { + QString authorlist; + for (QValueList::ConstIterator it = authors.begin(); it != authors.end(); ++it ) { + QString email; + if ( !(*it).emailAddress().isEmpty() ) + email = " <" + (*it).emailAddress() + ">"; + authorlist += QString(" ") + (*it).name() + email + "\n"; + } + printQ( i18n("the 2nd argument is a list of name+address, one on each line","%1 was written by\n%2").arg ( QString(about->programName()) ).arg( authorlist ) ); + } + } else { + printQ( i18n("%1 was written by somebody who wants to remain anonymous.").arg(about->programName()) ); + } + if (!about->bugAddress().isEmpty()) + { + if (about->bugAddress() == "submit@bugs.kde.org") + printQ( i18n( "Please use http://bugs.kde.org to report bugs, do not mail the authors directly.\n" ) ); + else + printQ( i18n( "Please use %1 to report bugs, do not mail the authors directly.\n" ).arg(about->bugAddress()) ); + } + exit(0); + } else { + if ((option[0] == 'n') && (option[1] == 'o')) + { + option += 2; + enabled = false; + } + findOption(orig, option, i, enabled, inOptions); + } + } + else + { + // Check whether appOptions allows these arguments + if (!allowArgs) + { + if (ignoreUnknown) + continue; + enable_i18n(); + usage( i18n("Unexpected argument '%1'.").arg(QString::fromLocal8Bit(argv[i]))); + } + else + { + appOptions->addArgument(argv[i]); + if (everythingAfterArgIsArgs) + inOptions = false; + } + } + } + parsed = true; +} + +/** + * For KApplication only: + * + * Return argc + */ +int * +KCmdLineArgs::qt_argc() +{ +// if (!argsList) +// KApplication::addCmdLineOptions(); // Lazy bastards! + + static int qt_argc = -1; + if( qt_argc != -1 ) + return &qt_argc; + + KCmdLineArgs *args = parsedArgs("qt"); + assert(args); // No qt options have been added! + if (!argv) + { + fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n"); + fprintf(stderr, "Application has not called KCmdLineArgs::init(...).\n\n"); + + assert( 0 ); + exit(255); + } + + assert(argc >= (args->count()+1)); + qt_argc = args->count() +1; + return &qt_argc; +} + +/** + * For KApplication only: + * + * Return argv + */ +char *** +KCmdLineArgs::qt_argv() +{ +// if (!argsList) +// KApplication::addCmdLineOptions(); // Lazy bastards! + + static char** qt_argv; + if( qt_argv != NULL ) + return &qt_argv; + + KCmdLineArgs *args = parsedArgs("qt"); + assert(args); // No qt options have been added! + if (!argv) + { + fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n"); + fprintf(stderr, "Application has not called KCmdLineArgs::init(...).\n\n"); + + assert( 0 ); + exit(255); + } + + qt_argv = new char*[ args->count() + 2 ]; + qt_argv[ 0 ] = qstrdup( appName()); + int i = 0; + for(; i < args->count(); i++) + { + qt_argv[i+1] = qstrdup((char *) args->arg(i)); + } + qt_argv[i+1] = 0; + + return &qt_argv; +} + +void +KCmdLineArgs::enable_i18n() +{ + // called twice or too late +/* if (KGlobal::_locale) + return; + + if (!KGlobal::_instance) { + KInstance *instance = new KInstance(about); + (void) instance->config(); + // Don't delete instance! + }*/ +} + +void +KCmdLineArgs::usage(const QString &error) +{ +// assert(KGlobal::_locale); +# if QT_VERSION<0x040000 + QCString localError = error.local8Bit(); +#else + QCString localError = error.toLocal8Bit(); +#endif + if (localError[error.length()-1] == '\n') + localError = localError.left(error.length()-1); + fprintf(stderr, "%s: %s\n", argv[0], localError.data()); + + QString tmp = i18n("Use --help to get a list of available command line options."); +# if QT_VERSION<0x040000 + localError = tmp.local8Bit(); +#else + localError = tmp.toLocal8Bit(); +#endif + fprintf(stderr, "%s: %s\n", argv[0], localError.data()); + exit(254); +} + +void +KCmdLineArgs::usage(const char *id) +{ + enable_i18n(); + assert(argsList != 0); // It's an error to call usage(...) without + // having done addCmdLineOptions first! + + QString optionFormatString = " %1 %2\n"; + QString optionFormatStringDef = " %1 %2 [%3]\n"; + QString optionHeaderString = i18n("\n%1:\n"); + QString tmp; + QString usage; + + KCmdLineArgs *args = argsList->last(); + + if (!(args->id) && (args->options) && + (args->options->name) && (args->options->name[0] != '+')) + { + usage = i18n("[options] ")+usage; + } + + while(args) + { + if (args->name) + { + usage = i18n("[%1-options]").arg(args->name)+" "+usage; + } + args = argsList->prev(); + } + + KCmdLineArgs *appOptions = argsList->last(); + if (!appOptions->id) + { + const KCmdLineOptions *option = appOptions->options; + while(option && option->name) + { + if (option->name[0] == '+') + usage = usage + (option->name+1) + " "; + else if ( option->name[0] == '!' && option->name[1] == '+' ) + usage = usage + (option->name+2) + " "; + + option++; + } + } + + printQ(i18n("Usage: %1 %2\n").arg(argv[0]).arg(usage)); + printQ("\n"+about->shortDescription()+"\n"); + + printQ(optionHeaderString.arg(i18n("Generic options"))); + printQ(optionFormatString.arg("--help", -25).arg(i18n("Show help about options"))); + + args = argsList->first(); + while(args) + { + if (args->name && args->id) + { + QString option = QString("--help-%1").arg(args->id); + QString desc = i18n("Show %1 specific options").arg(args->name); + + printQ(optionFormatString.arg(option, -25).arg(desc)); + } + args = argsList->next(); + } + + printQ(optionFormatString.arg("--help-all",-25).arg(i18n("Show all options"))); + printQ(optionFormatString.arg("--author",-25).arg(i18n("Show author information"))); + printQ(optionFormatString.arg("-v, --version",-25).arg(i18n("Show version information"))); + printQ(optionFormatString.arg("--license",-25).arg(i18n("Show license information"))); + printQ(optionFormatString.arg("--", -25).arg(i18n("End of options"))); + + args = argsList->first(); // Sets current to 1st. + + bool showAll = id && (::qstrcmp(id, "all") == 0); + + if (!showAll) + { + while(args) + { + if (!id && !args->id) break; + if (id && (::qstrcmp(args->id, id) == 0)) break; + args = argsList->next(); + } + } + + while(args) + { + bool hasArgs = false; + bool hasOptions = false; + QString optionsHeader; + if (args->name) + optionsHeader = optionHeaderString.arg(i18n("%1 options").arg(QString::fromLatin1(args->name))); + else + optionsHeader = i18n("\nOptions:\n"); + + while (args) + { + const KCmdLineOptions *option = args->options; + QCString opt = ""; +// + while(option && option->name) + { + QString description; + QString descriptionRest; + QStringList dl; + + // Option header + if (option->name[0] == ':') + { + if (option->description) + { + optionsHeader = "\n"+i18n(option->description); + if (!optionsHeader.endsWith("\n")) + optionsHeader.append("\n"); + hasOptions = false; + } + option++; + continue; + } + + // Free-form comment + if (option->name[0] == 0) + { + if (option->description) + { + QString tmp = "\n"+i18n(option->description); + if (!tmp.endsWith("\n")) + tmp.append("\n"); + printQ(tmp); + } + option++; + continue; + } + + // Options + if (option->description) + { + description = i18n(option->description); +# if QT_VERSION<0x040000 + dl = QStringList::split("\n", description, true); +#else + dl = description.split("\n"); +#endif + description = dl.first(); + dl.erase( dl.begin() ); + } + QCString name = option->name; + if (name[0] == '!') + name = name.mid(1); + + if (name[0] == '+') + { + if (!hasArgs) + { + printQ(i18n("\nArguments:\n")); + hasArgs = true; + } + + name = name.mid(1); + if ((name[0] == '[') && (name[name.length()-1] == ']')) + name = name.mid(1, name.length()-2); + printQ(optionFormatString.arg(QString(name), -25) + .arg(description)); + } + else + { + if (!hasOptions) + { + printQ(optionsHeader); + hasOptions = true; + } + + if ((name.length() == 1) || (name[1] == ' ')) + name = "-"+name; + else + name = "--"+name; + if (!option->description) + { + opt = name + ", "; + } + else + { + opt = opt + name; + if (!option->def) + { + printQ(optionFormatString.arg(QString(opt), -25) + .arg(description)); + } + else + { + printQ(optionFormatStringDef.arg(QString(opt), -25) + .arg(description).arg(option->def)); + } + opt = ""; + } + } + for(QStringList::Iterator it = dl.begin(); + it != dl.end(); + ++it) + { + printQ(optionFormatString.arg("", -25).arg(*it)); + } + + option++; + } + args = argsList->next(); + if (!args || args->name || !args->id) break; + } + if (!showAll) break; + } + + exit(254); +} + +// +// Member functions +// + +/** + * Constructor. + * + * The given arguments are assumed to be constants. + */ +KCmdLineArgs::KCmdLineArgs( const KCmdLineOptions *_options, + const char *_name, const char *_id) + : options(_options), name(_name), id(_id) +{ + parsedOptionList = 0; + parsedArgList = 0; + isQt = (::qstrcmp(id, "qt") == 0); +} + +/** + * Destructor. + */ +KCmdLineArgs::~KCmdLineArgs() +{ + delete parsedOptionList; + delete parsedArgList; + if (argsList) + argsList->removeRef(this); +} + +void +KCmdLineArgs::clear() +{ + delete parsedArgList; + parsedArgList = 0; + delete parsedOptionList; + parsedOptionList = 0; +} + +void +KCmdLineArgs::reset() +{ + if ( argsList ) { + argsList->setAutoDelete( true ); + argsList->clear(); + delete argsList; + argsList = 0; + } + parsed = false; +} + +void +KCmdLineArgs::save( QDataStream &ds) const +{ + uint count = 0; + if (parsedOptionList) + parsedOptionList->save( ds ); + else + ds << count; + + if (parsedArgList) + parsedArgList->save( ds ); + else + ds << count; +} + +void +KCmdLineArgs::load( QDataStream &ds) +{ + if (!parsedOptionList) parsedOptionList = new KCmdLineParsedOptions; + if (!parsedArgList) parsedArgList = new KCmdLineParsedArgs; + + parsedOptionList->load( ds ); + parsedArgList->load( ds ); + + if (parsedOptionList->count() == 0) + { + delete parsedOptionList; + parsedOptionList = 0; + } + if (parsedArgList->count() == 0) + { + delete parsedArgList; + parsedArgList = 0; + } +} + +void +KCmdLineArgs::setOption(const QCString &opt, bool enabled) +{ + if (isQt) + { + // Qt does it own parsing. + QCString arg = "-"; + if( !enabled ) + arg += "no"; + arg += opt; + addArgument(arg); + } + if (!parsedOptionList) { + parsedOptionList = new KCmdLineParsedOptions; + parsedOptionList->setAutoDelete(true); + } + + if (enabled) + parsedOptionList->replace( opt, new QCString("t") ); + else + parsedOptionList->replace( opt, new QCString("f") ); +} + +void +KCmdLineArgs::setOption(const QCString &opt, const char *value) +{ + if (isQt) + { + // Qt does it's own parsing. + QCString arg = "-"; + arg += opt; + addArgument(arg); + addArgument(value); + +#ifdef Q_WS_X11 + // Hack coming up! + if (arg == "-display") + { + setenv(DISPLAY, value, true); + } +#endif + } + if (!parsedOptionList) { + parsedOptionList = new KCmdLineParsedOptions; + parsedOptionList->setAutoDelete(true); + } + + parsedOptionList->insert( opt, new QCString(value) ); +} + +QCString +KCmdLineArgs::getOption(const char *_opt) const +{ + QCString *value = 0; + if (parsedOptionList) + { + value = parsedOptionList->find(_opt); + } + + if (value) + return (*value); + + // Look up the default. + const char *opt_name; + const char *def; + bool dummy = true; + QCString opt = _opt; + int result = ::findOption( options, opt, opt_name, def, dummy) & ~4; + + if (result != 3) + { + fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n"); + fprintf(stderr, "Application requests for getOption(\"%s\") but the \"%s\" option\n", + _opt, _opt); + fprintf(stderr, "has never been specified via addCmdLineOptions( ... )\n\n"); + + assert( 0 ); + exit(255); + } + return QCString(def); +} + +QCStringList +KCmdLineArgs::getOptionList(const char *_opt) const +{ + QCStringList result; + if (!parsedOptionList) + return result; + + while(true) + { + QCString *value = parsedOptionList->take(_opt); + if (!value) + break; + result.prepend(*value); + delete value; + } + + // Reinsert items in dictionary + // WABA: This is rather silly, but I don't want to add restrictions + // to the API like "you can only call this function once". + // I can't access all items without taking them out of the list. + // So taking them out and then putting them back is the only way. + for(QCStringList::ConstIterator it=result.begin(); + it != result.end(); + ++it) + { + parsedOptionList->insert(_opt, new QCString(*it)); + } + return result; +} + +bool +KCmdLineArgs::isSet(const char *_opt) const +{ + // Look up the default. + const char *opt_name; + const char *def; + bool dummy = true; + QCString opt = _opt; + int result = ::findOption( options, opt, opt_name, def, dummy) & ~4; + + if (result == 0) + { + fprintf(stderr, "\n\nFAILURE (KCmdLineArgs):\n"); + fprintf(stderr, "Application requests for isSet(\"%s\") but the \"%s\" option\n", + _opt, _opt); + fprintf(stderr, "has never been specified via addCmdLineOptions( ... )\n\n"); + + assert( 0 ); + exit(255); + } + + QCString *value = 0; + if (parsedOptionList) + { + value = parsedOptionList->find(opt); + } + + if (value) + { + if (result == 3) + return true; + else + return ((*value)[0] == 't'); + } + + if (result == 3) + return false; // String option has 'false' as default. + + // We return 'true' as default if the option was listed as '-nofork' + // We return 'false' as default if the option was listed as '-fork' + return (result == 2); +} + +int +KCmdLineArgs::count() const +{ + if (!parsedArgList) + return 0; + return parsedArgList->count(); +} + +const char * +KCmdLineArgs::arg(int n) const +{ + if (!parsedArgList || (n >= (int) parsedArgList->count())) + { + fprintf(stderr, "\n\nFAILURE (KCmdLineArgs): Argument out of bounds\n"); + fprintf(stderr, "Application requests for arg(%d) without checking count() first.\n", + n); + + assert( 0 ); + exit(255); + } + + return parsedArgList->at(n); +} + +KURL +KCmdLineArgs::url(int n) const +{ + return makeURL( arg(n) ); +} + +KURL KCmdLineArgs::makeURL(const char *_urlArg) +{ + QString urlArg = QFile::decodeName(_urlArg); + if (!QDir::isRelativePath(urlArg)) + { + //KURL result; + //result.setPath(urlArg); + //return result; // Absolute path. + return urlArg; + } +# if QT_VERSION<0x040000 + if ( !QUrl::isRelativeUrl(urlArg) ) +#else + if ( !QUrl(urlArg).isRelative() ) +#endif + //return KURL(urlArg); // Argument is a URL + return urlArg; + +// KURL result; +// result.setPath( cwd()+"/"+urlArg ); +// result.cleanPath(); +// return result; // Relative path + return cwd() + "/" + urlArg; +} + +void +KCmdLineArgs::addArgument(const char *argument) +{ + if (!parsedArgList) + parsedArgList = new KCmdLineParsedArgs; + + parsedArgList->append(argument); +} + +static const KCmdLineOptions kde_tempfile_option[] = +{ + { "tempfile", I18N_NOOP("The files/URLs opened by the application will be deleted after use"), 0}, + KCmdLineLastOption +}; + +void +KCmdLineArgs::addTempFileOption() +{ + KCmdLineArgs::addCmdLineOptions( kde_tempfile_option, "KDE-tempfile", "kde-tempfile" ); +} + +bool KCmdLineArgs::isTempFileSet() +{ + KCmdLineArgs* args = KCmdLineArgs::parsedArgs( "kde-tempfile" ); + if ( args ) + return args->isSet( "tempfile" ); + return false; +} diff --git a/src/common/nokde/nokde_kcmdlineargs.h b/src/common/nokde/nokde_kcmdlineargs.h new file mode 100644 index 0000000..8b79b62 --- /dev/null +++ b/src/common/nokde/nokde_kcmdlineargs.h @@ -0,0 +1,701 @@ +// modified from KDE 3.4 for Windows port (Nicolas Hadacek) + +/* This file is part of the KDE project + Copyright (C) 1999 Waldo Bastian + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef _KCMDLINEARGS_H_ +#define _KCMDLINEARGS_H_ + +#include "nokde_klocale.h" +#include "nokde_kurl.h" + +# if QT_VERSION<0x040000 +# include +# include +#else +# include +# define QCString Q3CString +# include +# define QPtrList Q3PtrList +# include +# define QValueList Q3ValueList +#endif +# include + +typedef QValueList QCStringList; + +/** + * @short Structure that holds command line options. + * + * This class is intended to be used with the KCmdLineArgs class, which + * provides convenient and powerful command line argument parsing and + * handling functionality. + * + * @see KCmdLineArgs for additional usage information + */ +struct KDECORE_EXPORT KCmdLineOptions +{ + /** + * The name of the argument as it should be called on the command line and + * appear in myapp --help. + * + * Note that if this option starts with "no" that you will need to test for + * the name without the "no" and the result will be the inverse of what is + * specified. i.e. if "nofoo" is the name of the option and + * myapp --nofoo is called: + * + * \code + * KCmdLineArgs::parsedArgs()->isSet("foo"); // false + * \endcode + */ + const char *name; + /** + * The text description of the option as should appear in + * myapp --help. This value should be wrapped with I18N_NOOP(). + */ + const char *description; + /** + * The default value for the option, if it is not specified on the + * command line. + */ + const char *def; // Default +}; + +#define KCmdLineLastOption { 0, 0, 0 } + +class KCmdLineArgsList; +class KApplication; +class KUniqueApplication; +class KCmdLineParsedOptions; +class KCmdLineParsedArgs; +class KAboutData; +class KCmdLineArgsPrivate; + +/** + * @short A class for command-line argument handling. + * + * KCmdLineArgs provides simple access to the command-line arguments + * for an application. It takes into account Qt-specific options, + * KDE-specific options and application specific options. + * + * This class is used in %main() via the static method + * init(). + * + * A typical %KDE application using %KCmdLineArgs should look like this: + * + * \code + * int main(int argc, char *argv[]) + * { + * // Initialize command line args + * KCmdLineArgs::init(argc, argv, appName, programName, description, version); + * + * // Tell which options are supported + * KCmdLineArgs::addCmdLineOptions( options ); + * + * // Add options from other components + * KUniqueApplication::addCmdLineOptions(); + * + * .... + * + * // Create application object without passing 'argc' and 'argv' again. + * KUniqueApplication app; + * + * .... + * + * // Handle our own options/arguments + * // A KApplication will usually do this in main but this is not + * // necessary. + * // A KUniqueApplication might want to handle it in newInstance(). + * + * KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + * + * // A binary option (on / off) + * if (args->isSet("some-option")) + * .... + * + * // An option which takes an additional argument + * QCString anotherOptionArg = args->getOption("another-option"); + * + * // Arguments (e.g. files to open) + * for(int i = 0; i < args->count(); i++) // Counting start at 0! + * { + * // don't forget to convert to Unicode! + * openFile( QFile::decodeName( args->arg(i))); + * // Or more convenient: + * // openURL( args->url(i)); + * + * } + * + * args->clear(); // Free up some memory. + * .... + * } + * \endcode + * + * The options that an application supports are configured using the + * KCmdLineOptions class. An example is shown below: + * + * \code + * static const KCmdLineOptions options[] = + * { + * { "a", I18N_NOOP("A short binary option"), 0 }, + * { "b \", I18N_NOOP("A short option which takes an argument"), 0 }, + * { "c \", I18N_NOOP("As above but with a default value"), "9600" }, + * { "option1", I18N_NOOP("A long binary option, off by default"), 0 }, + * { "nooption2", I18N_NOOP("A long binary option, on by default"), 0 }, + * { ":", I18N_NOOP("Extra options:"), 0 }, + * { "option3 \", I18N_NOOP("A long option which takes an argument"), 0 }, + * { "option4 \", I18N_NOOP("A long option which takes an argument, defaulting to 9600"), "9600" }, + * { "d", 0, 0 }, + * { "option5", I18N_NOOP("A long option which has a short option as alias"), 0 }, + * { "e", 0, 0 }, + * { "nooption6", I18N_NOOP("Another long option with an alias"), 0 }, + * { "f", 0, 0 }, + * { "option7 \", I18N_NOOP("'--option7 speed' is the same as '-f speed'"), 0 }, + * { "!option8 \", I18N_NOOP("All options following this one will be treated as arguments"), 0 }, + * { "+file", I18N_NOOP("A required argument 'file'"), 0 }, + * { "+[arg1]", I18N_NOOP("An optional argument 'arg1'"), 0 }, + * { "!+command", I18N_NOOP("A required argument 'command', that can contain multiple words, even starting with '-'"), 0 }, + * { "", I18N_NOOP("Additional help text not associated with any particular option") 0 }, + * KCmdLineLastOption // End of options. + * }; + * \endcode + * + * The I18N_NOOP macro is used to indicate that these strings should be + * marked for translation. The actual translation is done by KCmdLineArgs. + * You can't use i18n() here because we are setting up a static data + * structure and can't do translations at compile time. + * + * Note that a program should define the options before any arguments. + * + * When a long option has a short option as an alias, a program should + * only test for the long option. + * + * With the above options a command line could look like: + * \code + * myapp -a -c 4800 --display localhost:0.0 --nooption5 -d /tmp/file + * \endcode + * + * Long binary options can be in the form 'option' and 'nooption'. + * A command line may contain the same binary option multiple times, + * the last option determines the outcome: + * \code + * myapp --nooption4 --option4 --nooption4 + * \endcode + * is the same as: + * \code + * myapp --nooption4 + * \endcode + * + * If an option value is provided multiple times, normally only the last + * value is used: + * \code + * myapp -c 1200 -c 2400 -c 4800 + * \endcode + * is usually the same as: + * \code + * myapp -c 4800 + * \endcode + * + * However, an application can choose to use all values specified as well. + * As an example of this, consider that you may wish to specify a + * number of directories to use: + * \code + * myapp -I /usr/include -I /opt/kde/include -I /usr/X11/include + * \endcode + * When an application does this it should mention this in the description + * of the option. To access these options, use getOptionList() + * + * Tips for end-users: + * + * @li Single char options like "-a -b -c" may be combined into "-abc" + * @li The option "--foo bar" may also be written "--foo=bar" + * @li The option "-P lp1" may also be written "-P=lp1" or "-Plp1" + * @li The option "--foo bar" may also be written "-foo bar" + * + * @author Waldo Bastian + * @version 0.0.4 + */ +class KDECORE_EXPORT KCmdLineArgs +{ + friend class KApplication; + friend class KUniqueApplication; + friend class QPtrList; +public: + // Static functions: + + /** + * Initialize class. + * + * This function should be called as the very first thing in + * your application. + * @param _argc As passed to @p main(...). + * @param _argv As passed to @p main(...). + * @param _appname The untranslated name of your application. This should + * match with @p argv[0]. + * @param programName A program name string to be used for display + * purposes. This string should be marked for + * translation. Example: I18N_NOOP("KEdit") + * @param _description A short description of what your application is about. + * @param _version A version. + * @param noKApp Set this true to not add commandline options for + * QApplication / KApplication + * + * @since 3.2 + */ + static void init(int _argc, char **_argv, const char *_appname, + const char* programName, const char *_description, + const char *_version, bool noKApp = false); + /** + * @deprecated + * You should convert any calls to this method to use the one + * above, by adding in the program name to be used for display + * purposes. Do not forget to mark it for translation using I18N_NOOP. + */ + static void init(int _argc, char **_argv, + const char *_appname, const char *_description, + const char *_version, bool noKApp = false) KDE_DEPRECATED; + + /** + * Initialize class. + * + * This function should be called as the very first thing in + * your application. It uses KAboutData to replace some of the + * arguments that would otherwise be required. + * + * @param _argc As passed to @p main(...). + * @param _argv As passed to @p main(...). + * @param about A KAboutData object describing your program. + * @param noKApp Set this true to not add commandline options for + * QApplication / KApplication + */ + static void init(int _argc, char **_argv, + const KAboutData *about, bool noKApp = false); + + /** + * Initialize Class + * + * This function should be called as the very first thing in your + * application. This method will rarely be used, since it doesn't + * provide any argument parsing. It does provide access to the + * KAboutData information. + * This method is exactly the same as calling + * init(0,0, const KAboutData *about, true). + * + * @param about the about data. + * \see KAboutData + */ + static void init(const KAboutData *about); + + /** + * Add options to your application. + * + * You must make sure that all possible options have been added before + * any class uses the command line arguments. + * + * The list of options should look like this: + * + * \code + * static KCmdLineOptions options[] = + * { + * { "option1 \", I18N_NOOP("Description 1"), "my_extra_arg" }, + * { "o", 0, 0 }, + * { "option2", I18N_NOOP("Description 2"), 0 }, + * { "nooption3", I18N_NOOP("Description 3"), 0 }, + * KCmdLineLastOption + * } + * \endcode + * + * @li "option1" is an option that requires an additional argument, + * but if one is not provided, it uses "my_extra_arg". + * @li "option2" is an option that can be turned on. The default is off. + * @li "option3" is an option that can be turned off. The default is on. + * @li "o" does not have a description. It is an alias for the option + * that follows. In this case "option2". + * @li "+file" specifies an argument. The '+' is removed. If your program + * doesn't specify that it can use arguments your program will abort + * when an argument is passed to it. Note that the reverse is not + * true. If required, you must check yourself the number of arguments + * specified by the user: + * \code + * KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + * if (args->count() == 0) KCmdLineArgs::usage(i18n("No file specified!")); + * \endcode + * + * In BNF: + * \code + * cmd = myapp [options] file + * options = (option)* + * option = --option1 \ | + * (-o | --option2 | --nooption2) | + * ( --option3 | --nooption3 ) + * \endcode + * + * Instead of "--option3" one may also use "-option3" + * + * Usage examples: + * + * @li "myapp --option1 test" + * @li "myapp" (same as "myapp --option1 my_extra_arg") + * @li "myapp --option2" + * @li "myapp --nooption2" (same as "myapp", since it is off by default) + * @li "myapp -o" (same as "myapp --option2") + * @li "myapp --nooption3" + * @li "myapp --option3 (same as "myapp", since it is on by default) + * @li "myapp --option2 --nooption2" (same as "myapp", because it + * option2 is off by default, and the last usage applies) + * @li "myapp /tmp/file" + * + * @param options A list of options that your code supplies. + * @param name the name of the option, can be 0. + * @param id A name with which these options can be identified, can be 0. + * @param afterId The options are inserted after this set of options, can be 0. + */ + static void addCmdLineOptions( const KCmdLineOptions *options, + const char *name=0, const char *id = 0, + const char *afterId=0); + + /** + * Access parsed arguments. + * + * This function returns all command line arguments that your code + * handles. If unknown command-line arguments are encountered the program + * is aborted and usage information is shown. + * + * @param id The name of the options you are interested in, can be 0. + */ + static KCmdLineArgs *parsedArgs(const char *id=0); + + /** + * Get the CWD (Current Working Directory) associated with the + * current command line arguments. + * + * Typically this is needed in KUniqueApplication::newInstance() + * since the CWD of the process may be different from the CWD + * where the user started a second instance. + * @return the current working directory + **/ + static QString cwd(); + + /** + * Get the appname according to argv[0]. + * @return the name of the application + **/ + static const char *appName(); + + /** + * Print the usage help to stdout and exit. + * + * @param id if 0, print all options. If id is set, only print the + * option specified by id. The id is the value set by + * #ref addCmdLineOptions(). + **/ + static void usage(const char *id = 0); + + /** + * Print an error to stderr and the usage help to stdout and exit. + * @param error the error to print + **/ + static void usage(const QString &error); + + /** + * Enable i18n to be able to print a translated error message. + * + * N.B.: This function leaks memory, therefore you are expected to exit + * afterwards (e.g., by calling usage()). + **/ + static void enable_i18n(); + + // Member functions: + + + /** + * Read out a string option. + * + * The option must have a corresponding KCmdLineOptions entry + * of the form: + * \code + * { "option \", I18N_NOOP("Description"), "default" } + * \endcode + * You cannot test for the presence of an alias - you must always + * test for the full option. + * + * @param option The name of the option without '-'. + * + * @return The value of the option. If the option was not + * present on the command line the default is returned. + * If the option was present more than the value of the + * last occurrence is used. + */ + QCString getOption(const char *option) const; + + /** + * Read out all occurrences of a string option. + * + * The option must have a corresponding KCmdLineOptions entry + * of the form: + * \code + * { "option \", I18N_NOOP("Description"), "default" } + * \endcode + * You cannot test for the presence of an alias - you must always + * test for the full option. + * + * @param option The name of the option, without '-' or '-no'. + * + * @return A list of all option values. If no option was present + * on the command line, an empty list is returned. + */ + QCStringList getOptionList(const char *option) const; + + /** + * Read out a boolean option or check for the presence of string option. + * + * @param option The name of the option without '-' or '-no'. + * + * @return The value of the option. It will be true if the option + * was specifically turned on in the command line, or if the option + * is turned on by default (in the KCmdLineOptions list) and was + * not specifically turned off in the command line. Equivalently, + * it will be false if the option was specifically turned off in + * the command line, or if the option is turned off by default (in + * the KCmdLineOptions list) and was not specifically turned on in + * the command line. + */ + bool isSet(const char *option) const; + + /** + * Read the number of arguments that aren't options (but, + * for example, filenames). + * + * @return The number of arguments that aren't options + */ + int count() const; + + /** + * Read out an argument. + * + * @param n The argument to read. 0 is the first argument. + * count()-1 is the last argument. + * + * @return A @p const @p char @p * pointer to the n'th argument. + */ + const char *arg(int n) const; + + /** + * Read out an argument representing a URL. + * + * The argument can be + * @li an absolute filename + * @li a relative filename + * @li a URL + * + * @param n The argument to read. 0 is the first argument. + * count()-1 is the last argument. + * + * @return a URL representing the n'th argument. + */ + KURL url(int n) const; + + /** + * Used by url(). + * Made public for apps that don't use KCmdLineArgs + * @param urlArg the argument + * @return the url. + */ + static KURL makeURL( const char * urlArg ); + + /** + * Made public for apps that don't use KCmdLineArgs + * To be done before makeURL, to set the current working + * directory in case makeURL needs it. + * @param cwd the new working directory + */ + static void setCwd( char * cwd ) { mCwd = cwd; } + + /** + * Clear all options and arguments. + */ + void clear(); + + /** + * Reset all option definitions, i.e. cancel all addCmdLineOptions calls. + * Note that KApplication's options are removed too, you might want to + * call KApplication::addCmdLineOptions if you want them back. + * + * You usually don't want to call this method. + */ + static void reset(); + + /** + * Load arguments from a stream. + */ + static void loadAppArgs( QDataStream &); + + /** + * Add standard option --tempfile + * @since 3.4 + */ + static void addTempFileOption(); + + // this avoids having to know the "id" used by addTempFileOption + // but this approach doesn't scale well, we can't have 50 standard options here... + /** + * @return true if --tempfile was set + * @since 3.4 + */ + static bool isTempFileSet(); + +protected: + /** + * @internal + * Constructor. + */ + KCmdLineArgs( const KCmdLineOptions *_options, const char *_name, + const char *_id); + + /** + * @internal use only. + * + * Use clear() if you want to free up some memory. + * + * Destructor. + */ + ~KCmdLineArgs(); + +private: + /** + * @internal + * + * Checks what to do with a single option + */ + static void findOption(const char *_opt, QCString opt, int &i, bool enabled, bool &moreOptions); + + /** + * @internal + * + * Parse all arguments, verify correct syntax and put all arguments + * where they belong. + */ + static void parseAllArgs(); + + /** + * @internal for KApplication only: + * + * Return argc + */ + static int *qt_argc(); + + /** + * @internal for KApplication only: + * + * Return argv + */ + + static char ***qt_argv(); + + /** + * @internal + * + * Remove named options. + * + * @param id The name of the options to be removed. + */ + static void removeArgs(const char *id); + + /** + * @internal for KUniqueApplication only: + * + * Save all but the Qt and KDE arguments to a stream. + */ + static void saveAppArgs( QDataStream &); + + /** + * @internal + * + * Set a boolean option + */ + void setOption(const QCString &option, bool enabled); + + /** + * @internal + * + * Set a string option + */ + void setOption(const QCString &option, const char *value); + + /** + * @internal + * + * Add an argument + */ + void addArgument(const char *argument); + + /** + * @internal + * + * Save to a stream. + */ + void save( QDataStream &) const; + + /** + * @internal + * + * Restore from a stream. + */ + void load( QDataStream &); + + /** + * @internal for KApplication only + * + * Initialize class. + * + * This function should be called as the very first thing in + * your application. + * @param argc As passed to @p main(...). + * @param argv As passed to @p main(...). + * @param appname The untranslated name of your application. This should + * match with @p argv[0]. + * + * This function makes KCmdLineArgs ignore all unknown options as well as + * all arguments. + */ + static void initIgnore(int _argc, char **_argv, const char *_appname); + + static void printQ(const QString &msg); + + const KCmdLineOptions *options; + const char *name; + const char *id; + KCmdLineParsedOptions *parsedOptionList; + KCmdLineParsedArgs *parsedArgList; + bool isQt; + + static KCmdLineArgsList *argsList; // All options. + static const KAboutData *about; + + static int argc; // The original argc + static char **argv; // The original argv + static bool parsed; // Whether we have parsed the arguments since calling init + static bool ignoreUnknown; // Ignore unknown options and arguments + static char *mCwd; // Current working directory. Important for KUnqiueApp! + static bool parseArgs; + + KCmdLineArgsPrivate *d; +}; + +#endif + diff --git a/src/common/nokde/nokde_klocale.cpp b/src/common/nokde/nokde_klocale.cpp new file mode 100644 index 0000000..e30ba2f --- /dev/null +++ b/src/common/nokde/nokde_klocale.cpp @@ -0,0 +1,4 @@ +#include "nokde_klocale.h" + +QString i18n(const QString &, const QString &text) { return text; } +QString locate(const QString &, const QString &) { return QString::null; } diff --git a/src/common/nokde/nokde_klocale.h b/src/common/nokde/nokde_klocale.h new file mode 100644 index 0000000..a1cf720 --- /dev/null +++ b/src/common/nokde/nokde_klocale.h @@ -0,0 +1,17 @@ +#ifndef NOKDE_KLOCALE_H +#define NOKDE_KLOCALE_H + +#undef KDECORE_EXPORT +#define KDECORE_EXPORT + +#undef KDE_DEPRECATED +#define KDE_DEPRECATED + +#undef I18N_NOOP +#define I18N_NOOP(x) (x) +#include +inline QString i18n(const QString &text) { return text; } +extern QString i18n(const QString &index, const QString &text); +extern QString locate(const QString &, const QString &); + +#endif diff --git a/src/common/nokde/nokde_kprocess.cpp b/src/common/nokde/nokde_kprocess.cpp new file mode 100644 index 0000000..92c8968 --- /dev/null +++ b/src/common/nokde/nokde_kprocess.cpp @@ -0,0 +1,100 @@ +#include "nokde_kprocess.h" + +#if QT_VERSION<0x040000 +# include +# define Q3Process QProcess +#else +# include +#endif + +#if defined(Q_OS_UNIX) +# include +#endif + +KProcess::KProcess(QObject *parent, const char *name) + : QObject(parent, name) +{ + _process = new Q3Process(this); + connect(_process, SIGNAL(processExited()), SLOT(processExitedSlot())); + connect(_process, SIGNAL(readyReadStdout()), SLOT(readyReadStdoutSlot())); + connect(_process, SIGNAL(readyReadStderr()), SLOT(readyReadStderrSlot())); +} + +bool KProcess::start() +{ + _process->setArguments(_arguments); + QStringList env; + if ( !_environment.isEmpty() ) { + for (uint i=0; environ[i]; i++) env += environ[i]; + env += _environment; + } + return _process->start(env.isEmpty() ? 0 : &env); +} + +void KProcess::processExitedSlot() +{ + readyReadStdoutSlot(); + readyReadStderrSlot(); + emit processExited(this); +} + +void KProcess::readyReadStdoutSlot() +{ + QByteArray a = _process->readStdout(); + emit receivedStdout(this, a.data(), a.count()); +} + +void KProcess::readyReadStderrSlot() +{ + QByteArray a = _process->readStderr(); + emit receivedStderr(this, a.data(), a.count()); +} + +bool KProcess::writeStdin(const char *buffer, int len) +{ +#if QT_VERSION<0x040000 + QByteArray a; + a.assign(buffer, len); +#else + QByteArray a(buffer, len); +#endif + _process->writeToStdin(a); + return true; +} + +bool KProcess::kill() +{ + _process->kill(); + return true; +} + +bool KProcess::kill(int n) +{ +#if defined(Q_OS_UNIX) + return ( ::kill(_process->processIdentifier(), n)!=-1 ); +#elif defined(Q_OS_WIN) + // #### impossible to do ?? + return false; +#endif +} + +int KProcess::exitStatus() const +{ + return _process->exitStatus(); +} + +bool KProcess::isRunning() const +{ + return _process->isRunning(); +} + +void KProcess::setWorkingDirectory(const QDir &dir) +{ + return _process->setWorkingDirectory(dir); +} + +void KProcess::setUseShell(bool useShell) +{ + // ### TODO: just issue "/bin/sh" "-c" "command" + Q_ASSERT(false); +} diff --git a/src/common/nokde/nokde_kprocess.h b/src/common/nokde/nokde_kprocess.h new file mode 100644 index 0000000..59ff73c --- /dev/null +++ b/src/common/nokde/nokde_kprocess.h @@ -0,0 +1,51 @@ +#ifndef _KPROCESS_H_ +#define _KPROCESS_H_ + +#include +#include "common/global/global.h" +#include "common/common/synchronous.h" +#if QT_VERSION<0x040000 +class QProcess; +#else +class Q3Process; +#endif + +class KProcess : public QObject +{ +Q_OBJECT +public: + KProcess(QObject *parent = 0, const char *name = 0); + void clearArguments() { _arguments.clear(); } + KProcess &operator<< (const QString &arg) { _arguments += arg; return *this; } + KProcess &operator<< (const QStringList &args) { _arguments += args; return *this; } + QStringList args() const { return _arguments; } + void setEnvironment(const QString &name, const QString &value) { _environment += name + "=" + value; } + bool start(); + bool writeStdin(const char *buffer, int len); + bool kill(); + bool kill(int n); + int exitStatus() const; + bool isRunning() const; + void setWorkingDirectory(const QDir &dir); + void setUseShell(bool useShell); + +signals: + void processExited(KProcess *process); + void receivedStdout(KProcess *process, char *buffer, int len); + void receivedStderr(KProcess *process, char *buffer, int len); + +private slots: + void processExitedSlot(); + void readyReadStdoutSlot(); + void readyReadStderrSlot(); + +private: +#if QT_VERSION<0x040000 + QProcess *_process; +#else + Q3Process *_process; +#endif + QStringList _arguments,_environment; +}; + +#endif diff --git a/src/common/nokde/nokde_kurl.h b/src/common/nokde/nokde_kurl.h new file mode 100644 index 0000000..202c46d --- /dev/null +++ b/src/common/nokde/nokde_kurl.h @@ -0,0 +1,32 @@ +#ifndef _KURL_H_ +#define _KURL_H_ + +#include + +#include "common/global/global.h" + +class KURL : public Q3Url +{ +public: + KURL() {} + KURL(const QString &s) : Q3Url(s) {} + void cleanPath() {} + bool isEmpty() const { return toString(false, false).isEmpty(); } + QString fileName(bool b) const { Q_UNUSED(b); Q_ASSERT(!b); return Q3Url::fileName(); } + static KURL fromPathOrURL(const QString &s) { return KURL(s); } +#if QT_VERSION>=0x040000 + bool operator <(const KURL &url) const { return path() + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +// helper functions + +#include "win32_utils.h" + +#include +#include +#include +#include +#include +#include + +//--------------------------------------------- +#define _fcopy_BUFLEN 1024*32 +int fcopy(const char *src, const char *dest) +{ + static char _fcopy_buf[_fcopy_BUFLEN]; //not reentrant! + FILE *in, *out; + int c_in=0, c_out=0; + int res=0; + + in=fopen(src, "rb"); + if (!in) + return fcopy_src_err; + out=fopen(dest, "wb"); + if (!out) + return fcopy_dest_err; + while (!feof(in) && !ferror(in) && !ferror(out)) { + c_in=fread(_fcopy_buf, 1, _fcopy_BUFLEN, in); + if (ferror(in) || c_in==0) { + break; + } + c_out=fwrite(_fcopy_buf, 1, c_in, out); + if (ferror(out) || c_in!=c_out) { + break; + } + } + + if (ferror(in)) { + res=fcopy_src_err; + } + else if (ferror(out)) { + res=fcopy_dest_err; + } + else if (c_in!=c_out) { + res=fcopy_dest_err; + } + fclose(in); + fclose(out); + return res; +} + +KDEWIN32_EXPORT +void win32_slashify(char *path, int maxlen) +{ + int len = 0; + if (!path) + return; + for (; *path && len < maxlen ; path++) + if ( *path == '\\' ) + *path = '/'; +} + diff --git a/src/common/nokde/win32_utils.h b/src/common/nokde/win32_utils.h new file mode 100644 index 0000000..cc5e110 --- /dev/null +++ b/src/common/nokde/win32_utils.h @@ -0,0 +1,97 @@ +/* + This file is part of the KDE libraries + Copyright (C) 2004-2005 Jaroslaw Staniek + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KDE_WIN32_UTILS_H +#define KDE_WIN32_UTILS_H + +#include + +//#include +#define KDEWIN32_EXPORT + +#ifdef __cplusplus +#include + +extern "C" { +#endif + +#define fcopy_src_err -1 +#define fcopy_dest_err -2 + +/** + Copies @p src file to @p dest file. + @return 0 on success, fcopy_src_err on source file error, + fcopy_dest_err on destination file error. +*/ +KDEWIN32_EXPORT int fcopy(const char *src, const char *dest); + +/** + Converts all backslashes to slashes in @p path. + Converting is stopped on a null character or at @p maxlen character. +*/ +KDEWIN32_EXPORT void win32_slashify(char *path, int maxlen); + +#ifdef __cplusplus +} + +/** + \return a value from MS Windows native registry. + @param key is usually one of HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE + constants defined in WinReg.h. + @param subKey is a registry subkey defined as a path to a registry folder, eg. + "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders" + ('\' delimiter must be used) + @param item is an item inside subKey or "" if default folder's value should be returned + @param ok if not null, will be set to true on success and false on failure +*/ +KDEWIN32_EXPORT QString getWin32RegistryValue(HKEY key, const QString& subKey, + const QString& item, bool *ok = 0); + +/** + \return a value from MS Windows native registry for shell folder \a folder. +*/ +inline QString getWin32ShellFoldersPath(const QString& folder) { + return getWin32RegistryValue(HKEY_CURRENT_USER, + "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", folder); +} + +/** + Shows native MS Windows file property dialog for a file \a fileName. + Return true on success. Only works for local absolute paths. + Used by KPropertiesDialog, if possible. +*/ +KDEWIN32_EXPORT +bool showWin32FilePropertyDialog(const QString& fileName); + +/** + \return two-letter locale name (like "en" or "pl") taken from MS Windows native registry. + Useful when we don't want to rely on KSyCoCa. + Used e.g. by kbuildsycoca application. +*/ +KDEWIN32_EXPORT +QCString getWin32LocaleName(); + +/*! Temporary solutiuon + \return a KFileDialog-compatible filter string converted to QFileDialog compatible one. + This is temporary solution for kdelibs/win32... */ +KDEWIN32_EXPORT QString convertKFileDialogFilterToQFileDialogFilter(const QString& filter); + +#endif //__cplusplus + +#endif diff --git a/src/common/port/Makefile.am b/src/common/port/Makefile.am new file mode 100644 index 0000000..d1d2ce8 --- /dev/null +++ b/src/common/port/Makefile.am @@ -0,0 +1,7 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libport.la +libport_la_SOURCES = parallel.cpp port.cpp serial.cpp usb_port.cpp \ + port_base.cpp +libport_la_LDFLAGS = $(all_libraries) diff --git a/src/common/port/parallel.cpp b/src/common/port/parallel.cpp new file mode 100644 index 0000000..22b6a4c --- /dev/null +++ b/src/common/port/parallel.cpp @@ -0,0 +1,247 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * Copyright (C) 2002-2003 Stephen Landamore * + * * + * 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. * + ***************************************************************************/ +#include "parallel.h" + +#include "common/global/global.h" +#if defined(HAVE_PPDEV) +# include +# include +# include +# include +# include // needed on some system +# include +#elif defined(HAVE_PPBUS) +# include +# include +# include +# include +# include +# include +# include +#endif +#include "common/common/misc.h" + +//----------------------------------------------------------------------------- +QStringList *Port::Parallel::_list = 0; + +Port::IODirs Port::Parallel::probe(const QString &device) +{ +#if defined(HAVE_PPDEV) + int fd = ::open(device.latin1(), O_RDWR); + if ( fd<0) return NoIO; + if ( ioctl(fd, PPCLAIM)<0 ) { + ::close(fd) ; + return In; + } + ioctl(fd, PPRELEASE); + ::close(fd); + return (In | Out); +#elif defined(HAVE_PPBUS) + int fd = ::open(device.latin1(), O_RDWR); + if ( fd<0 ) return NoIO; + ::close(fd); + return In | Out; // #### can we detect read-only ? +#else + return NoIO; +#endif +} + +QStringList Port::Parallel::deviceList() +{ + QStringList list; +#if defined(HAVE_PPDEV) + // standard parport in user space + for(int i = 0; i<8; ++i) list.append(QString("/dev/parport%1").arg(i)); + // new devfs parport flavour + for(int i = 0; i<8; ++i) list.append(QString("/dev/parports/%1").arg(i)); +#elif defined(HAVE_PPBUS) + // FreeBSD + for(int i = 0; i<8; ++i) list.append(QString("/dev/ppi%1").arg(i)); +#endif + return list; +} + +const QStringList &Port::Parallel::probedDeviceList() +{ + if ( _list==0 ) { + QStringList all = deviceList(); + _list = new QStringList; + for (uint i=0; iappend(all[i]); + } + return *_list; +} + +bool Port::Parallel::isAvailable() +{ +#if defined(HAVE_PPDEV) || defined(HAVE_PPBUS) + return true; +#else + return false; +#endif +} + +//----------------------------------------------------------------------------- +const Port::Parallel::PPinData Port::Parallel::PIN_DATA[Nb_Pins] = { + { Control, 0x01, Out, "/DS" }, // !strobe + { Data, 0x01, Out, "D0" }, // data 0 + { Data, 0x02, Out, "D1" }, // data 1 + { Data, 0x04, Out, "D2" }, // data 2 + { Data, 0x08, Out, "D3" }, // data 3 + { Data, 0x10, Out, "D4" }, // data 4 + { Data, 0x20, Out, "D5" }, // data 5 + { Data, 0x40, Out, "D6" }, // data 6 + { Data, 0x80, Out, "D7" }, // data 7 + { Status, 0x40, In, "/ACK" }, // !ack + { Status, 0x80, In, "BUSY" }, // busy + { Status, 0x20, In, "PAPER" }, // pout + { Status, 0x10, In, "SELin" }, // select + { Control, 0x02, Out, "LF" }, // !feed + { Status, 0x08, In, "/ERROR" }, // !error + { Control, 0x04, Out, "PRIME" }, // !init + { Control, 0x08, Out, "SELout" }, // !si + { Nb_RequestTypes, 0x00, NoIO, "GND" }, // GND + { Nb_RequestTypes, 0x00, NoIO, "GND" }, // GND + { Nb_RequestTypes, 0x00, NoIO, "GND" }, // GND + { Nb_RequestTypes, 0x00, NoIO, "GND" }, // GND + { Nb_RequestTypes, 0x00, NoIO, "GND" }, // GND + { Nb_RequestTypes, 0x00, NoIO, "GND" }, // GND + { Nb_RequestTypes, 0x00, NoIO, "GND" }, // GND + { Nb_RequestTypes, 0x00, NoIO, "GND" } // GND +}; + +QValueVector Port::Parallel::pinData(IODir dir) const +{ + QValueVector v; + for (uint i=0; i * + * Copyright (C) 2003-2004 Alain Gibaud * + * Copyright (C) 2002-2003 Stephen Landamore * + * * + * 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. * + ***************************************************************************/ +#ifndef PARALLEL_H +#define PARALLEL_H + +#include "port_base.h" +#if defined(Q_OS_WIN) +# undef ERROR +#endif + +namespace Port +{ + +class Parallel : public Base +{ +public: + Parallel(const QString &device, Log::Base &base); + virtual ~Parallel() { close(); } + virtual Description description() const { return Description(PortType::Parallel, _device); } + + static IODirs probe(const QString &device); + static const QStringList &probedDeviceList(); + static bool isAvailable(); + + enum Pin { DS = 0, D0, D1, D2, D3, D4, D5, D6, D7, ACK, BUSY, PAPER, SELin, + LF, ERROR, PRIME, SELout, P18, P19, P20, P21, P22, P23, P24, P25, + Nb_Pins }; + enum RequestType { Control = 0, Status, Data, Nb_RequestTypes }; + struct PPinData { + RequestType rType; + uchar mask; + IODir dir; + const char *label; + }; + static const PPinData PIN_DATA[Nb_Pins]; + virtual bool setPinOn(uint pin, bool on, LogicType type); + virtual bool readPin(uint pin, LogicType type, bool &value); + virtual QValueVector pinData(IODir dir) const; + virtual bool isGroundPin(uint pin) const; + virtual uint groundPin() const { return P25; } + virtual IODir ioDir(uint pin) const; + +private: + int _fd; + QString _device; + struct RequestData { + int read, write; + }; + static const RequestData REQUEST_DATA[Nb_RequestTypes]; + uchar _images[Nb_RequestTypes]; + + static QStringList *_list; + static QStringList deviceList(); + + virtual bool internalOpen(); + virtual void internalClose(); + virtual void setSystemError(const QString &message); +}; + +} // namespace + +#endif diff --git a/src/common/port/port.cpp b/src/common/port/port.cpp new file mode 100644 index 0000000..c56c120 --- /dev/null +++ b/src/common/port/port.cpp @@ -0,0 +1,98 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "port.h" + +#if defined(Q_WS_WIN) +# include +#else +# include +#endif + +#include "common/global/global.h" +#include "serial.h" +#include "parallel.h" +#include "usb_port.h" + +//----------------------------------------------------------------------------- +void getTime(int &sec, int &usec) +{ +#if defined (Q_OS_WIN) + struct _timeb tb; + _ftime (&tb); + sec = tb.time; + usec = tb.millitm * 1000 + 500; +#else + struct timeval tv; + gettimeofday(&tv, 0); + usec = tv.tv_usec; + sec = tv.tv_sec; +#endif +} + +void Port::msleep(uint ms) +{ + usleep(ms*1000); +} + +// from Brian C Lane's code +// works better than usleep +void Port::usleep(uint us) +{ + if ( us==0 ) return; + int tsec, tusec; + getTime(tsec, tusec); + int usec = (tusec + us) % 1000000; + int sec = tsec + (tusec + us) / 1000000; + for (;;) { + getTime(tsec, tusec); + if ( tsec>sec ) return; + if ( tsec==sec && tusec>usec ) return; + } +} + +//----------------------------------------------------------------------------- +const PortType::Data PortType::DATA[Nb_Types] = { + { I18N_NOOP("Serial Port"), "serial", true }, + { I18N_NOOP("Parallel Port"), "parallel", true }, + { I18N_NOOP("USB Port"), "usb", false } +}; + +const char * const Port::IO_DIR_NAMES[3] = { "no_io", "in", "out" }; + +QStringList Port::probedDeviceList(PortType type) +{ + if ( !isAvailable(type) ) return QStringList(); + switch (type.type()) { + case PortType::Serial: return Serial::probedDeviceList(); + case PortType::Parallel: return Parallel::probedDeviceList(); + case PortType::USB: return USB::probedDeviceList(); + case PortType::Nb_Types: break; + } + return QStringList(); +} + +bool Port::isAvailable(PortType type) +{ + switch (type.type()) { + case PortType::Serial: return Serial::isAvailable(); + case PortType::Parallel: return Parallel::isAvailable(); + case PortType::USB: return USB::isAvailable(); + case PortType::Nb_Types: break; + } + return false; +} + +PortType Port::findType(const QString &portDevice) +{ + FOR_EACH(PortType, type) { + if ( !type.data().withDevice ) continue; + if ( probedDeviceList(type).contains(portDevice) ) return type; + } + return PortType::Nb_Types; +} diff --git a/src/common/port/port.h b/src/common/port/port.h new file mode 100644 index 0000000..f385deb --- /dev/null +++ b/src/common/port/port.h @@ -0,0 +1,56 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PORT_H +#define PORT_H + +#include + +#include "common/global/global.h" +#include "common/common/key_enum.h" + +//----------------------------------------------------------------------------- +struct PortTypeData { + const char *label, *key; + bool withDevice; +}; + +BEGIN_DECLARE_ENUM(PortType) + Serial = 0, Parallel, USB +END_DECLARE_ENUM(PortType, PortTypeData) + +namespace Port +{ +//----------------------------------------------------------------------------- +extern void msleep(uint ms); // in milliseconds +extern void usleep(uint us); // in microseconds + +//----------------------------------------------------------------------------- + class Description { + public: + Description() : type(PortType::Nb_Types) {} + Description(PortType ptype, const QString &pdevice) : type(ptype), device(pdevice) {} + PortType type; + QString device; + }; + + enum IODir { NoIO = 0, In = 1, Out = 2 }; + extern const char * const IO_DIR_NAMES[3]; + Q_DECLARE_FLAGS(IODirs, IODir) + Q_DECLARE_OPERATORS_FOR_FLAGS(IODirs) + extern QStringList probedDeviceList(PortType type); + extern PortType findType(const QString &device); + extern bool isAvailable(PortType type); + struct PinData { + uint pin; + const char *label; + }; + enum LogicType { PositiveLogic, NegativeLogic }; +} // namespace + +#endif diff --git a/src/common/port/port.pro b/src/common/port/port.pro new file mode 100644 index 0000000..f09414b --- /dev/null +++ b/src/common/port/port.pro @@ -0,0 +1,10 @@ +STOPDIR = ../../.. +include($${STOPDIR}/lib.pro) + +TARGET = port +HEADERS += port.h port_base.h parallel.h serial.h usb_port.h +SOURCES += port.cpp port_base.cpp parallel.cpp serial.cpp usb_port.cpp +contains(DEFINES, HAVE_USB) { + win32:INCLUDEPATH += $${LIBUSB_PATH}\include +} + diff --git a/src/common/port/port_base.cpp b/src/common/port/port_base.cpp new file mode 100644 index 0000000..7528eeb --- /dev/null +++ b/src/common/port/port_base.cpp @@ -0,0 +1,127 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "port_base.h" + +#include "common/global/global.h" +#include "common/common/misc.h" +#include "common/common/number.h" + +bool Port::Base::open() +{ + close(); + resetError(); + _closing = false; + return internalOpen(); +} + +void Port::Base::close() +{ + _closing = true; + internalClose(); +} + +bool Port::Base::send(const char *data, uint size, uint timeout) +{ + log(Log::DebugLevel::LowLevel, QString("Sending: \"%1\"").arg(toPrintable(data, size, PrintAlphaNum))); + return internalSend(data, size, timeout); +} + +bool Port::Base::receive(uint size, QString &s, uint timeout) +{ + QMemArray a; + if ( !receive(size, a, timeout) ) return false; + s.fill(0, size); + for (uint i=0; i &a, uint timeout) +{ + a.resize(size); + bool ok = internalReceive(size, (char *)a.data(), timeout); + if (ok) log(Log::DebugLevel::LowLevel, QString("Received: \"%1\"").arg(toPrintable(a, PrintAlphaNum))); + return ok; +} + +bool Port::Base::receiveChar(char &c, uint timeout) +{ + if ( !internalReceive(1, &c, timeout) ) return false; + log(Log::DebugLevel::LowLevel, QString("Received: \"%1\"").arg(toPrintable(c, PrintAlphaNum))); + return true; +} + +bool Port::Base::setPinOn(uint, bool, LogicType) +{ + qFatal("setPinOn not implemented"); + return false; +} +bool Port::Base::readPin(uint, LogicType, bool &) +{ + qFatal("readPin not implemented"); + return 0; +} +QValueVector Port::Base::pinData(IODir) const +{ + qFatal("pinData not implemented"); + return QValueVector(); +} +bool Port::Base::isGroundPin(uint) const +{ + qFatal("isGroundPin not implemented"); + return false; +} +uint Port::Base::groundPin() const +{ + qFatal("groundPin not implemented"); + return 0; +} +Port::IODir Port::Base::ioDir(uint) const +{ + qFatal("ioType not implemented"); + return NoIO; +} + +void Port::Base::log(Log::LineType lineType, const QString &message) +{ + if ( lineType==Log::LineType::Error && _closing ) return; + Log::Base::log(lineType, description().type.label() + ": " + message); + if ( lineType==Log::LineType::Error ) close(); +} + +void Port::Base::log(Log::DebugLevel level, const QString &message) +{ + Log::Base::log(level, description().type.label() + ": " + message); +} + +void Port::Base::logData(const QString &) +{ +/* + QString vs; + for (uint i=0; i': vs += ">"; break; + default: { + if ( c>=32 && c<=126 ) vs += c; + else { + QString tmp; + tmp.sprintf("\\x%02x", c); + vs += tmp; + } + break; + } + } + } + qDebug("%s", vs.latin1()); +*/ + //log(Log::Debug, vs); +} diff --git a/src/common/port/port_base.h b/src/common/port/port_base.h new file mode 100644 index 0000000..3ae4787 --- /dev/null +++ b/src/common/port/port_base.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PORT_BASE_H +#define PORT_BASE_H + +#include "port.h" +#include "common/global/log.h" + +namespace Port +{ + +class Base : public Log::Base +{ +public: + Base(Log::Base &base) : Log::Base(&base) {} + virtual PortType type() const { return description().type; } + virtual Description description() const = 0; + bool open(); + void close(); + + virtual void log(Log::LineType kind, const QString &message); + virtual void log(Log::DebugLevel level, const QString &message); + void logData(const QString &s); + + enum { DEFAULT_TIMEOUT = 3000 }; // 3s + bool sendChar(char c, uint timeout = DEFAULT_TIMEOUT) { return send(&c, 1, timeout); } + bool send(const char *data, uint size, uint timeout = DEFAULT_TIMEOUT); + bool send(const QMemArray &a, uint timeout = DEFAULT_TIMEOUT) { return send((const char *)a.data(), a.count(), timeout); } + bool receiveChar(char &c, uint timeout = DEFAULT_TIMEOUT); + bool receive(uint size, QString &s, uint timeout = DEFAULT_TIMEOUT); + bool receive(uint size, QMemArray &a, uint timeout = DEFAULT_TIMEOUT); + + virtual bool setPinOn(uint pin, bool on, LogicType type); + virtual bool readPin(uint pin, LogicType type, bool &value); + virtual QValueVector pinData(IODir dir) const; + virtual bool isGroundPin(uint pin) const; + virtual uint groundPin() const; + virtual IODir ioDir(uint pin) const; + +protected: + virtual bool internalOpen() = 0; + virtual void internalClose() = 0; + virtual bool internalSend(const char *, uint, uint) { qFatal("Not implemented"); return false; } + virtual bool internalReceive(uint, char *, uint) { qFatal("Not implemented"); return false; } + virtual void setSystemError(const QString &message) = 0; + +private: + bool _closing; +}; + +} // namespace + +#endif diff --git a/src/common/port/serial.cpp b/src/common/port/serial.cpp new file mode 100644 index 0000000..b370d22 --- /dev/null +++ b/src/common/port/serial.cpp @@ -0,0 +1,523 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * Copyright (C) 2002-2003 Stephen Landamore * + * * + * 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. * + ***************************************************************************/ +#include "serial.h" + +#ifdef Q_OS_UNIX +# include +# include +# include +# include +# include +# include +# include +# include // needed on some system +#endif +#include + +//----------------------------------------------------------------------------- +QStringList *Port::Serial::_list = 0; +#if defined(Q_OS_UNIX) +const Port::Serial::Handle Port::Serial::INVALID_HANDLE = -1; +#elif defined(Q_OS_WIN) +const Port::Serial::Handle Port::Serial::INVALID_HANDLE = INVALID_HANDLE_VALUE; +#endif + +Port::Serial::Handle Port::Serial::openHandle(const QString &device, IODirs dirs) +{ +#if defined(Q_OS_UNIX) + // open non blocking: avoid missing DCD (comment from xwisp2) + int mode = O_NOCTTY | O_NONBLOCK; + if ( dirs & In ) { + if ( dirs & Out ) mode |= O_RDWR; + else mode |= O_RDONLY; + } else mode |= O_WRONLY; + return ::open(device.latin1(), mode); +#elif defined(Q_OS_WIN) + int mode = 0; + if ( dirs & In ) mode |= GENERIC_READ; + if ( dirs & Out ) mode |= GENERIC_WRITE; + return CreateFileA(device.latin1(), mode, 0, NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL); +#endif +} + +void Port::Serial::closeHandle(Handle handle) +{ +#if defined(Q_OS_UNIX) + ::close(handle); +#elif defined(Q_OS_WIN) + CloseHandle(handle); +#endif +} + +Port::IODirs Port::Serial::probe(const QString &device) +{ + Handle handle = openHandle(device, In); + if ( handle==INVALID_HANDLE ) return NoIO; + closeHandle(handle); + handle = openHandle(device, In | Out); + if ( handle==INVALID_HANDLE ) return In; + closeHandle(handle); + return (In | Out); +} + +QStringList Port::Serial::deviceList() +{ + QStringList list; +#if defined(Q_OS_UNIX) + // standard serport in user space + for (uint i=0; i<8; i++) list.append(QString("/dev/ttyS%1").arg(i)); + // new devfs serport flavour + for (uint i=0; i<8; i++) list.append(QString("/dev/tts/%1").arg(i)); + // standard USB serport in user space + for (uint i=0; i<8; i++) list.append(QString("/dev/ttyUSB%1").arg(i)); + // new devfs USB serport flavour + for (uint i=0; i<8; i++) list.append(QString("/dev/usb/tts/%1").arg(i)); + // FreeBSD + for (uint i=0; i<8; i++) list.append(QString("/dev/ttyd%1").arg(i)); + // Slackware 11 devfs USB Serial port support. + for (uint i=0; i<8; i++) list.append(QString("/dev/tts/USB%1").arg(i)); + // MacOSX devfs USB Serial port support. + list.append("/dev/tty.usbserial"); +#elif defined(Q_OS_WIN) + for (uint i=1; i<10; i++) list.append(QString("COM%1").arg(i)); +#endif + return list; +} + +const QStringList &Port::Serial::probedDeviceList() +{ + if ( _list==0 ) { + QStringList all = deviceList(); + _list = new QStringList; + for (uint i=0; iappend(all[i]); + } + return *_list; +} + +//----------------------------------------------------------------------------- +const uint Port::Serial::SPEED_VALUES[Nb_Speeds] = { + 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, + 57600, 115200 +}; +const Port::Serial::SpeedData Port::Serial::SPEED_DATA[Nb_Speeds] = { +#if defined(Q_OS_UNIX) + { true, B0 }, { true, B50 }, { true, B75 }, { true, B110 }, + { true, B134 }, { true, B150 }, { true, B200 }, { true, B300 }, + { true, B600 }, { true, B1200 }, { true, B1800 }, { true, B2400 }, + { true, B4800 }, { true, B9600 }, { true, B19200 }, { true, B38400 }, + { true, B57600 }, { true, B115200 } +#elif defined(Q_OS_WIN) + { false, 0 }, { false, 0 }, { false, 0 }, { true, CBR_110 }, + { false, 0 }, { false, 0 }, { false, 0 }, { true, CBR_300 }, + { true, CBR_600 }, { true, CBR_1200 }, { false, 0 }, { true, CBR_2400 }, + { true, CBR_4800 }, { true, CBR_9600 }, { true, CBR_19200 }, { true, CBR_38400 }, + { true, CBR_57600 }, { true, CBR_115200 } +#endif +}; + +const Port::Serial::SPinData Port::Serial::PIN_DATA[Nb_Pins] = { + { In, "DCD" }, { In, "RX" }, { Out, "TX" }, { Out, "DTR" }, + { NoIO, "GND" }, { In, "DSR" }, { Out, "RTS" }, { In, "CTS" }, + { Out, "RI" } +}; + +QValueVector Port::Serial::pinData(IODir dir) const +{ + QValueVector v; + for (uint i=0; i0 ) todo -= res; + else { + if ( uint(time.elapsed())>timeout ) { + log(Log::LineType::Error, i18n("Timeout sending data (%1/%2 bytes sent).").arg(size-todo).arg(size)); + return false; + } + msleep(1); + } + } + if ( (_properties & NeedDrain) && !drain(timeout) ) return false; + return true; +} + +bool Port::Serial::internalReceive(uint size, char *data, uint timeout) +{ + if ( _fd==INVALID_HANDLE ) return false; + QTime time; + time.start(); + for(uint todo=size; todo!=0; ) { +#if defined(Q_OS_UNIX) + // this help reduce CPU usage. It also prevents blocking if the serial cable is disconnected + fd_set rfd; + FD_ZERO(&rfd); + FD_SET(_fd, &rfd); + struct timeval tv; + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout%1000)*1000; + int res = select(_fd+1, &rfd, 0, 0, &tv); + if ( res<0 ) { + setSystemError(i18n("Error receiving data")); + return false; + } + if ( res==0 ) { + log(Log::LineType::Error, i18n("Timeout waiting for data.")); + return false; + } + res = read(_fd, data+size-todo, todo); + if ( res<0 && errno!=EAGAIN ) { +#elif defined(Q_OS_WIN) + DWORD res = 0; + if ( ReadFile(_fd, data+size-todo, todo, &res, NULL)==0 ) { +#endif + setSystemError(i18n("Error receiving data")); + return false; + } + if ( res>0 ) todo -= res; + else { + if ( uint(time.elapsed())>timeout ) { + log(Log::LineType::Error, i18n("Timeout receiving data (%1/%2 bytes received).").arg(size-todo).arg(size)); + return false; + } + msleep(1); + } + } + return true; +} + +bool Port::Serial::drain(uint timeout) +{ + if ( _fd==INVALID_HANDLE ) return false; +#if defined(Q_OS_UNIX) + // tcdrain will block if the serial cable is disconnected + // so we first check for data in output buffer... + QTime time; + time.start(); + for (;;) { + int nb; + if ( ioctl(_fd, TIOCOUTQ, &nb)==-1 ) { + setSystemError(i18n("Error checking for data in output buffer")); + return false; + } + if ( nb==0 ) break; + if ( uint(time.elapsed())>timeout ) { + _fd = INVALID_HANDLE; // otherwise close blocks... + log(Log::LineType::Error, i18n("Timeout sending data (%1 bytes left).").arg(nb)); + return false; + } + } + if ( tcdrain(_fd)<0 ) { + setSystemError(i18n("Error while draining")); + return false; + } +#endif + return true; +} + +bool Port::Serial::flush(uint timeout) +{ + if ( _fd==INVALID_HANDLE ) return false; + if ( (_properties & NeedDrain) && !drain(timeout) ) return false; +#if defined(Q_OS_UNIX) + if ( tcflush(_fd, TCIFLUSH)<0 ) { +#elif defined(Q_OS_WIN) + if ( FlushFileBuffers(_fd)==0 || PurgeComm(_fd, PURGE_TXABORT)==0 + || PurgeComm(_fd, PURGE_RXABORT)==0 || PurgeComm(_fd, PURGE_TXCLEAR)==0 + || PurgeComm(_fd, PURGE_RXCLEAR)==0 ) { +#endif + setSystemError(i18n("Could not flush device")); + return false; + } + return true; +} + +bool Port::Serial::internalSetPinOn(Pin pin, bool on) +{ +#if defined(Q_OS_UNIX) + int bit = 0; + switch (pin) { + case TX: return ( ioctl(_fd, on ? TIOCSBRK : TIOCCBRK, 0)>=0 ); + case DTR: bit = TIOCM_DTR; break; + case RTS: bit = TIOCM_RTS; break; + case RI: bit = TIOCM_RI; break; + default: Q_ASSERT(false); return false; + } + return ( ioctl(_fd, on ? TIOCMBIS : TIOCMBIC, &bit)>=0 ); +#elif defined(Q_OS_WIN) + DWORD func = 0; + switch (pin) { + case TX: func = (on ? SETBREAK : CLRBREAK); break; + case DTR: func = (on ? SETDTR : CLRDTR); break; + case RTS: func = (on ? SETRTS : CLRRTS); break; + case RI: // #### not possible with Win32 API ?? + default: Q_ASSERT(false); return false; + } + return ( EscapeCommFunction(_fd, func)!=0 ); +#endif +} + +bool Port::Serial::setPinOn(uint pin, bool on, LogicType type) +{ + if ( _fd==INVALID_HANDLE ) return false; + if ( type==NegativeLogic ) on = !on; + Q_ASSERT( pin * + * Copyright (C) 2003-2004 Alain Gibaud * + * Copyright (C) 2002-2003 Stephen Landamore * + * * + * 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. * + ***************************************************************************/ +#ifndef SERIAL_H +#define SERIAL_H + +#include "common/global/global.h" +#ifdef Q_OS_UNIX +# include +#elif defined(Q_OS_WIN) +# include +#endif +#include "port_base.h" + +namespace Port +{ + +class Serial : public Base +{ +public: + enum Speed { S0 = 0, S50, S75, S110, S134, S150, S200, S300, S600, S1200, + S1800, S2400, S4800, S9600, S19200, S38400, S57600, S115200, + Nb_Speeds }; + static const uint SPEED_VALUES[Nb_Speeds]; + struct SpeedData { + bool supported; + uint flag; + }; + static const SpeedData SPEED_DATA[Nb_Speeds]; + + enum Property { NoProperty = 0, NeedDrain = 1, NeedFlush = 2, NeedBreak = 4, + Blocking = 8 }; + Q_DECLARE_FLAGS(Properties, Property) + + Serial(const QString &device, Properties properties, Log::Base &base); + virtual ~Serial() { close(); } + virtual Description description() const { return Description(PortType::Serial, _device); } + + static const QStringList &probedDeviceList(); + static IODirs probe(const QString &device); + static bool isAvailable() { return true; } + + enum InputFlag { NoInputFlag = 0, IgnoreBreak = 1, IgnoreParity = 2 }; + Q_DECLARE_FLAGS(InputFlags, InputFlag) + enum ControlFlag { NoControlFlag = 0, ByteSize8 = 1, HardwareFlowControl = 2, + EnableReceiver = 4, IgnoreControlLines = 8 }; + Q_DECLARE_FLAGS(ControlFlags, ControlFlag) + bool setMode(InputFlags inputFlags, ControlFlags controlFlags, Speed speed, uint readTimeout); // in ms + bool drain(uint timeout); + bool flush(uint timeout); + bool doBreak(uint duration); // in ms + bool setHardwareFlowControl(bool on); + + enum Pin { DCD = 0, RX, TX, DTR, SG, DSR, RTS, CTS, RI, Nb_Pins }; + struct SPinData { + IODir dir; + const char *label; + }; + static const SPinData PIN_DATA[Nb_Pins]; + virtual bool setPinOn(uint pin, bool on, LogicType type); + virtual bool readPin(uint pin, LogicType type, bool &value); + virtual QValueVector pinData(IODir dir) const; + virtual bool isGroundPin(uint pin) const; + virtual uint groundPin() const { return SG; } + virtual IODir ioDir(uint pin) const; + +private: + QString _device; + Properties _properties; +#if defined(Q_OS_UNIX) + typedef int Handle; + typedef termios Parameters; +#elif defined(Q_OS_WIN) + typedef HANDLE Handle; + struct Parameters { + DCB dcb; + COMMTIMEOUTS comtmo; + }; +#endif + Handle _fd; + Parameters _oldParameters; + + bool setParameters(const Parameters ¶meters); + bool getParameters(Parameters ¶meters); + virtual bool internalOpen(); + virtual void internalClose(); + virtual bool internalSend(const char *data, uint size, uint timeout); + virtual bool internalReceive(uint size, char *data, uint timeout); + virtual void setSystemError(const QString &message); + bool internalSetPinOn(Pin pin, bool on); + bool internalReadPin(Pin pin, LogicType type, bool &value); + + static const Handle INVALID_HANDLE; + static Handle openHandle(const QString &device, IODirs dirs); + static void closeHandle(Handle handle); + static QStringList *_list; + static QStringList deviceList(); + static void setHardwareFlowControl(Parameters ¶meters, bool on); +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(Serial::Properties) +Q_DECLARE_OPERATORS_FOR_FLAGS(Serial::InputFlags) +Q_DECLARE_OPERATORS_FOR_FLAGS(Serial::ControlFlags) + +} // namespace + +#endif diff --git a/src/common/port/usb_port.cpp b/src/common/port/usb_port.cpp new file mode 100644 index 0000000..392b483 --- /dev/null +++ b/src/common/port/usb_port.cpp @@ -0,0 +1,411 @@ +/*************************************************************************** + * Copyright (C) 2005 Lorenz Mösenlechner & Matthias Kranz * + * * + * Copyright (C) 2003-2005 Orion Sky Lawlor * + * Copyright (C) 2005-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "usb_port.h" + +#ifdef HAVE_USB +# include +#endif +#include + +#include "common/common/version_data.h" +#include "common/common/number.h" + +//----------------------------------------------------------------------------- +class Port::USB::Private +{ +public: +#ifdef HAVE_USB + Private() : _interface(0) {} + const usb_interface_descriptor *_interface; +#endif +}; + +bool Port::USB::_initialized = false; + +void Port::USB::initialize() +{ + if (_initialized) return; + _initialized = true; +#ifdef HAVE_USB + usb_init(); + VersionData vd = VersionData::fromString(LIBUSB_VERSION); + QString s = QString("libusb %1").arg(vd.pretty()); + if ( vddescriptor.bNumConfigurations); + for (int c=0; cdescriptor.bNumConfigurations; c++) { + qDebug("Looking at configuration %d...This configuration has %d interfaces.", c, dev->config[c].bNumInterfaces); + for(int i=0; iconfig[c].bNumInterfaces; i++) { + qDebug(" Looking at interface %d...This interface has %d altsettings.", i, dev->config[c].interface[i].num_altsetting); + for (int a=0; a < dev->config[c].interface[i].num_altsetting; a++) { + qDebug(" Looking at altsetting %d...This altsetting has %d endpoints.", a, dev->config[c].interface[i].altsetting[a].bNumEndpoints); + for (int e=0; e < dev->config[c].interface[i].altsetting[a].bNumEndpoints; e++) { + QString s; + s.sprintf(" Endpoint %d: Address %02xh, attributes %02xh ", e, dev->config[c].interface[i].altsetting[a].endpoint[e].bEndpointAddress, dev->config[c].interface[i].altsetting[a].endpoint[e].bmAttributes); + uchar attribs = (dev->config[c].interface[i].altsetting[a].endpoint[e].bmAttributes & 3); + switch (attribs) { + case 0: s += "(Control) "; break; + case 1: s += "(Isochronous) "; break; + case 2: s += "(Bulk) "; + /* Found the correct configuration, interface etc... it has bulk endpoints! */ + configuration=c; + interface=i; + altsetting=a; + break; + case 3: s += "(Interrupt) "; break; + default: s += "ERROR! Got an illegal value in endpoint bmAttributes"; + } + if ( attribs!=0 ) { + uchar dir = (dev->config[c].interface[i].altsetting[a].endpoint[e].bEndpointAddress & 0x80); + switch (dir) { + case 0x00: s += "(Out)"; + // Do nothing in this case + break; + case 0x80: s += "(In)"; + if ((dev->config[c].interface[i].altsetting[a].endpoint[e].bmAttributes & 0x03) == 2) /* Make sure it's a *bulk* endpoint */ { + // Found the correct endpoint to use for bulk transfer; use its ADDRESS + bulk_endpoint=dev->config[c].interface[i].altsetting[a].endpoint[e].bEndpointAddress; + } + break; + default: s += "ERROR! Got an illegal value in endpoint bEndpointAddress"; + } + } + qDebug("%s", s.latin1()); + } + } + } + } + if (bulk_endpoint<0) { + qDebug("No valid interface found!"); + return false; + } +#endif + return true; +} + +QStringList Port::USB::probedDeviceList() +{ + initialize(); + QStringList list; +#ifdef HAVE_USB + usb_init(); // needed ? + for (usb_bus *bus=getBusses(); bus; bus=bus->next) { + for (struct usb_device *dev=bus->devices; dev; dev=dev->next) { + if ( dev->descriptor.idVendor==0 ) continue; // controller + list.append(QString("Vendor Id: %1 - Product Id: %2") + .arg(toLabel(NumberBase::Hex, dev->descriptor.idVendor, 4)).arg(toLabel(NumberBase::Hex, dev->descriptor.idProduct, 4))); + } + } +#endif + return list; +} + +struct usb_device *Port::USB::findDevice(uint vendorId, uint productId) +{ + initialize(); +#ifdef HAVE_USB + for (usb_bus *bus=getBusses(); bus; bus=bus->next) { + for (struct usb_device *dev=bus->devices; dev; dev=dev->next) { + if ( dev->descriptor.idVendor==vendorId && dev->descriptor.idProduct==productId ) + return dev; + } + } +#else + Q_UNUSED(vendorId); Q_UNUSED(productId); + qDebug("USB support disabled"); +#endif + return 0; +} + +//----------------------------------------------------------------------------- +const char * const Port::USB::ENDPOINT_MODE_NAMES[Nb_EndpointModes] = { + "bulk", "interrupt", "control", "isochronous" +}; + +Port::USB::USB(Log::Base &base, uint vendorId, uint productId, uint config, uint interface) + : Base(base), _vendorId(vendorId), _productId(productId), + _config(config), _interface(interface), _handle(0), _device(0) +{ + Q_ASSERT( config>=1 ); + _private = new Private; + initialize(); +} + +Port::USB::~USB() +{ + close(); + delete _private; +} + +void Port::USB::setSystemError(const QString &message) +{ +#ifdef HAVE_USB + log(Log::LineType::Error, message + QString(" (err=%1).").arg(usb_strerror())); +#else + log(Log::LineType::Error, message); +#endif +} + +void Port::USB::tryToDetachDriver() +{ + // try to detach an already existing driver... (linux only) +#if defined(LIBUSB_HAS_GET_DRIVER_NP) && LIBUSB_HAS_GET_DRIVER_NP + log(Log::DebugLevel::Extra, "find if there is already an installed driver"); + char dname[256] = ""; + if ( usb_get_driver_np(_handle, _interface, dname, 255)<0 ) return; + log(Log::DebugLevel::Normal, QString(" a driver \"%1\" is already installed...").arg(dname)); +# if defined(LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP) && LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP + usb_detach_kernel_driver_np(_handle, _interface); + log(Log::DebugLevel::Normal, " try to detach it..."); + if ( usb_get_driver_np(_handle, _interface, dname, 255)<0 ) return; + log(Log::DebugLevel::Normal, " failed to detach it"); +# endif +#endif +} + +bool Port::USB::internalOpen() +{ +#ifdef HAVE_USB + _device = findDevice(_vendorId, _productId); + if ( _device==0 ) { + log(Log::LineType::Error, i18n("Could not find USB device (vendor=%1 product=%2).") + .arg(toLabel(NumberBase::Hex, _vendorId, 4)).arg(toLabel(NumberBase::Hex, _productId, 4))); + return false; + } + log(Log::DebugLevel::Extra, QString("found USB device as \"%1\" on bus \"%2\"").arg(_device->filename).arg(_device->bus->dirname)); + _handle = usb_open(_device); + if ( _handle==0 ) { + setSystemError(i18n("Error opening USB device.")); + return false; + } +// windows: usb_reset takes about 7-10 seconds to re-enumerate the device... +// BSD : not implemented in libusb... +# if !defined(Q_OS_BSD4) && !defined(Q_OS_WIN) + if ( usb_reset(_handle)<0 ) { + setSystemError(i18n("Error resetting USB device.")); + return false; + } +# endif + usb_close(_handle); + _handle = usb_open(_device); + if ( _handle==0 ) { + setSystemError(i18n("Error opening USB device.")); + return false; + } + tryToDetachDriver(); + uint i = 0; + for (; i<_device->descriptor.bNumConfigurations; i++) + if ( _config==_device->config[i].bConfigurationValue ) break; + if ( i==_device->descriptor.bNumConfigurations ) { + uint old = _config; + i = 0; + _config = _device->config[i].bConfigurationValue; + log(Log::LineType::Warning, i18n("Configuration %1 not present: using %2").arg(old).arg(_config)); + } + const usb_config_descriptor &configd = _device->config[i]; + if ( usb_set_configuration(_handle, _config)<0 ) { + setSystemError(i18n("Error setting USB configuration %1.").arg(_config)); + return false; + } + for (i=0; i_interface = &(configd.interface[i].altsetting[0]); + if ( usb_claim_interface(_handle, _interface)<0 ) { + setSystemError(i18n("Could not claim USB interface %1").arg(_interface)); + return false; + } + log(Log::DebugLevel::Max, QString("alternate setting is %1").arg(_private->_interface->bAlternateSetting)); + log(Log::DebugLevel::Max, QString("USB bcdDevice: %1").arg(toHexLabel(_device->descriptor.bcdDevice, 4))); + return true; +#else + log(Log::LineType::Error, i18n("USB support disabled")); + return false; +#endif +} + +void Port::USB::internalClose() +{ + if ( _handle==0 ) return; +#ifdef HAVE_USB + usb_release_interface(_handle, _interface); + usb_close(_handle); + _private->_interface = 0; +#endif + _device = 0; + _handle = 0; +} + +bool Port::USB::sendControlMessage(const ControlMessageData &data) +{ + if ( hasError() ) return false; +#ifdef HAVE_USB + QString s = data.bytes; + uint length = strlen(data.bytes) / 2; + QByteArray ba(length); + for (uint i=0; i_interface); + const usb_endpoint_descriptor *ued = _private->_interface->endpoint + index; + Q_ASSERT(ued); + switch (ued->bmAttributes & USB_ENDPOINT_TYPE_MASK) { + case USB_ENDPOINT_TYPE_BULK: return Bulk; + case USB_ENDPOINT_TYPE_INTERRUPT: return Interrupt; + case USB_ENDPOINT_TYPE_ISOCHRONOUS: return Isochronous; + case USB_ENDPOINT_TYPE_CONTROL: return Control; + default: break; + } +#endif + Q_ASSERT(false); + return Nb_EndpointModes; +} + +Port::IODir Port::USB::endpointDir(uint ep) const +{ +#ifdef HAVE_USB + switch (ep & USB_ENDPOINT_DIR_MASK) { + case USB_ENDPOINT_IN: return In; + case USB_ENDPOINT_OUT: return Out; + default: break; + } +#endif + Q_ASSERT(false); + return NoIO; +} + +bool Port::USB::write(uint ep, const char *data, uint size) +{ + if ( hasError() ) return false; +#ifdef HAVE_USB + IODir dir = endpointDir(ep); + EndpointMode mode = endpointMode(ep); + log(Log::DebugLevel::LowLevel, QString("write to endpoint %1 (%2 - %3) %4 chars: \"%5\"") + .arg(toHexLabel(ep, 2)).arg(ENDPOINT_MODE_NAMES[mode]).arg(IO_DIR_NAMES[dir]).arg(size).arg(toPrintable(data, size, PrintEscapeAll))); + Q_ASSERT( dir==Out ); + QTime time; + time.start(); + int todo = size; + for (;;) { + int res = 0; + //qDebug("write ep=%i todo=%i/%i", ep, todo, size); + if ( mode==Interrupt ) res = usb_interrupt_write(_handle, ep, (char *)data + size - todo, todo, timeout(todo)); + else res = usb_bulk_write(_handle, ep, (char *)data + size - todo, todo, timeout(todo)); + //qDebug("res: %i", res); + if ( res==todo ) break; + if ( uint(time.elapsed())>3000 ) { // 3 s + if ( res<0 ) setSystemError(i18n("Error sending data (ep=%1 res=%2)").arg(toHexLabel(ep, 2)).arg(res)); + else log(Log::LineType::Error, i18n("Timeout: only some data sent (%1/%2 bytes).").arg(size-todo).arg(size)); + return false; + } + if ( res==0 ) log(Log::DebugLevel::Normal, i18n("Nothing sent: retrying...")); + if ( res>0 ) todo -= res; + msleep(100); + } +#else + Q_UNUSED(ep); Q_UNUSED(data); Q_UNUSED(size); +#endif + return true; +} + +bool Port::USB::read(uint ep, char *data, uint size, bool *poll) +{ + if ( hasError() ) return false; +#ifdef HAVE_USB + IODir dir = endpointDir(ep); + EndpointMode mode = endpointMode(ep); + log(Log::DebugLevel::LowLevel, QString("read from endpoint %1 (%2 - %3) %4 chars") + .arg(toHexLabel(ep, 2)).arg(ENDPOINT_MODE_NAMES[mode]).arg(IO_DIR_NAMES[dir]).arg(size)); + Q_ASSERT( dir==In ); + QTime time; + time.start(); + int todo = size; + for (;;) { + int res = 0; + //qDebug("read ep=%i size=%i", ep, todo); + if ( mode==Interrupt ) res = usb_interrupt_read(_handle, ep, data + size - todo, todo, timeout(todo)); + else res = usb_bulk_read(_handle, ep, data + size - todo, todo, timeout(todo)); + //qDebug("res: %i", res); + if ( res==todo ) break; + if ( uint(time.elapsed())>3000 ) { // 3 s: seems to help icd2 in some case (?) + if ( res<0 ) setSystemError(i18n("Error receiving data (ep=%1 res=%2)").arg(toHexLabel(ep, 2)).arg(res)); + else log(Log::LineType::Error, i18n("Timeout: only some data received (%1/%2 bytes).").arg(size-todo).arg(size)); + return false; + } + if ( res==0 ) { + if (poll) { + *poll = false; + return true; + } else log(Log::DebugLevel::Normal, i18n("Nothing received: retrying...")); + } + if ( res>0 ) todo -= res; + msleep(100); + } + if (poll) *poll = true; +#else + Q_UNUSED(ep); Q_UNUSED(data); Q_UNUSED(size); +#endif + return true; +} diff --git a/src/common/port/usb_port.h b/src/common/port/usb_port.h new file mode 100644 index 0000000..73961cc --- /dev/null +++ b/src/common/port/usb_port.h @@ -0,0 +1,70 @@ +/*************************************************************************** + * Copyright (C) 2005 Lorenz Mösenlechner & Matthias Kranz * + * * + * Copyright (C) 2005 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef USB_PORT_H +#define USB_PORT_H + +#include "port_base.h" +#if defined(Q_OS_WIN) +#undef interface +#endif +struct usb_dev_handle; +struct usb_device; +struct usb_bus; + +namespace Port +{ + +class USB : public Base +{ +public: + USB(Log::Base &base, uint vendorId, uint productId, uint config, uint interface); + virtual ~USB(); + virtual Description description() const { return Description(PortType::USB, QString::null); } + + static struct usb_device *findDevice(uint vendorId, uint productId); + static bool isAvailable(); + static QStringList probedDeviceList(); + + struct ControlMessageData { + int type, request, value; + const char *bytes; + }; + bool sendControlMessage(const ControlMessageData &data); + enum EndpointMode { Bulk = 0, Interrupt, Control, Isochronous, Nb_EndpointModes }; + static const char * const ENDPOINT_MODE_NAMES[Nb_EndpointModes]; + EndpointMode endpointMode(uint ep) const; + IODir endpointDir(uint ep) const; + +protected: + bool write(uint endPoint, const char *data, uint size); + bool read(uint endPoint, char *data, uint size, bool *poll = 0); + +private: + class Private; + Private *_private; + uint _vendorId, _productId, _config, _interface; + usb_dev_handle *_handle; + usb_device *_device; + + virtual bool internalOpen(); + virtual void internalClose(); + virtual void setSystemError(const QString &message); + void tryToDetachDriver(); + + static bool _initialized; + static void initialize(); + static usb_bus *getBusses(); + static bool findBulk(const struct usb_device *device); +}; + +} // namespace + +#endif diff --git a/src/data/Makefile.am b/src/data/Makefile.am new file mode 100644 index 0000000..e900930 --- /dev/null +++ b/src/data/Makefile.am @@ -0,0 +1,17 @@ +INCLUDES = $(all_includes) +SUBDIRS = app_data likeback + +piklabdir = $(kde_datadir)/piklab/icons +piklab_ICON = AUTO + +syntaxkatedir = $(kde_datadir)/katepart/syntax +syntaxkate_DATA = asm-pic.xml coff-pic.xml jal-pic.xml coff-c-pic.xml + +noinst_PROGRAMS = syntax_xml_generator +syntax_xml_generator_SOURCES = syntax_xml_generator.cpp +syntax_xml_generator_LDADD = $(LIB_QT) +syntax_xml_generator_LDFLAGS = $(all_libraries) + +asm-pic.xml coff-pic.xml: syntax_xml_generator + ./syntax_xml_generator +CLEANFILES = asm-pic.xml coff-pic.xml diff --git a/src/data/app_data/Makefile.am b/src/data/app_data/Makefile.am new file mode 100644 index 0000000..61959e6 --- /dev/null +++ b/src/data/app_data/Makefile.am @@ -0,0 +1,9 @@ +xdg_apps_DATA = piklab.desktop + +rcdir = $(kde_datadir)/piklab +rc_DATA = piklabui.rc hexeditorpartui.rc + +KDE_ICON = AUTO + +mimedir = $(kde_mimedir)/application +mime_DATA = x-piklab.desktop diff --git a/src/data/app_data/hexeditorpartui.rc b/src/data/app_data/hexeditorpartui.rc new file mode 100644 index 0000000..5471b03 --- /dev/null +++ b/src/data/app_data/hexeditorpartui.rc @@ -0,0 +1,21 @@ + + + + + + &File + + + + + + &Tools + + + + +Main Toolbar + + + + diff --git a/src/data/app_data/hi16-app-piklab.png b/src/data/app_data/hi16-app-piklab.png new file mode 100644 index 0000000..05baea4 Binary files /dev/null and b/src/data/app_data/hi16-app-piklab.png differ diff --git a/src/data/app_data/hi32-app-piklab.png b/src/data/app_data/hi32-app-piklab.png new file mode 100644 index 0000000..586e094 Binary files /dev/null and b/src/data/app_data/hi32-app-piklab.png differ diff --git a/src/data/app_data/hi32-mime-piklab_project.png b/src/data/app_data/hi32-mime-piklab_project.png new file mode 100644 index 0000000..586e094 Binary files /dev/null and b/src/data/app_data/hi32-mime-piklab_project.png differ diff --git a/src/data/app_data/hi64-app-piklab.png b/src/data/app_data/hi64-app-piklab.png new file mode 100644 index 0000000..7b1bf37 Binary files /dev/null and b/src/data/app_data/hi64-app-piklab.png differ diff --git a/src/data/app_data/piklab.desktop b/src/data/app_data/piklab.desktop new file mode 100644 index 0000000..e2f8145 --- /dev/null +++ b/src/data/app_data/piklab.desktop @@ -0,0 +1,13 @@ +[Desktop Entry] +Type=Application +Exec=piklab %U +Icon=piklab.png +X-DocPath=piklab/index.html +Categories=Qt;KDE;Development;IDE;Electronics; +Comment=Integrated development environment for applications based on PIC microcontrollers. +Comment[fr]=Environnement de développement intégré pour applications utilisant des microcontroleurs PIC. +Comment[es]=Entorno integrado de desarrollo de aplicaciones basadas en microcontroladores PIC. +Terminal=false +Name=Piklab +GenericName=IDE +MimeType=text/x-hex;application/x-piklab diff --git a/src/data/app_data/piklabui.rc b/src/data/app_data/piklabui.rc new file mode 100644 index 0000000..b6c4845 --- /dev/null +++ b/src/data/app_data/piklabui.rc @@ -0,0 +1,203 @@ + + + + + + &File + + + + + + + + + + + + + + + + + + + + + + + + &Edit + + + + + + + + + + + + + + &View + + + + + + + + + + + + + + + + + + + &Project + + + + + + + + + + + + + Bu&ild + + + + + + + Pr&ogrammer + + + + + + + + + + + + + + + + + + &Debugger + + + + + + + + + + + + + + + &Tools + + + + + + + + + + + + + + &Settings + + + &Help + + + + + + + + + + + + + +Build Toolbar + + + + + +Programmer Toolbar + + + + + + + + + + + + + + + +Debugger Toolbar + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/data/app_data/x-piklab.desktop b/src/data/app_data/x-piklab.desktop new file mode 100644 index 0000000..de7e510 --- /dev/null +++ b/src/data/app_data/x-piklab.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +Name=Piklab +Comment=Piklab Project File +Comment[es]=Archivo de proyecto de Piklab +Icon=piklab_project +Type=MimeType +MimeType=application/x-piklab +Patterns=*.piklab; diff --git a/src/data/coff-c-pic.xml b/src/data/coff-c-pic.xml new file mode 100644 index 0000000..2090c02 --- /dev/null +++ b/src/data/coff-c-pic.xml @@ -0,0 +1,127 @@ + + + + + + + break + case + continue + default + do + else + enum + extern + for + goto + if + return + sizeof + struct + switch + typedef + union + while + + + auto + char + const + double + float + int + long + register + short + signed + static + unsigned + void + volatile + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/data/hi16-action-piklab_addcurrentfile.png b/src/data/hi16-action-piklab_addcurrentfile.png new file mode 100644 index 0000000..608c532 Binary files /dev/null and b/src/data/hi16-action-piklab_addcurrentfile.png differ diff --git a/src/data/hi16-action-piklab_addfile.png b/src/data/hi16-action-piklab_addfile.png new file mode 100644 index 0000000..1a3cfa0 Binary files /dev/null and b/src/data/hi16-action-piklab_addfile.png differ diff --git a/src/data/hi16-action-piklab_blankcheck.png b/src/data/hi16-action-piklab_blankcheck.png new file mode 100644 index 0000000..c71d4a5 Binary files /dev/null and b/src/data/hi16-action-piklab_blankcheck.png differ diff --git a/src/data/hi16-action-piklab_burnchip.png b/src/data/hi16-action-piklab_burnchip.png new file mode 100644 index 0000000..7ddef9e Binary files /dev/null and b/src/data/hi16-action-piklab_burnchip.png differ diff --git a/src/data/hi16-action-piklab_chip.png b/src/data/hi16-action-piklab_chip.png new file mode 100644 index 0000000..f0e3437 Binary files /dev/null and b/src/data/hi16-action-piklab_chip.png differ diff --git a/src/data/hi16-action-piklab_closeproject.png b/src/data/hi16-action-piklab_closeproject.png new file mode 100644 index 0000000..bdfd82c Binary files /dev/null and b/src/data/hi16-action-piklab_closeproject.png differ diff --git a/src/data/hi16-action-piklab_compile.png b/src/data/hi16-action-piklab_compile.png new file mode 100644 index 0000000..5a5360e Binary files /dev/null and b/src/data/hi16-action-piklab_compile.png differ diff --git a/src/data/hi16-action-piklab_createproject.png b/src/data/hi16-action-piklab_createproject.png new file mode 100644 index 0000000..5de505e Binary files /dev/null and b/src/data/hi16-action-piklab_createproject.png differ diff --git a/src/data/hi16-action-piklab_decompile.png b/src/data/hi16-action-piklab_decompile.png new file mode 100644 index 0000000..3490d6f Binary files /dev/null and b/src/data/hi16-action-piklab_decompile.png differ diff --git a/src/data/hi16-action-piklab_editproject.png b/src/data/hi16-action-piklab_editproject.png new file mode 100644 index 0000000..e8c3d55 Binary files /dev/null and b/src/data/hi16-action-piklab_editproject.png differ diff --git a/src/data/hi16-action-piklab_erasechip.png b/src/data/hi16-action-piklab_erasechip.png new file mode 100644 index 0000000..36077b0 Binary files /dev/null and b/src/data/hi16-action-piklab_erasechip.png differ diff --git a/src/data/hi16-action-piklab_find_next.png b/src/data/hi16-action-piklab_find_next.png new file mode 100644 index 0000000..3eaab85 Binary files /dev/null and b/src/data/hi16-action-piklab_find_next.png differ diff --git a/src/data/hi16-action-piklab_find_previous.png b/src/data/hi16-action-piklab_find_previous.png new file mode 100644 index 0000000..29db6e6 Binary files /dev/null and b/src/data/hi16-action-piklab_find_previous.png differ diff --git a/src/data/hi16-action-piklab_openproject.png b/src/data/hi16-action-piklab_openproject.png new file mode 100644 index 0000000..2da627b Binary files /dev/null and b/src/data/hi16-action-piklab_openproject.png differ diff --git a/src/data/hi16-action-piklab_readchip.png b/src/data/hi16-action-piklab_readchip.png new file mode 100644 index 0000000..b60277e Binary files /dev/null and b/src/data/hi16-action-piklab_readchip.png differ diff --git a/src/data/hi16-action-piklab_verifychip.png b/src/data/hi16-action-piklab_verifychip.png new file mode 100644 index 0000000..023f3b7 Binary files /dev/null and b/src/data/hi16-action-piklab_verifychip.png differ diff --git a/src/data/hi22-action-piklab_addcurrentfile.png b/src/data/hi22-action-piklab_addcurrentfile.png new file mode 100644 index 0000000..4b27037 Binary files /dev/null and b/src/data/hi22-action-piklab_addcurrentfile.png differ diff --git a/src/data/hi22-action-piklab_addfile.png b/src/data/hi22-action-piklab_addfile.png new file mode 100644 index 0000000..f911d65 Binary files /dev/null and b/src/data/hi22-action-piklab_addfile.png differ diff --git a/src/data/hi22-action-piklab_blankcheck.png b/src/data/hi22-action-piklab_blankcheck.png new file mode 100644 index 0000000..4c93c85 Binary files /dev/null and b/src/data/hi22-action-piklab_blankcheck.png differ diff --git a/src/data/hi22-action-piklab_breakpoint_active.png b/src/data/hi22-action-piklab_breakpoint_active.png new file mode 100644 index 0000000..35caf7c Binary files /dev/null and b/src/data/hi22-action-piklab_breakpoint_active.png differ diff --git a/src/data/hi22-action-piklab_breakpoint_disabled.png b/src/data/hi22-action-piklab_breakpoint_disabled.png new file mode 100644 index 0000000..c61f4c5 Binary files /dev/null and b/src/data/hi22-action-piklab_breakpoint_disabled.png differ diff --git a/src/data/hi22-action-piklab_breakpoint_invalid.png b/src/data/hi22-action-piklab_breakpoint_invalid.png new file mode 100644 index 0000000..7c624cc Binary files /dev/null and b/src/data/hi22-action-piklab_breakpoint_invalid.png differ diff --git a/src/data/hi22-action-piklab_breakpoint_reached.png b/src/data/hi22-action-piklab_breakpoint_reached.png new file mode 100644 index 0000000..55255af Binary files /dev/null and b/src/data/hi22-action-piklab_breakpoint_reached.png differ diff --git a/src/data/hi22-action-piklab_burnchip.png b/src/data/hi22-action-piklab_burnchip.png new file mode 100644 index 0000000..8590c71 Binary files /dev/null and b/src/data/hi22-action-piklab_burnchip.png differ diff --git a/src/data/hi22-action-piklab_chip.png b/src/data/hi22-action-piklab_chip.png new file mode 100644 index 0000000..0966442 Binary files /dev/null and b/src/data/hi22-action-piklab_chip.png differ diff --git a/src/data/hi22-action-piklab_closeproject.png b/src/data/hi22-action-piklab_closeproject.png new file mode 100644 index 0000000..4983783 Binary files /dev/null and b/src/data/hi22-action-piklab_closeproject.png differ diff --git a/src/data/hi22-action-piklab_compile.png b/src/data/hi22-action-piklab_compile.png new file mode 100644 index 0000000..7fa7489 Binary files /dev/null and b/src/data/hi22-action-piklab_compile.png differ diff --git a/src/data/hi22-action-piklab_createproject.png b/src/data/hi22-action-piklab_createproject.png new file mode 100644 index 0000000..a8b16dc Binary files /dev/null and b/src/data/hi22-action-piklab_createproject.png differ diff --git a/src/data/hi22-action-piklab_debug_step.png b/src/data/hi22-action-piklab_debug_step.png new file mode 100644 index 0000000..3b7204c Binary files /dev/null and b/src/data/hi22-action-piklab_debug_step.png differ diff --git a/src/data/hi22-action-piklab_debug_stepin.png b/src/data/hi22-action-piklab_debug_stepin.png new file mode 100644 index 0000000..6a09a4c Binary files /dev/null and b/src/data/hi22-action-piklab_debug_stepin.png differ diff --git a/src/data/hi22-action-piklab_debug_stepout.png b/src/data/hi22-action-piklab_debug_stepout.png new file mode 100644 index 0000000..405f9a9 Binary files /dev/null and b/src/data/hi22-action-piklab_debug_stepout.png differ diff --git a/src/data/hi22-action-piklab_debug_stepover.png b/src/data/hi22-action-piklab_debug_stepover.png new file mode 100644 index 0000000..cb512cb Binary files /dev/null and b/src/data/hi22-action-piklab_debug_stepover.png differ diff --git a/src/data/hi22-action-piklab_debughalt.png b/src/data/hi22-action-piklab_debughalt.png new file mode 100644 index 0000000..69dfb9e Binary files /dev/null and b/src/data/hi22-action-piklab_debughalt.png differ diff --git a/src/data/hi22-action-piklab_decompile.png b/src/data/hi22-action-piklab_decompile.png new file mode 100644 index 0000000..71eeff8 Binary files /dev/null and b/src/data/hi22-action-piklab_decompile.png differ diff --git a/src/data/hi22-action-piklab_editproject.png b/src/data/hi22-action-piklab_editproject.png new file mode 100644 index 0000000..259c08e Binary files /dev/null and b/src/data/hi22-action-piklab_editproject.png differ diff --git a/src/data/hi22-action-piklab_erasechip.png b/src/data/hi22-action-piklab_erasechip.png new file mode 100644 index 0000000..a13f057 Binary files /dev/null and b/src/data/hi22-action-piklab_erasechip.png differ diff --git a/src/data/hi22-action-piklab_find_next.png b/src/data/hi22-action-piklab_find_next.png new file mode 100644 index 0000000..c047271 Binary files /dev/null and b/src/data/hi22-action-piklab_find_next.png differ diff --git a/src/data/hi22-action-piklab_find_previous.png b/src/data/hi22-action-piklab_find_previous.png new file mode 100644 index 0000000..99cea7c Binary files /dev/null and b/src/data/hi22-action-piklab_find_previous.png differ diff --git a/src/data/hi22-action-piklab_openproject.png b/src/data/hi22-action-piklab_openproject.png new file mode 100644 index 0000000..2d97fd1 Binary files /dev/null and b/src/data/hi22-action-piklab_openproject.png differ diff --git a/src/data/hi22-action-piklab_power.png b/src/data/hi22-action-piklab_power.png new file mode 100644 index 0000000..b479583 Binary files /dev/null and b/src/data/hi22-action-piklab_power.png differ diff --git a/src/data/hi22-action-piklab_program_counter.png b/src/data/hi22-action-piklab_program_counter.png new file mode 100644 index 0000000..529281a Binary files /dev/null and b/src/data/hi22-action-piklab_program_counter.png differ diff --git a/src/data/hi22-action-piklab_program_counter_disabled.png b/src/data/hi22-action-piklab_program_counter_disabled.png new file mode 100644 index 0000000..617c4ae Binary files /dev/null and b/src/data/hi22-action-piklab_program_counter_disabled.png differ diff --git a/src/data/hi22-action-piklab_readchip.png b/src/data/hi22-action-piklab_readchip.png new file mode 100644 index 0000000..1df48d0 Binary files /dev/null and b/src/data/hi22-action-piklab_readchip.png differ diff --git a/src/data/hi22-action-piklab_restart.png b/src/data/hi22-action-piklab_restart.png new file mode 100644 index 0000000..a8dad33 Binary files /dev/null and b/src/data/hi22-action-piklab_restart.png differ diff --git a/src/data/hi22-action-piklab_run.png b/src/data/hi22-action-piklab_run.png new file mode 100644 index 0000000..fc861fb Binary files /dev/null and b/src/data/hi22-action-piklab_run.png differ diff --git a/src/data/hi22-action-piklab_stop.png b/src/data/hi22-action-piklab_stop.png new file mode 100644 index 0000000..c2b68f7 Binary files /dev/null and b/src/data/hi22-action-piklab_stop.png differ diff --git a/src/data/hi22-action-piklab_verifychip.png b/src/data/hi22-action-piklab_verifychip.png new file mode 100644 index 0000000..dbd11fa Binary files /dev/null and b/src/data/hi22-action-piklab_verifychip.png differ diff --git a/src/data/hi32-action-piklab_config_assembler.png b/src/data/hi32-action-piklab_config_assembler.png new file mode 100644 index 0000000..198b8d8 Binary files /dev/null and b/src/data/hi32-action-piklab_config_assembler.png differ diff --git a/src/data/hi32-action-piklab_config_disassembler.png b/src/data/hi32-action-piklab_config_disassembler.png new file mode 100644 index 0000000..6107b62 Binary files /dev/null and b/src/data/hi32-action-piklab_config_disassembler.png differ diff --git a/src/data/hi32-action-piklab_config_programmer.png b/src/data/hi32-action-piklab_config_programmer.png new file mode 100644 index 0000000..586e094 Binary files /dev/null and b/src/data/hi32-action-piklab_config_programmer.png differ diff --git a/src/data/jal-pic.xml b/src/data/jal-pic.xml new file mode 100644 index 0000000..272d957 --- /dev/null +++ b/src/data/jal-pic.xml @@ -0,0 +1,104 @@ + + + + + + + + function + procedure + var + at + const + volatile + return + asm + assembler + + + + if + then + else + elsif + forever + end + while + loop + for + + + + bit + byte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/data/likeback/Makefile.am b/src/data/likeback/Makefile.am new file mode 100644 index 0000000..1b17603 --- /dev/null +++ b/src/data/likeback/Makefile.am @@ -0,0 +1,2 @@ +piklabdir = $(kde_datadir)/piklab/icons +piklab_ICON = AUTO \ No newline at end of file diff --git a/src/data/likeback/cr16-action-likeback_dislike.png b/src/data/likeback/cr16-action-likeback_dislike.png new file mode 100644 index 0000000..4f0f8ee Binary files /dev/null and b/src/data/likeback/cr16-action-likeback_dislike.png differ diff --git a/src/data/likeback/cr16-action-likeback_like.png b/src/data/likeback/cr16-action-likeback_like.png new file mode 100644 index 0000000..bf6941d Binary files /dev/null and b/src/data/likeback/cr16-action-likeback_like.png differ diff --git a/src/data/likeback/hi16-action-likeback_bug.png b/src/data/likeback/hi16-action-likeback_bug.png new file mode 100644 index 0000000..4d7f5a6 Binary files /dev/null and b/src/data/likeback/hi16-action-likeback_bug.png differ diff --git a/src/data/syntax_xml_generator.cpp b/src/data/syntax_xml_generator.cpp new file mode 100644 index 0000000..9f3553e --- /dev/null +++ b/src/data/syntax_xml_generator.cpp @@ -0,0 +1,231 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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 generate xml files for kate highlighting +// the original syntax file was created by Alain Gibaud + +#include +#include + +const char * const DIRECTIVES[] = { +"__badram", "__config", "__idlocs", "__maxram", +"bankisel", "banksel", "cblock", "code", "cblock", "constant", "da", "data", "db", +"de", "dt", "dw", "endm", "endc", "endw", "equ", "error", "errorlevel", "extern", +"exitm", "expand", "fill", "global", "idata", "list", "local", "macro", "messg", +"noexpand", "nolist", "org", "page", "processor", "pagesel", "radix", "res", "set", +"space", "subtitle", "title", "udata", "udata_acs", "udata_ovr", "udata_shr", +"variable", "end", 0 +}; +const char * const CONDITIONNALS[] = { +"if", "else", "ifdef", "ifndef", "endif", "while", "include", "endw", "{", "}", 0 +}; +const char * const GPASM_MACROS[] = { +"addcf", "b", "bc", "bz", "bnc", "bnz", "clrc", "clrz", "setc", "setz", "movfw", +"negf", "skpc", "skpz", "skpnc", "skpnz", "subcf", "tstf", 0 +}; +const char * const CPIK_MACROS[] = { +"IBZ", "IBNZ", "IBRA", "ICALL", 0 +}; +const char * const SFRS[] = { // #### should be extracted from dev files... +"TOSU", "TOSH", "TOSL", "STKPTR", "PCLATU", "PCLATH", "PCL", "TBLPTRU", "TBLPTRH", +"TBLPTRL", "TABLAT", "PRODH", "PRODL", "INTCON", "INTCON2", "INTCON3", "INDF0", +"POSTINC0", "POSTDEC0", "PREINC0", "PLUSW0", "FSR0H", "FSR0L", "WREG", "INDF1", +"POSTINC1", "POSTDEC1", "PREINC1", "PLUSW1", "FSR1H", "FSR1L", "BSR", "INDF2", +"POSTINC2", "POSTDEC2", "PREINC2", "PLUSW2", "FSR2H", "FSR2L", "STATUS", "TMR0H", +"TMR0L", "T0CON", "OSCCON", "LVDCON", "WDTCON", "RCON", "TMR1H", "TMR1L","T1CON", +"TMR2", "PR2", "T2CON", "SSPBUF", "SSPADD", "SSPSTAT", "SSPCON1", "SSPCON2", "ADRESH", +"ADRESL", "ADCON0", "ADCON1", "ADCON2", "CCPR1H", "CCPR1L", "CCP1CON", "CCPR2H", +"CCPR2L", "CCP2CON", "PWM1CON", "ECCPAS", "CVRCON", "CMCON", "TMR3H", "TMR3L", +"T3CON", "SPBRG", "RCREG", "TXREG", "TXSTA", "RCSTA", "EEADR", "EEDATA", "EECON2", +"EECON1", "IPR2", "PIR2", "PIE2", "IPR1", "PIR1", "PIE1", "OSCTUNE", "TRISE", +"TRISD", "TRISC", "TRISB", "TRISA", "LATE", "LATD", "LATC", "LATB", "LATA", +"PORTE", "PORTD", "PORTC", "PORTB", "PORTA", "TMR0", "TMR1", "OPTION_REG", 0 +}; +const char * const INSTRUCTIONS[] = { +"addlw", "addwf", "addwfc", "andlw", "andwf", "bcf", "bc", "bn", "bnc", "bnn", "bnov", +"bnz", "bz", "bov", "bra", "bsf", "btfsc", "btg", "btfss", "call", "clrf", "clrw", +"clrwdt", "comf", "cpfseq", "cpfsgt", "cpfslt", "daw", "decf", "decfsz", "dcfsnz", +"goto", "incf", "incfsz", "infsnz", "iorlw", "iorwf", "lfsr", "movf", "movff", +"movlb", "movlw", "movwf", "mullw", "mulwf", "negf", "nop", "option", "pop", "push", +"rcall", "reset", "retfie", "retlw", "rlcf", "rlncf", "rrcf", "rrncf", "return", "rlf", +"rrf", "setf", "sleep", "sublw", "subfwb", "subwf", "subwfb", "swapf", "tstfsz", +"tris", "tblrd", "tblwt", "xorlw", "xorwf", 0 +}; + +QTextStream *initFile(QFile &file) +{ + if ( !file.open(IO_WriteOnly) ) qFatal("Cannot create \"%s\".", file.name().latin1()); + QTextStream *s = new QTextStream(&file); + (*s) << "" << endl; + (*s) << "" << endl; + (*s) << "" << endl; + return s; +} + +void addList(QTextStream &s, const QString &name, const char * const *items, bool upper) +{ + s << " " << endl; + for (uint i=0; items[i]; i++) { + s << " " << items[i] << ""; + if (upper) s << "" << QString(items[i]).upper() << ""; + s << endl; + }; + s <<" " << endl; +} + +void addCommon(QTextStream &s) +{ + addList(s, "instructions", INSTRUCTIONS, true); + s << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << endl; + s << " " << endl; + s << " " << endl; +} + +void addAsmContexts(QTextStream &s) +{ + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; +} + +void endFile(QTextStream &s) +{ + s << " " << endl; + s << "" << endl; + s << endl; + s << "" << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << " " << endl; + s << "" << endl; + s << endl; + s << "" << endl; +} + +int main(int, char **) +{ + QFile afile("asm-pic.xml"); + QTextStream *s = initFile(afile); + (*s) << "" << endl; + (*s) << endl; + (*s) << "" << endl; + addList(*s, "directives", DIRECTIVES, true); + addList(*s, "conditionnal", CONDITIONNALS, false); + addList(*s, "gpasm_macro", GPASM_MACROS, false); + addList(*s, "cpik_macro", CPIK_MACROS, false); + addList(*s, "sfrs", SFRS, false); + addCommon(*s); + addAsmContexts(*s); + endFile(*s); + + QFile cfile("coff-pic.xml"); + s = initFile(cfile); + (*s) << "" << endl; + (*s) << endl; + (*s) << "" << endl; + addCommon(*s); + (*s) << " " << endl; + (*s) << " " << endl; + (*s) << " " << endl; + (*s) << " " << endl; + (*s) << " " << endl; + (*s) << " " << endl; + (*s) << " " << endl; + (*s) << " " << endl; + (*s) << " " << endl; + (*s) << " " << endl; + (*s) << " " << endl; + (*s) << " " << endl; + (*s) << " " << endl; + (*s) << " " << endl; + (*s) << " " << endl; + (*s) << " " << endl; + (*s) << " " << endl; + (*s) << " " << endl; + (*s) << " " << endl; + (*s) << " " << endl; + (*s) << " " << endl; + (*s) << " " << endl; + (*s) << " " << endl; + (*s) << " " << endl; + (*s) << " " << endl; + (*s) << " " << endl; + (*s) << " " << endl; + endFile(*s); +} diff --git a/src/data/xpms/csourcefile.xpm b/src/data/xpms/csourcefile.xpm new file mode 100644 index 0000000..93fdf98 --- /dev/null +++ b/src/data/xpms/csourcefile.xpm @@ -0,0 +1,24 @@ +/* XPM */ +static const char * csourcefile_xpm[] = { +"16 16 5 1", +" c None", +". c #000000", +"+ c #2CF416", +"@ c #498942", +"# c #56CC49", +" ", +" .. ", +" .++.. ", +" .+++++. ", +" .+++++@. ", +" .. .##++@@. ", +" .++..###@@@. ", +" .+++++.##@@. ", +" .+++++@..#@. ", +" .##++@@. .. ", +" .###@@@. ", +" .###@@. ", +" ..#@. ", +" .. ", +" ", +" "}; diff --git a/src/data/xpms/includefile.xpm b/src/data/xpms/includefile.xpm new file mode 100644 index 0000000..9ac9cbc --- /dev/null +++ b/src/data/xpms/includefile.xpm @@ -0,0 +1,25 @@ +/* XPM */ +static const char *includefile_xpm[]={ +"16 16 6 1", +". c None", +"# c #000000", +"b c #e0bc38", +"c c #f0dc5c", +"a c #fcfc80", +"d c #ff0000", +"................", +"..........##....", +".........#aa##..", +"........#aaaaa#.", +".......#aaaaab#.", +"....##.#ccaabb#.", +"...#aa##cccbbb#.", +"..#aaaaa#ccbb#..", +".#aaaaab##cb#...", +".#ccaabb#.##....", +".#cccbbb#.......", +".#cccbb#...ddd..", +"..##cb#...ddddd.", +"....##....ddddd.", +"..........ddddd.", +"...........ddd.."}; diff --git a/src/data/xpms/objectfile.xpm b/src/data/xpms/objectfile.xpm new file mode 100644 index 0000000..5bef5d2 --- /dev/null +++ b/src/data/xpms/objectfile.xpm @@ -0,0 +1,24 @@ +/* XPM */ +static const char * objectfile_xpm[] = { +"16 16 5 1", +" c None", +". c #000000", +"+ c #ECDEEF", +"@ c #985EA5", +"# c #DCBEE2", +" ", +" .. ", +" .++.. ", +" .+++++. ", +" .+++++@. ", +" .. .##++@@. ", +" .++..###@@@. ", +" .+++++.##@@. ", +" .+++++@..#@. ", +" .##++@@. .. ", +" .###@@@. ", +" .###@@. ", +" ..#@. ", +" .. ", +" ", +" "}; diff --git a/src/data/xpms/project.xpm b/src/data/xpms/project.xpm new file mode 100644 index 0000000..28a6397 --- /dev/null +++ b/src/data/xpms/project.xpm @@ -0,0 +1,29 @@ +/* XPM */ +static const char * project_xpm[] = { +"16 16 10 1", +" c None", +". c #000000", +"+ c #A4E8FC", +"@ c #24D0FC", +"# c #001CD0", +"$ c #0080E8", +"% c #C0FFFF", +"& c #00FFFF", +"* c #008080", +"= c #00C0C0", +" .. ", +" .++.. ", +" .+++@@. ", +" .@@@@@#... ", +" .$$@@##.%%.. ", +" .$$$##.%%%&&. ", +" .$$$#.&&&&&*. ", +" ...#.==&&**. ", +" .++..===***. ", +" .+++@@.==**. ", +" .@@@@@#..=*. ", +" .$$@@##. .. ", +" .$$$###. ", +" .$$$##. ", +" ..$#. ", +" .. "}; diff --git a/src/data/xpms/sourcefile.xpm b/src/data/xpms/sourcefile.xpm new file mode 100644 index 0000000..3cb6c6a --- /dev/null +++ b/src/data/xpms/sourcefile.xpm @@ -0,0 +1,24 @@ +/* XPM */ +static const char * sourcefile_xpm[] = { +"16 16 5 1", +" c None", +". c #000000", +"+ c #FCFC80", +"@ c #E0BC38", +"# c #F0DC5C", +" ", +" .. ", +" .++.. ", +" .+++++. ", +" .+++++@. ", +" .. .##++@@. ", +" .++..###@@@. ", +" .+++++.##@@. ", +" .+++++@..#@. ", +" .##++@@. .. ", +" .###@@@. ", +" .###@@. ", +" ..#@. ", +" .. ", +" ", +" "}; diff --git a/src/devices/Makefile.am b/src/devices/Makefile.am new file mode 100644 index 0000000..00ec7c1 --- /dev/null +++ b/src/devices/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = base gui pic mem24 list diff --git a/src/devices/base/Makefile.am b/src/devices/base/Makefile.am new file mode 100644 index 0000000..836da68 --- /dev/null +++ b/src/devices/base/Makefile.am @@ -0,0 +1,9 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libdevicebase.la +libdevicebase_la_LDFLAGS = $(all_libraries) +libdevicebase_la_SOURCES = generic_device.cpp hex_buffer.cpp generic_memory.cpp \ + register.cpp device_group.cpp + + diff --git a/src/devices/base/base.pro b/src/devices/base/base.pro new file mode 100644 index 0000000..f74efc6 --- /dev/null +++ b/src/devices/base/base.pro @@ -0,0 +1,6 @@ +STOPDIR = ../../.. +include($${STOPDIR}/lib.pro) + +TARGET = devicebase +HEADERS += generic_device.h hex_buffer.h generic_memory.h device_group.h register.h +SOURCES += generic_device.cpp hex_buffer.cpp generic_memory.cpp register.cpp diff --git a/src/devices/base/device_group.cpp b/src/devices/base/device_group.cpp new file mode 100644 index 0000000..df230d1 --- /dev/null +++ b/src/devices/base/device_group.cpp @@ -0,0 +1,362 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "device_group.h" + +#if !defined(NO_KDE) +# include +# include + +QColor Device::statusColor(Status status) +{ + switch (status.type()) { + case Status::Future: return Qt::blue; + case Status::InProduction: return Qt::green; + case Status::Mature: + case Status::NotRecommended: return QColor("orange"); + case Status::EOL: return Qt::red; + case Status::Unknown: + case Status::Nb_Types: break; + } + return Qt::black; +} + +QString coloredString(const QString &text, QColor color) +{ + return QString("" + text + ""; +} + +QString supportedString(bool supported) +{ + return coloredString(supported ? i18n("Supported") : i18n("Unsupported"), + supported ? Qt::green : Qt::red); +} + +class Tick { +public: + Tick() {} + Tick(double value, double oValue) { + s = KGlobal::locale()->formatNumber(value, 1); + min = oValue; + } + QString s; + double min; +}; + +class TickMap : public QMap +{ +public: + TickMap() {} + void add(double value, double oValue) { + insert(value, Tick(value, oValue), false); + (*this)[value].min = QMIN((*this)[value].min, oValue); + } +}; + +QPixmap drawGraph(const QValueVector &boxes) +{ + const uint w = 300, h = 200; + QPixmap pixmap(w, h); + pixmap.fill(Qt::white); + QPainter p(&pixmap); + QFontMetrics f(p.font()); + TickMap xTicks, yTicks; + xTicks.add(0.0, 0.0); + yTicks.add(0.0, 0.0); + for (uint i=0; i &boxes) +{ + uint sp = 10; + QPixmap graph = drawGraph(boxes); + QPainter p; + QFontMetrics f(p.font()); + QPixmap pixmap(graph.width() + sp + f.width(xLabel), graph.height() + sp + f.lineSpacing()); + pixmap.fill(Qt::white); + copyBlt(&pixmap, 0, f.lineSpacing() + sp, &graph, 0, 0, graph.width(), graph.height()); + p.begin(&pixmap); + p.setPen(Qt::black); + p.drawText(0, f.lineSpacing(), yLabel); + p.drawText(pixmap.width()-1-f.width(xLabel), pixmap.height()-1, xLabel); + return pixmap; +} + +const Device::Package *Device::barPackage(const char *name, const Device::Data &data) +{ + for (uint i=0; i%2").arg(href).arg(data.alternatives()[i].upper()); + } + } + doc += htmlTableRow(i18n("Alternatives"), s); + } + doc += documentHtml; + doc += ""; + + doc += "
"; + doc += ""; + doc += data.group().informationHtml(data); + QString s; + for (uint i=0; i
"; + for (uint k=0; ktypes.count(); k++) { + if ( k!=0 ) doc += " "; + doc += i18n(Package::TYPE_DATA[package->types[k]].label); + doc += "(" + QString::number(package->pins.count()) + ")"; + } + doc += "
"; + QString label = data.name() + "_pins_graph.png"; + doc += ""; + if (msf) msf->setPixmap(label, pix); + doc += "
"; + } + return doc; +} + +QString Device::htmlVoltageFrequencyGraphs(const Device::Data &data, const QString &imagePrefix, QMimeSourceFactory *msf) +{ + QString doc; + FOR_EACH(Special, special) { + for (uint k=0; k"; + QString label = data.name() + "_" + data.fname(special) + "_" + + fr.operatingCondition.key() + ".png"; + doc += ""; + if (msf) msf->setPixmap(label, Device::vddGraph(i18n("F (MHz)"), i18n("Vdd (V)"), fr.vdds)); + } + } + return doc; +} + +QPixmap Device::memoryGraph(const QValueList &r) +{ + QValueList ranges = r; + QPixmap pixmap; + QPainter p; + QFontMetrics fm(p.font()); + // order + qHeapSort(ranges); + // add empty ranges + QValueList::iterator it; + for (it=ranges.begin(); it!=ranges.end(); ) { + QValueList::iterator prev = it; + ++it; + if ( it==ranges.end() ) break; + if ( (*prev).endAddress+1==(*it).startAddress ) continue; + MemoryGraphData data; + data.startAddress = (*prev).endAddress + 1; + data.endAddress = (*it).startAddress-1; + ranges.insert(it, data); + } + // compute widths and total height + int theight = fm.ascent() + (fm.ascent()%2==0 ? 1 : 0); + int hspacing = 5; + int height = 1; + int w1 = 0, w2 = 0; + for (it=ranges.begin(); it!=ranges.end(); ++it) { + w1 = QMAX(w1, fm.width((*it).start)); + w1 = QMAX(w1, fm.width((*it).end)); + w2 = QMAX(w2, fm.width((*it).label)); + (*it).height = 2*hspacing + theight; + if ( (*it).startAddress!=(*it).endAddress ) (*it).height += 2*theight; + height += (*it).height; + } + int wspacing = 4; + int width = wspacing + w1 + wspacing + wspacing + w2; + pixmap.resize(width, height); + pixmap.fill(Qt::white); + p.begin(&pixmap); + int h = 0; + // draw ranges + for (it=ranges.begin(); it!=ranges.end(); ++it) { + p.setPen(QPen(Qt::black, 1, Qt::DotLine)); + p.drawLine(0,h, width-1,h); + p.setPen(QPen(Qt::black, 1)); + p.setBrush((*it).label.isEmpty() ? Qt::gray : Qt::white); + p.drawRect(0,h, wspacing+w1+wspacing,(*it).height+1); + int hmid = h+(*it).height/2+theight/2; + p.drawText(wspacing+w1+wspacing+wspacing,hmid, (*it).label); + if ( (*it).startAddress==(*it).endAddress ) p.drawText(wspacing,hmid, (*it).start); + else { + p.drawText(wspacing,h+theight, (*it).start); + p.drawText(wspacing,h+(*it).height-3, (*it).end); + } + h += (*it).height; + p.setPen(QPen(Qt::black, 1, Qt::DotLine)); + p.drawLine(0,h, width-1,h); + } + p.end(); + return pixmap; +} + +#endif diff --git a/src/devices/base/device_group.h b/src/devices/base/device_group.h new file mode 100644 index 0000000..087ca99 --- /dev/null +++ b/src/devices/base/device_group.h @@ -0,0 +1,87 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef DEVICE_GROUP_H +#define DEVICE_GROUP_H + +#if !defined(NO_KDE) +# include +#endif + +#include "generic_device.h" +#include "common/common/group.h" +#include "common/common/streamer.h" +namespace Debugger { class DeviceSpecific; class Base; } + +namespace Device +{ +class Memory; + +//---------------------------------------------------------------------------- +class MemoryRange { +public: + MemoryRange() {} + virtual ~MemoryRange() {} + virtual bool all() const { return true; } +}; + +//---------------------------------------------------------------------------- +class GroupBase : public ::Group::Base +{ +public: + virtual Memory *createMemory(const Device::Data &data) const = 0; + virtual QString informationHtml(const Device::Data &data) const = 0; +#if !defined(NO_KDE) + virtual QPixmap memoryGraph(const Device::Data &data) const = 0; +#endif + +protected: + virtual void addDevice(const QString &name, const Device::Data *data, ::Group::Support support) { + const_cast(data)->_group = this; + ::Group::Base::addDevice(name, data, support); + } +}; + +template +class Group : public GroupBase, public DataStreamer +{ +protected: + virtual void initSupported() { + QValueList list = fromCppString(dataStream(), dataSize()); + for (uint i=0; iname(), list[i], ::Group::Support::Tested); + } + virtual uint dataSize() const = 0; + virtual const char *dataStream() const = 0; +}; + +//---------------------------------------------------------------------------- +#if !defined(NO_KDE) +extern QColor statusColor(Status status); +extern QPixmap vddGraph(const QString &xLabel, const QString &yLabel, const QValueVector &boxes); +extern const Package *barPackage(const char *name, const Data &data); +extern QPixmap pinsGraph(const Package &package); + +extern QString htmlInfo(const Data &data, const QString &deviceHref, const QString &documentHtml); +extern QString htmlPinDiagrams(const Device::Data &data, const QString &imagePrefix, QMimeSourceFactory *msf); +extern QString htmlVoltageFrequencyGraphs(const Device::Data &data, const QString &imagePrefix, QMimeSourceFactory *msf); + +class MemoryGraphData +{ +public: + Address startAddress, endAddress; + QString start, end, label; + int height; + bool operator <(const MemoryGraphData &data) const { return ( startAddress < data.startAddress ); } +}; +extern QPixmap memoryGraph(const QValueList &ranges); + +#endif + +} // namespace + +#endif diff --git a/src/devices/base/generic_device.cpp b/src/devices/base/generic_device.cpp new file mode 100644 index 0000000..bf69dce --- /dev/null +++ b/src/devices/base/generic_device.cpp @@ -0,0 +1,216 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "generic_device.h" + +#include "common/global/global.h" +#include "device_group.h" +#include "register.h" + +//----------------------------------------------------------------------------- +const Device::Status::Data Device::Status::DATA[Nb_Types] = { + { "IP", I18N_NOOP("In Production") }, + { "Future", I18N_NOOP("Future Product") }, + { "NR", I18N_NOOP("Not Recommended for New Design") }, + { "EOL", I18N_NOOP("End Of Life" ) }, + { "?", I18N_NOOP("Unknown") }, + { "Mature", I18N_NOOP("Mature") } +}; + +const Device::MemoryTechnology::Data Device::MemoryTechnology::DATA[Nb_Types] = { + { "FLASH", I18N_NOOP("Flash") }, + { "EPROM", I18N_NOOP("EPROM (OTP)") }, + { "ROM", I18N_NOOP("ROM") }, + { "ROMLESS", I18N_NOOP("ROM-less") } +}; + +const Device::OperatingCondition::Data Device::OperatingCondition::DATA[Nb_Types] = { + { "commercial", I18N_NOOP("Commercial") }, + { "industrial", I18N_NOOP("Industrial") }, + { "extended", I18N_NOOP("Extended") } +}; + +const Device::Special::Data Device::Special::DATA[Nb_Types] = { + { "", I18N_NOOP("Normal") }, + { "low_power", I18N_NOOP("Low Power") }, + { "low_voltage", I18N_NOOP("Low Voltage") }, + { "high_voltage", I18N_NOOP("High Voltage") } +}; + +const Device::Package::TypeData Device::Package::TYPE_DATA[] = { + { "pdip", I18N_NOOP("PDIP"), Bar, { 8, 14, 18, 20, 28, 40, 0, 0, 0 } }, + { "sdip", I18N_NOOP("SDIP"), Bar, { 0, 0, 0, 0, 28, 0, 0, 0, 0 } }, // skinny + { "spdip", I18N_NOOP("SPDIP"), Bar, { 0, 0, 0, 0, 28, 0, 64, 0, 0 } }, // shrink + { "sot23", I18N_NOOP("SOT-23"), Bar, { 5, 6, 0, 0, 0, 0, 0, 0, 0 } }, + { "msop", I18N_NOOP("MSOP"), Bar, { 8, 0, 0, 0, 0, 0, 0, 0, 0 } }, + { "ssop", I18N_NOOP("SSOP"), Bar, { 0, 0, 0, 20, 28, 0, 0, 0, 0 } }, + { "tssop", I18N_NOOP("TSSOP"), Bar, { 8, 14, 0, 0, 0, 0, 0, 0, 0 } }, + { "soic", I18N_NOOP("SOIC"), Bar, { 8, 14, 18, 20, 28, 0, 0, 0, 0 } }, + { "tqfp", I18N_NOOP("TQFP"), Square, { 0, 0, 0, 0, 0, 44, 64, 80, 100 } }, + { "mqfp", I18N_NOOP("MQFP"), Square, { 0, 0, 0, 0, 0, 44, 0, 0, 0 } }, + { "dfns", I18N_NOOP("DFN-S"), Bar, { 8, 0, 0, 0, 0, 0, 0, 0, 0 } }, + { "qfn", I18N_NOOP("QFN"), Square, { 0, 16, 0, 20, 28, 44, 0, 0, 0 } }, + { "qfns", I18N_NOOP("QFN-S"), Bar, { 0, 0, 0, 0, 28, 0, 0, 0, 0 } }, + { "plcc", I18N_NOOP("PLCC"), Square, { 0, 0, 0, 0, 0, 44, 68, 84, 0 } }, + { "mlf", I18N_NOOP("MLF"), Square, { 0, 0, 0, 0, 28, 0, 0, 0, 0 } }, + { "dfn", I18N_NOOP("DFN"), Bar, { 8, 0, 0, 0, 0, 0, 0, 0, 0 } }, + { 0, 0, Square, { 0, 0, 0, 0, 0, 0, 0, 0, 0 } } +}; + +//----------------------------------------------------------------------------- +double Device::FrequencyRange::vddMin() const +{ + double vdd = 0.0; + for (uint i=0; i=-1 ); + Array array(s==-1 ? size()-index : s); + for (uint i=0; i>(QDataStream &s, RangeBox::Value &rbv) +{ + s >> rbv.x >> rbv.yMin >> rbv.yMax; + return s; +} + +QDataStream &Device::operator <<(QDataStream &s, const RangeBox &rb) +{ + s << rb.start << rb.end << rb.osc << rb.mode << rb.special; + return s; +} +QDataStream &Device::operator >>(QDataStream &s, RangeBox &rb) +{ + s >> rb.start >> rb.end >> rb.osc >> rb.mode >> rb.special; + return s; +} + +QDataStream &Device::operator <<(QDataStream &s, const FrequencyRange &frange) +{ + s << frange.operatingCondition << frange.special << frange.vdds; + return s; +} +QDataStream &Device::operator >>(QDataStream &s, FrequencyRange &frange) +{ + s >> frange.operatingCondition >> frange.special >> frange.vdds; + return s; +} + +QDataStream &Device::operator <<(QDataStream &s, const Package &package) +{ + s << package.types << package.pins; + return s; +} +QDataStream &Device::operator >>(QDataStream &s, Package &package) +{ + s >> package.types >> package.pins; + return s; +} + +QDataStream &Device::operator <<(QDataStream &s, const Documents &documents) +{ + s << documents.webpage << documents.datasheet << documents.progsheet << documents.erratas; + return s; +} +QDataStream &Device::operator >>(QDataStream &s, Documents &documents) +{ + s >> documents.webpage >> documents.datasheet >> documents.progsheet >> documents.erratas; + return s; +} + +QDataStream &Device::operator <<(QDataStream &s, const Data &data) +{ + s << data._name << data._documents << data._alternatives << data._status + << data._frequencyRanges << data._memoryTechnology + << data._packages; + return s; +} +QDataStream &Device::operator >>(QDataStream &s, Data &data) +{ + s >> data._name >> data._documents >> data._alternatives >> data._status + >> data._frequencyRanges >> data._memoryTechnology + >> data._packages; + return s; +} diff --git a/src/devices/base/generic_device.h b/src/devices/base/generic_device.h new file mode 100644 index 0000000..e3cbec9 --- /dev/null +++ b/src/devices/base/generic_device.h @@ -0,0 +1,171 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef GENERIC_DEVICE_H +#define GENERIC_DEVICE_H + +#include + +#include "common/common/misc.h" +#include "common/common/bitvalue.h" +#include "common/common/key_enum.h" +#include "common/global/global.h" + +namespace Device +{ +//---------------------------------------------------------------------------- +BEGIN_DECLARE_ENUM(Status) + InProduction = 0, Future, NotRecommended, EOL, Unknown, Mature +END_DECLARE_ENUM_STD(Status) + +BEGIN_DECLARE_ENUM(MemoryTechnology) + Flash = 0, Eprom, Rom, Romless +END_DECLARE_ENUM_STD(MemoryTechnology) + +class RangeBox { +public: + struct Value { double x, yMin, yMax; }; + Value start, end; + QString osc, mode, special; + double yMin() const { return qMin(start.yMin, end.yMin); } + double yMax() const { return qMax(start.yMax, end.yMax); } +}; + +BEGIN_DECLARE_ENUM(OperatingCondition) + Commercial = 0, Industrial, Extended +END_DECLARE_ENUM_STD(OperatingCondition) + +BEGIN_DECLARE_ENUM(Special) + Normal = 0, LowPower, LowVoltage, HighVoltage +END_DECLARE_ENUM_STD(Special) + +class FrequencyRange { +public: + OperatingCondition operatingCondition; + Special special; + QValueVector vdds; + double vddMin() const; + double vddMax() const; +}; + +class IdData { +public: + BitValue revision, minorRevision, process; + Special special; +}; + +class Package +{ +public: + QValueVector types; + QValueVector pins; + +public: + enum Shape { Bar, Square }; + enum { MAX_NB = 9 }; + struct TypeData { + const char *name, *label; + Shape shape; + uint nbPins[MAX_NB]; + }; + static const TypeData TYPE_DATA[]; +}; + +class Documents +{ +public: + QString webpage, datasheet, progsheet; + QStringList erratas; +}; + +//---------------------------------------------------------------------------- +class XmlToDataBase; +class GroupBase; +class RegistersData; + +//---------------------------------------------------------------------------- +// we don't want implicit sharing +class Array +{ +public: + Array(uint size = 0) : _data(size) {} + Array(const Array &array); + Array &operator =(const Array &); + Array &operator +=(const Array &a); + void append(uint v); + Array mid(uint index, int size = -1) const; + void resize(uint s) { _data.resize(s); } + uint size() const { return _data.size(); } + uint count() const { return _data.size(); } + BitValue operator [](uint i) const { return _data[i]; } + BitValue &operator [](uint i) { return _data[i]; } + bool operator ==(const Array &array) const { return _data==array._data; } + bool operator !=(const Array &array) const { return _data!=array._data; } + +private: + QMemArray _data; +}; + +//---------------------------------------------------------------------------- +class Data +{ +public: + Data(RegistersData *rdata) : _group(0), _registersData(rdata) {} + virtual ~Data(); + const GroupBase &group() const { return *_group; } + virtual QString name() const { return _name; } + virtual QString fname(Special) const { return _name; } + virtual QString listViewGroup() const = 0; + Status status() const { return _status; } + const Documents &documents() const { return _documents; } + const QStringList &alternatives() const { return _alternatives; } + MemoryTechnology memoryTechnology() const { return _memoryTechnology; } + virtual bool matchId(BitValue rawId, IdData &idata) const = 0; + const QValueVector &frequencyRanges() const { return _frequencyRanges; } + double vddMin() const; + double vddMax() const; + virtual uint nbBitsAddress() const = 0; + uint nbBytesAddress() const { return nbBitsAddress()/8 + (nbBitsAddress()%8 ? 1 : 0); } + uint nbCharsAddress() const { return nbBitsAddress()/4 + (nbBitsAddress()%4 ? 1 : 0); } + virtual bool canWriteCalibration() const = 0; // #### REMOVE ME + const RegistersData *registersData() const { return _registersData; } + const QValueVector &packages() const { return _packages; } + +protected: + const GroupBase *_group; + QString _name; + Documents _documents; + QStringList _alternatives; + Status _status; + QValueVector _frequencyRanges; + MemoryTechnology _memoryTechnology; + RegistersData *_registersData; + QValueVector _packages; + + friend class XmlToDataBase; + friend class GroupBase; + friend QDataStream &operator <<(QDataStream &s, const Data &data); + friend QDataStream &operator >>(QDataStream &s, Data &data); +}; + +QDataStream &operator <<(QDataStream &s, const RangeBox::Value &rbv); +QDataStream &operator >>(QDataStream &s, RangeBox::Value &rbv); +QDataStream &operator <<(QDataStream &s, const RangeBox &rb); +QDataStream &operator >>(QDataStream &s, RangeBox &rb); +QDataStream &operator <<(QDataStream &s, const FrequencyRange &frange); +QDataStream &operator >>(QDataStream &s, FrequencyRange &frange); +QDataStream &operator <<(QDataStream &s, const Package &package); +QDataStream &operator >>(QDataStream &s, Package &package); +QDataStream &operator <<(QDataStream &s, const Documents &documents); +QDataStream &operator >>(QDataStream &s, Documents &documents); +QDataStream &operator <<(QDataStream &s, const Data &data); +QDataStream &operator >>(QDataStream &s, Data &data); + +} // namespace + +#endif diff --git a/src/devices/base/generic_memory.cpp b/src/devices/base/generic_memory.cpp new file mode 100644 index 0000000..78c4dd6 --- /dev/null +++ b/src/devices/base/generic_memory.cpp @@ -0,0 +1,48 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "generic_memory.h" + +bool Device::Memory::load(QTextStream &stream, QStringList &errors, + WarningTypes &warningTypes, QStringList &warnings) +{ + HexBuffer hb; + if ( !hb.load(stream, errors) ) return false; + warningTypes = fromHexBuffer(hb, warnings); + return true; +} + +Device::Memory::WarningTypes Device::Memory::fromHexBuffer(const HexBuffer &hb, QStringList &warnings) +{ + clear(); + WarningTypes result = NoWarning; + warnings.clear(); + QMap inRange; + fromHexBuffer(hb, result, warnings, inRange); + + // check that all values in FragBuffer are within memory ranges + HexBuffer::const_iterator it = hb.begin(); + for (; it!=hb.end(); ++it) { + if ( !it.data().isInitialized() || inRange[it.key()] ) continue; + if ( !(result & ValueOutsideRange) ) { + result |= ValueOutsideRange; + warnings += i18n("At least one value (at address %1) is defined outside memory ranges.").arg(toHexLabel(it.key(), 8)); + } + break; + } + + return result; +} + +bool Device::Memory::save(QTextStream &stream, HexBuffer::Format format) const +{ + savePartial(stream, format); + HexBuffer hb; + hb.saveEnd(stream); + return true; +} diff --git a/src/devices/base/generic_memory.h b/src/devices/base/generic_memory.h new file mode 100644 index 0000000..74bd938 --- /dev/null +++ b/src/devices/base/generic_memory.h @@ -0,0 +1,47 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef GENERIC_MEMORY_H +#define GENERIC_MEMORY_H + +#include "devices/base/generic_device.h" +#include "devices/base/hex_buffer.h" + +namespace Device +{ + +class Memory +{ +public: + const Data &device() const { return _device; } + virtual ~Memory() {} + virtual void fill(BitValue value) = 0; + virtual void clear() { fill(BitValue()); } + virtual void copyFrom(const Memory &memory) = 0; + virtual BitValue checksum() const = 0; + + virtual HexBuffer toHexBuffer() const = 0; + bool save(QTextStream &stream, HexBuffer::Format format) const; + enum WarningType { NoWarning = 0, ValueTooLarge = 1, ValueOutsideRange = 2 }; + Q_DECLARE_FLAGS(WarningTypes, WarningType) + WarningTypes fromHexBuffer(const HexBuffer &hb, QStringList &warnings); + bool load(QTextStream &stream, QStringList &errors, WarningTypes &warningTypes, QStringList &warnings); + +protected: + const Data &_device; + + Memory(const Data &device) : _device(device) {} + virtual void fromHexBuffer(const HexBuffer &hb, WarningTypes &warningTypes, + QStringList &warnings, QMap &inRange) = 0; + virtual void savePartial(QTextStream &stream, HexBuffer::Format format) const = 0; +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(Memory::WarningTypes) + +} // namespace + +#endif diff --git a/src/devices/base/hex_buffer.cpp b/src/devices/base/hex_buffer.cpp new file mode 100644 index 0000000..a63554d --- /dev/null +++ b/src/devices/base/hex_buffer.cpp @@ -0,0 +1,290 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * (C) 2003 by Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "hex_buffer.h" + +#include + +#include "devices/base/generic_device.h" + +//----------------------------------------------------------------------------- +const char * const HexBuffer::FORMATS[Nb_Formats] = { + "inhx8m", /*"inhx8s", */"inhx16", "inhx32" +}; + +void HexBuffer::savePartial(QTextStream &stream, Format format) const +{ + BitValue oldseg; + const_iterator block = begin(); + int len; + while ( fetchNextBlock(block, end(), &len) ) { + // block found, write it + BitValue seg = block.key() >> 15 ; // 2 * seg address + if ( format==IHX32 && seg!=oldseg ) { + char buf[50]; + BitValue check = 0x02 + 0x04 + seg.byte(1) + seg.byte(0); + sprintf(buf, ":02000004%04X%02X\n", seg.toUInt(), check.twoComplement().byte(0)); + stream << buf; + oldseg = seg; + } + writeHexBlock(stream, len, block, format); + } +} + +void HexBuffer::saveEnd(QTextStream &stream) const +{ + stream << ":00000001FF\n"; +} + +/* Write one line of Intel-hex file + * Original code source from Timo Rossi, + * modified by Alain Gibaud to support large blocks write + */ +void HexBuffer::writeHexBlock(QTextStream &stream, int reclen, // length (in words) + const_iterator& data, // pointer to 1st data word (incremented by function) + Format format) +{ + while ( reclen>HEXBLKSIZE ) { + writeHexBlock(stream, HEXBLKSIZE, data, format); + reclen -= HEXBLKSIZE; + } + if ( reclen<=0 ) return; /* Oops, block has just a HEXBLKSIZE * n size */ + + char buf[20]; + BitValue check = 0x0; + + // line start + uint loc = data.key(); + switch (format) { + case IHX8M: + case IHX32: + loc *= 2; + sprintf(buf, ":%02X%04X00", 2*reclen, loc & 0xFFFF); + check += ((loc) & 0xff) + (((loc) >> 8) & 0xff) + 2*reclen; + break; + case IHX16: + sprintf(buf, ":%02X%04X00", reclen, loc & 0xFFFF); + check += (loc & 0xff) + ((loc >> 8) & 0xff) + reclen; + break; + case Nb_Formats: Q_ASSERT(false); break; + } + stream << buf; + + // data + for (; reclen > 0; ++data, --reclen) { + BitValue word = data.data(); + switch (format) { + case IHX8M: + case IHX32: + sprintf(buf, "%02X%02X", word.byte(0), word.byte(1)); + break; + case IHX16: + sprintf(buf, "%02X%02X", word.byte(1), word.byte(0)); + break; + case Nb_Formats: Q_ASSERT(false); break; + } + stream << buf; + check += word.byte(0) + word.byte(1); + } + + // checksum, assumes 2-complement + sprintf(buf, "%02X\n", check.twoComplement().byte(0)); + stream << buf; +} + +/* ------------------------------------------------------------------------- + This routine detects the next block to output + A block is a set of consecutive addresse words not + containing 0xFFFFFFFF + @return true if a block has been detected + 'it' is updated to point to the first address of the block + '*len' contains the size of the block +*/ +bool HexBuffer::fetchNextBlock(const_iterator& it, const const_iterator &end, int *len) +{ + uint startadr, curadr; + // for( i = *start ; (i < MAXPICSIZE) && (Mem[i] == INVALID) ; ++i) ; + // skip non-used words + + // Search block start + while ( it!=end && !it.data().isInitialized() ) ++it; + + // if(i >= MAXPICSIZE ) return false ; + if ( it==end ) return false; + + //for( *start = i ; (i < MAXPICSIZE) && (Mem[i] != INVALID) ; ++i) ; + //*len = i - *start ; + // search block end - a block may not cross a segment boundary + const_iterator itt(it) ; + for (curadr = startadr = itt.key(), ++itt; itt!=end; ++itt) { + if ( itt.key()!=curadr+1 ) break; // non contiguous addresses + if ( !itt.data().isInitialized() ) break; // unused word found + if ( ((itt.key()) & 0xFFFF0000U)!=(curadr & 0xFFFF0000U) ) break; // cross segment boundary + curadr = itt.key(); + } + *len = curadr - startadr + 1 ; + + return *len != 0 ; +} + +QString HexBuffer::ErrorData::message() const +{ + switch (type) { + case UnrecognizedFormat: return i18n("Unrecognized format (line %1).").arg(line); + case UnexpectedEOF: return i18n("Unexpected end-of-file."); + case UnexpectedEOL: return i18n("Unexpected end-of-line (line %1).").arg(line); + case WrongCRC: return i18n("CRC mismatch (line %1).").arg(line); + } + Q_ASSERT(false); + return QString::null; +} + +bool HexBuffer::load(QTextStream &stream, QStringList &errors) +{ + Format format; + QValueList list = load(stream, format); + if ( list.isEmpty() ) return true; + errors.clear(); + for (uint i=0; i HexBuffer::load(QTextStream &stream, Format &format) +{ + clear(); + format = Nb_Formats; + QValueList errors; + load(stream, format, errors); + if ( format==Nb_Formats ) format = IHX8M; // default + return errors; +} + +/* ------------------------------------------------------------------------- + Read a Intel HEX file of either INHX16 or INHX8M format type, detecting + the format automagicly by the wordcount and length of the line + Tested in 8 and 16 bits modes + ------------------------------------------------------------------------ */ +void HexBuffer::load(QTextStream &stream, Format &format, QValueList &errors) +{ + uint addrH = 0; // upper 16 bits of 32 bits address (inhx32 format) + uint line = 1; + + for (; !stream.atEnd(); line++) { // read each line + QString s = stream.readLine(); + if ( !s.startsWith(":") ) continue; // skip invalid intel hex line + s = s.stripWhiteSpace(); // clean-up white spaces at end-of-line + if ( s==":" ) continue; // skip empty line + + const char *p = s.latin1(); + p += 1; // skip ':' + uint bytecount = (s.length()-11) / 2; // number of data bytes of this record + + // get the byte count, the address and the type for this line. + uint count, addr, type; + if ( sscanf(p, "%02X%04X%02X", &count , &addr, &type)!=3 ) { + errors += ErrorData(line, UnrecognizedFormat); + return; + } + p += 8; + uint cksum = count + (addr >> 8) + (addr & 0xFF) + type; + + if( type==0x01 ) { // EOF field :00 0000 01 FF + uint data; + if ( sscanf(p, "%02X", &data)!=1 ) errors += ErrorData(line, UnexpectedEOL); + else if ( ((cksum+data) & 0xFF)!=0 ) errors += ErrorData(line, WrongCRC); + return; + } + + if ( type==0x04 ) { // linear extended record (for 0x21xxxx, :02 0000 04 0021 D9) + if( sscanf(p, "%04X", &addrH)!=1 ) { + errors += ErrorData(line, UnrecognizedFormat); // bad address record + return; + } + p += 4; + cksum += (addrH & 0xFF); + cksum += (addrH >> 8); + if ( format==Nb_Formats || format==IHX8M ) format = IHX32; + else if ( format!=IHX32 ) { + errors += ErrorData(line, UnrecognizedFormat); // inconsistent format + return; + } + uint data; + if ( sscanf(p, "%02X", &data)!=1 ) errors += ErrorData(line, UnexpectedEOL); + else if ( ((cksum+data) & 0xFF)!=0 ) errors += ErrorData(line, WrongCRC); + //qDebug("new address high: %s", toHex(addrH<<16, 8).data()); + continue; // goto next record + } + + /* Figure out if its INHX16 or INHX8M + if count is a 16 bits words count => INHX16 + if count is a byte count => INHX8M or INHX32 */ + if ( bytecount==count ) { + if ( format==Nb_Formats ) format = IHX8M; + else if ( format!=IHX8M && format!=IHX32 ) { + errors += ErrorData(line, UnrecognizedFormat); // inconsistent format + return; + } + /* Processing a INHX8M line */ + /* Modified to be able to read fuses from hexfile created by C18 toolchain */ + /* changed by Tobias Schoene 9 April 2005, */ + /* modified by A.G, because low and hi bytes was swapped in Tobias's code , 8 may 2005 + */ + uint addrbase = ((addrH << 16) | addr); + //qDebug("line %i: address %s", line, toHex(addrbase, 8).data()); + for (uint x = 0; x> 1; + BitValue value = (*this)[a]; + if ( addrbase+x & 1 ) insert(a, value.maskWith(0x00FF) | data << 8); // Odd addr => Hi byte + else insert(a, value.maskWith(0xFF00) | data); // Low byte + //if ( x==0 ) qDebug("fb@%s: %s", toHex(addrbase+x >> 1, 8).data(), toHex(fb[addrbase+x >> 1], 8).data()); + cksum += data; + } + } else if ( bytecount==count*2 ) { + if ( format==Nb_Formats ) format = IHX16; + else if ( format!=IHX16 ) { + errors += ErrorData(line, UnrecognizedFormat); // inconsistent format + return; + } + /* Processing a INHX16 line */ + for(uint x=0; x * + * (C) 2003 by Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#ifndef HEX_BUFFER_H +#define HEX_BUFFER_H + +#include "common/global/global.h" +#include "common/common/bitvalue.h" +class QTextStream; + +class HexBuffer : public QMap +{ +public: + enum Format { /// Differents flavors of Intel HEX file formats + IHX8M = 0, ///< 8 bits "swapped" format + // IHX8S, + IHX16, ///< 16 bits format + IHX32, ///< 8 bit format with 32 bits addresses + Nb_Formats + }; + static const char * const FORMATS[Nb_Formats]; + + void savePartial(QTextStream &s, Format format) const; + void saveEnd(QTextStream &s) const; + enum ErrorType { UnrecognizedFormat, WrongCRC, UnexpectedEOF, UnexpectedEOL }; + class ErrorData { + public: + ErrorData() {} + ErrorData(uint _line, ErrorType _type) : line(_line), type(_type) {} + QString message() const; + uint line; + ErrorType type; + }; + QValueList load(QTextStream &stream, Format &format); + bool load(QTextStream &stream, QStringList &errors); + +private: + enum { HEXBLKSIZE = 8 }; // line size in HEX files + + static bool fetchNextBlock(const_iterator& start, const const_iterator &end, int *len); + static void writeHexBlock(QTextStream &stream, int reclen, const_iterator& data, Format format); + void load(QTextStream &stream, Format &format, QValueList &errors); +}; + +#endif diff --git a/src/devices/base/register.cpp b/src/devices/base/register.cpp new file mode 100644 index 0000000..85fc013 --- /dev/null +++ b/src/devices/base/register.cpp @@ -0,0 +1,156 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "register.h" + +//---------------------------------------------------------------------------- +namespace Register +{ + List *_list = 0; +} +Register::List &Register::list() +{ + if ( _list==0 ) _list = new List; + return *_list; +} + +//---------------------------------------------------------------------------- +Register::TypeData::TypeData(Address address, uint nbChars) + : _nbChars(nbChars), _address(address) +{ + Q_ASSERT( address.isValid() && nbChars!=0 ); +} +Register::TypeData::TypeData(const QString &name, uint nbChars) + : _nbChars(nbChars), _name(name) +{ + Q_ASSERT( !name.isEmpty() && nbChars!=0 ); +} +Register::TypeData::TypeData(const QString &name, Address address, uint nbChars) + : _nbChars(nbChars), _address(address), _name(name) +{ + Q_ASSERT( address.isValid() && nbChars!=0 && !name.isEmpty() ); +} + +Register::Type Register::TypeData::type() const +{ + if ( !_address.isValid() ) { + if ( _name.isEmpty() ) return Invalid; + return Special; + } + if ( _name.isEmpty() ) return Regular; + return Combined; +} + +QString Register::TypeData::toString() const +{ + return QString("%1 %2 %3").arg(toLabel(_address)).arg(_nbChars).arg(_name); +} + +Register::TypeData Register::TypeData::fromString(const QString &s) +{ + QStringList list = QStringList::split(" ", s); + if ( list.count()<2 || list.count()>3 ) return TypeData(); + bool ok; + Address address = list[0].toUInt(&ok); + if ( !ok ) return TypeData(); + uint nbChars = list[1].toUInt(&ok); + if ( !ok || nbChars==0 || (nbChars%2)!=0 ) return TypeData(); + QString name; + if ( list.count()==3 ) name = list[2]; + if ( !address.isValid() ) { + if ( name.isEmpty() ) return TypeData(); + return TypeData(name, nbChars); + } + if ( name.isEmpty() ) return TypeData(address, nbChars); + return TypeData(name, address, nbChars); +} + +//---------------------------------------------------------------------------- +void Register::List::init() +{ + _regulars.clear(); + _specials.clear(); + _watched.clear(); + _portDatas.clear(); + delayedChanged(); +} + +void Register::List::setWatched(const TypeData &data, bool watched) +{ + if (watched) { + if ( _watched.contains(data) ) return; + _watched.append(data); + } else _watched.remove(data); + delayedChanged(); +} + +void Register::List::clearWatched() +{ + _watched.clear(); + delayedChanged(); +} + +void Register::List::setValue(const TypeData &data, BitValue value) +{ + if ( !data.address().isValid() ) { + _specials[data.name()].old = _specials[data.name()].current; + _specials[data.name()].current = value; + } else { + Q_ASSERT( (data.nbChars()%2)==0 ); + uint nb = data.nbChars()/2; + for (uint i=0; i &data) +{ + _portDatas[index].old = _portDatas[index].current; + _portDatas[index].current = data; + delayedChanged(); +} + +BitValue Register::List::value(const TypeData &data) const +{ + if ( !data.address().isValid() ) { + if ( !_specials.contains(data.name()) ) return BitValue(); + return _specials[data.name()].current; + } + Q_ASSERT( (data.nbChars()%2)==0 ); + uint nb = data.nbChars()/2; + BitValue value = 0; + for (int i=nb-1; i>=0; i--) { + value <<= 8; + BitValue v = _regulars[data.address() + i].current; + if ( !v.isInitialized() ) return BitValue(); + value += v; + } + return value; +} + +BitValue Register::List::oldValue(const TypeData &data) const +{ + if ( !data.address().isValid() ) { + if ( !_specials.contains(data.name()) ) return BitValue(); + return _specials[data.name()].old; + } + Q_ASSERT( (data.nbChars()%2)==0 ); + uint nb = data.nbChars()/2; + BitValue value = 0; + for (int i=nb-1; i>=0; i--) { + value <<= 8; + BitValue v = _regulars[data.address() + i].old; + if ( !v.isInitialized() ) return BitValue(); + value += v; + } + return value; +} diff --git a/src/devices/base/register.h b/src/devices/base/register.h new file mode 100644 index 0000000..1c587e2 --- /dev/null +++ b/src/devices/base/register.h @@ -0,0 +1,130 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef REGISTER_H +#define REGISTER_H + +#include "common/common/storage.h" +#include "devices/base/generic_device.h" +namespace Register { class TypeData; } + +namespace Device +{ +enum RegisterProperty { NotAccessible = 0x0, Readable = 0x1, Writable = 0x2 }; +Q_DECLARE_FLAGS(RegisterProperties, RegisterProperty) +Q_DECLARE_OPERATORS_FOR_FLAGS(RegisterProperties) + +enum { MAX_NB_PORTS = 8 }; +enum { MAX_NB_PORT_BITS = 16 }; +enum BitState { Low = 0, High, WeakPullUp, WeakPullDown, HighImpedance, Unknown }; +enum IoState { IoLow = 0, IoHigh, IoUnknown }; +class PortBitData { +public: + PortBitData() : state(Unknown), driving(false), drivenState(IoUnknown), drivingState(IoUnknown) {} + BitState state; + bool driving; + IoState drivenState, drivingState; + bool operator !=(const PortBitData &pdb) const { + return ( state!=pdb.state || driving!=pdb.driving || drivenState!=pdb.drivenState || drivingState!=pdb.drivingState ); + } +}; + +} // namespace + +namespace Register +{ +//---------------------------------------------------------------------------- +enum Type { Regular, Special, Combined, Invalid }; +class TypeData { +public: + TypeData() : _nbChars(0) {} + TypeData(Address address, uint nbChars); + TypeData(const QString &name, uint nbChars); + TypeData(const QString &name, Address address, uint nbChars); + bool operator ==(const TypeData &data) const { return _name==data._name && _address==data._address && _nbChars==data._nbChars; } + Type type() const; + QString name() const { return _name; } + Address address() const { return _address; } + uint nbChars() const { return _nbChars; } + QString toString() const; + static TypeData fromString(const QString &s); + +private: + uint _nbChars; + Address _address; + QString _name; +}; + +} // namespace + +namespace Device +{ +//---------------------------------------------------------------------------- +class RegistersData +{ +public: + RegistersData() {} + virtual ~RegistersData() {} + virtual uint nbRegisters() const = 0; + virtual uint nbBits() const = 0; + uint nbBytes() const { return nbBitsToNbBytes(nbBits()); } + uint nbChars() const { return nbBitsToNbChars(nbBits()); } + virtual uint addressFromIndex(uint i) const = 0; + virtual uint indexFromAddress(Address address) const = 0; + virtual RegisterProperties properties(Address address) const = 0; + virtual QValueList relatedRegisters(const Register::TypeData &data) const = 0; + virtual bool hasPort(uint index) const = 0; + virtual int portIndex(Address address) const = 0; + virtual QString portName(uint index) const = 0; + virtual bool hasPortBit(uint index, uint bit) const = 0; + virtual QString portBitName(uint index, uint bit) const = 0; +}; + +} // namespace + +namespace Register +{ +//---------------------------------------------------------------------------- +class List; +extern List &list(); + +class List : public GenericStorage +{ +Q_OBJECT +public: + List() : GenericStorage(0, "register_list") {} + void init(); + void setWatched(const TypeData &data, bool watched); + void clearWatched(); + const QValueList &watched() const { return _watched; } + bool isWatched(const TypeData &data) const { return _watched.contains(data); } + void setValue(const TypeData &data, BitValue value); + BitValue value(const TypeData &data) const; + BitValue oldValue(const TypeData &data) const; + void setPortData(uint index, const QMap &data); + QMap portData(uint index) const { return _portDatas[index].current; } + QMap oldPortData(uint index) const { return _portDatas[index].old; } + +private: + class StateData { + public: + BitValue current, old; + }; + QMap _regulars; // registers with address + QMap _specials; // registers with no address + class PortData { + public: + QMap current, old; + }; + QMap _portDatas; // port index + QValueList _watched; +}; + +} // namespace + +#endif diff --git a/src/devices/devices.pro b/src/devices/devices.pro new file mode 100644 index 0000000..136930d --- /dev/null +++ b/src/devices/devices.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = base list pic mem24 diff --git a/src/devices/gui/Makefile.am b/src/devices/gui/Makefile.am new file mode 100644 index 0000000..ae92163 --- /dev/null +++ b/src/devices/gui/Makefile.am @@ -0,0 +1,7 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +libdeviceui_la_LDFLAGS = $(all_libraries) +noinst_LTLIBRARIES = libdeviceui.la +libdeviceui_la_SOURCES = hex_word_editor.cpp memory_editor.cpp \ + register_view.cpp hex_view.cpp device_group_ui.cpp diff --git a/src/devices/gui/device_group_ui.cpp b/src/devices/gui/device_group_ui.cpp new file mode 100644 index 0000000..64b5c14 --- /dev/null +++ b/src/devices/gui/device_group_ui.cpp @@ -0,0 +1,9 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "device_group_ui.h" diff --git a/src/devices/gui/device_group_ui.h b/src/devices/gui/device_group_ui.h new file mode 100644 index 0000000..3b2fa91 --- /dev/null +++ b/src/devices/gui/device_group_ui.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef DEVICE_GROUP_UI_H +#define DEVICE_GROUP_UI_H + +#include +class QWidget; +class KPopupMenu; +class KListViewItem; +class KAction; + +#include "devices/base/generic_device.h" +#include "devices/base/device_group.h" +#include "devices/base/register.h" +namespace Register { class View; class ListViewItem; } +class HexEditor; +class ListContainer; + +namespace Device +{ +class Memory; +class HexView; +class MemoryEditor; + +class GroupUI : public ::Group::BaseGui +{ +public: + virtual HexView *createHexView(const HexEditor &editor, QWidget *parent) const = 0; + virtual Register::View *createRegisterView(QWidget *parent) const = 0; + virtual MemoryEditor *createConfigEditor(Device::Memory &memory, QWidget *parent) const = 0; + virtual void fillWatchListContainer(ListContainer *container, QValueVector &ids) const = 0; + virtual Register::ListViewItem *createWatchItem(const Register::TypeData &data, KListViewItem *parent) const = 0; +}; + +inline const Device::GroupUI &groupui(const Device::Data &data) { return static_cast(*data.group().gui()); } + +} // namespace + +#endif diff --git a/src/devices/gui/hex_view.cpp b/src/devices/gui/hex_view.cpp new file mode 100644 index 0000000..6b26b0a --- /dev/null +++ b/src/devices/gui/hex_view.cpp @@ -0,0 +1,23 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * Copyright (C) 2003 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "hex_view.h" + +Device::HexView::HexView(const HexEditor &editor, QWidget *parent, const char *name) + : MemoryEditorGroup(0, parent, name), _editor(editor) +{} + +void Device::HexView::display(Memory *memory) +{ + _memory = memory; + for (uint i=0; i<_editors.count(); i++) delete _editors[i]; + _editors.clear(); + if ( _memory==0 ) return; + display(); +} diff --git a/src/devices/gui/hex_view.h b/src/devices/gui/hex_view.h new file mode 100644 index 0000000..d73710e --- /dev/null +++ b/src/devices/gui/hex_view.h @@ -0,0 +1,39 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * Copyright (C) 2003 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#ifndef HEX_VIEW_H +#define HEX_VIEW_H + +#include "memory_editor.h" +#include "libgui/hex_editor.h" + +namespace Device +{ + +class HexView : public MemoryEditorGroup +{ +Q_OBJECT +public: + HexView(const HexEditor &editor, QWidget *parent, const char *name); + virtual void display(Memory *memory); + virtual uint nbChecksumChars() const = 0; + virtual BitValue checksum() const = 0; + bool isModified() const { return _editor.isModified(); } + const Memory *originalMemory() const { return _editor.originalMemory(); } + +protected: + virtual void display() = 0; + +private: + const HexEditor &_editor; +}; + +} // namespace + +#endif diff --git a/src/devices/gui/hex_word_editor.cpp b/src/devices/gui/hex_word_editor.cpp new file mode 100644 index 0000000..fd64e13 --- /dev/null +++ b/src/devices/gui/hex_word_editor.cpp @@ -0,0 +1,42 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "hex_word_editor.h" + +#include +#include +#include +#include +#include + +//----------------------------------------------------------------------------- +Device::HexWordEditor::HexWordEditor(Memory &memory, uint nbChars, QWidget *parent) + : GenericHexWordEditor(nbChars, true, parent), _memory(memory) +{ + setOffset(-1); +} + +void Device::HexWordEditor::setOffset(int offset) +{ + _offset = offset; + set(); +} + +//----------------------------------------------------------------------------- +Device::RegisterHexWordEditor::RegisterHexWordEditor(QWidget *parent, uint nbChars, BitValue mask) + : GenericHexWordEditor(nbChars, true, parent), _mask(mask) +{ + clear(); +} + +void Device::RegisterHexWordEditor::setValue(BitValue word) +{ + _word = word; + set(); +} diff --git a/src/devices/gui/hex_word_editor.h b/src/devices/gui/hex_word_editor.h new file mode 100644 index 0000000..bd9fadb --- /dev/null +++ b/src/devices/gui/hex_word_editor.h @@ -0,0 +1,64 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#ifndef HEX_WORD_EDITOR_H +#define HEX_WORD_EDITOR_H + +#include "common/gui/hexword_gui.h" +#include "devices/base/generic_memory.h" + +namespace Device +{ +//----------------------------------------------------------------------------- +class HexWordEditor : public GenericHexWordEditor +{ +Q_OBJECT +public: + HexWordEditor(Memory &memory, uint nbChars, QWidget *parent); + void setOffset(int offset); + int offset() const { return _offset; } + +protected: + Device::Memory &_memory; + int _offset; + + virtual bool isValid() const { return _offset!=-1; } + virtual BitValue mask() const = 0; + virtual BitValue normalizeWord(BitValue value) const = 0; + virtual BitValue word() const = 0; + virtual void setWord(BitValue value) = 0; + virtual BitValue blankValue() const { return BitValue(); } +}; + +//----------------------------------------------------------------------------- +class RegisterHexWordEditor : public GenericHexWordEditor +{ +Q_OBJECT +public: + RegisterHexWordEditor(QWidget *parent, uint nbChars, BitValue mask); + void clear() { setValue(BitValue()); } + void setValue(BitValue word); + BitValue value() const { return _word; } + void setColor(QColor color) { setPaletteForegroundColor(color); } + void unsetColor() { unsetPalette(); } + +private: + BitValue _mask, _word; + + virtual bool isValid() const { return true; } + virtual BitValue mask() const { return _mask; } + virtual BitValue normalizeWord(BitValue value) const { return value.maskWith(_mask); } + virtual BitValue word() const { return _word; } + virtual void setWord(BitValue value) { _word = value; } + virtual BitValue blankValue() const { return BitValue(); } +}; + +} // namespace + +#endif diff --git a/src/devices/gui/memory_editor.cpp b/src/devices/gui/memory_editor.cpp new file mode 100644 index 0000000..175f011 --- /dev/null +++ b/src/devices/gui/memory_editor.cpp @@ -0,0 +1,369 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "memory_editor.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common/common/misc.h" +#include "hex_word_editor.h" +#include "device_group_ui.h" +#include "libgui/toplevel.h" +#include "libgui/main_global.h" +#include "hex_view.h" +#include "libgui/gui_prog_manager.h" + +//----------------------------------------------------------------------------- +Device::MemoryEditor::MemoryEditor(Device::Memory *memory, QWidget *parent, const char *name) + : QFrame(parent, name), _memory(memory) +{ + _top = new QVBoxLayout(this, 5, 10); +} + +//----------------------------------------------------------------------------- +Device::MemoryRangeEditor::MemoryRangeEditor(Device::Memory &memory, + uint nbLines, uint nbCols, uint offset, int nb, + QWidget *parent, const char *name) + : MemoryEditor(&memory, parent, name), + _nbLines(nbLines), _nbCols(nbCols), _offset(offset), _nb(nb) +{} + +void Device::MemoryRangeEditor::init() +{ + if ( _nb==-1 ) _nb = nbWords(); + uint totalNbLines = _nb / _nbCols; + if ( (_nb % _nbCols)!=0 ) totalNbLines++; + + QHBoxLayout *hbox = new QHBoxLayout(_top); + + QVBoxLayout *vbox = new QVBoxLayout(hbox); + QFrame *frame = new QFrame(this); + frame->setFrameStyle(QFrame::Panel | QFrame::Raised); + frame->setMargin(5); + vbox->addWidget(frame); + vbox->addStretch(1); + QHBoxLayout *fbox = new QHBoxLayout(frame, 5, 5); + QGrid *grid = new QGrid(3+_nbCols, QGrid::Horizontal, frame, "memory_range_editor_grid"); + fbox->addWidget(grid); + grid->setSpacing(0); + grid->setMargin(3); + QFont f("courier", font().pointSize()); + grid->setFont(f); + for (uint k=0; k<_nbLines; ++k) { + // addresses + QWidget *w = new QWidget(grid); + w->setFixedWidth(10); + _blocks.append(w); + QLabel *label = new QLabel(toHex(0, 2*_memory->device().nbBytesAddress()), grid, "address_label"); + _addresses.append(label); + label = new QLabel(":", grid); + // memory + for (uint i = 0; i<_nbCols; ++i) { + HexWordEditor *h = createHexWordEditor(grid); + _editors.append(h); + connect(h, SIGNAL(modified()), SIGNAL(modified())); + connect(h, SIGNAL(moveNext()), SLOT(moveNext())); + connect(h, SIGNAL(movePrev()), SLOT(movePrev())); + connect(h, SIGNAL(moveFirst()), SLOT(moveFirst())); + connect(h, SIGNAL(moveLast()), SLOT(moveLast())); + connect(h, SIGNAL(moveUp()), SLOT(moveUp())); + connect(h, SIGNAL(moveDown()), SLOT(moveDown())); + connect(h, SIGNAL(moveNextPage()), SLOT(moveNextPage())); + connect(h, SIGNAL(movePrevPage()), SLOT(movePrevPage())); + } + } + + // scrollbar if there are more lines to display than visible + _scrollbar = new QScrollBar(0, QMAX(_nbLines, totalNbLines)-_nbLines, 1, _nbLines, 0, + QScrollBar::Vertical, frame, "memory_range_editor_scrollbar"); + connect(_scrollbar, SIGNAL(valueChanged(int)), SLOT(setIndex(int))) ; + if ( totalNbLines<=_nbLines ) _scrollbar->hide(); + fbox->addWidget(_scrollbar); + fbox->addStretch(1); + + vbox->addStretch(1); + QVBoxLayout *vboxc = new QVBoxLayout(hbox); + vboxc->setSpacing(0); + _comment = new QLabel(this); + _comment->hide(); + vboxc->addWidget(_comment); + _spacer = new QLabel(this); + _spacer->setFixedHeight(10); + _spacer->hide(); + vboxc->addWidget(_spacer); + addLegend(vboxc); + vboxc->addStretch(1); + hbox->addStretch(1); + + setReadOnly(false); + setIndex(0); +} + +void Device::MemoryRangeEditor::setComment(const QString &text) +{ + _comment->setText(text); + _comment->show(); + _spacer->show(); +} + +void Device::MemoryRangeEditor::setReadOnly(bool readOnly) +{ + for (uint i=0; i<_editors.count(); i++) + _editors[i]->setReadOnly(readOnly || isRangeReadOnly()); +} + +void Device::MemoryRangeEditor::updateDisplay() +{ + setIndex(_scrollbar->value()); +} + +void Device::MemoryRangeEditor::setStartWord(int index) +{ + setIndex(index / _nbCols / addressIncrement()); +} + +void Device::MemoryRangeEditor::setEndWord(int index) +{ + uint i = index / _nbCols / addressIncrement(); + i = (i<_nbLines ? 0 : i - _nbLines + 1); + setIndex(i); +} + +void Device::MemoryRangeEditor::setIndex(int index) +{ + _scrollbar->blockSignals(true); + _scrollbar->setValue(index); + _scrollbar->blockSignals(false); + + // memory + for (uint i=0; i<_editors.count(); i++) { + int offset = wordOffset() + i; + _editors[i]->setOffset(offsetsetText(toHex(address, 2*_memory->device().nbBytesAddress())); + updateAddressColor(i, address); + address += inc * _nbCols; + } +} + +void Device::MemoryRangeEditor::moveNext() +{ + QValueList::iterator it = _editors.find((HexWordEditor *)sender()); + ++it; + if ( it==_editors.end() || (*it)->offset()==-1 ) { + if ( current()==uint(_scrollbar->maxValue()) ) return; // at end + setIndex(current()+1); + _editors[_editors.count()-_nbCols]->setFocus(); + } else (*it)->setFocus(); +} + +void Device::MemoryRangeEditor::movePrev() +{ + QValueList::iterator it = _editors.find((HexWordEditor *)sender()); + if ( it==_editors.begin() ) { + if ( current()==0 ) return; // at beginning + setIndex(current()-1); + _editors[_nbCols-1]->setFocus(); + } else { + --it; + (*it)->setFocus(); + } +} + +void Device::MemoryRangeEditor::moveFirst() +{ + if ( _editors[0]==0 ) return; + setIndex(0); + _editors[0]->setFocus(); +} + +void Device::MemoryRangeEditor::moveLast() +{ + if ( _editors.count()==0 ) return; + setIndex(_scrollbar->maxValue()); + for (uint i=1; i<=_nbCols; i++) { + if ( _editors[_editors.count()-i]->offset()==-1 ) continue; + _editors[_editors.count()-i]->setFocus(); + break; + } +} + +void Device::MemoryRangeEditor::moveUp() +{ + int i = _editors.findIndex((HexWordEditor *)sender()); + uint line = i / _nbCols; + if ( line==0 ) { + if ( current()==0 ) return; // on first line + setIndex(current()-1); + _editors[i]->setFocus(); + } else _editors[i-_nbCols]->setFocus(); +} + +void Device::MemoryRangeEditor::moveDown() +{ + int i = _editors.findIndex((HexWordEditor *)sender()); + uint line = i / _nbCols; + if ( line+1==_nbLines ) { + if ( current()==uint(_scrollbar->maxValue()) ) return; // on last line + setIndex(current()+1); + if ( _editors[i]->offset()==-1 ) _editors[i-_nbCols]->setFocus(); + else _editors[i]->setFocus(); + } else _editors[i+_nbCols]->setFocus(); +} + +void Device::MemoryRangeEditor::moveNextPage() +{ + int i = _editors.findIndex((HexWordEditor *)sender()); + if ( _nbLines>(uint(_scrollbar->maxValue()) - current()) ) i = (_nbLines-1) * _nbCols + (i % _nbCols); + else setIndex(current()+_nbLines); + if ( _editors[i]->offset()==-1 ) _editors[i-_nbCols]->setFocus(); + else _editors[i]->setFocus(); +} + +void Device::MemoryRangeEditor::movePrevPage() +{ + int i = _editors.findIndex((HexWordEditor *)sender()); + if ( current()<_nbLines ) i = (i % _nbCols); + else setIndex(current()-_nbLines); + _editors[i]->setFocus(); +} + +//----------------------------------------------------------------------------- +Device::MemoryEditorGroup::MemoryEditorGroup(Device::Memory *memory, QWidget *parent, const char *name) + : MemoryEditor(memory, parent, name) +{} + +void Device::MemoryEditorGroup::addEditor(MemoryEditor *editor) +{ + connect(editor, SIGNAL(modified()), SIGNAL(modified())); + _editors.append(editor); +} + +void Device::MemoryEditorGroup::setReadOnly(bool readOnly) +{ + for (uint i=0; i<_editors.count(); i++) + _editors[i]->setReadOnly(readOnly); +} + +void Device::MemoryEditorGroup::updateDisplay() +{ + for (uint i=0; i<_editors.count(); i++) + _editors[i]->updateDisplay(); +} + +//----------------------------------------------------------------------------- +const Device::ActionData Device::ACTION_DATA[Nb_Actions] = { + { I18N_NOOP("&Clear"), "fileclose", NeedWrite }, + { I18N_NOOP("&Zero"), 0, NeedWrite }, + { I18N_NOOP("For checksum check"), 0, NeedWrite }, + { I18N_NOOP("Re&load"), "reload", SeparatorAfter | NeedModified }, + { I18N_NOOP("&Program"), "piklab_burnchip", NeedProgrammer }, + { I18N_NOOP("&Verify"), "piklab_verifychip", NeedProgrammer }, + { I18N_NOOP("&Read"), "piklab_readchip", NeedProgrammer | NeedWrite }, + { I18N_NOOP("&Erase"), "piklab_erasechip", NeedProgrammer }, + { I18N_NOOP("&Blank Check"), "piklab_blankcheck", NeedProgrammer } +}; + +Device::MemoryTypeEditor::MemoryTypeEditor(const HexView *hexview, Device::Memory &memory, + QWidget *parent, const char *name) + : MemoryEditorGroup(&memory, parent, name), + _title(0), _comment(0), _hexview(hexview) +{ + for (uint i=0; iaddWidget(new SeparatorWidget(this)); + QHBoxLayout *hbox = new QHBoxLayout(_top); + + _title = new PopupButton(this); + for (uint i=0; iappendSeparator(); + } + _title->appendSeparator(); + hbox->addWidget(_title); + + _comment = new QLabel(this); + hbox->addWidget(_comment); + hbox->addStretch(1); + + connect(&Main::toplevel(), SIGNAL(stateChanged()), SLOT(stateChanged())); +} + +void Device::MemoryTypeEditor::addAction(KAction *action) +{ + _title->appendAction(action); +} + +void Device::MemoryTypeEditor::doAction() +{ + for (uint i=0; iinitProgramming(false) ) return; + bool ok = internalDoAction(action); + if ( ACTION_DATA[action].properties & NeedProgrammer ) + Programmer::manager->endProgramming(); + if (ok) { + updateDisplay(); + modified(); + } +} + +void Device::MemoryTypeEditor::stateChanged() +{ + bool idle = ( Main::state()==Main::Idle ); + for (uint i=0; iisModified()) ) on = false; + _actions[i]->setEnabled(on); + } +} + +void Device::MemoryTypeEditor::setReadOnly(bool readOnly) +{ + _readOnly = readOnly; + MemoryEditorGroup::setReadOnly(readOnly); + stateChanged(); +} + +const Device::Memory *Device::MemoryTypeEditor::originalMemory() const +{ + return (_hexview ? _hexview->originalMemory() : 0); +} diff --git a/src/devices/gui/memory_editor.h b/src/devices/gui/memory_editor.h new file mode 100644 index 0000000..9836261 --- /dev/null +++ b/src/devices/gui/memory_editor.h @@ -0,0 +1,156 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef MEMORY_EDITOR_H +#define MEMORY_EDITOR_H + +#include +#include +#include +#include "common/common/qflags.h" +#include "common/common/bitvalue.h" +class QVBoxLayout; +class QHBoxLayout; +class QHBox; +class KAction; +class PopupButton; + +namespace Device +{ +class HexView; +class HexWordEditor; +class Memory; + +enum Action { Clear = 0, Zero, ChecksumCheck, Reload, + Program, Verify, Read, Erase, BlankCheck, Nb_Actions }; +enum ActionProperty { NoProperty = 0, SeparatorAfter = 1, NeedProgrammer = 2, + NeedWrite = 4, NeedModified = 8 }; +Q_DECLARE_FLAGS(ActionProperties, ActionProperty) +Q_DECLARE_OPERATORS_FOR_FLAGS(ActionProperties) +struct ActionData { + const char *label, *icon; + ActionProperties properties; +}; +extern const ActionData ACTION_DATA[Nb_Actions]; + +//---------------------------------------------------------------------------- +class MemoryEditor : public QFrame +{ +Q_OBJECT +public: + MemoryEditor(Device::Memory *memory, QWidget *parent, const char *name); + virtual void setReadOnly(bool readOnly) = 0; + +public slots: + virtual void updateDisplay() = 0; + +signals: + void modified(); + +protected: + Device::Memory *_memory; + QVBoxLayout *_top; +}; + +//---------------------------------------------------------------------------- +class MemoryRangeEditor : public MemoryEditor +{ +Q_OBJECT +public: + MemoryRangeEditor(Device::Memory &memory, uint nbLines, uint nbCols, + uint offset, int nb, QWidget *parent, const char *name); + virtual void init(); + virtual void setReadOnly(bool readOnly); + void setComment(const QString &text); + +public slots: + virtual void updateDisplay(); + void moveNext(); + void movePrev(); + void moveFirst(); + void moveLast(); + void moveUp(); + void moveDown(); + void moveNextPage(); + void movePrevPage(); + +protected slots: + void setStartWord(int index); + void setEndWord(int index); + void setIndex(int index); + +protected: + uint _nbLines, _nbCols, _offset; + int _nb; + QValueList _addresses; + QValueList _blocks; + QValueList _editors; + QScrollBar *_scrollbar; + QLabel *_comment; + QWidget *_spacer; + + uint wordOffset() const { return _offset + current() * _nbCols; } + uint current() const { return _scrollbar->value(); } + virtual uint nbWords() const = 0; + virtual uint addressIncrement() const = 0; + virtual Address startAddress() const = 0; + virtual HexWordEditor *createHexWordEditor(QWidget *parent) = 0; + virtual bool isRangeReadOnly() const = 0; + virtual void updateAddressColor(uint i, Address address) { Q_UNUSED(i); Q_UNUSED(address); } + virtual void addLegend(QVBoxLayout *vbox) { Q_UNUSED(vbox); } +}; + +//---------------------------------------------------------------------------- +class MemoryEditorGroup : public MemoryEditor +{ +Q_OBJECT +public: + MemoryEditorGroup(Device::Memory *memory, QWidget *parent, const char *name); + void addEditor(MemoryEditor *editor); + virtual void setReadOnly(bool readOnly); + +public slots: + virtual void updateDisplay(); + +protected: + bool _modified; + QValueList _editors; +}; + +//---------------------------------------------------------------------------- +class MemoryTypeEditor : public MemoryEditorGroup +{ +Q_OBJECT +public: + MemoryTypeEditor(const HexView *hexview, Device::Memory &memory, QWidget *parent, const char *name); + virtual void init(bool first); + virtual void setReadOnly(bool readOnly); + +protected slots: + void doAction(); + void stateChanged(); + +protected: + PopupButton *_title; + QLabel *_comment; + const HexView *_hexview; + virtual bool internalDoAction(Action action) = 0; // return true if memory modified + virtual bool hasAction(Action) const { return true; } + void addAction(KAction *action); + const Device::Memory *originalMemory() const; + +private: + bool _readOnly; + KAction *_actions[Nb_Actions]; + + void doAction(Action action); +}; + +} // namespace + +#endif diff --git a/src/devices/gui/register_view.cpp b/src/devices/gui/register_view.cpp new file mode 100644 index 0000000..70dedc9 --- /dev/null +++ b/src/devices/gui/register_view.cpp @@ -0,0 +1,208 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "register_view.h" + +#include "libgui/main_global.h" +#include "libgui/gui_debug_manager.h" + +//---------------------------------------------------------------------------- +Register::PortBitListViewItem::PortBitListViewItem(uint index, uint bit, KListViewItem *parent) + : KListViewItem(parent), _index(index), _bit(bit) +{ + const Device::RegistersData *rdata = Main::deviceData()->registersData(); + setText(1, rdata->portBitName(_index, _bit)); + setSelectable(false); +} + +void Register::PortBitListViewItem::updateView() +{ + const QMap &pdata = Register::list().portData(_index); + QString text; + if ( pdata.isEmpty() ) text = "--"; + else { +/* + switch (pdata[_bit].state) { + case Device::High: text = " 1"; break; + case Device::Low: text = " 0"; break; + case Device::WeakPullUp: text = "w1"; break; + case Device::WeakPullDown: text = "w0"; break; + case Device::HighImpedance: text = "HZ"; break; + case Device::Unknown: text = " "; break; + } +*/ + if ( pdata[_bit].drivingState==Device::IoUnknown ) text = " "; + else text += (pdata[_bit].drivingState==Device::IoHigh ? "1" : "0"); + text += (pdata[_bit].driving ? " > " : " < "); + if ( pdata[_bit].drivenState==Device::IoUnknown ) text += " "; + else text += (pdata[_bit].drivenState==Device::IoHigh ? "1" : "0"); + } + setText(2, text); + repaint(); +} + +void Register::PortBitListViewItem::paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int align) +{ + QColorGroup ncg = cg; + const QMap &data = Register::list().portData(_index); + const QMap &odata = Register::list().oldPortData(_index); + bool changed = ( !data.isEmpty() && data[_bit]!=odata[_bit] ); + if ( column==2 && changed ) ncg.setColor(QColorGroup::Text, red); + KListViewItem::paintCell(p, ncg, column, width, align); +} + +QString Register::PortBitListViewItem::tooltip(int col) const +{ + if ( col!=2 ) return QString::null; + const QMap &pdata = Register::list().portData(_index); + if ( pdata.isEmpty() ) return QString::null; + QString s = text(1) + ": "; + if (pdata[_bit].driving) { + if ( pdata[_bit].drivingState!=Device::IoUnknown ) s += i18n("unknown state"); + else s += (pdata[_bit].drivingState==Device::IoHigh ? i18n("driving high") : i18n("driving low")); + s += i18n(" (output)"); + } else { + if ( pdata[_bit].drivenState==Device::IoUnknown ) s += i18n("unknown state"); + else s += (pdata[_bit].drivenState==Device::IoHigh ? i18n("driven high") : i18n("driven low")); + s += i18n(" (input)"); + } + return s; +} + +//----------------------------------------------------------------------------- +Register::ListViewItem::ListViewItem(const TypeData &data, KListViewItem *parent) + : EditListViewItem(parent), _data(data), _base(NumberBase::Hex) +{ + setSelectable(false); + const Device::RegistersData *rdata = Main::deviceData()->registersData(); + if ( data.type()==Regular && rdata ) { + int i = rdata->portIndex(data.address()); + if ( i!=-1 ) { + for (int k=Device::MAX_NB_PORT_BITS-1; k>=0; k--) { + if ( !rdata->hasPortBit(i, k) ) continue; + PortBitListViewItem *item = new PortBitListViewItem(i, k, this); + _items.append(item); + } + } + } +} + +QString Register::ListViewItem::text() const +{ + BitValue value = Register::list().value(_data); + uint nbChars = convertNbChars(_data.nbChars(), NumberBase::Hex, _base); + return (value.isInitialized() ? toLabel(_base, value, nbChars) : "--"); +} + +int Register::ListViewItem::compare(QListViewItem *item, int, bool) const +{ + const TypeData &data = static_cast(item)->data(); + int i1 = list().watched().findIndex(data); + Q_ASSERT( i1!=-1 ); + int i2 = list().watched().findIndex(_data); + Q_ASSERT( i2!=-1 ); + return ( i1-i2 ); +} + +void Register::ListViewItem::updateView() +{ + if ( _data.type()!=Special ) setText(0, toHexLabel(_data.address(), nbCharsAddress()) + ":"); + setText(1, label()); + setText(2, text()); + repaint(); + for (uint i=0; i<_items.count(); i++) _items[i]->updateView(); +} + +void Register::ListViewItem::setBase(NumberBase base) +{ + _base = base; + updateView(); +} + +void Register::ListViewItem::paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int align) +{ + QColorGroup ncg = cg; + BitValue value = Register::list().value(_data); + BitValue oldValue = Register::list().oldValue(_data); + if ( column==2 && value!=oldValue ) ncg.setColor(QColorGroup::Text, red); + EditListViewItem::paintCell(p, ncg, column, width, align); +} + +QString Register::ListViewItem::tooltip(int col) const +{ + if ( col!=2 ) return QString::null; + BitValue value = Register::list().value(_data); + if ( !value.isInitialized() ) return QString::null; + BitValue v = value; + QString s; + for (uint i=0; i<_data.nbChars(); i++) { + char c = v.nybble(i); + if ( isprint(c) ) s = c + s; + else s = "." + s; + } + return QString("%1 - %2 - \"%3\"").arg(toHexLabel(value, _data.nbChars())) + .arg(toLabel(NumberBase::Bin, value, 4*_data.nbChars())).arg(s); +} + +QWidget *Register::ListViewItem::editWidgetFactory(int col) const +{ + if ( col!=2 || Main::programmerState()!=Programmer::Halted ) return 0; + return new NumberLineEdit(text(), 0); +} + +void Register::ListViewItem::editDone(int col, const QWidget *edit) +{ + if ( col!=2 ) return; + bool ok; + ulong value = static_cast(edit)->value(&ok); + if (ok) Debugger::manager->writeRegister(_data, value); +} + +//---------------------------------------------------------------------------- +Register::LineEdit::LineEdit(QWidget *parent, const char *name) + : NumberLineEdit(parent, name), _base(NumberBase::Nb_Types) +{ + connect(this, SIGNAL(lostFocus()), SLOT(updateText())); + connect(this, SIGNAL(returnPressed()), SLOT(returnPressedSlot())); +} + +void Register::LineEdit::updateText() +{ + setText(_value.isInitialized() ? toLabel(_base, _value, _nbChars) : "--"); + uint w = 2*frameWidth() + maxLabelWidth(_base, _nbChars, font()); + setFixedWidth(w+5); + setFixedHeight(minimumSizeHint().height()); +} + +void Register::LineEdit::setValue(NumberBase base, BitValue value, uint nbChars) +{ + _base = base; + _value = value; + _nbChars = nbChars; + updateText(); +} + +void Register::LineEdit::returnPressedSlot() +{ + bool ok; + uint v = fromAnyLabel(text(), &ok); + if (ok) _value = v; + updateText(); + emit modified(); +} + +void Register::LineEdit::keyPressEvent(QKeyEvent *e) +{ + if ( e->key()==Key_Escape ) clearFocus(); + else NumberLineEdit::keyPressEvent(e); +} + +//---------------------------------------------------------------------------- +Register::View::View(QWidget *parent, const char *name) + : QFrame(parent, name), GenericView(list()) +{} diff --git a/src/devices/gui/register_view.h b/src/devices/gui/register_view.h new file mode 100644 index 0000000..7ef8a54 --- /dev/null +++ b/src/devices/gui/register_view.h @@ -0,0 +1,105 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef REGISTER_VIEW_H +#define REGISTER_VIEW_H + +#include + +#include "devices/base/register.h" +#include "common/gui/number_gui.h" +#include "common/gui/list_view.h" + +namespace Register +{ +enum { PortBitRtti = 1000, RegisterRtti = 1001 }; + +//----------------------------------------------------------------------------- +class PortBitListViewItem : public KListViewItem +{ +public: + PortBitListViewItem(uint address, uint bit, KListViewItem *parent); + virtual int rtti() const { return PortBitRtti; } + void updateView(); + QString tooltip(int column) const; + +private: + uint _index, _bit; + + virtual void paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int align); +}; + +//----------------------------------------------------------------------------- +class ListViewItem : public EditListViewItem +{ +public: + ListViewItem(const TypeData &data, KListViewItem *item); + virtual int rtti() const { return RegisterRtti; } + virtual void updateView(); + const TypeData &data() const { return _data; } + QString tooltip(int column) const; + NumberBase base() const { return _base; } + void setBase(NumberBase base); + virtual QString label() const = 0; + virtual int compare(QListViewItem *item, int, bool) const; + +protected: + TypeData _data; + QValueList _items; + NumberBase _base; + + virtual void paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int align); + virtual QWidget *editWidgetFactory(int col) const; + virtual bool alwaysAcceptEdit(int) const { return false; } + virtual void editDone(int col, const QWidget *editWidget); + virtual uint nbCharsAddress() const = 0; + virtual QString text() const; + virtual void activate() {} +}; + +//----------------------------------------------------------------------------- +class LineEdit : public NumberLineEdit +{ +Q_OBJECT +public: + LineEdit(QWidget *parent, const char *name = 0); + void setValue(NumberBase base, BitValue value, uint nbChars); + BitValue value() const { return _value; } + +signals: + void modified(); + +protected: + virtual void keyPressEvent(QKeyEvent *e); + +private slots: + void updateText(); + void returnPressedSlot(); + +private: + NumberBase _base; + BitValue _value; + uint _nbChars; +}; + +//----------------------------------------------------------------------------- +class View : public QFrame, public GenericView +{ +Q_OBJECT +public: + View(QWidget *parent, const char *name); + +signals: + void readSignal(uint address); + void writeSignal(uint address, uint value); + void setWatchedSignal(uint address, bool watched); +}; + +} // namespace + +#endif diff --git a/src/devices/list/Makefile.am b/src/devices/list/Makefile.am new file mode 100644 index 0000000..ce1c03a --- /dev/null +++ b/src/devices/list/Makefile.am @@ -0,0 +1,11 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + + +noinst_LTLIBRARIES = libdevicelistnoui.la libdevicelistui.la + +libdevicelistnoui_la_LDFLAGS = $(all_libraries) +libdevicelistnoui_la_SOURCES = device_list.cpp device_list_noui.cpp + +libdevicelistui_la_LDFLAGS = $(all_libraries) +libdevicelistui_la_SOURCES = device_list.cpp device_list_ui.cpp diff --git a/src/devices/list/device_list.cpp b/src/devices/list/device_list.cpp new file mode 100644 index 0000000..1434ec8 --- /dev/null +++ b/src/devices/list/device_list.cpp @@ -0,0 +1,40 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "device_list.h" + +#include + +#include "devices/pic/pic/pic_group.h" +#include "devices/mem24/mem24/mem24_group.h" + +const Device::AutoData Device::AUTO_DATA = { "*", I18N_NOOP("") }; + +const Device::Data *Device::Lister::data(const QString &device) const +{ + for (ConstIterator it=begin(); it!=end(); it++) { + const Data *data = static_cast(it.data()->deviceData(device).data); + if (data) return data; + } + return 0; +} + +QString Device::Lister::checkName(const QString &device) const +{ + if ( device==AUTO_DATA.name ) return device; + if ( isSupported(device) ) return device; + if ( device.startsWith("p") ) // compat mode for PiKdev + return checkName(device.mid(1)); + return "16F871"; // default... +} + +namespace Device +{ + Lister _lister; + const Lister &lister() { return _lister; } +} diff --git a/src/devices/list/device_list.h b/src/devices/list/device_list.h new file mode 100644 index 0000000..3d9fb78 --- /dev/null +++ b/src/devices/list/device_list.h @@ -0,0 +1,34 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef DEVICE_LIST_H +#define DEVICE_LIST_H + +#include "devices/base/generic_device.h" +#include "common/common/lister.h" + +namespace Device +{ + +struct AutoData { + const char *name, *label; +}; +extern const AutoData AUTO_DATA; + +class Lister : public ::Group::Lister +{ +public: + Lister(); + const Data *data(const QString &device) const; + QString checkName(const QString &device) const; +}; +extern const Lister &lister(); + +} // namespace + +#endif diff --git a/src/devices/list/device_list_noui.cpp b/src/devices/list/device_list_noui.cpp new file mode 100644 index 0000000..46d909e --- /dev/null +++ b/src/devices/list/device_list_noui.cpp @@ -0,0 +1,18 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "device_list.h" + +#include "devices/pic/pic/pic_group.h" +#include "devices/mem24/mem24/mem24_group.h" + +Device::Lister::Lister() +{ + addGroup(new Pic::Group, 0); + addGroup(new Mem24::Group, 0); +} diff --git a/src/devices/list/device_list_ui.cpp b/src/devices/list/device_list_ui.cpp new file mode 100644 index 0000000..ebcd7ea --- /dev/null +++ b/src/devices/list/device_list_ui.cpp @@ -0,0 +1,20 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "device_list.h" + +#include "devices/pic/pic/pic_group.h" +#include "devices/pic/gui/pic_group_ui.h" +#include "devices/mem24/mem24/mem24_group.h" +#include "devices/mem24/gui/mem24_group_ui.h" + +Device::Lister::Lister() +{ + addGroup(new Pic::Group, new Pic::GroupUI); + addGroup(new Mem24::Group, new Mem24::GroupUI); +} diff --git a/src/devices/list/list.pro b/src/devices/list/list.pro new file mode 100644 index 0000000..02f07b0 --- /dev/null +++ b/src/devices/list/list.pro @@ -0,0 +1,6 @@ +STOPDIR = ../../.. +include($${STOPDIR}/lib.pro) + +TARGET = devicelist +HEADERS += device_list.h +SOURCES += device_list.cpp device_list_noui.cpp diff --git a/src/devices/mem24/Makefile.am b/src/devices/mem24/Makefile.am new file mode 100644 index 0000000..7c80d86 --- /dev/null +++ b/src/devices/mem24/Makefile.am @@ -0,0 +1,3 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +SUBDIRS = base xml xml_data mem24 prog gui diff --git a/src/devices/mem24/base/Makefile.am b/src/devices/mem24/base/Makefile.am new file mode 100644 index 0000000..336afca --- /dev/null +++ b/src/devices/mem24/base/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libmem24base.la +libmem24base_la_LDFLAGS = $(all_libraries) +libmem24base_la_SOURCES = mem24.cpp diff --git a/src/devices/mem24/base/base.pro b/src/devices/mem24/base/base.pro new file mode 100644 index 0000000..a42b768 --- /dev/null +++ b/src/devices/mem24/base/base.pro @@ -0,0 +1,6 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/lib.pro) + +TARGET = mem24base +HEADERS += mem24.h +SOURCES += mem24.cpp diff --git a/src/devices/mem24/base/mem24.cpp b/src/devices/mem24/base/mem24.cpp new file mode 100644 index 0000000..03bffe3 --- /dev/null +++ b/src/devices/mem24/base/mem24.cpp @@ -0,0 +1,22 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "mem24.h" + +QDataStream &Mem24::operator <<(QDataStream &s, const Data &data) +{ + s << static_cast(data); + s << data._nbBytes << data._nbBlocks << data._nbBytesPage; + return s; +} +QDataStream &Mem24::operator >>(QDataStream &s, Data &data) +{ + s >> static_cast(data); + s >> data._nbBytes >> data._nbBlocks >> data._nbBytesPage; + return s; +} diff --git a/src/devices/mem24/base/mem24.h b/src/devices/mem24/base/mem24.h new file mode 100644 index 0000000..d66ff47 --- /dev/null +++ b/src/devices/mem24/base/mem24.h @@ -0,0 +1,47 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef MEM24_H +#define MEM24_H + +#include "common/common/misc.h" +#include "devices/base/generic_device.h" + +namespace Mem24 +{ +class XmlToData; +class Group; + +//----------------------------------------------------------------------------- +class Data : public Device::Data +{ +public: + Data() : Device::Data(0) {} + virtual QString listViewGroup() const { return i18n("24 EEPROM"); } + uint nbBytes() const { return _nbBytes; } + virtual bool matchId(BitValue, Device::IdData &) const { return false; } + virtual uint nbBitsAddress() const { return nbBits(_nbBytes-1); } + virtual bool canWriteCalibration() const { return false; } + uint nbBlocks() const { return _nbBlocks; } + uint nbBytesPage() const { return _nbBytesPage; } + +private: + uint _nbBytes, _nbBlocks, _nbBytesPage; + + friend class XmlToData; + friend class Group; + friend QDataStream &operator <<(QDataStream &s, const Data &data); + friend QDataStream &operator >>(QDataStream &s, Data &data); +}; + +QDataStream &operator <<(QDataStream &s, const Data &data); +QDataStream &operator >>(QDataStream &s, Data &data); + +} // namespace + +#endif diff --git a/src/devices/mem24/gui/Makefile.am b/src/devices/mem24/gui/Makefile.am new file mode 100644 index 0000000..6838d57 --- /dev/null +++ b/src/devices/mem24/gui/Makefile.am @@ -0,0 +1,7 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libmem24ui.la +libmem24ui_la_SOURCES = mem24_hex_view.cpp mem24_memory_editor.cpp \ + mem24_group_ui.cpp +libmem24ui_la_LDFLAGS = $(all_libraries) diff --git a/src/devices/mem24/gui/mem24_group_ui.cpp b/src/devices/mem24/gui/mem24_group_ui.cpp new file mode 100644 index 0000000..751e5a7 --- /dev/null +++ b/src/devices/mem24/gui/mem24_group_ui.cpp @@ -0,0 +1,16 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "mem24_group_ui.h" + +#include "mem24_hex_view.h" + +Device::HexView *Mem24::GroupUI::createHexView(const HexEditor &editor, QWidget *parent) const +{ + return new HexView(editor, parent); +} diff --git a/src/devices/mem24/gui/mem24_group_ui.h b/src/devices/mem24/gui/mem24_group_ui.h new file mode 100644 index 0000000..37766b5 --- /dev/null +++ b/src/devices/mem24/gui/mem24_group_ui.h @@ -0,0 +1,28 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef MEM24_GROUP_UI_H +#define MEM24_GROUP_UI_H + +#include "devices/gui/device_group_ui.h" + +namespace Mem24 +{ +class GroupUI : public Device::GroupUI +{ +public: + virtual Device::HexView *createHexView(const HexEditor &editor, QWidget *parent) const; + virtual Register::View *createRegisterView(QWidget *) const { return 0; } + virtual Device::MemoryEditor *createConfigEditor(Device::Memory &, QWidget *) const { return 0; } + virtual void fillWatchListContainer(ListContainer *, QValueVector &) const {} + virtual Register::ListViewItem *createWatchItem(const Register::TypeData &, KListViewItem *) const { return 0; } +}; + +} // namespace + +#endif diff --git a/src/devices/mem24/gui/mem24_hex_view.cpp b/src/devices/mem24/gui/mem24_hex_view.cpp new file mode 100644 index 0000000..0ada8d0 --- /dev/null +++ b/src/devices/mem24/gui/mem24_hex_view.cpp @@ -0,0 +1,38 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "mem24_hex_view.h" + +#include +#include +#include + +#include "mem24_memory_editor.h" + +Mem24::HexView::HexView(const HexEditor &editor, QWidget *parent) + : Device::HexView(editor, parent, "mem24_hex_view") +{} + +void Mem24::HexView::display() +{ + Memory *pmemory = static_cast(_memory); + MemoryTypeEditor *e = new MemoryTypeEditor(this, *pmemory, this); + e->init(true); + e->show(); + _top->addWidget(e); + addEditor(e); +} + +BitValue Mem24::HexView::checksum() const +{ + if ( _memory==0 ) return 0x0000; + BitValue cs = 0x0000; + for (uint i=0; i(_memory->device()).nbBytes(); i++) + cs += static_cast(_memory)->byte(i); + return cs.maskWith(0xFFFF); +} diff --git a/src/devices/mem24/gui/mem24_hex_view.h b/src/devices/mem24/gui/mem24_hex_view.h new file mode 100644 index 0000000..378a25e --- /dev/null +++ b/src/devices/mem24/gui/mem24_hex_view.h @@ -0,0 +1,33 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef MEM24_HEX_VIEW_H +#define MEM24_HEX_VIEW_H + +class QVBoxLayout; + +#include "devices/gui/hex_view.h" + +namespace Mem24 +{ + +class HexView : public Device::HexView +{ +Q_OBJECT +public: + HexView(const HexEditor &editor, QWidget *parent); + virtual uint nbChecksumChars() const { return 4; } + virtual BitValue checksum() const; + +private: + virtual void display(); +}; + +} // namespace + +#endif diff --git a/src/devices/mem24/gui/mem24_memory_editor.cpp b/src/devices/mem24/gui/mem24_memory_editor.cpp new file mode 100644 index 0000000..61f98fe --- /dev/null +++ b/src/devices/mem24/gui/mem24_memory_editor.cpp @@ -0,0 +1,80 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "mem24_memory_editor.h" + +#include +#include +#include + +#include "common/gui/misc_gui.h" +#include "mem24_hex_view.h" +#include "progs/base/generic_prog.h" +#include "libgui/main_global.h" +#include "devices/base/device_group.h" + +//----------------------------------------------------------------------------- +Mem24::MemoryRangeEditor::MemoryRangeEditor(Memory &memory, QWidget *parent) + : Device::MemoryRangeEditor(memory, 16, 16, 0, -1, parent, "mem24_memory_range_editor"), + MemoryCaster(memory) +{} + +Device::HexWordEditor *Mem24::MemoryRangeEditor::createHexWordEditor(QWidget *parent) +{ + return new HexWordEditor(memory(), parent); +} + +//----------------------------------------------------------------------------- +Mem24::MemoryTypeEditor::MemoryTypeEditor(const HexView *hexview, Memory &memory, QWidget *parent) + : Device::MemoryTypeEditor(hexview, memory, parent, "mem24_memory_type_editor"), + MemoryCaster(memory) +{} + +void Mem24::MemoryTypeEditor::init(bool first) +{ + Device::MemoryTypeEditor::init(first); + _title->setText(i18n("EEPROM Memory")); + MemoryRangeEditor *mre = new MemoryRangeEditor(memory(), this); + mre->init(); + addEditor(mre); + _top->addWidget(mre); +} + +bool Mem24::MemoryTypeEditor::internalDoAction(Device::Action action) +{ + switch (action) { + case Device::Clear: + case Device::ChecksumCheck: + memory().clear(); return true; + case Device::Zero: memory().fill(0); return true; + case Device::Reload: + Q_ASSERT(originalMemory()); + memory().copyFrom(*originalMemory()); return true; + case Device::Program: + Main::programmer()->program(memory(), Device::MemoryRange()); + return false; + case Device::Verify: + Main::programmer()->verify(memory(), Device::MemoryRange()); + return false; + case Device::Read: { + Memory mem(device()); + if ( !Main::programmer()->read(mem, Device::MemoryRange()) ) return false; + memory().copyFrom(mem); + return true; + } + case Device::Erase: + Main::programmer()->erase(Device::MemoryRange()); + return false; + case Device::BlankCheck: + Main::programmer()->blankCheck(Device::MemoryRange()); + return false; + case Device::Nb_Actions: break; + } + Q_ASSERT(false); + return false; +} diff --git a/src/devices/mem24/gui/mem24_memory_editor.h b/src/devices/mem24/gui/mem24_memory_editor.h new file mode 100644 index 0000000..eb99e97 --- /dev/null +++ b/src/devices/mem24/gui/mem24_memory_editor.h @@ -0,0 +1,77 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef MEM24_MEMORY_EDITOR_H +#define MEM24_MEMORY_EDITOR_H + +#include "devices/gui/memory_editor.h" +#include "devices/gui/hex_word_editor.h" +#include "devices/mem24/mem24/mem24_memory.h" + +namespace Mem24 +{ +class HexView; + +//----------------------------------------------------------------------------- +class MemoryCaster +{ +public: + MemoryCaster(Memory &memory) : _memory(memory) {} + const Data &device() const { return static_cast(_memory.device()); } + const Memory &memory() const { return static_cast(_memory); } + Memory &memory() { return static_cast(_memory); } + +private: + Memory &_memory; +}; + +//----------------------------------------------------------------------------- +class HexWordEditor : public Device::HexWordEditor, public MemoryCaster +{ +Q_OBJECT +public: + HexWordEditor(Memory &memory, QWidget *parent) + : Device::HexWordEditor(memory, 2, parent), MemoryCaster(memory) {} + +private: + virtual BitValue mask() const { return 0xFF; } + virtual BitValue normalizeWord(BitValue value) const { return value; } + virtual BitValue word() const { return memory().byte(_offset); } + virtual void setWord(BitValue value) { memory().setByte(_offset, value); } +}; + +//----------------------------------------------------------------------------- +class MemoryRangeEditor : public Device::MemoryRangeEditor, public MemoryCaster +{ +Q_OBJECT +public: + MemoryRangeEditor(Memory &memory, QWidget *parent); + +private: + virtual uint nbWords() const { return device().nbBytes(); } + virtual uint addressIncrement() const { return 1; } + virtual Address startAddress() const { return 0x0; } + virtual Device::HexWordEditor *createHexWordEditor(QWidget *parent); + virtual bool isRangeReadOnly() const { return false; } +}; + +//----------------------------------------------------------------------------- +class MemoryTypeEditor : public Device::MemoryTypeEditor, public MemoryCaster +{ +Q_OBJECT +public: + MemoryTypeEditor(const HexView *hexview, Memory &memory, QWidget *parent); + virtual void init(bool first); + +private: + virtual bool internalDoAction(Device::Action action); +}; + +} // namespace + +#endif diff --git a/src/devices/mem24/mem24.pro b/src/devices/mem24/mem24.pro new file mode 100644 index 0000000..0602143 --- /dev/null +++ b/src/devices/mem24/mem24.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = base xml mem24 xml_data prog diff --git a/src/devices/mem24/mem24/Makefile.am b/src/devices/mem24/mem24/Makefile.am new file mode 100644 index 0000000..3c7e9a8 --- /dev/null +++ b/src/devices/mem24/mem24/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libmem24.la +libmem24_la_LDFLAGS = $(all_libraries) +libmem24_la_SOURCES = mem24_memory.cpp mem24_group.cpp diff --git a/src/devices/mem24/mem24/mem24.pro b/src/devices/mem24/mem24/mem24.pro new file mode 100644 index 0000000..4bdbea4 --- /dev/null +++ b/src/devices/mem24/mem24/mem24.pro @@ -0,0 +1,6 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/lib.pro) + +TARGET = mem24 +HEADERS += mem24_memory.h mem24_group.h +SOURCES += mem24_memory.cpp mem24_group.cpp diff --git a/src/devices/mem24/mem24/mem24_group.cpp b/src/devices/mem24/mem24/mem24_group.cpp new file mode 100644 index 0000000..53cad5b --- /dev/null +++ b/src/devices/mem24/mem24/mem24_group.cpp @@ -0,0 +1,43 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "mem24_group.h" + +#include "mem24_memory.h" + +Device::Memory *Mem24::Group::createMemory(const Device::Data &data) const +{ + return new Memory(static_cast(data)); +} + +QString Mem24::Group::informationHtml(const Device::Data &data) const +{ + const Mem24::Data &mdata = static_cast(data); + QString tmp = i18n("%1 bytes").arg(formatNumber(mdata.nbBytes())); + return htmlTableRow(i18n("Memory Size"), tmp); +} + +#if !defined(NO_KDE) +QPixmap Mem24::Group::memoryGraph(const Device::Data &data) const +{ + const Mem24::Data &mdata = static_cast(data); + uint offset = 0x0; + QValueList ranges; + for (uint i=0; i * + * * + * 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. * + ***************************************************************************/ +#ifndef MEM24_GROUP_H +#define MEM24_GROUP_H + +#include "common/global/global.h" +#include "devices/base/device_group.h" +#include "devices/mem24/base/mem24.h" + +namespace Mem24 +{ +extern const uint DATA_SIZE; +extern const char *DATA_STREAM; + +class Group : public Device::Group +{ +public: + virtual QString name() const { return "mem24"; } + virtual QString label() const { return i18n("Serial Memory 24"); } + virtual Device::Memory *createMemory(const Device::Data &data) const; + virtual QString informationHtml(const Device::Data &data) const; +#if !defined(NO_KDE) + virtual QPixmap memoryGraph(const Device::Data &data) const; +#endif + +private: + virtual uint dataSize() const { return DATA_SIZE; } + virtual const char *dataStream() const { return DATA_STREAM; } +}; + +} // namespace + +#endif diff --git a/src/devices/mem24/mem24/mem24_memory.cpp b/src/devices/mem24/mem24/mem24_memory.cpp new file mode 100644 index 0000000..a4296ea --- /dev/null +++ b/src/devices/mem24/mem24/mem24_memory.cpp @@ -0,0 +1,92 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "mem24_memory.h" + +#include + +#include "common/global/global.h" +#include "common/common/misc.h" + +Mem24::Memory::Memory(const Data &data) + : Device::Memory(data) +{ + fill(BitValue()); +} + +void Mem24::Memory::fill(BitValue value) +{ + _data = Device::Array(device().nbBytes()); + for (uint i=0; i<_data.count(); i++) _data[i] = value; +} + +void Mem24::Memory::copyFrom(const Device::Memory &memory) +{ + Q_ASSERT( device().name()==memory.device().name() ); + _data = static_cast(memory)._data; +} + +Device::Array Mem24::Memory::arrayForWriting() const +{ + Device::Array data(_data.count()); + for (uint i=0; ioffset ); + return _data[offset]; +} + +void Mem24::Memory::setByte(uint offset, BitValue value) +{ + Q_ASSERT( _data.size()>offset ); + Q_ASSERT( value<=0xFF ); + _data[offset] = value; +} + +BitValue Mem24::Memory::checksum() const +{ + BitValue cs = 0x0000; + for (uint i=0; i<_data.count(); i++) cs += _data[i]; + return cs.maskWith(0xFFFF); +} + +//----------------------------------------------------------------------------- +void Mem24::Memory::savePartial(QTextStream &stream, HexBuffer::Format format) const +{ + HexBuffer hb = toHexBuffer(); + hb.savePartial(stream, format); +} + +//----------------------------------------------------------------------------- +HexBuffer Mem24::Memory::toHexBuffer() const +{ + HexBuffer hb; + for (uint k=0; k &inRange) +{ + BitValue mask = 0xFF; + for (uint k=0; k * + * * + * 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. * + ***************************************************************************/ +#ifndef MEM24_MEMORY_H +#define MEM24_MEMORY_H + +#include "common/global/global.h" +#include "devices/base/generic_memory.h" +#include "devices/base/hex_buffer.h" +#include "devices/mem24/base/mem24.h" + +namespace Mem24 +{ + +class Memory : public Device::Memory +{ +public: + Memory(const Data &data); + const Data &device() const { return static_cast(_device); } + virtual void fill(BitValue value); + virtual void checksumCheckFill() { clear(); } + Device::Array arrayForWriting() const; + BitValue byte(uint offset) const; + void setByte(uint offset, BitValue value); + virtual BitValue checksum() const; + + virtual HexBuffer toHexBuffer() const; + virtual void copyFrom(const Device::Memory &memory); + +private: + Device::Array _data; + + virtual void savePartial(QTextStream &stream, HexBuffer::Format format) const; + virtual void fromHexBuffer(const HexBuffer &hb, WarningTypes &warningTypes, + QStringList &warnings, QMap &inRange); +}; + +} // namespace + +#endif diff --git a/src/devices/mem24/prog/Makefile.am b/src/devices/mem24/prog/Makefile.am new file mode 100644 index 0000000..1c1a55e --- /dev/null +++ b/src/devices/mem24/prog/Makefile.am @@ -0,0 +1,5 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libmem24prog.la +libmem24prog_la_SOURCES = mem24_prog.cpp diff --git a/src/devices/mem24/prog/mem24_prog.cpp b/src/devices/mem24/prog/mem24_prog.cpp new file mode 100644 index 0000000..4c4b201 --- /dev/null +++ b/src/devices/mem24/prog/mem24_prog.cpp @@ -0,0 +1,88 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "mem24_prog.h" + +#include "common/global/global.h" +#include "devices/list/device_list.h" +#include "progs/base/prog_config.h" + +//----------------------------------------------------------------------------- +bool Programmer::Mem24DeviceSpecific::read(Device::Array &data, const VerifyData *vdata) +{ + setPowerOn(); + doRead(data, vdata); + setPowerOff(); + return !hasError(); +} + +bool Programmer::Mem24DeviceSpecific::write(const Device::Array &data) +{ + setPowerOn(); + doWrite(data); + setPowerOff(); + return !hasError(); +} + +bool Programmer::Mem24DeviceSpecific::verifyByte(uint index, BitValue d, const VerifyData &vdata) +{ + BitValue v = static_cast(vdata.memory).byte(index); + v = v.maskWith(0xFF); + d = d.maskWith(0xFF); + if ( v==d ) return true; + Address address = index; + if ( vdata.actions & BlankCheckVerify ) + log(Log::LineType::Error, i18n("Device memory is not blank (at address %1: reading %2 and expecting %3).") + .arg(toHexLabel(address, device().nbCharsAddress())).arg(toHexLabel(d, 2)).arg(toHexLabel(v, 2))); + else log(Log::LineType::Error, i18n("Device memory doesn't match hex file (at address %1: reading %2 and expecting %3).") + .arg(toHexLabel(address, device().nbCharsAddress())).arg(toHexLabel(d, 2)).arg(toHexLabel(v, 2))); + return false; +} + +//---------------------------------------------------------------------------- +uint Programmer::Mem24Base::nbSteps(Task task, const Device::MemoryRange *) const +{ + uint nb = device()->nbBytes(); + if ( task==Task::Write && readConfigEntry(Config::VerifyAfterProgram).toBool() ) nb += device()->nbBytes(); + return nb; +} + +bool Programmer::Mem24Base::internalErase(const Device::MemoryRange &) +{ + initProgramming(); + Mem24::Memory memory(*device()); + return specific()->write(memory.arrayForWriting()); +} + +bool Programmer::Mem24Base::internalRead(Device::Memory *memory, const Device::MemoryRange &, const VerifyData *vdata) +{ + initProgramming(); + Device::Array data; + if ( !specific()->read(data, vdata) ) return false; + if (memory) for (uint i=0; i(memory)->setByte(i, data[i]); + return true; +} + +bool Programmer::Mem24Base::internalProgram(const Device::Memory &memory, const Device::MemoryRange &) +{ + initProgramming(); + const Mem24::Memory &pmemory = static_cast(memory); + const Device::Array &data = pmemory.arrayForWriting(); + if ( !specific()->write(data) ) return false; + if ( !readConfigEntry(Config::VerifyAfterProgram).toBool() ) return true; + VerifyActions actions = IgnoreProtectedVerify; + if ( readConfigEntry(Config::OnlyVerifyProgrammed).toBool() ) actions |= OnlyProgrammedVerify; + VerifyData vdata(actions, pmemory); + Device::Array adata; + return specific()->read(adata, &vdata); +} + +bool Programmer::Mem24Base::verifyDeviceId() +{ + return specific()->verifyPresence(); +} diff --git a/src/devices/mem24/prog/mem24_prog.h b/src/devices/mem24/prog/mem24_prog.h new file mode 100644 index 0000000..86948c2 --- /dev/null +++ b/src/devices/mem24/prog/mem24_prog.h @@ -0,0 +1,63 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef MEM24_PROG_H +#define MEM24_PROG_H + +#include "progs/base/generic_prog.h" +#include "devices/mem24/mem24/mem24_memory.h" + +namespace Programmer +{ +//----------------------------------------------------------------------------- +class Mem24DeviceSpecific : public DeviceSpecific +{ +public: + Mem24DeviceSpecific(::Programmer::Base &base) : DeviceSpecific(base) {} + const Mem24::Data &device() const { return static_cast(*_base.device()); } + bool read(Device::Array &data, const VerifyData *vdata); + bool write(const Device::Array &data); + bool verifyByte(uint index, BitValue d, const VerifyData &vdata); + virtual bool verifyPresence() = 0; + +protected: + virtual bool doRead(Device::Array &data, const VerifyData *vdata) = 0; + virtual bool doWrite(const Device::Array &data) = 0; +}; + +//----------------------------------------------------------------------------- +class Mem24Hardware : public Hardware +{ +public: + Mem24Hardware(::Programmer::Base &base, Port::Base *port, const QString &name) : Hardware(base, port, name) {} + const Mem24::Data &device() const { return static_cast(*_base.device()); } +}; + +//----------------------------------------------------------------------------- +class Mem24Base : public Base +{ +public: + Mem24Base(const Group &group, const Mem24::Data *data, const char *name) : Base(group, data, name) {} + const Mem24::Data *device() const { return static_cast(_device); } + +protected: + Mem24DeviceSpecific *specific() const { return static_cast(_specific); } + virtual bool verifyDeviceId(); + virtual uint nbSteps(Task task, const Device::MemoryRange *range) const; + virtual bool initProgramming() { return true; } + virtual bool checkErase() { return true; } + virtual bool internalErase(const Device::MemoryRange &range); + virtual bool checkRead() { return true; } + virtual bool internalRead(Device::Memory *memory, const Device::MemoryRange &range, const VerifyData *vdata); + virtual bool checkProgram(const Device::Memory &) { return true; } + virtual bool internalProgram(const Device::Memory &memory, const Device::MemoryRange &range); +}; + +} // namespace + +#endif diff --git a/src/devices/mem24/prog/prog.pro b/src/devices/mem24/prog/prog.pro new file mode 100644 index 0000000..2acd347 --- /dev/null +++ b/src/devices/mem24/prog/prog.pro @@ -0,0 +1,6 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/lib.pro) + +TARGET = mem24prog +HEADERS += mem24_prog.h +SOURCES += mem24_prog.cpp diff --git a/src/devices/mem24/xml/Makefile.am b/src/devices/mem24/xml/Makefile.am new file mode 100644 index 0000000..88a4305 --- /dev/null +++ b/src/devices/mem24/xml/Makefile.am @@ -0,0 +1,12 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_PROGRAMS = mem24_xml_to_data + +mem24_xml_to_data_SOURCES = mem24_xml_to_data.cpp +mem24_xml_to_data_DEPENDENCIES = $(top_builddir)/src/devices/mem24/base/libmem24base.la \ + $(top_builddir)/src/xml_to_data/libxmltodata.la $(top_builddir)/src/devices/base/libdevicebase.la \ + $(top_builddir)/src/common/common/libcommon.la +mem24_xml_to_data_LDADD = $(top_builddir)/src/devices/mem24/base/libmem24base.la \ + $(top_builddir)/src/xml_to_data/libxmltodata.la $(top_builddir)/src/devices/base/libdevicebase.la \ + $(top_builddir)/src/common/common/libcommon.la $(LIB_KDECORE) diff --git a/src/devices/mem24/xml/mem24_xml_to_data.cpp b/src/devices/mem24/xml/mem24_xml_to_data.cpp new file mode 100644 index 0000000..734ebca --- /dev/null +++ b/src/devices/mem24/xml/mem24_xml_to_data.cpp @@ -0,0 +1,60 @@ +/*************************************************************************** + * Copyright (C) 2006-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include +#include + +#include "xml_to_data/device_xml_to_data.h" +#include "common/common/misc.h" +#include "devices/mem24/base/mem24.h" + +namespace Mem24 +{ + +class XmlToData : public Device::XmlToData +{ +private: + virtual uint nbOutputFiles(uint) const { return 1; } + virtual bool isIncluded(uint, uint) const { return true; } + virtual QString namespaceName() const { return "Mem24"; } + +virtual void processDevice(QDomElement device) +{ + Device::XmlToDataBase::processDevice(device); + + QDomElement e = findUniqueElement(device, "memory", "name", QString::null); + bool ok; + data()->_nbBytes = fromHexLabel(e.attribute("size"), &ok); + if ( !ok ) qFatal("Missing or invalid size"); + data()->_nbBlocks = e.attribute("nb_blocks").toUInt(&ok); + if ( !ok || data()->_nbBlocks==0 ) qFatal("Missing, zero, or invalid nb_blocks"); + if ( (data()->_nbBytes % data()->_nbBlocks)!=0 ) qFatal("nb_blocks should divide size"); + if ( data()->_nbBlocks>8 ) qFatal("nb_blocks is too large (>8)"); + data()->_nbBytesPage = e.attribute("page_size").toUInt(&ok); + if ( !ok || data()->_nbBytesPage==0 ) qFatal("Missing, zero, or invalid page_size"); + if ( ((data()->_nbBytes/data()->_nbBlocks) % data()->_nbBytesPage)!=0 ) qFatal("page_size should divide size/nb_blocks"); + QStringList names; + names.append(QString::null); + checkTagNames(device, "memory", names); +} + +virtual void checkPins(const QMap &pinLabels) const +{ + if ( !pinLabels.contains("VCC") ) qFatal("No VDD pin specified"); + if ( !pinLabels.contains("VSS") ) qFatal("No VSS pin specified"); + QMap::const_iterator it; + for (it=pinLabels.begin(); it!=pinLabels.end(); ++it) + if ( it.data()!=1 ) qFatal(QString("Duplicated pin %1").arg(it.key())); +} + +}; // class + +} // namespace + +//----------------------------------------------------------------------------- +XML_MAIN(Mem24::XmlToData) diff --git a/src/devices/mem24/xml/xml.pro b/src/devices/mem24/xml/xml.pro new file mode 100644 index 0000000..9730b29 --- /dev/null +++ b/src/devices/mem24/xml/xml.pro @@ -0,0 +1,13 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/app.pro) + +TARGET = mem24_xml_to_data +SOURCES += mem24_xml_to_data.cpp +LIBS += ../../../devices/mem24/base/libmem24base.a ../../../xml_to_data/libxmltodata.a \ + ../../../devices/base/libdevicebase.a ../../../common/global/libglobal.a \ + ../../../common/nokde/libnokde.a ../../../common/common/libcommon.a + +unix:QMAKE_POST_LINK = cd ../xml_data && ../xml/mem24_xml_to_data +unix:QMAKE_CLEAN += ../xml_data/mem24_data.cpp +win32:QMAKE_POST_LINK = cd ..\xml_data && ..\xml\mem24_xml_to_data.exe +win32:QMAKE_CLEAN += ..\xml_data\mem24_data.cpp diff --git a/src/devices/mem24/xml_data/24AA00.xml b/src/devices/mem24/xml_data/24AA00.xml new file mode 100644 index 0000000..6b9e114 --- /dev/null +++ b/src/devices/mem24/xml_data/24AA00.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24AA01.xml b/src/devices/mem24/xml_data/24AA01.xml new file mode 100644 index 0000000..f3aa59d --- /dev/null +++ b/src/devices/mem24/xml_data/24AA01.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24AA014.xml b/src/devices/mem24/xml_data/24AA014.xml new file mode 100644 index 0000000..91b93ca --- /dev/null +++ b/src/devices/mem24/xml_data/24AA014.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24AA02.xml b/src/devices/mem24/xml_data/24AA02.xml new file mode 100644 index 0000000..a4c3174 --- /dev/null +++ b/src/devices/mem24/xml_data/24AA02.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24AA024.xml b/src/devices/mem24/xml_data/24AA024.xml new file mode 100644 index 0000000..7d2bfe5 --- /dev/null +++ b/src/devices/mem24/xml_data/24AA024.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24AA025.xml b/src/devices/mem24/xml_data/24AA025.xml new file mode 100644 index 0000000..174c163 --- /dev/null +++ b/src/devices/mem24/xml_data/24AA025.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24AA04.xml b/src/devices/mem24/xml_data/24AA04.xml new file mode 100644 index 0000000..18ca2ac --- /dev/null +++ b/src/devices/mem24/xml_data/24AA04.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24AA08.xml b/src/devices/mem24/xml_data/24AA08.xml new file mode 100644 index 0000000..84852f2 --- /dev/null +++ b/src/devices/mem24/xml_data/24AA08.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24AA1025.xml b/src/devices/mem24/xml_data/24AA1025.xml new file mode 100644 index 0000000..54940f3 --- /dev/null +++ b/src/devices/mem24/xml_data/24AA1025.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24AA128.xml b/src/devices/mem24/xml_data/24AA128.xml new file mode 100644 index 0000000..bf113e8 --- /dev/null +++ b/src/devices/mem24/xml_data/24AA128.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24AA16.xml b/src/devices/mem24/xml_data/24AA16.xml new file mode 100644 index 0000000..fb471b5 --- /dev/null +++ b/src/devices/mem24/xml_data/24AA16.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24AA164.xml b/src/devices/mem24/xml_data/24AA164.xml new file mode 100644 index 0000000..76ac031 --- /dev/null +++ b/src/devices/mem24/xml_data/24AA164.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24AA256.xml b/src/devices/mem24/xml_data/24AA256.xml new file mode 100644 index 0000000..899389d --- /dev/null +++ b/src/devices/mem24/xml_data/24AA256.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24AA32A.xml b/src/devices/mem24/xml_data/24AA32A.xml new file mode 100644 index 0000000..bc8d0f4 --- /dev/null +++ b/src/devices/mem24/xml_data/24AA32A.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24AA512.xml b/src/devices/mem24/xml_data/24AA512.xml new file mode 100644 index 0000000..baa575e --- /dev/null +++ b/src/devices/mem24/xml_data/24AA512.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24AA515.xml b/src/devices/mem24/xml_data/24AA515.xml new file mode 100644 index 0000000..b80a53a --- /dev/null +++ b/src/devices/mem24/xml_data/24AA515.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24AA64.xml b/src/devices/mem24/xml_data/24AA64.xml new file mode 100644 index 0000000..0d52b6b --- /dev/null +++ b/src/devices/mem24/xml_data/24AA64.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24AA65.xml b/src/devices/mem24/xml_data/24AA65.xml new file mode 100644 index 0000000..b35b50b --- /dev/null +++ b/src/devices/mem24/xml_data/24AA65.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24C00.xml b/src/devices/mem24/xml_data/24C00.xml new file mode 100644 index 0000000..13bc0f7 --- /dev/null +++ b/src/devices/mem24/xml_data/24C00.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24C01C.xml b/src/devices/mem24/xml_data/24C01C.xml new file mode 100644 index 0000000..3526522 --- /dev/null +++ b/src/devices/mem24/xml_data/24C01C.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24C02C.xml b/src/devices/mem24/xml_data/24C02C.xml new file mode 100644 index 0000000..f4ce091 --- /dev/null +++ b/src/devices/mem24/xml_data/24C02C.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24C65.xml b/src/devices/mem24/xml_data/24C65.xml new file mode 100644 index 0000000..6f9be98 --- /dev/null +++ b/src/devices/mem24/xml_data/24C65.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24FC1025.xml b/src/devices/mem24/xml_data/24FC1025.xml new file mode 100644 index 0000000..c783952 --- /dev/null +++ b/src/devices/mem24/xml_data/24FC1025.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24FC128.xml b/src/devices/mem24/xml_data/24FC128.xml new file mode 100644 index 0000000..88b0c8e --- /dev/null +++ b/src/devices/mem24/xml_data/24FC128.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24FC256.xml b/src/devices/mem24/xml_data/24FC256.xml new file mode 100644 index 0000000..08595ed --- /dev/null +++ b/src/devices/mem24/xml_data/24FC256.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24FC512.xml b/src/devices/mem24/xml_data/24FC512.xml new file mode 100644 index 0000000..0811a8d --- /dev/null +++ b/src/devices/mem24/xml_data/24FC512.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24FC515.xml b/src/devices/mem24/xml_data/24FC515.xml new file mode 100644 index 0000000..9469c8c --- /dev/null +++ b/src/devices/mem24/xml_data/24FC515.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24LC00.xml b/src/devices/mem24/xml_data/24LC00.xml new file mode 100644 index 0000000..b6b588e --- /dev/null +++ b/src/devices/mem24/xml_data/24LC00.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24LC014.xml b/src/devices/mem24/xml_data/24LC014.xml new file mode 100644 index 0000000..f3dd3e7 --- /dev/null +++ b/src/devices/mem24/xml_data/24LC014.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24LC01B.xml b/src/devices/mem24/xml_data/24LC01B.xml new file mode 100644 index 0000000..f96bc6d --- /dev/null +++ b/src/devices/mem24/xml_data/24LC01B.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24LC024.xml b/src/devices/mem24/xml_data/24LC024.xml new file mode 100644 index 0000000..7fa84bf --- /dev/null +++ b/src/devices/mem24/xml_data/24LC024.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24LC025.xml b/src/devices/mem24/xml_data/24LC025.xml new file mode 100644 index 0000000..8f5df38 --- /dev/null +++ b/src/devices/mem24/xml_data/24LC025.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24LC02B.xml b/src/devices/mem24/xml_data/24LC02B.xml new file mode 100644 index 0000000..3e34cde --- /dev/null +++ b/src/devices/mem24/xml_data/24LC02B.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24LC04B.xml b/src/devices/mem24/xml_data/24LC04B.xml new file mode 100644 index 0000000..0f83be9 --- /dev/null +++ b/src/devices/mem24/xml_data/24LC04B.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24LC08B.xml b/src/devices/mem24/xml_data/24LC08B.xml new file mode 100644 index 0000000..a617e0c --- /dev/null +++ b/src/devices/mem24/xml_data/24LC08B.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24LC1025.xml b/src/devices/mem24/xml_data/24LC1025.xml new file mode 100644 index 0000000..79ba144 --- /dev/null +++ b/src/devices/mem24/xml_data/24LC1025.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24LC128.xml b/src/devices/mem24/xml_data/24LC128.xml new file mode 100644 index 0000000..b850eac --- /dev/null +++ b/src/devices/mem24/xml_data/24LC128.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24LC16B.xml b/src/devices/mem24/xml_data/24LC16B.xml new file mode 100644 index 0000000..f07bd5e --- /dev/null +++ b/src/devices/mem24/xml_data/24LC16B.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24LC21A.xml b/src/devices/mem24/xml_data/24LC21A.xml new file mode 100644 index 0000000..010b3a2 --- /dev/null +++ b/src/devices/mem24/xml_data/24LC21A.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24LC22A.xml b/src/devices/mem24/xml_data/24LC22A.xml new file mode 100644 index 0000000..237b47e --- /dev/null +++ b/src/devices/mem24/xml_data/24LC22A.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24LC256.xml b/src/devices/mem24/xml_data/24LC256.xml new file mode 100644 index 0000000..5a49ee9 --- /dev/null +++ b/src/devices/mem24/xml_data/24LC256.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24LC32A.xml b/src/devices/mem24/xml_data/24LC32A.xml new file mode 100644 index 0000000..abd17f2 --- /dev/null +++ b/src/devices/mem24/xml_data/24LC32A.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24LC512.xml b/src/devices/mem24/xml_data/24LC512.xml new file mode 100644 index 0000000..f643c99 --- /dev/null +++ b/src/devices/mem24/xml_data/24LC512.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24LC515.xml b/src/devices/mem24/xml_data/24LC515.xml new file mode 100644 index 0000000..55482b3 --- /dev/null +++ b/src/devices/mem24/xml_data/24LC515.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24LC64.xml b/src/devices/mem24/xml_data/24LC64.xml new file mode 100644 index 0000000..d35cf1a --- /dev/null +++ b/src/devices/mem24/xml_data/24LC64.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24LC65.xml b/src/devices/mem24/xml_data/24LC65.xml new file mode 100644 index 0000000..3fb3fbb --- /dev/null +++ b/src/devices/mem24/xml_data/24LC65.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/24LCS21A.xml b/src/devices/mem24/xml_data/24LCS21A.xml new file mode 100644 index 0000000..0cb4846 --- /dev/null +++ b/src/devices/mem24/xml_data/24LCS21A.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/mem24/xml_data/Makefile.am b/src/devices/mem24/xml_data/Makefile.am new file mode 100644 index 0000000..42cacaa --- /dev/null +++ b/src/devices/mem24/xml_data/Makefile.am @@ -0,0 +1,12 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libmem24xml.la +libmem24xml_la_LDFLAGS = $(all_libraries) +libmem24xml_la_SOURCES = mem24_data.cpp +libmem24xml_la_DEPENDENCIES = mem24_data.cpp + +include deps.mak +mem24_data.cpp: ../xml/mem24_xml_to_data $(noinst_DATA) + ../xml/mem24_xml_to_data +CLEANFILES = mem24_data.cpp diff --git a/src/devices/mem24/xml_data/deps.mak b/src/devices/mem24/xml_data/deps.mak new file mode 100644 index 0000000..5c1f243 --- /dev/null +++ b/src/devices/mem24/xml_data/deps.mak @@ -0,0 +1,6 @@ +noinst_DATA = \ + 24AA00.xml 24AA01.xml 24AA014.xml 24AA02.xml 24AA024.xml 24AA025.xml 24AA04.xml 24AA08.xml 24AA1025.xml 24AA128.xml\ + 24AA16.xml 24AA164.xml 24AA256.xml 24AA32A.xml 24AA512.xml 24AA515.xml 24AA64.xml 24AA65.xml 24C00.xml 24C01C.xml\ + 24C02C.xml 24C65.xml 24FC1025.xml 24FC128.xml 24FC256.xml 24FC512.xml 24FC515.xml 24LC00.xml 24LC014.xml 24LC01B.xml\ + 24LC024.xml 24LC025.xml 24LC02B.xml 24LC04B.xml 24LC08B.xml 24LC1025.xml 24LC128.xml 24LC16B.xml 24LC21A.xml 24LC22A.xml\ + 24LC256.xml 24LC32A.xml 24LC512.xml 24LC515.xml 24LC64.xml 24LC65.xml 24LCS21A.xml diff --git a/src/devices/mem24/xml_data/xml_data.pro b/src/devices/mem24/xml_data/xml_data.pro new file mode 100644 index 0000000..4842ae2 --- /dev/null +++ b/src/devices/mem24/xml_data/xml_data.pro @@ -0,0 +1,5 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/lib.pro) + +TARGET = mem24xml +SOURCES += mem24_data.cpp diff --git a/src/devices/pic/Makefile.am b/src/devices/pic/Makefile.am new file mode 100644 index 0000000..13e5611 --- /dev/null +++ b/src/devices/pic/Makefile.am @@ -0,0 +1,3 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +SUBDIRS = base xml xml_data pic prog gui diff --git a/src/devices/pic/base/Makefile.am b/src/devices/pic/base/Makefile.am new file mode 100644 index 0000000..ebade1c --- /dev/null +++ b/src/devices/pic/base/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libpicbase.la +libpicbase_la_SOURCES = pic.cpp pic_config.cpp pic_protection.cpp \ + pic_register.cpp diff --git a/src/devices/pic/base/base.pro b/src/devices/pic/base/base.pro new file mode 100644 index 0000000..621d6d3 --- /dev/null +++ b/src/devices/pic/base/base.pro @@ -0,0 +1,6 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/lib.pro) + +TARGET = picbase +HEADERS += pic_protection.h pic_config.h pic_register.h pic.h +SOURCES += pic_protection.cpp pic_config.cpp pic_register.cpp pic.cpp diff --git a/src/devices/pic/base/pic.cpp b/src/devices/pic/base/pic.cpp new file mode 100644 index 0000000..8f81540 --- /dev/null +++ b/src/devices/pic/base/pic.cpp @@ -0,0 +1,426 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "pic.h" + +#include "common/global/global.h" +#include "common/common/misc.h" +#include "common/global/purl.h" +#include "pic_register.h" +#include "pic_config.h" + +//------------------------------------------------------------------------------ +const Pic::ProgVoltageType::Data Pic::ProgVoltageType::DATA[Nb_Types] = { + { "vpp", 0 }, + { "vdd_prog", 0 }, + { "vdd_prog_write", 0 } +}; + +const Pic::MemoryRangeType::Data Pic::MemoryRangeType::DATA[Nb_Types] = { + { "code", I18N_NOOP("Code memory"), Writable }, + { "calibration", I18N_NOOP("Calibration"), Writable }, + { "user_ids", I18N_NOOP("User IDs"), Writable }, + { "device_id", I18N_NOOP("Device ID"), ReadOnly }, + { "config", I18N_NOOP("Configuration Bits"), Writable }, + { "eeprom", I18N_NOOP("Data EEPROM"), Writable }, + { "debug_vector", I18N_NOOP("Debug Vector"), Writable }, + { "hardware_stack", I18N_NOOP("Hardware Stack"), ReadOnly }, + { "calibration_backup", I18N_NOOP("Calibration Backup"), Writable }, + { "program_executive", I18N_NOOP("Program Executive"), Writable } +}; + +const Pic::SelfWrite::Data Pic::SelfWrite::DATA[Nb_Types] = { + { "yes", 0 }, + { "no", 0 } +}; + +const Pic::DeviceType::Data Pic::DeviceType::DATA[Nb_Types] = { + { 0, I18N_NOOP("Normal") }, + { 0, I18N_NOOP("J") }, + { 0, I18N_NOOP("K") } +}; + +const Pic::Architecture::Data Pic::Architecture::DATA[Nb_Types] = { +// name family_label nbBytesPC nbBytesWord packed nbBitsRegister registerBankLength +// {Code, Cal, UserID, DevId, Conf, EEPROM, DebugVec, HardStack, CalBackup, Program Executive} randomAccess + { "10X", I18N_NOOP("Baseline Family"), 0, 2, false, 8, 0x020, { 12, 12, 12, 12, 12, 8, 12, 0, 12, 0 }, false, SelfWrite::No, DeviceType::Normal }, // 9, 10, 11 or 12-bit program counter + { "16X", I18N_NOOP("Midrange Family"), 13, 2, false, 8, 0x080, { 14, 14, 14, 14, 14, 8, 14, 0, 14, 0 }, false, SelfWrite::Nb_Types, DeviceType::Normal }, // max eeprom: 256 words + { "17C", I18N_NOOP("17C Family"), 16, 2, false, 8, 0x100, { 16, 0, 0, 0, 16, 8, 0, 0, 0, 0 }, true, SelfWrite::No, DeviceType::Normal }, + { "18C", I18N_NOOP("18C Family"), 21, 2, true, 8, 0x100, { 16, 8, 8, 8, 8, 8, 16, 0, 8, 0 }, true, SelfWrite::No, DeviceType::Normal }, + { "18F", I18N_NOOP("18F Family"), 21, 2, true, 8, 0x100, { 16, 8, 8, 8, 8, 8, 16, 0, 8, 0 }, true, SelfWrite::Nb_Types, DeviceType::Normal }, + { "18J", I18N_NOOP("18J Family"), 21, 2, true, 8, 0x100, { 16, 8, 8, 8, 8, 8, 16, 0, 8, 0 }, true, SelfWrite::Yes, DeviceType::J }, + { "24F", I18N_NOOP("24F Family"), 23, 4, false, 16, 0x800, { 24, 0, 0, 16, 24, 0, 24, 0, 0, 24 }, true, SelfWrite::Yes, DeviceType::J }, + { "24H", I18N_NOOP("24H Family"), 23, 4, false, 16, 0x800, { 24, 0, 8, 16, 8, 0, 24, 0, 0, 24 }, true, SelfWrite::Yes, DeviceType::J }, + { "30F", I18N_NOOP("30F Family"), 23, 4, false, 16, 0xA00, { 24, 0, 24, 16, 16, 16, 24, 0, 0, 24 }, true, SelfWrite::Yes, DeviceType::Normal }, // dsPIC: eeprom max = 2 kwords = 4 kbytes + { "33F", I18N_NOOP("33F Family"), 23, 4, false, 16, 0x800, { 24, 0, 8, 16, 8, 0, 24, 0, 0, 24 }, true, SelfWrite::Yes, DeviceType::J } +}; + +const Pic::Checksum::Algorithm::Data Pic::Checksum::Algorithm::DATA[Nb_Types] = { + { "", 0 }, + { "XOR4", 0 }, + { "XNOR7", 0 }, + { "XNOR8", 0 } +}; + +const Pic::Feature::Data Pic::Feature::DATA[Nb_Types] = { + { "ccp", I18N_NOOP("CCP") }, + { "adc", I18N_NOOP("ADC") }, + { "ssp", I18N_NOOP("SSP") }, + { "lvd", I18N_NOOP("Low Voltage Detect") }, + { "usb", I18N_NOOP("USB") }, + { "usart", I18N_NOOP("USART") }, + { "can", I18N_NOOP("CAN") }, + { "ecan", I18N_NOOP("ECAN") }, + { "ethernet", I18N_NOOP("Ethernet") }, + { "lcd", I18N_NOOP("LCD") }, + { "motor_control", I18N_NOOP("Motor Control") }, + { "motion_feedback", I18N_NOOP("Motion Feeback") }, + { "self_write", I18N_NOOP("Self-Write") } +}; + +//----------------------------------------------------------------------------- +Pic::Data::Data() + : Device::Data(new RegistersData(*this)) +{ + FOR_EACH(ProgVoltageType, type) { + _voltages[type].min = 0.0; + _voltages[type].max = 0.0; + _voltages[type].nominal = 0.0; + } + FOR_EACH(MemoryRangeType, type) { + _ranges[type].properties = NotPresent; + _ranges[type].start = 0; + _ranges[type].end = 0; + _ranges[type].hexFileOffset = 0; + } + _config = new Config(*this); + _calibration.opcode = 0; + _calibration.opcodeMask = 0; +} + +Pic::Data::~Data() +{ + delete _config; +} + +bool Pic::Data::isReadable(MemoryRangeType type) const +{ + return ( range(type).properties & Programmable ); +} + +bool Pic::Data::isWritable(MemoryRangeType type) const +{ + return ( (type.data().properties & Writable) && (range(type).properties & Programmable) ); +} + +uint Pic::Data::addressIncrement(MemoryRangeType type) const +{ + uint inc = _architecture.data().nbBytesWord; + if ( _architecture.data().packed + && ( type==MemoryRangeType::Code || type==MemoryRangeType::DebugVector ) ) return inc; + return inc / 2; +} + +uint Pic::Data::nbWords(MemoryRangeType type) const +{ + if ( !isPresent(type) ) return 0; + return nbAddresses(type) / addressIncrement(type); +} + +uint Pic::Data::nbAddresses(MemoryRangeType type) const +{ + if ( !isPresent(type) ) return 0; + return (range(type).end - range(type).start + 1); +} + +QString Pic::Data::fname(Device::Special special) const +{ + QString s = name(); + switch (special.type()) { + case Device::Special::Normal: break; + case Device::Special::LowPower: + // assume name is of form "NNX..." + s.insert(2, 'L'); + break; + case Device::Special::LowVoltage: + // assume name is of form "NNXN..." + s.replace(2, 1, "LV"); + break; + case Device::Special::HighVoltage: + // assume name is of form "NNXN..." + s.replace(2, 1, "HV"); + break; + case Device::Special::Nb_Types: Q_ASSERT(false); break; + } + return s; +} + +bool Pic::Data::matchId(BitValue rawId, Device::IdData &idata) const +{ + if ( !isPresent(MemoryRangeType::DeviceId) ) return false; + QMap::const_iterator it; + for (it=_ids.begin(); it!=_ids.end(); ++it) { + idata.special = it.key(); + BitValue nid = 0x0; + switch (architecture().type()) { + case Architecture::P10X: + case Architecture::P16X: + case Architecture::P17C: + case Architecture::P18C: + case Architecture::P18F: + case Architecture::P18J: + nid = rawId.clearMaskBits(0x1F); + idata.revision = rawId.maskWith(0x1F); + break; + case Architecture::P24F: + nid = (rawId >> 16).maskWith(0x3FFF); + idata.revision = (rawId >> 6).maskWith(0x7); + idata.minorRevision = rawId.maskWith(0x7); + break; + case Architecture::P30F: + nid = (rawId >> 16).maskWith(0xFFFF); + idata.revision = (rawId >> 6).maskWith(0x3F); + idata.minorRevision = rawId.maskWith(0x3F); + idata.process = (rawId >> 12).maskWith(0xF); + break; + case Architecture::P24H: + case Architecture::P33F: + nid = (rawId >> 16).maskWith(0xFFFF); + idata.revision = rawId.maskWith(0xFFFF); // ?? + break; + case Architecture::Nb_Types: Q_ASSERT(false); break; + } + if ( nid==it.data() ) return true; + } + return false; +} + +QStringList Pic::Data::idNames(const QMap &ids) const +{ + QStringList list; + QMap::const_iterator it; + for (it=ids.begin(); it!=ids.end(); ++it) { + switch (_architecture.type()) { + case Architecture::P10X: + case Architecture::P16X: + case Architecture::P17C: + case Architecture::P18C: + case Architecture::P18F: + case Architecture::P18J: + list += i18n("%1 (rev. %2)").arg(it.key()).arg(toLabel(it.data().revision)); + break; + case Architecture::P24F: + list += i18n("%1 (rev. %2.%3)").arg(it.key()).arg(toLabel(it.data().revision)).arg(toLabel(it.data().minorRevision)); + break; + case Architecture::P30F: + list += i18n("%1 (proc. %2; rev. %3.%4)").arg(it.key()).arg(toLabel(it.data().process)).arg(toLabel(it.data().revision)).arg(toLabel(it.data().minorRevision)); + break; + case Architecture::P24H: + case Architecture::P33F: + list += i18n("%1 (rev. %2)").arg(it.key()).arg(toLabel(it.data().revision)); + break; + case Architecture::Nb_Types: Q_ASSERT(false); break; + } + } + return list; +} + +bool Pic::Data::checkCalibration(const Device::Array &data, QString *message) const +{ + Q_ASSERT( nbWords(MemoryRangeType::Cal)==data.count() ); + for (uint i=0; i(*_registersData); +} + +bool Pic::Data::hasFeature(Feature feature, bool *unknown) const +{ + bool ok = ( registersData().nbBanks!=0 ); + if (unknown) *unknown = !ok; + if (!ok) return false; + switch (feature.type()) { + case Feature::CCP: return registersData().sfrs.contains("CCP1CON"); + case Feature::ADC: return registersData().sfrs.contains("ADCON0"); + case Feature::SSP: return registersData().sfrs.contains("SSPCON"); + case Feature::LVD: return registersData().sfrs.contains("LVDCON"); + case Feature::USB: return registersData().sfrs.contains("UCON"); + case Feature::USART: + return ( registersData().sfrs.contains("TXSTA") // 16F + || registersData().sfrs.contains("TXSTA1") // 18F + || registersData().sfrs.contains("U1MODE") ); // 30F + case Feature::CAN: return registersData().sfrs.contains("CANCON") && !registersData().sfrs.contains("ECANCON"); + case Feature::ECAN: return registersData().sfrs.contains("ECANCON"); + case Feature::Ethernet: return registersData().sfrs.contains("ETHCON1"); + case Feature::LCD: return registersData().sfrs.contains("LCDCON"); + case Feature::MotorControl: return registersData().sfrs.contains("PWMCON0"); + case Feature::MotionFeedback: return registersData().sfrs.contains("CAP1CON"); + case Feature::SelfWrite: return _selfWrite==SelfWrite::Yes; + case Feature::Nb_Types: Q_ASSERT(false); break; + } + return false; +} + +Device::Array Pic::Data::gotoInstruction(Address address, bool withPageSelection) const +{ + Q_ASSERT( address0x1FF && withPageSelection) + a.append(0x4A3 | (address>0x1FF ? 0x100 : 0x000)); // bsf STATUS,PA0 or bcf STATUS,PA0 + a.append(0xA00 | (address.toUInt() & 0x1FF)); // goto + break; + case Architecture::P16X: + if ( nbWords(MemoryRangeType::Code)>0x7FF && withPageSelection ) { + if ( address<=0x7FF ) a.append(0x018A); // clrf PCLATH + else { + a.append(0x3000 | (address.toUInt() >> 8)); // movl high address + a.append(0x008A); // movwf PCLATH + } + } + a.append(0x2800 | (address.toUInt() & 0x7FF)); + break; + case Architecture::P17C: + a.append(0xC000 | (address.toUInt() & 0x1FFF)); + break; + case Architecture::P18C: + case Architecture::P18F: + case Architecture::P18J: + a.append(0xEF00 | ((address.toUInt()/2) & 0xFF)); + a.append(0xF000 | ((address.toUInt()/2) >> 8)); + break; + case Architecture::P24F: + case Architecture::P24H: + case Architecture::P30F: + case Architecture::P33F: + a.append(0x040000 | (address.toUInt() & 0x00FFFE)); + a.append(0X000000 | (address.toUInt() >> 16)); + break; + case Architecture::Nb_Types: Q_ASSERT(false); break; + } + return a; +} + +bool Pic::Data::isGotoInstruction(BitValue instruction) const +{ + switch (_architecture.type()) { + case Architecture::P10X: return ( instruction.maskWith(0xE00)==0xA00 ); + case Architecture::P16X: return ( instruction.maskWith(0xF800)==0x2800 ); + case Architecture::P17C: return ( instruction.maskWith(0xE000)==0xC000 ); + case Architecture::P18C: + case Architecture::P18F: + case Architecture::P18J: return ( instruction.maskWith(0xFF00)==0xEF00 ); + case Architecture::P24F: + case Architecture::P24H: + case Architecture::P30F: + case Architecture::P33F: return ( instruction.maskWith(0xFF0000)==0x040000 ); + case Architecture::Nb_Types: Q_ASSERT(false); break; + } + return false; +} + +uint Pic::Data::nbWordsWriteAlignment(MemoryRangeType type) const +{ + if ( type!=MemoryRangeType::Code ) return 1; + return QMAX(_nbWordsCodeWrite, uint(16)); +} + +//---------------------------------------------------------------------------- +QDataStream &operator <<(QDataStream &s, const Pic::VoltageData &vd) +{ + s << vd.min << vd.max << vd.nominal; + return s; +} +QDataStream &operator >>(QDataStream &s, Pic::VoltageData &vd) +{ + s >> vd.min >> vd.max >> vd.nominal; + return s; +} + +QDataStream &operator <<(QDataStream &s, const Pic::MemoryRangeData &mrd) +{ + s << Q_UINT8(mrd.properties) << mrd.start << mrd.end << mrd.hexFileOffset; + return s; +} +QDataStream &operator >>(QDataStream &s, Pic::MemoryRangeData &mrd) +{ + Q_UINT8 properties; + s >> properties >> mrd.start >> mrd.end >> mrd.hexFileOffset; + mrd.properties = Pic::MemoryRangeProperties(properties); + return s; +} + +QDataStream &operator <<(QDataStream &s, const Pic::Checksum::Data &cd) +{ + s << cd.constant << cd.bbsize << cd.algorithm << cd.protectedMaskNames; + s << cd.blankChecksum << cd.checkChecksum; + return s; +} +QDataStream &operator >>(QDataStream &s, Pic::Checksum::Data &cd) +{ + s >> cd.constant >> cd.bbsize >> cd.algorithm >> cd.protectedMaskNames; + s >> cd.blankChecksum >> cd.checkChecksum; + return s; +} + +QDataStream &operator <<(QDataStream &s, const Pic::CalibrationData &cd) +{ + s << cd.opcode << cd.opcodeMask; + return s; +} +QDataStream &operator >>(QDataStream &s, Pic::CalibrationData &cd) +{ + s >> cd.opcode >> cd.opcodeMask; + return s; +} + +QDataStream &Pic::operator <<(QDataStream &s, const Pic::Data &data) +{ + s << static_cast(data); + s << data._architecture << data._ids << data._nbBitsPC; + s << data._voltages << data._ranges; + s << data._userIdRecommendedMask; + s << *data._config; + s << data._checksums; + s << data._calibration; + s << static_cast(*data._registersData); + s << data._nbWordsCodeWrite << data._nbWordsCodeRowErase; + s << data._selfWrite; + return s; +} +QDataStream &Pic::operator >>(QDataStream &s, Pic::Data &data) +{ + s >> static_cast(data); + s >> data._architecture >> data._ids >> data._nbBitsPC; + s >> data._voltages >> data._ranges; + s >> data._userIdRecommendedMask; + s >> *data._config; + s >> data._checksums; + s >> data._calibration; + s >> static_cast(*data._registersData); + s >> data._nbWordsCodeWrite >> data._nbWordsCodeRowErase; + s >> data._selfWrite; + return s; +} diff --git a/src/devices/pic/base/pic.h b/src/devices/pic/base/pic.h new file mode 100644 index 0000000..7b0dfc4 --- /dev/null +++ b/src/devices/pic/base/pic.h @@ -0,0 +1,179 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PIC_H +#define PIC_H + +#include +#include + +#include "common/global/global.h" +#include "common/common/bitvalue.h" +#include "devices/base/generic_device.h" + +namespace Pic +{ +class XmlToData; +class Group; +class Config; +class RegistersData; + +//----------------------------------------------------------------------------- +struct VoltageData { + double min, max, nominal; +}; +inline bool operator ==(const Pic::VoltageData &v1, const Pic::VoltageData &v2) { return ( v1.min==v2.min && v1.max==v2.max && v1.nominal==v2.nominal ); } + +BEGIN_DECLARE_ENUM(ProgVoltageType) + Vpp = 0, VddBulkErase, VddWrite +END_DECLARE_ENUM_STD(ProgVoltageType) + +struct CalibrationData { + BitValue opcode, opcodeMask; +}; + +enum MemoryRangeTypeProperty { ReadOnly = 0, Writable = 1 }; +Q_DECLARE_FLAGS(MemoryRangeTypeProperties, MemoryRangeTypeProperty) +Q_DECLARE_OPERATORS_FOR_FLAGS(MemoryRangeTypeProperties) +struct MemoryRangeTypeData { + const char *key, *label; + MemoryRangeTypeProperties properties; +}; +BEGIN_DECLARE_ENUM(MemoryRangeType) + Code = 0, Cal, UserId, DeviceId, Config, Eeprom, DebugVector, HardwareStack, CalBackup, ProgramExecutive +END_DECLARE_ENUM(MemoryRangeType, MemoryRangeTypeData) + +BEGIN_DECLARE_ENUM(SelfWrite) + Yes, No +END_DECLARE_ENUM_STD(SelfWrite) + +BEGIN_DECLARE_ENUM(DeviceType) + Normal, J, K +END_DECLARE_ENUM_STD(DeviceType) + +struct ArchitectureData { + const char *key, *label; + uint nbBitsPC; // nb bits program counter + uint nbBytesWord; // nb bytes per word (hex file and icd2) + bool packed; // addressIncrement = (packed ? nbBytesWord : nbBytesWord/2) + uint nbBitsRegister; + uint registerBankLength; + uint nbBits[MemoryRangeType::Nb_Types]; // nb bits per word + bool hasAddressAccess; // memory can be accessed randomly + SelfWrite::Type selfWrite; + DeviceType::Type deviceType; +}; +BEGIN_DECLARE_ENUM(Architecture) + P10X = 0, P16X, P17C, P18C, P18F, P18J, P24F, P24H, P30F, P33F +END_DECLARE_ENUM(Architecture, ArchitectureData) + +enum MemoryRangeProperty { NotPresent = 0, Present = 1, Programmable = 2 }; +Q_DECLARE_FLAGS(MemoryRangeProperties, MemoryRangeProperty) +Q_DECLARE_OPERATORS_FOR_FLAGS(MemoryRangeProperties) +struct MemoryRangeData { + MemoryRangeProperties properties; + Address start, end; + uint hexFileOffset; +}; + +namespace Checksum +{ + BEGIN_DECLARE_ENUM(Algorithm) + Normal = 0, XOR4, XNOR7, XNOR8 + END_DECLARE_ENUM_STD(Algorithm) + class Data { + public: + BitValue constant; + Algorithm algorithm; + QStringList protectedMaskNames; + QString bbsize; + BitValue blankChecksum, checkChecksum; + }; +} // namespace + +BEGIN_DECLARE_ENUM(Feature) + CCP, ADC, SSP, LVD, USB, USART, CAN, ECAN, Ethernet, LCD, MotorControl, + MotionFeedback, SelfWrite +END_DECLARE_ENUM_STD(Feature) + +//----------------------------------------------------------------------------- +class Data : public Device::Data +{ +public: + Data(); + virtual ~Data(); + virtual QString fname(Device::Special special) const; + virtual QString listViewGroup() const { return _architecture.label(); } + bool isPresent(MemoryRangeType type) const { return (range(type).properties & Present); } + bool isReadable(MemoryRangeType type) const; + bool isWritable(MemoryRangeType type) const; + uint nbAddresses(MemoryRangeType type) const; + uint nbWords(MemoryRangeType type) const; + uint addressIncrement(MemoryRangeType type) const; + uint nbWordsWriteAlignment(MemoryRangeType type) const; + MemoryRangeData range(MemoryRangeType type) const { return _ranges[type]; } + virtual uint nbBitsAddress() const { return _nbBitsPC; } + uint nbBitsWord(MemoryRangeType type) const { return _architecture.data().nbBits[type.type()]; } + uint nbBytesWord(MemoryRangeType type) const { return nbBitsToNbBytes(nbBitsWord(type)); } + uint nbCharsWord(MemoryRangeType type) const { return nbBitsToNbChars(nbBitsWord(type)); } + BitValue mask(MemoryRangeType type) const { return uint(1 << nbBitsWord(type))-1; } + BitValue userIdRecommendedMask() const { return _userIdRecommendedMask; } + const Config &config() const { return *_config; } + Architecture architecture() const { return _architecture; } + bool is18Family() const { return ( _architecture==Architecture::P18C || _architecture==Architecture::P18F || _architecture==Architecture::P18J); } + bool is16bitFamily() const { return ( _architecture.data().nbBitsRegister==16 ); } + VoltageData voltage(ProgVoltageType type) const { return _voltages[type]; } + virtual bool canWriteCalibration() const { return isWritable(MemoryRangeType::Cal); } + bool checkCalibration(const Device::Array &data, QString *message = 0) const; + const QMap ids() const { return _ids; } + virtual bool matchId(BitValue rawId, Device::IdData &data) const; + QStringList idNames(const QMap &ids) const; + const QMap checksums() const { return _checksums; } + const RegistersData ®istersData() const; + const CalibrationData &calibrationData() const { return _calibration; } + + bool hasFeature(Feature feature, bool *unknown = 0) const; + BitValue nopInstruction() const { return 0x0; } + Device::Array gotoInstruction(Address address, bool withPageSelection) const; + bool isGotoInstruction(BitValue instruction) const; + +private: + Architecture _architecture; + QMap _ids; + uint _nbBitsPC; + uint _nbWordsCodeWrite; // #### only for 18F/18J devices [0 for other devices] + uint _nbWordsCodeRowErase; // #### only for 18F/18J devices [0 for other devices or if not available] + QMap _voltages; + QMap _ranges; + BitValue _userIdRecommendedMask; + Config *_config; + QMap _checksums; + CalibrationData _calibration; + SelfWrite _selfWrite; + + friend class XmlToData; + friend class Group; + friend QDataStream &operator <<(QDataStream &s, const Data &data); + friend QDataStream &operator >>(QDataStream &s, Data &data); +}; + +QDataStream &operator <<(QDataStream &s, const Data &data); +QDataStream &operator >>(QDataStream &s, Data &data); + +} // namespace + +QDataStream &operator <<(QDataStream &s, const Pic::VoltageData &vd); +QDataStream &operator >>(QDataStream &s, Pic::VoltageData &vd); +QDataStream &operator <<(QDataStream &s, const Pic::MemoryRangeData &mrd); +QDataStream &operator >>(QDataStream &s, Pic::MemoryRangeData &mrd); +QDataStream &operator <<(QDataStream &s, const Pic::Checksum::Data &cd); +QDataStream &operator >>(QDataStream &s, Pic::Checksum::Data &cd); +QDataStream &operator <<(QDataStream &s, const Pic::CalibrationData &cd); +QDataStream &operator >>(QDataStream &s, Pic::CalibrationData &cd); + +#endif diff --git a/src/devices/pic/base/pic_config.cpp b/src/devices/pic/base/pic_config.cpp new file mode 100644 index 0000000..6672794 --- /dev/null +++ b/src/devices/pic/base/pic_config.cpp @@ -0,0 +1,456 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "pic_config.h" + +#include + +const Pic::ConfigNameType::Data Pic::ConfigNameType::DATA[Nb_Types] = { + { "cname", 0 }, + { "ecname", 0 }, + { "sdcc_cname", 0 } +}; + +const Pic::Config::Data Pic::Config::DATA[] = { + { { "CP", I18N_NOOP("Code code-protection") }, MemoryRange, { { 0, 0 } } }, + { { "CPD", I18N_NOOP("Data code-protection") }, MemoryRange, { { 0, 0 } } }, + { { "CPC", I18N_NOOP("Calibration code-protection") }, MemoryRange, { { 0, 0 } } }, + { { "CPB", I18N_NOOP("Boot code-protection") }, MemoryRange, { { 0, 0 } } }, + + { { "WRT", I18N_NOOP("Code write-protection") }, MemoryRange, { { 0, 0 } } }, + { { "WRTD", I18N_NOOP("Data write-protection") }, MemoryRange, { { 0, 0 } } }, + { { "WRTB", I18N_NOOP("Boot write-protection") }, MemoryRange, { { 0, 0 } } }, + { { "WRTC", I18N_NOOP("Configuration write-protection") }, MemoryRange, { { 0, 0 } } }, + + { { "EBTR", I18N_NOOP("Table read-protection") }, MemoryRange, { { 0, 0 } } }, + { { "EBTRB", I18N_NOOP("Boot table read-protection") }, MemoryRange, { { 0, 0 } } }, + + { { "WDT", I18N_NOOP("Watchdog timer") }, Toggle, { { 0, 0 } } }, + { { "MCLRE", I18N_NOOP("Master clear reset"), }, Fixed, { + { "External", I18N_NOOP("External"), }, + { "Internal", I18N_NOOP("Disabled (connected to Vdd)") }, { 0, 0 } } }, + { { "PWRTE", I18N_NOOP("Power-up timer") }, Toggle, { { 0, 0 } } }, + + { { "FOSC", I18N_NOOP("Oscillator") }, Fixed, { + { "EXTRC", I18N_NOOP("External RC oscillator") }, + { "EXTRC_CLKOUT", I18N_NOOP("External RC oscillator with CLKOUT") }, + { "EXTRC_IO", I18N_NOOP("External RC oscillator (no CLKOUT)") }, + { "INTRC", I18N_NOOP("Internal oscillator") }, + { "INTRC_CLKOUT", I18N_NOOP("Internal oscillator with CLKOUT") }, + { "INTRC_IO", I18N_NOOP("Internal oscillator (no CLKOUT)") }, + { "XT", I18N_NOOP("Crystal/resonator") }, + { "XTPLL", I18N_NOOP("Crystal/resonator, PLL enabled") }, + { "LP", I18N_NOOP("Low power crystal") }, + { "EC", I18N_NOOP("External clock") }, + { "EC_CLKOUT", I18N_NOOP("External clock with CLKOUT") }, + { "EC_IO", I18N_NOOP("External clock (no CLKOUT)") }, + { "ECPLL_CLKOUT", I18N_NOOP("External clock with CLKOUT, PLL enabled") }, + { "ECPLL_IO", I18N_NOOP("External clock (no CLKOUT), PLL enabled") }, + { "E4_CLKOUT", I18N_NOOP("External clock with 4x PLL and with CLKOUT") }, + { "E4_IO", I18N_NOOP("External clock with 4x PLL (no CLKOUT)") }, + { "E4S_IO", I18N_NOOP("External clock with software controlled 4x PLL (no CLKOUT)") }, + { "ER", I18N_NOOP("External resistor") }, + { "ER_CLKOUT", I18N_NOOP("External resistor with CLKOUT") }, + { "ER_IO", I18N_NOOP("External resistor (no CLKOUT)") }, + { "HS", I18N_NOOP("High speed crystal/resonator") }, + { "HSPLL", I18N_NOOP("High speed crystal/resonator, PLL enabled") }, + { "H4", I18N_NOOP("High speed crystal/resonator with 4x PLL") }, + { "H4S", I18N_NOOP("High speed crystal/resonator with software controlled 4x PLL") }, + { "INTXT", I18N_NOOP("Internal oscillator, XT used by USB") }, + { "INTHS", I18N_NOOP("Internal oscillator, HS used by USB") }, + { 0, 0 } } }, + + { { "BG", I18N_NOOP("Bandgap voltage calibration") }, Fixed, { + { "Lowest", I18N_NOOP("Lowest") }, + { "Mid/Low", I18N_NOOP("Mid/Low") }, + { "Mid/High", I18N_NOOP("Mid/High") }, + { "Highest", I18N_NOOP("Highest") }, { 0, 0 } } }, + { { "TRIM", I18N_NOOP("Internal Trim") }, Fixed, { + { "00", I18N_NOOP("00") }, { "01", I18N_NOOP("01") }, + { "10", I18N_NOOP("10") }, { "11", I18N_NOOP("11") }, { 0, 0 } } }, + { { "BODEN", I18N_NOOP("Brown-out detect") }, Toggle, { + { "On_run", I18N_NOOP("Enabled in run - Disabled in sleep") }, + { "Software", I18N_NOOP("SBODEN controls BOD function") }, { 0, 0 } } }, + { { "FCMEN", I18N_NOOP("Fail-safe clock monitor") }, Toggle, { { 0, 0 } } }, + { { "IESO", I18N_NOOP("Internal-external switchover") }, Toggle, { { 0, 0 } } }, + { { "WUREN", I18N_NOOP("Wake-up reset") }, Toggle, { { 0, 0 } } }, + { { "DEBUG", I18N_NOOP("In-circuit debugger") }, Toggle, { { 0, 0 } } }, + { { "MPEEN", I18N_NOOP("Memory parity error") }, Toggle, { { 0, 0 } } }, + { { "BORV", I18N_NOOP("Brown-out reset voltage") }, ValueDouble, { + { "0", I18N_NOOP("Undefined") }, { 0, 0 } } }, + { { "LVP", I18N_NOOP("Low voltage programming") }, Toggle, { { 0, 0 } } }, + { { "CCP2MX", I18N_NOOP("CCP2 multiplex") }, Pin, { { 0, 0 } } }, + { { "CCP1MX", I18N_NOOP("CCP1 multiplex") }, Pin, { { 0, 0 } } }, + { { "BORSEN", I18N_NOOP("Brown-out reset software") }, Toggle, { { 0, 0 } } }, + { { "WDTPS", I18N_NOOP("WDT post-scaler") }, Ratio, { + { "Disabled", I18N_NOOP("Disabled") }, { 0, 0 } } }, + { { "PM", I18N_NOOP("Processor mode") }, Fixed, { + { "Extended microcontroller", I18N_NOOP("Extended microcontroller") }, + { "Microcontroller", I18N_NOOP("Microcontroller") }, + { "Microprocessor", I18N_NOOP("Microprocessor") }, + { "Code-protected microcontroller", I18N_NOOP("Code protected microcontroller") }, + { "Microprocessor with boot", I18N_NOOP("Microprocessor with boot block") }, + { 0, 0 } } }, + + { { "OSCSEN", I18N_NOOP("Oscillator system clock switch") }, Toggle, { { 0, 0 } } }, + { { "STVREN", I18N_NOOP("Stack full/underflow reset") }, Toggle, { { 0, 0 } } }, + { { "BW", I18N_NOOP("External bus data width (in bits)") }, ValueUInt, { { 0, 0 } } }, + { { "PBADEN", I18N_NOOP("PORTB A/D") }, Fixed, { + { "digital", I18N_NOOP("Digital") }, + { "analog", I18N_NOOP("Analog") }, { 0, 0 } } }, + { { "WINEN", I18N_NOOP("Watchdog timer window") }, Toggle, { { 0, 0 } } }, + { { "HPOL", I18N_NOOP("Odd PWM output polarity") }, Fixed, { + { "high", I18N_NOOP("Active high") }, + { "low", I18N_NOOP("Active low") }, { 0, 0 } } }, + { { "LPOL", I18N_NOOP("Even PWM output polarity") }, Fixed, { + { "high", I18N_NOOP("Active high") }, + { "low", I18N_NOOP("Active low") }, { 0, 0 } } }, + { { "PWMPIN", I18N_NOOP("PWM output pin reset state") }, Toggle, { { 0, 0 } } }, + { { "T1OSCMX", I18N_NOOP("Timer1 oscillator mode") }, Fixed, { + { "Legacy", I18N_NOOP("Standard operation") }, + { "Low Power", I18N_NOOP("Low power in sleep mode") }, + { "RA6", I18N_NOOP("T1OSO/T1CKI on RA6") }, + { "RB2", I18N_NOOP("T1OSO/T1CKI on RB2") }, { 0, 0 } } }, + { { "EXCLKMX", I18N_NOOP("TMR0/T5CKI external clock mux") }, Pin, { { 0, 0 } } }, + { { "FLTAMX", I18N_NOOP("FLTA mux") }, Pin, { { 0, 0 } } }, + { { "PWM4MX", I18N_NOOP("PWM4 mux") }, Pin, { { 0, 0 } } }, + { { "SSPMX", I18N_NOOP("SSP I/O mux (SCK/SLC, SDA/SDI, SD0)") }, Pins, { { 0, 0 } } }, + { { "LPT1OSC", I18N_NOOP("Low-power timer1 oscillator") }, Toggle, { { 0, 0 } } }, + { { "XINST", I18N_NOOP("Extended instruction set") }, Toggle, { { 0, 0 } } }, + { { "BBSIZ", I18N_NOOP("Boot block size") }, ValueUInt, { { 0, 0 } } }, + { { "ICPORT", I18N_NOOP("Dedicated in-circuit port") }, Toggle, { { 0, 0 } } }, + { { "VREGEN", I18N_NOOP("USB voltage regulator") }, Toggle, { { 0, 0 } } }, + { { "WAIT", I18N_NOOP("External bus data wait") }, Toggle, { { 0, 0 } } }, + { { "ABW", I18N_NOOP("Address bus width (in bits)") }, ValueUInt, { { 0, 0 } } }, + { { "ECCPMX", I18N_NOOP("ECCP mux") }, Fixed, { + { "RE6-RE3", I18N_NOOP("PWM multiplexed onto RE6 and RE3") }, + { "RH7-RH4", I18N_NOOP("PWM multiplexed onto RH7 and RH4") }, + { "RE6-RE5", I18N_NOOP("PWM multiplexed onto RE6 and RE5") }, + { "RH7-RH6", I18N_NOOP("PWM multiplexed onto RH7 and RH6") }, { 0, 0 } } }, + + { { "FCKSM", I18N_NOOP("Clock switching mode") }, Fixed, { + { "Switching off, monitor off", I18N_NOOP("Switching off, monitor off") }, + { "Switching on, monitor off", I18N_NOOP("Switching on, monitor off") }, + { "Switching on, monitor on", I18N_NOOP("Switching on, monitor on") }, { 0, 0 } } }, + { { "FOS", I18N_NOOP("Oscillator source") }, Fixed, { + { "INTRC_F", I18N_NOOP("Internal fast RC") }, + { "INTRC_LP", I18N_NOOP("Internal low-power RC") }, + { "PRIM", I18N_NOOP("Primary") }, + { "TMR1", I18N_NOOP("Timer1") }, { 0, 0 } } }, + { { "FPR", I18N_NOOP("Primary oscillator mode") }, Fixed, { + { "XTL", I18N_NOOP("Low-power/low-frequency crystal") }, + { "HS", I18N_NOOP("High speed crystal") }, + { "XT", I18N_NOOP("XT Crystal") }, + { "XT4", I18N_NOOP("XT Crystal with 4x PLL") }, + { "XT8", I18N_NOOP("XT Crystal with 8x PLL") }, + { "XT16", I18N_NOOP("XT Crystal with 16x PLL") }, + { "EC_CLKOUT", I18N_NOOP("External clock with CLKOUT") }, + { "EC_IO", I18N_NOOP("External clock (no CLKOUT)") }, + { "EC4", I18N_NOOP("External clock with 4x PLL") }, + { "EC8", I18N_NOOP("External clock with 8x PLL") }, + { "EC16", I18N_NOOP("External clock with 16x PLL") }, + { "FRC8", I18N_NOOP("Internal fast RC oscillator with 8x PLL") }, + { "EXTRC_CLKOUT", I18N_NOOP("External RC oscillator with CLKOUT") }, + { "EXTRC_IO", I18N_NOOP("External RC oscillator (no CLKOUT)") }, { 0, 0 } } }, + { { "FOSFPR", I18N_NOOP("Oscillator mode") }, Fixed, { + { "XTL", I18N_NOOP("Low-power/low-frequency crystal") }, + { "HS", I18N_NOOP("High speed crystal") }, + { "XT", I18N_NOOP("XT Crystal") }, + { "XT4", I18N_NOOP("XT Crystal with 4x PLL") }, + { "XT8", I18N_NOOP("XT Crystal with 8x PLL") }, + { "XT16", I18N_NOOP("XT Crystal with 16x PLL") }, + { "HS2_4", I18N_NOOP("HS/2 Crystal with 4x PLL") }, + { "HS2_8", I18N_NOOP("HS/2 Crystal with 8x PLL") }, + { "HS2_16", I18N_NOOP("HS/2 Crystal with 16x PLL") }, + { "HS3_4", I18N_NOOP("HS/3 Crystal with 4x PLL") }, + { "HS3_8", I18N_NOOP("HS/3 Crystal with 8x PLL") }, + { "HS3_16", I18N_NOOP("HS/3 Crystal with 16x PLL") }, + { "EC_CLKOUT", I18N_NOOP("External clock with CLKOUT") }, + { "EC_IO", I18N_NOOP("External clock (no CLKOUT)") }, + { "EC4", I18N_NOOP("External clock with 4x PLL") }, + { "EC8", I18N_NOOP("External clock with 8x PLL") }, + { "EC16", I18N_NOOP("External clock with 16x PLL") }, + { "FRC4", I18N_NOOP("Internal fast RC oscillator with 4x PLL") }, + { "FRC8", I18N_NOOP("Internal fast RC oscillator with 8x PLL") }, + { "FRC16", I18N_NOOP("Internal fast RC oscillator with 16x PLL") }, + { "TMR1", I18N_NOOP("Low-power 32 kHz oscillator (TMR1 oscillator)") }, + { "INTRC_F", I18N_NOOP("Internal fast RC oscillator (no PLL)") }, + { "INTRC_LP", I18N_NOOP("Internal low-power RC oscillator") }, + { "EXTRC_CLKOUT", I18N_NOOP("External RC oscillator with CLKOUT") }, + { "EXTRC_IO", I18N_NOOP("External RC oscillator (no CLKOUT)") }, { 0, 0 } } }, + { { "FWPSA", I18N_NOOP("Watchdog timer prescaler A") }, Ratio, { { 0, 0 } } }, + { { "FWPSB", I18N_NOOP("Watchdog timer prescaler B") }, Ratio, { { 0, 0 } } }, + { { "FWDTEN", I18N_NOOP("Watchdog") }, Toggle, { + { "Software", I18N_NOOP("Software") }, { 0, 0 } } }, + { { "FPWRT", I18N_NOOP("Power-on reset timer value (ms)") }, ValueUInt, { + { "0", I18N_NOOP("Disabled") }, { 0, 0 } } }, + { { "GCP", I18N_NOOP("General code segment read-protection") }, MemoryRange, { { 0, 0 } } }, + { { "GWRP", I18N_NOOP("General code segment write-protection") }, MemoryRange, { { 0, 0 } } }, + { { "COE", I18N_NOOP("Reset into clip on emulation mode") }, Toggle, { { 0, 0 } } }, + { { "ICS", I18N_NOOP("ICD communication channel") }, Pins, { { 0, 0 } } }, + + { { "USBDIV", I18N_NOOP("USB clock (PLL divided by)") }, ValueUInt, { + { "1", I18N_NOOP("not divided") }, { 0, 0 } } }, + { { "CPUDIV", I18N_NOOP("CPU system clock (divided by)") }, ValueUInt, { + { "1", I18N_NOOP("not divided") }, { 0, 0 } } }, + { { "PLLDIV", I18N_NOOP("PLL clock (divided by)") }, ValueUInt, { + { "1", I18N_NOOP("not divided") }, { 0, 0 } } }, + + { { "MCPU", I18N_NOOP("Master clear pull-up resistor") }, Toggle, { { 0, 0 } } }, + { { "IOSCFS", I18N_NOOP("Internal oscillator speed") }, Fixed, { + { "8MHZ", I18N_NOOP("8 MHz") }, + { "4MHZ", I18N_NOOP("4 MHz") }, { 0, 0 } } }, + + // 18J specific + { { "ETHLED", I18N_NOOP("Ethernet LED enable") }, Toggle, { { 0, 0 } } }, + { { "FOSC2", I18N_NOOP("Default system clock select") }, Fixed, { + { "FOSC1:FOSC0", I18N_NOOP("FOSC1:FOSC0") }, + { "INTRC", I18N_NOOP("INTRC") }, { 0, 0 } } }, + { { "EMB", I18N_NOOP("External memory bus") }, Fixed, { + { "Disabled", I18N_NOOP("Disabled") }, + { "12BIT", I18N_NOOP("12-bit external bus") }, + { "16BIT", I18N_NOOP("16-bit external bus") }, + { "20BIT", I18N_NOOP("20-bit external bus") }, { 0, 0 } } }, + { { "EASHFT", I18N_NOOP("External address bus shift") }, Toggle, { { 0, 0 } } }, + { { "MSSPSEL", I18N_NOOP("MSSP address select bit") }, Fixed, { + { "7BIT", I18N_NOOP("7-bit address mask mode") }, + { "5BIT", I18N_NOOP("5-bit address mask mode") }, { 0, 0 } } }, + { { "PMPMX", I18N_NOOP("PMP pin select bit") }, Fixed, { + { "Connected", I18N_NOOP("Connected to EMB") }, + { "NotConnected", I18N_NOOP("Not connected to EMB") }, { 0, 0 } } }, + + // 24X specific / 30F1010 / 30F202X + { { "WRTBS", I18N_NOOP("Boot segment write-protection") }, MemoryRange, { { 0, 0 } } }, + { { "BSSIZ", I18N_NOOP("Boot segment size") }, ValueUInt, { { 0, 0 } } }, + { { "BSSEC", I18N_NOOP("Boot segment security") }, Fixed, { + { "High Security", I18N_NOOP("High Security") }, + { "Standard Security", I18N_NOOP("Standard Security") }, { 0, 0 } } }, + { { "EBSSIZ", I18N_NOOP("Boot segment EEPROM size") }, ValueUInt, { { 0, 0 } } }, + { { "RBSSIZ", I18N_NOOP("Boot segment RAM size") }, ValueUInt, { { 0, 0 } } }, + { { "WRTSS", I18N_NOOP("Secure segment write-protection") }, MemoryRange, { { 0, 0 } } }, + { { "SSSIZ", I18N_NOOP("Secure segment size") }, ValueUInt, { { 0, 0 } } }, + { { "SSSEC", I18N_NOOP("Secure segment security") }, Fixed, { + { "High Security", I18N_NOOP("High Security") }, + { "Standard Security", I18N_NOOP("Standard Security") }, { 0, 0 } } }, + { { "ESSSIZ", I18N_NOOP("Secure segment EEPROM size") }, ValueUInt, { { 0, 0 } } }, + { { "RSSSIZ", I18N_NOOP("Secure segment RAM size") }, ValueUInt, { { 0, 0 } } }, + { { "WRTGS", I18N_NOOP("General segment write-protection") }, MemoryRange, { { 0, 0 } } }, + { { "GSSEC", I18N_NOOP("General segment security") }, Fixed, { + { "Off", I18N_NOOP("Off") }, + { "High Security", I18N_NOOP("High security") }, + { "Standard Security", I18N_NOOP("Standard security") }, { 0, 0 } } }, + { { "FNOSC", I18N_NOOP("Initial oscillator source") }, Fixed, { + { "EXTRC_F" , I18N_NOOP("Fast RC oscillator") }, + { "INTRC_F", I18N_NOOP("Internal fast RC oscillator") }, + { "INTRC_F_PLL", I18N_NOOP("Internal fast RC oscillator with PLL") }, + { "PRIM", I18N_NOOP("Primary oscillator") }, + { "PRIM_PLL", I18N_NOOP("Primary oscillator with PLL") }, + { "SECOND", I18N_NOOP("Secondary oscillator (LP)") }, + { "EXTRC_LP", I18N_NOOP("Low power RC oscillator") }, + { "INTRC_F_POST", I18N_NOOP("Internal fast RC oscillator with postscaler") }, { 0, 0 } } }, + { { "POSCMD", I18N_NOOP("Primary oscillator mode") }, Fixed, { + { "Off", I18N_NOOP("Off") }, + { "HS", I18N_NOOP("HS crystal oscillator") }, + { "XT", I18N_NOOP("XT crystal oscillator") }, + { "EC", I18N_NOOP("External clock") }, { 0, 0 } } }, + { { "TEMP", I18N_NOOP("Temperature protection") }, Toggle, { { 0, 0 } } }, + { { "OSCIOFNC", I18N_NOOP("OSC2 pin function") }, Fixed, { + { "IO", I18N_NOOP("Digital I/O") }, + { "Clock", I18N_NOOP("Clock output") }, { 0, 0 } } }, + { { "WINDIS", I18N_NOOP("Watchdog timer window") }, Toggle, { { 0, 0 } } }, + { { "WDTPRE", I18N_NOOP("Watchdog timer prescaler") }, Ratio, { { 0, 0 } } }, + { { "WDTPOST", I18N_NOOP("Watchdog timer postscaler") }, Ratio, { { 0, 0 } } }, + { { "JTAGEN", I18N_NOOP("JTAG port enabled") }, Toggle, { { 0, 0 } } }, + { { "IOL1WAY", I18N_NOOP("Peripheral pin select configuration") }, Fixed, { + { "One reconfiguration", I18N_NOOP("Allow only one reconfiguration") }, + { "Multiple reconfigurations", I18N_NOOP("Allow multiple reconfigurations") }, { 0, 0 } } }, + { { "ALTI2C", I18N_NOOP("Alternate I2C pins") }, Pin, { { 0, 0 } } }, + { { "I2C1SEL", I18N_NOOP("I2C pins selection") }, Fixed, { + { "Default", I18N_NOOP("Default") }, + { "Alternate", I18N_NOOP("Alternate") }, { 0, 0 } } }, + { { "FRANGE", I18N_NOOP("Frequency range selection for FRC oscillator") }, Fixed, { + { "High range", I18N_NOOP("High range (nominal FRC frequency is 14.1 MHz)") }, + { "Low range", I18N_NOOP("Low range (nominal FRC frequency is 9.7 MHz)") }, { 0, 0 } } }, + + { { 0, 0 }, Fixed, { { 0, 0 } } } +}; + +QMap *Pic::Config::_masks = 0; +QMap &Pic::Config::masks() +{ + if ( _masks==0 ) { + _masks = new QMap; + for (uint i=0; DATA[i].mask.name; i++) { + (*_masks)[DATA[i].mask.name] = MapData(i, -1); + if ( DATA[i].type==MemoryRange ) { + for (uint k=0; k=0 ) return i18n("%1 for block %2").arg(s).arg(mp.block); + return s; +} + +const Pic::Config::Mask *Pic::Config::findMask(const QString &mask, uint *wordIndex) const +{ + for (uint i=0; ivalues.count()); i++) + if ( cmask->values[i].name==value ) return &cmask->values[i]; + return 0; +} + +bool Pic::Config::checkValueName(const QString &mask, const QString &name) const +{ + const Data &data = DATA[masks()[mask].index]; + QString pinRegexp = "[A-Z]+\\d*(/[A-Z]+\\d*)?"; + switch (data.type) { + case Fixed: break; + case ValueDouble: { + bool ok; + (void)name.toDouble(&ok); + if (ok) return true; + break; + } + case ValueUInt: { + bool ok; + (void)name.toUInt(&ok); + if (ok) return true; + break; + } + case Ratio: { + QRegExp regexp("(\\d+):(\\d+)"); + if ( regexp.exactMatch(name) ) { + bool ok1, ok2; + (void)regexp.cap(1).toUInt(&ok1); + (void)regexp.cap(2).toUInt(&ok2); + if ( ok1 && ok2 ) return true; + } + break; + } + case MemoryRange: + return _protection.checkRange(mask, name); + case Toggle: + if ( name=="On" || name=="Off" ) return true; + break; + case Pin: { + QRegExp regexp(pinRegexp); + if ( regexp.exactMatch(name) ) return true; + break; + } + case Pins: { + QRegExp regexp(pinRegexp + "(, " + pinRegexp + ")+"); + if ( regexp.exactMatch(name) ) return true; + break; + } + } + for (uint i=0; data.values[i].name; i++) + if ( data.values[i].name==name ) return true; + return false; +} + +QString Pic::Config::valueLabel(const QString &mask, const QString &name) +{ + const Data &data = DATA[masks()[mask].index]; + switch (data.type) { + case Fixed: + case ValueDouble: + case ValueUInt: + case Pin: + case Pins: + case Ratio: break; + case MemoryRange: + if ( name=="All" ) return i18n("All"); + if ( name=="Off" ) return i18n("Disabled"); + break; + case Toggle: + if ( name=="On" ) return i18n("Enabled"); + if ( name=="Off" ) return i18n("Disabled"); + break; + } + for (uint i=0; data.values[i].name; i++) + if ( data.values[i].name==name ) return i18n(data.values[i].label); + return name; +} + +BitValue Pic::Config::Word::usedMask() const +{ + BitValue mask = 0x0; + for (uint i=0; i>(QDataStream &s, Config::Value &value) +{ + s >> value.name >> value.configNames >> value.value; + return s; +} + +QDataStream &Pic::operator <<(QDataStream &s, const Config::Mask &mask) +{ + s << mask.name << mask.value << mask.values; + return s; +} +QDataStream &Pic::operator >>(QDataStream &s, Config::Mask &mask) +{ + s >> mask.name >> mask.value >> mask.values; + return s; +} + +QDataStream &Pic::operator <<(QDataStream &s, const Config::Word &word) +{ + s << word.name << word.ignoredCNames << word.wmask << word.pmask << word.cmask << word.bvalue << word.masks; + return s; +} +QDataStream &Pic::operator >>(QDataStream &s, Config::Word &word) +{ + s >> word.name >> word.ignoredCNames >> word.wmask >> word.pmask >> word.cmask >> word.bvalue >> word.masks; + return s; +} + +QDataStream &Pic::operator <<(QDataStream &s, const Config &config) +{ + s << config._words; + return s; +} +QDataStream &Pic::operator >>(QDataStream &s, Config &config) +{ + s >> config._words; + return s; +} diff --git a/src/devices/pic/base/pic_config.h b/src/devices/pic/base/pic_config.h new file mode 100644 index 0000000..185a19e --- /dev/null +++ b/src/devices/pic/base/pic_config.h @@ -0,0 +1,107 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PIC_CONFIG_H +#define PIC_CONFIG_H + +#include +#include + +#include "common/common/bitvalue.h" +#include "pic_protection.h" +#include "pic.h" + +namespace Pic +{ +class Data; + +BEGIN_DECLARE_ENUM(ConfigNameType) + Default = 0, Extra, SDCC +END_DECLARE_ENUM_STD(ConfigNameType) + +class Config +{ +public: + class Value { + public: + QString name; + QMap configNames; + BitValue value; + bool operator <(const Value &cv) const { return value values; // ordered from lower to higher + bool operator <(const Mask &cm) const { return value masks; // ordered from lower to higher + BitValue usedMask() const; + }; + +public: + Config(const Pic::Data &data) : _data(data), _protection(data, *this) {} + QValueVector _words; + const Protection &protection() const { return _protection; } + + const Value *findValue(const QString &mask, const QString &value) const; + const Mask *findMask(const QString &mask, uint *wordIndex = 0) const; + static bool hasMaskName(const QString &mask); + static QString maskLabel(const QString &mask); + bool checkValueName(const QString &mask, const QString &name) const; + static QString valueLabel(const QString &mask, const QString &name); + +private: + class MapData { + public: + MapData() {} + MapData(int i, int b) : index(i), block(b) {} + int index, block; + }; + static QMap &masks(); + static QMap *_masks; // mask name -> index in DATA + + struct NameData { + const char *name, *label; + }; + enum Type { Fixed, ValueDouble, ValueUInt, Ratio, MemoryRange, Toggle, Pin, Pins }; + class Data { + public: + const NameData mask; + Type type; + const NameData values[50]; + }; + static const Data DATA[]; + +private: + const Pic::Data &_data; + Protection _protection; +}; + +QDataStream &operator <<(QDataStream &s, const Config::Value &value); +QDataStream &operator >>(QDataStream &s, Config::Value &value); +QDataStream &operator <<(QDataStream &s, const Config::Mask &mask); +QDataStream &operator >>(QDataStream &s, Config::Mask &mask); +QDataStream &operator <<(QDataStream &s, const Config::Word &word); +QDataStream &operator >>(QDataStream &s, Config::Word &word); +QDataStream &operator <<(QDataStream &s, const Config &config); +QDataStream &operator >>(QDataStream &s, Config &config); + +} //namespace + +#endif diff --git a/src/devices/pic/base/pic_protection.cpp b/src/devices/pic/base/pic_protection.cpp new file mode 100644 index 0000000..da77881 --- /dev/null +++ b/src/devices/pic/base/pic_protection.cpp @@ -0,0 +1,361 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "pic_protection.h" + +#include "pic_config.h" + +#include + +bool Pic::Protection::isNoneProtectedValueName(const QString &name) const +{ + if ( name=="Off" ) return true; + if ( _data.architecture()==Architecture::P17C ) return !isAllProtectedValueName(name); + return false; +} + +bool Pic::Protection::isAllProtectedValueName(const QString &name) const +{ + if ( name=="All" ) return true; + if ( _data.architecture()==Architecture::P17C ) return ( name=="Code-protected microcontroller" ); + return false; +} + +Pic::Protection::Family Pic::Protection::family() const +{ + if ( _config.findMask("WRTBS") ) return CodeGuard; + QString mask = maskName(ProgramProtected, MemoryRangeType::Code); + if ( _config.findMask(QString("%1_%2").arg(mask).arg(0)) ) return BlockProtection; + if ( _config.findMask(mask) ) return BasicProtection; + return NoProtection; +} + +QString Pic::Protection::securityValueName(Type type) const +{ + if ( type==StandardSecurity ) return "Standard Security"; + if ( type==HighSecurity ) return "High Security"; + Q_ASSERT( type==Nb_Types ); + return "Off"; +} + +QString Pic::Protection::bootSizeMaskName() const +{ + return (family()==CodeGuard ? "BSSIZ" : "BBSIZ"); +} + +QString Pic::Protection::bootMaskName(Type type) const +{ + Q_ASSERT( type!=Nb_Types ); + if ( family()==CodeGuard ) { + if ( type==WriteProtected ) return "WRTBS"; + if ( type==StandardSecurity || type==HighSecurity ) return "BSSEC"; + } else { + if ( type==ProgramProtected ) return "CPB"; + if ( type==WriteProtected ) return "WRTB"; + if ( type==ReadProtected ) return "EBTRB"; + } + return QString::null; +} + +QString Pic::Protection::blockSizeMaskName(uint block) const +{ + if ( family()==CodeGuard ) { + Q_ASSERT( block==0 ); + return "SSSIZ"; + } + return blockMaskName(ProgramProtected, block); +} + +QString Pic::Protection::blockMaskName(Type type, uint block) const +{ + Q_ASSERT( type!=Nb_Types ); + if ( family()==CodeGuard ) { + if ( type==WriteProtected ) return (block==0 ? "WRTSS" : "WRTGS"); + if ( type==StandardSecurity || type==HighSecurity ) return (block==0 ? "SSSEC" : "GSSEC"); + return QString::null; + } + return QString("%1_%2").arg(maskName(type, MemoryRangeType::Code)).arg(block); +} + +QString Pic::Protection::maskName(Type type, MemoryRangeType mtype) const +{ + Q_ASSERT( type!=Nb_Types ); + switch (mtype.type()) { + case MemoryRangeType::Code: + if ( type==ProgramProtected ) { + if ( _data.architecture()==Architecture::P17C ) return "PM"; + if ( _data.architecture()==Architecture::P30F || _data.architecture()==Architecture::P24F ) return "GCP"; + return "CP"; + } + if ( type==WriteProtected ) { + if ( _data.architecture()==Architecture::P30F || _data.architecture()==Architecture::P24F ) return "GWRP"; + return "WRT"; + } + if ( type==ReadProtected ) return "EBTR"; + break; + case MemoryRangeType::Eeprom: + if ( type==ProgramProtected ) return "CPD"; + if ( type==WriteProtected ) return "WRTD"; + break; + case MemoryRangeType::Cal: + if ( type==ProgramProtected ) return "CPC"; + break; + case MemoryRangeType::Config: + if ( type==WriteProtected ) return "WRTC"; + if ( type==ReadProtected ) return "EBTRC"; + break; + case MemoryRangeType::Nb_Types: Q_ASSERT(false); break; + default: break; + } + return QString::null; +} + +bool Pic::Protection::extractRanges(const QString &name, QValueVector
&starts, Address &end, bool &ok) +{ + ok = false; + QRegExp regexp("([A-F0-9]+)(/[A-F0-9]+)?(/[A-F0-9]+)?:([A-F0-9]+)"); + if ( !regexp.exactMatch(name) ) return false; + bool ok1; + end = fromHex(regexp.cap(regexp.numCaptures()), &ok1); + if ( !ok1 ) { + qDebug("Malformed end address"); + return true; + } + starts.clear(); + for (int i=1; i=end && (starts.count()==0 || starts[starts.count()-1] starts; + Address end; + bool ok2 = extractRanges(name, starts, end, ok1); + Q_ASSERT(ok1); + Q_ASSERT(ok2); + Q_UNUSED(ok2); + AddressRangeVector rv; + for (uint i=0; ivalues.count()); k++) { + bool ok1; + uint size = bsmask->values[k].name.toUInt(&ok1); + if ( !ok1 ) { + qDebug("Could not recognize boot size value"); + return pr; + } + if ( size==0 ) { + qDebug("Boot size cannot be zero"); + return pr; + } + Address end = 2 * size - 1; // instruction words + if ( pr.ends.count()!=0 && end==pr.ends[pr.ends.count()-1] ) continue; + pr.ends.append(end); + qHeapSort(pr.ends); + } + } else { + pr.starts.append(rdata.start); + pr.ends.append(rdata.end); + } + ok = true; + return pr; + } + if ( isBootBlock && bsmask ) { + qDebug("Protected range should not be explicit when boot size is present"); + return pr; + } + + // extract start and end + Address end; + bool ok1; + if ( !extractRanges(name, pr.starts, end, ok1) ) { + qDebug("Could not recognized explicit range"); + return pr; + } + if ( !ok1 ) return pr; + if ( end>rdata.end ) { + qDebug("End is beyond memory range"); + return pr; + } + if ( (rtype!=MemoryRangeType::Code || isBootBlock) && (pr.starts.count()>1 || !rexp.cap(2).isEmpty() || bmask==0) ) { + qDebug("Only code with blocks and boot can have multiple protected ranges"); + return pr; + } + if ( isBootBlock && pr.starts[0]!=0 ) { + qDebug("Boot block start should be zero"); + return pr; + } + pr.ends.append(end); + + // check with boot block + if ( pr.starts.count()>1 ) { + if ( bmask==0 ) { + qDebug("No boot mask"); + return pr; + } + for (uint i=0; ivalues.count()); i++) { + if ( bmask->values[i].name=="Off" ) continue; + bool ok1; + ProtectedRange bpr = extractRange(bmask->name, bmask->values[i].name, ok1); + if ( !ok1 ) return pr; + if ( bpr.ends.count()!=pr.starts.count() ) { + qDebug("Boot number of ends (%i) should be the same as code number of starts (%i)", int(bpr.ends.count()), int(pr.starts.count())); + return pr; + } + for (uint k=0; k * + * * + * 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. * + ***************************************************************************/ +#ifndef PIC_PROTECTION_H +#define PIC_PROTECTION_H + +#include "pic.h" + +namespace Pic +{ +class Data; + +//---------------------------------------------------------------------------- +class Protection +{ +public: + enum { MAX_NB_BLOCKS = 8 }; + enum Family { NoProtection = 0, BasicProtection, BlockProtection, CodeGuard, Nb_Families }; + enum Type { ProgramProtected = 0, WriteProtected, ReadProtected, + StandardSecurity, HighSecurity, Nb_Types }; + +public: + Protection(const Pic::Data &data, const Config &config) : _data(data), _config(config) {} + Family family() const; + QString securityValueName(Type type) const; + bool hasBootBlock() const; + QString bootSizeMaskName() const; + QString bootMaskName(Type ptype) const; + QString bootLabel() const; + uint nbBlocks() const; + QString blockSizeMaskName(uint i) const; + QString blockMaskName(Type ptype, uint i) const; + QString blockLabel(uint i) const; + AddressRangeVector extractRanges(const QString &name, MemoryRangeType type) const; + bool checkRange(const QString &mask, const QString &name) const; + QString maskName(Type type, MemoryRangeType mtype) const; + bool isAllProtectedValueName(const QString &valueName) const; + bool isNoneProtectedValueName(const QString &valueName) const; + +private: + const Pic::Data &_data; + const Config &_config; + + enum SegmentType { BootSegment = 0, SecureSegment, GeneralSegment, Nb_SegmentTypes }; + static bool extractRanges(const QString &name, QValueVector
&starts, Address &end, bool &ok); + class ProtectedRange { + public: + QValueVector
starts, ends; + }; + ProtectedRange extractRange(const QString &mask, const QString &name, bool &ok) const; +}; + +} //namespace + +#endif diff --git a/src/devices/pic/base/pic_register.cpp b/src/devices/pic/base/pic_register.cpp new file mode 100644 index 0000000..fcfe5ef --- /dev/null +++ b/src/devices/pic/base/pic_register.cpp @@ -0,0 +1,287 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "pic_register.h" + +#include "pic.h" + +//----------------------------------------------------------------------------- +Pic::RegistersData::RegistersData(const Data &data) + : nbBanks(0), accessBankSplit(0), _data(data) +{} + +Address Pic::RegistersData::mirroredAddress(Address address) const +{ + Address mirror = address; + for (uint i=0; i=mirrored[i][k].start+mirrored[i][k].length ) continue; + delta = address - mirrored[i][k].start; + break; + } + if ( delta==-1 ) continue; + for (uint k=0; k::const_iterator it; + for (it=sfrs.begin(); it!=sfrs.end(); ++it) { + if ( it.data().address!=address ) continue; + for (uint i=0; i=unused[i].start && address"; + case Sfr: return sfrNames[address]; + } + Q_ASSERT(false); + return QString::null; +} + +bool Pic::RegistersData::hasPort(uint index) const +{ + Q_ASSERT( index Pic::RegistersData::relatedRegisters(const Register::TypeData &data) const +{ + QValueList list; + if ( data.type()==Register::Regular ) { + int i = portIndex(data.address()); + if ( i==-1 ) list.append(data); + else { + list.append(Register::TypeData(sfrs[portName(i)].address, nbChars())); + if ( hasTris(i) ) list.append(Register::TypeData(sfrs[trisName(i)].address, nbChars())); + if ( hasLatch(i) ) list.append(Register::TypeData(sfrs[latchName(i)].address, nbChars())); + } + } else if ( data.type()==Register::Combined ) { + uint nb = nbBitsToNbBytes(4*data.nbChars()) / nbBytes(); + for (uint i=0; i::const_iterator it; + for (it=sfrNames.begin(); it!=sfrNames.end(); ++it) + if ( bankFromAddress(it.key())==i ) return true; + return false; +} + +bool Pic::RegistersData::hasSharedGprs(uint &firstIndex, bool &all) const +{ + bool ok = false; + all = true; + for (uint i=0; i>(QDataStream &s, RangeData &rd) +{ + s >> rd.start >> rd.length; + return s; +} + +QDataStream &Pic::operator <<(QDataStream &s, const RegisterBitData &rbd) +{ + s << Q_UINT8(rbd.properties) << Q_UINT8(rbd.por) << Q_UINT8(rbd.mclr); + return s; +} +QDataStream &Pic::operator >>(QDataStream &s, RegisterBitData &rbd) +{ + Q_UINT8 properties, por, mclr; + s >> properties >> por >> mclr; + rbd.properties = RegisterBitProperties(properties); + rbd.por = RegisterBitState(por); + rbd.mclr = RegisterBitState(mclr); + return s; +} + +QDataStream &Pic::operator <<(QDataStream &s, const RegisterData &rd) +{ + s << rd.address; + for (int i=0; i>(QDataStream &s, RegisterData &rd) +{ + s >> rd.address; + for (int i=0; i> rd.bits[i]; + return s; +} + +QDataStream &Pic::operator <<(QDataStream &s, const CombinedData &rd) +{ + s << rd.address << rd.nbChars; + return s; +} +QDataStream &Pic::operator >>(QDataStream &s, CombinedData &rd) +{ + s >> rd.address >> rd.nbChars; + return s; +} + +QDataStream &Pic::operator <<(QDataStream &s, const RegistersData &rd) +{ + s << rd.nbBanks << rd.accessBankSplit << rd.unusedBankMask; + s << rd.sfrs << rd.mirrored << rd.unused << rd.combined; + return s; +} +QDataStream &Pic::operator >>(QDataStream &s, RegistersData &rd) +{ + s >> rd.nbBanks >> rd.accessBankSplit >> rd.unusedBankMask; + s >> rd.sfrs >> rd.mirrored >> rd.unused >> rd.combined; + rd.sfrNames.clear(); + QMap::const_iterator it; + for(it=rd.sfrs.begin(); it!=rd.sfrs.end(); ++it) rd.sfrNames[it.data().address] = it.key(); + return s; +} diff --git a/src/devices/pic/base/pic_register.h b/src/devices/pic/base/pic_register.h new file mode 100644 index 0000000..41da020 --- /dev/null +++ b/src/devices/pic/base/pic_register.h @@ -0,0 +1,115 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PIC_REGISTER_H +#define PIC_REGISTER_H + +#include + +#include "devices/base/register.h" +#include "pic.h" + +namespace Pic +{ +class Data; +struct RangeData { + Address start; + uint length; +}; + +//----------------------------------------------------------------------------- +enum RegisterType { UnusedRegister, Sfr, Gpr, Mirrored}; +enum RegisterBitProperty { RegisterBitUnused = 0x0, + RegisterBitRead = 0x1, RegisterBitWrite = 0x2, + RegisterBitOnlySoftwareClear = 0x4, RegisterBitOnlySoftwareSet = 0x8, + MaxRegisterBitProperty = 0x15 +}; +Q_DECLARE_FLAGS(RegisterBitProperties, RegisterBitProperty) +Q_DECLARE_OPERATORS_FOR_FLAGS(RegisterBitProperties) +enum RegisterBitState { RegisterBitUnknown = 0, RegisterBitLow, RegisterBitHigh, + RegisterBitUnchanged, RegisterBitDepends, RegisterBitDependsConfig, Nb_RegisterBitStates +}; + +//----------------------------------------------------------------------------- +class RegisterBitData +{ +public: + RegisterBitData() : properties(RegisterBitUnused) {} + RegisterBitProperties properties; + RegisterBitState por, mclr; +}; +struct RegisterData +{ + Address address; + RegisterBitData bits[Device::MAX_NB_PORT_BITS]; +}; +struct CombinedData +{ + Address address; + uint nbChars; +}; + +class RegistersData : public Device::RegistersData +{ +public: + RegistersData(const Data &data); + virtual uint nbBits() const { return _data.architecture().data().nbBitsRegister; } + uint nbBytesPerBank() const { return _data.architecture().data().registerBankLength; } + uint nbRegistersPerBank() const { return nbBytesPerBank() / nbBytes(); } + uint nbCharsAddress() const { return ::nbChars(nbRegisters() - 1); } + virtual uint nbRegisters() const { return nbBanks * nbRegistersPerBank(); } + virtual uint addressFromIndex(uint i) const { return nbBytes() * i; } + virtual uint indexFromAddress(Address address) const { return address.toUInt() / nbBytes(); } + bool isBankUsed(uint i) const; + uint bankFromAddress(Address address) const { return indexFromAddress(address) / nbRegistersPerBank(); } + bool bankHasSfrs(uint i) const; // slow + bool hasSharedGprs(uint &firstIndex, bool &all) const; // i.e. mirrored in all banks (all is for first bank only) + uint firstGprIndex() const; // in first bank + + uint nbBanks, accessBankSplit, unusedBankMask; + QMap sfrs; + QMap sfrNames; // address -> name + QValueVector > mirrored; + QValueVector unused; + QMap combined; + + virtual Device::RegisterProperties properties(Address address) const; + RegisterType type(Address address) const; + QString label(Address address) const; + virtual QValueList relatedRegisters(const Register::TypeData &data) const; + + virtual bool hasPort(uint index) const; + virtual int portIndex(Address address) const; + virtual QString portName(uint index) const; + bool hasTris(uint index) const; + QString trisName(uint index) const; + bool hasLatch(uint index) const; + QString latchName(uint index) const; + virtual bool hasPortBit(uint index, uint bit) const; + virtual QString portBitName(uint index, uint bit) const; + +private: + const Data &_data; + Address mirroredAddress(Address address) const; +}; + +//----------------------------------------------------------------------------- +QDataStream &operator <<(QDataStream &s, const RangeData &rd); +QDataStream &operator >>(QDataStream &s, RangeData &rd); +QDataStream &operator <<(QDataStream &s, const RegisterBitData &rbd); +QDataStream &operator >>(QDataStream &s, RegisterBitData &rbd); +QDataStream &operator <<(QDataStream &s, const RegisterData &rd); +QDataStream &operator >>(QDataStream &s, RegisterData &rd); +QDataStream &operator <<(QDataStream &s, const CombinedData &rd); +QDataStream &operator >>(QDataStream &s, CombinedData &rd); +QDataStream &operator <<(QDataStream &s, const RegistersData &rd); +QDataStream &operator >>(QDataStream &s, RegistersData &rd); + +} // namespace + +#endif diff --git a/src/devices/pic/gui/Makefile.am b/src/devices/pic/gui/Makefile.am new file mode 100644 index 0000000..72f3165 --- /dev/null +++ b/src/devices/pic/gui/Makefile.am @@ -0,0 +1,9 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +libpicui_la_LDFLAGS = $(all_libraries) +noinst_LTLIBRARIES = libpicui.la + + +libpicui_la_SOURCES = pic_config_editor.cpp \ + pic_config_word_editor.cpp pic_hex_view.cpp pic_memory_editor.cpp pic_register_view.cpp pic_group_ui.cpp \ + pic_prog_group_ui.cpp diff --git a/src/devices/pic/gui/pic_config_editor.cpp b/src/devices/pic/gui/pic_config_editor.cpp new file mode 100644 index 0000000..1812bbf --- /dev/null +++ b/src/devices/pic/gui/pic_config_editor.cpp @@ -0,0 +1,68 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "pic_config_editor.h" + +#include +#include +#include + +#include "pic_config_word_editor.h" +#include "common/common/misc.h" +#include "common/gui/misc_gui.h" + +//---------------------------------------------------------------------------- +Pic::MemoryConfigEditorWidget::MemoryConfigEditorWidget(Memory &memory, bool withWordEditor, QWidget *parent) + : Device::MemoryEditorGroup(&memory, parent, "pic_config_editor_widget"), + MemoryCaster(MemoryRangeType::Config, memory) +{ + QHBoxLayout *hb = new QHBoxLayout(_top); + + TabWidget *tabw = 0; + uint nbWords = device().nbWords(MemoryRangeType::Config); + if ( nbWords>1 ) { + tabw = new TabWidget(this); + tabw->setIgnoreWheelEvent(true); + hb->addWidget(tabw); + } + + for(uint i=0; i1 ) { + page = new QWidget(tabw); + tabw->addTab(page, device().config()._words[i].name); + } else { + page = new QGroupBox(this); + hb->addWidget(page); + } + QVBoxLayout *vbox = new QVBoxLayout(page, 10, 10); + QHBoxLayout *hbox = new QHBoxLayout(vbox); + ConfigWordEditor *we = new ConfigWordEditor(memory, i, withWordEditor, page); + addEditor(we); + hbox->addWidget(we); + hbox->addStretch(1); + vbox->addStretch(1); + } +} + +//---------------------------------------------------------------------------- +Pic::MemoryConfigEditor::MemoryConfigEditor(const HexView *hexview, Memory &memory, QWidget *parent) + : MemoryTypeEditor(hexview, MemoryRangeType::Config, memory, parent, "pic_config_editor") +{} + +void Pic::MemoryConfigEditor::init(bool first) +{ + MemoryTypeEditor::init(first); + MemoryConfigEditorWidget *w = new MemoryConfigEditorWidget(memory(), true, this); + addEditor(w); + _top->addWidget(w); +} diff --git a/src/devices/pic/gui/pic_config_editor.h b/src/devices/pic/gui/pic_config_editor.h new file mode 100644 index 0000000..888debf --- /dev/null +++ b/src/devices/pic/gui/pic_config_editor.h @@ -0,0 +1,37 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PIC_CONFIG_EDITOR_H +#define PIC_CONFIG_EDITOR_H + +#include "pic_memory_editor.h" + +//---------------------------------------------------------------------------- +namespace Pic +{ +class HexView; + +class MemoryConfigEditorWidget : public Device::MemoryEditorGroup, public MemoryCaster +{ +Q_OBJECT +public: + MemoryConfigEditorWidget(Memory &memory, bool withWordEditor, QWidget *parent); +}; + +//---------------------------------------------------------------------------- +class MemoryConfigEditor : public MemoryTypeEditor +{ +Q_OBJECT +public: + MemoryConfigEditor(const HexView *hexview, Memory &memory, QWidget *parent); + virtual void init(bool first); +}; + +} // namespace + +#endif diff --git a/src/devices/pic/gui/pic_config_word_editor.cpp b/src/devices/pic/gui/pic_config_word_editor.cpp new file mode 100644 index 0000000..23e4bce --- /dev/null +++ b/src/devices/pic/gui/pic_config_word_editor.cpp @@ -0,0 +1,196 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "pic_config_word_editor.h" + +#include +#include +#include +#include + +#include "common/common/misc.h" +#include "common/gui/misc_gui.h" + +//---------------------------------------------------------------------------- +Pic::ConfigWordComboBox::ConfigWordComboBox(QWidget *parent) + : ComboBox(parent) +{ + setIgnoreWheelEvent(true); +} + +uint Pic::ConfigWordComboBox::index() const +{ + if ( isValid() ) return _map[currentItem()]; + if ( currentItem()==0 ) return _invalidIndex; + return _map[currentItem()-1]; +} + +void Pic::ConfigWordComboBox::setItem(uint i) +{ + if ( !isValid() ) removeItem(0); + for (uint l=0; l<_map.count(); l++) + if ( _map[l]==i ) setCurrentItem(l); +} + +void Pic::ConfigWordComboBox::setInvalidItem(uint i, const QString &label) +{ + if ( !isValid() ) changeItem(label, 0); + else insertItem(label, 0); + setCurrentItem(0); + _invalidIndex = i; +} + +//---------------------------------------------------------------------------- +Pic::ConfigWordDialog::ConfigWordDialog(const Memory &memory, uint ci, QWidget *parent) + : Dialog(parent, "config_word_dialog", true, i18n("Config Word Details"), Close, Close, false) +{ + uint nbChars = memory.device().nbCharsWord(MemoryRangeType::Config); + const Config::Word &cword = memory.device().config()._words[ci]; + + QGridLayout *grid = new QGridLayout(mainWidget(), 0, 0, 10, 10); + uint row = 0; + QLabel *label = new QLabel(i18n("Name:"), mainWidget()); + grid->addWidget(label, row, 0); + label = new QLabel(cword.name, mainWidget()); + grid->addWidget(label, row, 1); + row++; + label = new QLabel(i18n("Index:"), mainWidget()); + grid->addWidget(label, row, 0); + label = new QLabel(QString::number(ci), mainWidget()); + grid->addWidget(label, row, 1); + row++; + label = new QLabel(i18n("Raw Value:"), mainWidget()); + grid->addWidget(label, row, 0); + label = new QLabel(toHexLabel(memory.word(MemoryRangeType::Config, ci), nbChars), mainWidget()); + grid->addWidget(label, row, 1); + row++; + label = new QLabel(i18n("Value:"), mainWidget()); + grid->addWidget(label, row, 0); + label = new QLabel(toHexLabel(memory.normalizedWord(MemoryRangeType::Config, ci), nbChars), mainWidget()); + grid->addWidget(label, row, 1); + row++; + label = new QLabel(i18n("Raw Blank Value:"), mainWidget()); + grid->addWidget(label, row, 0); + label = new QLabel(toHexLabel(cword.bvalue, nbChars), mainWidget()); + grid->addWidget(label, row, 1); + row++; + label = new QLabel(i18n("Used Mask:"), mainWidget()); + grid->addWidget(label, row, 0); + label = new QLabel(toHexLabel(cword.usedMask(), nbChars), mainWidget()); + grid->addWidget(label, row, 1); + row++; + label = new QLabel(i18n("Write Mask:"), mainWidget()); + grid->addWidget(label, row, 0); + label = new QLabel(toHexLabel(cword.wmask, nbChars), mainWidget()); + grid->addWidget(label, row, 1); + row++; + label = new QLabel(i18n("Protected Mask:"), mainWidget()); + grid->addWidget(label, row, 0); + label = new QLabel(toHexLabel(cword.pmask, nbChars), mainWidget()); + grid->addWidget(label, row, 1); + row++; + label = new QLabel(i18n("Checksum Mask:"), mainWidget()); + grid->addWidget(label, row, 0); + label = new QLabel(toHexLabel(cword.cmask, nbChars), mainWidget()); + grid->addWidget(label, row, 1); + row++; +} + +//---------------------------------------------------------------------------- +Pic::ConfigWordEditor::ConfigWordEditor(Memory &memory, uint ci, bool withWordEditor, QWidget *parent) + : MemoryEditor(MemoryRangeType::Config, memory, parent, "pic_config_word_editor"), _configIndex(ci) +{ + if (withWordEditor) { + QHBoxLayout *hbox = new QHBoxLayout(_top); + _mdb = new MemoryRangeEditor(MemoryRangeType::Config, memory, 1, 1, ci, 1, this); + _mdb->init(); + connect(_mdb, SIGNAL(modified()), SIGNAL(modified())); + connect(_mdb, SIGNAL(modified()), SLOT(updateDisplay())); + hbox->addWidget(_mdb); + KPushButton *button = new KPushButton(i18n("Details..."), this); + button->setFixedHeight(button->sizeHint().height()); + connect(button, SIGNAL(clicked()), SLOT(showDialog())); + hbox->addWidget(button); + hbox->addStretch(1); + } else _mdb = 0; + + QGridLayout *grid = new QGridLayout(_top); + grid->setColStretch(2, 1); + const Config::Word &cword = device().config()._words[ci]; + _combos.resize(cword.masks.count()); + uint nbChars = device().nbCharsWord(MemoryRangeType::Config); + for (uint k=0; k<_combos.count(); k++) { + const Config::Mask &cmask = cword.masks[k]; + QLabel *label = new QLabel(Config::maskLabel(cmask.name) + ":", this); + grid->addWidget(label, k, 0); + label = new QLabel(cmask.name, this); + grid->addWidget(label, k, 1); + _combos[k] = new ConfigWordComboBox(this); + for (uint i=0; iappendItem(label, i); + } + connect(_combos[k], SIGNAL(activated(int)), SLOT(slotModified())); + grid->addWidget(_combos[k], k, 2); + } +} + +void Pic::ConfigWordEditor::setReadOnly(bool readOnly) +{ + if (_mdb) _mdb->setReadOnly(readOnly); + const Config::Word &cword = device().config()._words[_configIndex]; + for (uint k=0; k<_combos.count(); k++) { + const Config::Mask &cmask = cword.masks[k]; + _combos[k]->setEnabled(!readOnly && !cmask.value.isOverlapping(cword.pmask) && cmask.values.count()!=1); + } +} + +void Pic::ConfigWordEditor::slotModified() +{ + BitValue v = memory().word(MemoryRangeType::Config, _configIndex); + //qDebug("BinWordEditor::slotModified %i: %s", _configIndex, toHex(v, 4).data()); + for (uint k=0; k<_combos.count(); k++) { + const Config::Mask &cmask = device().config()._words[_configIndex].masks[k]; + v = v.clearMaskBits(cmask.value); + v |= cmask.values[_combos[k]->index()].value; // set value + } + memory().setWord(MemoryRangeType::Config, _configIndex, v); + //qDebug(" now: %s", toHex(v, 4).data()); + if (_mdb) _mdb->updateDisplay(); + emit modified(); +} + +void Pic::ConfigWordEditor::updateDisplay() +{ + BitValue v = memory().word(MemoryRangeType::Config, _configIndex); + uint nbChars = device().nbCharsWord(MemoryRangeType::Config); + //qDebug("BinWordEditor::updateDisplay %i: %s", _configIndex, toHex(v, 4).data()); + for (uint k=0; k<_combos.count(); k++) { + const Config::Mask &cmask = device().config()._words[_configIndex].masks[k]; + for (int i=cmask.values.count()-1; i>=0; i--) { + if ( cmask.values[i].value.isInside(v) ) { + if ( cmask.values[i].isValid() ) _combos[k]->setItem(i); + else { + QString label = i18n("") + " (" + toHexLabel(cmask.values[i].value, nbChars) + ")"; + _combos[k]->setInvalidItem(i, label); + } + break; + } + } + } + if (_mdb) _mdb->updateDisplay(); +} + +void Pic::ConfigWordEditor::showDialog() +{ + ConfigWordDialog dialog(memory(), _configIndex, this); + dialog.exec(); +} diff --git a/src/devices/pic/gui/pic_config_word_editor.h b/src/devices/pic/gui/pic_config_word_editor.h new file mode 100644 index 0000000..8f483c7 --- /dev/null +++ b/src/devices/pic/gui/pic_config_word_editor.h @@ -0,0 +1,70 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#ifndef PIC_CONFIG_WORD_EDITOR_H +#define PIC_CONFIG_WORD_EDITOR_H + +#include + +#include "common/gui/dialog.h" +#include "common/gui/misc_gui.h" +#include "pic_memory_editor.h" + +namespace Pic +{ +//---------------------------------------------------------------------------- +class ConfigWordDialog : public Dialog +{ +Q_OBJECT +public: + ConfigWordDialog(const Memory &memory, uint index, QWidget *parent); +}; + +//---------------------------------------------------------------------------- +class ConfigWordComboBox : public ComboBox +{ +Q_OBJECT +public: + ConfigWordComboBox(QWidget *parent); + void appendItem(const QString &text, uint index) { insertItem(text); _map.append(index); } + uint index() const; + void setItem(uint index); + void setInvalidItem(uint index, const QString &label); + +private: + QValueVector _map; // item index -> value index + uint _invalidIndex; // if invalid -> value index + + bool isValid() const { return uint(count())==_map.count(); } +}; + +//---------------------------------------------------------------------------- +class ConfigWordEditor : public MemoryEditor +{ +Q_OBJECT +public: + ConfigWordEditor(Memory &memory, uint index, bool withWordEditor, QWidget *parent); + virtual void setReadOnly(bool readOnly); + +public slots: + virtual void updateDisplay(); + +private slots: + void slotModified(); + void showDialog(); + +private: + uint _configIndex; + MemoryRangeEditor *_mdb; + QValueVector _combos; +}; + +} // namespace + +#endif diff --git a/src/devices/pic/gui/pic_group_ui.cpp b/src/devices/pic/gui/pic_group_ui.cpp new file mode 100644 index 0000000..3f7a84c --- /dev/null +++ b/src/devices/pic/gui/pic_group_ui.cpp @@ -0,0 +1,87 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "pic_group_ui.h" + +#include + +#include "libgui/main_global.h" +#include "pic_hex_view.h" +#include "pic_register_view.h" +#include "pic_config_editor.h" +#include "coff/base/text_coff.h" +#include "libgui/gui_debug_manager.h" +#include "common/gui/list_container.h" + +Device::HexView *Pic::GroupUI::createHexView(const HexEditor &editor, QWidget *parent) const +{ + return new HexView(editor, parent); +} + +Register::View *Pic::GroupUI::createRegisterView(QWidget *parent) const +{ + return new RegisterView(parent); +} + +Device::MemoryEditor *Pic::GroupUI::createConfigEditor(Device::Memory &memory, QWidget *parent) const +{ + return new MemoryConfigEditorWidget(static_cast(memory), false, parent); +} + +void Pic::GroupUI::fillWatchListContainer(ListContainer *container, QValueVector &ids) const +{ + ids.clear(); + const Pic::Data &data = static_cast(*Main::deviceData()); + const Pic::RegistersData &rdata = data.registersData(); + ListContainer *branch = container->appendBranch(i18n("SFRs")); + QValueVector list = Pic::sfrList(data); + for (uint i=0; iappendItem(list[i].label(), ids.count(), ListContainer::UnChecked); + ids.append(list[i].data()); + } + branch = container->appendBranch(i18n("I/Os")); + for (uint i=0; iappendItem(name, ids.count(), ListContainer::UnChecked); + ids.append(Register::TypeData(rdata.sfrs[name].address, rdata.nbChars())); + } + branch = container->appendBranch(i18n("GPRs")); + const Coff::Object *coff = Debugger::manager->coff(); + list = Pic::gprList(data, coff); + for (uint k=0; kappendBranch(i18n("Bank %1").arg(k))); + uint nb = 0; + for (uint i=0; iappendItem(list[i].label(), ids.count(), ListContainer::UnChecked); + ids.append(list[i].data()); + nb++; + } + } + branch = container->appendBranch(i18n("Variables")); + if (coff) { + list = Pic::variableList(data, *coff); + if ( list.count()==0 ) { + branch->appendItem(i18n("No variable"), ids.count(), ListContainer::Disabled); + ids.append(Register::TypeData()); + } else for (uint i=0; iappendItem(list[i].label(), ids.count(), ListContainer::UnChecked); + ids.append(list[i].data()); + } + } else { + branch->appendItem(i18n("Please compile the current project"), ids.count(), ListContainer::Disabled); + ids.append(Register::TypeData()); + } +} + +Register::ListViewItem *Pic::GroupUI::createWatchItem(const Register::TypeData &data, KListViewItem *parent) const +{ + return new Pic::RegisterListViewItem(data, parent); +} diff --git a/src/devices/pic/gui/pic_group_ui.h b/src/devices/pic/gui/pic_group_ui.h new file mode 100644 index 0000000..a8bee66 --- /dev/null +++ b/src/devices/pic/gui/pic_group_ui.h @@ -0,0 +1,29 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PIC_GROUP_UI_H +#define PIC_GROUP_UI_H + +#include "devices/gui/device_group_ui.h" + +namespace Pic +{ + +class GroupUI : public Device::GroupUI +{ +public: + virtual Device::HexView *createHexView(const HexEditor &editor, QWidget *parent) const; + virtual Register::View *createRegisterView(QWidget *parent) const; + virtual Device::MemoryEditor *createConfigEditor(Device::Memory &memory, QWidget *parent) const; + virtual void fillWatchListContainer(ListContainer *container, QValueVector &ids) const; + virtual Register::ListViewItem *createWatchItem(const Register::TypeData &data, KListViewItem *parent) const; +}; + +} // namespace + +#endif diff --git a/src/devices/pic/gui/pic_hex_view.cpp b/src/devices/pic/gui/pic_hex_view.cpp new file mode 100644 index 0000000..07a1938 --- /dev/null +++ b/src/devices/pic/gui/pic_hex_view.cpp @@ -0,0 +1,60 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * Copyright (C) 2003 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "pic_hex_view.h" + +#include +#include + +#include + +#include "pic_memory_editor.h" +#include "pic_config_editor.h" + +Pic::HexView::HexView(const HexEditor &editor, QWidget *parent) + : Device::HexView(editor, parent, "pic_hex_view") +{} + +const Pic::MemoryRangeType::Type Pic::HexView::MEMORY_DATA[] = { + MemoryRangeType::Code, MemoryRangeType::Config, MemoryRangeType::Eeprom, MemoryRangeType::UserId, + MemoryRangeType::Cal, MemoryRangeType::Nb_Types +}; + +void Pic::HexView::display() +{ + bool first = true; + for (uint i=0; MEMORY_DATA[i]!=MemoryRangeType::Nb_Types; i++) { + Pic::MemoryRangeType type = MEMORY_DATA[i]; + if ( !memory()->device().isReadable(type) ) continue; + Device::MemoryTypeEditor *e = 0; + switch (type.type()) { + case MemoryRangeType::Config: e = new MemoryConfigEditor(this, *memory(), this); break; + case MemoryRangeType::Cal: e = new MemoryCalibrationEditor(this, *memory(), this); break; + case MemoryRangeType::Code: + case MemoryRangeType::Eeprom: e = new MemoryTypeRangeEditor(this, type, *memory(), this); break; + case MemoryRangeType::UserId: e = new MemoryUserIdEditor(this, *memory(), this); break; + case MemoryRangeType::DeviceId: + case MemoryRangeType::HardwareStack: + case MemoryRangeType::ProgramExecutive: + case MemoryRangeType::DebugVector: + case MemoryRangeType::CalBackup: + case MemoryRangeType::Nb_Types: Q_ASSERT(false); break; + } + e->init(first); + e->show(); + _top->addWidget(e); + addEditor(e); + first = false; + } +} + +BitValue Pic::HexView::checksum() const +{ + return (_memory ? memory()->checksum() : 0x0000); +} diff --git a/src/devices/pic/gui/pic_hex_view.h b/src/devices/pic/gui/pic_hex_view.h new file mode 100644 index 0000000..2086ccb --- /dev/null +++ b/src/devices/pic/gui/pic_hex_view.h @@ -0,0 +1,39 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * Copyright (C) 2003 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#ifndef PIC_HEX_VIEW_H +#define PIC_HEX_VIEW_H + +class QVBoxLayout; + +#include "devices/gui/hex_view.h" +#include "devices/pic/pic/pic_memory.h" + +namespace Pic +{ + +class HexView : public Device::HexView +{ +Q_OBJECT +public: + HexView(const HexEditor &editor, QWidget *parent); + Memory *memory() { return static_cast(_memory); } + const Memory *memory() const { return static_cast(_memory); } + virtual uint nbChecksumChars() const { return 4; } + virtual BitValue checksum() const; + +private: + static const MemoryRangeType::Type MEMORY_DATA[]; + + virtual void display(); +}; + +} // namespace + +#endif diff --git a/src/devices/pic/gui/pic_memory_editor.cpp b/src/devices/pic/gui/pic_memory_editor.cpp new file mode 100644 index 0000000..3d78097 --- /dev/null +++ b/src/devices/pic/gui/pic_memory_editor.cpp @@ -0,0 +1,404 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "pic_memory_editor.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "common/common/misc.h" +#include "pic_config_editor.h" +#include "libgui/toplevel.h" +#include "libgui/main_global.h" +#include "devices/pic/prog/pic_prog.h" +#include "libgui/global_config.h" +#include "pic_hex_view.h" + +//----------------------------------------------------------------------------- +Pic::MemoryEditorLegend::Data::Data(const QString &text, QWidget *parent) +{ + button = new PopupButton(text, parent); + KActionCollection *ac = 0; + KAction *a = new KAction(i18n("Go to start"), "top", 0, parent, SLOT(gotoStart()), ac); + actions.append(a); + button->appendAction(a); + a = new KAction(i18n("Go to end"), "bottom", 0, parent, SLOT(gotoEnd()), ac); + actions.append(a); + button->appendAction(a); + label = new QLabel(parent); +} + +void Pic::MemoryEditorLegend::Data::setProtected(bool on) +{ + if (on) label->setPaletteBackgroundColor(MemoryEditorLegend::protectedColor()); + else label->unsetPalette(); +} + +bool Pic::MemoryEditorLegend::Data::hasAction(const KAction *action) const +{ + for (uint i=0; isetFixedWidth(20); + w->setPaletteBackgroundColor(protectedColor()); + grid->addWidget(w, 0, 0); + const Protection &protection = device().config().protection(); + QString s = (protection.family()==Protection::CodeGuard ? i18n("High Security") : i18n("Code protection")); + QLabel *label = new QLabel(s, this); + grid->addMultiCellWidget(label, 0,0, 1,2); + grid->addRowSpacing(1, 10); + uint row = 2; + + if ( type==MemoryRangeType::Code && protection.hasBootBlock() ) { + w = new QWidget(this); + w->setFixedWidth(20); + w->setPaletteBackgroundColor(bootColor()); + grid->addWidget(w, row, 0); + _boot = Data(protection.bootLabel(), this); + grid->addWidget(_boot.button, row, 1); + grid->addWidget(_boot.label, row, 2); + row++; + } + + uint nb = (type==MemoryRangeType::Code ? protection.nbBlocks() : 0); + for (uint i=0; isetFixedWidth(20); + w->setPaletteBackgroundColor(blockColor(i)); + grid->addWidget(w, row, 0); + _blocks.append(Data(protection.blockLabel(i), this)); + grid->addWidget(_blocks[i].button, row, 1); + grid->addWidget(_blocks[i].label, row, 2); + row++; + } +} + +void Pic::MemoryEditorLegend::updateDisplay() +{ + const Protection &protection = device().config().protection(); + Protection::Type ptype = (protection.family()==Protection::CodeGuard ? Protection::HighSecurity : Protection::ProgramProtected); + uint nbChars = 2 * device().nbBytesAddress(); + if (_boot.label) { + AddressRange r = memory().bootRange(); + if ( r.isEmpty() ) _boot.label->setText(i18n("not present")); + else _boot.label->setText(QString("[%1:%2]").arg(toHex(r.start, nbChars)).arg(toHex(r.end, nbChars))); + _boot.button->setEnabled(!r.isEmpty()); + _boot.setProtected(memory().isBootProtected(ptype)); + } + for (uint i=0; i<_blocks.count(); i++) { + AddressRange r = memory().blockRange(i); + if ( r.isEmpty() ) _blocks[i].label->setText(i18n("not present")); + else _blocks[i].label->setText(QString("[%1:%2]").arg(toHex(r.start, nbChars)).arg(toHex(r.end, nbChars))); + _blocks[i].button->setEnabled(!r.isEmpty()); + _blocks[i].setProtected(memory().isBlockProtected(ptype, i)); + } +} + +void Pic::MemoryEditorLegend::gotoStart() +{ + Address start = device().range(type()).start; + const KAction *action = static_cast(sender()); + if ( _boot.hasAction(action) ) { + AddressRange r = memory().bootRange(); + emit setStartWord(r.start - start); + return; + } + for (uint i=0; i<_blocks.count(); i++) { + if ( _blocks[i].hasAction(action) ) { + AddressRange r = memory().blockRange(i); + emit setStartWord(r.start - start); + return; + } + } + Q_ASSERT(false); +} + +void Pic::MemoryEditorLegend::gotoEnd() +{ + Address start = device().range(type()).start; + const KAction *action = static_cast(sender()); + if ( _boot.hasAction(action) ) { + AddressRange r = memory().bootRange(); + emit setEndWord(r.end - start); + return; + } + for (uint i=0; i<_blocks.count(); i++) { + if ( _blocks[i].hasAction(action) ) { + AddressRange r = memory().blockRange(i); + emit setEndWord(r.end - start); + return; + } + } + Q_ASSERT(false); +} + + +//----------------------------------------------------------------------------- +Pic::HexWordEditor::HexWordEditor(MemoryRangeType type, Memory &memory, QWidget *parent) + : Device::HexWordEditor(memory, memory.device().nbCharsWord(type), parent), + MemoryCaster(type, memory) +{} + +void Pic::HexWordEditor::setWord(BitValue value) +{ + if ( type()==MemoryRangeType::Config ) { + const Config::Word &cword = device().config()._words[_offset]; + value |= cword.usedMask().complementInMask(device().mask(MemoryRangeType::Config)); + } + memory().setWord(type(), _offset, value); +} + +//----------------------------------------------------------------------------- +Pic::MemoryRangeEditor::MemoryRangeEditor(MemoryRangeType type, Memory &memory, + uint nbLines, uint nbCols, + uint wordOffset, int nbWords, QWidget *parent) + : Device::MemoryRangeEditor(memory, nbLines, nbCols, wordOffset, nbWords, parent, "pic_memory_range_editor"), + MemoryCaster(type, memory), _legend(0) +{ + if ( type==MemoryRangeType::Code ) _blockRanges.resize(memory.device().config().protection().nbBlocks()); +} + +void Pic::MemoryRangeEditor::addLegend(QVBoxLayout *vbox) +{ + if ( type()==MemoryRangeType::Code || type()==MemoryRangeType::Eeprom ) { + _legend = new MemoryEditorLegend(type(), memory(), this); + connect(_legend, SIGNAL(setStartWord(int)), SLOT(setStartWord(int))); + connect(_legend, SIGNAL(setEndWord(int)), SLOT(setEndWord(int))); + vbox->addWidget(_legend); + } +} + +bool Pic::MemoryRangeEditor::isRangeReadOnly() const +{ + return ( (type().data().properties & ReadOnly) || type()==MemoryRangeType::CalBackup ); +} + +void Pic::MemoryRangeEditor::updateDisplay() +{ + const Protection &protection = device().config().protection(); + if ( type()==MemoryRangeType::Code ) { + if ( protection.hasBootBlock() ) _bootRange = memory().bootRange(); + for (uint k=0; k<_blockRanges.count(); k++) + _blockRanges[k] = memory().blockRange(k); + } + Protection::Type ptype = (protection.family()==Protection::CodeGuard ? Protection::HighSecurity : Protection::ProgramProtected); + _codeProtected = memory().protectedRanges(ptype, type()); + Device::MemoryRangeEditor::updateDisplay(); + if (_legend) _legend->updateDisplay(); +} + +void Pic::MemoryRangeEditor::updateAddressColor(uint i, Address address) +{ + if ( _codeProtected.contains(address) ) + _addresses[i]->setPaletteBackgroundColor(MemoryEditorLegend::protectedColor()); + else _addresses[i]->unsetPalette(); + _blocks[i]->unsetPalette(); + if ( type()==MemoryRangeType::Code ) { + if ( _bootRange.contains(address) ) _blocks[i]->setPaletteBackgroundColor(MemoryEditorLegend::bootColor()); + else for (uint k=0; k<_blockRanges.count(); k++) { + if ( !_blockRanges[k].contains(address) ) continue; + _blocks[i]->setPaletteBackgroundColor(MemoryEditorLegend::blockColor(k)); + break; + } + } +} + +Device::HexWordEditor *Pic::MemoryRangeEditor::createHexWordEditor(QWidget *parent) +{ + return new HexWordEditor(type(), memory(), parent); +} + +//----------------------------------------------------------------------------- +Pic::MemoryTypeEditor::MemoryTypeEditor(const HexView *hexview, MemoryRangeType type, Memory &memory, QWidget *parent, const char *name) + : Device::MemoryTypeEditor(hexview, memory, parent, name), MemoryCaster(type, memory) +{} + +void Pic::MemoryTypeEditor::init(bool first) +{ + Device::MemoryTypeEditor::init(first); + _title->setText(type().label()); + + uint nbChars = device().nbCharsWord(type()); + QString add; + if ( type()==MemoryRangeType::UserId ) add = i18n(" - recommended mask: %1").arg(toHexLabel(device().userIdRecommendedMask(), nbChars)); + if ( type()==MemoryRangeType::Cal && _hexview ) add = i18n(" - not programmed by default"); + QString comment = i18n("%1-bit words - mask: %2") + .arg(device().nbBitsWord(type())).arg(toHexLabel(device().mask(type()), nbChars)); + _comment->setText(comment + add); +} + +bool Pic::MemoryTypeEditor::internalDoAction(Device::Action action) +{ + Programmer::PicBase *prog = static_cast(Main::programmer()); + switch (action) { + case Device::Clear: memory().clear(type()); return true; + case Device::Zero: memory().fill(type(), 0); return true; + case Device::ChecksumCheck : memory().checksumCheckFill(); return true; + case Device::Reload: { + const Memory *omemory = static_cast(originalMemory()); + Q_ASSERT(omemory); + memory().copyFrom(type(), *omemory); return true; + } + case Device::Program: + prog->programSingle(type(), memory()); + return false; + case Device::Verify: + prog->verifySingle(type(), memory()); + return false; + case Device::Read: + return prog->readSingle(type(), memory()); + case Device::Erase: + prog->eraseSingle(type()); + return false; + case Device::BlankCheck: + prog->blankCheckSingle(type()); + return false; + case Device::Nb_Actions: break; + } + Q_ASSERT(false); + return false; +} + +//----------------------------------------------------------------------------- +Pic::MemoryTypeRangeEditor::MemoryTypeRangeEditor(const HexView *hexview, MemoryRangeType type, Memory &memory, QWidget *parent) + : MemoryTypeEditor(hexview, type, memory, parent, "pic_memory_type_range_editor"), _mre(0) +{} + +void Pic::MemoryTypeRangeEditor::init(bool first) +{ + MemoryTypeEditor::init(first); + uint nbLines = 0; + if ( type()==MemoryRangeType::Code ) nbLines = 16; + else if ( type()==MemoryRangeType::Eeprom ) nbLines = 8; + else nbLines = (device().nbWords(type())/8>1 ? 2 : 1); + _mre = new MemoryRangeEditor(type(), memory(), nbLines, 8, 0, -1, this); + addEditor(_mre); + _top->addWidget(_mre); + _mre->init(); +} + +//----------------------------------------------------------------------------- +Pic::MemoryUserIdEditor::MemoryUserIdEditor(const HexView *hexview, Memory &memory, QWidget *parent) + : MemoryTypeRangeEditor(hexview, MemoryRangeType::UserId, memory, parent), _saveReadOnly(false) +{} + +void Pic::MemoryUserIdEditor::init(bool first) +{ + MemoryTypeRangeEditor::init(first); + _setToChecksum = new KToggleAction(i18n("Set to unprotected checksum"), 0, 0, + this, SLOT(toggleSetToChecksum()), Main::toplevel().actionCollection()); + addAction(_setToChecksum); + if ( readConfigEntry(BaseGlobalConfig::UserIdSetToChecksum).toBool() && memory().isClear(MemoryRangeType::UserId) ) { + _setToChecksum->activate(); + toggleSetToChecksum(); + } +} + +void Pic::MemoryUserIdEditor::toggleSetToChecksum() +{ + if ( _setToChecksum->isChecked() ) { + _mre->setComment(i18n("Set to unprotected checksum")); + emit modified(); + } else _mre->setComment(QString::null); + setReadOnly(_saveReadOnly); +} + +void Pic::MemoryUserIdEditor::updateDisplay() +{ + if ( _setToChecksum->isChecked() ) memory().setUserIdToUnprotectedChecksum(); + MemoryTypeRangeEditor::updateDisplay(); +} + +void Pic::MemoryUserIdEditor::setReadOnly(bool readOnly) +{ + _saveReadOnly = readOnly; + MemoryTypeRangeEditor::setReadOnly(readOnly || _setToChecksum->isChecked()); +} + +//----------------------------------------------------------------------------- +Pic::MemoryCalibrationEditor::MemoryCalibrationEditor(const HexView *hexview, Memory &memory, QWidget *parent) + : MemoryTypeEditor(hexview, MemoryRangeType::Cal, memory, parent, "pic_memory_calibration_editor") +{} + +void Pic::MemoryCalibrationEditor::init(bool first) +{ + MemoryTypeEditor::init(first); + MemoryRangeEditor *mre = new MemoryRangeEditor(MemoryRangeType::Cal, memory(), 1, 8, 0, -1, this); + addEditor(mre); + _top->addWidget(mre); + mre->init(); + if ( device().isReadable(MemoryRangeType::CalBackup) ) { + mre = new MemoryRangeEditor(MemoryRangeType::CalBackup, memory(), 1, 8, 0, -1, this); + addEditor(mre); + _top->addWidget(mre); + mre->init(); + mre->setComment(i18n("(backup)")); + } +} + +bool Pic::MemoryCalibrationEditor::hasAction(Device::Action action) const +{ + return ( action==Device::Read || action==Device::Verify || action==Device::Program ); +} + +bool Pic::MemoryCalibrationEditor::internalDoAction(Device::Action action) +{ + Programmer::PicBase *prog = static_cast(Main::programmer()); + switch (action) { + case Device::Reload: { + const Memory *omemory = static_cast(originalMemory()); + Q_ASSERT(omemory); + memory().copyFrom(MemoryRangeType::Cal, *omemory); + memory().copyFrom(MemoryRangeType::CalBackup, *omemory); + return true; + } + case Device::Program: + if ( prog->programCalibration(memory().arrayForWriting(Pic::MemoryRangeType::Cal)) ) + return prog->readSingle(MemoryRangeType::Cal, memory()); + return false; + case Device::Verify: + prog->verifySingle(MemoryRangeType::Cal, memory()); + return false; + case Device::Read: + return prog->readSingle(MemoryRangeType::Cal, memory()); + case Device::Clear: + case Device::Zero: + case Device::ChecksumCheck: + case Device::Erase: + case Device::BlankCheck: + case Device::Nb_Actions: break; + } + Q_ASSERT(false); + return false; +} diff --git a/src/devices/pic/gui/pic_memory_editor.h b/src/devices/pic/gui/pic_memory_editor.h new file mode 100644 index 0000000..bf67cd1 --- /dev/null +++ b/src/devices/pic/gui/pic_memory_editor.h @@ -0,0 +1,189 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#ifndef PIC_MEMORY_EDITOR_H +#define PIC_MEMORY_EDITOR_H + +#include +#include +class KToggleAction; + +#include "devices/gui/memory_editor.h" +#include "devices/gui/hex_word_editor.h" +#include "devices/pic/pic/pic_memory.h" +class PopupButton; + +namespace Pic +{ +class HexView; + +//----------------------------------------------------------------------------- +class MemoryCaster +{ +public: + MemoryCaster(MemoryRangeType type, Device::Memory &memory) : _type(type), _memory(memory) {} + MemoryRangeType type() const { return _type; } + const Data &device() const { return static_cast(_memory.device()); } + const Memory &memory() const { return static_cast(_memory); } + Memory &memory() { return static_cast(_memory); } + +private: + MemoryRangeType _type; + Device::Memory &_memory; +}; + +//----------------------------------------------------------------------------- +class MemoryEditor : public Device::MemoryEditor, public MemoryCaster +{ +Q_OBJECT +public: + MemoryEditor(MemoryRangeType type, Memory &memory, QWidget *parent, const char *name) + : Device::MemoryEditor(&memory, parent, name), MemoryCaster(type, memory) {} +}; + +//----------------------------------------------------------------------------- +class MemoryEditorLegend : public MemoryEditor +{ +Q_OBJECT +public: + MemoryEditorLegend(MemoryRangeType type, Memory &memory, QWidget *parent); + virtual void setReadOnly(bool) {} + + static QColor protectedColor() { return QColor("#FF8888"); } + static QColor bootColor() { return QColor("#8888FF"); } + static QColor blockColor(uint i) { return QColor(BLOCK_COLORS[i]); } + +signals: + void setStartWord(int i); + void setEndWord(int i); + +public slots: + virtual void updateDisplay(); + +private slots: + void gotoStart(); + void gotoEnd(); + +private: + class Data { + public: + Data() : button(0), label(0) {} + Data(const QString &text, QWidget *parent); + void setProtected(bool on); + bool hasAction(const KAction *action) const; + PopupButton *button; + QLabel *label; + QValueVector actions; + }; + Data _boot; + QValueVector _blocks; + + static const char * const BLOCK_COLORS[Protection::MAX_NB_BLOCKS]; +}; + +//----------------------------------------------------------------------------- +class HexWordEditor : public Device::HexWordEditor, public MemoryCaster +{ +Q_OBJECT +public: + HexWordEditor(MemoryRangeType type, Memory &memory, QWidget *parent); + +private: + virtual BitValue mask() const { return memory().device().mask(type()); } + virtual BitValue normalizeWord(BitValue value) const { return memory().normalizeWord(type(), _offset, value); } + virtual BitValue word() const { return memory().word(type(), _offset); } + virtual void setWord(BitValue value); +}; + +//----------------------------------------------------------------------------- +class MemoryRangeEditor : public Device::MemoryRangeEditor, public MemoryCaster +{ + Q_OBJECT +public: + MemoryRangeEditor(MemoryRangeType type, Memory &memory, + uint nbLines, uint nbCols, uint wordOffset, int nbWords, QWidget *parent); + +public slots: + virtual void updateDisplay(); + +private: + MemoryEditorLegend *_legend; + AddressRange _bootRange; + AddressRangeVector _blockRanges; + AddressRangeVector _codeProtected; + + virtual uint nbWords() const { return device().nbWords(type()); } + virtual uint addressIncrement() const { return device().addressIncrement(type()); } + virtual Address startAddress() const { return device().range(type()).start; } + virtual Device::HexWordEditor *createHexWordEditor(QWidget *parent); + virtual void updateAddressColor(uint i, Address address); + virtual bool isRangeReadOnly() const; + virtual void addLegend(QVBoxLayout *vbox); +}; + +//----------------------------------------------------------------------------- +class MemoryTypeEditor : public Device::MemoryTypeEditor, public MemoryCaster +{ +Q_OBJECT +public: + MemoryTypeEditor(const HexView *hexview, MemoryRangeType type, Memory &memory, QWidget *parent, const char *name); + virtual void init(bool first); + +private: + virtual bool internalDoAction(Device::Action action); +}; + +//----------------------------------------------------------------------------- +class MemoryTypeRangeEditor : public MemoryTypeEditor +{ +Q_OBJECT +public: + MemoryTypeRangeEditor(const HexView *hexview, MemoryRangeType type, Memory &memory, QWidget *parent); + virtual void init(bool first); + +protected: + MemoryRangeEditor *_mre; +}; + +//----------------------------------------------------------------------------- +class MemoryUserIdEditor : public MemoryTypeRangeEditor +{ +Q_OBJECT +public: + MemoryUserIdEditor(const HexView *hexview, Memory &memory, QWidget *parent); + virtual void init(bool first); + virtual void setReadOnly(bool readOnly); + +public slots: + virtual void updateDisplay(); + +private slots: + void toggleSetToChecksum(); + +private: + bool _saveReadOnly; + KToggleAction *_setToChecksum; +}; + +//----------------------------------------------------------------------------- +class MemoryCalibrationEditor : public MemoryTypeEditor +{ +Q_OBJECT +public: + MemoryCalibrationEditor(const HexView *hexview, Memory &memory, QWidget *parent); + virtual void init(bool first); + +private: + virtual bool hasAction(Device::Action action) const; + virtual bool internalDoAction(Device::Action action); +}; + +} // namespace + +#endif diff --git a/src/devices/pic/gui/pic_prog_group_ui.cpp b/src/devices/pic/gui/pic_prog_group_ui.cpp new file mode 100644 index 0000000..e063b77 --- /dev/null +++ b/src/devices/pic/gui/pic_prog_group_ui.cpp @@ -0,0 +1,41 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "pic_prog_group_ui.h" + +#include "progs/gui/prog_config_widget.h" +#include "progs/base/prog_group.h" + +Programmer::PicAdvancedDialog::PicAdvancedDialog(PicBase &base, QWidget *parent, const char *name) + : AdvancedDialog(base, parent, name) +{ + if (_voltagesContainer) { + uint k = _voltagesContainer->numRows(); + for (uint i=0; iaddWidget(label, k,k, 0,0); + _voltages[i] = new QLabel(_voltagesContainer); + _voltagesContainer->addWidget(_voltages[i], k,k, 1,1); + k++; + } + } + } +} + +void Programmer::PicAdvancedDialog::updateDisplay() +{ + ::Programmer::AdvancedDialog::updateDisplay(); + for (uint i=0; isetText("---"); + else _voltages[i]->setText(QString("%1 V").arg(v)); + } +} diff --git a/src/devices/pic/gui/pic_prog_group_ui.h b/src/devices/pic/gui/pic_prog_group_ui.h new file mode 100644 index 0000000..75821b5 --- /dev/null +++ b/src/devices/pic/gui/pic_prog_group_ui.h @@ -0,0 +1,31 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PIC_PROG_GROUP_UI_H +#define PIC_PROG_GROUP_UI_H + +#include "progs/gui/prog_group_ui.h" +#include "devices/pic/prog/pic_prog.h" + +namespace Programmer +{ +class PicAdvancedDialog : public ::Programmer::AdvancedDialog +{ +Q_OBJECT +public: + PicAdvancedDialog(PicBase &base, QWidget *parent, const char *name); + virtual void updateDisplay(); + +private: + QLabel *_voltages[Pic::Nb_VoltageTypes]; + PicBase &base() { return static_cast(_base); } +}; + +} // namespace + +#endif diff --git a/src/devices/pic/gui/pic_register_view.cpp b/src/devices/pic/gui/pic_register_view.cpp new file mode 100644 index 0000000..ef7de9b --- /dev/null +++ b/src/devices/pic/gui/pic_register_view.cpp @@ -0,0 +1,329 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "pic_register_view.h" + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "libgui/main_global.h" +#include "devices/gui/hex_word_editor.h" +#include "common/gui/misc_gui.h" +#include "devices/pic/base/pic.h" +#include "progs/base/generic_prog.h" +#include "progs/base/generic_debug.h" +#include "progs/base/prog_group.h" +#include "libgui/gui_debug_manager.h" +#include "coff/base/text_coff.h" + +//----------------------------------------------------------------------------- +Pic::BankWidget::BankWidget(uint i, QWidget *parent) + : QFrame(parent, "bank_widget"), _bindex(i), _bankCombo(0) +{ + setFrameStyle(WinPanel | Sunken); + QGridLayout *top = new QGridLayout(this, 1, 1, 5, 0); + top->setColSpacing(1, 4); + QFont f("courier", font().pointSize()); + + const Pic::Data &data = static_cast(*Main::deviceData()); + const Pic::RegistersData &rdata = data.registersData(); + bool debugging = Main::programmerGroup().isDebugger(); + uint row = 0; + if ( rdata.nbBanks!=1 ) { + if ( data.is18Family() ) { + if ( (i/2)==0 ) { + QString title = ((i%2)==0 ? i18n("Access Bank (low)") : i18n("Access Bank (high)")); + QLabel *label = new QLabel(title, this); + label->setAlignment(AlignCenter); + top->addMultiCellWidget(label, row,row, 0,6, AlignHCenter); + } else { + _bankCombo = new QComboBox(this); + for (uint k=1; k<2*rdata.nbBanks-1; k++) { + _bankCombo->insertItem((k%2)==0 ? i18n("Bank %1 (low)").arg(k/2) : i18n("Bank %1 (high)").arg(k/2)); + } + if ( _bindex==3 ) _bankCombo->setCurrentItem(1); + connect(_bankCombo, SIGNAL(activated(int)), SLOT(bankChanged())); + top->addMultiCellWidget(_bankCombo, row,row, 0,6, AlignHCenter); + } + } else { + QLabel *label = new QLabel(i18n("Bank %1").arg(i), this); + label->setAlignment(AlignCenter); + top->addMultiCellWidget(label, row,row, 0,6, AlignHCenter); + } + row++; + top->setRowSpacing(row, 5); + row++; + } + + KIconLoader loader; + QPixmap readIcon = loader.loadIcon("viewmag", KIcon::Small); + QPixmap editIcon = loader.loadIcon("edit", KIcon::Small); + uint nb; + if ( !data.is18Family() ) nb = rdata.nbRegistersPerBank(); + else nb = kMax(rdata.accessBankSplit, rdata.nbRegistersPerBank() - rdata.accessBankSplit); + _registers.resize(nb); + for (uint k=0; ksetFont(f); + top->addWidget(_registers[k].alabel, row, 0); + if (debugging) { + _registers[k].button = new PopupButton(this); + _registers[k].button->appendItem(i18n("Read"), readIcon, ReadId); + _registers[k].button->appendItem(i18n("Edit"), editIcon, EditId); + _registers[k].button->appendItem(i18n("Watch"), WatchId); + connect(_registers[k].button, SIGNAL(activated(int)), SLOT(buttonActivated(int))); + top->addWidget(_registers[k].button, row, 2); + _registers[k].edit = new Register::LineEdit(this); + connect(_registers[k].edit, SIGNAL(modified()), SLOT(write())); + _registers[k].edit->setFont(f); + top->addWidget(_registers[k].edit, row, 6); + } else { + _registers[k].label = new QLabel(this); + top->addWidget(_registers[k].label, row, 2); + } + row++; + } + + if (debugging) { + top->setColSpacing(3, 5); + top->setColSpacing(5, 5); + } + top->setRowStretch(row, 1); + + updateRegisterAddresses(); +} + +void Pic::BankWidget::bankChanged() +{ + updateRegisterAddresses(); + updateView(); +} + +uint Pic::BankWidget::bank() const +{ + const Pic::Data &data = static_cast(*Main::deviceData()); + if ( !data.is18Family() ) return _bindex; + if ( _bindex==0 ) return 0; + const Pic::RegistersData &rdata = data.registersData(); + if ( _bindex==1 ) return rdata.nbBanks - 1; + return (_bankCombo->currentItem()+1)/2; +} + +uint Pic::BankWidget::nbRegisters() const +{ + const Pic::Data &data = static_cast(*Main::deviceData()); + const Pic::RegistersData &rdata = data.registersData(); + if ( !data.is18Family() ) return rdata.nbRegistersPerBank(); + if ( _bindex==0 || (_bankCombo && _bankCombo->currentItem()==2*int(rdata.nbBanks)-3) ) return rdata.accessBankSplit; + if ( _bindex==1 || (_bankCombo && _bankCombo->currentItem()==0) ) return rdata.nbRegistersPerBank() - rdata.accessBankSplit; + return rdata.nbRegistersPerBank() / 2; +} + +uint Pic::BankWidget::indexOffset() const +{ + const Pic::Data &data = static_cast(*Main::deviceData()); + const Pic::RegistersData &rdata = data.registersData(); + uint offset = bank() * rdata.nbRegistersPerBank(); + if ( !data.is18Family() ) return offset; + if ( _bindex==0 || (_bankCombo && (_bankCombo->currentItem()%2)==1) ) return offset; + if ( _bindex==1 || (_bankCombo && _bankCombo->currentItem()==0) ) return offset + rdata.accessBankSplit; + return offset + rdata.nbRegistersPerBank()/2; +} + +void Pic::BankWidget::updateRegisterAddresses() +{ + const Pic::Data &data = static_cast(*Main::deviceData()); + const Pic::RegistersData &rdata = data.registersData(); + uint nbChars = rdata.nbCharsAddress(); + uint nb = nbRegisters(); + uint offset = indexOffset(); + for (uint k=0; k<_registers.count(); k++) { + if ( kshow(); + _registers[k].address = rdata.addressFromIndex(offset + k); + _registers[k].alabel->setText(toHexLabel(_registers[k].address, nbChars) + ":"); + } else _registers[k].alabel->hide(); + } +} + +void Pic::BankWidget::buttonActivated(int id) +{ + const Pic::Data &data = static_cast(*Main::deviceData()); + const Pic::RegistersData &rdata = data.registersData(); + for (uint i=0; i<_registers.count(); i++) { + if ( sender()!=_registers[i].button ) continue; + Register::TypeData rtd(_registers[i].address, rdata.nbChars()); + switch (id) { + case ReadId: Debugger::manager->readRegister(rtd); break; + case EditId: + _registers[i].edit->selectAll(); + _registers[i].edit->setFocus(); + break; + case WatchId: { + bool isWatched = Register::list().isWatched(rtd); + Debugger::manager->setRegisterWatched(rtd, !isWatched); + break; + } + } + break; + } +} + +void Pic::BankWidget::write() +{ + const Pic::Data &data = static_cast(*Main::deviceData()); + const Pic::RegistersData &rdata = data.registersData(); + for (uint i=0; i<_registers.count(); i++) { + if ( sender()!=_registers[i].edit ) continue; + Register::TypeData rtd(_registers[i].address, rdata.nbChars()); + Debugger::manager->writeRegister(rtd, _registers[i].edit->value()); + break; + } +} + +void Pic::BankWidget::updateView() +{ + const Pic::Data &data = static_cast(*Main::deviceData()); + const Pic::RegistersData &rdata = data.registersData(); + bool active = ( Main::programmerState()==Programmer::Halted ); + const Coff::Object *coff = Debugger::manager->coff(); + uint nb = nbRegisters(); + for (uint i=0; i<_registers.count(); i++) { + uint address = _registers[i].address; + Device::RegisterProperties rp = rdata.properties(address); + QString label = rdata.label(address); + Register::TypeData rtd(address, rdata.nbChars()); + bool isWatched = Register::list().isWatched(rtd); + if (coff) { + QString name = coff->variableName(address); + if ( !name.isEmpty() ) label = "<" + name + ">"; + } + if (_registers[i].button) { + if ( ishow(); + _registers[i].button->setText(label); + if (isWatched) { + QFont f = _registers[i].button->font(); + f.setBold(true); + _registers[i].button->setFont(f); + } else _registers[i].button->unsetFont(); + _registers[i].button->popup()->setItemEnabled(ReadId, active && (rp & Device::Readable)); + _registers[i].button->popup()->setItemEnabled(EditId, active); + _registers[i].button->popup()->changeItem(WatchId, isWatched ? i18n("Stop Watching") : i18n("Watch")); + _registers[i].button->popup()->setItemEnabled(WatchId, rp & Device::Readable); + } else _registers[i].button->hide(); + } + if (_registers[i].label) { + if ( ishow(); + _registers[i].label->setText(label); + } else _registers[i].label->hide(); + } + if (_registers[i].edit) { + if ( ishow(); + _registers[i].edit->setEnabled(active); + BitValue value = Register::list().value(rtd); + if ( value!=Register::list().oldValue(rtd) ) _registers[i].edit->setColor(red); + else _registers[i].edit->unsetColor(); + _registers[i].edit->setValue(NumberBase::Hex, value, rdata.nbChars()); + } else _registers[i].edit->hide(); + } + } +} + +//----------------------------------------------------------------------------- +Pic::RegisterView::RegisterView(QWidget *parent) + : Register::View(parent, "pic_register_view"), + _readAllButton(0), _clearAllButton(0) +{ + QVBoxLayout *vbox = new QVBoxLayout(this, 10, 10); + QHBoxLayout *hbox = new QHBoxLayout(vbox); + + bool debugging = Main::programmerGroup().isDebugger(); + const Pic::Data &data = static_cast(*Main::deviceData()); + uint nb = data.registersData().nbBanks; + if ( debugging && nb!=0 ) { + QWidget *w = new QWidget(this); + hbox->addWidget(w); + QGridLayout *grid = new QGridLayout(w, 1, 1, 0, 10); + _readAllButton = new QPushButton(i18n("Read All"), w); + connect(_readAllButton, SIGNAL(clicked()), Debugger::manager, SLOT(readAllRegisters())); + grid->addWidget(_readAllButton, 0, 0); + _clearAllButton = new QPushButton(i18n("Clear all watching"), w); + connect(_clearAllButton, SIGNAL(clicked()), SLOT(stopWatchAllRegisters())); + grid->addWidget(_clearAllButton, 0, 1); + grid->setColStretch(2, 1); + } + + QHBoxLayout *hbox2 = 0; + if ( nb==0 ) { + QLabel *label = new QLabel(i18n("Registers information not available."), this); + vbox->addWidget(label); + } else { + hbox = new QHBoxLayout(vbox); + hbox2 = new QHBoxLayout(hbox); + hbox->addStretch(1); + if ( data.is18Family() ) { + nb = 2; + for (uint k=1; kshow(); + hbox2->addWidget(_banks[i]); + } + } + vbox->addStretch(1); +} + +void Pic::RegisterView::updateView() +{ + if (_readAllButton) _readAllButton->setEnabled(Main::programmerState()==Programmer::Halted); + for (uint i=0; i<_banks.count(); i++) if (_banks[i]) _banks[i]->updateView(); +} + +void Pic::RegisterView::stopWatchAllRegisters() +{ + Debugger::manager->stopWatchAll(); +} + +//---------------------------------------------------------------------------- +Pic::RegisterListViewItem::RegisterListViewItem(const Register::TypeData &data, KListViewItem *parent) + : Register::ListViewItem(data, parent) +{} + +uint Pic::RegisterListViewItem::nbCharsAddress() const +{ + const Pic::Data &data = static_cast(*Main::deviceData()); + return data.registersData().nbCharsAddress(); +} + +QString Pic::RegisterListViewItem::label() const +{ + if ( _data.type()!=Register::Regular ) return _data.name(); + const Coff::Object *coff = Debugger::manager->coff(); + if (coff) { + QString name = coff->variableName(_data.address()); + if ( !name.isEmpty() ) return "<" + name + ">"; + } + const Pic::Data &data = static_cast(*Main::deviceData()); + return data.registersData().label(_data.address()); +} diff --git a/src/devices/pic/gui/pic_register_view.h b/src/devices/pic/gui/pic_register_view.h new file mode 100644 index 0000000..f5b9d4b --- /dev/null +++ b/src/devices/pic/gui/pic_register_view.h @@ -0,0 +1,88 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PIC_REGISTER_VIEW_H +#define PIC_REGISTER_VIEW_H + +#include +class QPushButton; +class QCheckBox; +class QLabel; +class QComboBox; + +#include "devices/gui/register_view.h" +#include "devices/pic/base/pic.h" +#include "devices/pic/base/pic_register.h" +class PopupButton; +namespace Device { class RegisterHexWordEditor; } + +namespace Pic +{ +//----------------------------------------------------------------------------- +class BankWidget : public QFrame +{ +Q_OBJECT +public: + BankWidget(uint bank, QWidget *parent); + void updateView(); + +private slots: + void buttonActivated(int id); + void write(); + void bankChanged(); + +private: + enum Id { ReadId, EditId, WatchId }; + class Data { + public: + Data() : label(0), button(0), edit(0) {} + uint address; + QLabel *alabel, *label; + PopupButton *button; + Register::LineEdit *edit; + }; + uint _bindex; + QComboBox *_bankCombo; + QValueVector _registers; + + uint bank() const; + uint nbRegisters() const; + uint indexOffset() const; + void updateRegisterAddresses(); +}; + +//----------------------------------------------------------------------------- +class RegisterView : public Register::View +{ +Q_OBJECT +public: + RegisterView(QWidget *parent); + virtual void updateView(); + +private slots: + void stopWatchAllRegisters(); + +private: + QPushButton *_readAllButton, *_clearAllButton; + QValueVector _banks; +}; + +//----------------------------------------------------------------------------- +class RegisterListViewItem : public Register::ListViewItem +{ +public: + RegisterListViewItem(const Register::TypeData &data, KListViewItem *parent); + +private: + virtual uint nbCharsAddress() const; + virtual QString label() const; +}; + +} // namespace + +#endif diff --git a/src/devices/pic/pic.pro b/src/devices/pic/pic.pro new file mode 100644 index 0000000..cf3c06a --- /dev/null +++ b/src/devices/pic/pic.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = base xml pic xml_data prog diff --git a/src/devices/pic/pic/Makefile.am b/src/devices/pic/pic/Makefile.am new file mode 100644 index 0000000..e9deb80 --- /dev/null +++ b/src/devices/pic/pic/Makefile.am @@ -0,0 +1,5 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libpic.la +libpic_la_SOURCES = pic_memory.cpp pic_group.cpp diff --git a/src/devices/pic/pic/pic.pro b/src/devices/pic/pic/pic.pro new file mode 100644 index 0000000..8893c67 --- /dev/null +++ b/src/devices/pic/pic/pic.pro @@ -0,0 +1,6 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/lib.pro) + +TARGET = pic +HEADERS += pic_memory.h pic_group.h +SOURCES += pic_memory.cpp pic_group.cpp \ No newline at end of file diff --git a/src/devices/pic/pic/pic_group.cpp b/src/devices/pic/pic/pic_group.cpp new file mode 100644 index 0000000..639d2cf --- /dev/null +++ b/src/devices/pic/pic/pic_group.cpp @@ -0,0 +1,87 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "pic_group.h" + +#if !defined(NO_KDE) +# include +#endif + +#include "pic_memory.h" +#include "devices/pic/base/pic_register.h" + +Device::Memory *Pic::Group::createMemory(const Device::Data &data) const +{ + return new Memory(static_cast(data)); +} + +QString Pic::Group::informationHtml(const Device::Data &data) const +{ + const Pic::Data &pdata = static_cast(data); + // memory type + QString s = htmlTableRow(i18n("Memory Type"), data.memoryTechnology().label()); + if ( pdata.isPresent(MemoryRangeType::Code) ) { + uint nbw = pdata.nbWords(MemoryRangeType::Code); + QString tmp = i18n("%1 words").arg(formatNumber(nbw)); + tmp += i18n(" (%2 bits)").arg(pdata.nbBitsWord(MemoryRangeType::Code)); + s += htmlTableRow(MemoryRangeType(MemoryRangeType::Code).label(), tmp); + } + if ( pdata.isPresent(MemoryRangeType::Eeprom) ) { + uint nbw = pdata.nbWords(MemoryRangeType::Eeprom); + QString tmp = i18n("%1 bytes").arg(formatNumber(nbw)); + tmp += i18n(" (%2 bits)").arg(pdata.nbBitsWord(MemoryRangeType::Eeprom)); + if ( !(pdata.range(MemoryRangeType::Eeprom).properties & Programmable) ) tmp += i18n(" (not programmable)"); + s += htmlTableRow(MemoryRangeType(MemoryRangeType::Eeprom).label(), tmp); + } + + // io ports + const Pic::RegistersData &rdata = pdata.registersData(); + QString tmp; + if ( rdata.nbBanks!=0 ) { + uint nb = 0; + for (uint i=0; i"); + s += htmlTableRow(i18n("IO Ports"), tmp); + } + + // features + tmp = QString::null; + FOR_EACH(Feature, feature) { + if ( !pdata.hasFeature(feature) ) continue; + if ( !tmp.isEmpty() ) tmp += ", "; + tmp += feature.label(); + } + if ( !tmp.isEmpty() ) s += htmlTableRow(i18n("Features"), tmp); + + return s; +} + +#if !defined(NO_KDE) +QPixmap Pic::Group::memoryGraph(const Device::Data &data) const +{ + const Pic::Data &pdata = static_cast(data); + QValueList ranges; + FOR_EACH(Pic::MemoryRangeType, type) { + if ( type==Pic::MemoryRangeType::Eeprom || !pdata.isPresent(type) ) continue; + Device::MemoryGraphData data; + data.startAddress = pdata.range(type).start; + data.start = toHexLabel(pdata.range(type).start, pdata.nbCharsAddress()); + data.endAddress = pdata.range(type).end; + data.end = toHexLabel(pdata.range(type).end, pdata.nbCharsAddress()); + data.label = type.label(); + ranges.append(data); + } + return Device::memoryGraph(ranges); +} +#endif diff --git a/src/devices/pic/pic/pic_group.h b/src/devices/pic/pic/pic_group.h new file mode 100644 index 0000000..1b95e09 --- /dev/null +++ b/src/devices/pic/pic/pic_group.h @@ -0,0 +1,39 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PIC_GROUP_H +#define PIC_GROUP_H + +#include "common/global/global.h" +#include "devices/base/device_group.h" +#include "devices/pic/base/pic.h" + +namespace Pic +{ +extern const uint DATA_SIZE; +extern const char *DATA_STREAM; + +class Group : public Device::Group +{ +public: + virtual QString name() const { return "pic"; } + virtual QString label() const { return i18n("PIC"); } + virtual Device::Memory *createMemory(const Device::Data &data) const; + virtual QString informationHtml(const Device::Data &data) const; +#if !defined(NO_KDE) + virtual QPixmap memoryGraph(const Device::Data &data) const; +#endif + +private: + virtual uint dataSize() const { return DATA_SIZE; } + virtual const char *dataStream() const { return DATA_STREAM; } +}; + +} // namespace + +#endif diff --git a/src/devices/pic/pic/pic_memory.cpp b/src/devices/pic/pic/pic_memory.cpp new file mode 100644 index 0000000..cccb2f9 --- /dev/null +++ b/src/devices/pic/pic/pic_memory.cpp @@ -0,0 +1,560 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "pic_memory.h" + +#include + +#include "common/common/misc.h" + +Pic::Memory::Memory(const Data &data) + : Device::Memory(data) +{ + FOR_EACH(MemoryRangeType, i) _ranges[i].resize(device().nbWords(i)); + fill(BitValue()); +} + +void Pic::Memory::fill(MemoryRangeType type, BitValue value) +{ + for (uint i=0; i<_ranges[type].count(); i++) { + if ( type==MemoryRangeType::Config && !value.isInitialized() ) _ranges[type][i] = device().config()._words[i].bvalue; + else _ranges[type][i] = value; + } +} + +bool Pic::Memory::isClear(MemoryRangeType type) const +{ + for (uint i=0; i<_ranges[type].count(); i++) { + if ( type==MemoryRangeType::Config ) { + if ( _ranges[type][i]!=device().config()._words[i].bvalue ) return false; + } else if ( _ranges[type][i].isInitialized() ) return false; + } + return true; +} + +void Pic::Memory::fill(BitValue value) +{ + FOR_EACH(MemoryRangeType, k) fill(k, value); +} + +void Pic::Memory::copyFrom(MemoryRangeType type, const Memory &memory) +{ + Q_ASSERT( memory.device().name()==device().name() ); + for (uint i=0; i<_ranges[type].count(); i++) _ranges[type][i] = memory._ranges[type][i]; +} + +void Pic::Memory::copyFrom(const Device::Memory &memory) +{ + Q_ASSERT( memory.device().name()==device().name() ); + FOR_EACH(MemoryRangeType, i) copyFrom(i, static_cast(memory)); +} + +Device::Array Pic::Memory::arrayForWriting(MemoryRangeType type) const +{ + Device::Array data = _ranges[type]; + for (uint i=0; i=_ranges[type].size() ) qDebug("Memory::setWord: type=%s offset=%s size=%s value=%s", type.key(), toHexLabelAbs(offset).latin1(), toHexLabelAbs(_ranges[type].size()).latin1(), toHexLabelAbs(value).latin1()); + CRASH_ASSERT( offset<_ranges[type].size() ); + _ranges[type][offset] = value; +} + +void Pic::Memory::setArray(MemoryRangeType type, const Device::Array &data) +{ + CRASH_ASSERT( _ranges[type].size()==data.size() ); + _ranges[type] = data; +} + +QString Pic::Memory::findValue(const QString &maskName) const +{ + if ( maskName.isEmpty() ) return QString::null; + uint i; + const Config::Mask *mask = device().config().findMask(maskName, &i); + if ( mask==0 ) return QString::null; + BitValue v = word(MemoryRangeType::Config, i).maskWith(mask->value); + for (uint k=0; kvalues.count()); k++) + if ( v.isInside(mask->values[k].value) ) return mask->values[k].name; + Q_ASSERT(false); + return QString::null; +} + +AddressRange Pic::Memory::bootRange() const +{ + const Protection &protection = device().config().protection(); + // with boot size + QString value = findValue(protection.bootSizeMaskName()); + if ( !value.isEmpty() ) { + uint size = value.toUInt(); + if ( size==0 ) return AddressRange(); + Address start = device().range(MemoryRangeType::Code).start; + if ( device().architecture()==Architecture::P30F ) start = 0x100; + return AddressRange(start, 2 * size - 1); // instruction words + } + // only CPB + QString maskName = protection.bootMaskName(Protection::ProgramProtected); + const Config::Mask *mask = device().config().findMask(maskName); + for (uint k=0; kvalues.count()); k++) { + AddressRangeVector rv = protection.extractRanges(mask->values[k].name, MemoryRangeType::Code); + if ( !rv.isEmpty() ) return rv[0]; + } + Q_ASSERT(false); + return AddressRange(); +} + +AddressRange Pic::Memory::blockRange(uint i) const +{ + const Protection &protection = device().config().protection(); + Q_ASSERT( ivalues.count()); k++) { + AddressRangeVector rv = protection.extractRanges(mask->values[k].name, MemoryRangeType::Code); + if ( !rv.isEmpty() ) return AddressRange(previous.end + 1, rv[0].end); + } + Q_ASSERT(false); + return AddressRange(); +} + +AddressRange Pic::Memory::bootProtectedRange(Protection::Type ptype) const +{ + const Protection &protection = device().config().protection(); + QString maskName = protection.bootMaskName(ptype); + QString value = findValue(maskName); + if ( value.isEmpty() ) return AddressRange(); + if ( protection.family()!=Protection::CodeGuard ) { + if ( protection.extractRanges(value, MemoryRangeType::Code).isEmpty() ) return AddressRange(); + } else { + if ( value!=protection.securityValueName(ptype) ) return AddressRange(); + } + return bootRange(); +} + +AddressRange Pic::Memory::blockProtectedRange(Protection::Type ptype, uint i) const +{ + const Protection &protection = device().config().protection(); + QString maskName = protection.blockMaskName(ptype, i); + QString value = findValue(maskName); + if ( value.isEmpty() ) return AddressRange(); + if ( protection.family()!=Protection::CodeGuard ) { + if ( protection.extractRanges(value, MemoryRangeType::Code).isEmpty() ) return AddressRange(); + } else { + if ( value!=protection.securityValueName(ptype) ) return AddressRange(); + } + return blockRange(i); +} + +AddressRangeVector Pic::Memory::protectedRanges(Protection::Type ptype, MemoryRangeType type) const +{ + const Protection &protection = device().config().protection(); + AddressRangeVector rv; + if ( type==MemoryRangeType::Code ) { + if ( protection.hasBootBlock() ) rv.append(bootProtectedRange(ptype)); + if ( protection.nbBlocks()!=0 ) { + for (uint i=0; ivalue); + for (int k=mask->values.count()-1; k>=0; k--) { // important to get the highest value in case of identical values + if ( mask->values[k].name!=valueName ) continue; + setWord(MemoryRangeType::Config, i, v | mask->values[k].value); + return; + } + Q_ASSERT(false); +} + +void Pic::Memory::setProtection(bool on, const QString &maskName, Protection::Type ptype) +{ + const Config::Mask *mask = device().config().findMask(maskName, 0); + if( mask==0 ) return; + const Protection &protection = device().config().protection(); + QString valueName; + if ( ptype==Protection::StandardSecurity || ptype==Protection::HighSecurity ) + valueName = protection.securityValueName(ptype); + else { + for (int k=mask->values.count()-1; k>=0; k--) { + if ( (on && protection.isAllProtectedValueName(mask->values[k].name)) + || (!on && protection.isNoneProtectedValueName(mask->values[k].name)) ) valueName = mask->values[k].name; + } + } + setConfigValue(maskName, valueName); +} + +bool Pic::Memory::hasFlagOn(const QString &maskName, bool valueIfNotPresent) const +{ + const Config::Mask *mask = device().config().findMask(maskName, 0); + if ( mask==0 ) return valueIfNotPresent; + Q_ASSERT(mask); + Q_ASSERT( mask->values.count()==2 ); + return ( findValue(maskName)=="On" ); +} + +void Pic::Memory::setFlagOn(const QString &maskName, bool on) +{ + const Config::Mask *mask = device().config().findMask(maskName, 0); + Q_UNUSED(mask); + Q_ASSERT(mask); + Q_ASSERT( mask->values.count()==2 ); + setConfigValue(maskName, on ? "On" : "Off"); +} + +void Pic::Memory::checksumCheckFill() +{ + clear(); + switch (device().architecture().type()) { + case Architecture::P10X: + setWord(MemoryRangeType::Code, device().range(MemoryRangeType::Code).start.toUInt(), 0x723); + setWord(MemoryRangeType::Code, device().range(MemoryRangeType::Code).end.toUInt(), 0x723); + break; + case Architecture::P16X: + if ( device().name()=="16F72" || device().name()=="16F73" || device().name()=="16F74" || device().name()=="16F76" || device().name()=="16F77" + || device().name()=="16CR73" || device().name()=="16CR74" || device().name()=="16CR76" || device().name()=="16CR77" ) { + setWord(MemoryRangeType::Code, device().range(MemoryRangeType::Code).start.toUInt(), 0x05E6); + setWord(MemoryRangeType::Code, device().range(MemoryRangeType::Code).end.toUInt(), 0x05E6); + } else { + setWord(MemoryRangeType::Code, device().range(MemoryRangeType::Code).start.toUInt(), 0x25E6); + setWord(MemoryRangeType::Code, device().range(MemoryRangeType::Code).end.toUInt(), 0x25E6); + } + break; + case Architecture::P17C: + setWord(MemoryRangeType::Code, device().range(MemoryRangeType::Code).start.toUInt(), 0xC0DE); + setWord(MemoryRangeType::Code, device().range(MemoryRangeType::Code).end.toUInt(), 0xC0DE); + break; + case Architecture::P18C: + case Architecture::P18F: + case Architecture::P18J: + setWord(MemoryRangeType::Code, device().range(MemoryRangeType::Code).start.toUInt()/2, 0xAAFF); + setWord(MemoryRangeType::Code, device().range(MemoryRangeType::Code).end.toUInt()/2, 0xFFAA); + break; + case Architecture::P24F: + case Architecture::P24H: + case Architecture::P30F: + case Architecture::P33F: + setWord(MemoryRangeType::Code, device().range(MemoryRangeType::Code).start.toUInt(), 0xAAAAAA); + setWord(MemoryRangeType::Code, device().range(MemoryRangeType::Code).end.toUInt(), 0xAAAAAA); + break; + case Architecture::Nb_Types: Q_ASSERT(false); break; + } +} + +BitValue Pic::Memory::checksum() const +{ + // code + BitValue mask = device().mask(MemoryRangeType::Code); + AddressRangeVector rv = protectedRanges(Protection::ProgramProtected, MemoryRangeType::Code); + bool isProtected = !rv.isEmpty(); + uint inc = device().addressIncrement(MemoryRangeType::Code); + //uint nbChars = device().nbCharsWord(MemoryRangeType::Code); + //qDebug("protected: %i nb: %s (%s)", isProtected, toHexLabelAbs(inc*device().nbWords(MemoryRangeType::Code)).latin1(), toHexLabel(mask, nbChars).latin1()); + //for (uint i=0; i &checksums = device().checksums(); + if ( checksums.contains(valueName) ) { // #### REMOVE ME !! + algorithm = checksums[valueName].algorithm; + cs = checksums[valueName].constant; + } + } + //qDebug("constant: %s", toHexLabelAbs(cs).data()); + //qDebug("algo: %s", Checksum::ALGORITHM_DATA[algorithm].name); + for (uint i=0; i &inRange) +{ + if ( !device().isWritable(type) ) return; + uint nbBytes = device().architecture().data().nbBytesWord; + bool packed = device().architecture().data().packed; + uint offset = device().range(type).hexFileOffset; + if ( offset==0 ) offset = device().range(type).start.toUInt(); + BitValue mask = device().mask(type); + uint wNbBytes = nbBytes; + if ( packed && type!=Pic::MemoryRangeType::Code ) { + offset /= 2; + wNbBytes /= 2; + } + uint byte = 0; + uint wOffset = 0; + uint wByte = 0; + //qDebug("%s wnb=%i snb=%i", MEMORY_RANGE_TYPE_DATA[type].label, wNbBytes, nbBytes); + for (uint k=0; k &inRange) +{ + FOR_EACH(MemoryRangeType, i) fromHexBuffer(i, hb, result, warnings, inRange); +} diff --git a/src/devices/pic/pic/pic_memory.h b/src/devices/pic/pic/pic_memory.h new file mode 100644 index 0000000..f7c98ba --- /dev/null +++ b/src/devices/pic/pic/pic_memory.h @@ -0,0 +1,80 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PIC_MEMORY_H +#define PIC_MEMORY_H + +#include "common/global/global.h" +#include "devices/base/generic_memory.h" +#include "devices/base/hex_buffer.h" +#include "devices/pic/base/pic_config.h" + +namespace Pic +{ + +class Memory : public Device::Memory +{ +public: + Memory(const Data &data); + const Data &device() const { return static_cast(_device); } + virtual void fill(BitValue value); + void checksumCheckFill(); // a special memory fill for checksum check (cf datasheets) + virtual void fill(MemoryRangeType type, BitValue value); + virtual void clear() { Device::Memory::clear(); } + bool isClear(MemoryRangeType type) const; + void clear(MemoryRangeType type) { fill(type, BitValue()); } + Device::Array arrayForWriting(MemoryRangeType type) const; + BitValue word(MemoryRangeType type, uint offset) const; + BitValue normalizeWord(MemoryRangeType type, uint offset, BitValue value) const; + BitValue normalizedWord(MemoryRangeType type, uint offset) const; + void setWord(MemoryRangeType type, uint offset, BitValue value); + void setArray(MemoryRangeType type, const Device::Array &array); + + AddressRange bootRange() const; + AddressRange blockRange(uint i) const; + bool isBootProtected(Protection::Type ptype) const { return !bootProtectedRange(ptype).isEmpty(); } + bool isBlockProtected(Protection::Type ptype, uint i) const { return !blockProtectedRange(ptype, i).isEmpty(); } + bool isProtected(Protection::Type ptype, MemoryRangeType type) const { return !protectedRanges(ptype, type).isEmpty(); } + AddressRangeVector protectedRanges(Protection::Type ptype, MemoryRangeType type) const; + void setConfigValue(const QString &maskName, const QString &valueName); + bool hasDebugOn() const { return hasFlagOn("DEBUG", false); } + void setDebugOn(bool on) { setFlagOn("DEBUG", on); } + bool hasWatchdogTimerOn() const { return hasFlagOn("WDT", false); } + void setWatchdogTimerOn(bool on) { return setFlagOn("WDT", on); } + void setBootProtection(bool on, Protection::Type ptype); + void setBlockProtection(bool on, Protection::Type ptype, uint block); + void setProtection(bool on, Protection::Type ptype, MemoryRangeType type); + + virtual BitValue checksum() const; + BitValue unprotectedChecksum() const; + void setUserIdToUnprotectedChecksum(); + + virtual HexBuffer toHexBuffer() const; + virtual void copyFrom(const Device::Memory &memory); + void copyFrom(MemoryRangeType type, const Memory &memory); + void fromHexBuffer(MemoryRangeType type, const HexBuffer &hb, WarningTypes &warningTypes, + QStringList &warnings, QMap &inRange); + +private: + QMap _ranges; + + void toHexBuffer(MemoryRangeType type, HexBuffer &hb) const; + virtual void savePartial(QTextStream &stream, HexBuffer::Format format) const; + virtual void fromHexBuffer(const HexBuffer &hb, WarningTypes &warningTypes, + QStringList &warnings, QMap &inRange); + QString findValue(const QString &maskName) const; + bool hasFlagOn(const QString &maskName, bool valueIfNotPresent) const; + void setFlagOn(const QString &maskName, bool on); + void setProtection(bool on, const QString &maskName, Protection::Type ptype); + AddressRange bootProtectedRange(Protection::Type ptype) const; + AddressRange blockProtectedRange(Protection::Type ptype, uint block) const; +}; + +} // namespace + +#endif diff --git a/src/devices/pic/prog/Makefile.am b/src/devices/pic/prog/Makefile.am new file mode 100644 index 0000000..055d2cd --- /dev/null +++ b/src/devices/pic/prog/Makefile.am @@ -0,0 +1,5 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libpicprog.la +libpicprog_la_SOURCES = pic_prog.cpp pic_prog_specific.cpp pic_debug.cpp diff --git a/src/devices/pic/prog/pic_debug.cpp b/src/devices/pic/prog/pic_debug.cpp new file mode 100644 index 0000000..443bb10 --- /dev/null +++ b/src/devices/pic/prog/pic_debug.cpp @@ -0,0 +1,118 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "pic_debug.h" + +#include "common/common/misc.h" +#include "devices/pic/base/pic_register.h" +#include "progs/manager/debug_manager.h" + +//---------------------------------------------------------------------------- +Register::TypeData Debugger::PicBase::registerTypeData(const QString &name) const +{ + const Pic::RegistersData &rdata = device()->registersData(); + Q_ASSERT(rdata.sfrs.contains(name)); + return Register::TypeData(rdata.sfrs[name].address, rdata.nbChars()); +} + +bool Debugger::PicBase::updatePortStatus(uint index, QMap &bits) +{ + const Pic::RegistersData &rdata = device()->registersData(); + BitValue tris; + if ( rdata.hasTris(index) ) { + tris = Register::list().value(registerTypeData(rdata.trisName(index))); + Q_ASSERT( tris.isInitialized() ); + } + BitValue port = Register::list().value(registerTypeData(rdata.portName(index))); + Q_ASSERT( port.isInitialized() ); + BitValue latch; + if ( rdata.hasLatch(index) ) { + latch = Register::list().value(registerTypeData(rdata.latchName(index))); + Q_ASSERT( latch.isInitialized() ); + } + for (uint i=0; i(_base); +} +const Debugger::PicBase &Debugger::PicSpecific::base() const +{ + return static_cast(_base); +} + +bool Debugger::PicSpecific::updateStatus() +{ + if ( !Debugger::manager->readRegister(base().pcTypeData()) ) return false; + if ( !Debugger::manager->readRegister(base().registerTypeData("STATUS")) ) return false; + if ( !Debugger::manager->readRegister(wregTypeData()) ) return false; + return true; +} + +//---------------------------------------------------------------------------- +Register::TypeData Debugger::P16FSpecific::wregTypeData() const +{ + return Register::TypeData("WREG", device().registersData().nbChars()); +} + +QString Debugger::P16FSpecific::statusString() const +{ + const Pic::RegistersData &rdata = device().registersData(); + BitValue status = Register::list().value(base().registerTypeData("STATUS")); + uint bank = (status.bit(5) ? 1 : 0) + (status.bit(6) ? 2 : 0); + BitValue wreg = Register::list().value(wregTypeData()); + return QString("W:%1 %2 %3 %4 PC:%5 Bank:%6") + .arg(toHexLabel(wreg, rdata.nbChars())).arg(status.bit(2) ? "Z" : "z") + .arg(status.bit(1) ? "DC" : "dc").arg(status.bit(0) ? "C" : "c") + .arg(toHexLabel(_base.pc(), device().nbCharsAddress())).arg(bank); +} + +//---------------------------------------------------------------------------- +bool Debugger::P18FSpecific::updateStatus() +{ + if ( !PicSpecific::updateStatus() ) return false; + if ( !Debugger::manager->readRegister(base().registerTypeData("BSR")) ) return false; + return true; +} + +Register::TypeData Debugger::P18FSpecific::wregTypeData() const +{ + return base().registerTypeData("WREG"); +} + +QString Debugger::P18FSpecific::statusString() const +{ + const Pic::RegistersData &rdata = device().registersData(); + BitValue status = Register::list().value(base().registerTypeData("STATUS")); + BitValue bsr = Register::list().value(base().registerTypeData("BSR")); + BitValue wreg = Register::list().value(wregTypeData()); + return QString("W:%1 %2 %3 %4 %5 %6 PC:%7 Bank:%8") + .arg(toHexLabel(wreg, rdata.nbChars())).arg(status.bit(4) ? "N" : "n") + .arg(status.bit(3) ? "OV" : "ov").arg(status.bit(2) ? "Z" : "z") + .arg(status.bit(1) ? "DC" : "dc").arg(status.bit(0) ? "C" : "c") + .arg(toHexLabel(base().pc(), device().nbCharsAddress())).arg(toLabel(bsr)); +} diff --git a/src/devices/pic/prog/pic_debug.h b/src/devices/pic/prog/pic_debug.h new file mode 100644 index 0000000..dfb8af6 --- /dev/null +++ b/src/devices/pic/prog/pic_debug.h @@ -0,0 +1,65 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PIC_DEBUG_H +#define PIC_DEBUG_H + +#include "progs/base/generic_debug.h" +#include "pic_prog.h" +#include "devices/base/register.h" + +namespace Debugger +{ +class PicBase; + +//---------------------------------------------------------------------------- +class PicSpecific : public DeviceSpecific +{ +public: + PicSpecific(Debugger::Base &base) : DeviceSpecific(base) {} + const Pic::Data &device() const { return static_cast(*_base.device()); } + PicBase &base(); + const PicBase &base() const; + virtual bool updateStatus(); + virtual Register::TypeData wregTypeData() const = 0; +}; + +//---------------------------------------------------------------------------- +class P16FSpecific : public PicSpecific +{ +public: + P16FSpecific(Debugger::Base &base) : PicSpecific(base) {} + virtual QString statusString() const; + virtual Register::TypeData wregTypeData() const; +}; + +//---------------------------------------------------------------------------- +class P18FSpecific : public PicSpecific +{ +public: + P18FSpecific(Debugger::Base &base) : PicSpecific(base) {} + virtual QString statusString() const; + virtual bool updateStatus(); + virtual Register::TypeData wregTypeData() const; +}; + +//---------------------------------------------------------------------------- +class PicBase : public Debugger::Base +{ +public: + PicBase(Programmer::PicBase &base) : Debugger::Base(base) {} + PicSpecific *deviceSpecific() { return static_cast(_deviceSpecific); } + const PicSpecific *deviceSpecific() const { return static_cast(_deviceSpecific); } + const Pic::Data *device() const { return static_cast(Debugger::Base::device()); } + Register::TypeData registerTypeData(const QString &name) const; + virtual bool updatePortStatus(uint index, QMap &bits); +}; + +} // namespace + +#endif diff --git a/src/devices/pic/prog/pic_prog.cpp b/src/devices/pic/prog/pic_prog.cpp new file mode 100644 index 0000000..bc7dcd1 --- /dev/null +++ b/src/devices/pic/prog/pic_prog.cpp @@ -0,0 +1,751 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "pic_prog.h" + +#include "common/global/global.h" +#include "devices/list/device_list.h" +#include "progs/base/prog_config.h" +#include "progs/base/prog_group.h" +#include "pic_debug.h" + +//----------------------------------------------------------------------------- +bool Programmer::PicGroup::canReadVoltages() const +{ + for (uint i=0; i(base.device()); + if ( data==0 ) return 0; + switch (data->architecture().type()) { + case Pic::Architecture::P10X: + case Pic::Architecture::P16X: return new ::Debugger::P16FSpecific(base); + case Pic::Architecture::P18C: + case Pic::Architecture::P18F: + case Pic::Architecture::P18J: return new ::Debugger::P18FSpecific(base); + case Pic::Architecture::P24F: + case Pic::Architecture::P24H: + case Pic::Architecture::P30F: + case Pic::Architecture::P33F: + case Pic::Architecture::P17C: + case Pic::Architecture::Nb_Types: break; + } + Q_ASSERT(false); + return 0; +} + +//----------------------------------------------------------------------------- +Programmer::PicBase::PicBase(const Group &group, const Pic::Data *data, const char *name) + : Base(group, data, name), _deviceMemory(0), _hasProtectedCode(false), _hasProtectedEeprom(false) +{ + if (data) _deviceMemory = new Pic::Memory(*data); +} + +Programmer::PicBase::~PicBase() +{ + delete _deviceMemory; +} + +void Programmer::PicBase::clear() +{ + ::Programmer::Base::clear(); + for (uint i=0; i(range); + switch (task.type()) { + case Task::Erase: return 1; + case Task::Read: + case Task::Verify: + case Task::BlankCheck: { + uint nb = 0; + FOR_EACH(Pic::MemoryRangeType, type) { + if ( type!=Pic::MemoryRangeType::Code && type!=Pic::MemoryRangeType::Eeprom ) continue; + if ( !device()->isReadable(type) || !specific()->canReadRange(type) ) continue; + if ( !prange->all() && prange->_type!=type ) continue; + nb += device()->nbWords(type); + } + return QMAX(nb, uint(1)); + } + case Task::Write: { + uint nb = 0; + FOR_EACH(Pic::MemoryRangeType, type) { + if ( type!=Pic::MemoryRangeType::Code && type!=Pic::MemoryRangeType::Eeprom ) continue; + if ( !device()->isWritable(type) || !specific()->canWriteRange(type) ) continue; + if ( !prange->all() && prange->_type!=type ) continue; + nb += device()->nbWords(type); + if ( readConfigEntry(Config::VerifyAfterProgram).toBool() ) nb += device()->nbWords(type); + } + return QMAX(nb, uint(1)); + } + case Task::Nb_Types: break; + } + Q_ASSERT(false); + return 0; +} + +bool Programmer::PicBase::readVoltages() +{ + if ( !hardware()->readVoltages(_voltages) ) return false; + bool ok = true; + for (uint i=0; isetTargetReset(Pic::ResetHeld) ) return false; + } + Pic::TargetMode mode; + if ( !getTargetMode(mode) ) return false; + if ( mode!=Pic::TargetInProgramming ) { + log(Log::LineType::Error, i18n("Device not in programming")); + return false; + } + return true; +} + +bool Programmer::PicBase::initProgramming(Task) +{ +/* + if ( vpp()!=UNKNOWN_VOLTAGE ) { + const Pic::VoltageData &tvpp = device()->voltage(Pic::Vpp); + if ( vpp()tvpp.max ) { + QString s = i18n("Vpp (%1 V) is higher than the maximum voltage (%2 V). You may damage the device.") + .arg(vpp()).arg(tvpp.max); + log(Log::LineType::Warning, s); + if ( !askContinue(s) ) { + logUserAbort(); + return false; + } + } + } + if ( vdd()!=UNKNOWN_VOLTAGE ) { + Q_ASSERT( type!=Pic::Vpp ); + const Pic::VoltageData &tvdd = device()->voltage(type); + if ( vdd()voltage(Pic::VddWrite).min!=tvdd.min ) + log(Log::LineType::Warning, i18n("Vdd (%1 V) is too low for high-voltage programming\n(piklab only supports high-voltage programming at the moment).\nMinimum required is %2 V.") + .arg(vdd()).arg(tvdd.min)); + else if ( type==Pic::VddRead && device()->voltage(Pic::VddWrite).min!=tvdd.min ) + log(Log::LineType::Warning, i18n("Vdd (%1 V) is too low for reading\nMinimum required is %2 V.") + .arg(vdd()).arg(tvdd.min)); + else log(Log::LineType::Warning, i18n("Vdd (%1 V) is too low for programming\nMinimum required is %2 V.") + .arg(vdd()).arg(tvdd.min)); + } else if ( vdd()>tvdd.max ) { + QString s = i18n("Vdd (%1 V) is higher than the maximum voltage (%2 V). You may damage the device.") + .arg(vdd()).arg(tvdd.max); + log(Log::LineType::Warning, s); + if ( !askContinue(s) ) { + logUserAbort(); + return false; + } + } + } +*/ + if ( specific()->canReadRange(Pic::MemoryRangeType::Config) ) { + // read config + Device::Array data; + if ( !specific()->read(Pic::MemoryRangeType::Config, data, 0) ) return false; + _deviceMemory->setArray(Pic::MemoryRangeType::Config, data); + _hasProtectedCode = _deviceMemory->isProtected(Pic::Protection::ProgramProtected, Pic::MemoryRangeType::Code); + _hasProtectedEeprom = _deviceMemory->isProtected(Pic::Protection::ProgramProtected, Pic::MemoryRangeType::Eeprom); + log(Log::DebugLevel::Normal, QString(" protected: code=%1 data=%2") + .arg(_hasProtectedCode ? "true" : "false").arg(_hasProtectedEeprom ? "true" : "false")); + // read calibration + if ( !readCalibration() ) return false; + } + + return initProgramming(); +} + +bool Programmer::PicBase::preserveCode() +{ + if ( _hasProtectedCode && !askContinue(i18n("All or part of code memory is protected so it cannot be preserved. Continue anyway?")) ) + return false; + return readRange(Pic::MemoryRangeType::Code, _deviceMemory, 0); +} + +bool Programmer::PicBase::preserveEeprom() +{ + if ( _hasProtectedEeprom && !askContinue(i18n("All or part of data EEPROM is protected so it cannot be preserved. Continue anyway?")) ) + return false; + return readRange(Pic::MemoryRangeType::Eeprom, _deviceMemory, 0); +} + +bool Programmer::PicBase::internalRun() +{ + _state = ::Programmer::Running; + return hardware()->setTargetReset(Pic::ResetReleased); +} + +bool Programmer::PicBase::internalStop() +{ + _state = ::Programmer::Stopped; + return hardware()->setTargetReset(Pic::ResetHeld); +} + +bool Programmer::PicBase::getTargetMode(Pic::TargetMode &mode) +{ + return hardware()->getTargetMode(mode); +} + +bool Programmer::PicBase::initProgramming() +{ + _state = ::Programmer::Stopped; + return hardware()->setTargetReset(Pic::ResetHeld); +} + +//----------------------------------------------------------------------------- +BitValue Programmer::PicBase::readDeviceId() +{ + Device::Array data; + if ( !specific()->read(Pic::MemoryRangeType::DeviceId, data, 0) ) return 0; + Q_ASSERT( data.count()!=0 ); + BitValue id = 0x0; + switch (device()->architecture().type()) { + case Pic::Architecture::P10X: + case Pic::Architecture::P16X: + case Pic::Architecture::P17C: id = data[0]; break; + case Pic::Architecture::P18C: + case Pic::Architecture::P18F: + case Pic::Architecture::P18J: id = data[0] | (data[1] << 8); break; + case Pic::Architecture::P24F: + case Pic::Architecture::P24H: + case Pic::Architecture::P30F: + case Pic::Architecture::P33F: id = data[1] | (data[0] << 16); break; + case Pic::Architecture::Nb_Types: Q_ASSERT(false); break; + } + return id; +} + +bool Programmer::PicBase::verifyDeviceId() +{ + if ( !specific()->canReadRange(Pic::MemoryRangeType::DeviceId ) ) return true; + if ( !device()->isReadable(Pic::MemoryRangeType::DeviceId) ) { + log(Log::LineType::Information, i18n("Device not autodetectable: continuing with the specified device name \"%1\"...").arg(device()->name())); + return true; + } + BitValue rawId = readDeviceId(); + if ( hasError() ) return false; + uint nbChars = device()->nbWords(Pic::MemoryRangeType::DeviceId) * device()->nbCharsWord(Pic::MemoryRangeType::DeviceId); + if ( rawId==0x0 || rawId==device()->mask(Pic::MemoryRangeType::DeviceId) ) { + log(Log::LineType::Error, i18n("Missing or incorrect device (Read id is %1).").arg(toHexLabel(rawId, nbChars))); + return false; + } + QMap ids; + QValueVector names = group().supportedDevices(); + for (uint k=0; k(group().deviceData(names[k]).data); + if ( data->architecture()!=device()->architecture() ) continue; + Device::IdData idata; + if ( data->matchId(rawId, idata) ) ids[names[k]] = idata; + } + QString message; + if ( ids.count()!=0 ) { + log(Log::LineType::Information, i18n("Read id: %1").arg(device()->idNames(ids).join("; "))); + if ( ids.contains(device()->name()) ) return true; + message = i18n("Read id does not match the specified device name \"%1\".").arg(device()->name()); + } else { + log(Log::LineType::Warning, i18n(" Unknown or incorrect device (Read id is %1).").arg(toHexLabel(rawId, nbChars))); + message = i18n("Unknown device."); + } + if ( !askContinue(message) ) { + logUserAbort(); + return false; + } + log(Log::LineType::Information, i18n("Continue with the specified device name: \"%1\"...").arg(device()->name())); + return true; +} + +//----------------------------------------------------------------------------- +QString Programmer::PicBase::prettyCalibration(const Device::Array &data) const +{ + QString s; + for (uint i=0; inbCharsWord(Pic::MemoryRangeType::Cal)); + } + return s; +} + +bool Programmer::PicBase::readCalibration() +{ + if ( device()->isReadable(Pic::MemoryRangeType::Cal) ) { + if ( !specific()->canReadRange(Pic::MemoryRangeType::Cal) ) { + log(Log::LineType::Warning, i18n("Osccal cannot be read by the selected programmer")); + return true; + } + Device::Array data; + if ( !specific()->read(Pic::MemoryRangeType::Cal, data, 0) ) return false; + _deviceMemory->setArray(Pic::MemoryRangeType::Cal, data); + log(Log::DebugLevel::Normal, QString(" Read osccal: %1").arg(prettyCalibration(data))); + QString message; + if ( !device()->checkCalibration(data, &message) ) log(Log::LineType::Warning, " " + message); + if ( device()->isReadable(Pic::MemoryRangeType::CalBackup) ) { + if ( !specific()->canReadRange(Pic::MemoryRangeType::CalBackup) ) { + log(Log::LineType::Warning, i18n("Osccal backup cannot be read by the selected programmer")); + return true; + } + if ( !specific()->read(Pic::MemoryRangeType::CalBackup, data, 0) ) return false; + _deviceMemory->setArray(Pic::MemoryRangeType::CalBackup, data); + log(Log::DebugLevel::Normal, QString(" Read osccal backup: %1").arg(prettyCalibration(data))); + if ( !device()->checkCalibration(data, &message) ) log(Log::LineType::Warning, " " + message); + } + } + return true; +} + +bool Programmer::PicBase::restoreCalibration() +{ + if ( !specific()->canReadRange(Pic::MemoryRangeType::Cal) || !specific()->canWriteRange(Pic::MemoryRangeType::Cal) ) return true; + if ( !device()->isWritable(Pic::MemoryRangeType::Cal) ) return true; + Device::Array data = _deviceMemory->arrayForWriting(Pic::MemoryRangeType::Cal); + Device::Array bdata = _deviceMemory->arrayForWriting(Pic::MemoryRangeType::CalBackup); + if ( device()->isReadable(Pic::MemoryRangeType::CalBackup) && specific()->canReadRange(Pic::MemoryRangeType::CalBackup) ) { + if ( !device()->checkCalibration(data) && device()->checkCalibration(bdata) ) { + log(Log::LineType::Information, i18n(" Replace invalid osccal with backup value.")); + data = bdata; + } + } + Device::Array cdata; + if ( !specific()->read(Pic::MemoryRangeType::Cal, cdata, 0) ) return false; + if ( cdata==data ) { + log(Log::LineType::Information, i18n(" Osccal is unchanged.")); + return true; + } + if ( !programRange(Pic::MemoryRangeType::Cal, data) ) return false; + if ( !specific()->read(Pic::MemoryRangeType::Cal, cdata, 0) ) return false; + if ( cdata==data ) log(Log::LineType::Information, i18n(" Osccal has been preserved.")); + + if ( !device()->isWritable(Pic::MemoryRangeType::CalBackup) || !device()->checkCalibration(bdata) ) return true; + if ( !specific()->read(Pic::MemoryRangeType::CalBackup, cdata, 0) ) return false; + if ( cdata.count()==0 ) { + log(Log::LineType::Warning, i18n("Osccal backup cannot be read by selected programmer")); + return true; + } + if ( cdata==bdata ) { + log(Log::LineType::Information, i18n(" Osccal backup is unchanged.")); + return true; + } + if ( !programRange(Pic::MemoryRangeType::CalBackup, bdata) ) return false; + if ( !specific()->read(Pic::MemoryRangeType::CalBackup, cdata, 0) ) return false; + if ( cdata==bdata ) log(Log::LineType::Information, i18n(" Osccal backup has been preserved.")); + return true; +} + +bool Programmer::PicBase::restoreBandGapBits() +{ + if ( !specific()->canReadRange(Pic::MemoryRangeType::Config) ) return true; + bool hasProtectedBits = false; + for (uint i=0; inbWords(Pic::MemoryRangeType::Config); i++) + if ( device()->config()._words[i].pmask!=0 ) hasProtectedBits = true; + if ( !hasProtectedBits ) return true; + Device::Array cdata; + if ( !specific()->read(Pic::MemoryRangeType::Config, cdata, 0) ) return false; + Device::Array data = _deviceMemory->arrayForWriting(Pic::MemoryRangeType::Config); + for (uint i=0; iconfig()._words[i].pmask; + if ( pmask==0 ) continue; + cdata[i] = cdata[i].clearMaskBits(pmask); + cdata[i] |= data[i].maskWith(pmask); + } + if ( !specific()->canWriteRange(Pic::MemoryRangeType::Config) ) { + log(Log::LineType::Warning, i18n("Could not restore band gap bits because programmer does not support writing config bits.")); + return true; + } + log(Log::DebugLevel::Normal, QString(" Write config with band gap bits: %2").arg(toHexLabel(cdata[0], device()->nbCharsWord(Pic::MemoryRangeType::Config)))); + if ( !programRange(Pic::MemoryRangeType::Config, cdata) ) return false; + if ( !specific()->read(Pic::MemoryRangeType::Config, data, 0) ) return false; + if ( data==cdata ) log(Log::LineType::Information, i18n(" Band gap bits have been preserved.")); + return true; +} + +bool Programmer::PicBase::eraseAll() +{ + if ( !specific()->canEraseAll() ) { + log(Log::LineType::SoftError, i18n("The selected programmer does not support erasing the whole device.")); + return false; + } + if ( !specific()->erase(_hasProtectedCode || _hasProtectedEeprom) ) return false; + if ( !restoreCalibration() ) return false; + return true; +} + +bool Programmer::PicBase::checkErase() +{ + if ( device()->memoryTechnology()==Device::MemoryTechnology::Rom || device()->memoryTechnology()==Device::MemoryTechnology::Romless + || device()->memoryTechnology()==Device::MemoryTechnology::Eprom ) { + log(Log::LineType::SoftError, i18n("Cannot erase ROM or EPROM device.")); + return false; + } + return true; +} + +bool Programmer::PicBase::internalErase(const Device::MemoryRange &range) +{ + if ( !initProgramming(Task::Erase) ) return false; + bool ok = true; + if ( range.all() ) ok = eraseAll(); + else ok = eraseRange(static_cast(range)._type); + if ( !restoreBandGapBits() ) return false; + return ok; +} + +bool Programmer::PicBase::eraseSingle(Pic::MemoryRangeType type) +{ + return erase(Pic::MemoryRange(type)); +} + +bool Programmer::PicBase::eraseRange(Pic::MemoryRangeType type) +{ + bool ok = internalEraseRange(type); + if ( !restoreCalibration() ) return false; + if ( ok && readConfigEntry(Config::BlankCheckAfterErase).toBool() ) { + Pic::Memory memory(*device()); + VerifyData vdata(BlankCheckVerify, memory); + return readRange(type, 0, &vdata); + } + return ok; +} + +bool Programmer::PicBase::internalEraseRange(Pic::MemoryRangeType type) +{ + if ( !specific()->canEraseRange(type) && !specific()->canEraseAll() ) { + log(Log::LineType::SoftError, i18n("The selected programmer does not support erasing neither the specified range nor the whole device.")); + return false; + } + if ( type==Pic::MemoryRangeType::Code && _hasProtectedCode ) { + log(Log::LineType::SoftError, i18n("Cannot erase protected code memory. Consider erasing the whole chip.")); + return false; + } + if ( type==Pic::MemoryRangeType::Eeprom && _hasProtectedEeprom ) { + log(Log::LineType::SoftError, i18n("Cannot erase protected data EEPROM. Consider erasing the whole chip.")); + return false; + } + if ( specific()->canEraseRange(type) ) return specific()->eraseRange(type); + bool softErase = true; + if ( type!=Pic::MemoryRangeType::Code && (!specific()->canReadRange(Pic::MemoryRangeType::Code) + || !specific()->canWriteRange(Pic::MemoryRangeType::Code)) ) softErase = false; + if ( type!=Pic::MemoryRangeType::Eeprom && (!specific()->canReadRange(Pic::MemoryRangeType::Eeprom) + || !specific()->canWriteRange(Pic::MemoryRangeType::Eeprom)) ) softErase = false; + if ( type!=Pic::MemoryRangeType::Config && (!specific()->canReadRange(Pic::MemoryRangeType::Config) + || !specific()->canWriteRange(Pic::MemoryRangeType::Config)) ) softErase = false; + if ( type!=Pic::MemoryRangeType::UserId && (!specific()->canReadRange(Pic::MemoryRangeType::UserId) + || !specific()->canWriteRange(Pic::MemoryRangeType::UserId)) ) softErase = false; + if ( !softErase ) { + log(Log::LineType::SoftError, i18n("Cannot erase specified range because of programmer limitations.")); + return false; + } + if ( !askContinue(i18n("%1: Erasing this range only is not supported with this programmer. This will erase the whole chip and restore the other memory ranges.").arg(type.label())) ) { + logUserAbort(); + return false; + } + if ( type!=Pic::MemoryRangeType::Code && !preserveCode() ) return false; + if ( type!=Pic::MemoryRangeType::Eeprom && !preserveEeprom() ) return false; + if ( type!=Pic::MemoryRangeType::UserId && !readRange(Pic::MemoryRangeType::UserId, _deviceMemory, 0) ) return false; + specific()->erase(_hasProtectedCode || _hasProtectedEeprom); + if ( type!=Pic::MemoryRangeType::Code && !programAndVerifyRange(Pic::MemoryRangeType::Code, *_deviceMemory) ) return false; + if ( type!=Pic::MemoryRangeType::Eeprom && !programAndVerifyRange(Pic::MemoryRangeType::Eeprom, *_deviceMemory) ) return false; + if ( type!=Pic::MemoryRangeType::UserId && !programAndVerifyRange(Pic::MemoryRangeType::UserId, *_deviceMemory) ) return false; + if ( !programAndVerifyRange(Pic::MemoryRangeType::Config, *_deviceMemory) ) return false; + return true; +} + +//----------------------------------------------------------------------------- +bool Programmer::PicBase::readSingle(Pic::MemoryRangeType type, Pic::Memory &memory) +{ + if ( !specific()->canReadRange(type) ) { + log(Log::LineType::SoftError, i18n("The selected programmer cannot read the specified memory range.")); + return false; + } + Pic::Memory tmp(*device()); + if ( !read(tmp, Pic::MemoryRange(type)) ) return false; + memory.copyFrom(type, tmp); + if ( type==Pic::MemoryRangeType::Cal ) memory.copyFrom(Pic::MemoryRangeType::CalBackup, tmp); + return true; +} + +bool Programmer::PicBase::readRange(Pic::MemoryRangeType type, Pic::Memory *memory, const VerifyData *vd) +{ + if ( !device()->isReadable(type) ) return true; + if ( !specific()->canReadRange(type) ) { + log(Log::LineType::Information, i18n("The selected programmer cannot read %1: operation skipped.").arg(type.label())); + return true; + } + VerifyData *vdata = (vd ? new VerifyData(vd->actions, vd->memory) : 0); + if (vdata) { + log(Log::LineType::Information, i18n(" Verify memory: %1").arg(type.label())); + if ( !(vdata->actions & IgnoreProtectedVerify) ) { + vdata->protectedRanges = static_cast(vdata->memory).protectedRanges(Pic::Protection::ProgramProtected, type); + if ( !vdata->protectedRanges.isEmpty() ) log(Log::LineType::Warning, i18n(" Part of device memory is protected (in %1) and cannot be verified.") + .arg(type.label())); + } else vdata->protectedRanges.clear(); + } else { + log(Log::LineType::Information, i18n(" Read memory: %1").arg(type.label())); + CRASH_ASSERT(memory); + } + Device::Array data; + bool ok = specific()->read(type, data, vdata); + delete vdata; + if (!ok) return false; + if (memory) memory->setArray(type, data); + return true; +} + +bool Programmer::PicBase::checkRead() +{ + if ( device()->memoryTechnology()==Device::MemoryTechnology::Romless ) { + log(Log::LineType::SoftError, i18n("Cannot read ROMless device.")); + return false; + } + return true; +} + +bool Programmer::PicBase::internalRead(Device::Memory *memory, const Device::MemoryRange &range, const VerifyData *vdata) +{ + if ( !initProgramming(Task::Read) ) return false; + Pic::Memory *pmemory = static_cast(memory); + if ( !range.all() ) { + Pic::MemoryRangeType type = static_cast(range)._type; + if ( type==Pic::MemoryRangeType::Cal ) { + if ( !readRange(Pic::MemoryRangeType::Cal, pmemory, vdata) ) return false; + return readRange(Pic::MemoryRangeType::CalBackup, pmemory, vdata); + } + return readRange(type, pmemory, vdata); + } + if ( !readRange(Pic::MemoryRangeType::Config, pmemory, vdata) ) return false; + if ( !readRange(Pic::MemoryRangeType::UserId, pmemory, vdata) ) return false; + if ( vdata==0 ) if ( !readRange(Pic::MemoryRangeType::Cal, pmemory, 0) ) return false; + if ( vdata==0 ) if ( !readRange(Pic::MemoryRangeType::CalBackup, pmemory, 0) ) return false; + if ( !readRange(Pic::MemoryRangeType::Code, pmemory, vdata) ) return false; + if ( !readRange(Pic::MemoryRangeType::Eeprom, pmemory, vdata) ) return false; + return true; +} + +//----------------------------------------------------------------------------- +bool Programmer::PicBase::programSingle(Pic::MemoryRangeType type, const Pic::Memory &memory) +{ + if ( !specific()->canWriteRange(type) ) { + log(Log::LineType::SoftError, i18n("The selected programmer cannot read the specified memory range.")); + return false; + } + return program(memory, Pic::MemoryRange(type)); +} + +bool Programmer::PicBase::programRange(Pic::MemoryRangeType mtype, const Device::Array &data) +{ + log(Log::LineType::Information, i18n(" Write memory: %1").arg(mtype.label())); + bool only = ( readConfigEntry(Config::OnlyProgramNonMask).toBool() + && (mtype==Pic::MemoryRangeType::Code || mtype==Pic::MemoryRangeType::Eeprom) ); + return specific()->write(mtype, data, !only); +} + +bool Programmer::PicBase::programAndVerifyRange(Pic::MemoryRangeType type, const Pic::Memory &memory) +{ + if ( !device()->isWritable(type) || !specific()->canWriteRange(type) ) return true; + Device::Array data = memory.arrayForWriting(type); + if ( !programRange(type, data) ) return false; + if ( !readConfigEntry(Config::VerifyAfterProgram).toBool() ) return true; + if ( !specific()->canReadRange(type) ) return true; + VerifyActions actions = IgnoreProtectedVerify; + if ( type==Pic::MemoryRangeType::Code && readConfigEntry(Config::OnlyVerifyProgrammed).toBool() ) actions |= OnlyProgrammedVerify; + VerifyData vdata(actions, memory); + return readRange(type, 0, &vdata); +} + +bool Programmer::PicBase::programAll(const Pic::Memory &memory) +{ + if ( !programAndVerifyRange(Pic::MemoryRangeType::Code, memory) ) return false; + if ( readConfigEntry(Config::ProgramEeprom).toBool() ) { + const Pic::Memory &tmp = (readConfigEntry(Config::PreserveEeprom).toBool() ? *_deviceMemory : memory); + if ( !programAndVerifyRange(Pic::MemoryRangeType::Eeprom, tmp) ) return false; + } + if ( !programAndVerifyRange(Pic::MemoryRangeType::UserId, memory) ) return false; + if ( memory.isProtected(Pic::Protection::WriteProtected, Pic::MemoryRangeType::Config) ) { + log(Log::DebugLevel::Normal, " Config write protection is on: first program without it and then with it"); + Pic::Memory tmp(memory.device()); + tmp.copyFrom(Pic::MemoryRangeType::Config, memory); + tmp.setProtection(false, Pic::Protection::WriteProtected, Pic::MemoryRangeType::Config); + if ( !programAndVerifyRange(Pic::MemoryRangeType::Config, tmp) ) return false; + } + if ( !programAndVerifyRange(Pic::MemoryRangeType::Config, memory) ) return false; + return true; +} + +bool Programmer::PicBase::checkProgram(const Device::Memory &memory) +{ + if ( device()->memoryTechnology()==Device::MemoryTechnology::Rom || device()->memoryTechnology()==Device::MemoryTechnology::Romless ) { + log(Log::LineType::SoftError, i18n("Cannot write ROM or ROMless device.")); + return false; + } + if ( !group().isDebugger() && static_cast(memory).hasDebugOn() ) { + if ( !askContinue(i18n("DEBUG configuration bit is on. Are you sure you want to continue programming the chip?")) ) { + logUserAbort(); + return false; + } + } + return true; +} + +bool Programmer::PicBase::internalProgram(const Device::Memory &memory, const Device::MemoryRange &range) +{ + if ( !initProgramming(Task::Erase) ) return false; + const Pic::Memory &pmemory = static_cast(memory); + + // blank check if OTP device + bool eprom = ( device()->memoryTechnology()==Device::MemoryTechnology::Eprom ); + if (eprom) { + log(Log::LineType::Information, i18n(" EPROM device: blank checking first...")); + Pic::Memory memory(*device()); + VerifyData vdata(BlankCheckVerify, memory); + if ( !internalRead(0, range, &vdata) ) return false; + log(Log::LineType::Information, i18n(" Blank check successful")); + // check if protecting device + bool protectedCode = pmemory.isProtected(Pic::Protection::ProgramProtected, Pic::MemoryRangeType::Code); + bool protectedEeprom = pmemory.isProtected(Pic::Protection::ProgramProtected, Pic::MemoryRangeType::Eeprom); + if ( protectedCode || protectedEeprom ) { + log(Log::LineType::SoftError, i18n("Protecting code memory or data EEPROM on OTP devices is disabled as a security...")); + return false; + } + } + + // programming + bool ok = true; + if ( !range.all() ) { + Pic::MemoryRangeType type = static_cast(range)._type; + if ( (type==Pic::MemoryRangeType::Code && _hasProtectedCode) || (type==Pic::MemoryRangeType::Eeprom && _hasProtectedEeprom) ) { + log(Log::LineType::SoftError, i18n("This memory range is programming protected.")); + return false; + } + if ( specific()->canEraseRange(type) ) { + if ( !specific()->emulatedErase() && !eraseRange(type) ) return false; + } else log(Log::LineType::Warning, i18n("The range cannot be erased first by the selected programmer so programming may fail...")); + ok = programRange(type, pmemory.arrayForWriting(type)); + VerifyData vdata(NormalVerify, pmemory); + if (ok) ok = readRange(type, 0, &vdata); + } else { + if ( !eprom ) { + if ( specific()->canEraseAll() ) { + if ( !specific()->emulatedErase() ) { + log(Log::LineType::Information, i18n(" Erasing device")); + ok = ( !readConfigEntry(Config::PreserveEeprom).toBool() || preserveEeprom() ); + if (ok) ok = eraseAll(); + } + } else log(Log::LineType::Warning, i18n("The device cannot be erased first by the selected programmer so programming may fail...")); + } + if (ok) ok = programAll(pmemory); + } + if ( !restoreBandGapBits() ) return false; + return ok; +} + +//----------------------------------------------------------------------------- +bool Programmer::PicBase::checkProgramCalibration(const Device::Array &data) +{ + QString message, s = prettyCalibration(data); + if ( !device()->checkCalibration(data, &message) ) { + sorry(i18n("The calibration word %1 is not valid.").arg(s), message); + return false; + } + return askContinue(i18n("Do you want to overwrite the device calibration with %1?").arg(s)); +} + +bool Programmer::PicBase::tryProgramCalibration(const Device::Array &data, bool &success) +{ + log(Log::LineType::Information, i18n(" Write memory: %1").arg(Pic::MemoryRangeType(Pic::MemoryRangeType::Cal).label())); + success = true; + if ( !specific()->write(Pic::MemoryRangeType::Cal, data, true) ) return false; + Device::Array read; + if ( !specific()->read(Pic::MemoryRangeType::Cal, read, 0) ) return false; + for (uint i=0; iisWritable(Pic::MemoryRangeType::CalBackup) ) { + if ( !specific()->read(Pic::MemoryRangeType::CalBackup, read, 0) ) return false; + if ( device()->checkCalibration(read) ) return true; // do not overwrite correct backup value + log(Log::LineType::Information, i18n(" Write memory: %1").arg(Pic::MemoryRangeType(Pic::MemoryRangeType::CalBackup).label())); + if ( !specific()->write(Pic::MemoryRangeType::CalBackup, data, true) ) return false; + if ( !specific()->read(Pic::MemoryRangeType::CalBackup, read, 0) ) return false; + for (uint i=0; ierase(_hasProtectedCode || _hasProtectedEeprom); + if ( !restoreBandGapBits() ) return false; + if ( !ok ) return false; + // retry + if ( !tryProgramCalibration(data, success) ) return false; + return success; +} + +bool Programmer::PicBase::programCalibration(const Device::Array &data) +{ + _progressMonitor.clear(); + bool ok = doProgramCalibration(data); + endProgramming(); + return ok; +} + +bool Programmer::PicBase::doProgramCalibration(const Device::Array &data) +{ + if ( !checkProgramCalibration(data) ) return false; + if ( !doConnectDevice() ) return false; + log(Log::LineType::Information, i18n("Programming calibration...")); + emit actionMessage(i18n("Programming calibration...")); + if ( !internalProgramCalibration(data) ) return false; + log(Log::LineType::Information, i18n("Programming calibration successful")); + return true; +} + +//----------------------------------------------------------------------------- +bool Programmer::PicBase::verifySingle(Pic::MemoryRangeType type, const Pic::Memory &memory) +{ + return verify(memory, Pic::MemoryRange(type)); +} + +bool Programmer::PicBase::blankCheckSingle(Pic::MemoryRangeType type) +{ + return blankCheck(Pic::MemoryRange(type)); +} diff --git a/src/devices/pic/prog/pic_prog.h b/src/devices/pic/prog/pic_prog.h new file mode 100644 index 0000000..0fb37f7 --- /dev/null +++ b/src/devices/pic/prog/pic_prog.h @@ -0,0 +1,110 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PIC_PROG_H +#define PIC_PROG_H + +#include "pic_prog_specific.h" +#include "progs/base/prog_group.h" +#include "devices/base/device_group.h" + +namespace Pic +{ + +class MemoryRange : public Device::MemoryRange { +public: + MemoryRange(MemoryRangeType type) : _type(type) {} + virtual bool all() const { return _type==MemoryRangeType::Nb_Types; } + MemoryRangeType _type; +}; + +} //namespace + +namespace Programmer +{ +//----------------------------------------------------------------------------- +class PicGroup : public Group +{ +public: + virtual bool canReadVoltage(Pic::VoltageType) const { return false; } + virtual bool canReadVoltages() const; + virtual ::Debugger::DeviceSpecific *createDebuggerDeviceSpecific(::Debugger::Base &base) const; +}; + +//----------------------------------------------------------------------------- +class PicBase : public Base +{ +public: + PicBase(const Group &group, const Pic::Data *data, const char *name); + virtual ~PicBase(); + PicDeviceSpecific *specific() { return static_cast(_specific); } + const PicDeviceSpecific *specific() const { return static_cast(_specific); } + const Pic::Data *device() const { return static_cast(_device); } + const Pic::Memory &deviceMemory() const { return *_deviceMemory; } + const PicGroup &group() const { return static_cast(_group); } + double voltage(Pic::VoltageType type) const { return _voltages[type].value; } + virtual bool readVoltages(); + bool getTargetMode(Pic::TargetMode &mode); + + bool eraseSingle(Pic::MemoryRangeType type); + bool readSingle(Pic::MemoryRangeType type, Pic::Memory &memory); + bool programSingle(Pic::MemoryRangeType type, const Pic::Memory &memory); + bool verifySingle(Pic::MemoryRangeType type, const Pic::Memory &memory); + bool blankCheckSingle(Pic::MemoryRangeType type); + bool readCalibration(); + bool programCalibration(const Device::Array &data); + +protected: + PicHardware *hardware() { return static_cast(_hardware); } + virtual bool internalSetupHardware(); + virtual double vdd() const { return _voltages[Pic::TargetVdd].value; } + virtual double vpp() const { return _voltages[Pic::TargetVpp].value; } + virtual bool verifyDeviceId(); + virtual uint nbSteps(Task task, const Device::MemoryRange *range) const; + bool initProgramming(Task task); + virtual bool initProgramming(); + virtual bool internalRun(); + virtual bool internalStop(); + virtual void clear(); + + virtual bool checkErase(); + virtual bool internalErase(const Device::MemoryRange &range); + + virtual bool checkRead(); + virtual bool internalRead(Device::Memory *memory, const Device::MemoryRange &range, const VerifyData *data); + bool readRange(Pic::MemoryRangeType type, Pic::Memory *memory, const VerifyData *data); + + virtual bool checkProgram(const Device::Memory &memory); + virtual bool internalProgram(const Device::Memory &memory, const Device::MemoryRange &range); + virtual bool programAll(const Pic::Memory &memory); + bool programAndVerifyRange(Pic::MemoryRangeType type, const Pic::Memory &memory); + bool programRange(Pic::MemoryRangeType type, const Device::Array &array); + +private: + Pic::Memory *_deviceMemory; + bool _hasProtectedCode, _hasProtectedEeprom; + PicHardware::VoltagesData _voltages; + + BitValue readDeviceId(); + bool eraseAll(); + bool eraseRange(Pic::MemoryRangeType type); + bool restoreCalibration(); + bool restoreBandGapBits(); + bool doProgramCalibration(const Device::Array &data); + bool checkProgramCalibration(const Device::Array &data); + bool internalProgramCalibration(const Device::Array &data); + QString prettyCalibration(const Device::Array &data) const; + bool tryProgramCalibration(const Device::Array &data, bool &success); + bool preserveCode(); + bool preserveEeprom(); + bool internalEraseRange(Pic::MemoryRangeType type); +}; + +} // namespace + +#endif diff --git a/src/devices/pic/prog/pic_prog_specific.cpp b/src/devices/pic/prog/pic_prog_specific.cpp new file mode 100644 index 0000000..bfcd2fa --- /dev/null +++ b/src/devices/pic/prog/pic_prog_specific.cpp @@ -0,0 +1,121 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "pic_prog_specific.h" + +#include "common/global/global.h" + +//----------------------------------------------------------------------------- +const char * const Pic::VOLTAGE_TYPE_LABELS[Nb_VoltageTypes] = { + I18N_NOOP("Programmer Vpp"), I18N_NOOP("Target Vdd"), I18N_NOOP("Target Vpp") +}; + +const char * const Pic::TARGET_MODE_LABELS[Nb_TargetModes] = { + I18N_NOOP("Stopped"), I18N_NOOP("Running"), I18N_NOOP("In Programming") +}; + +const char * const Pic::RESET_MODE_LABELS[Nb_ResetModes] = { + I18N_NOOP("Reset Held"), I18N_NOOP("Reset Released") +}; + +//----------------------------------------------------------------------------- +uint Programmer::PicDeviceSpecific::findNonMaskStart(Pic::MemoryRangeType type, const Device::Array &data) const +{ + uint start = 0; + for (; start(this)->log(Log::DebugLevel::Normal, QString("start before align: %1").arg(start)); + uint align = device().nbWordsWriteAlignment(type); + start -= start % align; + const_cast(this)->log(Log::DebugLevel::Normal, QString("start after align: %1 (align=%2)").arg(start).arg(align)); + return start; +} + +uint Programmer::PicDeviceSpecific::findNonMaskEnd(Pic::MemoryRangeType type, const Device::Array &data) const +{ + uint end = data.count()-1; + for (; end>0; end--) + if ( data[end]!=device().mask(type) ) break; + const_cast(this)->log(Log::DebugLevel::Normal, QString("end before align: %1").arg(end)); + uint align = device().nbWordsWriteAlignment(type); + if ( (end+1) % align ) end += align - (end+1) % align; + const_cast(this)->log(Log::DebugLevel::Normal, QString("end after align: %1 (align=%2)").arg(end).arg(align)); + Q_ASSERT(end(vdata.memory).normalizedWord(type, i); + BitValue d = static_cast(vdata.memory).normalizeWord(type, i, word); + if ( type==Pic::MemoryRangeType::Config ) { + BitValue pmask = device().config()._words[i].pmask; + v = v.clearMaskBits(pmask); + d = d.clearMaskBits(pmask); + } + return compareWords(type, i, v, d, vdata.actions); +} diff --git a/src/devices/pic/prog/pic_prog_specific.h b/src/devices/pic/prog/pic_prog_specific.h new file mode 100644 index 0000000..fef8a61 --- /dev/null +++ b/src/devices/pic/prog/pic_prog_specific.h @@ -0,0 +1,86 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PIC_PROG_SPECIFIC_H +#define PIC_PROG_SPECIFIC_H + +#include "progs/base/prog_specific.h" +#include "progs/base/generic_prog.h" +#include "devices/pic/pic/pic_memory.h" + +//---------------------------------------------------------------------------- +namespace Pic +{ + enum ResetMode { ResetHeld = 0, ResetReleased, Nb_ResetModes}; + extern const char * const RESET_MODE_LABELS[Nb_ResetModes]; + + enum VoltageType { ProgrammerVpp = 0, TargetVdd, TargetVpp, Nb_VoltageTypes }; + extern const char * const VOLTAGE_TYPE_LABELS[Nb_VoltageTypes]; + + enum TargetMode { TargetStopped = 0, TargetRunning, TargetInProgramming, Nb_TargetModes}; + extern const char * const TARGET_MODE_LABELS[Nb_TargetModes]; + + enum WriteMode { WriteOnlyMode = 0, EraseWriteMode, Nb_WriteModes }; +} // namespace + +namespace Programmer +{ +//----------------------------------------------------------------------------- +class PicDeviceSpecific : public DeviceSpecific +{ +public: + PicDeviceSpecific(::Programmer::Base &base) : DeviceSpecific(base) {} + const Pic::Data &device() const { return static_cast(*_base.device()); } + virtual bool canEraseAll() const = 0; + virtual bool canEraseRange(Pic::MemoryRangeType type) const = 0; + virtual bool emulatedErase() const { return false; } + virtual bool canReadRange(Pic::MemoryRangeType type) const = 0; + virtual bool canWriteRange(Pic::MemoryRangeType type) const = 0; + bool eraseRange(Pic::MemoryRangeType type); + bool erase(bool isProtected); + bool read(Pic::MemoryRangeType type, Device::Array &data, const VerifyData *vdata); + bool write(Pic::MemoryRangeType type, const Device::Array &data, bool force); + uint findNonMaskStart(Pic::MemoryRangeType type, const Device::Array &data) const; + uint findNonMaskEnd(Pic::MemoryRangeType type, const Device::Array &data) const; + +protected: + virtual bool doErase(bool isProtected) = 0; + virtual bool doEraseRange(Pic::MemoryRangeType type) = 0; + bool doEmulatedEraseRange(Pic::MemoryRangeType type); + virtual bool doRead(Pic::MemoryRangeType type, Device::Array &data, const VerifyData *vdata) = 0; + virtual bool doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force) = 0; +}; + +//----------------------------------------------------------------------------- +class PicHardware : public Hardware +{ +public: + class VoltageData { + public: + VoltageData() : value(UNKNOWN_VOLTAGE) {} + double value; + bool error; + }; + class VoltagesData : public QValueVector { + public: + VoltagesData() : QValueVector(Pic::Nb_VoltageTypes) {} + }; + +public: + PicHardware(::Programmer::Base &base, Port::Base *port, const QString &name) : Hardware(base, port, name) {} + const Pic::Data &device() const { return static_cast(*_base.device()); } + virtual bool readVoltages(VoltagesData &) { return true; } + virtual bool getTargetMode(Pic::TargetMode &mode) { mode = Pic::TargetInProgramming; return true; } + virtual bool setTargetReset(Pic::ResetMode) { return true; } + bool compareWords(Pic::MemoryRangeType type, uint index, BitValue v, BitValue d, VerifyActions actions); + bool verifyWord(uint index, BitValue word, Pic::MemoryRangeType type, const VerifyData &vdata); +}; + +} // namespace + +#endif diff --git a/src/devices/pic/prog/prog.pro b/src/devices/pic/prog/prog.pro new file mode 100644 index 0000000..c0caf87 --- /dev/null +++ b/src/devices/pic/prog/prog.pro @@ -0,0 +1,6 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/lib.pro) + +TARGET = picprog +HEADERS += pic_prog.h pic_debug.h pic_prog_specific.h +SOURCES += pic_prog.cpp pic_debug.cpp pic_prog_specific.cpp diff --git a/src/devices/pic/xml/Makefile.am b/src/devices/pic/xml/Makefile.am new file mode 100644 index 0000000..a941f8d --- /dev/null +++ b/src/devices/pic/xml/Makefile.am @@ -0,0 +1,12 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_PROGRAMS = pic_xml_to_data + +pic_xml_to_data_SOURCES = pic_xml_to_data.cpp +pic_xml_to_data_DEPENDENCIES = $(top_builddir)/src/devices/pic/base/libpicbase.la \ + $(top_builddir)/src/xml_to_data/libxmltodata.la $(top_builddir)/src/devices/base/libdevicebase.la \ + $(top_builddir)/src/common/common/libcommon.la +pic_xml_to_data_LDADD = $(top_builddir)/src/devices/pic/base/libpicbase.la \ + $(top_builddir)/src/xml_to_data/libxmltodata.la $(top_builddir)/src/devices/base/libdevicebase.la \ + $(top_builddir)/src/common/common/libcommon.la $(LIB_KDECORE) diff --git a/src/devices/pic/xml/pic_xml_to_data.cpp b/src/devices/pic/xml/pic_xml_to_data.cpp new file mode 100644 index 0000000..f3675de --- /dev/null +++ b/src/devices/pic/xml/pic_xml_to_data.cpp @@ -0,0 +1,718 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include +#include + +#include "xml_to_data/device_xml_to_data.h" +#include "common/common/misc.h" +#include "devices/pic/base/pic_config.h" +#include "devices/pic/base/pic_register.h" + +namespace Pic +{ +class XmlToData : public Device::XmlToData +{ +private: + virtual QString namespaceName() const { return "Pic"; } + +bool getVoltages(ProgVoltageType type, QDomElement element) +{ + QDomElement voltages = findUniqueElement(element, "voltages", "name", type.key()); + if ( voltages.isNull() ) return false; + bool ok1, ok2, ok3; + data()->_voltages[type].min = voltages.attribute("min").toDouble(&ok1); + data()->_voltages[type].max = voltages.attribute("max").toDouble(&ok2); + data()->_voltages[type].nominal = voltages.attribute("nominal").toDouble(&ok3); + if ( !ok1 || !ok2 || !ok3 ) qFatal(QString("Cannot extract voltage value for \"%1\"").arg(type.key())); + if ( data()->_voltages[type].min>data()->_voltages[type].max + || data()->_voltages[type].nominal_voltages[type].min + || data()->_voltages[type].nominal>data()->_voltages[type].max ) + qFatal("Inconsistent voltages order"); + return true; +} + +bool getMemoryRange(MemoryRangeType type, QDomElement element) +{ + QDomElement range = findUniqueElement(element, "memory", "name", type.key()); + if ( range.isNull() ) return false; + data()->_ranges[type].properties = Present; + bool ok; + uint nbCharsAddress = data()->nbCharsAddress(); + data()->_ranges[type].start = fromHexLabel(range.attribute("start"), nbCharsAddress, &ok); + if ( !ok ) qFatal("Cannot extract start address"); + data()->_ranges[type].end = fromHexLabel(range.attribute("end"), nbCharsAddress, &ok); + if ( !ok ) qFatal("Cannot extract end address"); + if ( data()->_ranges[type].end_ranges[type].start ) qFatal("Memory range end is before its start"); + uint nbCharsWord = data()->nbCharsWord(type); + if ( data()->nbBitsWord(type)==0 ) qFatal(QString("Architecture doesn't contain memory range %1").arg(type.key())); + if ( type==MemoryRangeType::UserId ) { + data()->_userIdRecommendedMask = fromHexLabel(range.attribute("rmask"), nbCharsWord, &ok); + if ( !ok ) qFatal("Cannot extract rmask value for user id"); + if ( !data()->_userIdRecommendedMask.isInside(data()->mask(type)) ) qFatal(QString("rmask is not inside mask %1 (%2)").arg(toHexLabel(data()->_userIdRecommendedMask, 8)).arg(toHexLabel(data()->mask(type), 8))); + } + if ( range.attribute("hexfile_offset")!="?" ) { + data()->_ranges[type].properties |= Programmable; + if ( !range.attribute("hexfile_offset").isEmpty() ) { + data()->_ranges[type].hexFileOffset = fromHexLabel(range.attribute("hexfile_offset"), nbCharsAddress, &ok); + if ( !ok ) qFatal("Cannot extract hexfile_offset"); + } + } + if ( type==MemoryRangeType::Cal && !data()->is18Family() ) { + data()->_calibration.opcodeMask = fromHexLabel(range.attribute("cal_opmask"), nbCharsWord, &ok); + if ( !ok ) qFatal("Cannot extract calibration opcode mask"); + data()->_calibration.opcode = fromHexLabel(range.attribute("cal_opcode"), nbCharsWord, &ok); + if ( !ok ) qFatal("Cannot extract calibration opcode"); + if ( !data()->_calibration.opcode.isInside(data()->_calibration.opcodeMask) ) qFatal("Calibration opcode should be inside opcode mask"); + if ( !data()->_calibration.opcodeMask.isInside(data()->mask(type)) ) qFatal("Calibration mask should be inside opcode mask"); + } + QString wwa = range.attribute("word_write_align"); + QString wea = range.attribute("word_erase_align"); + if ( type==MemoryRangeType::Code ) { + if ( data()->_architecture==Architecture::P18F || data()->_architecture==Architecture::P18J ) { + data()->_nbWordsCodeWrite = wwa.toUInt(&ok); + if ( !ok || data()->_nbWordsCodeWrite==0 || (data()->_nbWordsCodeWrite%4)!=0 ) qFatal("Missing or malformed word write align"); + data()->_nbWordsCodeRowErase = wea.toUInt(&ok); + if ( !ok || (data()->_nbWordsCodeRowErase%4)!=0 ) qFatal("Missing or malformed word erase align"); + } else { + if ( !wwa.isEmpty() || !wea.isEmpty() ) qFatal("word align should not be defined for this device family/subfamily"); + data()->_nbWordsCodeWrite = 0; // #### TODO + data()->_nbWordsCodeRowErase = 0; // #### TODO + } + } else if ( !wwa.isEmpty() || !wea.isEmpty() ) qFatal("word align should not be defined for this memory range"); + return true; +} + +bool hasValue(const Pic::Config::Mask &mask, BitValue value) +{ + for (uint i=0; iarchitecture()!=Pic::Architecture::P18J && data()->architecture()!=Pic::Architecture::P24H + && data()->architecture()!=Pic::Architecture::P24F && data()->architecture()!=Pic::Architecture::P33F + && data()->name()!="30F1010" && data()->name()!="30F2020" && data()->name()!="30F2023" ) + qFatal(QString("cname not defined for \"%1\" (%2)").arg(cvalue.name).arg(cmask.name)); + } + if ( cnames.count()==1 && cnames[0]=="_" ) cnames.clear(); + for (uint i=0; inbCharsWord(MemoryRangeType::Config); + BitValue mask = cmask.value.complementInMask(maxValue(NumberBase::Hex, nbChars)); + if ( ok && v==(mask | cvalue.value) ) continue; + } else if ( XOR(cnames[i].startsWith("_"), data()->architecture()==Pic::Architecture::P30F) ) continue; + qFatal(QString("Invalid config name for \"%1\"/\"%2\"").arg(cmask.name).arg(cvalue.name)); + } + QStringList &ecnames = cvalue.configNames[Pic::ConfigNameType::Extra]; + for (uint i=0; inbCharsWord(MemoryRangeType::Config); + bool ok; + QString defName; + QMap defConfigNames; + Config::Mask cmask; + cmask.name = mask.attribute("name"); + if ( !Config::hasMaskName(cmask.name) ) qFatal(QString("Unknown mask name %1").arg(cmask.name)); + cmask.value = fromHexLabel(mask.attribute("value"), nbChars, &ok); + if ( !ok || cmask.value==0 || cmask.value>data()->mask(MemoryRangeType::Config) ) + qFatal(QString("Malformed mask value in mask %1").arg(mask.attribute("name"))); + //QStringList names; + QDomNode child = mask.firstChild(); + while ( !child.isNull() ) { + QDomElement value = child.toElement(); + child = child.nextSibling(); + if ( value.isNull() ) continue; + if ( value.nodeName()!="value" ) qFatal(QString("Non value child in mask %1").arg(cmask.name)); + if ( value.attribute("value")=="default" ) { + if ( !defName.isEmpty() ) qFatal(QString("Default value already defined for mask %1").arg(cmask.name)); + defName = value.attribute("name"); + //if ( names.contains(defName) ) qFatal(QString("Value name duplicated in mask %1").arg(cmask.name)); + //names.append(defName); + FOR_EACH(Pic::ConfigNameType, type) defConfigNames[type] = QStringList::split(' ', value.attribute(type.data().key)); + continue; + } + Config::Value cvalue; + cvalue.value = fromHexLabel(value.attribute("value"), nbChars, &ok); + if ( !ok || !cvalue.value.isInside(cmask.value) ) qFatal(QString("Malformed value in mask %1").arg(cmask.name)); + cvalue.name = value.attribute("name"); + //if ( names.contains(cvalue.name) ) qFatal(QString("Value name duplicated in mask %1").arg(cmask.name)); + //names.append(cvalue.name); + FOR_EACH(Pic::ConfigNameType, type) cvalue.configNames[type] = QStringList::split(' ', value.attribute(type.data().key)); + processName(cmask, pmask, cvalue); + cmask.values.append(cvalue); + } + // add default values + if ( !defName.isEmpty() ) { + uint nb = 0; + BitValue::const_iterator it; + for (it=cmask.value.begin(); it!=cmask.value.end(); ++it) { + if ( hasValue(cmask, *it) ) continue; // already set + nb++; + Config::Value cvalue; + cvalue.value = *it; + cvalue.name = defName; + cvalue.configNames = defConfigNames; + processName(cmask, pmask, cvalue); + cmask.values.append(cvalue); + } + if ( nb<=1 ) qFatal(QString("Default value used less than twice in mask %1").arg(cmask.name)); + } + qHeapSort(cmask.values); + return cmask; +} + +Pic::Config::Word toConfigWord(QDomElement config) +{ + uint nbChars = data()->nbCharsWord(MemoryRangeType::Config); + Config::Word cword; + cword.name = config.attribute("name"); + if ( cword.name.isNull() ) qFatal("Config word name not specified."); + bool ok; + cword.wmask = fromHexLabel(config.attribute("wmask"), nbChars, &ok); + BitValue gmask = data()->mask(MemoryRangeType::Config); + if ( !ok || cword.wmask>gmask ) qFatal(QString("Missing or malformed config wmask \"%1\"").arg(config.attribute("wmask"))); + cword.bvalue = fromHexLabel(config.attribute("bvalue"), nbChars, &ok); + if ( !ok ) qFatal(QString("Missing or malformed config bvalue \"%1\"").arg(config.attribute("bvalue"))); + if ( config.attribute("pmask").isEmpty() ) cword.pmask = 0; + else { + bool ok; + cword.pmask = fromHexLabel(config.attribute("pmask"), nbChars, &ok); + if ( !ok || cword.pmask>gmask ) qFatal("Missing or malformed config pmask"); + } + cword.ignoredCNames = QStringList::split(' ', config.attribute("icnames")); + for (uint i=0; i_architecture==Pic::Architecture::P30F ) cword.cmask = cword.wmask; + else cword.cmask = mask; + } else { + bool ok; + cword.cmask = fromHexLabel(config.attribute("cmask"), nbChars, &ok); + if ( !ok || cword.cmask>gmask ) qFatal("Missing or malformed config cmask"); + //if ( data()->_architecture==Pic::Architecture::P30X &&cword.cmask==cword.wmask ) qFatal(QString("Redundant cmask in %1").arg(cword.name)); + if ( cword.cmask==mask ) qFatal(QString("Redundant cmask in %1").arg(cword.name)); + } + if ( !cword.pmask.isInside(cword.usedMask()) ) qFatal("pmask should be inside or'ed mask values."); + return cword; +} + +QValueVector getConfigWords(QDomElement element) +{ + uint nbWords = data()->nbWords(MemoryRangeType::Config); + QValueVector configWords(nbWords); + QDomNode child = element.firstChild(); + while ( !child.isNull() ) { + QDomElement config = child.toElement(); + child = child.nextSibling(); + if ( config.isNull() || config.nodeName()!="config" ) continue; + bool ok; + uint offset = fromHexLabel(config.attribute("offset"), 1, &ok); + if ( !ok ) qFatal("Missing or malformed config offset"); + if ( (offset % data()->addressIncrement(MemoryRangeType::Config))!=0 ) qFatal("Config offset not aligned"); + offset /= data()->addressIncrement(MemoryRangeType::Config); + if ( offset>=nbWords ) qFatal(QString("Offset too big %1/%2").arg(offset).arg(nbWords)); + if ( !configWords[offset].name.isNull() ) qFatal(QString("Config offset %1 is duplicated").arg(offset)); + for (uint i=0; i_config->protection(); + QString valueName; + if ( protection.family()==Protection::BlockProtection ) { + valueName = checksum.attribute("protected_blocks"); + bool ok; + uint nb = valueName.toUInt(&ok); + uint max = (protection.hasBootBlock() ? 1 : 0) + protection.nbBlocks(); + if ( !ok || nb>max ) qFatal("Invalid number of protected blocks for checksum"); + if ( nb>0 ) cdata.protectedMaskNames += "CPB"; + for (uint i=1; i_config->findMask(protection.bootSizeMaskName()); + if ( mask==0 ) { + if ( !cdata.bbsize.isEmpty() ) qFatal("Device does not have a variable boot size (no \"bbsize\" allowed in checksum)"); + } else if ( cdata.bbsize.isEmpty() ) { + if ( nb==1 ) qFatal("\"bbsize\" should be define in checksum for \"protected_blocks\"==1"); + } else { + const Config::Value *value = data()->_config->findValue(protection.bootSizeMaskName(), cdata.bbsize); + if ( value==0 ) qFatal("Invalid \"bbsize\" in checksum"); + valueName += "_" + cdata.bbsize; + } + } else { + valueName = checksum.attribute("protected"); + if ( protection.family()==Protection::NoProtection && !valueName.isEmpty() ) + qFatal("Checksum protected attribute for device with no code protection"); + } + if ( data()->_checksums.contains(valueName) ) qFatal("Duplicate checksum protected range"); + + QString s = checksum.attribute("constant"); + if ( s.isEmpty() ) cdata.constant = 0x0000; + else { + bool ok; + cdata.constant = fromHexLabel(s, 4, &ok); + if ( !ok ) qFatal("Malformed checksum constant"); + } + + s = checksum.attribute("type"); + if ( s.isEmpty() ) cdata.algorithm = Checksum::Algorithm::Normal; + else { + cdata.algorithm = Checksum::Algorithm::fromKey(s); + if ( cdata.algorithm==Checksum::Algorithm::Nb_Types ) qFatal("Unrecognized checksum algorithm"); + } + + s = checksum.attribute("mprotected"); + if ( !s.isEmpty() ) { + QStringList list = QStringList::split(" ", s); + for (uint i=0; iconfig().findMask(list[i]); + if ( mask==0 ) qFatal(QString("Not valid mask name for \"protected\" tag in checksum: %1").arg(list[i])); + if ( mask->values.count()==2 ) continue; + for (uint k=0; kvalues.count()); k++) { + QString valueName = mask->values[k].name; + if ( valueName.isEmpty() ) continue; + if ( !protection.isNoneProtectedValueName(valueName) && !protection.isAllProtectedValueName(valueName) ) + qFatal(QString("Not switch protection from mask name for \"protected\" tag in checksum: %1").arg(list[i])); + } + } + cdata.protectedMaskNames = list; + } + + s = checksum.attribute("bchecksum"); + if ( s.isEmpty() ) qFatal("No blank checksum"); + else { + bool ok; + cdata.blankChecksum = fromHexLabel(s, 4, &ok); + if ( !ok ) qFatal("Malformed blank checksum"); + } + + s = checksum.attribute("cchecksum"); + if ( s.isEmpty() ) qFatal("No check checksum"); + else { + bool ok; + cdata.checkChecksum = fromHexLabel(s, 4, &ok); + if ( !ok ) qFatal("Malformed check checksum"); + } + + data()->_checksums[valueName] = cdata; + return valueName; +} + +virtual void processDevice(QDomElement device) +{ + Device::XmlToDataBase::processDevice(device); + + QString arch = device.attribute("architecture"); + data()->_architecture = Architecture::fromKey(arch); + if ( data()->_architecture==Architecture::Nb_Types ) qFatal(QString("Unrecognized architecture \"%1\"").arg(arch)); + if ( (data()->_architecture==Architecture::P18F && data()->_name.contains("C")) + || (data()->_architecture==Architecture::P18F && data()->_name.contains("J")) ) qFatal("Not matching family"); + + bool ok; + QString pc = device.attribute("pc"); + data()->_nbBitsPC = data()->_architecture.data().nbBitsPC; + if ( data()->_nbBitsPC==0 ) { + data()->_nbBitsPC = pc.toUInt(&ok); + if ( !ok || data()->_nbBitsPC==0 ) qFatal("Malformed or missing PC"); + } else if ( !pc.isEmpty() ) qFatal("No PC should be provided for this device architecture"); + + QString sw = device.attribute("self_write"); + data()->_selfWrite = (data()->_memoryTechnology!=Device::MemoryTechnology::Flash ? SelfWrite::No : data()->_architecture.data().selfWrite); + if ( data()->_selfWrite==SelfWrite::Nb_Types ) { + data()->_selfWrite = SelfWrite::fromKey(sw); + if ( data()->_selfWrite==SelfWrite::Nb_Types ) qFatal("Malformed or missing self-write field"); + } else if ( !sw.isEmpty() ) qFatal("Self-write is set for the whole family or non-flash device"); + + // device ids + FOR_EACH(Device::Special, special) { + QString key = "id" + (special==Device::Special::Normal ? QString::null : QString("_") + special.key()); + QString id = device.attribute(key); + if ( id.isEmpty() ) { + if ( special==Device::Special::Normal ) data()->_ids[special] = 0x0000; + } else { + data()->_ids[special] = fromHexLabel(id, 4, &ok); + if ( !ok ) qFatal("Malformed id"); + } + } + + // voltages + QStringList names; + FOR_EACH(ProgVoltageType, vtype) { + names += vtype.key(); + if ( !getVoltages(vtype, device) ) { + switch (vtype.type()) { + case ProgVoltageType::Vpp: + case ProgVoltageType::VddBulkErase: qFatal(QString("Voltage \"%1\" not defined").arg(vtype.key())); + case ProgVoltageType::VddWrite: data()->_voltages[ProgVoltageType::VddWrite] = data()->_voltages[ProgVoltageType::VddBulkErase]; break; + case ProgVoltageType::Nb_Types: Q_ASSERT(false); break; + } + } + } + //if ( data()->vddMin()>data()->_voltages[ProgVoltageType::VddWrite].min ) qFatal("Vdd min higher than VddWrite min"); + //if ( data()->vddMax()_voltages[ProgVoltageType::VddWrite].max ) qFatal("Vdd max lower than VddWrite max"); + if ( data()->_voltages[ProgVoltageType::VddWrite].min>data()->_voltages[ProgVoltageType::VddBulkErase].min ) qFatal("VddWrite min higher than VddBulkErase min"); + if ( data()->_voltages[ProgVoltageType::VddWrite].max_voltages[ProgVoltageType::VddBulkErase].max ) qFatal("VddWrite max lower than VddBulkErase max"); + checkTagNames(device, "voltages", names); + + // memory ranges + names.clear(); + FOR_EACH(MemoryRangeType, i) { + names += i.key(); + if ( !getMemoryRange(i, device) ) continue; + if ( !(data()->_ranges[i].properties & Programmable) ) continue; + for(MemoryRangeType k; k_ranges[k].properties & Present) + || !(data()->_ranges[k].properties & Programmable) ) continue; + if ( i==MemoryRangeType::DebugVector + && k==MemoryRangeType::ProgramExecutive ) continue; + if ( k==MemoryRangeType::DebugVector + && i==MemoryRangeType::ProgramExecutive ) continue; + Address start1 = data()->_ranges[k].start + data()->_ranges[k].hexFileOffset; + Address end1 = data()->_ranges[k].end + data()->_ranges[k].hexFileOffset; + Address start2 = data()->_ranges[i].start + data()->_ranges[i].hexFileOffset; + Address end2 = data()->_ranges[i].end + data()->_ranges[i].hexFileOffset; + if ( end1>=start2 && start1<=end2 ) + qFatal(QString("Overlapping memory ranges (%1 and %2)").arg(k.key()).arg(i.key())); + } + } + checkTagNames(device, "memory", names); + if ( XOR(data()->_ids[Device::Special::Normal]!=0x0000, (data()->_ranges[MemoryRangeType::DeviceId].properties & Present)) ) + qFatal("Id present and device id memory range absent or the opposite"); + + // config words + QValueVector cwords = getConfigWords(device); + uint nbWords = data()->nbWords(MemoryRangeType::Config); + data()->_config->_words.resize(nbWords); + FOR_EACH(Pic::ConfigNameType, type) { + QMap cnames; // cname -> mask name + for (uint i=0; i_config->_words[i] = cwords[i]; + const Config::Word &word = data()->_config->_words[i]; + for (uint j=0; j_config->_words[i]; + for (uint j=0; j_config->checkValueName(mask.name, value.name) ) + qFatal(QString("Malformed value name \"%1\" in mask %2").arg(value.name).arg(mask.name)); + } + } + } + // check if all values are explicit + for (uint i=0; i_config->_words[i]; + for (uint j=0; jnbCharsWord(MemoryRangeType::Config))).arg(mask.name)); + } + } + + // checksums (after config bits!) + QDomElement checksums = findUniqueElement(device, "checksums", QString::null, QString::null); + if ( checksums.isNull() ) { + // qFatal("No checksum defined"); // #### FIXME + } else { + QMap valueNames; + const Pic::Protection &protection = data()->_config->protection(); + if ( protection.family()==Protection::BasicProtection ) { + QString maskName = protection.maskName(Protection::ProgramProtected, MemoryRangeType::Code); + const Pic::Config::Mask *mask = data()->_config->findMask(maskName); + Q_ASSERT(mask); + for (uint i=0; ivalues.count()); i++) valueNames[mask->values[i].name] = false; + } + QDomNode child = checksums.firstChild(); + while ( !child.isNull() ) { + if ( !child.isElement() ) continue; + if ( child.nodeName()!="checksum" ) qFatal("Childs of \"checksums\" should \"checksum\""); + QString valueName = getChecksumData(child.toElement()); + if ( protection.family()==Protection::BasicProtection ) { + if ( !valueNames.contains(valueName) ) qFatal("Unknown protected attribute"); + valueNames[valueName] = true; + } + child = child.nextSibling(); + } + QMap::const_iterator it; + for (it=valueNames.begin(); it!=valueNames.end(); ++it) + if ( !it.key().isEmpty() && !it.data() ) qFatal(QString("Missing checksum \"%1\"").arg(it.key())); + } +} + +void processMirrored(QDomElement element) +{ + QValueVector mirrored; + QDomNode child = element.firstChild(); + while ( !child.isNull() ) { + if ( !child.isElement() ) qFatal("\"mirror\" child should be an element"); + QDomElement e = child.toElement(); + if ( e.nodeName()!="range" ) qFatal("\"mirror\" child should be \"range\""); + RangeData rd; + bool ok; + rd.start = fromHexLabel(e.attribute("start"), &ok); + Address end = fromHexLabel(e.attribute("end"), &ok); + rd.length = end-rd.start+1; + if ( !mirrored.isEmpty() && rd.length!=mirrored[0].length ) + qFatal("Mirrored are not of the same length"); + mirrored.append(rd); + child = child.nextSibling(); + } + if ( !mirrored.isEmpty() ) static_cast(data()->_registersData)->mirrored.append(mirrored); +} + +void processUnused(QDomElement e) +{ + RangeData rd; + bool ok; + rd.start = fromHexLabel(e.attribute("start"), &ok); + if (!ok) qFatal("Malformed start for unused register"); + Address end = fromHexLabel(e.attribute("end"), &ok); + rd.length = end-rd.start+1; + if (!ok) qFatal("Malformed end for unused register"); + static_cast(data()->_registersData)->unused.append(rd); +} + +void processSfr(QDomElement e) +{ + QString name = e.attribute("name"); + if ( name.isEmpty() ) qFatal("SFR cannot have empty name"); + if ( data()->registersData().sfrs.contains(name) || data()->registersData().combined.contains(name) ) + qFatal("SFR name is duplicated"); + bool ok; + uint address = fromHexLabel(e.attribute("address"), &ok); + if ( !ok ) qFatal(QString("SFR %1 address %2 is malformed").arg(name).arg(e.attribute("address"))); + uint rlength = data()->registersData().nbBanks * data()->architecture().data().registerBankLength; + if ( address>=rlength ) qFatal(QString("Address %1 outside register range").arg(toHexLabel(address, 3))); + RegisterData rdata; + rdata.address = address; + uint nb = data()->registersData().nbBits(); + if ( nb>Device::MAX_NB_PORT_BITS ) qFatal(QString("Need higher MAX_NB_PORT_BITS: %1").arg(nb)); + QString access = e.attribute("access"); + if ( uint(access.length())!=nb ) qFatal("access is missing or malformed"); + QString mclr = e.attribute("mclr"); + if ( uint(mclr.length())!=nb ) qFatal("mclr is missing or malformed"); + QString por = e.attribute("por"); + if ( uint(por.length())!=nb ) qFatal("por is missing or malformed"); + for (uint i=0; iMaxRegisterBitProperty ) qFatal(QString("Malformed access bit %1").arg(k)); + rdata.bits[k].mclr = RegisterBitState(fromHex(mclr[i].latin1(), &ok)); + if ( !ok || rdata.bits[k].mclr>Nb_RegisterBitStates ) qFatal(QString("Malformed mclr bit %1").arg(k)); + rdata.bits[k].por = RegisterBitState(fromHex(por[i].latin1(), &ok)); + if ( !ok || rdata.bits[k].por>Nb_RegisterBitStates ) qFatal(QString("Malformed por bit %1").arg(k)); + } + static_cast(data()->_registersData)->sfrs[name] = rdata; +} + +void processCombined(QDomElement e) +{ + QString name = e.attribute("name"); + if ( name.isEmpty() ) qFatal("Combined register cannot have empty name"); + if ( data()->registersData().sfrs.contains(name) || data()->registersData().combined.contains(name) ) + qFatal("Combined register name is duplicated"); + bool ok; + CombinedData rdata; + rdata.address = fromHexLabel(e.attribute("address"), &ok); + if ( !ok ) qFatal(QString("Combined %1 address %2 is malformed").arg(name).arg(e.attribute("address"))); + uint rlength = data()->registersData().nbBanks * data()->architecture().data().registerBankLength; + if ( rdata.address>=rlength ) qFatal(QString("Address %1 outside register range").arg(toHexLabel(rdata.address, 3))); + rdata.nbChars = 2*e.attribute("size").toUInt(&ok); + if ( !ok || rdata.nbChars<2 ) qFatal(QString("Combined %1 size %2 is malformed").arg(name).arg(e.attribute("size"))); + Address end = rdata.address + rdata.nbChars/2 - 1; + if ( end>=rlength ) qFatal(QString("Address %1 outside register range").arg(toHexLabel(end, 3))); + static_cast(data()->_registersData)->combined[name] = rdata; +} + +void processDeviceRegisters(QDomElement element) +{ + QString s = element.attribute("same_as"); + if ( !s.isEmpty() ) { + if ( !_map.contains(s) ) qFatal(QString("Registers same as unknown device %1").arg(s)); + const Pic::Data *d = static_cast(_map[s]); + data()->_registersData = d->_registersData; + return; + } + + RegistersData &rdata = *static_cast(data()->_registersData); + bool ok; + rdata.nbBanks = element.attribute("nb_banks").toUInt(&ok); + if ( !ok || data()->registersData().nbBanks==0 ) qFatal("Malformed number of banks"); + if ( data()->is18Family() ) { + rdata.accessBankSplit = fromHexLabel(element.attribute("access_bank_split_offset"), &ok); + if ( !ok || rdata.accessBankSplit==0 || rdata.accessBankSplit>=0xFF ) qFatal("Malformed access bank split offset"); + rdata.unusedBankMask = fromHexLabel(element.attribute("unused_bank_mask"), &ok); + if ( !ok || rdata.unusedBankMask>=maxValue(NumberBase::Hex, rdata.nbBanks) ) qFatal("Malformed access unused bank mask"); + } else { + rdata.accessBankSplit = 0; + rdata.unusedBankMask = 0; + } + + QDomNode child = element.firstChild(); + while ( !child.isNull() ) { + if ( !child.isElement() ) qFatal("\"device\" child should be an element"); + QDomElement e = child.toElement(); + if ( e.nodeName()=="mirror" ) processMirrored(e); + else if ( e.nodeName()=="unused" ) processUnused(e); + else if ( e.nodeName()=="combined" ) processCombined(e); + else if ( e.nodeName()=="sfr" ) processSfr(e); + else qFatal(QString("Node name \"%1\" is not recognized").arg(e.nodeName())); + child = child.nextSibling(); + } + + for (uint i=0; i::const_iterator it = _map.begin(); + for (; it!=_map.end(); ++it) { + _data = it.data(); + if ( !devices.contains(it.key()) ) qWarning("Register description not found for %s", it.key().latin1()); + } +} + +virtual void checkPins(const QMap &pinLabels) const +{ + if ( !pinLabels.contains("VDD") ) qFatal("No VDD pin specified"); + if ( !pinLabels.contains("VSS") ) qFatal("No VSS pin specified"); + QMap::const_iterator it; + for (it=pinLabels.begin(); it!=pinLabels.end(); ++it) { + if ( it.key()=="VDD" || it.key()=="VSS" || it.key().startsWith("CCP") ) continue; + if ( it.data()!=1 ) qFatal(QString("Duplicated pin \"%1\"").arg(it.key())); + } + const Pic::RegistersData &rdata = static_cast(*_data->registersData()); + for (uint i=0; i + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/10F202.xml b/src/devices/pic/xml_data/10F202.xml new file mode 100644 index 0000000..25ce72a --- /dev/null +++ b/src/devices/pic/xml_data/10F202.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/10F204.xml b/src/devices/pic/xml_data/10F204.xml new file mode 100644 index 0000000..e2d2e6d --- /dev/null +++ b/src/devices/pic/xml_data/10F204.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/10F206.xml b/src/devices/pic/xml_data/10F206.xml new file mode 100644 index 0000000..4e66268 --- /dev/null +++ b/src/devices/pic/xml_data/10F206.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/10F220.xml b/src/devices/pic/xml_data/10F220.xml new file mode 100644 index 0000000..694d161 --- /dev/null +++ b/src/devices/pic/xml_data/10F220.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/10F222.xml b/src/devices/pic/xml_data/10F222.xml new file mode 100644 index 0000000..4cba906 --- /dev/null +++ b/src/devices/pic/xml_data/10F222.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/12C508.xml b/src/devices/pic/xml_data/12C508.xml new file mode 100644 index 0000000..cb39eae --- /dev/null +++ b/src/devices/pic/xml_data/12C508.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/12C508A.xml b/src/devices/pic/xml_data/12C508A.xml new file mode 100644 index 0000000..f1ffb3f --- /dev/null +++ b/src/devices/pic/xml_data/12C508A.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/12C509.xml b/src/devices/pic/xml_data/12C509.xml new file mode 100644 index 0000000..dbe885b --- /dev/null +++ b/src/devices/pic/xml_data/12C509.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/12C509A.xml b/src/devices/pic/xml_data/12C509A.xml new file mode 100644 index 0000000..240783f --- /dev/null +++ b/src/devices/pic/xml_data/12C509A.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/12C671.xml b/src/devices/pic/xml_data/12C671.xml new file mode 100644 index 0000000..f675723 --- /dev/null +++ b/src/devices/pic/xml_data/12C671.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/12C672.xml b/src/devices/pic/xml_data/12C672.xml new file mode 100644 index 0000000..80511f1 --- /dev/null +++ b/src/devices/pic/xml_data/12C672.xml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/12CE518.xml b/src/devices/pic/xml_data/12CE518.xml new file mode 100644 index 0000000..e27cbb3 --- /dev/null +++ b/src/devices/pic/xml_data/12CE518.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/12CE519.xml b/src/devices/pic/xml_data/12CE519.xml new file mode 100644 index 0000000..210e186 --- /dev/null +++ b/src/devices/pic/xml_data/12CE519.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/12CE673.xml b/src/devices/pic/xml_data/12CE673.xml new file mode 100644 index 0000000..3007c29 --- /dev/null +++ b/src/devices/pic/xml_data/12CE673.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/12CE674.xml b/src/devices/pic/xml_data/12CE674.xml new file mode 100644 index 0000000..7670f3f --- /dev/null +++ b/src/devices/pic/xml_data/12CE674.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/12CR509A.xml b/src/devices/pic/xml_data/12CR509A.xml new file mode 100644 index 0000000..9a795da --- /dev/null +++ b/src/devices/pic/xml_data/12CR509A.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/12F508.xml b/src/devices/pic/xml_data/12F508.xml new file mode 100644 index 0000000..19fd956 --- /dev/null +++ b/src/devices/pic/xml_data/12F508.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/12F509.xml b/src/devices/pic/xml_data/12F509.xml new file mode 100644 index 0000000..8f3ae12 --- /dev/null +++ b/src/devices/pic/xml_data/12F509.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/12F510.xml b/src/devices/pic/xml_data/12F510.xml new file mode 100644 index 0000000..15a2d81 --- /dev/null +++ b/src/devices/pic/xml_data/12F510.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/12F519.xml b/src/devices/pic/xml_data/12F519.xml new file mode 100644 index 0000000..600618c --- /dev/null +++ b/src/devices/pic/xml_data/12F519.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/12F609.xml b/src/devices/pic/xml_data/12F609.xml new file mode 100644 index 0000000..d3409ee --- /dev/null +++ b/src/devices/pic/xml_data/12F609.xml @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/12F615.xml b/src/devices/pic/xml_data/12F615.xml new file mode 100644 index 0000000..d59445e --- /dev/null +++ b/src/devices/pic/xml_data/12F615.xml @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/12F629.xml b/src/devices/pic/xml_data/12F629.xml new file mode 100644 index 0000000..53c0cf4 --- /dev/null +++ b/src/devices/pic/xml_data/12F629.xml @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/12F635.xml b/src/devices/pic/xml_data/12F635.xml new file mode 100644 index 0000000..f06c3b6 --- /dev/null +++ b/src/devices/pic/xml_data/12F635.xml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/12F675.xml b/src/devices/pic/xml_data/12F675.xml new file mode 100644 index 0000000..6e0f054 --- /dev/null +++ b/src/devices/pic/xml_data/12F675.xml @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/12F683.xml b/src/devices/pic/xml_data/12F683.xml new file mode 100644 index 0000000..1c23260 --- /dev/null +++ b/src/devices/pic/xml_data/12F683.xml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/14000.xml b/src/devices/pic/xml_data/14000.xml new file mode 100644 index 0000000..8cf2db6 --- /dev/null +++ b/src/devices/pic/xml_data/14000.xml @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C432.xml b/src/devices/pic/xml_data/16C432.xml new file mode 100644 index 0000000..e112d5c --- /dev/null +++ b/src/devices/pic/xml_data/16C432.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C433.xml b/src/devices/pic/xml_data/16C433.xml new file mode 100644 index 0000000..cf07aaa --- /dev/null +++ b/src/devices/pic/xml_data/16C433.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C505.xml b/src/devices/pic/xml_data/16C505.xml new file mode 100644 index 0000000..2cbe2c9 --- /dev/null +++ b/src/devices/pic/xml_data/16C505.xml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C52.xml b/src/devices/pic/xml_data/16C52.xml new file mode 100644 index 0000000..6ef7753 --- /dev/null +++ b/src/devices/pic/xml_data/16C52.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C54.xml b/src/devices/pic/xml_data/16C54.xml new file mode 100644 index 0000000..06455ee --- /dev/null +++ b/src/devices/pic/xml_data/16C54.xml @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C54A.xml b/src/devices/pic/xml_data/16C54A.xml new file mode 100644 index 0000000..c264f10 --- /dev/null +++ b/src/devices/pic/xml_data/16C54A.xml @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C54B.xml b/src/devices/pic/xml_data/16C54B.xml new file mode 100644 index 0000000..d20ae0e --- /dev/null +++ b/src/devices/pic/xml_data/16C54B.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C54C.xml b/src/devices/pic/xml_data/16C54C.xml new file mode 100644 index 0000000..0d1907b --- /dev/null +++ b/src/devices/pic/xml_data/16C54C.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C55.xml b/src/devices/pic/xml_data/16C55.xml new file mode 100644 index 0000000..0d93443 --- /dev/null +++ b/src/devices/pic/xml_data/16C55.xml @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C554.xml b/src/devices/pic/xml_data/16C554.xml new file mode 100644 index 0000000..1723220 --- /dev/null +++ b/src/devices/pic/xml_data/16C554.xml @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C557.xml b/src/devices/pic/xml_data/16C557.xml new file mode 100644 index 0000000..3a9ddab --- /dev/null +++ b/src/devices/pic/xml_data/16C557.xml @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C558.xml b/src/devices/pic/xml_data/16C558.xml new file mode 100644 index 0000000..484efee --- /dev/null +++ b/src/devices/pic/xml_data/16C558.xml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C55A.xml b/src/devices/pic/xml_data/16C55A.xml new file mode 100644 index 0000000..27b9eac --- /dev/null +++ b/src/devices/pic/xml_data/16C55A.xml @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C56.xml b/src/devices/pic/xml_data/16C56.xml new file mode 100644 index 0000000..a8ec195 --- /dev/null +++ b/src/devices/pic/xml_data/16C56.xml @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C56A.xml b/src/devices/pic/xml_data/16C56A.xml new file mode 100644 index 0000000..0543765 --- /dev/null +++ b/src/devices/pic/xml_data/16C56A.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C57.xml b/src/devices/pic/xml_data/16C57.xml new file mode 100644 index 0000000..4aef05a --- /dev/null +++ b/src/devices/pic/xml_data/16C57.xml @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C57C.xml b/src/devices/pic/xml_data/16C57C.xml new file mode 100644 index 0000000..4d5f180 --- /dev/null +++ b/src/devices/pic/xml_data/16C57C.xml @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C58A.xml b/src/devices/pic/xml_data/16C58A.xml new file mode 100644 index 0000000..a12abb6 --- /dev/null +++ b/src/devices/pic/xml_data/16C58A.xml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C58B.xml b/src/devices/pic/xml_data/16C58B.xml new file mode 100644 index 0000000..04f56ce --- /dev/null +++ b/src/devices/pic/xml_data/16C58B.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C61.xml b/src/devices/pic/xml_data/16C61.xml new file mode 100644 index 0000000..0b62c88 --- /dev/null +++ b/src/devices/pic/xml_data/16C61.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C62.xml b/src/devices/pic/xml_data/16C62.xml new file mode 100644 index 0000000..8eebe47 --- /dev/null +++ b/src/devices/pic/xml_data/16C62.xml @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C620.xml b/src/devices/pic/xml_data/16C620.xml new file mode 100644 index 0000000..8a676af --- /dev/null +++ b/src/devices/pic/xml_data/16C620.xml @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C620A.xml b/src/devices/pic/xml_data/16C620A.xml new file mode 100644 index 0000000..9770da4 --- /dev/null +++ b/src/devices/pic/xml_data/16C620A.xml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C621.xml b/src/devices/pic/xml_data/16C621.xml new file mode 100644 index 0000000..401ee06 --- /dev/null +++ b/src/devices/pic/xml_data/16C621.xml @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C621A.xml b/src/devices/pic/xml_data/16C621A.xml new file mode 100644 index 0000000..97e136e --- /dev/null +++ b/src/devices/pic/xml_data/16C621A.xml @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C622.xml b/src/devices/pic/xml_data/16C622.xml new file mode 100644 index 0000000..f1675bc --- /dev/null +++ b/src/devices/pic/xml_data/16C622.xml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C622A.xml b/src/devices/pic/xml_data/16C622A.xml new file mode 100644 index 0000000..04e0d9b --- /dev/null +++ b/src/devices/pic/xml_data/16C622A.xml @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C62A.xml b/src/devices/pic/xml_data/16C62A.xml new file mode 100644 index 0000000..71bf13f --- /dev/null +++ b/src/devices/pic/xml_data/16C62A.xml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C62B.xml b/src/devices/pic/xml_data/16C62B.xml new file mode 100644 index 0000000..6550cbb --- /dev/null +++ b/src/devices/pic/xml_data/16C62B.xml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C63.xml b/src/devices/pic/xml_data/16C63.xml new file mode 100644 index 0000000..7d21001 --- /dev/null +++ b/src/devices/pic/xml_data/16C63.xml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C63A.xml b/src/devices/pic/xml_data/16C63A.xml new file mode 100644 index 0000000..2a3eac3 --- /dev/null +++ b/src/devices/pic/xml_data/16C63A.xml @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C64.xml b/src/devices/pic/xml_data/16C64.xml new file mode 100644 index 0000000..2bd6f77 --- /dev/null +++ b/src/devices/pic/xml_data/16C64.xml @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C641.xml b/src/devices/pic/xml_data/16C641.xml new file mode 100644 index 0000000..2a819ff --- /dev/null +++ b/src/devices/pic/xml_data/16C641.xml @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C642.xml b/src/devices/pic/xml_data/16C642.xml new file mode 100644 index 0000000..c5847a9 --- /dev/null +++ b/src/devices/pic/xml_data/16C642.xml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C64A.xml b/src/devices/pic/xml_data/16C64A.xml new file mode 100644 index 0000000..c5331e6 --- /dev/null +++ b/src/devices/pic/xml_data/16C64A.xml @@ -0,0 +1,253 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C65.xml b/src/devices/pic/xml_data/16C65.xml new file mode 100644 index 0000000..1d5de06 --- /dev/null +++ b/src/devices/pic/xml_data/16C65.xml @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C65A.xml b/src/devices/pic/xml_data/16C65A.xml new file mode 100644 index 0000000..4220f2d --- /dev/null +++ b/src/devices/pic/xml_data/16C65A.xml @@ -0,0 +1,253 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C65B.xml b/src/devices/pic/xml_data/16C65B.xml new file mode 100644 index 0000000..c5eae8a --- /dev/null +++ b/src/devices/pic/xml_data/16C65B.xml @@ -0,0 +1,207 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C66.xml b/src/devices/pic/xml_data/16C66.xml new file mode 100644 index 0000000..bfa3307 --- /dev/null +++ b/src/devices/pic/xml_data/16C66.xml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C661.xml b/src/devices/pic/xml_data/16C661.xml new file mode 100644 index 0000000..612f636 --- /dev/null +++ b/src/devices/pic/xml_data/16C661.xml @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C662.xml b/src/devices/pic/xml_data/16C662.xml new file mode 100644 index 0000000..a09c5c5 --- /dev/null +++ b/src/devices/pic/xml_data/16C662.xml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C67.xml b/src/devices/pic/xml_data/16C67.xml new file mode 100644 index 0000000..43c1aa1 --- /dev/null +++ b/src/devices/pic/xml_data/16C67.xml @@ -0,0 +1,253 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C71.xml b/src/devices/pic/xml_data/16C71.xml new file mode 100644 index 0000000..d23acc3 --- /dev/null +++ b/src/devices/pic/xml_data/16C71.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C710.xml b/src/devices/pic/xml_data/16C710.xml new file mode 100644 index 0000000..d6a90c2 --- /dev/null +++ b/src/devices/pic/xml_data/16C710.xml @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C711.xml b/src/devices/pic/xml_data/16C711.xml new file mode 100644 index 0000000..29518e3 --- /dev/null +++ b/src/devices/pic/xml_data/16C711.xml @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C712.xml b/src/devices/pic/xml_data/16C712.xml new file mode 100644 index 0000000..6979deb --- /dev/null +++ b/src/devices/pic/xml_data/16C712.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C715.xml b/src/devices/pic/xml_data/16C715.xml new file mode 100644 index 0000000..501018f --- /dev/null +++ b/src/devices/pic/xml_data/16C715.xml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C716.xml b/src/devices/pic/xml_data/16C716.xml new file mode 100644 index 0000000..f34e760 --- /dev/null +++ b/src/devices/pic/xml_data/16C716.xml @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C717.xml b/src/devices/pic/xml_data/16C717.xml new file mode 100644 index 0000000..19c6f6a --- /dev/null +++ b/src/devices/pic/xml_data/16C717.xml @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C72.xml b/src/devices/pic/xml_data/16C72.xml new file mode 100644 index 0000000..e6b88a2 --- /dev/null +++ b/src/devices/pic/xml_data/16C72.xml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C72A.xml b/src/devices/pic/xml_data/16C72A.xml new file mode 100644 index 0000000..cabb079 --- /dev/null +++ b/src/devices/pic/xml_data/16C72A.xml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C73.xml b/src/devices/pic/xml_data/16C73.xml new file mode 100644 index 0000000..78b69fa --- /dev/null +++ b/src/devices/pic/xml_data/16C73.xml @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C73A.xml b/src/devices/pic/xml_data/16C73A.xml new file mode 100644 index 0000000..df9a672 --- /dev/null +++ b/src/devices/pic/xml_data/16C73A.xml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C73B.xml b/src/devices/pic/xml_data/16C73B.xml new file mode 100644 index 0000000..b2418f1 --- /dev/null +++ b/src/devices/pic/xml_data/16C73B.xml @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C74.xml b/src/devices/pic/xml_data/16C74.xml new file mode 100644 index 0000000..091501d --- /dev/null +++ b/src/devices/pic/xml_data/16C74.xml @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C745.xml b/src/devices/pic/xml_data/16C745.xml new file mode 100644 index 0000000..1a4ab42 --- /dev/null +++ b/src/devices/pic/xml_data/16C745.xml @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C74A.xml b/src/devices/pic/xml_data/16C74A.xml new file mode 100644 index 0000000..0d784c9 --- /dev/null +++ b/src/devices/pic/xml_data/16C74A.xml @@ -0,0 +1,206 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C74B.xml b/src/devices/pic/xml_data/16C74B.xml new file mode 100644 index 0000000..ce7274f --- /dev/null +++ b/src/devices/pic/xml_data/16C74B.xml @@ -0,0 +1,207 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C76.xml b/src/devices/pic/xml_data/16C76.xml new file mode 100644 index 0000000..c5819a2 --- /dev/null +++ b/src/devices/pic/xml_data/16C76.xml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C765.xml b/src/devices/pic/xml_data/16C765.xml new file mode 100644 index 0000000..c441e17 --- /dev/null +++ b/src/devices/pic/xml_data/16C765.xml @@ -0,0 +1,198 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C77.xml b/src/devices/pic/xml_data/16C77.xml new file mode 100644 index 0000000..f863d24 --- /dev/null +++ b/src/devices/pic/xml_data/16C77.xml @@ -0,0 +1,206 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C770.xml b/src/devices/pic/xml_data/16C770.xml new file mode 100644 index 0000000..de1d9e9 --- /dev/null +++ b/src/devices/pic/xml_data/16C770.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C771.xml b/src/devices/pic/xml_data/16C771.xml new file mode 100644 index 0000000..4bf7fcd --- /dev/null +++ b/src/devices/pic/xml_data/16C771.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C773.xml b/src/devices/pic/xml_data/16C773.xml new file mode 100644 index 0000000..1b74ed5 --- /dev/null +++ b/src/devices/pic/xml_data/16C773.xml @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C774.xml b/src/devices/pic/xml_data/16C774.xml new file mode 100644 index 0000000..1d577ee --- /dev/null +++ b/src/devices/pic/xml_data/16C774.xml @@ -0,0 +1,259 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C781.xml b/src/devices/pic/xml_data/16C781.xml new file mode 100644 index 0000000..2861a67 --- /dev/null +++ b/src/devices/pic/xml_data/16C781.xml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C782.xml b/src/devices/pic/xml_data/16C782.xml new file mode 100644 index 0000000..6192a30 --- /dev/null +++ b/src/devices/pic/xml_data/16C782.xml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C84.xml b/src/devices/pic/xml_data/16C84.xml new file mode 100644 index 0000000..595bcd9 --- /dev/null +++ b/src/devices/pic/xml_data/16C84.xml @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C923.xml b/src/devices/pic/xml_data/16C923.xml new file mode 100644 index 0000000..a670a59 --- /dev/null +++ b/src/devices/pic/xml_data/16C923.xml @@ -0,0 +1,270 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C924.xml b/src/devices/pic/xml_data/16C924.xml new file mode 100644 index 0000000..614ff48 --- /dev/null +++ b/src/devices/pic/xml_data/16C924.xml @@ -0,0 +1,270 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C925.xml b/src/devices/pic/xml_data/16C925.xml new file mode 100644 index 0000000..b9c703d --- /dev/null +++ b/src/devices/pic/xml_data/16C925.xml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16C926.xml b/src/devices/pic/xml_data/16C926.xml new file mode 100644 index 0000000..4120d43 --- /dev/null +++ b/src/devices/pic/xml_data/16C926.xml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16CE623.xml b/src/devices/pic/xml_data/16CE623.xml new file mode 100644 index 0000000..18e6848 --- /dev/null +++ b/src/devices/pic/xml_data/16CE623.xml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16CE624.xml b/src/devices/pic/xml_data/16CE624.xml new file mode 100644 index 0000000..4f205a7 --- /dev/null +++ b/src/devices/pic/xml_data/16CE624.xml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16CE625.xml b/src/devices/pic/xml_data/16CE625.xml new file mode 100644 index 0000000..d7aa576 --- /dev/null +++ b/src/devices/pic/xml_data/16CE625.xml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16CR54.xml_broken b/src/devices/pic/xml_data/16CR54.xml_broken new file mode 100644 index 0000000..cef44cb --- /dev/null +++ b/src/devices/pic/xml_data/16CR54.xml_broken @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16CR54A.xml b/src/devices/pic/xml_data/16CR54A.xml new file mode 100644 index 0000000..c3a5d2a --- /dev/null +++ b/src/devices/pic/xml_data/16CR54A.xml @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16CR54B.xml b/src/devices/pic/xml_data/16CR54B.xml new file mode 100644 index 0000000..43456d8 --- /dev/null +++ b/src/devices/pic/xml_data/16CR54B.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16CR54C.xml b/src/devices/pic/xml_data/16CR54C.xml new file mode 100644 index 0000000..3667ce3 --- /dev/null +++ b/src/devices/pic/xml_data/16CR54C.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16CR56A.xml b/src/devices/pic/xml_data/16CR56A.xml new file mode 100644 index 0000000..0b28931 --- /dev/null +++ b/src/devices/pic/xml_data/16CR56A.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16CR57B.xml b/src/devices/pic/xml_data/16CR57B.xml new file mode 100644 index 0000000..caba4c3 --- /dev/null +++ b/src/devices/pic/xml_data/16CR57B.xml @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16CR57C.xml b/src/devices/pic/xml_data/16CR57C.xml new file mode 100644 index 0000000..379f1bc --- /dev/null +++ b/src/devices/pic/xml_data/16CR57C.xml @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16CR58A.xml b/src/devices/pic/xml_data/16CR58A.xml new file mode 100644 index 0000000..3841400 --- /dev/null +++ b/src/devices/pic/xml_data/16CR58A.xml @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16CR58B.xml b/src/devices/pic/xml_data/16CR58B.xml new file mode 100644 index 0000000..b450e31 --- /dev/null +++ b/src/devices/pic/xml_data/16CR58B.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16CR62.xml b/src/devices/pic/xml_data/16CR62.xml new file mode 100644 index 0000000..0b27a3c --- /dev/null +++ b/src/devices/pic/xml_data/16CR62.xml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16CR620A.xml b/src/devices/pic/xml_data/16CR620A.xml new file mode 100644 index 0000000..a2e6db3 --- /dev/null +++ b/src/devices/pic/xml_data/16CR620A.xml @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16CR63.xml b/src/devices/pic/xml_data/16CR63.xml new file mode 100644 index 0000000..08d6f3f --- /dev/null +++ b/src/devices/pic/xml_data/16CR63.xml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16CR64.xml b/src/devices/pic/xml_data/16CR64.xml new file mode 100644 index 0000000..e155a97 --- /dev/null +++ b/src/devices/pic/xml_data/16CR64.xml @@ -0,0 +1,206 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16CR65.xml b/src/devices/pic/xml_data/16CR65.xml new file mode 100644 index 0000000..df4d3f4 --- /dev/null +++ b/src/devices/pic/xml_data/16CR65.xml @@ -0,0 +1,253 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16CR72.xml b/src/devices/pic/xml_data/16CR72.xml new file mode 100644 index 0000000..efaa9f8 --- /dev/null +++ b/src/devices/pic/xml_data/16CR72.xml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16CR73.xml b/src/devices/pic/xml_data/16CR73.xml new file mode 100644 index 0000000..6513255 --- /dev/null +++ b/src/devices/pic/xml_data/16CR73.xml @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16CR74.xml b/src/devices/pic/xml_data/16CR74.xml new file mode 100644 index 0000000..6fec92e --- /dev/null +++ b/src/devices/pic/xml_data/16CR74.xml @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16CR76.xml b/src/devices/pic/xml_data/16CR76.xml new file mode 100644 index 0000000..dd9916a --- /dev/null +++ b/src/devices/pic/xml_data/16CR76.xml @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16CR77.xml b/src/devices/pic/xml_data/16CR77.xml new file mode 100644 index 0000000..661ebf0 --- /dev/null +++ b/src/devices/pic/xml_data/16CR77.xml @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16CR83.xml b/src/devices/pic/xml_data/16CR83.xml new file mode 100644 index 0000000..01c4166 --- /dev/null +++ b/src/devices/pic/xml_data/16CR83.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16CR84.xml b/src/devices/pic/xml_data/16CR84.xml new file mode 100644 index 0000000..5d93205 --- /dev/null +++ b/src/devices/pic/xml_data/16CR84.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F505.xml b/src/devices/pic/xml_data/16F505.xml new file mode 100644 index 0000000..bbc2607 --- /dev/null +++ b/src/devices/pic/xml_data/16F505.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F506.xml b/src/devices/pic/xml_data/16F506.xml new file mode 100644 index 0000000..4fa7a47 --- /dev/null +++ b/src/devices/pic/xml_data/16F506.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F54.xml b/src/devices/pic/xml_data/16F54.xml new file mode 100644 index 0000000..4b55624 --- /dev/null +++ b/src/devices/pic/xml_data/16F54.xml @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F57.xml b/src/devices/pic/xml_data/16F57.xml new file mode 100644 index 0000000..e84e053 --- /dev/null +++ b/src/devices/pic/xml_data/16F57.xml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F59.xml b/src/devices/pic/xml_data/16F59.xml new file mode 100644 index 0000000..b29659a --- /dev/null +++ b/src/devices/pic/xml_data/16F59.xml @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F610.xml b/src/devices/pic/xml_data/16F610.xml new file mode 100644 index 0000000..46795b1 --- /dev/null +++ b/src/devices/pic/xml_data/16F610.xml @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F616.xml b/src/devices/pic/xml_data/16F616.xml new file mode 100644 index 0000000..9f8ca55 --- /dev/null +++ b/src/devices/pic/xml_data/16F616.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F627.xml b/src/devices/pic/xml_data/16F627.xml new file mode 100644 index 0000000..7ce03a5 --- /dev/null +++ b/src/devices/pic/xml_data/16F627.xml @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F627A.xml b/src/devices/pic/xml_data/16F627A.xml new file mode 100644 index 0000000..de43d7a --- /dev/null +++ b/src/devices/pic/xml_data/16F627A.xml @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F628.xml b/src/devices/pic/xml_data/16F628.xml new file mode 100644 index 0000000..fed16fa --- /dev/null +++ b/src/devices/pic/xml_data/16F628.xml @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F628A.xml b/src/devices/pic/xml_data/16F628A.xml new file mode 100644 index 0000000..8c5a4cc --- /dev/null +++ b/src/devices/pic/xml_data/16F628A.xml @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F630.xml b/src/devices/pic/xml_data/16F630.xml new file mode 100644 index 0000000..a82ffdb --- /dev/null +++ b/src/devices/pic/xml_data/16F630.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F631.xml b/src/devices/pic/xml_data/16F631.xml new file mode 100644 index 0000000..e6a5274 --- /dev/null +++ b/src/devices/pic/xml_data/16F631.xml @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F636.xml b/src/devices/pic/xml_data/16F636.xml new file mode 100644 index 0000000..e47314e --- /dev/null +++ b/src/devices/pic/xml_data/16F636.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F639.xml b/src/devices/pic/xml_data/16F639.xml new file mode 100644 index 0000000..7affb7b --- /dev/null +++ b/src/devices/pic/xml_data/16F639.xml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F648A.xml b/src/devices/pic/xml_data/16F648A.xml new file mode 100644 index 0000000..17b4f83 --- /dev/null +++ b/src/devices/pic/xml_data/16F648A.xml @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F676.xml b/src/devices/pic/xml_data/16F676.xml new file mode 100644 index 0000000..b608d48 --- /dev/null +++ b/src/devices/pic/xml_data/16F676.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F677.xml b/src/devices/pic/xml_data/16F677.xml new file mode 100644 index 0000000..d27b2eb --- /dev/null +++ b/src/devices/pic/xml_data/16F677.xml @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F684.xml b/src/devices/pic/xml_data/16F684.xml new file mode 100644 index 0000000..f330925 --- /dev/null +++ b/src/devices/pic/xml_data/16F684.xml @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F685.xml b/src/devices/pic/xml_data/16F685.xml new file mode 100644 index 0000000..aa35aa3 --- /dev/null +++ b/src/devices/pic/xml_data/16F685.xml @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F687.xml b/src/devices/pic/xml_data/16F687.xml new file mode 100644 index 0000000..2e58780 --- /dev/null +++ b/src/devices/pic/xml_data/16F687.xml @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F688.xml b/src/devices/pic/xml_data/16F688.xml new file mode 100644 index 0000000..2692159 --- /dev/null +++ b/src/devices/pic/xml_data/16F688.xml @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F689.xml b/src/devices/pic/xml_data/16F689.xml new file mode 100644 index 0000000..f22fdcd --- /dev/null +++ b/src/devices/pic/xml_data/16F689.xml @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F690.xml b/src/devices/pic/xml_data/16F690.xml new file mode 100644 index 0000000..7a51bac --- /dev/null +++ b/src/devices/pic/xml_data/16F690.xml @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F716.xml b/src/devices/pic/xml_data/16F716.xml new file mode 100644 index 0000000..8ebaa00 --- /dev/null +++ b/src/devices/pic/xml_data/16F716.xml @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F72.xml b/src/devices/pic/xml_data/16F72.xml new file mode 100644 index 0000000..d49b2cd --- /dev/null +++ b/src/devices/pic/xml_data/16F72.xml @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F73.xml b/src/devices/pic/xml_data/16F73.xml new file mode 100644 index 0000000..157cb74 --- /dev/null +++ b/src/devices/pic/xml_data/16F73.xml @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F737.xml b/src/devices/pic/xml_data/16F737.xml new file mode 100644 index 0000000..0184aa9 --- /dev/null +++ b/src/devices/pic/xml_data/16F737.xml @@ -0,0 +1,215 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F74.xml b/src/devices/pic/xml_data/16F74.xml new file mode 100644 index 0000000..fc2b312 --- /dev/null +++ b/src/devices/pic/xml_data/16F74.xml @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F747.xml b/src/devices/pic/xml_data/16F747.xml new file mode 100644 index 0000000..ec03640 --- /dev/null +++ b/src/devices/pic/xml_data/16F747.xml @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F76.xml b/src/devices/pic/xml_data/16F76.xml new file mode 100644 index 0000000..3b6fcf3 --- /dev/null +++ b/src/devices/pic/xml_data/16F76.xml @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F767.xml b/src/devices/pic/xml_data/16F767.xml new file mode 100644 index 0000000..77ed134 --- /dev/null +++ b/src/devices/pic/xml_data/16F767.xml @@ -0,0 +1,215 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F77.xml b/src/devices/pic/xml_data/16F77.xml new file mode 100644 index 0000000..e02e2cb --- /dev/null +++ b/src/devices/pic/xml_data/16F77.xml @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F777.xml b/src/devices/pic/xml_data/16F777.xml new file mode 100644 index 0000000..71899b2 --- /dev/null +++ b/src/devices/pic/xml_data/16F777.xml @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F785.xml b/src/devices/pic/xml_data/16F785.xml new file mode 100644 index 0000000..80c9091 --- /dev/null +++ b/src/devices/pic/xml_data/16F785.xml @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F818.xml b/src/devices/pic/xml_data/16F818.xml new file mode 100644 index 0000000..0ff73b5 --- /dev/null +++ b/src/devices/pic/xml_data/16F818.xml @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F819.xml b/src/devices/pic/xml_data/16F819.xml new file mode 100644 index 0000000..e7ee0a6 --- /dev/null +++ b/src/devices/pic/xml_data/16F819.xml @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F83.xml b/src/devices/pic/xml_data/16F83.xml new file mode 100644 index 0000000..25b80a3 --- /dev/null +++ b/src/devices/pic/xml_data/16F83.xml @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F84.xml b/src/devices/pic/xml_data/16F84.xml new file mode 100644 index 0000000..62c1f8d --- /dev/null +++ b/src/devices/pic/xml_data/16F84.xml @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F84A.xml b/src/devices/pic/xml_data/16F84A.xml new file mode 100644 index 0000000..ffffba1 --- /dev/null +++ b/src/devices/pic/xml_data/16F84A.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F87.xml b/src/devices/pic/xml_data/16F87.xml new file mode 100644 index 0000000..835b481 --- /dev/null +++ b/src/devices/pic/xml_data/16F87.xml @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F870.xml b/src/devices/pic/xml_data/16F870.xml new file mode 100644 index 0000000..ec66b54 --- /dev/null +++ b/src/devices/pic/xml_data/16F870.xml @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F871.xml b/src/devices/pic/xml_data/16F871.xml new file mode 100644 index 0000000..8b918ca --- /dev/null +++ b/src/devices/pic/xml_data/16F871.xml @@ -0,0 +1,226 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F872.xml b/src/devices/pic/xml_data/16F872.xml new file mode 100644 index 0000000..7702922 --- /dev/null +++ b/src/devices/pic/xml_data/16F872.xml @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F873.xml b/src/devices/pic/xml_data/16F873.xml new file mode 100644 index 0000000..4bbb1cb --- /dev/null +++ b/src/devices/pic/xml_data/16F873.xml @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F873A.xml b/src/devices/pic/xml_data/16F873A.xml new file mode 100644 index 0000000..ee26828 --- /dev/null +++ b/src/devices/pic/xml_data/16F873A.xml @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F874.xml b/src/devices/pic/xml_data/16F874.xml new file mode 100644 index 0000000..fe20128 --- /dev/null +++ b/src/devices/pic/xml_data/16F874.xml @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F874A.xml b/src/devices/pic/xml_data/16F874A.xml new file mode 100644 index 0000000..c89b407 --- /dev/null +++ b/src/devices/pic/xml_data/16F874A.xml @@ -0,0 +1,273 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F876.xml b/src/devices/pic/xml_data/16F876.xml new file mode 100644 index 0000000..19264e8 --- /dev/null +++ b/src/devices/pic/xml_data/16F876.xml @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F876A.xml b/src/devices/pic/xml_data/16F876A.xml new file mode 100644 index 0000000..f1c23ce --- /dev/null +++ b/src/devices/pic/xml_data/16F876A.xml @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F877.xml b/src/devices/pic/xml_data/16F877.xml new file mode 100644 index 0000000..f83da05 --- /dev/null +++ b/src/devices/pic/xml_data/16F877.xml @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F877A.xml b/src/devices/pic/xml_data/16F877A.xml new file mode 100644 index 0000000..3a16d77 --- /dev/null +++ b/src/devices/pic/xml_data/16F877A.xml @@ -0,0 +1,273 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F88.xml b/src/devices/pic/xml_data/16F88.xml new file mode 100644 index 0000000..b2325c3 --- /dev/null +++ b/src/devices/pic/xml_data/16F88.xml @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F882.xml b/src/devices/pic/xml_data/16F882.xml new file mode 100644 index 0000000..db2c723 --- /dev/null +++ b/src/devices/pic/xml_data/16F882.xml @@ -0,0 +1,175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F883.xml b/src/devices/pic/xml_data/16F883.xml new file mode 100644 index 0000000..1140b72 --- /dev/null +++ b/src/devices/pic/xml_data/16F883.xml @@ -0,0 +1,175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F884.xml b/src/devices/pic/xml_data/16F884.xml new file mode 100644 index 0000000..fbe9423 --- /dev/null +++ b/src/devices/pic/xml_data/16F884.xml @@ -0,0 +1,250 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F886.xml b/src/devices/pic/xml_data/16F886.xml new file mode 100644 index 0000000..3205cd7 --- /dev/null +++ b/src/devices/pic/xml_data/16F886.xml @@ -0,0 +1,175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F887.xml b/src/devices/pic/xml_data/16F887.xml new file mode 100644 index 0000000..78be11e --- /dev/null +++ b/src/devices/pic/xml_data/16F887.xml @@ -0,0 +1,250 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F913.xml b/src/devices/pic/xml_data/16F913.xml new file mode 100644 index 0000000..c904d5d --- /dev/null +++ b/src/devices/pic/xml_data/16F913.xml @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F914.xml b/src/devices/pic/xml_data/16F914.xml new file mode 100644 index 0000000..d74a0d5 --- /dev/null +++ b/src/devices/pic/xml_data/16F914.xml @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F916.xml b/src/devices/pic/xml_data/16F916.xml new file mode 100644 index 0000000..b066f93 --- /dev/null +++ b/src/devices/pic/xml_data/16F916.xml @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F917.xml b/src/devices/pic/xml_data/16F917.xml new file mode 100644 index 0000000..9e17dcc --- /dev/null +++ b/src/devices/pic/xml_data/16F917.xml @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16F946.xml b/src/devices/pic/xml_data/16F946.xml new file mode 100644 index 0000000..53df522 --- /dev/null +++ b/src/devices/pic/xml_data/16F946.xml @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/16HV540.xml b/src/devices/pic/xml_data/16HV540.xml new file mode 100644 index 0000000..439aa82 --- /dev/null +++ b/src/devices/pic/xml_data/16HV540.xml @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/17C42.xml b/src/devices/pic/xml_data/17C42.xml new file mode 100644 index 0000000..e072c94 --- /dev/null +++ b/src/devices/pic/xml_data/17C42.xml @@ -0,0 +1,192 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/17C42A.xml b/src/devices/pic/xml_data/17C42A.xml new file mode 100644 index 0000000..58c59b3 --- /dev/null +++ b/src/devices/pic/xml_data/17C42A.xml @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/17C43.xml b/src/devices/pic/xml_data/17C43.xml new file mode 100644 index 0000000..4c91f40 --- /dev/null +++ b/src/devices/pic/xml_data/17C43.xml @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/17C44.xml b/src/devices/pic/xml_data/17C44.xml new file mode 100644 index 0000000..da4be7b --- /dev/null +++ b/src/devices/pic/xml_data/17C44.xml @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/17C752.xml b/src/devices/pic/xml_data/17C752.xml new file mode 100644 index 0000000..20f798f --- /dev/null +++ b/src/devices/pic/xml_data/17C752.xml @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/17C756.xml b/src/devices/pic/xml_data/17C756.xml new file mode 100644 index 0000000..a5df4c4 --- /dev/null +++ b/src/devices/pic/xml_data/17C756.xml @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/17C756A.xml b/src/devices/pic/xml_data/17C756A.xml new file mode 100644 index 0000000..f20ee31 --- /dev/null +++ b/src/devices/pic/xml_data/17C756A.xml @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/17C762.xml b/src/devices/pic/xml_data/17C762.xml new file mode 100644 index 0000000..10e3a86 --- /dev/null +++ b/src/devices/pic/xml_data/17C762.xml @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/17C766.xml b/src/devices/pic/xml_data/17C766.xml new file mode 100644 index 0000000..0d2559d --- /dev/null +++ b/src/devices/pic/xml_data/17C766.xml @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/17CR42.xml b/src/devices/pic/xml_data/17CR42.xml new file mode 100644 index 0000000..b691cd8 --- /dev/null +++ b/src/devices/pic/xml_data/17CR42.xml @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/17CR43.xml b/src/devices/pic/xml_data/17CR43.xml new file mode 100644 index 0000000..13c1f2c --- /dev/null +++ b/src/devices/pic/xml_data/17CR43.xml @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18C242.xml b/src/devices/pic/xml_data/18C242.xml new file mode 100644 index 0000000..798c478 --- /dev/null +++ b/src/devices/pic/xml_data/18C242.xml @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18C252.xml b/src/devices/pic/xml_data/18C252.xml new file mode 100644 index 0000000..81f370b --- /dev/null +++ b/src/devices/pic/xml_data/18C252.xml @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18C442.xml b/src/devices/pic/xml_data/18C442.xml new file mode 100644 index 0000000..419ee29 --- /dev/null +++ b/src/devices/pic/xml_data/18C442.xml @@ -0,0 +1,252 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18C452.xml b/src/devices/pic/xml_data/18C452.xml new file mode 100644 index 0000000..73e3610 --- /dev/null +++ b/src/devices/pic/xml_data/18C452.xml @@ -0,0 +1,252 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18C601.xml b/src/devices/pic/xml_data/18C601.xml new file mode 100644 index 0000000..6d41b1c --- /dev/null +++ b/src/devices/pic/xml_data/18C601.xml @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18C658.xml b/src/devices/pic/xml_data/18C658.xml new file mode 100644 index 0000000..9ca140c --- /dev/null +++ b/src/devices/pic/xml_data/18C658.xml @@ -0,0 +1,248 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18C801.xml b/src/devices/pic/xml_data/18C801.xml new file mode 100644 index 0000000..3e067ad --- /dev/null +++ b/src/devices/pic/xml_data/18C801.xml @@ -0,0 +1,257 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18C858.xml b/src/devices/pic/xml_data/18C858.xml new file mode 100644 index 0000000..7ce8087 --- /dev/null +++ b/src/devices/pic/xml_data/18C858.xml @@ -0,0 +1,280 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F1220.xml b/src/devices/pic/xml_data/18F1220.xml new file mode 100644 index 0000000..e46f7f0 --- /dev/null +++ b/src/devices/pic/xml_data/18F1220.xml @@ -0,0 +1,279 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F1230.xml b/src/devices/pic/xml_data/18F1230.xml new file mode 100644 index 0000000..043687a --- /dev/null +++ b/src/devices/pic/xml_data/18F1230.xml @@ -0,0 +1,311 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F1320.xml b/src/devices/pic/xml_data/18F1320.xml new file mode 100644 index 0000000..d4dd214 --- /dev/null +++ b/src/devices/pic/xml_data/18F1320.xml @@ -0,0 +1,280 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F1330.xml b/src/devices/pic/xml_data/18F1330.xml new file mode 100644 index 0000000..14130ce --- /dev/null +++ b/src/devices/pic/xml_data/18F1330.xml @@ -0,0 +1,313 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F2220.xml b/src/devices/pic/xml_data/18F2220.xml new file mode 100644 index 0000000..43f6fbc --- /dev/null +++ b/src/devices/pic/xml_data/18F2220.xml @@ -0,0 +1,244 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F2221.xml b/src/devices/pic/xml_data/18F2221.xml new file mode 100644 index 0000000..f2a58d6 --- /dev/null +++ b/src/devices/pic/xml_data/18F2221.xml @@ -0,0 +1,281 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F2320.xml b/src/devices/pic/xml_data/18F2320.xml new file mode 100644 index 0000000..80e8250 --- /dev/null +++ b/src/devices/pic/xml_data/18F2320.xml @@ -0,0 +1,271 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F2321.xml b/src/devices/pic/xml_data/18F2321.xml new file mode 100644 index 0000000..a016fc7 --- /dev/null +++ b/src/devices/pic/xml_data/18F2321.xml @@ -0,0 +1,282 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F2331.xml b/src/devices/pic/xml_data/18F2331.xml new file mode 100644 index 0000000..46a8872 --- /dev/null +++ b/src/devices/pic/xml_data/18F2331.xml @@ -0,0 +1,256 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F2410.xml b/src/devices/pic/xml_data/18F2410.xml new file mode 100644 index 0000000..15d6179 --- /dev/null +++ b/src/devices/pic/xml_data/18F2410.xml @@ -0,0 +1,268 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F242.xml b/src/devices/pic/xml_data/18F242.xml new file mode 100644 index 0000000..d09dd83 --- /dev/null +++ b/src/devices/pic/xml_data/18F242.xml @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F2420.xml b/src/devices/pic/xml_data/18F2420.xml new file mode 100644 index 0000000..aba9ace --- /dev/null +++ b/src/devices/pic/xml_data/18F2420.xml @@ -0,0 +1,277 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F2423.xml b/src/devices/pic/xml_data/18F2423.xml new file mode 100644 index 0000000..0905f18 --- /dev/null +++ b/src/devices/pic/xml_data/18F2423.xml @@ -0,0 +1,274 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F2431.xml b/src/devices/pic/xml_data/18F2431.xml new file mode 100644 index 0000000..f898f99 --- /dev/null +++ b/src/devices/pic/xml_data/18F2431.xml @@ -0,0 +1,257 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F2439.xml b/src/devices/pic/xml_data/18F2439.xml new file mode 100644 index 0000000..ad389e3 --- /dev/null +++ b/src/devices/pic/xml_data/18F2439.xml @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F2450.xml b/src/devices/pic/xml_data/18F2450.xml new file mode 100644 index 0000000..2388a92 --- /dev/null +++ b/src/devices/pic/xml_data/18F2450.xml @@ -0,0 +1,299 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F2455.xml b/src/devices/pic/xml_data/18F2455.xml new file mode 100644 index 0000000..7097218 --- /dev/null +++ b/src/devices/pic/xml_data/18F2455.xml @@ -0,0 +1,288 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F248.xml b/src/devices/pic/xml_data/18F248.xml new file mode 100644 index 0000000..973ba90 --- /dev/null +++ b/src/devices/pic/xml_data/18F248.xml @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F2480.xml b/src/devices/pic/xml_data/18F2480.xml new file mode 100644 index 0000000..7f8929b --- /dev/null +++ b/src/devices/pic/xml_data/18F2480.xml @@ -0,0 +1,283 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F24J10.xml b/src/devices/pic/xml_data/18F24J10.xml new file mode 100644 index 0000000..c4ae257 --- /dev/null +++ b/src/devices/pic/xml_data/18F24J10.xml @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F2510.xml b/src/devices/pic/xml_data/18F2510.xml new file mode 100644 index 0000000..1950de1 --- /dev/null +++ b/src/devices/pic/xml_data/18F2510.xml @@ -0,0 +1,298 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F2515.xml b/src/devices/pic/xml_data/18F2515.xml new file mode 100644 index 0000000..89960ae --- /dev/null +++ b/src/devices/pic/xml_data/18F2515.xml @@ -0,0 +1,255 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F252.xml b/src/devices/pic/xml_data/18F252.xml new file mode 100644 index 0000000..b1d4153 --- /dev/null +++ b/src/devices/pic/xml_data/18F252.xml @@ -0,0 +1,246 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F2520.xml b/src/devices/pic/xml_data/18F2520.xml new file mode 100644 index 0000000..3c77df0 --- /dev/null +++ b/src/devices/pic/xml_data/18F2520.xml @@ -0,0 +1,307 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F2523.xml b/src/devices/pic/xml_data/18F2523.xml new file mode 100644 index 0000000..6a92c8d --- /dev/null +++ b/src/devices/pic/xml_data/18F2523.xml @@ -0,0 +1,298 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F2525.xml b/src/devices/pic/xml_data/18F2525.xml new file mode 100644 index 0000000..2ff5bc7 --- /dev/null +++ b/src/devices/pic/xml_data/18F2525.xml @@ -0,0 +1,264 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F2539.xml b/src/devices/pic/xml_data/18F2539.xml new file mode 100644 index 0000000..0f4a17a --- /dev/null +++ b/src/devices/pic/xml_data/18F2539.xml @@ -0,0 +1,222 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F2550.xml b/src/devices/pic/xml_data/18F2550.xml new file mode 100644 index 0000000..21ab9ae --- /dev/null +++ b/src/devices/pic/xml_data/18F2550.xml @@ -0,0 +1,292 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F258.xml b/src/devices/pic/xml_data/18F258.xml new file mode 100644 index 0000000..bb27ca5 --- /dev/null +++ b/src/devices/pic/xml_data/18F258.xml @@ -0,0 +1,241 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F2580.xml b/src/devices/pic/xml_data/18F2580.xml new file mode 100644 index 0000000..6721af5 --- /dev/null +++ b/src/devices/pic/xml_data/18F2580.xml @@ -0,0 +1,307 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F2585.xml b/src/devices/pic/xml_data/18F2585.xml new file mode 100644 index 0000000..12b38f1 --- /dev/null +++ b/src/devices/pic/xml_data/18F2585.xml @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F25J10.xml b/src/devices/pic/xml_data/18F25J10.xml new file mode 100644 index 0000000..57f37d4 --- /dev/null +++ b/src/devices/pic/xml_data/18F25J10.xml @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F2610.xml b/src/devices/pic/xml_data/18F2610.xml new file mode 100644 index 0000000..e38c6d2 --- /dev/null +++ b/src/devices/pic/xml_data/18F2610.xml @@ -0,0 +1,267 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F2620.xml b/src/devices/pic/xml_data/18F2620.xml new file mode 100644 index 0000000..7c25f21 --- /dev/null +++ b/src/devices/pic/xml_data/18F2620.xml @@ -0,0 +1,265 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F2680.xml b/src/devices/pic/xml_data/18F2680.xml new file mode 100644 index 0000000..2dcd013 --- /dev/null +++ b/src/devices/pic/xml_data/18F2680.xml @@ -0,0 +1,278 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F2682.xml b/src/devices/pic/xml_data/18F2682.xml new file mode 100644 index 0000000..8c13b2d --- /dev/null +++ b/src/devices/pic/xml_data/18F2682.xml @@ -0,0 +1,284 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F2685.xml b/src/devices/pic/xml_data/18F2685.xml new file mode 100644 index 0000000..bca6818 --- /dev/null +++ b/src/devices/pic/xml_data/18F2685.xml @@ -0,0 +1,296 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F4220.xml b/src/devices/pic/xml_data/18F4220.xml new file mode 100644 index 0000000..f1c19c7 --- /dev/null +++ b/src/devices/pic/xml_data/18F4220.xml @@ -0,0 +1,351 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F4221.xml b/src/devices/pic/xml_data/18F4221.xml new file mode 100644 index 0000000..d4a7e11 --- /dev/null +++ b/src/devices/pic/xml_data/18F4221.xml @@ -0,0 +1,368 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F4320.xml b/src/devices/pic/xml_data/18F4320.xml new file mode 100644 index 0000000..734bb11 --- /dev/null +++ b/src/devices/pic/xml_data/18F4320.xml @@ -0,0 +1,377 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F4321.xml b/src/devices/pic/xml_data/18F4321.xml new file mode 100644 index 0000000..6bdd265 --- /dev/null +++ b/src/devices/pic/xml_data/18F4321.xml @@ -0,0 +1,368 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F4331.xml b/src/devices/pic/xml_data/18F4331.xml new file mode 100644 index 0000000..a22e667 --- /dev/null +++ b/src/devices/pic/xml_data/18F4331.xml @@ -0,0 +1,384 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F4410.xml b/src/devices/pic/xml_data/18F4410.xml new file mode 100644 index 0000000..8ca9b17 --- /dev/null +++ b/src/devices/pic/xml_data/18F4410.xml @@ -0,0 +1,349 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F442.xml b/src/devices/pic/xml_data/18F442.xml new file mode 100644 index 0000000..61f6a63 --- /dev/null +++ b/src/devices/pic/xml_data/18F442.xml @@ -0,0 +1,327 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F4420.xml b/src/devices/pic/xml_data/18F4420.xml new file mode 100644 index 0000000..83a0022 --- /dev/null +++ b/src/devices/pic/xml_data/18F4420.xml @@ -0,0 +1,358 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F4423.xml b/src/devices/pic/xml_data/18F4423.xml new file mode 100644 index 0000000..1760494 --- /dev/null +++ b/src/devices/pic/xml_data/18F4423.xml @@ -0,0 +1,349 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F4431.xml b/src/devices/pic/xml_data/18F4431.xml new file mode 100644 index 0000000..c19b48a --- /dev/null +++ b/src/devices/pic/xml_data/18F4431.xml @@ -0,0 +1,409 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F4439.xml b/src/devices/pic/xml_data/18F4439.xml new file mode 100644 index 0000000..3441809 --- /dev/null +++ b/src/devices/pic/xml_data/18F4439.xml @@ -0,0 +1,316 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F4450.xml b/src/devices/pic/xml_data/18F4450.xml new file mode 100644 index 0000000..e634df1 --- /dev/null +++ b/src/devices/pic/xml_data/18F4450.xml @@ -0,0 +1,378 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F4455.xml b/src/devices/pic/xml_data/18F4455.xml new file mode 100644 index 0000000..282decb --- /dev/null +++ b/src/devices/pic/xml_data/18F4455.xml @@ -0,0 +1,398 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F448.xml b/src/devices/pic/xml_data/18F448.xml new file mode 100644 index 0000000..40de124 --- /dev/null +++ b/src/devices/pic/xml_data/18F448.xml @@ -0,0 +1,322 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F4480.xml b/src/devices/pic/xml_data/18F4480.xml new file mode 100644 index 0000000..b9a87da --- /dev/null +++ b/src/devices/pic/xml_data/18F4480.xml @@ -0,0 +1,358 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F44J10.xml b/src/devices/pic/xml_data/18F44J10.xml new file mode 100644 index 0000000..ddf2019 --- /dev/null +++ b/src/devices/pic/xml_data/18F44J10.xml @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F4510.xml b/src/devices/pic/xml_data/18F4510.xml new file mode 100644 index 0000000..b038b39 --- /dev/null +++ b/src/devices/pic/xml_data/18F4510.xml @@ -0,0 +1,373 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F4515.xml b/src/devices/pic/xml_data/18F4515.xml new file mode 100644 index 0000000..4325432 --- /dev/null +++ b/src/devices/pic/xml_data/18F4515.xml @@ -0,0 +1,361 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F452.xml b/src/devices/pic/xml_data/18F452.xml new file mode 100644 index 0000000..12ad5ce --- /dev/null +++ b/src/devices/pic/xml_data/18F452.xml @@ -0,0 +1,352 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F4520.xml b/src/devices/pic/xml_data/18F4520.xml new file mode 100644 index 0000000..a1a1e75 --- /dev/null +++ b/src/devices/pic/xml_data/18F4520.xml @@ -0,0 +1,382 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F4523.xml b/src/devices/pic/xml_data/18F4523.xml new file mode 100644 index 0000000..29b2583 --- /dev/null +++ b/src/devices/pic/xml_data/18F4523.xml @@ -0,0 +1,379 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F4525.xml b/src/devices/pic/xml_data/18F4525.xml new file mode 100644 index 0000000..f37d90b --- /dev/null +++ b/src/devices/pic/xml_data/18F4525.xml @@ -0,0 +1,370 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F4539.xml b/src/devices/pic/xml_data/18F4539.xml new file mode 100644 index 0000000..71a1f4c --- /dev/null +++ b/src/devices/pic/xml_data/18F4539.xml @@ -0,0 +1,328 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F4550.xml b/src/devices/pic/xml_data/18F4550.xml new file mode 100644 index 0000000..b0e26c8 --- /dev/null +++ b/src/devices/pic/xml_data/18F4550.xml @@ -0,0 +1,402 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F458.xml b/src/devices/pic/xml_data/18F458.xml new file mode 100644 index 0000000..33069dd --- /dev/null +++ b/src/devices/pic/xml_data/18F458.xml @@ -0,0 +1,347 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F4580.xml b/src/devices/pic/xml_data/18F4580.xml new file mode 100644 index 0000000..e6e105a --- /dev/null +++ b/src/devices/pic/xml_data/18F4580.xml @@ -0,0 +1,382 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F4585.xml b/src/devices/pic/xml_data/18F4585.xml new file mode 100644 index 0000000..fb438b8 --- /dev/null +++ b/src/devices/pic/xml_data/18F4585.xml @@ -0,0 +1,372 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F45J10.xml b/src/devices/pic/xml_data/18F45J10.xml new file mode 100644 index 0000000..af2c752 --- /dev/null +++ b/src/devices/pic/xml_data/18F45J10.xml @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F4610.xml b/src/devices/pic/xml_data/18F4610.xml new file mode 100644 index 0000000..d105cdb --- /dev/null +++ b/src/devices/pic/xml_data/18F4610.xml @@ -0,0 +1,373 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F4620.xml b/src/devices/pic/xml_data/18F4620.xml new file mode 100644 index 0000000..5964590 --- /dev/null +++ b/src/devices/pic/xml_data/18F4620.xml @@ -0,0 +1,371 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F4680.xml b/src/devices/pic/xml_data/18F4680.xml new file mode 100644 index 0000000..f5ef137 --- /dev/null +++ b/src/devices/pic/xml_data/18F4680.xml @@ -0,0 +1,384 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F4682.xml b/src/devices/pic/xml_data/18F4682.xml new file mode 100644 index 0000000..19b387b --- /dev/null +++ b/src/devices/pic/xml_data/18F4682.xml @@ -0,0 +1,390 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F4685.xml b/src/devices/pic/xml_data/18F4685.xml new file mode 100644 index 0000000..7b68ee2 --- /dev/null +++ b/src/devices/pic/xml_data/18F4685.xml @@ -0,0 +1,402 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F6310.xml b/src/devices/pic/xml_data/18F6310.xml new file mode 100644 index 0000000..9bdbfb7 --- /dev/null +++ b/src/devices/pic/xml_data/18F6310.xml @@ -0,0 +1,250 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F6390.xml b/src/devices/pic/xml_data/18F6390.xml new file mode 100644 index 0000000..02f2498 --- /dev/null +++ b/src/devices/pic/xml_data/18F6390.xml @@ -0,0 +1,250 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F6393.xml b/src/devices/pic/xml_data/18F6393.xml new file mode 100644 index 0000000..bc778f4 --- /dev/null +++ b/src/devices/pic/xml_data/18F6393.xml @@ -0,0 +1,253 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F63J11.xml b/src/devices/pic/xml_data/18F63J11.xml new file mode 100644 index 0000000..37273bc --- /dev/null +++ b/src/devices/pic/xml_data/18F63J11.xml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F63J90.xml b/src/devices/pic/xml_data/18F63J90.xml new file mode 100644 index 0000000..ef1310c --- /dev/null +++ b/src/devices/pic/xml_data/18F63J90.xml @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F6410.xml b/src/devices/pic/xml_data/18F6410.xml new file mode 100644 index 0000000..c270208 --- /dev/null +++ b/src/devices/pic/xml_data/18F6410.xml @@ -0,0 +1,250 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F6490.xml b/src/devices/pic/xml_data/18F6490.xml new file mode 100644 index 0000000..1727686 --- /dev/null +++ b/src/devices/pic/xml_data/18F6490.xml @@ -0,0 +1,250 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F6493.xml b/src/devices/pic/xml_data/18F6493.xml new file mode 100644 index 0000000..89f409d --- /dev/null +++ b/src/devices/pic/xml_data/18F6493.xml @@ -0,0 +1,253 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F64J11.xml b/src/devices/pic/xml_data/18F64J11.xml new file mode 100644 index 0000000..fd126a0 --- /dev/null +++ b/src/devices/pic/xml_data/18F64J11.xml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F64J90.xml b/src/devices/pic/xml_data/18F64J90.xml new file mode 100644 index 0000000..fedf592 --- /dev/null +++ b/src/devices/pic/xml_data/18F64J90.xml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F6520.xml b/src/devices/pic/xml_data/18F6520.xml new file mode 100644 index 0000000..a022295 --- /dev/null +++ b/src/devices/pic/xml_data/18F6520.xml @@ -0,0 +1,283 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F6525.xml b/src/devices/pic/xml_data/18F6525.xml new file mode 100644 index 0000000..953e12a --- /dev/null +++ b/src/devices/pic/xml_data/18F6525.xml @@ -0,0 +1,287 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F6527.xml b/src/devices/pic/xml_data/18F6527.xml new file mode 100644 index 0000000..04a2bf1 --- /dev/null +++ b/src/devices/pic/xml_data/18F6527.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F6585.xml b/src/devices/pic/xml_data/18F6585.xml new file mode 100644 index 0000000..0bf9bab --- /dev/null +++ b/src/devices/pic/xml_data/18F6585.xml @@ -0,0 +1,350 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F65J10.xml b/src/devices/pic/xml_data/18F65J10.xml new file mode 100644 index 0000000..a67fe87 --- /dev/null +++ b/src/devices/pic/xml_data/18F65J10.xml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F65J11.xml b/src/devices/pic/xml_data/18F65J11.xml new file mode 100644 index 0000000..2ef5b3d --- /dev/null +++ b/src/devices/pic/xml_data/18F65J11.xml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F65J15.xml b/src/devices/pic/xml_data/18F65J15.xml new file mode 100644 index 0000000..f5f310a --- /dev/null +++ b/src/devices/pic/xml_data/18F65J15.xml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F65J50.xml b/src/devices/pic/xml_data/18F65J50.xml new file mode 100644 index 0000000..d0cdd2b --- /dev/null +++ b/src/devices/pic/xml_data/18F65J50.xml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F65J90.xml b/src/devices/pic/xml_data/18F65J90.xml new file mode 100644 index 0000000..91997da --- /dev/null +++ b/src/devices/pic/xml_data/18F65J90.xml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F6620.xml b/src/devices/pic/xml_data/18F6620.xml new file mode 100644 index 0000000..e88ee06 --- /dev/null +++ b/src/devices/pic/xml_data/18F6620.xml @@ -0,0 +1,285 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F6621.xml b/src/devices/pic/xml_data/18F6621.xml new file mode 100644 index 0000000..664de3f --- /dev/null +++ b/src/devices/pic/xml_data/18F6621.xml @@ -0,0 +1,299 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F6622.xml b/src/devices/pic/xml_data/18F6622.xml new file mode 100644 index 0000000..6fb81d7 --- /dev/null +++ b/src/devices/pic/xml_data/18F6622.xml @@ -0,0 +1,314 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F6627.xml b/src/devices/pic/xml_data/18F6627.xml new file mode 100644 index 0000000..74248c6 --- /dev/null +++ b/src/devices/pic/xml_data/18F6627.xml @@ -0,0 +1,332 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F6680.xml b/src/devices/pic/xml_data/18F6680.xml new file mode 100644 index 0000000..d0a9922 --- /dev/null +++ b/src/devices/pic/xml_data/18F6680.xml @@ -0,0 +1,362 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F66J10.xml b/src/devices/pic/xml_data/18F66J10.xml new file mode 100644 index 0000000..7bb9aa7 --- /dev/null +++ b/src/devices/pic/xml_data/18F66J10.xml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F66J11.xml b/src/devices/pic/xml_data/18F66J11.xml new file mode 100644 index 0000000..8fd1314 --- /dev/null +++ b/src/devices/pic/xml_data/18F66J11.xml @@ -0,0 +1,190 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F66J15.xml b/src/devices/pic/xml_data/18F66J15.xml new file mode 100644 index 0000000..c1c5c95 --- /dev/null +++ b/src/devices/pic/xml_data/18F66J15.xml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F66J16.xml b/src/devices/pic/xml_data/18F66J16.xml new file mode 100644 index 0000000..cf84f44 --- /dev/null +++ b/src/devices/pic/xml_data/18F66J16.xml @@ -0,0 +1,189 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F66J50.xml b/src/devices/pic/xml_data/18F66J50.xml new file mode 100644 index 0000000..34dbe21 --- /dev/null +++ b/src/devices/pic/xml_data/18F66J50.xml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F66J55.xml b/src/devices/pic/xml_data/18F66J55.xml new file mode 100644 index 0000000..7e95978 --- /dev/null +++ b/src/devices/pic/xml_data/18F66J55.xml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F66J60.xml b/src/devices/pic/xml_data/18F66J60.xml new file mode 100644 index 0000000..e4ac5ea --- /dev/null +++ b/src/devices/pic/xml_data/18F66J60.xml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F66J65.xml b/src/devices/pic/xml_data/18F66J65.xml new file mode 100644 index 0000000..8431ec8 --- /dev/null +++ b/src/devices/pic/xml_data/18F66J65.xml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F6720.xml b/src/devices/pic/xml_data/18F6720.xml new file mode 100644 index 0000000..c023b5e --- /dev/null +++ b/src/devices/pic/xml_data/18F6720.xml @@ -0,0 +1,330 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F6722.xml b/src/devices/pic/xml_data/18F6722.xml new file mode 100644 index 0000000..fb30985 --- /dev/null +++ b/src/devices/pic/xml_data/18F6722.xml @@ -0,0 +1,356 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F67J10.xml b/src/devices/pic/xml_data/18F67J10.xml new file mode 100644 index 0000000..78223c3 --- /dev/null +++ b/src/devices/pic/xml_data/18F67J10.xml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F67J11.xml b/src/devices/pic/xml_data/18F67J11.xml new file mode 100644 index 0000000..d13e7dc --- /dev/null +++ b/src/devices/pic/xml_data/18F67J11.xml @@ -0,0 +1,190 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F67J50.xml b/src/devices/pic/xml_data/18F67J50.xml new file mode 100644 index 0000000..91eade3 --- /dev/null +++ b/src/devices/pic/xml_data/18F67J50.xml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F67J60.xml b/src/devices/pic/xml_data/18F67J60.xml new file mode 100644 index 0000000..29922db --- /dev/null +++ b/src/devices/pic/xml_data/18F67J60.xml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F8310.xml b/src/devices/pic/xml_data/18F8310.xml new file mode 100644 index 0000000..1fe084d --- /dev/null +++ b/src/devices/pic/xml_data/18F8310.xml @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F8390.xml b/src/devices/pic/xml_data/18F8390.xml new file mode 100644 index 0000000..4dbff0c --- /dev/null +++ b/src/devices/pic/xml_data/18F8390.xml @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F8393.xml b/src/devices/pic/xml_data/18F8393.xml new file mode 100644 index 0000000..ce846db --- /dev/null +++ b/src/devices/pic/xml_data/18F8393.xml @@ -0,0 +1,254 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F83J11.xml b/src/devices/pic/xml_data/18F83J11.xml new file mode 100644 index 0000000..4a9d249 --- /dev/null +++ b/src/devices/pic/xml_data/18F83J11.xml @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F83J90.xml b/src/devices/pic/xml_data/18F83J90.xml new file mode 100644 index 0000000..8e10c27 --- /dev/null +++ b/src/devices/pic/xml_data/18F83J90.xml @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F8410.xml b/src/devices/pic/xml_data/18F8410.xml new file mode 100644 index 0000000..b5c49cd --- /dev/null +++ b/src/devices/pic/xml_data/18F8410.xml @@ -0,0 +1,251 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F8490.xml b/src/devices/pic/xml_data/18F8490.xml new file mode 100644 index 0000000..3871a60 --- /dev/null +++ b/src/devices/pic/xml_data/18F8490.xml @@ -0,0 +1,251 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F8493.xml b/src/devices/pic/xml_data/18F8493.xml new file mode 100644 index 0000000..4e8bc52 --- /dev/null +++ b/src/devices/pic/xml_data/18F8493.xml @@ -0,0 +1,254 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F84J11.xml b/src/devices/pic/xml_data/18F84J11.xml new file mode 100644 index 0000000..9c69d2b --- /dev/null +++ b/src/devices/pic/xml_data/18F84J11.xml @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F84J90.xml b/src/devices/pic/xml_data/18F84J90.xml new file mode 100644 index 0000000..59711f3 --- /dev/null +++ b/src/devices/pic/xml_data/18F84J90.xml @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F8520.xml b/src/devices/pic/xml_data/18F8520.xml new file mode 100644 index 0000000..6bc1aae --- /dev/null +++ b/src/devices/pic/xml_data/18F8520.xml @@ -0,0 +1,311 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F8525.xml b/src/devices/pic/xml_data/18F8525.xml new file mode 100644 index 0000000..e7b5219 --- /dev/null +++ b/src/devices/pic/xml_data/18F8525.xml @@ -0,0 +1,312 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F8527.xml b/src/devices/pic/xml_data/18F8527.xml new file mode 100644 index 0000000..62c01d4 --- /dev/null +++ b/src/devices/pic/xml_data/18F8527.xml @@ -0,0 +1,346 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F8585.xml b/src/devices/pic/xml_data/18F8585.xml new file mode 100644 index 0000000..08367ab --- /dev/null +++ b/src/devices/pic/xml_data/18F8585.xml @@ -0,0 +1,312 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F85J10.xml b/src/devices/pic/xml_data/18F85J10.xml new file mode 100644 index 0000000..99b998c --- /dev/null +++ b/src/devices/pic/xml_data/18F85J10.xml @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F85J11.xml b/src/devices/pic/xml_data/18F85J11.xml new file mode 100644 index 0000000..91b4cc2 --- /dev/null +++ b/src/devices/pic/xml_data/18F85J11.xml @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F85J15.xml b/src/devices/pic/xml_data/18F85J15.xml new file mode 100644 index 0000000..c2445ab --- /dev/null +++ b/src/devices/pic/xml_data/18F85J15.xml @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F85J50.xml b/src/devices/pic/xml_data/18F85J50.xml new file mode 100644 index 0000000..dee0637 --- /dev/null +++ b/src/devices/pic/xml_data/18F85J50.xml @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F85J90.xml b/src/devices/pic/xml_data/18F85J90.xml new file mode 100644 index 0000000..61e7571 --- /dev/null +++ b/src/devices/pic/xml_data/18F85J90.xml @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F8620.xml b/src/devices/pic/xml_data/18F8620.xml new file mode 100644 index 0000000..8503556 --- /dev/null +++ b/src/devices/pic/xml_data/18F8620.xml @@ -0,0 +1,311 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F8621.xml b/src/devices/pic/xml_data/18F8621.xml new file mode 100644 index 0000000..e5689ae --- /dev/null +++ b/src/devices/pic/xml_data/18F8621.xml @@ -0,0 +1,324 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F8622.xml b/src/devices/pic/xml_data/18F8622.xml new file mode 100644 index 0000000..fe29be9 --- /dev/null +++ b/src/devices/pic/xml_data/18F8622.xml @@ -0,0 +1,358 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F8627.xml b/src/devices/pic/xml_data/18F8627.xml new file mode 100644 index 0000000..2b7f70b --- /dev/null +++ b/src/devices/pic/xml_data/18F8627.xml @@ -0,0 +1,376 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F8680.xml b/src/devices/pic/xml_data/18F8680.xml new file mode 100644 index 0000000..97ec3c0 --- /dev/null +++ b/src/devices/pic/xml_data/18F8680.xml @@ -0,0 +1,324 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F86J10.xml b/src/devices/pic/xml_data/18F86J10.xml new file mode 100644 index 0000000..6cc1ec1 --- /dev/null +++ b/src/devices/pic/xml_data/18F86J10.xml @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F86J11.xml b/src/devices/pic/xml_data/18F86J11.xml new file mode 100644 index 0000000..05e065e --- /dev/null +++ b/src/devices/pic/xml_data/18F86J11.xml @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F86J15.xml b/src/devices/pic/xml_data/18F86J15.xml new file mode 100644 index 0000000..bcebf10 --- /dev/null +++ b/src/devices/pic/xml_data/18F86J15.xml @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F86J16.xml b/src/devices/pic/xml_data/18F86J16.xml new file mode 100644 index 0000000..b06b858 --- /dev/null +++ b/src/devices/pic/xml_data/18F86J16.xml @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F86J50.xml b/src/devices/pic/xml_data/18F86J50.xml new file mode 100644 index 0000000..fa67e08 --- /dev/null +++ b/src/devices/pic/xml_data/18F86J50.xml @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F86J55.xml b/src/devices/pic/xml_data/18F86J55.xml new file mode 100644 index 0000000..9b29823 --- /dev/null +++ b/src/devices/pic/xml_data/18F86J55.xml @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F86J60.xml b/src/devices/pic/xml_data/18F86J60.xml new file mode 100644 index 0000000..42f3d20 --- /dev/null +++ b/src/devices/pic/xml_data/18F86J60.xml @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F86J65.xml b/src/devices/pic/xml_data/18F86J65.xml new file mode 100644 index 0000000..c2cdf41 --- /dev/null +++ b/src/devices/pic/xml_data/18F86J65.xml @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F8720.xml b/src/devices/pic/xml_data/18F8720.xml new file mode 100644 index 0000000..f634b25 --- /dev/null +++ b/src/devices/pic/xml_data/18F8720.xml @@ -0,0 +1,359 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F8722.xml b/src/devices/pic/xml_data/18F8722.xml new file mode 100644 index 0000000..3db0bbd --- /dev/null +++ b/src/devices/pic/xml_data/18F8722.xml @@ -0,0 +1,400 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F87J10.xml b/src/devices/pic/xml_data/18F87J10.xml new file mode 100644 index 0000000..bc21af2 --- /dev/null +++ b/src/devices/pic/xml_data/18F87J10.xml @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F87J11.xml b/src/devices/pic/xml_data/18F87J11.xml new file mode 100644 index 0000000..d3c84fb --- /dev/null +++ b/src/devices/pic/xml_data/18F87J11.xml @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F87J50.xml b/src/devices/pic/xml_data/18F87J50.xml new file mode 100644 index 0000000..1749435 --- /dev/null +++ b/src/devices/pic/xml_data/18F87J50.xml @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F87J60.xml b/src/devices/pic/xml_data/18F87J60.xml new file mode 100644 index 0000000..d101ed3 --- /dev/null +++ b/src/devices/pic/xml_data/18F87J60.xml @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F96J60.xml b/src/devices/pic/xml_data/18F96J60.xml new file mode 100644 index 0000000..655b586 --- /dev/null +++ b/src/devices/pic/xml_data/18F96J60.xml @@ -0,0 +1,211 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F96J65.xml b/src/devices/pic/xml_data/18F96J65.xml new file mode 100644 index 0000000..a61bb94 --- /dev/null +++ b/src/devices/pic/xml_data/18F96J65.xml @@ -0,0 +1,211 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/18F97J60.xml b/src/devices/pic/xml_data/18F97J60.xml new file mode 100644 index 0000000..ce570ba --- /dev/null +++ b/src/devices/pic/xml_data/18F97J60.xml @@ -0,0 +1,211 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/24FJ128GA006.xml b/src/devices/pic/xml_data/24FJ128GA006.xml new file mode 100644 index 0000000..7f264b9 --- /dev/null +++ b/src/devices/pic/xml_data/24FJ128GA006.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/24FJ128GA008.xml b/src/devices/pic/xml_data/24FJ128GA008.xml new file mode 100644 index 0000000..b8d43d8 --- /dev/null +++ b/src/devices/pic/xml_data/24FJ128GA008.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/24FJ128GA010.xml b/src/devices/pic/xml_data/24FJ128GA010.xml new file mode 100644 index 0000000..d57c7ff --- /dev/null +++ b/src/devices/pic/xml_data/24FJ128GA010.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/24FJ64GA002.xml b/src/devices/pic/xml_data/24FJ64GA002.xml new file mode 100644 index 0000000..e051b07 --- /dev/null +++ b/src/devices/pic/xml_data/24FJ64GA002.xml @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/24FJ64GA004.xml b/src/devices/pic/xml_data/24FJ64GA004.xml new file mode 100644 index 0000000..c87748e --- /dev/null +++ b/src/devices/pic/xml_data/24FJ64GA004.xml @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/24FJ64GA006.xml b/src/devices/pic/xml_data/24FJ64GA006.xml new file mode 100644 index 0000000..6492f51 --- /dev/null +++ b/src/devices/pic/xml_data/24FJ64GA006.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/24FJ64GA008.xml b/src/devices/pic/xml_data/24FJ64GA008.xml new file mode 100644 index 0000000..2ead302 --- /dev/null +++ b/src/devices/pic/xml_data/24FJ64GA008.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/24FJ64GA010.xml b/src/devices/pic/xml_data/24FJ64GA010.xml new file mode 100644 index 0000000..627da04 --- /dev/null +++ b/src/devices/pic/xml_data/24FJ64GA010.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/24FJ96GA006.xml b/src/devices/pic/xml_data/24FJ96GA006.xml new file mode 100644 index 0000000..9f02be4 --- /dev/null +++ b/src/devices/pic/xml_data/24FJ96GA006.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/24FJ96GA008.xml b/src/devices/pic/xml_data/24FJ96GA008.xml new file mode 100644 index 0000000..eeba6d2 --- /dev/null +++ b/src/devices/pic/xml_data/24FJ96GA008.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/24FJ96GA010.xml b/src/devices/pic/xml_data/24FJ96GA010.xml new file mode 100644 index 0000000..700d288 --- /dev/null +++ b/src/devices/pic/xml_data/24FJ96GA010.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/24HJ128GP206.xml b/src/devices/pic/xml_data/24HJ128GP206.xml new file mode 100644 index 0000000..c065e99 --- /dev/null +++ b/src/devices/pic/xml_data/24HJ128GP206.xml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/24HJ128GP210.xml b/src/devices/pic/xml_data/24HJ128GP210.xml new file mode 100644 index 0000000..b0922d0 --- /dev/null +++ b/src/devices/pic/xml_data/24HJ128GP210.xml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/24HJ128GP306.xml b/src/devices/pic/xml_data/24HJ128GP306.xml new file mode 100644 index 0000000..97f23e1 --- /dev/null +++ b/src/devices/pic/xml_data/24HJ128GP306.xml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/24HJ128GP310.xml b/src/devices/pic/xml_data/24HJ128GP310.xml new file mode 100644 index 0000000..a600601 --- /dev/null +++ b/src/devices/pic/xml_data/24HJ128GP310.xml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/24HJ128GP506.xml b/src/devices/pic/xml_data/24HJ128GP506.xml new file mode 100644 index 0000000..ae2fd06 --- /dev/null +++ b/src/devices/pic/xml_data/24HJ128GP506.xml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/24HJ128GP510.xml b/src/devices/pic/xml_data/24HJ128GP510.xml new file mode 100644 index 0000000..7195e60 --- /dev/null +++ b/src/devices/pic/xml_data/24HJ128GP510.xml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/24HJ12GP201.xml b/src/devices/pic/xml_data/24HJ12GP201.xml new file mode 100644 index 0000000..b0c3357 --- /dev/null +++ b/src/devices/pic/xml_data/24HJ12GP201.xml @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/24HJ12GP202.xml b/src/devices/pic/xml_data/24HJ12GP202.xml new file mode 100644 index 0000000..60fdce8 --- /dev/null +++ b/src/devices/pic/xml_data/24HJ12GP202.xml @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/24HJ16GP304.xml b/src/devices/pic/xml_data/24HJ16GP304.xml new file mode 100644 index 0000000..f4d50d8 --- /dev/null +++ b/src/devices/pic/xml_data/24HJ16GP304.xml @@ -0,0 +1,180 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/24HJ256GP206.xml b/src/devices/pic/xml_data/24HJ256GP206.xml new file mode 100644 index 0000000..d977b29 --- /dev/null +++ b/src/devices/pic/xml_data/24HJ256GP206.xml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/24HJ256GP210.xml b/src/devices/pic/xml_data/24HJ256GP210.xml new file mode 100644 index 0000000..000bc00 --- /dev/null +++ b/src/devices/pic/xml_data/24HJ256GP210.xml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/24HJ256GP610.xml b/src/devices/pic/xml_data/24HJ256GP610.xml new file mode 100644 index 0000000..4c1e714 --- /dev/null +++ b/src/devices/pic/xml_data/24HJ256GP610.xml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/24HJ32GP202.xml b/src/devices/pic/xml_data/24HJ32GP202.xml new file mode 100644 index 0000000..d93607a --- /dev/null +++ b/src/devices/pic/xml_data/24HJ32GP202.xml @@ -0,0 +1,180 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/24HJ32GP204.xml b/src/devices/pic/xml_data/24HJ32GP204.xml new file mode 100644 index 0000000..5a9e126 --- /dev/null +++ b/src/devices/pic/xml_data/24HJ32GP204.xml @@ -0,0 +1,180 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/24HJ64GP206.xml b/src/devices/pic/xml_data/24HJ64GP206.xml new file mode 100644 index 0000000..a3266fa --- /dev/null +++ b/src/devices/pic/xml_data/24HJ64GP206.xml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/24HJ64GP210.xml b/src/devices/pic/xml_data/24HJ64GP210.xml new file mode 100644 index 0000000..630a12a --- /dev/null +++ b/src/devices/pic/xml_data/24HJ64GP210.xml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/24HJ64GP506.xml b/src/devices/pic/xml_data/24HJ64GP506.xml new file mode 100644 index 0000000..372c767 --- /dev/null +++ b/src/devices/pic/xml_data/24HJ64GP506.xml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/24HJ64GP510.xml b/src/devices/pic/xml_data/24HJ64GP510.xml new file mode 100644 index 0000000..8711793 --- /dev/null +++ b/src/devices/pic/xml_data/24HJ64GP510.xml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/30F1010.xml b/src/devices/pic/xml_data/30F1010.xml new file mode 100644 index 0000000..1d59008 --- /dev/null +++ b/src/devices/pic/xml_data/30F1010.xml @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/30F2010.xml b/src/devices/pic/xml_data/30F2010.xml new file mode 100644 index 0000000..f252785 --- /dev/null +++ b/src/devices/pic/xml_data/30F2010.xml @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/30F2011.xml b/src/devices/pic/xml_data/30F2011.xml new file mode 100644 index 0000000..a767855 --- /dev/null +++ b/src/devices/pic/xml_data/30F2011.xml @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/30F2012.xml b/src/devices/pic/xml_data/30F2012.xml new file mode 100644 index 0000000..6da9eb7 --- /dev/null +++ b/src/devices/pic/xml_data/30F2012.xml @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/30F2020.xml b/src/devices/pic/xml_data/30F2020.xml new file mode 100644 index 0000000..3aa30e9 --- /dev/null +++ b/src/devices/pic/xml_data/30F2020.xml @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/30F2023.xml b/src/devices/pic/xml_data/30F2023.xml new file mode 100644 index 0000000..8241600 --- /dev/null +++ b/src/devices/pic/xml_data/30F2023.xml @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/30F3010.xml b/src/devices/pic/xml_data/30F3010.xml new file mode 100644 index 0000000..1041c86 --- /dev/null +++ b/src/devices/pic/xml_data/30F3010.xml @@ -0,0 +1,242 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/30F3011.xml b/src/devices/pic/xml_data/30F3011.xml new file mode 100644 index 0000000..b092d8b --- /dev/null +++ b/src/devices/pic/xml_data/30F3011.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/30F3012.xml b/src/devices/pic/xml_data/30F3012.xml new file mode 100644 index 0000000..b87d96a --- /dev/null +++ b/src/devices/pic/xml_data/30F3012.xml @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/30F3013.xml b/src/devices/pic/xml_data/30F3013.xml new file mode 100644 index 0000000..702e415 --- /dev/null +++ b/src/devices/pic/xml_data/30F3013.xml @@ -0,0 +1,230 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/30F3014.xml b/src/devices/pic/xml_data/30F3014.xml new file mode 100644 index 0000000..13bd387 --- /dev/null +++ b/src/devices/pic/xml_data/30F3014.xml @@ -0,0 +1,289 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/30F4011.xml b/src/devices/pic/xml_data/30F4011.xml new file mode 100644 index 0000000..89791c2 --- /dev/null +++ b/src/devices/pic/xml_data/30F4011.xml @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/30F4012.xml b/src/devices/pic/xml_data/30F4012.xml new file mode 100644 index 0000000..e42b34c --- /dev/null +++ b/src/devices/pic/xml_data/30F4012.xml @@ -0,0 +1,246 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/30F4013.xml b/src/devices/pic/xml_data/30F4013.xml new file mode 100644 index 0000000..1732e6e --- /dev/null +++ b/src/devices/pic/xml_data/30F4013.xml @@ -0,0 +1,290 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/30F5011.xml b/src/devices/pic/xml_data/30F5011.xml new file mode 100644 index 0000000..a1f311d --- /dev/null +++ b/src/devices/pic/xml_data/30F5011.xml @@ -0,0 +1,276 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/30F5013.xml b/src/devices/pic/xml_data/30F5013.xml new file mode 100644 index 0000000..debd97f --- /dev/null +++ b/src/devices/pic/xml_data/30F5013.xml @@ -0,0 +1,292 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/30F5015.xml b/src/devices/pic/xml_data/30F5015.xml new file mode 100644 index 0000000..af7c20a --- /dev/null +++ b/src/devices/pic/xml_data/30F5015.xml @@ -0,0 +1,232 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/30F5016.xml b/src/devices/pic/xml_data/30F5016.xml new file mode 100644 index 0000000..aa2e7e1 --- /dev/null +++ b/src/devices/pic/xml_data/30F5016.xml @@ -0,0 +1,248 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/30F6010.xml b/src/devices/pic/xml_data/30F6010.xml new file mode 100644 index 0000000..8b26c7c --- /dev/null +++ b/src/devices/pic/xml_data/30F6010.xml @@ -0,0 +1,252 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/30F6010A.xml b/src/devices/pic/xml_data/30F6010A.xml new file mode 100644 index 0000000..2f5e976 --- /dev/null +++ b/src/devices/pic/xml_data/30F6010A.xml @@ -0,0 +1,308 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/30F6011.xml b/src/devices/pic/xml_data/30F6011.xml new file mode 100644 index 0000000..60e6f5f --- /dev/null +++ b/src/devices/pic/xml_data/30F6011.xml @@ -0,0 +1,224 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/30F6011A.xml b/src/devices/pic/xml_data/30F6011A.xml new file mode 100644 index 0000000..bb499b1 --- /dev/null +++ b/src/devices/pic/xml_data/30F6011A.xml @@ -0,0 +1,273 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/30F6012.xml b/src/devices/pic/xml_data/30F6012.xml new file mode 100644 index 0000000..e7c1797 --- /dev/null +++ b/src/devices/pic/xml_data/30F6012.xml @@ -0,0 +1,224 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/30F6012A.xml b/src/devices/pic/xml_data/30F6012A.xml new file mode 100644 index 0000000..6dd84fb --- /dev/null +++ b/src/devices/pic/xml_data/30F6012A.xml @@ -0,0 +1,273 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/30F6013.xml b/src/devices/pic/xml_data/30F6013.xml new file mode 100644 index 0000000..34b66cf --- /dev/null +++ b/src/devices/pic/xml_data/30F6013.xml @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/30F6013A.xml b/src/devices/pic/xml_data/30F6013A.xml new file mode 100644 index 0000000..e0a5758 --- /dev/null +++ b/src/devices/pic/xml_data/30F6013A.xml @@ -0,0 +1,289 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/30F6014.xml b/src/devices/pic/xml_data/30F6014.xml new file mode 100644 index 0000000..8cf7766 --- /dev/null +++ b/src/devices/pic/xml_data/30F6014.xml @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/30F6014A.xml b/src/devices/pic/xml_data/30F6014A.xml new file mode 100644 index 0000000..c6a6efe --- /dev/null +++ b/src/devices/pic/xml_data/30F6014A.xml @@ -0,0 +1,289 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/30F6015.xml b/src/devices/pic/xml_data/30F6015.xml new file mode 100644 index 0000000..784f38d --- /dev/null +++ b/src/devices/pic/xml_data/30F6015.xml @@ -0,0 +1,285 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/Makefile.am b/src/devices/pic/xml_data/Makefile.am new file mode 100644 index 0000000..43b13d4 --- /dev/null +++ b/src/devices/pic/xml_data/Makefile.am @@ -0,0 +1,12 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libpicxml.la +libpicxml_la_SOURCES = pic_data.cpp +libpicxml_la_DEPENDENCIES = pic_data.cpp + +include deps.mak +noinst_DATA += registers/registers.xml registers/registers_missing.xml +pic_data.cpp: ../xml/pic_xml_to_data $(noinst_DATA) + ../xml/pic_xml_to_data +CLEANFILES = pic_data.cpp diff --git a/src/devices/pic/xml_data/deps.mak b/src/devices/pic/xml_data/deps.mak new file mode 100644 index 0000000..ac8dcee --- /dev/null +++ b/src/devices/pic/xml_data/deps.mak @@ -0,0 +1,43 @@ +noinst_DATA = \ + 10F200.xml 10F202.xml 10F204.xml 10F206.xml 10F220.xml 10F222.xml 12C508.xml 12C508A.xml 12C509.xml 12C509A.xml\ + 12C671.xml 12C672.xml 12CE518.xml 12CE519.xml 12CE673.xml 12CE674.xml 12CR509A.xml 12F508.xml 12F509.xml 12F510.xml\ + 12F519.xml 12F609.xml 12F615.xml 12F629.xml 12F635.xml 12F675.xml 12F683.xml 14000.xml 16C432.xml 16C433.xml\ + 16C505.xml 16C52.xml 16C54.xml 16C54A.xml 16C54B.xml 16C54C.xml 16C55.xml 16C554.xml 16C557.xml 16C558.xml\ + 16C55A.xml 16C56.xml 16C56A.xml 16C57.xml 16C57C.xml 16C58A.xml 16C58B.xml 16C61.xml 16C62.xml 16C620.xml\ + 16C620A.xml 16C621.xml 16C621A.xml 16C622.xml 16C622A.xml 16C62A.xml 16C62B.xml 16C63.xml 16C63A.xml 16C64.xml\ + 16C641.xml 16C642.xml 16C64A.xml 16C65.xml 16C65A.xml 16C65B.xml 16C66.xml 16C661.xml 16C662.xml 16C67.xml\ + 16C71.xml 16C710.xml 16C711.xml 16C712.xml 16C715.xml 16C716.xml 16C717.xml 16C72.xml 16C72A.xml 16C73.xml\ + 16C73A.xml 16C73B.xml 16C74.xml 16C745.xml 16C74A.xml 16C74B.xml 16C76.xml 16C765.xml 16C77.xml 16C770.xml\ + 16C771.xml 16C773.xml 16C774.xml 16C781.xml 16C782.xml 16C84.xml 16C923.xml 16C924.xml 16C925.xml 16C926.xml\ + 16CE623.xml 16CE624.xml 16CE625.xml 16CR54A.xml 16CR54B.xml 16CR54C.xml 16CR56A.xml 16CR57B.xml 16CR57C.xml 16CR58A.xml\ + 16CR58B.xml 16CR62.xml 16CR620A.xml 16CR63.xml 16CR64.xml 16CR65.xml 16CR72.xml 16CR73.xml 16CR74.xml 16CR76.xml\ + 16CR77.xml 16CR83.xml 16CR84.xml 16F505.xml 16F506.xml 16F54.xml 16F57.xml 16F59.xml 16F610.xml 16F616.xml\ + 16F627.xml 16F627A.xml 16F628.xml 16F628A.xml 16F630.xml 16F631.xml 16F636.xml 16F639.xml 16F648A.xml 16F676.xml\ + 16F677.xml 16F684.xml 16F685.xml 16F687.xml 16F688.xml 16F689.xml 16F690.xml 16F716.xml 16F72.xml 16F73.xml\ + 16F737.xml 16F74.xml 16F747.xml 16F76.xml 16F767.xml 16F77.xml 16F777.xml 16F785.xml 16F818.xml 16F819.xml\ + 16F83.xml 16F84.xml 16F84A.xml 16F87.xml 16F870.xml 16F871.xml 16F872.xml 16F873.xml 16F873A.xml 16F874.xml\ + 16F874A.xml 16F876.xml 16F876A.xml 16F877.xml 16F877A.xml 16F88.xml 16F882.xml 16F883.xml 16F884.xml 16F886.xml\ + 16F887.xml 16F913.xml 16F914.xml 16F916.xml 16F917.xml 16F946.xml 16HV540.xml 17C42.xml 17C42A.xml 17C43.xml\ + 17C44.xml 17C752.xml 17C756.xml 17C756A.xml 17C762.xml 17C766.xml 17CR42.xml 17CR43.xml 18C242.xml 18C252.xml\ + 18C442.xml 18C452.xml 18C601.xml 18C658.xml 18C801.xml 18C858.xml 18F1220.xml 18F1230.xml 18F1320.xml 18F1330.xml\ + 18F2220.xml 18F2221.xml 18F2320.xml 18F2321.xml 18F2331.xml 18F2410.xml 18F242.xml 18F2420.xml 18F2423.xml 18F2431.xml\ + 18F2439.xml 18F2450.xml 18F2455.xml 18F248.xml 18F2480.xml 18F24J10.xml 18F2510.xml 18F2515.xml 18F252.xml 18F2520.xml\ + 18F2523.xml 18F2525.xml 18F2539.xml 18F2550.xml 18F258.xml 18F2580.xml 18F2585.xml 18F25J10.xml 18F2610.xml 18F2620.xml\ + 18F2680.xml 18F2682.xml 18F2685.xml 18F4220.xml 18F4221.xml 18F4320.xml 18F4321.xml 18F4331.xml 18F4410.xml 18F442.xml\ + 18F4420.xml 18F4423.xml 18F4431.xml 18F4439.xml 18F4450.xml 18F4455.xml 18F448.xml 18F4480.xml 18F44J10.xml 18F4510.xml\ + 18F4515.xml 18F452.xml 18F4520.xml 18F4523.xml 18F4525.xml 18F4539.xml 18F4550.xml 18F458.xml 18F4580.xml 18F4585.xml\ + 18F45J10.xml 18F4610.xml 18F4620.xml 18F4680.xml 18F4682.xml 18F4685.xml 18F6310.xml 18F6390.xml 18F6393.xml 18F63J11.xml\ + 18F63J90.xml 18F6410.xml 18F6490.xml 18F6493.xml 18F64J11.xml 18F64J90.xml 18F6520.xml 18F6525.xml 18F6527.xml 18F6585.xml\ + 18F65J10.xml 18F65J11.xml 18F65J15.xml 18F65J50.xml 18F65J90.xml 18F6620.xml 18F6621.xml 18F6622.xml 18F6627.xml 18F6680.xml\ + 18F66J10.xml 18F66J11.xml 18F66J15.xml 18F66J16.xml 18F66J50.xml 18F66J55.xml 18F66J60.xml 18F66J65.xml 18F6720.xml 18F6722.xml\ + 18F67J10.xml 18F67J11.xml 18F67J50.xml 18F67J60.xml 18F8310.xml 18F8390.xml 18F8393.xml 18F83J11.xml 18F83J90.xml 18F8410.xml\ + 18F8490.xml 18F8493.xml 18F84J11.xml 18F84J90.xml 18F8520.xml 18F8525.xml 18F8527.xml 18F8585.xml 18F85J10.xml 18F85J11.xml\ + 18F85J15.xml 18F85J50.xml 18F85J90.xml 18F8620.xml 18F8621.xml 18F8622.xml 18F8627.xml 18F8680.xml 18F86J10.xml 18F86J11.xml\ + 18F86J15.xml 18F86J16.xml 18F86J50.xml 18F86J55.xml 18F86J60.xml 18F86J65.xml 18F8720.xml 18F8722.xml 18F87J10.xml 18F87J11.xml\ + 18F87J50.xml 18F87J60.xml 18F96J60.xml 18F96J65.xml 18F97J60.xml 24FJ128GA006.xml 24FJ128GA008.xml 24FJ128GA010.xml 24FJ64GA002.xml 24FJ64GA004.xml\ + 24FJ64GA006.xml 24FJ64GA008.xml 24FJ64GA010.xml 24FJ96GA006.xml 24FJ96GA008.xml 24FJ96GA010.xml 24HJ128GP206.xml 24HJ128GP210.xml 24HJ128GP306.xml 24HJ128GP310.xml\ + 24HJ128GP506.xml 24HJ128GP510.xml 24HJ12GP201.xml 24HJ12GP202.xml 24HJ16GP304.xml 24HJ256GP206.xml 24HJ256GP210.xml 24HJ256GP610.xml 24HJ32GP202.xml 24HJ32GP204.xml\ + 24HJ64GP206.xml 24HJ64GP210.xml 24HJ64GP506.xml 24HJ64GP510.xml 30F1010.xml 30F2010.xml 30F2011.xml 30F2012.xml 30F2020.xml 30F2023.xml\ + 30F3010.xml 30F3011.xml 30F3012.xml 30F3013.xml 30F3014.xml 30F4011.xml 30F4012.xml 30F4013.xml 30F5011.xml 30F5013.xml\ + 30F5015.xml 30F5016.xml 30F6010.xml 30F6010A.xml 30F6011.xml 30F6011A.xml 30F6012.xml 30F6012A.xml 30F6013.xml 30F6013A.xml\ + 30F6014.xml 30F6014A.xml 30F6015.xml diff --git a/src/devices/pic/xml_data/pic.xsd b/src/devices/pic/xml_data/pic.xsd new file mode 100644 index 0000000..f358f68 --- /dev/null +++ b/src/devices/pic/xml_data/pic.xsd @@ -0,0 +1,295 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/devices/pic/xml_data/registers/registers.xml b/src/devices/pic/xml_data/registers/registers.xml new file mode 100644 index 0000000..d7c0884 --- /dev/null +++ b/src/devices/pic/xml_data/registers/registers.xml @@ -0,0 +1,57694 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/registers/registers_missing.xml b/src/devices/pic/xml_data/registers/registers_missing.xml new file mode 100644 index 0000000..b6e3173 --- /dev/null +++ b/src/devices/pic/xml_data/registers/registers_missing.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/devices/pic/xml_data/validate.sh b/src/devices/pic/xml_data/validate.sh new file mode 100755 index 0000000..20dbe5e --- /dev/null +++ b/src/devices/pic/xml_data/validate.sh @@ -0,0 +1,5 @@ +cd validate +make +cd .. +validate/validate $1 + diff --git a/src/devices/pic/xml_data/validate/Makefile b/src/devices/pic/xml_data/validate/Makefile new file mode 100644 index 0000000..d235259 --- /dev/null +++ b/src/devices/pic/xml_data/validate/Makefile @@ -0,0 +1,4 @@ +all: validate + +validate: validate.cpp + g++ -o validate -lxerces-c validate.cpp diff --git a/src/devices/pic/xml_data/validate/validate.cpp b/src/devices/pic/xml_data/validate/validate.cpp new file mode 100644 index 0000000..7e733b0 --- /dev/null +++ b/src/devices/pic/xml_data/validate/validate.cpp @@ -0,0 +1,72 @@ +// Necessary includes. We refer to these as "common includes" +// in the following examples. +#include +#include +#include + +// Handy definitions of constants. +#include + +#include + +using namespace std; +XERCES_CPP_NAMESPACE_USE + +class Handler : public DefaultHandler +{ +public: + virtual void error (const SAXParseException &exc) { + char* message = XMLString::transcode(exc.getMessage()); + cout << "Exception: " << message << "\n"; + XMLString::release(&message); + } + virtual void fatalError (const SAXParseException &exc) { + char* message = XMLString::transcode(exc.getMessage()); + cout << "Exception: " << message << "\n"; + XMLString::release(&message); + } +}; + +int main(int argc, char* argv[]) +{ +XMLPlatformUtils::Initialize(); + +// Create a SAX2 parser object. +SAX2XMLReader* parser = XMLReaderFactory::createXMLReader(); + +// Set the appropriate features on the parser. +// Enable namespaces, schema validation, and the checking +// of all Schema constraints. +// We refer to these as "common features" in following examples. +parser->setFeature(XMLUni::fgSAX2CoreNameSpaces, true); +parser->setFeature(XMLUni::fgSAX2CoreValidation, true); +parser->setFeature(XMLUni::fgXercesDynamic, false); +parser->setFeature(XMLUni::fgXercesSchema, true); +parser->setFeature(XMLUni::fgXercesSchemaFullChecking, true); +//parser->setProperty(XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation, (void *)"pic.xsd"); + +// Set appropriate ContentHandler, ErrorHandler, and EntityResolver. +// These will be referred to as "common handlers" in subsequent examples. + +// You will use a default handler provided by Xerces-C++ (no op action). +// Users should write their own handlers and install them. +Handler handler; +parser->setContentHandler(&handler); + +// The object parser calls when it detects violations of the schema. +parser->setErrorHandler(&handler); + +// The object parser calls to find the schema and +// resolve schema imports/includes. +parser->setEntityResolver(&handler); + +// Parse the XML document. +// Document content sent to registered ContentHandler instance. +if ( argc==1 ) { printf("Needs one argument\n"); return -1; } +parser->parse(argv[1]); + +// Delete the parser instance. +delete parser; + +return 0; +} diff --git a/src/devices/pic/xml_data/xml_data.pro b/src/devices/pic/xml_data/xml_data.pro new file mode 100644 index 0000000..086bf53 --- /dev/null +++ b/src/devices/pic/xml_data/xml_data.pro @@ -0,0 +1,5 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/lib.pro) + +TARGET = picxml +SOURCES += pic_data.cpp diff --git a/src/libgui/Makefile.am b/src/libgui/Makefile.am new file mode 100644 index 0000000..b12fc23 --- /dev/null +++ b/src/libgui/Makefile.am @@ -0,0 +1,12 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libgui.la +libgui_la_LDFLAGS = $(all_libraries) +libgui_la_SOURCES = editor.cpp device_gui.cpp toplevel.cpp object_view.cpp \ + config_gen.cpp register_view.cpp device_editor.cpp watch_view.cpp project.cpp \ + project_editor.cpp project_manager.cpp hex_editor.cpp global_config.cpp config_center.cpp \ + editor_manager.cpp new_dialogs.cpp text_editor.cpp log_view.cpp gui_prog_manager.cpp \ + gui_debug_manager.cpp breakpoint_view.cpp likeback.cpp main_global.cpp console.cpp \ + project_wizard.cpp toplevel_ui.cpp project_manager_ui.cpp + diff --git a/src/libgui/breakpoint_view.cpp b/src/libgui/breakpoint_view.cpp new file mode 100644 index 0000000..6f49aac --- /dev/null +++ b/src/libgui/breakpoint_view.cpp @@ -0,0 +1,94 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "breakpoint_view.h" + +#include +#include +#include + +#include "main_global.h" +#include "editor_manager.h" +#include "coff/base/text_coff.h" +#include "gui_debug_manager.h" + +//---------------------------------------------------------------------------- +void Breakpoint::updateActions(const Data *data) +{ + bool hasBreakpoint = (data ? Breakpoint::list().contains(*data) : false); + Main::action("toggle_breakpoint")->setText(hasBreakpoint ? i18n("Remove breakpoint") : i18n("Set breakpoint")); + Main::action("toggle_breakpoint")->setEnabled(data); + bool isActive = (hasBreakpoint ? Breakpoint::list().state(*data)==Breakpoint::Active : false); + Main::action("enable_breakpoint")->setText(!isActive ? i18n("Enable breakpoint") : i18n("Disable breakpoint")); + Main::action("enable_breakpoint")->setEnabled(Debugger::manager->coff() && hasBreakpoint); +} + +//---------------------------------------------------------------------------- +Breakpoint::ListViewItem::ListViewItem(ListView *parent, const Data &data) + : KListViewItem(parent), _data(data) +{} + +//---------------------------------------------------------------------------- +Breakpoint::View::View(QWidget *parent) + : QWidget(parent, "breakpoints_view"), GenericView(Breakpoint::list()), + _currentData(0) +{ + QVBoxLayout *top = new QVBoxLayout(this); + _listview = new ListView(this); + connect(_listview, SIGNAL(clicked(QListViewItem *)), SLOT(itemClicked(QListViewItem *))); + connect(_listview, SIGNAL(contextMenuRequested(QListViewItem *, const QPoint &, int)), + SLOT(contextMenu(QListViewItem *, const QPoint &, int))); + _listview->setAllColumnsShowFocus(true); + _listview->addColumn(i18n("Status")); + _listview->addColumn(i18n("Location")); + _listview->addColumn(i18n("Address")); + top->addWidget(_listview); +} + +void Breakpoint::View::updateView() +{ + // #### flickering... + _listview->clear(); + for (uint i=0; isetPixmap(0, TextEditor::pixmap(Debugger::manager->breakpointType(data))); + item->setText(1, data.url.filename() + ":" + QString::number(data.line)); + Address address = Breakpoint::list().address(data); + if ( address.isValid() ) item->setText(2, toHexLabelAbs(address)); + else if ( Debugger::manager->coff() ) item->setText(2, i18n("Non-code breakpoint")); + else item->setText(2, "---"); + } +} + +void Breakpoint::View::itemClicked(QListViewItem *item) +{ + if ( item==0 ) return; + const Data &data = static_cast(item)->data(); + Address address = Breakpoint::list().address(data); + TextEditor *editor = ::qt_cast(Main::currentEditor()); + const Coff::TextObject *coff = Debugger::manager->coff(); + int line = -1; + if ( coff && editor && editor->fileType()==PURL::Coff && address.isValid() ) + line = coff->lineForAddress(editor->url(), address); + if ( line==-1 ) { + editor = ::qt_cast(Main::editorManager().openEditor(data.url)); + line = data.line; + } + if ( editor==0 ) return; + editor->show(); + editor->setCursor(line, 0); +} + +void Breakpoint::View::contextMenu(QListViewItem *item, const QPoint &pos, int) +{ + _currentData = (item ? &static_cast(item)->data() : 0); + updateActions(_currentData); + Main::popup("breakpoint_context_menu").exec(pos); + _currentData = 0; +} diff --git a/src/libgui/breakpoint_view.h b/src/libgui/breakpoint_view.h new file mode 100644 index 0000000..984a7ed --- /dev/null +++ b/src/libgui/breakpoint_view.h @@ -0,0 +1,48 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef BREAKPOINT_VIEW_H +#define BREAKPOINT_VIEW_H + +#include "progs/manager/breakpoint.h" +#include "common/gui/list_view.h" + +namespace Breakpoint +{ +//---------------------------------------------------------------------------- +class ListViewItem : public KListViewItem +{ +public: + ListViewItem(ListView *parent, const Data &data); + const Data &data() const { return _data; } + +private: + Data _data; +}; + +//---------------------------------------------------------------------------- +class View : public QWidget, public GenericView +{ +Q_OBJECT +public: + View(QWidget *parent); + virtual void updateView(); + const Data *currentData() const { return _currentData; } + +private slots: + void itemClicked(QListViewItem *item); + void contextMenu(QListViewItem *item, const QPoint &pos, int col); + +private: + ListView *_listview; + const Data *_currentData; +}; + +} // namespace + +#endif diff --git a/src/libgui/config_center.cpp b/src/libgui/config_center.cpp new file mode 100644 index 0000000..530cbbf --- /dev/null +++ b/src/libgui/config_center.cpp @@ -0,0 +1,132 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * Copyright (C) 2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "config_center.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "global_config.h" +#include "device_gui.h" +#include "tools/list/tools_config_widget.h" +#include "progs/gui/prog_config_center.h" +#include "progs/gui/debug_config_center.h" +#include "tools/list/compile_config.h" + +//---------------------------------------------------------------------------- +GlobalConfigWidget::GlobalConfigWidget() +{ + uint row = numRows(); + _showDebug = new KeyComboBox(this); + FOR_EACH(Log::DebugLevel, level) _showDebug->appendItem(level, level.label()); + addWidget(_showDebug->widget(), row,row, 0,0); + row++; +} + +void GlobalConfigWidget::loadConfig() +{ + BaseGlobalConfigWidget::loadConfig(); + _showDebug->setCurrentItem(GlobalConfig::debugLevel()); +} + +void GlobalConfigWidget::saveConfig() +{ + BaseGlobalConfigWidget::saveConfig(); + GlobalConfig::writeDebugLevel(_showDebug->currentItem()); +} + +QPixmap GlobalConfigWidget::pixmap() const +{ + KIconLoader loader; + return loader.loadIcon("configure", KIcon::Toolbar, KIcon::SizeMedium); +} + +//---------------------------------------------------------------------------- +StandaloneConfigWidget::StandaloneConfigWidget() + : ConfigWidget(0) +{ + uint row = 0; + + QLabel *label = new QLabel(i18n("Device:"), this); + addWidget(label, row,row, 0,0); + _device = new DeviceChooser::Button(true, this); + addWidget(_device, row,row, 1,1); + row++; + + _tools = new ToolsConfigWidget(0, this); + addWidget(_tools, row,row, 0,2); + row++; + + setColStretch(2, 1); +} + +void StandaloneConfigWidget::loadConfig() +{ + _device->setDevice(Compile::Config::device(0)); + _tools->loadConfig(); +} + +void StandaloneConfigWidget::saveConfig() +{ + Compile::Config::setDevice(0, _device->device()); + _tools->saveConfig(); +} + +QPixmap StandaloneConfigWidget::pixmap() const +{ + KIconLoader loader; + return loader.loadIcon("configure", KIcon::Toolbar, KIcon::SizeMedium); +} + +//---------------------------------------------------------------------------- +ConfigWidget *ConfigCenter::factory(Type type) +{ + switch (type) { + case General: return new GlobalConfigWidget; + case ProgSelect: return new Programmer::SelectConfigWidget; + case ProgOptions: return new Programmer::OptionsConfigWidget; + case DebugOptions: return new Debugger::OptionsConfigWidget; + case Standalone: return new StandaloneConfigWidget; + case Nb_Types: break; + } + Q_ASSERT(false); + return 0; +} + +ConfigCenter::ConfigCenter(Type showType, QWidget *parent) + : Dialog(IconList, i18n("Configure Piklab"), Ok|Cancel, Cancel, parent, "configure_piklab_dialog", true, false) +{ + for (uint i=0; iloadConfig(); + _pages[i] = addPage(_configWidgets[i]->title(), _configWidgets[i]->header(), _configWidgets[i]->pixmap()); + QVBoxLayout *vbox = new QVBoxLayout(_pages[i]); + _configWidgets[i]->reparent(_pages[i], QPoint(0,0)); + vbox->addWidget(_configWidgets[i]); + } + showPage(showType); +} + +void ConfigCenter::slotApply() +{ + for (uint i=0; isaveConfig(); +} + +void ConfigCenter::slotOk() +{ + slotApply(); + accept(); +} diff --git a/src/libgui/config_center.h b/src/libgui/config_center.h new file mode 100644 index 0000000..1e543b7 --- /dev/null +++ b/src/libgui/config_center.h @@ -0,0 +1,85 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * Copyright (C) 2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#ifndef CONFIG_CENTER_H +#define CONFIG_CENTER_H + +#include +#include +#include + +#include "common/gui/key_gui.h" +#include "common/gui/dialog.h" +#include "progs/gui/prog_config_widget.h" +#include "global_config.h" +namespace DeviceChooser { class Button; } +class SelectDirectoryWidget; +class ToolsConfigWidget; + +//---------------------------------------------------------------------------- +BEGIN_DECLARE_CONFIG_WIDGET(BaseGlobalConfig, BaseGlobalConfigWidget) +END_DECLARE_CONFIG_WIDGET + +class GlobalConfigWidget : public BaseGlobalConfigWidget +{ +Q_OBJECT +public: + GlobalConfigWidget(); + virtual QString title() const { return i18n("General"); } + virtual QString header() const { return i18n("General Configuration"); } + virtual QPixmap pixmap() const; + virtual void loadConfig(); + +public slots: + virtual void saveConfig(); + +private: + KeyComboBox *_showDebug; +}; + +//---------------------------------------------------------------------------- +class StandaloneConfigWidget : public ConfigWidget +{ + Q_OBJECT +public: + StandaloneConfigWidget(); + virtual void loadConfig(); + virtual QString title() const { return i18n("Standalone File"); } + virtual QString header() const { return i18n("Standalone File Compilation"); } + virtual QPixmap pixmap() const; + +public slots: + virtual void saveConfig(); + +private: + DeviceChooser::Button *_device; + ToolsConfigWidget *_tools; +}; + +//---------------------------------------------------------------------------- +class ConfigCenter : public Dialog +{ +Q_OBJECT +public: + enum Type { General = 0, ProgSelect, ProgOptions, DebugOptions, + Standalone, Nb_Types }; + ConfigCenter(Type showType, QWidget *parent); + +public slots: + virtual void slotOk(); + virtual void slotApply(); + +private: + QWidget *_pages[Nb_Types]; + ConfigWidget *_configWidgets[Nb_Types]; + + static ConfigWidget *factory(Type type); +}; + +#endif diff --git a/src/libgui/config_gen.cpp b/src/libgui/config_gen.cpp new file mode 100644 index 0000000..036e62e --- /dev/null +++ b/src/libgui/config_gen.cpp @@ -0,0 +1,189 @@ +/*************************************************************************** + * Copyright (C) 2006-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "config_gen.h" + +#include +#include +#include + +#include "device_gui.h" +#include "devices/base/generic_memory.h" +#include "devices/gui/hex_view.h" +#include "devices/gui/memory_editor.h" +#include "devices/base/device_group.h" +#include "devices/gui/device_group_ui.h" +#include "devices/list/device_list.h" +#include "text_editor.h" +#include "tools/list/tool_list.h" + +//----------------------------------------------------------------------------- +GeneratorDialog::GeneratorDialog(const QString &title, QWidget *parent, const char *name) + : Dialog(parent, name, true, title, Close|User1, Close, false, QSize(400, 300)) +{ + QVBoxLayout *top = new QVBoxLayout(mainWidget(), 10, 10); + + QHBoxLayout *hbox = new QHBoxLayout(top); + QLabel *label = new QLabel(i18n("Device:"), mainWidget()); + hbox->addWidget(label); + _deviceChooser = new DeviceChooser::Button(false, mainWidget()); + connect(_deviceChooser, SIGNAL(changed()), SLOT(reset())); + hbox->addWidget(_deviceChooser); + hbox->addSpacing(20); + + label = new QLabel(i18n("Toolchain:"), mainWidget()); + hbox->addWidget(label); + _configType = new KeyComboBox(mainWidget()); + Tool::Lister::ConstIterator it; + for (it=Tool::lister().begin(); it!=Tool::lister().end(); ++it) + _configType->appendItem(it.key(), it.data()->label()); + connect(_configType->widget(), SIGNAL(activated(int)), SLOT(typeChanged())); + hbox->addWidget(_configType->widget()); + + label = new QLabel(i18n("Tool Type:"), mainWidget()); + hbox->addWidget(label); + _toolType = new KeyComboBox(mainWidget()); + FOR_EACH(PURL::ToolType, type) _toolType->appendItem(type, type.label()); + _toolType->fixMinimumWidth(); + connect(_toolType->widget(), SIGNAL(activated(int)), SLOT(compute())); + hbox->addWidget(_toolType->widget()); + hbox->addStretch(1); + + _hbox = new QHBoxLayout(top); + + _text = new SimpleTextEditor(false, PURL::Nb_FileTypes, mainWidget()); + _text->setReadOnly(true); + top->addWidget(_text); + + _warning = new QLabel(mainWidget()); + top->addWidget(_warning); + + setButtonText(User1, i18n("Copy to clipboard")); +} + +void GeneratorDialog::set(const Device::Data *data, const Tool::Group &group, PURL::ToolType stype) +{ + QString device; + if ( data==0 ) { + QValueVector devices = group.supportedDevices(); + if ( devices.isEmpty() ) return; + device = devices[0]; + } else device = data->name(); + _deviceChooser->setDevice(device); + _configType->setCurrentItem(group.name()); + setToolType(stype); + reset(); +} + +void GeneratorDialog::typeChanged() +{ + setToolType(PURL::ToolType::Nb_Types); + compute(); +} + +void GeneratorDialog::setToolType(PURL::ToolType stype) +{ + const Tool::Group *group = Tool::lister().group(_configType->currentItem()); + _toolType->clear(); + FOR_EACH(PURL::ToolType, type) + if ( group->implementationType(type)!=PURL::Nb_FileTypes ) _toolType->appendItem(type, type.label()); + _toolType->setCurrentItem(stype); + _toolType->widget()->setEnabled( _toolType->count()>=2 ); +} + +PURL::ToolType GeneratorDialog::toolType() const +{ + return _toolType->currentItem(); +} + +void GeneratorDialog::compute() +{ + const Tool::Group *group = Tool::lister().group(_configType->currentItem()); + _warning->hide(); + if ( group->isSupported(_deviceChooser->device()) ) { + const Tool::SourceGenerator *generator = group->sourceGenerator(); + if ( generator==0 ) { + _text->setFileType(PURL::Nb_FileTypes); + _text->setText(i18n("Generation is not supported yet for the selected toolchain or device.")); + } else { + bool ok = true; + PURL::FileType type = group->implementationType(toolType()); + SourceLine::List lines = generateLines(ok); + if ( ok && lines.isEmpty() ) { + _text->setFileType(PURL::Nb_FileTypes); + _text->setText(i18n("This toolchain does not need explicit config bits.")); + } else { + _text->setFileType(type); + _text->setText(SourceLine::text(type.data().sourceFamily, lines, 4)); + } + if ( !ok ) { + _warning->show(); + _warning->setText(i18n("Generation is only partially supported for this device.")); + } + } + } else { + _text->setFileType(PURL::Nb_FileTypes); + if ( group->supportedDevices().isEmpty() ) _text->setText(i18n("Could not detect supported devices for selected toolchain. Please check installation.")); + else _text->setText(i18n("Device not supported by the selected toolchain.")); + } +} + +void GeneratorDialog::slotUser1() +{ + _text->selectAll(); + _text->copy(); + _text->deselect(); +} + +//----------------------------------------------------------------------------- +ConfigGenerator::ConfigGenerator(QWidget *parent) + : GeneratorDialog(i18n("Config Generator"), parent, "config_generator"), _memory(0), _configEditor(0) +{} + +ConfigGenerator::~ConfigGenerator() +{ + delete _memory; +} + +void ConfigGenerator::reset() +{ + delete _memory; + const Device::Data *data = Device::lister().data(_deviceChooser->device()); + _memory = data->group().createMemory(*data); + delete _configEditor; + _configEditor = Device::groupui(*data).createConfigEditor(*_memory, mainWidget()); + if (_configEditor) { + _configEditor->show(); + connect(_configEditor, SIGNAL(modified()), SLOT(compute())); + _configEditor->updateDisplay(); + _hbox->addWidget(_configEditor); + } + compute(); +} + +SourceLine::List ConfigGenerator::generateLines(bool &ok) const +{ + const Tool::Group *group = Tool::lister().group(_configType->currentItem()); + const Tool::SourceGenerator *generator = group->sourceGenerator(); + Q_ASSERT(generator); + return generator->configLines(toolType(), *_memory, ok); +} + +//----------------------------------------------------------------------------- +TemplateGenerator::TemplateGenerator(QWidget *parent) + : GeneratorDialog(i18n("Template Generator"), parent, "template_generator") +{} + +SourceLine::List TemplateGenerator::generateLines(bool &ok) const +{ + const Tool::Group *group = Tool::lister().group(_configType->currentItem()); + const Tool::SourceGenerator *generator = group->sourceGenerator(); + Q_ASSERT(generator); + const Device::Data *data = Device::lister().data(_deviceChooser->device()); + return generator->templateSourceFile(toolType(), *data, ok); +} diff --git a/src/libgui/config_gen.h b/src/libgui/config_gen.h new file mode 100644 index 0000000..fa9fd56 --- /dev/null +++ b/src/libgui/config_gen.h @@ -0,0 +1,82 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef CONFIG_GEN_H +#define CONFIG_GEN_H + +class QHBoxLayout; +class QLabel; + +#include "common/gui/dialog.h" +#include "tools/base/tool_group.h" +#include "common/gui/key_gui.h" +namespace DeviceChooser { class Button; } +namespace Device { + class Memory; + class MemoryEditor; +} +class SimpleTextEditor; + +//----------------------------------------------------------------------------- +class GeneratorDialog : public Dialog +{ +Q_OBJECT +public: + GeneratorDialog(const QString &title, QWidget *parent, const char *name); + void set(const Device::Data *data, const Tool::Group &group, PURL::ToolType stype); + +protected slots: + void typeChanged(); + virtual void reset() { compute(); } + virtual void compute(); + virtual void slotUser1(); + +protected: + QHBoxLayout *_hbox; + DeviceChooser::Button *_deviceChooser; + KeyComboBox *_configType; + KeyComboBox *_toolType; + SimpleTextEditor *_text; + QLabel *_warning; + + PURL::ToolType toolType() const; + void setToolType(PURL::ToolType stype); + virtual SourceLine::List generateLines(bool &ok) const = 0; +}; + +//----------------------------------------------------------------------------- +class ConfigGenerator : public GeneratorDialog +{ +Q_OBJECT +public: + ConfigGenerator(QWidget *parent); + virtual ~ConfigGenerator(); + +private slots: + virtual void reset(); + +private: + Device::Memory *_memory; + Device::MemoryEditor *_configEditor; + + void setToolType(PURL::ToolType stype); + virtual SourceLine::List generateLines(bool &ok) const; +}; + +//----------------------------------------------------------------------------- +class TemplateGenerator : public GeneratorDialog +{ +Q_OBJECT +public: + TemplateGenerator(QWidget *parent); + +private: + virtual SourceLine::List generateLines(bool &ok) const; +}; + +#endif diff --git a/src/libgui/console.cpp b/src/libgui/console.cpp new file mode 100644 index 0000000..99c996c --- /dev/null +++ b/src/libgui/console.cpp @@ -0,0 +1,42 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "console.h" + +#include +#include +#include +#include +#include +#include +#include + +ConsoleView::ConsoleView(QWidget *parent) + : QWidget(parent, "console_view"), _initialized(false) +{} + +void ConsoleView::showEvent(QShowEvent *e) +{ + if ( !_initialized ) { + _initialized = true; + KLibFactory *factory = KLibLoader::self()->factory("libkonsolepart"); + QVBoxLayout *top = new QVBoxLayout(this, 0, 10); + if ( factory==0 ) { + QLabel *label = new QLabel(i18n("Could not find \"konsolepart\"; please install kdebase."), this); + label->show(); + top->addWidget(label); + return; + } else { + QWidget *pwidget = static_cast(factory->create(this, "konsole"))->widget(); + pwidget->show(); + top->addWidget(pwidget); + setFocusProxy(pwidget); + } + } + QWidget::showEvent(e); +} diff --git a/src/libgui/console.h b/src/libgui/console.h new file mode 100644 index 0000000..e073754 --- /dev/null +++ b/src/libgui/console.h @@ -0,0 +1,27 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef CONSOLE_H +#define CONSOLE_H + +#include + +class ConsoleView : public QWidget +{ +Q_OBJECT +public: + ConsoleView(QWidget *parent); + +protected: + virtual void showEvent(QShowEvent *e); + +private: + bool _initialized; +}; + +#endif diff --git a/src/libgui/device_editor.cpp b/src/libgui/device_editor.cpp new file mode 100644 index 0000000..7a2a3c6 --- /dev/null +++ b/src/libgui/device_editor.cpp @@ -0,0 +1,141 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "device_editor.h" + +#include +#include + +#include "devices/list/device_list.h" +#include "toplevel.h" +#include "gui_debug_manager.h" +#include "project_manager.h" +#include "common/global/pfile.h" +#include "main_global.h" + +DeviceEditor::DeviceEditor(const QString &title, const QString &tag, QWidget *parent, const char *name) + : Editor(title, tag, parent, name), _view(0) +{ + init(); +} + +DeviceEditor::DeviceEditor(QWidget *parent, const char *name) + : Editor(parent, name), _view(0) +{ + init(); +} + +void DeviceEditor::init() +{ + QHBoxLayout *hbox = new QHBoxLayout(this, 0); + QScrollView *sview = new QScrollView(this, "scroll_view"); + sview->setResizePolicy(QScrollView::AutoOneFit); + hbox->addWidget(sview); + _widget = new QWidget(sview->viewport(), "main_scroll_widget"); + sview->addChild(_widget); + _top = new QVBoxLayout(_widget, 0, 0); + _labelDevice = new QLabel(_widget); + _labelDevice->setMargin(10); + _labelDevice->setTextFormat(RichText); + _top->addWidget(_labelDevice); + _labelWarning = new QLabel(_widget); + _labelWarning->setMargin(10); + _labelWarning->setTextFormat(RichText); + _top->addWidget(_labelWarning); + _vbox = new QVBoxLayout(_top); + + connect(&Main::toplevel(), SIGNAL(stateChanged()), SLOT(updateDevice())); +} + +void DeviceEditor::setDevice(bool force) +{ + if ( Main::device()==Device::AUTO_DATA.name ) { + PURL::Url url = Main::projectManager().projectUrl(); + QString name = guessDeviceFromFile(url); + if ( !force && name==_device ) return; + _device = name; + if ( name==Device::AUTO_DATA.name ) + _labelDevice->setText(i18n("The target device is not configured and cannot be guessed from source file. " + "The source file either cannot be found or does not contain any processor directive.")); + else _labelDevice->setText(i18n("Device guessed from file: %1").arg(name)); + _labelDevice->show(); + } else { + if ( !force && Main::device()==_device ) return; + _device = Main::device(); + _labelDevice->hide(); + } + if ( _view && isModified() ) { + if ( MessageBox::questionYesNo(i18n("File %1 not saved.").arg(filename()), KStdGuiItem::save(), KStdGuiItem::discard()) ) + Editor::save(); + } + _labelWarning->hide(); + const Device::Data *data = Device::lister().data(_device); + delete _view; + _view = createView(data, _widget); + if (_view) { + _view->show(); + _vbox->addWidget(_view); + updateGeometry(); + } + setModified(false); + emit guiChanged(); +} + +PURL::Url DeviceEditor::findAsmFile(const PURL::Url &url) +{ + if ( url.isEmpty() ) return PURL::Url(); + PURL::SourceFamily family = url.fileType().data().sourceFamily; + if ( family.data().toolType==PURL::ToolType::Assembler ) return url; + FOR_EACH(PURL::FileType, i) { + PURL::SourceFamily source = i.data().sourceFamily; + if ( source.data().toolType!=PURL::ToolType::Assembler ) continue; + for (uint k=0; i.data().extensions[k]; k++) { + PURL::Url src = url.toExtension(i.data().extensions[k]); + if ( PURL::findExistingUrl(src) ) return src; + } + } + return PURL::Url(); +} + +QString DeviceEditor::guessDeviceFromFile(const PURL::Url &url) +{ + PURL::Url src = findAsmFile(url); + if ( src.isEmpty() ) return Device::AUTO_DATA.name; + Log::StringView sview; + PURL::File file(src, sview); + if ( !file.openForRead() ) return Device::AUTO_DATA.name; + + QString device; + // QRegExp re1("^[ \\t]+(?:PROCESSOR|processor)[ \\t]+((?:p|sx|P|SX)[a-z0-9A-Z]+)" ) ; + QRegExp re1("^[ \\t]+(?:PROCESSOR|processor)[ \\t]+([a-z0-9A-Z]+)" ) ; + QRegExp re2("^[ \\t]+(?:LIST|list)[ \\t]+" ) ; + for (;;) { + QString line = file.readLine(); + if ( line.isNull() ) break; + // search PROCESSOR directive + if ( re1.search(line, 0)!=-1 ) { + device = re1.cap(1); + break; + } + // search LIST p=... directive + int k = re2.search(line,0); + if ( k!=-1 ) { + //QRegExp re3("(?:p|P)[ \\t]*=[ \\t]*((?:p|sx|P|SX)[a-z0-9A-Z]+)") ; + QRegExp re3("(?:p|P)[ \\t]*=[ \\t]*([a-z0-9A-Z]+)") ; + if ( re3.search(line, k+5)!=-1 ) { + device = re3.cap(1); + break; + } + } + } + device = device.upper(); + if( device[0]=='P') return device.mid(1); + if ( Device::lister().data(device)==0 ) return Device::AUTO_DATA.name; + return device; +} diff --git a/src/libgui/device_editor.h b/src/libgui/device_editor.h new file mode 100644 index 0000000..8b7cab7 --- /dev/null +++ b/src/libgui/device_editor.h @@ -0,0 +1,47 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef DEVICE_EDITOR_H +#define DEVICE_EDITOR_H + +#include "editor.h" +namespace Device { class Data; } + +class DeviceEditor : public Editor +{ +Q_OBJECT +public: + DeviceEditor(const QString &title, const QString &tag, QWidget *parent, const char *name); + DeviceEditor(QWidget *parent, const char *name); + virtual PURL::FileType fileType() const { return PURL::Nb_FileTypes; } + virtual PURL::Url url() const { return PURL::Url(); } + virtual void setDevice(bool force = false); + static QString guessDeviceFromFile(const PURL::Url &url); + virtual bool save(const PURL::Url &) { return false; } + virtual bool open(const PURL::Url &) { return true; } + virtual QValueList bookmarkLines() const { return QValueList(); } + virtual void setBookmarkLines(const QValueList &) {} + +public slots: + virtual void statusChanged() { emit statusTextChanged(" "); } + +protected: + QString _device; + QWidget *_widget, *_view; + QVBoxLayout *_top, *_vbox; + QLabel *_labelDevice, *_labelWarning; + + void init(); + virtual QWidget *createView(const Device::Data *data, QWidget *parent) = 0; + static PURL::Url findAsmFile(const PURL::Url &url); + +private slots: + void updateDevice() { setDevice(); } +}; + +#endif diff --git a/src/libgui/device_gui.cpp b/src/libgui/device_gui.cpp new file mode 100644 index 0000000..8183725 --- /dev/null +++ b/src/libgui/device_gui.cpp @@ -0,0 +1,463 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "device_gui.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "devices/list/device_list.h" +#include "devices/base/device_group.h" +#include "devices/gui/device_group_ui.h" +#include "progs/list/prog_list.h" +#include "tools/list/device_info.h" +#include "tools/list/tool_list.h" + +namespace DeviceChooser +{ +//----------------------------------------------------------------------------- +void DeviceChooser::Config::writeProgrammerGroup(const Programmer::Group *group) +{ + writeEntry("programmer", group ? group->name() : QString::null); +} +const Programmer::Group *DeviceChooser::Config::programmerGroup() +{ + QString name = readEntry("programmer", QString::null); + return Programmer::lister().group(name); +} + +void DeviceChooser::Config::writeToolGroup(const Tool::Group *group) +{ + writeEntry("tool", group ? group->name() : QString::null); +} +const Tool::Group *DeviceChooser::Config::toolGroup() +{ + QString name = readEntry("tool", QString::null); + return Tool::lister().group(name); +} + +//----------------------------------------------------------------------------- +class ListItem : public KListViewItem +{ +public: + ListItem(KListView *list, const QString &name, bool selectable, bool isDevice) + : KListViewItem(list, name), _device(isDevice) { + setSelectable(selectable); + } + ListItem(KListViewItem *item, const QString &name) + : KListViewItem(item, name), _device(true) {} + + bool isDevice() const { return _device; } + virtual void paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int align) { + QColorGroup ncg = cg; + if (_device) { + const Device::Data *device = Device::lister().data(text(0)); + Q_ASSERT(device); + ncg.setColor(QColorGroup::Text, Device::statusColor(device->status())); + } + KListViewItem::paintCell(p, ncg, column, width, align); + } + +private: + bool _device; +}; + +} // namespace + +//----------------------------------------------------------------------------- +const DeviceChooser::ListType::Data DeviceChooser::ListType::DATA[Nb_Types] = { + { "family_tree", I18N_NOOP("Family Tree") }, + { "flat", I18N_NOOP("Flat List") } +}; + +DeviceChooser::Dialog::Dialog(const QString &device, Type type, QWidget *parent) + : ::Dialog(parent, "device_chooser_dialog", true, i18n("Select a device"), + Ok|Close, Close, false, QSize(400, 300)), _withAuto(type==ChooseWithAuto) +{ + setButtonOK(KGuiItem(i18n( "&Select"), "button_ok")); + QVBoxLayout *top = new QVBoxLayout(mainWidget(), 0, 10); + + // view + QHBoxLayout *hbox = new QHBoxLayout(top, 10); + QVBoxLayout *vbox = new QVBoxLayout(hbox); + _listTypeCombo = new EnumComboBox("list_type", mainWidget()); + connect(_listTypeCombo->combo(), SIGNAL(activated(int)), SLOT(updateList())); + vbox->addWidget(_listTypeCombo->combo()); + QPushButton *button = new KPushButton(KGuiItem(i18n("Reset Filters"), "reload"), mainWidget()); + connect(button, SIGNAL(clicked()), SLOT(resetFilters())); + vbox->addWidget(button); + vbox->addStretch(1); + + // filters + QFrame *frame = new QFrame(mainWidget()); + frame->setFrameStyle(QFrame::Panel | QFrame::Raised); + frame->setMargin(5); + hbox->addWidget(frame); + hbox = new QHBoxLayout(frame, 10, 10); + QLabel *label = new QLabel(i18n("Filters:"), frame); + hbox->addWidget(label); + vbox = new QVBoxLayout(hbox); + + QHBoxLayout *shbox = new QHBoxLayout(vbox); + + // programmer filter + _programmerCombo = new KeyComboBox(frame); + _programmerCombo->appendItem("", i18n("")); + Programmer::Lister::ConstIterator pit; + for (pit=Programmer::lister().begin(); pit!=Programmer::lister().end(); ++pit) + _programmerCombo->appendItem(pit.key(), pit.data()->label()); + Config config; + const Programmer::Group *pgroup = config.programmerGroup(); + if (pgroup) _programmerCombo->setCurrentItem(pgroup->name()); + connect(_programmerCombo->widget(), SIGNAL(activated(int)), SLOT(updateList())); + shbox->addWidget(_programmerCombo->widget()); + + // tool filter + _toolCombo = new KeyComboBox(frame); + _toolCombo->appendItem("", i18n("")); + Tool::Lister::ConstIterator tit; + for (tit=Tool::lister().begin(); tit!=Tool::lister().end(); ++tit) { + if ( tit.data()->isCustom() ) continue; + _toolCombo->appendItem(tit.key(), tit.data()->label()); + } + const Tool::Group *tgroup = config.toolGroup(); + if (tgroup) _toolCombo->setCurrentItem(tgroup->name()); + connect(_toolCombo->widget(), SIGNAL(activated(int)), SLOT(updateList())); + shbox->addWidget(_toolCombo->widget()); + + // memory filter + _memoryCombo = new EnumComboBox(i18n(""), "memory_technology", frame); + connect(_memoryCombo->combo(), SIGNAL(activated(int)), SLOT(updateList())); + shbox->addWidget(_memoryCombo->combo()); + + shbox->addStretch(1); + shbox = new QHBoxLayout(vbox); + + // status filter + _statusCombo = new EnumComboBox(i18n(""), "status", frame); + connect(_statusCombo->combo(), SIGNAL(activated(int)), SLOT(updateList())); + shbox->addWidget(_statusCombo->combo()); + + // features filter + _featureCombo = new EnumComboBox(i18n(""), "feature", frame); + connect(_featureCombo->combo(), SIGNAL(activated(int)), SLOT(updateList())); + shbox->addWidget(_featureCombo->combo()); + + shbox->addStretch(1); + + // list view + QValueList widths; + widths += 80; + widths += 500; + Splitter *splitter = new Splitter(widths, Horizontal, mainWidget(), "device_shooser_splitter"); + top->addWidget(splitter, 1); + _listView = new KListView(splitter); + connect(_listView, SIGNAL(currentChanged(QListViewItem *)), + SLOT(currentChanged(QListViewItem *))); + connect(_listView, SIGNAL(doubleClicked(QListViewItem *, const QPoint &, int)), + SLOT(listDoubleClicked(QListViewItem *))); + _listView->setAllColumnsShowFocus(true); + _listView->setRootIsDecorated(true); + _listView->setSorting(-1); + _listView->addColumn(i18n("Device")); + _listView->setResizeMode(QListView::LastColumn); + + // device view + _deviceView = new View(splitter); + connect(_deviceView, SIGNAL(deviceChanged(const QString &)), + SLOT(deviceChange(const QString &))); + + updateList(device); +} + +DeviceChooser::Dialog::~Dialog() +{ + Config config; + config.writeProgrammerGroup(programmerGroup()); + config.writeToolGroup(toolGroup()); + _listTypeCombo->writeConfig(); + _memoryCombo->writeConfig(); + _statusCombo->writeConfig(); + _featureCombo->writeConfig(); +} + +QString DeviceChooser::Dialog::device() const +{ + QListViewItem *item = _listView->selectedItem(); + if ( item==0 || !static_cast(item)->isDevice() ) return Device::AUTO_DATA.name; + return item->text(0); +} + +void DeviceChooser::Dialog::listDoubleClicked(QListViewItem *item) +{ + if ( item==0 ) return; + if ( !static_cast(item)->isDevice() ) item->setOpen(!item->isOpen()); + else accept(); +} + +void DeviceChooser::Dialog::currentChanged(QListViewItem *item) +{ + if ( item==0 || !static_cast(item)->isDevice() ) _deviceView->clear(); + else _deviceView->setDevice(item->text(0), false); +} + +void DeviceChooser::Dialog::deviceChange(const QString &name) +{ + QListViewItemIterator it(_listView); + for (; it.current(); ++it) + if ( it.current()->text(0)==name ) { + _listView->setSelected(it.current(), true); + _listView->ensureItemVisible(it.current()); + break; + } +} + +void DeviceChooser::Dialog::resetFilters() +{ + _programmerCombo->setCurrentItem(""); + _toolCombo->setCurrentItem(""); + _memoryCombo->reset(); + _statusCombo->reset(); + _featureCombo->reset(); + updateList(); +} + +void DeviceChooser::Dialog::updateList() +{ + QListViewItem *item = _listView->selectedItem(); + QString device = (item ? item->text(0) : QString::null); + _listView->clear(); + updateList(device); +} + +const Programmer::Group *DeviceChooser::Dialog::programmerGroup() const +{ + return Programmer::lister().group(_programmerCombo->currentItem()); +} + +const Tool::Group *DeviceChooser::Dialog::toolGroup() const +{ + return Tool::lister().group(_toolCombo->currentItem()); +} + +void DeviceChooser::Dialog::updateList(const QString &device) +{ + QValueVector list = Device::lister().supportedDevices(); + QMap groups; + QListViewItem *selected = 0; + const Programmer::Group *pgroup = programmerGroup(); + if ( pgroup && pgroup->supportedDevices().isEmpty() && pgroup->isSoftware() ) { + _deviceView->setText(i18n("Could not detect supported devices for \"%1\". Please check installation.").arg(pgroup->label())); + return; + } + const Tool::Group *tgroup = toolGroup(); + if ( tgroup && tgroup->supportedDevices().isEmpty() ) { + _deviceView->setText(i18n("Could not detect supported devices for toolchain \"%1\". Please check installation.").arg(tgroup->label())); + return; + } + for (int i=list.count()-1; i>=0; i--) { + if ( pgroup && !pgroup->isSupported(list[i]) ) continue; + if ( tgroup && !tgroup->isSupported(list[i]) ) continue; + const Device::Data *data = Device::lister().data(list[i]); + Q_ASSERT(data); + if ( _memoryCombo->value()!=Device::MemoryTechnology::Nb_Types && data->memoryTechnology()!=_memoryCombo->value() ) continue; + if ( _statusCombo->value()!=Device::Status::Nb_Types && data->status()!=_statusCombo->value() ) continue; + if ( _featureCombo->value()!=Pic::Feature::Nb_Types ) { + if ( data->group().name()!="pic" ) continue; + if ( !static_cast(data)->hasFeature(_featureCombo->value()) ) continue; + } + KListViewItem *item = 0; + switch (_listTypeCombo->value().type()) { + case ListType::FamilyTree: { + QString gname = data->listViewGroup(); + if ( !groups.contains(gname) ) + groups[gname] = new ListItem(_listView, gname, false, false); + item = new ListItem(groups[gname], list[i]); + break; + } + case ListType::Flat: + item = new ListItem(_listView, list[i], true, true); + break; + case ListType::Nb_Types: Q_ASSERT(false); break; + } + if ( device==list[i] ) selected = item; + } + if (_withAuto) (void)new ListItem(_listView, i18n(Device::AUTO_DATA.label), true, false); + if ( selected==0 ) selected = _listView->firstChild(); + if (selected) { + _listView->setSelected(selected, true); + _listView->ensureItemVisible(selected); + currentChanged(selected); + } +} + +//----------------------------------------------------------------------------- +DeviceChooser::ComboBox::ComboBox(bool withAuto, QWidget *parent) + : QComboBox(parent, "device_chooser_combo"), _withAuto(withAuto) +{ + if (withAuto) insertItem(i18n(Device::AUTO_DATA.label)); + Device::Lister::ConstIterator it; + for (it=Device::lister().begin(); it!=Device::lister().end(); ++it) { + QValueVector devices = it.data()->supportedDevices(); + qHeapSort(devices); + for (uint k=0; kname() + " " + i18n(Device::AUTO_DATA.label), 0); + else changeItem(i18n(Device::AUTO_DATA.label), 0); + setCurrentItem(0); + } else setCurrentText(text); +} + +QString DeviceChooser::ComboBox::device() const +{ + if ( _withAuto && currentItem()==0 ) return Device::AUTO_DATA.name; + return currentText(); +} + +//----------------------------------------------------------------------------- +DeviceChooser::Button::Button(bool withAuto, QWidget *parent) + : QWidget(parent, "device_chooser_button") +{ + QHBoxLayout *hbox = new QHBoxLayout(this, 0, 10); + _combo = new ComboBox(withAuto, this); + connect(_combo, SIGNAL(activated(int)), SIGNAL(changed())); + hbox->addWidget(_combo); + KIconLoader loader; + QIconSet iconset = loader.loadIcon("fileopen", KIcon::Toolbar); + KPushButton *button = new KPushButton(iconset, QString::null, this); + connect(button, SIGNAL(clicked()), SLOT(chooseDevice())); + hbox->addWidget(button); +} + +void DeviceChooser::Button::chooseDevice() +{ + Dialog dialog(_combo->device(), (_combo->withAuto() ? ChooseWithAuto : Choose), this); + if ( !dialog.exec() || dialog.device().isEmpty() ) return; + _combo->setDevice(dialog.device()); + emit changed(); +} + +//----------------------------------------------------------------------------- +DeviceChooser::Browser::Browser(QWidget *parent) + : KTextBrowser(parent, "device_browser") +{} + +PURL::Url findDocumentUrl(const QString &prefix, const QString &baseName) +{ + PURL::Url previous = KURL::fromPathOrURL(prefix + baseName + ".pdf"); + bool previousExists = previous.exists(); + for (uint i=0; i<26; i++) { + PURL::Url url = KURL::fromPathOrURL(prefix + baseName + QChar('a' + i) + ".pdf"); + bool exists = url.exists(); + if ( !exists && previousExists ) return previous; + previous = url; + previousExists = exists; + } + return previous; +} + +void DeviceChooser::Browser::setSource(const QString &name) +{ + ::BusyCursor bc; + if ( name.startsWith("device://") ) emit deviceChanged(name.mid(9)); + else if ( name.startsWith("document://") ) { + QString prefix = "http://ww1.microchip.com/downloads/en/DeviceDoc/"; + PURL::Url url = findDocumentUrl(prefix, name.mid(11, name.length()-11-1)); + KTextBrowser::setSource(url.kurl().htmlURL()); + } + else KTextBrowser::setSource(name); +} + +//----------------------------------------------------------------------------- +DeviceChooser::View::View(QWidget *parent) + : TabWidget(parent, "device_view") +{ + // Information + _info = new Browser(this); + _info->setMimeSourceFactory(&_msf); + insertTab(_info, i18n("Information")); + connect(_info, SIGNAL(deviceChanged(const QString &)), + SIGNAL(deviceChanged(const QString &))); + + // Memory Map + _memory = new Browser(this); + _memory->setMimeSourceFactory(&_msf); + insertTab(_memory, i18n("Memory Map")); + + // Voltage-Frequency Graphs + _vfg = new Browser(this); + _vfg->setMimeSourceFactory(&_msf); + insertTab(_vfg, i18n("Voltage-Frequency Graphs")); + + // Pin Diagrams + _pins = new Browser(this); + _pins->setMimeSourceFactory(&_msf); + insertTab(_pins, i18n("Pin Diagrams")); +} + +void DeviceChooser::View::setDevice(const QString &name, bool cannotChangeDevice) +{ + const Device::Data *data = Device::lister().data(name); + if ( data==0 ) return; + QString doc = htmlInfo(*data, (cannotChangeDevice ? QString::null : "device:%1"), Device::documentHtml(*data)); + doc += Device::supportedHtmlInfo(*data); + _info->setText("" + doc + ""); + doc = htmlVoltageFrequencyGraphs(*data, QString::null, &_msf); + QPixmap pix = data->group().memoryGraph(*data); + QString label = data->name() + "_memory_map.png"; + _msf.setPixmap(label, pix); + _memory->setText(""); + _vfg->setText("" + doc + ""); + doc = htmlPinDiagrams(*data, QString::null, &_msf); + _pins->setText("" + doc + ""); +} + +void DeviceChooser::View::setText(const QString &text) +{ + _info->setText(text); + _vfg->setText(text); + _pins->setText(text); +} + +void DeviceChooser::View::clear() +{ + _info->clear(); + _vfg->clear(); + _pins->clear(); +} + +//----------------------------------------------------------------------------- +DeviceChooser::Editor::Editor(const QString &title, const QString &tag, QWidget *widget) + : DeviceEditor(title, tag, widget, "device_view_editor") +{} + +QWidget *DeviceChooser::Editor::createView(const Device::Data *, QWidget *parent) +{ + DeviceChooser::View *view = new DeviceChooser::View(parent); + connect(view, SIGNAL(deviceChanged(const QString &)), SIGNAL(deviceChanged(const QString &))); + view->setDevice(_device, true); + return view; +} diff --git a/src/libgui/device_gui.h b/src/libgui/device_gui.h new file mode 100644 index 0000000..a10c58a --- /dev/null +++ b/src/libgui/device_gui.h @@ -0,0 +1,205 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef DEVICE_GUI_H +#define DEVICE_GUI_H + +#include +#include +#include +class QListViewItem; +class QCheckBox; +#include +class KListView; + +#include "common/gui/key_gui.h" +#include "common/gui/dialog.h" +#include "device_editor.h" +#include "devices/pic/base/pic.h" +namespace Programmer { class Group; } +namespace Tool { class Group; } + +namespace DeviceChooser +{ + +enum Type { Choose, ChooseWithAuto }; +class View; + +BEGIN_DECLARE_ENUM(ListType) + FamilyTree = 0, Flat +END_DECLARE_ENUM_STD(ListType) + +//----------------------------------------------------------------------------- +class Config : public GenericConfig +{ +public: + Config() : GenericConfig("device_chooser") {} + const Programmer::Group *programmerGroup(); + void writeProgrammerGroup(const Programmer::Group *group); + const Tool::Group *toolGroup(); + void writeToolGroup(const Tool::Group *group); +}; + +//----------------------------------------------------------------------------- +template +class EnumComboBox +{ +public: + EnumComboBox(const QString &key, QWidget *parent) : _key(key) { + _combo = new QComboBox(parent); + for (Enum type; typeinsertItem(type.label()); + Config config; + Enum type = config.readEnumEntry(key, Enum(Enum::Nb_Types)); + if ( type!=Enum::Nb_Types ) _combo->setCurrentItem(type.type()); + } + EnumComboBox(const QString &emptyLabel, const QString &key, QWidget *parent) : _key(key) { + _combo = new QComboBox(parent); + _combo->insertItem(emptyLabel); + for (Enum type; typeinsertItem(type.label()); + Config config; + Enum type = config.readEnumEntry(key, Enum(Enum::Nb_Types)); + if ( type!=Enum::Nb_Types ) _combo->setCurrentItem(type.type()+1); + } + QComboBox *combo() { return _combo; } + Enum value() const { + if ( _combo->count()==Enum::Nb_Types ) return typename Enum::Type(_combo->currentItem()); + if ( _combo->currentItem()==0 ) return Enum::Nb_Types; + return typename Enum::Type(_combo->currentItem()-1); + } + void reset() { _combo->setCurrentItem(0); } + void writeConfig() { + Config config; + config.writeEnumEntry(_key, value()); + } + +private: + QString _key; + QComboBox *_combo; +}; + +//----------------------------------------------------------------------------- +class Dialog : public ::Dialog +{ +Q_OBJECT +public: + Dialog(const QString &device, Type type, QWidget *parent); + virtual ~Dialog(); + + QString device() const; + +private slots: + void listDoubleClicked(QListViewItem *item); + void currentChanged(QListViewItem *item); + void deviceChange(const QString &device); + void updateList(); + void resetFilters(); + +private: + bool _withAuto; + KeyComboBox *_programmerCombo, *_toolCombo; + EnumComboBox *_listTypeCombo; + EnumComboBox *_memoryCombo; + EnumComboBox *_statusCombo; + EnumComboBox *_featureCombo; + KListView *_listView; + View *_deviceView; + + void updateList(const QString &device); + const Programmer::Group *programmerGroup() const; + const Tool::Group *toolGroup() const; +}; + +//----------------------------------------------------------------------------- +class ComboBox : public QComboBox +{ +Q_OBJECT +public: + ComboBox(bool withAuto, QWidget *parent); + void setDevice(const QString &device, const Device::Data *data = 0); + QString device() const; + bool withAuto() const { return _withAuto; } + +private: + bool _withAuto; +}; + +//----------------------------------------------------------------------------- +class Button : public QWidget +{ +Q_OBJECT +public: + Button(bool withAuto, QWidget *parent); + void setDevice(const QString &device) { _combo->setDevice(device); } + QString device() const { return _combo->device(); } + +signals: + void changed(); + +private slots: + void chooseDevice(); + +private: + ComboBox *_combo; +}; + +//----------------------------------------------------------------------------- +class Browser : public KTextBrowser +{ +Q_OBJECT +public: + Browser(QWidget *parent); + +signals: + void deviceChanged(const QString &device); + +public slots: + virtual void setSource(const QString &name); +}; + +//----------------------------------------------------------------------------- +class View : public TabWidget +{ +Q_OBJECT +public: + View(QWidget *parent); + void clear(); + void setText(const QString &text); + void setDevice(const QString &name, bool cannotChangeDevice); + +signals: + void deviceChanged(const QString &device); + +private: + QMimeSourceFactory _msf; + Browser *_info, *_memory, *_vfg, *_pins; +}; + +//----------------------------------------------------------------------------- +class Editor : public DeviceEditor +{ +Q_OBJECT +public: + Editor(const QString &title, const QString &tag, QWidget *parent); + virtual bool isModified() const { return false; } + virtual bool isReadOnly() const { return true; } + virtual void addGui() {} + virtual void removeGui() {} + virtual void setFocus() {} + +signals: + void deviceChanged(const QString &device); + +private: + virtual QWidget *createView(const Device::Data *data, QWidget *parent); + virtual void setModifiedInternal(bool) {} + virtual void setReadOnlyInternal(bool) {} +}; + +} // namespace + +#endif diff --git a/src/libgui/editor.cpp b/src/libgui/editor.cpp new file mode 100644 index 0000000..c64d98f --- /dev/null +++ b/src/libgui/editor.cpp @@ -0,0 +1,91 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "editor.h" + +#include + +#include "common/gui/purl_gui.h" +#include "common/gui/misc_gui.h" + +Editor::Editor(const QString &title, const QString &tag, QWidget *parent, const char *name) + : QWidget(parent, name), _title(title), _tag(tag) +{} + +Editor::Editor(QWidget *parent, const char *name) + : QWidget(parent, name) +{} + +QSizePolicy Editor::sizePolicy() const +{ + return QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); +} + +void Editor::setModified(bool m) +{ + setModifiedInternal(m); + if (m) emit modified(); +} + +void Editor::setReadOnly(bool ro) +{ + setReadOnlyInternal(ro); + emit guiChanged(); +} + +bool Editor::save() +{ + if ( url().isEmpty() ) return saveAs(); + if ( !save(url()) ) return false; + setModified(false); + emit guiChanged(); + return true; +} + +bool Editor::saveAs() +{ + QString filter = PURL::filter(fileType()); + PURL::Url purl = PURL::getSaveUrl(":save_file_as", filter, this, i18n("Save File"), PURL::AskOverwrite); + if ( purl.isEmpty() ) return false; + if ( !save(purl) ) return false; + setModified(false); + emit guiChanged(); + return true; +} + +bool Editor::slotLoad() +{ + bool readOnly = isReadOnly(); + if ( !open(url()) ) return false; + setModified(false); + setReadOnly(readOnly); + statusChanged(); + emit guiChanged(); + return true; +} + +QString Editor::filename() const +{ + return (url().isEmpty() ? "<" + _title + ">" : "\"" + url().filepath() + "\""); +} + +bool Editor::checkSaved() +{ + if ( !isModified() ) return true; + MessageBox::Result res = MessageBox::questionYesNoCancel(i18n("File %1 not saved.").arg(filename()), + KStdGuiItem::save(), KStdGuiItem::discard()); + if ( res==MessageBox::Cancel ) return false; + if ( res==MessageBox::Yes ) save(); + return true; +} + +bool Editor::reload() +{ + if ( !checkSaved() ) return false; + return slotLoad(); +} diff --git a/src/libgui/editor.h b/src/libgui/editor.h new file mode 100644 index 0000000..9247c80 --- /dev/null +++ b/src/libgui/editor.h @@ -0,0 +1,68 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef EDITOR_H +#define EDITOR_H + +#include +#include +#include +#include "common/common/qflags.h" +#include +class KPopupMenu; + +#include "common/global/purl.h" + +class Editor : public QWidget +{ +Q_OBJECT +public: + Editor(const QString &title, const QString &tag, QWidget *parent, const char *name); + Editor(QWidget *parent, const char *name); + virtual QSizePolicy sizePolicy() const; + virtual PURL::FileType fileType() const = 0; + virtual bool isModified() const = 0; + void setModified(bool modified); + virtual PURL::Url url() const = 0; + QString name() const { return _title; } + QString tag() const { return _tag; } + void setReadOnly(bool readOnly); + virtual bool isReadOnly() const = 0; + bool checkSaved(); + bool reload(); + virtual void setFocus() = 0; + virtual bool open(const PURL::Url &url) = 0; + virtual bool save(const PURL::Url &url) = 0; + virtual void addGui() = 0; + virtual void removeGui() = 0; + virtual QValueList bookmarkLines() const = 0; + virtual void setBookmarkLines(const QValueList &lines) = 0; + +public slots: + bool slotLoad(); + bool save(); + bool saveAs(); + void toggleReadOnly() { setReadOnly(!isReadOnly()); } + virtual void statusChanged() = 0; + +signals: + void modified(); + void guiChanged(); + void statusTextChanged(const QString &text); + void dropEventPass(QDropEvent *e); + +protected: + QString filename() const; + virtual void setModifiedInternal(bool modified) = 0; + virtual void setReadOnlyInternal(bool readOnly) = 0; + +private: + QString _title, _tag; +}; + +#endif diff --git a/src/libgui/editor_manager.cpp b/src/libgui/editor_manager.cpp new file mode 100644 index 0000000..2a42554 --- /dev/null +++ b/src/libgui/editor_manager.cpp @@ -0,0 +1,506 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "editor_manager.h" + +#include +#include +#include + +#include +#include +#include +#include + +#include "text_editor.h" +#include "hex_editor.h" +#include "object_view.h" +#include "new_dialogs.h" +#include "main_global.h" +#include "gui_debug_manager.h" +#include "common/gui/purl_gui.h" +#include "device_gui.h" +#include "register_view.h" +#include "device_editor.h" +#include "project_manager.h" +#include "global_config.h" +#include "project.h" + +//----------------------------------------------------------------------------- +SwitchToDialog::SwitchToDialog(const QStringList &names, QWidget *parent) + : Dialog(parent, "switch_to_dialog", true, i18n("Switch to editor"), Ok | Cancel, Ok, false) +{ + QVBoxLayout *top = new QVBoxLayout(mainWidget(), 10, 10); + _edit = new KLineEdit(mainWidget()); + _edit->setCompletedItems(names); + top->addWidget(_edit); +} + +//----------------------------------------------------------------------------- +void EditorTabBar::paintLabel(QPainter *p, const QRect &br, QTab *t, bool has_focus) const +{ + QFont f = p->font(); + f.setItalic(_readOnly[t]); + p->setFont(f); + QTabBar::paintLabel(p, br, t, has_focus); +} + +//----------------------------------------------------------------------------- +QString EditorHistory::goBack() +{ + if ( !hasBack() ) return QString::null; + _current--; + return _names[_current]; +} + +QString EditorHistory::goForward() +{ + if ( !hasForward() ) return QString::null; + _current++; + return _names[_current]; +} + +void EditorHistory::add(const QString &name) +{ + if ( _names.count()!=0 ) { + _current = QMIN(_current, _names.count()-1); + if ( _names[_current]==name ) return; + if ( _current!=0 && _names[_current-1]==name ) { + _current--; + return; + } + _current++; + if ( _current<_names.count() && _names[_current]==name ) return; + } + _names.resize(_current+1); + _names[_current] = name; +} + +void EditorHistory::closedLast() +{ + if ( _names.count()==0 ) return; + _names.resize(_current); + if ( _current!=0 ) _current--; +} + +//----------------------------------------------------------------------------- +const char * const EditorManager::EDITOR_TAGS[Nb_EditorTypes] = { "device", "registers" }; + +EditorManager::EditorManager(QWidget *parent) + : TabWidget(parent, "editor_manager"), _current(0) +{ + setTabBar(new EditorTabBar(this)); + connect(this, SIGNAL(currentChanged(QWidget *)), SLOT(showEditor(QWidget *))); + setHoverCloseButton(readConfigEntry(BaseGlobalConfig::ShowTabCloseButton).toBool()); + setHoverCloseButtonDelayed(false); +} + +bool EditorManager::openFile(const PURL::Url &url) +{ + if ( url.isEmpty() ) return false; + Editor *e = findEditor(url); + if (e) { // document already loaded + if ( !MessageBox::askContinue(i18n("File \"%1\" already loaded. Reload?").arg(url.kurl().prettyURL()), + i18n("Warning"), i18n("Reload")) ) return true; + if ( !e->slotLoad() ) { + closeEditor(e, false); + return false; + } + return true; + } + if ( !openEditor(url) ) { + static_cast< KRecentFilesAction *>(Main::action("file_open_recent"))->removeURL(url.kurl()); + return false; + } + static_cast(Main::action("file_open_recent"))->addURL(url.kurl()); + return true; +} + +void EditorManager::connectEditor(Editor *editor) +{ + disconnectEditor(currentEditor()); + if ( editor==0 ) return; + editor->addGui(); + connect(editor, SIGNAL(modified()), SLOT(modifiedSlot())); + connect(editor, SIGNAL(guiChanged()), SIGNAL(guiChanged())); + connect(editor, SIGNAL(dropEventPass(QDropEvent *)), SLOT(slotDropEvent(QDropEvent *))); + connect(editor, SIGNAL(statusTextChanged(const QString &)), SIGNAL(statusChanged(const QString &))); +} + +void EditorManager::modifiedSlot() +{ + emit modified(currentEditor()->url()); +} + +void EditorManager::disconnectEditor(Editor *editor) +{ + if ( editor==0 ) return; + editor->disconnect(this); + editor->removeGui(); +} + +QString EditorManager::title(const Editor &e) const +{ + return (e.url().isEmpty() ? "<" + e.name() + ">" : e.url().filename()); +} + +void EditorManager::updateTitles() +{ + KIconLoader loader; + QPixmap def = loader.loadIcon("piklab", KIcon::Small); + QPixmap modified = loader.loadIcon("filesave", KIcon::Small); + QPixmap chip = loader.loadIcon("piklab_chip", KIcon::Small); + QValueList::iterator it = _editors.begin(); + for (; it!=_editors.end(); ++it) { + static_cast(tabBar())->setReadOnly(indexOf(*it), (*it)->isReadOnly()); + QPixmap pixmap; + if ( (*it)->isModified() ) pixmap = modified; + else if ( ::qt_cast< ::DeviceEditor *>(*it)==0 ) pixmap = PURL::icon((*it)->fileType()); + else pixmap = chip; + changeTab(*it, pixmap.isNull() ? def : pixmap, title(**it)); + } +} + +bool EditorManager::closeCurrentEditor() +{ + if ( !closeEditor(_current, true) ) return false; + emit guiChanged(); + return true; +} + +bool EditorManager::closeAllEditors() +{ + if ( currentEditor()==0 ) return true; + while ( currentEditor() ) + if ( !closeEditor(currentEditor(), true) ) break; + emit guiChanged(); + return ( currentEditor()==0 ); +} + +bool EditorManager::closeAllOtherEditors() +{ + if ( nbEditors()==1 ) return true; + QValueList list = _editors; + list.remove(currentEditor()); + QValueList::iterator it = list.begin(); + bool ok = true; + for (; it!=list.end(); ++it) { + if ( !closeEditor(*it, true) ) { + ok = false; + break; + } + } + emit guiChanged(); + return ok; +} + +bool EditorManager::closeEditor(const PURL::Url &url) +{ + Editor *e = findEditor(url); + if ( e==0 ) return true; + if ( !closeEditor(e, true) ) return false; + emit guiChanged(); + return true; +} + +void EditorManager::closeRequest(int i) +{ + closeEditor(static_cast(page(i)), true); + emit guiChanged(); +} + +bool EditorManager::closeEditor(Editor *e, bool ask) +{ + if ( e==0 ) return true; + if ( ask && !e->checkSaved() ) return false; + removePage(e); + _editors.remove(e); + Editor *g = static_cast(currentPage()); + changeToEditor(g); + saveBookmarks(*e); + delete e; + return true; +} + +void EditorManager::saveBookmarks(const Editor &e) +{ + if ( Main::project()==0 ) return; + QValueList lines = e.bookmarkLines(); + Main::project()->setBookmarkLines(e.url(), lines); +} + +void EditorManager::restoreBookmarks(Editor &e) +{ + if ( Main::project()==0 ) return; + QValueList lines = Main::project()->bookmarkLines(e.url()); + e.setBookmarkLines(lines); +} + +void EditorManager::showEditor(Editor *e) +{ + changeToEditor(e); + emit guiChanged(); +} + +void EditorManager::changeToEditor(Editor *e) +{ + if ( e==_current ) return; + connectEditor(e); + _current = e; + if (e) { + showPage(e); + e->clearFocus(); // force a got focus signal + e->setFocus(); + e->statusChanged(); + _history.add(name(*e)); + } else { + emit statusChanged(QString::null); + _history.closedLast(); + } +} + +Editor *EditorManager::findEditor(const QString &tag) +{ + QValueList::iterator it = _editors.begin(); + for (; it!=_editors.end(); ++it) if ( (*it)->tag()==tag ) return *it; + return 0; +} + +Editor *EditorManager::findEditor(const PURL::Url &url) +{ + QValueList::iterator it = _editors.begin(); + for (; it!=_editors.end(); ++it) if ( (*it)->url()==url ) return *it; + return 0; +} + +Editor *EditorManager::createEditor(PURL::FileType type, const PURL::Url &url) +{ + Editor *e = findEditor(url); + if (e) closeEditor(e, false); + switch (type.type()) { + case PURL::Hex: + e = new HexEditor(this); + break; + case PURL::CSource: + case PURL::CppSource: + case PURL::CHeader: + case PURL::AsmGPAsm: + case PURL::AsmPIC30: + case PURL::AsmPICC: + case PURL::Inc: + case PURL::JalSource: + case PURL::BasicSource: + e = new TextEditor(true, this); + break; + case PURL::Lkr: + case PURL::Gld: + case PURL::Map: + case PURL::Lst: + case PURL::Cod: + case PURL::Unknown: + e = new TextEditor(false, this); + break; + case PURL::Coff: + if ( Main::project()==0 ) { + if ( Main::deviceData()==0 ) return 0; + e = new Coff::CoffEditor(url, *Main::deviceData(), this); + } else { + if ( Debugger::manager->coff()==0 ) return 0; + e = new Coff::CoffEditor(*Debugger::manager->coff(), this); + } + static_cast(e)->setView(&Main::compileLog()); + break; + case PURL::Object: + e = new Coff::ObjectEditor(url, this); + static_cast(e)->setView(&Main::compileLog()); + break; + case PURL::Library: + e = new Coff::LibraryEditor(url, this); + static_cast(e)->setView(&Main::compileLog()); + break; + case PURL::Elf: + case PURL::Project: + case PURL::PikdevProject: + case PURL::Nb_FileTypes: break; + } + return e; +} + +void EditorManager::addEditor(Editor *e) +{ + QValueList::iterator it = _editors.begin(); + for (; it!=_editors.end(); ++it) if ( *it==e ) return; + _editors.append(e); + addTab(e, QString::null); + setTabEnabled(e, true); + restoreBookmarks(*e); + showEditor(e); +} + +void EditorManager::slotDropEvent(QDropEvent *event) +{ + QStringList urls; + if ( !QUriDrag::decodeLocalFiles(event, urls)) return; + QStringList::const_iterator it = urls.begin(); + for(; it!=urls.end(); ++it) openEditor(PURL::Url::fromPathOrUrl(*it)); +} + +Editor *EditorManager::openEditor(const PURL::Url &url) +{ + Editor *e = findEditor(url); + if ( e==0 ) { + e = createEditor(url.fileType(), url); + if ( e==0 ) return 0; + if ( !e->open(url) ) { + closeEditor(e, false); + return 0; + } + addEditor(e); + } else showEditor(e); + return e; +} + +void EditorManager::saveAllFiles() +{ + QValueList::iterator it = _editors.begin(); + for (; it!=_editors.end(); ++it) { + if ( !(*it)->isModified() ) continue; + (*it)->save(); + } + emit guiChanged(); +} + +PURL::UrlList EditorManager::files() const +{ + PURL::UrlList names; + QValueList::const_iterator it = _editors.begin(); + for(; it!=_editors.end(); ++it) { + if ( (*it)->url().isEmpty() ) continue; + names.push_back((*it)->url()); + } + return names; +} + +void EditorManager::contextMenu(int i, const QPoint &p) +{ + Editor *editor = static_cast(page(i)); + if ( editor==0 ) return; + + KIconLoader loader; + QPixmap closeIcon = loader.loadIcon("fileclose", KIcon::Small); + QPixmap saveIcon = loader.loadIcon("filesave", KIcon::Small); + QPixmap saveAsIcon = loader.loadIcon("filesaveas", KIcon::Small); + QPixmap reloadIcon = loader.loadIcon("reload", KIcon::Small); + KPopupMenu *popup = new KPopupMenu; + popup->insertTitle(title(*editor)); + popup->insertItem(closeIcon, i18n("Close"), 1); + if ( nbEditors()>1 ) popup->insertItem(i18n("Close All Others"), 2); + if ( editor->isModified() ) popup->insertItem(saveIcon, i18n("Save"), 3); + popup->insertItem(saveAsIcon, i18n("Save As..."), 4); + if ( !editor->url().isEmpty() ) popup->insertItem(reloadIcon, i18n("Reload"), 5); + switch (popup->exec(p)) { + case 1: closeEditor(editor, true); break; + case 2: closeAllOtherEditors(); break; + case 3: editor->save(); break; + case 4: editor->saveAs(); break; + case 5: editor->reload(); break; + } + emit guiChanged(); + delete popup; +} + +void EditorManager::switchHeaderImplementation() +{ + if ( currentEditor()==0 ) return; + PURL::Url url = currentEditor()->url(); + PURL::FileType type = url.fileType(); + PURL::SourceFamily source = type.data().sourceFamily; + if ( type.data().group==PURL::Source ) type = source.data().headerType; + else { + Q_ASSERT( type.data().group==PURL::Source ); + type = Main::toolGroup().implementationType(source.data().toolType); + } + if ( type==PURL::Nb_FileTypes ) return; + url = url.toFileType(type); + if ( !url.exists() ) return; + openEditor(url); +} + +void EditorManager::switchToEditor() +{ + QStringList names; + for (uint i=0; i<_editors.count(); i++) names.append(title(*_editors[i])); + SwitchToDialog dialog(names, this); + if ( dialog.exec()!=QDialog::Accepted ) return; + for (uint i=0; i(e)->setDevice(false); + static_cast(e)->setDevice(true); // #### needed to fix GUI glitch ??? + created = true; + } + break; + } + case RegisterEditor: { + e = findEditor(tag); + if ( e==0 ) { + ::BusyCursor bc; + e = new Register::MainView(i18n("Registers"), tag); + static_cast(Debugger::manager)->addRegisterView(*static_cast(e)); + created = true; + } + break; + } + case Nb_EditorTypes: Q_ASSERT(false); break; + } + if ( e==0 ) return 0; + if (created) { + if ( !e->slotLoad() ) { + delete e; + return 0; + } + addEditor(e); + } else showEditor(e); + return e; +} diff --git a/src/libgui/editor_manager.h b/src/libgui/editor_manager.h new file mode 100644 index 0000000..0d180b9 --- /dev/null +++ b/src/libgui/editor_manager.h @@ -0,0 +1,128 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#ifndef EDITOR_MANAGER_H +#define EDITOR_MANAGER_H + +class QEvent; +#include +#include +#include + +#include "text_editor.h" +#include "common/gui/misc_gui.h" +#include "common/gui/dialog.h" + +//----------------------------------------------------------------------------- +class SwitchToDialog : public Dialog +{ +Q_OBJECT +public: + SwitchToDialog(const QStringList &names, QWidget *parent); + QString name() const { return _edit->text(); } + +private: + KLineEdit *_edit; +}; + +//----------------------------------------------------------------------------- +class EditorTabBar : public TabBar +{ +Q_OBJECT +public: + EditorTabBar(QWidget *parent) : TabBar(parent, "editor_tab_bar") {} + void setReadOnly(uint index, bool readOnly) { _readOnly[tabAt(index)] = readOnly; } + +private: + QMap _readOnly; + virtual void paintLabel(QPainter *p, const QRect &br, QTab *t, bool has_focus) const; +}; + +//----------------------------------------------------------------------------- +class EditorHistory +{ +public: + EditorHistory() : _current(0) {} + bool hasBack() const { return _current!=0; } + bool hasForward() const { return (_current+1)<_names.count(); } + void add(const QString &name); + void closedLast(); + QString goBack(); + QString goForward(); + +private: + uint _current; + QValueVector _names; +}; + +//----------------------------------------------------------------------------- +class EditorManager : public TabWidget +{ +Q_OBJECT +public: + EditorManager(QWidget *parent); + + PURL::UrlList files() const; + QValueList &editors() { return _editors; } + uint nbEditors() const { return _editors.count(); } + Editor *createEditor(PURL::FileType type, const PURL::Url &url); + void addEditor(Editor *e); + Editor *currentEditor() const { return _current; } + Editor *findEditor(const PURL::Url &file); + Editor *findEditor(const QString &tag); + void showEditor(Editor *e); + bool closeEditor(const PURL::Url &url); + bool closeEditor(Editor *e, bool ask); + bool openFile(const PURL::Url &url); + Editor *openEditor(const PURL::Url &url); + void connectEditor(Editor *editor); + void disconnectEditor(Editor *editor); + const EditorHistory &history() const { return _history; } + enum EditorType { DeviceEditor = 0, RegisterEditor, Nb_EditorTypes }; + Editor *openEditor(EditorType type); + +public slots: + void updateTitles(); + void slotDropEvent(QDropEvent *e); + void saveAllFiles(); + bool closeCurrentEditor(); + bool closeAllEditors(); + bool closeAllOtherEditors(); + void switchHeaderImplementation(); + void switchToEditor(); + void goBack(); + void goForward(); + +signals: + void modified(const PURL::Url &url); + void guiChanged(); + void statusChanged(const QString &); + +private: + void changeToEditor(Editor *e); + void enableActions(bool enable); + QString title(const Editor &e) const; + QString name(const Editor &e) const; + virtual void contextMenu(int i, const QPoint &p); + void saveBookmarks(const Editor &e); + void restoreBookmarks(Editor &e); + +private slots: + void showEditor(QWidget *w) { showEditor(static_cast(w)); } + void closeRequest(int i); + void modifiedSlot(); + +private: + Editor *_current; + QValueList _editors; + EditorHistory _history; + static const char * const EDITOR_TAGS[Nb_EditorTypes]; +}; + +#endif diff --git a/src/libgui/global_config.cpp b/src/libgui/global_config.cpp new file mode 100644 index 0000000..8424450 --- /dev/null +++ b/src/libgui/global_config.cpp @@ -0,0 +1,106 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "global_config.h" + +#include +#include +#include + +#include "progs/list/prog_list.h" +#include "tools/list/tool_list.h" + +const BaseGlobalConfig::Data BaseGlobalConfig::DATA[Nb_Types] = { + { "auto_rebuild_modified", I18N_NOOP("Automatically rebuild project before programming if it is modified."), QVariant(true, 0) }, + { "program_after_build", I18N_NOOP("Program device after successful build."), QVariant(false, 0) }, + { "user_id_set_to_checksum", I18N_NOOP("Set User Ids to unprotected checksum (if User Ids are empty)."), QVariant(false, 0) }, + { "show_tab_close_buttons", I18N_NOOP("Show close buttons on tabs (need restart to take effect)."), QVariant(true, 0) } +}; + +PURL::Url GlobalConfig::openedProject() +{ + GenericConfig config(QString::null); + return PURL::Url::fromPathOrUrl(config.readEntry("project", QString::null)); +} +void GlobalConfig::writeOpenedProject(const PURL::Url &p) +{ + GenericConfig config(QString::null); + config.writeEntry("project", p.filepath()); +} + +PURL::UrlList GlobalConfig::openedFiles() +{ + GenericConfig config(QString::null); + PURL::UrlList files; + uint i = 0; + for (;;) { + QString file = config.readEntry(QString("file%1").arg(i), QString::null); + if ( file.isEmpty() ) break; + files += PURL::Url::fromPathOrUrl(file); + i++; + } + return files; +} +void GlobalConfig::writeOpenedFiles(const PURL::UrlList &files) +{ + GenericConfig config(QString::null); + for (uint i=0; i<=files.count(); i++) { + QString s = (i==files.count() ? QString::null : files[i].filepath()); + config.writeEntry(QString("file%1").arg(i), s); + } +} + +void GlobalConfig::writeProgrammerGroup(const Programmer::Group &group) +{ + GenericConfig config(QString::null); + config.writeEntry("programmer", group.name()); +} +const Programmer::Group &GlobalConfig::programmerGroup() +{ + GenericConfig config(QString::null); + QString s = config.readEntry("programmer"); + const Programmer::Group *group = Programmer::lister().group(s); + if ( group==0 ) return *Programmer::lister().begin().data(); + return *group; +} + +void GlobalConfig::writeDebugLevel(Log::DebugLevel level) +{ + GenericConfig config(QString::null); + config.writeEnumEntry("log_debug_level", level); +} +Log::DebugLevel GlobalConfig::debugLevel() +{ + GenericConfig config(QString::null); + return config.readEnumEntry("log_debug_level", Log::DebugLevel::Normal); +} + +void GlobalConfig::writeLogOutputType(Log::OutputType type) +{ + GenericConfig config(QString::null); + config.writeEntry("log_output_type", type); +} +Log::OutputType GlobalConfig::logOutputType() +{ + GenericConfig config(QString::null); + uint output = config.readUIntEntry("log_output_type", Log::GuiOnly); + if ( output>=Log::Nb_OutputTypes ) return Log::GuiOnly; + return Log::OutputType(output); +} + +void GlobalConfig::writeShowLineNumbers(bool show) +{ + GenericConfig config(QString::null); + config.writeEntry("show_line_numbers", show); +} +bool GlobalConfig::showLineNumbers() +{ + GenericConfig config(QString::null); + return config.readBoolEntry("show_line_numbers", false); +} diff --git a/src/libgui/global_config.h b/src/libgui/global_config.h new file mode 100644 index 0000000..8e5cfaa --- /dev/null +++ b/src/libgui/global_config.h @@ -0,0 +1,39 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#ifndef GLOBAL_CONFIG_H +#define GLOBAL_CONFIG_H + +#include "progs/base/generic_prog.h" +#include "common/global/purl.h" +#include "tools/base/tool_group.h" +#include "log_view.h" + +BEGIN_DECLARE_CONFIG(BaseGlobalConfig) + AutoRebuildModified, ProgramAfterBuild, UserIdSetToChecksum, + ShowTabCloseButton +END_DECLARE_CONFIG(BaseGlobalConfig, "") + +namespace GlobalConfig +{ +extern PURL::Url openedProject(); +extern void writeOpenedProject(const PURL::Url &p); +extern PURL::UrlList openedFiles(); +extern void writeOpenedFiles(const PURL::UrlList &files); +extern void writeProgrammerGroup(const Programmer::Group &group); +extern const Programmer::Group &programmerGroup(); +extern void writeDebugLevel(Log::DebugLevel level); +extern Log::DebugLevel debugLevel(); +extern void writeLogOutputType(Log::OutputType type); +extern Log::OutputType logOutputType(); +extern void writeShowLineNumbers(bool show); +extern bool showLineNumbers(); +} // namespace + +#endif diff --git a/src/libgui/gui_debug_manager.cpp b/src/libgui/gui_debug_manager.cpp new file mode 100644 index 0000000..adda68a --- /dev/null +++ b/src/libgui/gui_debug_manager.cpp @@ -0,0 +1,249 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "gui_debug_manager.h" + +#include "toplevel.h" +#include "text_editor.h" +#include "project.h" +#include "tools/list/compile_config.h" +#include "register_view.h" +#include "watch_view.h" +#include "project_manager.h" +#include "editor_manager.h" +#include "main_global.h" +#include "coff/base/text_coff.h" +#include "progs/base/generic_prog.h" +#include "gui_prog_manager.h" +#include "breakpoint_view.h" +#include "progs/base/prog_group.h" + +bool Debugger::GuiManager::addEditor(Editor &editor) +{ + if ( _editors.find(&editor)!=_editors.end() ) return false; + connect(&editor, SIGNAL(destroyed()), SLOT(editorDestroyed())); + _editors.append(&editor); + return true; +} + +void Debugger::GuiManager::addRegisterView(Register::MainView &view) +{ + if ( !addEditor(view) ) return; + updateRegisters(); +} + +void Debugger::GuiManager::addTextEditor(TextEditor &editor) +{ + if ( !addEditor(editor) ) return; + updateView(false); +} + +void Debugger::GuiManager::clearEditors() +{ + QValueList::iterator it = _editors.begin(); + for (; it!=_editors.end(); ++it) (*it)->disconnect(this); + _editors.clear(); +} + +void Debugger::GuiManager::editorDestroyed() +{ + QValueList::iterator it = _editors.begin(); + for (; it!=_editors.end(); ++it) { + if ( (*it)!=sender() ) continue; + _editors.remove(it); + break; + } +} + +void Debugger::GuiManager::updateDevice() +{ + Manager::updateDevice(); + Main::watchView().init(false); +} + +PURL::Url Debugger::GuiManager::coffUrl() const +{ + return Main::projectManager().projectUrl().toFileType(PURL::Coff); +} + +bool Debugger::GuiManager::internalInit() +{ + if ( !Manager::internalInit() ) return false; + if ( !Main::projectManager().contains(coffUrl()) ) + Main::projectManager().addExternalFile(coffUrl(), ProjectManager::Generated); + Main::watchView().init(true); + if ( registerView() ) registerView()->view()->updateView(); + return true; +} + +bool Debugger::GuiManager::checkState(bool &first) +{ + if ( !Debugger::Manager::checkState(first) ) return false; + if ( first && !Main::toolGroup().generateDebugInformation(Main::device()) ) + MessageBox::information(i18n("The toolchain in use does not generate all necessary debugging information with the selected device. This may reduce debugging capabilities."), Log::Show, "doesnt_generate_debug_information"); + return true; +} + +Breakpoint::Data Debugger::GuiManager::currentBreakpointData() +{ + const Breakpoint::Data *data = Main::breakpointsView().currentData(); + if (data) return *data; + TextEditor *editor = ::qt_cast(Main::currentEditor()); + Q_ASSERT(editor); + return Breakpoint::Data(editor->url(), editor->cursorLine()); +} + +void Debugger::GuiManager::toggleBreakpoint() +{ + if ( !Main::programmerGroup().isDebugger() ) { + MessageBox::sorry(i18n("You cannot set breakpoints when a debugger is not selected."), Log::Show); + return; + } + Breakpoint::Data data = currentBreakpointData(); + if ( Breakpoint::list().contains(data) ) { + Breakpoint::list().remove(data); + return; + } + Address address; + if ( !checkBreakpoint(data, false, address) ) return; + Breakpoint::list().append(data); + Breakpoint::list().setAddress(data, address); + if (_coff) toggleEnableBreakpoint(); +} + +void Debugger::GuiManager::toggleEnableBreakpoint() +{ + Q_ASSERT(_coff); + Breakpoint::Data data = currentBreakpointData(); + bool isActive = ( Breakpoint::list().state(data)==Breakpoint::Active ); + if ( !Breakpoint::list().address(data).isValid() ) { + if ( !isActive ) MessageBox::sorry(i18n("Breakpoint at non-code line cannot be activated."), Log::Show); + } else { + if ( !isActive ) { + freeActiveBreakpoint(); + Breakpoint::list().setState(data, Breakpoint::Active); + } else Breakpoint::list().setState(data, Breakpoint::Disabled); + } +} + +void Debugger::GuiManager::updateEditorMarks(TextEditor &editor) const +{ + editor.clearBreakpointMarks(); + // update breakpoints + bool reached = false; + for (uint i=0; ilineForAddress(editor.url(), address); + else if ( data.url==editor.url() ) line = data.line; + Breakpoint::MarkType type = breakpointType(data); + if ( line!=-1 ) editor.setMark(line, type); + if ( type==Breakpoint::BreakpointReached ) reached = true; + } + // update pc + if ( _coff && programmer() && programmer()->isActive() && pc().isInitialized() && !reached + && _currentSourceLines.contains(editor.url()) ) { + int pcline = _currentSourceLines[editor.url()]; + if ( programmer()->state()==Programmer::Halted ) editor.setMark(pcline, Breakpoint::ProgramCounterActive); + else editor.setMark(pcline, Breakpoint::ProgramCounterDisabled); + } +} + +void Debugger::GuiManager::clear() +{ + Manager::clear(); + Main::watchView().init(true); +} + +bool Debugger::GuiManager::update(bool gotoPC) +{ + bool on = (programmer() ? programmer()->isTargetPowerOn() : false); + static_cast(Main::action("prog_power"))->setChecked(on); + return Manager::update(gotoPC); +} + +bool Debugger::GuiManager::checkIfContinueStepping(bool &continueStepping) +{ + if ( Main::toolGroup().generateDebugInformation(Main::device()) ) + return Debugger::Manager::checkIfContinueStepping(continueStepping); + if ( !update(false) ) return false; + continueStepping = false; + return true; +} + +void Debugger::GuiManager::updateView(bool gotoPC) +{ + Main::breakpointsView().updateView(); + bool currentHasPC = false; + QValueList::iterator ite; + for (ite=_editors.begin(); ite!=_editors.end(); ++ite) { + TextEditor *e = ::qt_cast(*ite); + if ( e==0 ) continue; + updateEditorMarks(*e); + if ( !_currentSourceLines.contains(e->url()) ) continue; + if (gotoPC) e->setCursor(_currentSourceLines[e->url()], 0); + if ( e==Main::currentEditor() ) currentHasPC = true; + } + if ( programmer()==0 || programmer()->state()!=Programmer::Halted || !pc().isInitialized() || currentHasPC ) return; + // 1: look at files inside project and not generated + // 2: look at files inside project + // 3: look at existing files + for (uint i=0; i<3; i++) { + QMap::const_iterator it; + for (it=_currentSourceLines.begin(); it!=_currentSourceLines.end(); ++it) { + switch (i) { + case 0: if ( !Main::projectManager().contains(it.key()) || Main::projectManager().isExternalFile(it.key()) ) continue; break; + case 1: if ( !Main::projectManager().contains(it.key()) ) continue; break; + case 2: if ( !it.key().exists() ) continue; break; + } + TextEditor *e = ::qt_cast(Main::editorManager().findEditor(it.key())); + if ( e==0 ) { + if (gotoPC) e = ::qt_cast(Main::editorManager().openEditor(it.key())); + if ( e==0 ) continue; + } + updateEditorMarks(*e); + if (gotoPC) { + e->setCursor(_currentSourceLines[e->url()], 0); + Main::editorManager().showEditor(e); + } + return; + } + } +} + +Register::MainView *Debugger::GuiManager::registerView() const +{ + QValueList::const_iterator it = _editors.begin(); + for (; it!=_editors.end(); ++it) { + Register::MainView *rv = ::qt_cast(*it); + if (rv) return rv; + } + return 0; +} + +bool Debugger::GuiManager::isProjectSource(const PURL::Url &url) const +{ + return ( Main::projectManager().contains(url) && !Main::projectManager().isExternalFile(url) ); +} + +void Debugger::GuiManager::showDisassemblyLocation() +{ + TextEditor *editor = ::qt_cast(Main::currentEditor()); + Q_ASSERT(editor); + Q_ASSERT(_coff); + QValueVector
addresses = _coff->addresses(editor->url(), editor->cursorLine()); + if ( addresses.isEmpty() ) { + MessageBox::sorry(i18n("Cannot show disassembly location for non-code line."), Log::Show); + return; + } + int line = _coff->lineForAddress(_coff->url(), addresses[0]); + if ( line==-1 ) return; // possible ? + TextEditor *e = ::qt_cast(Main::editorManager().openEditor(_coff->url())); + if (e) e->setCursor(line, 0); +} diff --git a/src/libgui/gui_debug_manager.h b/src/libgui/gui_debug_manager.h new file mode 100644 index 0000000..661f86a --- /dev/null +++ b/src/libgui/gui_debug_manager.h @@ -0,0 +1,61 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef GUI_DEBUG_MANAGER_H +#define GUI_DEBUG_MANAGER_H + +#include "progs/manager/debug_manager.h" +#include "text_editor.h" +#include "main_global.h" +#include "tools/list/compile_process.h" +namespace Register { class MainView; } + +namespace Debugger +{ +class GuiManager : public Manager +{ +Q_OBJECT +public: + GuiManager() {} + virtual void updateDevice(); + void addTextEditor(TextEditor &editor); + void addRegisterView(Register::MainView &view); + void clearEditors(); + virtual void clear(); + +public slots: + virtual bool update(bool gotoPC); + void toggleBreakpoint(); + void toggleEnableBreakpoint(); + void showPC() { updateView(true); } + void showDisassemblyLocation(); + +private slots: + void editorDestroyed(); + +private: + QValueList _editors; + + static Breakpoint::Data currentBreakpointData(); + void updateEditorMarks(TextEditor &editor) const; // return PC line + Register::MainView *registerView() const; + bool addEditor(Editor &editor); + virtual bool internalInit(); + virtual bool checkState(bool &first); + virtual const Programmer::Group *programmerGroup() const { return &Main::programmerGroup(); } + virtual const Device::Data *deviceData() const { return Main::deviceData(); } + virtual PURL::Url coffUrl() const; + virtual Log::View *compileView() { return &Main::compileLog(); } + virtual void updateView(bool gotoPC); + virtual bool isProjectSource(const PURL::Url &url) const; + virtual bool checkIfContinueStepping(bool &continueStepping); +}; + +} // namespace + +#endif diff --git a/src/libgui/gui_prog_manager.cpp b/src/libgui/gui_prog_manager.cpp new file mode 100644 index 0000000..ea22d7e --- /dev/null +++ b/src/libgui/gui_prog_manager.cpp @@ -0,0 +1,72 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "gui_prog_manager.h" + +#include + +#include "progs/base/generic_prog.h" +#include "progs/base/prog_group.h" +#include "progs/base/prog_config.h" +#include "progs/base/hardware_config.h" +#include "progs/base/generic_debug.h" +#include "progs/gui/prog_group_ui.h" +#include "toplevel.h" +#include "project.h" +#include "project_manager.h" +#include "progs/manager/debug_manager.h" + +//---------------------------------------------------------------------------- +bool Programmer::GuiManager::internalInitProgramming(bool debugging) +{ + if ( !Manager::internalInitProgramming(debugging) ) return false; + if ( !debugging && _programmer->isActive() ) { + if ( group().isDebugger() && !askContinue(i18n("The selected operation will stop the debugging session. Continue anyway?")) ) return false; + if ( !halt() ) return false; + } + if ( debugging && !_programmer->isActive() ) { + if ( ::Debugger::manager->coff()==0 && !::Debugger::manager->init() ) { + sorry(i18n("Cannot start debugging without a COFF file. Please compile the project.")); + return false; + } + if ( !group().isSoftware() ) { + if ( !askContinue(i18n("The device memory is in an unknown state. You may want to reprogram the device. Continue anyway?")) ) + return false; + } + } + return true; +} + +void Programmer::GuiManager::toggleDevicePower() +{ + bool on = static_cast(Main::action("prog_power"))->isChecked(); + setDevicePower(on); +} + +void Programmer::GuiManager::showAdvancedDialog() +{ + const ::Programmer::GroupUI *groupui = static_cast(group().gui()); + const Device::Data *data = Main::deviceData(); + if ( data && !group().isSupported(data->name()) ) data = 0; + createProgrammer(data); + ::Programmer::AdvancedDialog *dialog = groupui->createAdvancedDialog(*_programmer, &Main::toplevel()); + Q_ASSERT(dialog); + dialog->updateDisplay(); + dialog->exec(); + delete dialog; +} + +void Programmer::GuiManager::createProgrammer(const Device::Data *data) +{ + HardwareDescription hd; + hd.port = GroupConfig::portDescription(group()); + ::Hardware::Config *hconfig = group().hardwareConfig(); + if (hconfig) hd.name = hconfig->currentHardware(hd.port.type); + delete hconfig; + Manager::createProgrammer(data, hd); +} diff --git a/src/libgui/gui_prog_manager.h b/src/libgui/gui_prog_manager.h new file mode 100644 index 0000000..b19186e --- /dev/null +++ b/src/libgui/gui_prog_manager.h @@ -0,0 +1,37 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef GUI_PROG_MANAGER_H +#define GUI_PROG_MANAGER_H + +#include "progs/manager/prog_manager.h" +#include "libgui/main_global.h" + +namespace Programmer +{ +class GuiManager : public Manager +{ +Q_OBJECT +public: + GuiManager(QObject *parent) : Manager(parent) {} + virtual void createProgrammer(const Device::Data *data); + virtual void setState(State state) { Main::setState(state==Idle ? Main::Idle : Main::Programming); } + +public slots: + void toggleDevicePower(); + void showAdvancedDialog(); + +private: + virtual const Group &group() const { return Main::programmerGroup(); } + virtual bool internalInitProgramming(bool debugging); + virtual const Device::Data *device() const { return Main::deviceData(); } +}; + +} // namespace + +#endif diff --git a/src/libgui/hex_editor.cpp b/src/libgui/hex_editor.cpp new file mode 100644 index 0000000..48ad7e8 --- /dev/null +++ b/src/libgui/hex_editor.cpp @@ -0,0 +1,192 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * Copyright (C) 2003 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "hex_editor.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "devices/base/device_group.h" +#include "devices/gui/device_group_ui.h" +#include "devices/gui/hex_view.h" +#include "toplevel.h" +#include "common/global/pfile.h" +#include "main_global.h" + +//----------------------------------------------------------------------------- +HexEditorPart::HexEditorPart(HexEditor *editor) + : KParts::ReadWritePart(editor, "hex_editor_part") +{ + setXMLFile("hexeditorpartui.rc"); + + (void)KStdAction::save(editor, SLOT(save()), actionCollection()); + (void)KStdAction::saveAs(editor, SLOT(saveAs()), actionCollection()); + (void)new KToggleAction(i18n("Read Only Mode"), 0, 0, editor, SLOT(toggleReadOnly()), actionCollection(), "tools_toggle_write_lock"); +} + +void HexEditorPart::setReadWrite(bool rw) +{ + KParts::ReadWritePart::setReadWrite(rw); + static_cast(action("tools_toggle_write_lock"))->setChecked(!rw); +} + +//----------------------------------------------------------------------------- +HexEditor::HexEditor(const QString &name, QWidget *parent) + : DeviceEditor(name, QString::null, parent, "hex_editor") +{ + init(); +} + +HexEditor::HexEditor(QWidget *parent) + : DeviceEditor(parent, "hex_editor") +{ + init(); +} + +void HexEditor::init() +{ + _modified = false; + _memory = 0; + _originalMemory = 0; + _top->addStretch(1); + _part = new HexEditorPart(this); + setReadOnly(false); +} + +void HexEditor::clear() +{ + delete _memory; + _memory = 0; + delete _originalMemory; + _originalMemory = 0; +} + +QWidget *HexEditor::createView(const Device::Data *data, QWidget *parent) +{ + clear(); + if (data) { + _originalMemory = data->group().createMemory(*data); + _memory = data->group().createMemory(*data); + } + if ( data==0 ) return new QWidget(parent); + Device::HexView *hv = Device::groupui(*data).createHexView(*this, parent); + connect(hv, SIGNAL(modified()), SLOT(slotModified())); + _dirty = true; + QTimer::singleShot(0, this, SLOT(simpleLoad())); + return hv; +} + +bool HexEditor::simpleLoad() +{ + if ( !_dirty ) return true; + _dirty = false; + if (_memory) { + QStringList warnings; + if ( _memory->fromHexBuffer(_hexBuffer, warnings)!=Device::Memory::NoWarning ) { + _labelWarning->setText(i18n("Warning: hex file seems to be incompatible with the selected device %1:
%2") + .arg(_memory->device().name()).arg(warnings.join("
"))); + _labelWarning->show(); + } else _labelWarning->hide(); + display(); + } + return true; +} + +void HexEditor::setReadOnlyInternal(bool readOnly) +{ + _part->setReadWrite(!readOnly); + if (_memory) static_cast(_view)->setReadOnly(readOnly); +} + +void HexEditor::addGui() +{ + Main::toplevel().guiFactory()->addClient(_part); +} + +void HexEditor::removeGui() +{ + Main::toplevel().guiFactory()->removeClient(_part); +} + +bool HexEditor::open(const PURL::Url &url) +{ + _url = url; + PURL::File file(url, Main::compileLog()); + if ( !file.openForRead() ) return false; + QStringList errors; + if ( !_hexBuffer.load(file.stream(), errors) ) { + MessageBox::detailedSorry(i18n("Error(s) reading hex file."), errors.join("\n"), Log::Show); + return false; + } + _dirty = true; + return simpleLoad(); +} + +bool HexEditor::save(const PURL::Url &url) +{ + return save(url, i18n("File URL: \"%1\".").arg(url.pretty())); +} + +bool HexEditor::save(const PURL::Url &url, const QString &fileErrorString) +{ + PURL::File file(url, Main::compileLog()); + if ( !file.openForWrite() ) return false; + if ( !_memory->save(file.stream(), HexBuffer::IHX32) ) { + MessageBox::detailedSorry(i18n("Error while writing file \"%1\".").arg(url.pretty()), fileErrorString, Log::Show); + return false; + } + _originalMemory->copyFrom(*_memory); + _url = url; + return file.close(); +} + +void HexEditor::display() +{ + _modified = false; + if (_memory) { + _originalMemory->copyFrom(*_memory); + static_cast(_view)->display(_memory); + static_cast(_view)->setReadOnly(isReadOnly()); + static_cast(_view)->updateDisplay(); + } + statusChanged(); +} + +void HexEditor::memoryRead() +{ + display(); + emit guiChanged(); +} + +void HexEditor::slotModified() +{ + static_cast(_view)->updateDisplay(); + _modified = true; + statusChanged(); + emit guiChanged(); +} + +void HexEditor::statusChanged() +{ + QString s; + if (_memory) { + BitValue cs = static_cast(_view)->checksum(); + s = i18n("Checksum: %1").arg(toHexLabel(cs, 4)); + } + emit statusTextChanged(s); +} diff --git a/src/libgui/hex_editor.h b/src/libgui/hex_editor.h new file mode 100644 index 0000000..86b7f2c --- /dev/null +++ b/src/libgui/hex_editor.h @@ -0,0 +1,83 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * Copyright (C) 2003 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#ifndef HEX_EDITOR_H +#define HEX_EDITOR_H + +#include + +#include "device_editor.h" +#include "devices/base/hex_buffer.h" +#include "devices/base/generic_memory.h" + +//----------------------------------------------------------------------------- +class HexEditor; + +class HexEditorPart : public KParts::ReadWritePart +{ +Q_OBJECT +public: + HexEditorPart(HexEditor *editor); + virtual void setReadWrite(bool readWrite); + +private: + virtual bool openFile() { return true; } + virtual bool saveFile() { return true; } +}; + +//----------------------------------------------------------------------------- +class HexEditor : public DeviceEditor +{ +Q_OBJECT +public: + HexEditor(const QString &name, QWidget *parent); + HexEditor(QWidget *parent); + virtual bool isModified() const { return _modified; } + virtual bool isReadOnly() const { return !_part->isReadWrite(); } + virtual ~HexEditor() { clear(); } + virtual PURL::FileType fileType() const { return PURL::Hex; } + virtual PURL::Url url() const { return _url; } + virtual bool save(const PURL::Url &url); + virtual bool open(const PURL::Url &url); + Device::Memory *memory() { return _memory; } + const Device::Memory *memory() const { return _memory; } + const Device::Memory *originalMemory() const { return _originalMemory; } + void memoryRead(); + virtual void addGui(); + virtual void removeGui(); + virtual void setFocus() {} + virtual QValueList bookmarkLines() const { return QValueList(); } + virtual void setBookmarkLines(const QValueList &) {} + +public slots: + virtual void statusChanged(); + +private slots: + void slotModified(); + bool simpleLoad(); + +private: + Device::Memory *_originalMemory, *_memory; + HexBuffer _hexBuffer; + bool _modified, _dirty; + HexEditorPart *_part; + PURL::Url _url; + + virtual void dropEvent(QDropEvent *e) { emit dropEventPass(e); } + bool save(const PURL::Url &url, const QString &fileErrorString); + bool verifyDeviceType(); + virtual QWidget *createView(const Device::Data *data, QWidget *parent); + virtual void setModifiedInternal(bool modified) { _modified = modified; } + virtual void setReadOnlyInternal(bool readOnly); + void display(); + void init(); + void clear(); +}; + +#endif diff --git a/src/libgui/likeback.cpp b/src/libgui/likeback.cpp new file mode 100644 index 0000000..eac86ff --- /dev/null +++ b/src/libgui/likeback.cpp @@ -0,0 +1,668 @@ +/*************************************************************************** + * Copyright (C) 2006 by S�bastien Laot * + * slaout@linux62.org * + * * + * 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., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "netwm.h" + +#include + +#include + +#include "likeback.h" + +#include +#include "common/global/about.h" + +LikeBack::LikeBack(Button buttons) + : QWidget( 0, "LikeBack", Qt::WX11BypassWM | Qt::WStyle_NoBorder | Qt::WNoAutoErase | Qt::WStyle_StaysOnTop | Qt::WStyle_NoBorder | Qt::Qt::WGroupLeader) + , m_buttons(buttons) +{ + QHBoxLayout *layout = new QHBoxLayout(this); + + QIconSet likeIconSet = kapp->iconLoader()->loadIconSet("likeback_like", KIcon::Small); + QIconSet dislikeIconSet = kapp->iconLoader()->loadIconSet("likeback_dislike", KIcon::Small); + QIconSet bugIconSet = kapp->iconLoader()->loadIconSet("likeback_bug", KIcon::Small); +// QIconSet configureIconSet = kapp->iconLoader()->loadIconSet("configure", KIcon::Small); + + QToolButton *m_likeButton = new QToolButton(this, "ilike"); + m_likeButton->setIconSet(likeIconSet); + m_likeButton->setTextLabel(i18n("I Like...")); + m_likeButton->setAutoRaise(true); + connect( m_likeButton, SIGNAL(clicked()), this, SLOT(iLike()) ); + layout->add(m_likeButton); + + QToolButton *m_dislikeButton = new QToolButton(this, "idonotlike"); + m_dislikeButton->setIconSet(dislikeIconSet); + m_dislikeButton->setTextLabel(i18n("I Do not Like...")); + m_dislikeButton->setAutoRaise(true); + connect( m_dislikeButton, SIGNAL(clicked()), this, SLOT(iDoNotLike()) ); + layout->add(m_dislikeButton); + + QToolButton *m_bugButton = new QToolButton(this, "ifoundabug"); + m_bugButton->setIconSet(bugIconSet); + m_bugButton->setTextLabel(i18n("I Found a Bug...")); + m_bugButton->setAutoRaise(true); + connect( m_bugButton, SIGNAL(clicked()), this, SLOT(iFoundABug()) ); + layout->add(m_bugButton); + + m_configureButton = new QToolButton(this, "configure"); + QIconSet helpIconSet = kapp->iconLoader()->loadIconSet("help", KIcon::Small); + m_configureButton->setIconSet(helpIconSet); + m_configureButton->setTextLabel(i18n("Configure...")); + m_configureButton->setAutoRaise(true); + connect( m_likeButton, SIGNAL(clicked()), this, SLOT(configure()) ); + layout->add(m_configureButton); + + QPopupMenu *configureMenu = new QPopupMenu(this); + configureMenu->insertItem(helpIconSet, i18n("What's &This?"), this , SLOT(showWhatsThisMessage()) ); + QIconSet changeEmailIconSet = kapp->iconLoader()->loadIconSet("mail_generic", KIcon::Small); + configureMenu->insertItem(changeEmailIconSet, i18n("&Configure Email Address..."), this , SLOT(askEMail()) ); +// QIconSet dontHelpIconSet = kapp->iconLoader()->loadIconSet("stop", KIcon::Small); +// configureMenu->insertItem( dontHelpIconSet, i18n("&Do not Help Anymore"), this , SLOT(doNotHelpAnymore()) ); + m_configureButton->setPopup(configureMenu); + connect( m_configureButton, SIGNAL(pressed()), this, SLOT(openConfigurePopup()) ); + + if (!emailAddressAlreadyProvided()) + //beginFetchingEmail(); // Begin before showing the message, so we have time! + endFetchingEmailFrom(); + +// static const char *messageShown = "LikeBack_starting_information"; +// if (KMessageBox::shouldBeShownContinue(messageShown)) { +// showInformationMessage(); +// KMessageBox::saveDontShowAgainContinue(messageShown); +// } + + resize(sizeHint()); + + connect( &m_timer, SIGNAL(timeout()), this, SLOT(autoMove()) ); + m_timer.start(10); + + s_instance = this; +} + +LikeBack::~LikeBack() +{ +} + +void LikeBack::openConfigurePopup() +{ + m_configureButton->openPopup(); +} + +void LikeBack::doNotHelpAnymore() +{ + disable(); + int result = KMessageBox::questionYesNo( + kapp->activeWindow(), + i18n("Are you sure you do not want to participate anymore in the application enhancing program?"), + i18n("Do not Help Anymore")); + if (result == KMessageBox::No) { + enable(); + return; + } + + s_config->setGroup("LikeBack"); + s_config->writeEntry("userWantToParticipateForVersion_" + s_about->version(), false); + deleteLater(); +} + +void LikeBack::showWhatsThisMessage() +{ + disable(); + showInformationMessage(); + enable(); +} + +bool LikeBack::userWantToParticipate() +{ + if (!kapp) + return true; + + s_config->setGroup("LikeBack"); + return s_config->readBoolEntry("userWantToParticipateForVersion_" + s_about->version(), true); +} + +// TODO: Only show relevant buttons! + +void LikeBack::showInformationMessage() +{ + QPixmap likeIcon = kapp->iconLoader()->loadIcon("likeback_like", KIcon::Small); + QPixmap dislikeIcon = kapp->iconLoader()->loadIcon("likeback_dislike", KIcon::Small); + QPixmap bugIcon = kapp->iconLoader()->loadIcon("likeback_bug", KIcon::Small); + QMimeSourceFactory::defaultFactory()->setPixmap("likeback_icon_like", likeIcon); + QMimeSourceFactory::defaultFactory()->setPixmap("likeback_icon_dislike", dislikeIcon); + QMimeSourceFactory::defaultFactory()->setPixmap("likeback_icon_bug", bugIcon); + KMessageBox::information(0, + "

" + i18n("This is a quick feedback system for %1.").arg(s_about->programName()) + "

" + "

" + i18n("To help us improve it, your comments are important.") + "

" + "

" + i18n("Each time you have a great or frustrating experience, " + "please click the appropriate hand below the window title-bar, " + "briefly describe what you like or dislike and click Send.") + "

" + "

" + i18n("Icons description:") + "" + "" + "" + "" + "
: " + i18n("Send a comment about what you like.") + "
: " + i18n("Send a comment about what you don't like.") + "
: " + i18n("Report a bug.") + "

", + i18n("Help Improve the Application")); + QMimeSourceFactory::defaultFactory()->setData("likeback_icon_like", 0L); + QMimeSourceFactory::defaultFactory()->setData("likeback_icon_dislike", 0L); + QMimeSourceFactory::defaultFactory()->setData("likeback_icon_bug", 0L); +} + +QString LikeBack::s_customLanguageMessage = QString(); +bool LikeBack::s_allowFeatureWishes = false; +LikeBack::WindowListing LikeBack::s_windowListing = LikeBack::NoListing; +QString LikeBack::s_hostName = QString(); +QString LikeBack::s_remotePath = QString(); +Q_UINT16 LikeBack::s_hostPort = 16; +int LikeBack::s_disabledCount = 0; +LikeBack* LikeBack::s_instance = 0; +KConfig* LikeBack::s_config = 0; +KAboutData* LikeBack::s_about = 0; + +LikeBack* LikeBack::instance() +{ + return s_instance; +} + +QString LikeBack::customLanguageMessage() +{ + return s_customLanguageMessage; +} + +QString LikeBack::hostName() +{ + return s_hostName; +} + +QString LikeBack::remotePath() +{ + return s_remotePath; +} + +Q_UINT16 LikeBack::hostPort() +{ + return s_hostPort; +} + +KAboutData* LikeBack::about() +{ + return s_about; +} + +void LikeBack::disable() +{ + s_disabledCount++; +} + +void LikeBack::enable() +{ + s_disabledCount--; + if (s_disabledCount < 0) + std::cerr << "===== LikeBack ===== Enabled too many times (less than how many times it was disabled)" << std::endl; +} + +bool LikeBack::enabled() +{ + return s_disabledCount == 0; +} + +void LikeBack::setServer(QString hostName, QString remotePath, Q_UINT16 hostPort) +{ + s_hostName = hostName; + s_remotePath = remotePath; + s_hostPort = hostPort; +} + +void LikeBack::setWindowNamesListing(WindowListing windowListing) +{ + s_windowListing = windowListing; +} + +void LikeBack::setCustomLanguageMessage(const QString &message) +{ + s_customLanguageMessage = message; +} + +void LikeBack::setAllowFeatureWishes(bool allow) +{ + s_allowFeatureWishes = allow; +} + +bool LikeBack::allowFeatureWishes() +{ + return s_allowFeatureWishes; +} + +void LikeBack::autoMove() +{ + static QWidget *lastWindow = 0; + + QWidget *window = kapp->activeWindow(); + // When a Kicker applet has the focus, like the Commandline QLineEdit, + // the systemtray icon indicates to be the current window and the LikeBack is shown next to the system tray icon. + // It's obviously bad ;-) : + bool shouldShow = false;//(enabled() && window && window->inherits("KMainWindow") ); + if (shouldShow) { + //move(window->x() + window->width() - 100 - width(), window->y()); + //move(window->x() + window->width() - 100 - width(), window->mapToGlobal(QPoint(0, 0)).y() - height()); + move(window->mapToGlobal(QPoint(0, 0)).x() + window->width() - width(), window->mapToGlobal(QPoint(0, 0)).y() + 1); + + if (window != lastWindow && s_windowListing != NoListing) +// if (qstricmp(window->name(), "") == 0 || qstricmp(window->name(), "unnamed") == 0) ; +// std::cout << "===== LikeBack ===== UNNAMED ACTIVE WINDOW OF TYPE " << window->className() << " ======" << activeWindowPath() << std::endl; +// else if (s_windowListing == AllWindows) ; +// std::cout << "LikeBack: Active Window: " << activeWindowPath() << std::endl; + lastWindow = window; + } + if (shouldShow && !isShown()) { + show(); + } else if (!shouldShow && isShown()) + hide(); +} + +void LikeBack::iLike() +{ + showDialog(ILike); +} + +void LikeBack::iDoNotLike() +{ + showDialog(IDoNotLike); +} + +void LikeBack::iFoundABug() +{ + (void)new KRun(Piklab::URLS[Piklab::BugReport], kapp->mainWidget()); + // showDialog(IFoundABug); +} + +void LikeBack::configure() +{ +} + +QString LikeBack::activeWindowPath() +{ + QStringList windowNames; + QWidget *window = kapp->activeWindow(); + while (window) { + QString name = window->name(); + if (name == "unnamed") + name += QString(":") + window->className(); + windowNames.append(name); + window = dynamic_cast(window->parent()); + } + + QString windowName; + for (int i = ((int)windowNames.count()) - 1; i >= 0; i--) { + if (windowName.isEmpty()) + windowName = windowNames[i]; + else + windowName += QString("~~") + windowNames[i]; + } + + return windowName; +} + +void LikeBack::showDialog(Button button) +{ + LikeBackDialog dialog(button, activeWindowPath(), ""); + disable(); + hide(); + kapp->processEvents(); + dialog.exec(); + enable(); +} + +bool LikeBack::emailAddressAlreadyProvided() +{ + return s_config->readBoolEntry("emailAlreadyAsked", false); +} + +QString LikeBack::emailAddress() +{ + if (!emailAddressAlreadyProvided()) + instance()->askEMail(); + + return s_config->readEntry("emailAddress", ""); +} + +void LikeBack::setEmailAddress(const QString &address) +{ + s_config->setGroup("LikeBack"); + s_config->writeEntry("emailAddress", address); + s_config->writeEntry("emailAlreadyAsked", true); +} + +void LikeBack::askEMail() +{ + s_config->setGroup("LikeBack"); + + QString currentEMailAddress = s_config->readEntry("emailAddress", ""); + if (!emailAddressAlreadyProvided() && !instance()->m_fetchedEmail.isEmpty()) + currentEMailAddress = instance()->m_fetchedEmail; + + bool ok; + + QString mailExpString = "[\\w-\\.]+@[\\w-\\.]+\\.[\\w]+"; + //QString namedMailExpString = "[.]*[ \\t]+<" + mailExpString + ">"; + //QRegExp mailExp("^(|" + mailExpString + "|" + namedMailExpString + ")$"); + QRegExp mailExp("^(|" + mailExpString + ")$"); + QRegExpValidator emailValidator(mailExp, this); + + disable(); + QString email = KInputDialog::getText( + i18n("Set Email Address"), + "

" + i18n("Please provide your email address.") + "

" + + "

" + i18n("It will only be used to contact you back if more information is needed about your comments, how to reproduce the bugs you report, send bug corrections for you to test...") + "

" + + "

" + i18n("The email address is optional. If you do not provide any, your comments will be sent anonymously. Just click OK in that case.") + "

" + + "

" + i18n("You can change or remove your email address whenever you want. For that, use the little arrow icon at the top-right corner of a window.") + "

" + + "

" + i18n("Your email address (keep empty to post comments anonymously):"), + currentEMailAddress, &ok, kapp->activeWindow(), /*name=*/(const char*)0, &emailValidator); + enable(); + + if (ok) + setEmailAddress(email); +} + +// FIXME: Should be moved to KAboutData? Cigogne will also need it. +bool LikeBack::isDevelopmentVersion(const QString &version) +{ + QString theVersion = (version.isEmpty() ? s_about->version() : version); + + return theVersion.find("alpha", /*index=*/0, /*caseSensitive=*/false) != -1 || + theVersion.find("beta", /*index=*/0, /*caseSensitive=*/false) != -1 || + theVersion.find("rc", /*index=*/0, /*caseSensitive=*/false) != -1 || + theVersion.find("svn", /*index=*/0, /*caseSensitive=*/false) != -1 || + theVersion.find("cvs", /*index=*/0, /*caseSensitive=*/false) != -1; +} + +void LikeBack::init(KConfig* config, KAboutData* about, Button buttons) +{ + s_config = config; + s_about = about; + init(isDevelopmentVersion(), buttons); +} + +void LikeBack::init(Button buttons) +{ + init(isDevelopmentVersion(), buttons); +} + +void LikeBack::init(bool isDevelopmentVersion, Button buttons) +{ + if (s_config == 0) + s_config = kapp->config(); + if (s_about == 0) + s_about = (KAboutData*) kapp->aboutData(); + + if (LikeBack::userWantToParticipate() && isDevelopmentVersion) + new LikeBack(buttons); +} + + + + + + + +/** + * Code from KBugReport::slotConfigureEmail() in kdeui/kbugreport.cpp: + */ +/*void LikeBack::beginFetchingEmail() +{ + if (m_process) + return; + m_process = new KProcess(); + *m_process << QString::fromLatin1("kcmshell") << QString::fromLatin1("kcm_useraccount"); + connect( m_process, SIGNAL(processExited(KProcess*)), SLOT(endFetchingEmailFrom()) ); + if (!m_process->start()) { + kdDebug() << "Couldn't start kcmshell.." << endl; + delete m_process; + m_process = 0; + return; + } +// m_configureEmail->setEnabled(false); +}*/ + +/** + * Code from KBugReport::slotSetFrom() in kdeui/kbugreport.cpp: + */ +void LikeBack::endFetchingEmailFrom() +{ +// delete m_process; +// m_process = 0; +// m_configureEmail->setEnabled(true); + + // ### KDE4: why oh why is KEmailSettings in kio? + KConfig emailConf( QString::fromLatin1("emaildefaults") ); + + // find out the default profile + emailConf.setGroup(QString::fromLatin1("Defaults")); + QString profile = QString::fromLatin1("PROFILE_"); + profile += emailConf.readEntry(QString::fromLatin1("Profile"), QString::fromLatin1("Default")); + + emailConf.setGroup(profile); + QString fromaddr = emailConf.readEntry(QString::fromLatin1("EmailAddress")); + if (fromaddr.isEmpty()) { + struct passwd *p; + p = getpwuid(getuid()); + m_fetchedEmail = QString::fromLatin1(p->pw_name); + } else { + QString name = emailConf.readEntry(QString::fromLatin1("FullName")); + if (!name.isEmpty()) + m_fetchedEmail = /*name + QString::fromLatin1(" <") +*/ fromaddr /*+ QString::fromLatin1(">")*/; + } +// m_from->setText( fromaddr ); +} + + + + + + + +/** class LikeBackDialog: */ + +LikeBackDialog::LikeBackDialog(LikeBack::Button reason, QString windowName, QString context) + : KDialog(kapp->activeWindow(), "_likeback_feedback_window_") + , m_reason(reason) + , m_windowName(windowName) + , m_context(context) +{ + setModal(true); + QVBoxLayout *mainLayout = new QVBoxLayout(this); + + QWidget *coloredWidget = new QWidget(this); + QLabel *explainings = new QLabel(this); + QHBoxLayout *explainingLayout = new QHBoxLayout((QWidget*)0, KDialogBase::marginHint()); + explainingLayout->addWidget(explainings); + mainLayout->addWidget(coloredWidget); + + QColor color; + QColor lineColor; + QPixmap icon; + QString title; + QString please; + switch (reason) { + case LikeBack::ILike: + color = QColor("#DFFFDF"); + lineColor = Qt::green; + icon = kapp->iconLoader()->loadIcon("likeback_like", KIcon::Small); + title = i18n("I like..."); + please = i18n("Please briefly describe what you like."); + break; + case LikeBack::IDoNotLike: + color = QColor("#FFDFDF"); + lineColor = Qt::red; + icon = kapp->iconLoader()->loadIcon("likeback_dislike", KIcon::Small); + title = i18n("I do not like..."); + please = i18n("Please briefly describe what you do not like."); + break; + case LikeBack::IFoundABug: + color = QColor("#C0C0C0"); + lineColor = Qt::black; + icon = kapp->iconLoader()->loadIcon("bug", KIcon::Small); + title = i18n("I found a bug..."); + please = i18n("Please briefly describe the bug you encountered."); + break; + case LikeBack::Configure: + case LikeBack::AllButtons: + return; + } + + QWidget *line = new QWidget(this); + line->setPaletteBackgroundColor(lineColor); + line->setFixedHeight(1); + mainLayout->addWidget(line); + mainLayout->addLayout(explainingLayout); + + QHBoxLayout *titleLayout = new QHBoxLayout(0); + coloredWidget->setPaletteBackgroundColor(color); + QLabel *iconLabel = new QLabel(coloredWidget); + iconLabel->setPixmap(icon); + QLabel *titleLabel = new QLabel(title, coloredWidget); + QFont font = titleLabel->font(); + font.setBold(true); + titleLabel->setFont(font); + titleLabel->setPaletteForegroundColor(Qt::black); + titleLayout->addWidget(iconLabel); + titleLayout->addSpacing(4); + titleLayout->addWidget(titleLabel); + titleLayout->addStretch(); + + QVBoxLayout *coloredWidgetLayout = new QVBoxLayout(coloredWidget); + coloredWidgetLayout->setMargin(KDialogBase::marginHint()); + coloredWidgetLayout->setSpacing(KDialogBase::spacingHint()); + coloredWidgetLayout->addLayout(titleLayout); + + QHBoxLayout *commentLayout = new QHBoxLayout((QWidget*)0); + commentLayout->setMargin(0); + commentLayout->setSpacing(KDialogBase::spacingHint()); + m_comment = new QTextEdit(coloredWidget); + QIconSet sendIconSet = kapp->iconLoader()->loadIconSet("mail_send", KIcon::Toolbar); + m_sendButton = new QPushButton(sendIconSet, i18n("Send"), coloredWidget); + m_sendButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding); + m_sendButton->setEnabled(false); + connect( m_sendButton, SIGNAL(clicked()), this, SLOT(send()) ); + connect( m_comment, SIGNAL(textChanged()), this, SLOT(commentChanged()) ); + commentLayout->addWidget(m_comment); + commentLayout->addWidget(m_sendButton); + coloredWidgetLayout->addLayout(commentLayout); + + explainings->setText( + "

" + please + " " + + (LikeBack::customLanguageMessage().isEmpty() ? + i18n("Only english language is accepted.") : + LikeBack::customLanguageMessage() + ) + " " + + (reason == LikeBack::ILike || reason == LikeBack::IDoNotLike ? + i18n("Note that to improve this application, it's important to tell us the things you like as much as the things you dislike.") + " " : + "" + ) + + (LikeBack::allowFeatureWishes() ? + "" : + i18n("Do not ask for features: your wishes will be ignored.") + ) + "

" + ); + + resize(kapp->desktop()->width() / 2, kapp->desktop()->height() / 3); + + setCaption(kapp->makeStdCaption(i18n("Send a Comment"))); + // setMinimumSize(mainLayout->sizeHint()); // FIXME: Doesn't work! +} + +LikeBackDialog::~LikeBackDialog() +{ +} + +QHttp *http ; + +void LikeBackDialog::send() +{ + QString emailAddress = LikeBack::instance()->emailAddress(); + + QString type = (m_reason == LikeBack::ILike ? "Like" : (m_reason == LikeBack::IDoNotLike ? "Dislike" : "Bug")); + QString data = + "protocol=" + KURL::encode_string("1.0") + "&" + + "type=" + KURL::encode_string(type) + "&" + + "version=" + KURL::encode_string(LikeBack::about()->version()) + "&" + + "locale=" + KURL::encode_string(KGlobal::locale()->language()) + "&" + + "window=" + KURL::encode_string(m_windowName) + "&" + + "context=" + KURL::encode_string(m_context) + "&" + + "comment=" + KURL::encode_string(m_comment->text()) + "&" + + "email=" + KURL::encode_string(emailAddress); + //QByteArray *data = new QByteArray(); + /*QHttp **/http = new QHttp(LikeBack::hostName(), LikeBack::hostPort()); + +// std::cout << "http://" << LikeBack::hostName() << ":" << LikeBack::hostPort() << LikeBack::remotePath() << std::endl; +// std::cout << data << std::endl; + connect( http, SIGNAL(requestFinished(int, bool)), this, SLOT(requestFinished(int, bool)) ); +// http->post(LikeBack::remotePath(), data.utf8()); + + QHttpRequestHeader header("POST", LikeBack::remotePath()); + header.setValue("Host", LikeBack::hostName()); + header.setValue("Content-Type", "application/x-www-form-urlencoded"); + http->setHost(LikeBack::hostName()); + http->request(header, data.utf8()); + + + m_comment->setEnabled(false); +} + +void LikeBackDialog::requestFinished(int /*id*/, bool error) +{ + // TODO: Save to file if error (connection not present at the moment) + m_comment->setEnabled(true); + LikeBack::disable(); + if (error) { + KMessageBox::error(this, i18n("

Error while trying to send the report.

Please retry later.

"), i18n("Transfer Error")); + } else { + KMessageBox::information(this, i18n("

Your comment has been sent successfully. It will help improve the application.

Thanks for your time.

") /*+ QString(http->readAll())*/, i18n("Comment Sent")); + close(); + } + LikeBack::enable(); +} + +void LikeBackDialog::commentChanged() +{ + m_sendButton->setEnabled(!m_comment->text().isEmpty()); +} diff --git a/src/libgui/likeback.h b/src/libgui/likeback.h new file mode 100644 index 0000000..70a68dd --- /dev/null +++ b/src/libgui/likeback.h @@ -0,0 +1,120 @@ +/*************************************************************************** + * Copyright (C) 2006 by Sébastien Laot * + * slaout@linux62.org * + * * + * 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., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#ifndef LIKEBACK_H +#define LIKEBACK_H + +#include +#include + +class QTextEdit; +class QToolButton; +class QPushButton; +class KProcess; +class KConfig; +class KAboutData; + +/** + * @author S�astien Laot + */ +class LikeBack : public QWidget +{ + Q_OBJECT + public: + enum Button { ILike = 0x01, IDoNotLike = 0x02, IFoundABug = 0x04, Configure = 0x10, + AllButtons = ILike | IDoNotLike | IFoundABug | Configure }; + enum WindowListing { NoListing, WarnUnnamedWindows, AllWindows }; + LikeBack(Button buttons = AllButtons); + ~LikeBack(); + static void showInformationMessage(); + static LikeBack* instance(); + static QString customLanguageMessage(); + static bool allowFeatureWishes(); + static QString hostName(); + static QString remotePath(); + static Q_UINT16 hostPort(); + static void setServer(QString hostName, QString remotePath, Q_UINT16 hostPort = 80); + static void setWindowNamesListing(WindowListing windowListing); + static void setCustomLanguageMessage(const QString &message); + static void setAllowFeatureWishes(bool allow); + static bool enabled(); + static void disable(); + static void enable(); + static bool userWantToParticipate(); /// << @Returns true if the user have not disabled LikeBack for this version + static bool emailAddressAlreadyProvided(); + static QString emailAddress(); /// << @Returns the email user address, or ask it to the user if he haven't provided or ignored it + static void setEmailAddress(const QString &address); /// << Calling emailAddress() will ask it to the user the first time + static bool isDevelopmentVersion(const QString &version = QString::null); /// << @Returns true if version is an alpha/beta/rc/svn/cvs version. Use kapp->aboutData()->version is @p version is empty + static void init(Button buttons = AllButtons); /// << Initialize the LikeBack system: enable it if the application version is a development one. + static void init(bool isDevelopmentVersion, Button buttons = AllButtons); /// << Initialize the LikeBack system: enable it if @p isDevelopmentVersion is true. + static void init(KConfig* config, KAboutData* about, Button buttons = AllButtons); + static QString activeWindowPath(); + static KAboutData* about(); + public slots: + void iLike(); + void iDoNotLike(); + void iFoundABug(); + void configure(); + + private slots: + void autoMove(); + void showDialog(Button button); + void openConfigurePopup(); + void doNotHelpAnymore(); + void showWhatsThisMessage(); + void askEMail(); +// void beginFetchingEmail(); + void endFetchingEmailFrom(); // static QString fetchingEmail(); + private: + QTimer m_timer; + Button m_buttons; + QToolButton *m_configureButton; + QString m_fetchedEmail; + KProcess *m_process; + static QString s_hostName; + static QString s_remotePath; + static Q_UINT16 s_hostPort; + static QString s_customLanguageMessage; + static bool s_allowFeatureWishes; + static WindowListing s_windowListing; + static LikeBack *s_instance; + static int s_disabledCount; + static KConfig *s_config; + static KAboutData *s_about; +}; + +class LikeBackDialog : public KDialog +{ + Q_OBJECT + public: + LikeBackDialog(LikeBack::Button reason, QString windowName, QString context); + ~LikeBackDialog(); + private: + LikeBack::Button m_reason; + QTextEdit *m_comment; + QPushButton *m_sendButton; + QString m_windowName; + QString m_context; + private slots: + void send(); + void requestFinished(int id, bool error); + void commentChanged(); +}; + +#endif // LIKEBACK_H diff --git a/src/libgui/log_view.cpp b/src/libgui/log_view.cpp new file mode 100644 index 0000000..158c281 --- /dev/null +++ b/src/libgui/log_view.cpp @@ -0,0 +1,135 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "log_view.h" + +#include +#include +#include +#include + +#include "global_config.h" +#include "common/gui/purl_gui.h" +#include "common/gui/misc_gui.h" + +Log::Widget::Widget(QWidget *parent, const char *name) + : QTextEdit(parent, name) +{ + setTextFormat(LogText); + setMinimumWidth(300); +} + +void Log::Widget::updateDebugLevel() +{ + setDebugLevel(GlobalConfig::debugLevel()); +} + +void Log::Widget::logExtra(const QString &text) +{ + _text += text; + if ( GlobalConfig::logOutputType()==GuiConsole ) fprintf(stdout, "%s", text.latin1()); +} + +void Log::Widget::doLog(LineType type, const QString &text, Action action) +{ + doLog(text, type.data().color, type.data().bold, action); +} + +void Log::Widget::doLog(DebugLevel level, const QString &text, Action action) +{ + doLog(text, level.data().color, false, action); +} + +void Log::Widget::doLog(const QString &text, const QString &color, bool bold, Action action) +{ + logExtra(text + "\n"); + QString s = QString("").arg(color); + if (bold) s += ""; + s += escapeXml(text); + if (bold) s += ""; + s += ""; + QTextEdit::append(s); + updateContents(); // #### fix bug in Qt (display is messed up) + ensureVisible(0, contentsHeight()); + if ( action==Immediate) + QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput); +} + +void Log::Widget::appendToLastLine(const QString &text) +{ + logExtra(text); + uint p = paragraphs() - 1; + insertAt(escapeXml(text), p, paragraphLength(p)); + updateContents(); // #### fix bug in Qt (display is messed up) + ensureVisible(0, contentsHeight()); + // immediately visible... + QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput); +} + +QPopupMenu *Log::Widget::createPopupMenu(const QPoint &pos) +{ + updateDebugLevel(); + _popup = QTextEdit::createPopupMenu(pos); + KIconLoader loader; + QIconSet iset = loader.loadIconSet("filesave", KIcon::Small, 0); + _popup->insertItem(iset, "Save As...", this, SLOT(saveAs())); + iset = loader.loadIconSet("fileclose", KIcon::Small, 0); + _popup->insertItem(iset, "Clear", this, SLOT(clear())); + _popup->insertSeparator(); + FOR_EACH(DebugLevel, level) { + _id[level.type()] = _popup->insertItem(level.label()); + _popup->setItemChecked(_id[level.type()], _debugLevel==level); + } + _popup->insertSeparator(); + int id = _popup->insertItem(i18n("Output in console"), this, SLOT(toggleConsoleOutput())); + _popup->setItemChecked(id, GlobalConfig::logOutputType()==GuiConsole); + connect(_popup, SIGNAL(activated(int)), SLOT(toggleVisible(int))); + return _popup; +} + +void Log::Widget::toggleVisible(int id) +{ + FOR_EACH(DebugLevel, level) { + if ( _id[level.type()]==id ) { + _debugLevel = level; + GlobalConfig::writeDebugLevel(level); + break; + } + } +} + +void Log::Widget::toggleConsoleOutput() +{ + GlobalConfig::writeLogOutputType(GlobalConfig::logOutputType()==GuiOnly ? GuiConsole : GuiOnly); +} + +void Log::Widget::sorry(const QString &message, const QString &details) +{ + logExtra(message + " [" + details + "]\n"); + MessageBox::detailedSorry(message, details, Log::Show); +} + +bool Log::Widget::askContinue(const QString &message) +{ + bool ok = MessageBox::askContinue(message); + logExtra(message + " [" + (ok ? "continue" : "cancel") + "]\n"); + return ok; +} + +void Log::Widget::clear() +{ + QTextEdit::clear(); + _text = QString::null; +} + +void Log::Widget::saveAs() +{ + PURL::Url url = PURL::getSaveUrl(":save_log", "text/x-log", this, i18n("Save log to file"), PURL::AskOverwrite); + if ( url.isEmpty() ) return; + url.write(_text, *this); +} diff --git a/src/libgui/log_view.h b/src/libgui/log_view.h new file mode 100644 index 0000000..c84849e --- /dev/null +++ b/src/libgui/log_view.h @@ -0,0 +1,51 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef LOG_VIEW_H +#define LOG_VIEW_H + +#include +#include "common/global/log.h" + +namespace Log +{ +enum OutputType { GuiOnly = 0, GuiConsole, Nb_OutputTypes }; + +class Widget : public QTextEdit, public View +{ + Q_OBJECT +public: + Widget(QWidget *parent = 0, const char *name = 0); + virtual void appendToLastLine(const QString &text); + virtual void clear(); + virtual void sorry(const QString &message, const QString &details); + virtual bool askContinue(const QString &message); + +protected: + QPopupMenu *createPopupMenu(const QPoint &pos); + +private slots: + void toggleVisible(int i); + void toggleConsoleOutput(); + void saveAs(); + +private: + int _id[DebugLevel::Nb_Types]; + QPopupMenu *_popup; + QString _text; + + virtual void updateDebugLevel(); + virtual void doLog(LineType type, const QString &text, Action action = Immediate); + virtual void doLog(DebugLevel level, const QString &text, Action action = Immediate); + void doLog(const QString &text, const QString &color, bool bold, Action action = Immediate); + void logExtra(const QString &text); +}; + +} // namespace + +#endif diff --git a/src/libgui/main_global.cpp b/src/libgui/main_global.cpp new file mode 100644 index 0000000..8741a44 --- /dev/null +++ b/src/libgui/main_global.cpp @@ -0,0 +1,81 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "main_global.h" + +#include + +#include "toplevel.h" +#include "common/global/about.h" +#include "global_config.h" +#include "devices/list/device_list.h" +#include "project_manager.h" +#include "editor_manager.h" +#include "tools/list/compile_config.h" +#include "gui_prog_manager.h" +#include "device_editor.h" + +Main::State Main::_state = Main::Idle; +MainWindow *Main::_toplevel = 0; +EditorManager *Main::_editorManager = 0; +ProjectManager::View *Main::_projectManager = 0; +Breakpoint::View *Main::_breakpointsView = 0; +Register::WatchView *Main::_watchView = 0; +Compile::LogWidget *Main::_compileLog = 0; +Compile::Manager *Main::_compileManager = 0; +ConsoleView *Main::_consoleView = 0; + +void Main::setState(State state) +{ + _state = state; + _toplevel->updateGUI(); +} + +Programmer::Base *Main::programmer() +{ + return Programmer::manager->programmer(); +} + +const Programmer::Group &Main::programmerGroup() +{ + return GlobalConfig::programmerGroup(); +} + +Programmer::State Main::programmerState() +{ + return (programmer() ? programmer()->state() : Programmer::NotConnected); +} + +KAction *Main::action(const char* name) +{ + return _toplevel->KMainWindow::action(name); +} +KAction *Main::action(KStdAction::StdAction action) +{ + return _toplevel->KMainWindow::action(KStdAction::name(action)); +} + +QPopupMenu &Main::popup(const char *name) +{ + QPopupMenu *popup = static_cast(_toplevel->factory()->container(name, _toplevel)); + Q_ASSERT(popup); + return *popup; +} + +const Device::Data *Main::deviceData() +{ + QString name = device(); + if ( name==Device::AUTO_DATA.name ) + name = DeviceEditor::guessDeviceFromFile(_projectManager->projectUrl()); + return Device::lister().data(name); +} + +Editor *Main::currentEditor() { return _editorManager->currentEditor(); } +Project *Main::project() { return _projectManager->project(); } +QString Main::device() { return Compile::Config::device(project()); } +const Tool::Group &Main::toolGroup() { return Compile::Config::toolGroup(project()); } diff --git a/src/libgui/main_global.h b/src/libgui/main_global.h new file mode 100644 index 0000000..020253e --- /dev/null +++ b/src/libgui/main_global.h @@ -0,0 +1,70 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef MAIN_GLOBAL_H +#define MAIN_GLOBAL_H + +#include +#include +#include + +#include "progs/base/generic_prog.h" + +class EditorManager; +namespace ProjectManager { class View; } +class Editor; +class Project; +namespace Compile { class LogWidget; class Manager; } +namespace Register { class List; class WatchView; } +namespace Breakpoint { class View; } +class MainWindow; +namespace Programmer { class Group; class Base; } +namespace Device { class Data; } +namespace Tool { class Group; } +class ConsoleView; + +class Main +{ +public: + enum State { Idle, Compiling, Programming, Closing }; + static void setState(State state); + static State state() { return _state; } + + static MainWindow &toplevel() { return *_toplevel; } + static const Programmer::Group &programmerGroup(); + static Programmer::Base *programmer(); + static Programmer::State programmerState(); + static KAction *action(const char *name); + static KAction *action(KStdAction::StdAction action); + static QPopupMenu &popup(const char *name); + static EditorManager &editorManager() { return *_editorManager; } + static Editor *currentEditor(); + static QString device(); + static const Device::Data *deviceData(); + static Breakpoint::View &breakpointsView() { return *_breakpointsView; } + static ProjectManager::View &projectManager() { return *_projectManager; } + static Project *project(); + static Register::WatchView &watchView() { return *_watchView; } + static Compile::LogWidget &compileLog() { return *_compileLog; } + static const Tool::Group &toolGroup(); + +private: + static State _state; + static MainWindow *_toplevel; + static EditorManager *_editorManager; + static ProjectManager::View *_projectManager; + static Breakpoint::View *_breakpointsView; + static Register::WatchView *_watchView; + static Compile::LogWidget *_compileLog; + static Compile::Manager *_compileManager; + static ConsoleView *_consoleView; + + friend class MainWindow; +}; + +#endif diff --git a/src/libgui/new_dialogs.cpp b/src/libgui/new_dialogs.cpp new file mode 100644 index 0000000..d26c15c --- /dev/null +++ b/src/libgui/new_dialogs.cpp @@ -0,0 +1,83 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "new_dialogs.h" + +#include +#include +#include + +#include "common/gui/purl_gui.h" +#include "project.h" + +//---------------------------------------------------------------------------- +NewDialog::NewDialog(const QString &caption, QWidget *parent) + : Dialog(parent, "new_dialog", true, caption, Ok|Cancel, Ok, false) +{ + _top = new QGridLayout(mainWidget(), 0, 0, 10, 10); + _top->setColStretch(2, 1); + + _fLabel = new QLabel(mainWidget()); + _top->addWidget(_fLabel, 0, 0); + _filename = new QLineEdit(mainWidget()); + connect(_filename, SIGNAL(textChanged(const QString &)), SLOT(changed())); + _top->addMultiCellWidget(_filename, 0,0, 1,3); + + QLabel *label= new QLabel(i18n("Location:"), mainWidget()); + _top->addWidget(label, 1, 0); + _dir = new QLineEdit(mainWidget()); + connect(_dir, SIGNAL(textChanged(const QString &)), SLOT(changed())); + _top->addMultiCellWidget(_dir, 1,1, 1,2); + KIconLoader loader; + QIconSet iconset = loader.loadIcon("fileopen", KIcon::Toolbar); + KPushButton *button = new KPushButton(iconset, QString::null, mainWidget()); + connect(button, SIGNAL(clicked()), SLOT(browse())); + _top->addWidget(button, 1, 3); + + _filename->setFocus(); + enableButtonOK(false); +} + +void NewDialog::changed() +{ + enableButtonOK(!_filename->text().isEmpty() && !_dir->text().isEmpty()); +} + +void NewDialog::browse() +{ + PURL::Directory dir = PURL::getExistingDirectory(startDir(), this, QString::null); + if ( dir.isEmpty() ) return; + _dir->setText(dir.path()); +} + +//---------------------------------------------------------------------------- +NewFileDialog::NewFileDialog(Project *project, QWidget *parent) + : NewDialog(i18n("Create New File"), parent), _project(project) +{ + _fLabel->setText(i18n("File Name:")); + + if (project) { + _add = new QCheckBox(i18n("Add to project"), mainWidget()); + _add->setChecked(project); + _top->addMultiCellWidget(_add, 2,2, 1,2); + _top->setRowStretch(3, 1); + _dir->setText(project->directory().path()); + } +} + +QString NewFileDialog::startDir() const +{ + if (_project) return _project->directory().path(); + return ":new_file"; +} + +PURL::Url NewFileDialog::url() const +{ + return PURL::Url(PURL::Directory(_dir->text()), _filename->text()); +} diff --git a/src/libgui/new_dialogs.h b/src/libgui/new_dialogs.h new file mode 100644 index 0000000..26e3cf7 --- /dev/null +++ b/src/libgui/new_dialogs.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#ifndef NEW_DIALOGS_H +#define NEW_DIALOGS_H + +#include +#include +#include +#include +#include +#include + +#include "common/global/purl.h" +#include "common/gui/dialog.h" +class Project; + +//---------------------------------------------------------------------------- +class NewDialog : public Dialog +{ +Q_OBJECT +public: + NewDialog(const QString &caption, QWidget *parent); + +protected: + QGridLayout *_top; + QLabel *_fLabel; + QLineEdit *_filename, *_dir; + + virtual QString startDir() const = 0; + +private slots: + void changed(); + void browse(); +}; + +//---------------------------------------------------------------------------- +class NewFileDialog : public NewDialog +{ +Q_OBJECT +public: + NewFileDialog(Project *project, QWidget *parent); + PURL::Url url() const; + bool addToProject() const { return (_project ? _add->isChecked() : false); } + +private: + Project *_project; + QCheckBox *_add; + + virtual QString startDir() const; +}; + +#endif diff --git a/src/libgui/object_view.cpp b/src/libgui/object_view.cpp new file mode 100644 index 0000000..91625fb --- /dev/null +++ b/src/libgui/object_view.cpp @@ -0,0 +1,145 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "object_view.h" + +#include + +#include "devices/base/device_group.h" +#include "devices/pic/pic/pic_memory.h" +#include "tools/gputils/gputils.h" +#include "hex_editor.h" +#include "coff/base/text_coff.h" +#include "coff/base/coff_archive.h" +#include "main_global.h" +#include "tools/list/compile_process.h" +#include "coff/base/disassembler.h" +#include "common/gui/misc_gui.h" + +//----------------------------------------------------------------------------- +Coff::BaseEditor::BaseEditor(const PURL::Url &source, const Device::Data *data, QWidget *parent) + : SimpleTextEditor(true, parent), _source(source), _ok(false), _created(0), _device(data) +{ + setReadOnly(true); + _view->setDynWordWrap(false); + setView(&Main::compileLog()); +} + +Coff::BaseEditor::~BaseEditor() +{ + delete _created; +} + +//----------------------------------------------------------------------------- +Coff::CoffEditor::CoffEditor(const PURL::Url &source, const Device::Data &data, QWidget *parent) + : BaseEditor(source, &data, parent), _provided(0) +{} + +Coff::CoffEditor::CoffEditor(const TextObject &object, QWidget *parent) + : BaseEditor(PURL::Url(), object.device(), parent), _provided(&object) +{} + +bool Coff::CoffEditor::open(const PURL::Url &url) +{ + _url = url; + if (_provided) return setText(_provided->disassembly()); + if ( _created==0 ) { + _created = new TextObject(_device, _source); + _ok = _created->parse(*this); + } + return setText(static_cast(_created)->disassembly()); +} + +//----------------------------------------------------------------------------- +Coff::ObjectEditor::ObjectEditor(const PURL::Url &source, QWidget *parent) + : BaseEditor(source, 0, parent) +{} + +bool Coff::ObjectEditor::open(const PURL::Url &url) +{ + _url = url; + if ( _created==0 ) { + _created = new TextObject(0, _source); + _ok = _created->parse(*this); + } + if ( !_ok ) return setText(i18n("Error parsing object:\n") + error()); + QString s = coff()->information().text() + "\n"; + return setText(s); +} + +//----------------------------------------------------------------------------- +Coff::LibraryEditor::LibraryEditor(const PURL::Url &source, QWidget *parent) + : BaseEditor(source, 0, parent) +{} + +bool Coff::LibraryEditor::open(const PURL::Url &url) +{ + _url = url; + if ( _created==0 ) { + _created = new Archive(_source); + _ok = _created->parse(*this); + } + if ( !_ok ) return setText(i18n("Error parsing library:\n") + error()); + QString s = coff()->information().text() + "\n"; + if ( coff()->members().count()!=0 ) s += coff()->membersInformation().text() + "\n"; + if ( coff()->symbols().count()!=0 ) s += coff()->symbolsInformation().text() + "\n"; + return setText(s); +} + +//----------------------------------------------------------------------------- +DisassemblyEditor::DisassemblyEditor(const PURL::Url &source, const Device::Data &data, QWidget *parent) + : SimpleTextEditor(true, parent), _source(source), _device(data), _editor(0) +{ + setReadOnly(true); + _view->setDynWordWrap(false); + setView(&Main::compileLog()); +} + +DisassemblyEditor::DisassemblyEditor(const HexEditor &e, const Device::Data &data, QWidget *parent) + : SimpleTextEditor(true, parent), _device(data), _editor(&e) +{ + setReadOnly(true); + _view->setDynWordWrap(false); + setView(&Main::compileLog()); +} + +bool DisassemblyEditor::open(const PURL::Url &url) +{ + _url = url; + if ( Main::toolGroup().name()!="sdcc" && Main::toolGroup().name()!="gputils" ) { + MessageBox::sorry(i18n("Disassembly not supported for the selected toolchain."), Log::Show); + return false; + } + Pic::Architecture arch = (_device.group().name()=="pic" ? static_cast(_device).architecture() : Pic::Architecture(Pic::Architecture::Nb_Types)); + if ( arch==Pic::Architecture::Nb_Types ) { + MessageBox::sorry(i18n("Disassembly not supported for the selected device."), Log::Show); + return false; + } + + Device::Memory *memory = 0; + if ( _editor==0 ) { + log(Log::LineType::Information, i18n("Disassembling hex file: %1").arg(_source.pretty())); + PURL::File file(_source, Main::compileLog()); + if ( !file.openForRead() ) return false; + memory = _device.group().createMemory(_device); + QStringList errors, warnings; + Device::Memory::WarningTypes warningTypes; + if ( !memory->load(file.stream(), errors, warningTypes, warnings) ) { + delete memory; + log(Log::LineType::Error, errors[0]); + return false; + } + for (uint i=0; i(_editor->memory()); + } + SourceLine::List list = GPUtils::disassemble(static_cast(*memory)); + if ( _editor==0 ) delete memory; + return setText(SourceLine::text(PURL::SourceFamily::Asm, list, 4)); +} diff --git a/src/libgui/object_view.h b/src/libgui/object_view.h new file mode 100644 index 0000000..358101b --- /dev/null +++ b/src/libgui/object_view.h @@ -0,0 +1,99 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef OBJECT_VIEW_H +#define OBJECT_VIEW_H + +#include "text_editor.h" +#include "coff/base/coff_archive.h" +#include "coff/base/coff_object.h" +namespace Device { class Data; } +class HexEditor; + +namespace Coff +{ +class Base; +class TextObject; + +//----------------------------------------------------------------------------- +class BaseEditor : public SimpleTextEditor, public Log::Base +{ +Q_OBJECT +public: + BaseEditor(const PURL::Url &source, const Device::Data *data, QWidget *parent); + virtual ~BaseEditor(); + virtual PURL::Url url() const { return _url; } + +protected: + PURL::Url _source, _url; + bool _ok; + Coff::Base *_created; + const Device::Data *_device; +}; + +//----------------------------------------------------------------------------- +class CoffEditor : public BaseEditor +{ +Q_OBJECT +public: + CoffEditor(const PURL::Url &source, const Device::Data &data, QWidget *parent); + CoffEditor(const TextObject &object, QWidget *parent); + virtual PURL::FileType fileType() const { return PURL::Coff; } + virtual bool open(const PURL::Url &url); + +private: + const TextObject *_provided; +}; + +//----------------------------------------------------------------------------- +class ObjectEditor : public BaseEditor +{ +Q_OBJECT +public: + ObjectEditor(const PURL::Url &source, QWidget *parent); + virtual PURL::FileType fileType() const { return PURL::Unknown; } + virtual bool open(const PURL::Url &url); + +private: + const Coff::Object *coff() const { return static_cast(_created); } +}; + +//----------------------------------------------------------------------------- +class LibraryEditor : public BaseEditor +{ +Q_OBJECT +public: + LibraryEditor(const PURL::Url &source, QWidget *parent); + virtual PURL::FileType fileType() const { return PURL::Unknown; } + virtual bool open(const PURL::Url &url); + +private: + const Coff::Archive *coff() const { return static_cast(_created); } +}; + +} // namespace + +//----------------------------------------------------------------------------- +class DisassemblyEditor : public SimpleTextEditor, public Log::Base +{ +Q_OBJECT +public: + DisassemblyEditor(const PURL::Url &hexUrl, const Device::Data &data, QWidget *parent); + DisassemblyEditor(const HexEditor &e, const Device::Data &data, QWidget *parent); + virtual PURL::FileType fileType() const { return PURL::AsmGPAsm; } + virtual bool open(const PURL::Url &url); + virtual PURL::Url url() const { return _url; } + +private: + PURL::Url _source, _url; + const Device::Data &_device; + const HexEditor *_editor; +}; + + +#endif diff --git a/src/libgui/project.cpp b/src/libgui/project.cpp new file mode 100644 index 0000000..dcf34c3 --- /dev/null +++ b/src/libgui/project.cpp @@ -0,0 +1,226 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * Copyright (C) 2003 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "project.h" + +#include + +#include "devices/list/device_list.h" +#include "progs/base/prog_group.h" +#include "global_config.h" +#include "tools/gputils/gputils_config.h" + +bool Project::load(QString &error) +{ + if ( _url.fileType()==PURL::Project ) return XmlDataFile::load(error); + + if ( !_url.exists() ) { + error = i18n("Project file %1 does not exist.").arg(_url.pretty()); + return false; + } + PURL::Url tmp = _url; + _url = _url.toFileType(PURL::Project); + if ( _url.exists() && XmlDataFile::load(error) ) return true; + KConfig *config = new KSimpleConfig(tmp.filepath(), false); + + config->setGroup("Files"); + QStringList list = config->readListEntry("inputFiles"); + QStringList::const_iterator it = list.begin(); + for (; it!=list.end(); ++it) addFile(PURL::Url(directory(), *it)); + + config->setGroup("General"); + setVersion(config->readEntry("version", "0.1")); + setDescription(config->readEntry("description", QString::null)); + + config->setGroup("Assembler"); + QString device = config->readEntry("target-device"); + if ( device=="*" ) device = GlobalConfig::programmerGroup().supportedDevices()[0]; // compatibility + Compile::Config::setDevice(this, Device::lister().checkName(device)); + GPUtils::Config *gconfig = new GPUtils::Config(this); + gconfig->setGPAsmWarningLevel(QMIN(config->readUnsignedNumEntry("warn-level", 0), uint(GPUtils::Config::Nb_WarningLevels))); + gconfig->setRawIncludeDirs(Tool::Category::Assembler, config->readEntry("include-dir", QString::null)); + gconfig->setRawCustomOptions(Tool::Category::Assembler, config->readEntry("other-options", QString::null)); + + config->setGroup("Linker") ; + QString hexFormatString = config->readEntry("hex-format", HexBuffer::FORMATS[HexBuffer::IHX32]); + for (uint i=0; isetHexFormat(HexBuffer::Format(i)); + gconfig->setRawIncludeDirs(Tool::Category::Linker, config->readEntry("objs-libs-dir", QString::null)); + gconfig->setRawCustomOptions(Tool::Category::Linker, config->readEntry("other-options", QString::null)); + + delete gconfig; + delete config; + return true; +} + +PURL::UrlList Project::openedFiles() const +{ + PURL::UrlList files; + QStringList list = listValues("general", "opened_files", QStringList()); + QStringList::const_iterator it = list.begin(); + for (; it!=list.end(); ++it) { + if ( PURL::Url::fromPathOrUrl(*it).isRelative() ) files += PURL::Url(directory(), *it); + else files += PURL::Url::fromPathOrUrl(*it); + } + return files; +} +void Project::setOpenedFiles(const PURL::UrlList &list) +{ + clearList("general", "opened_files"); + PURL::UrlList::const_iterator it = list.begin(); + for (; it!=list.end(); ++it) + appendListValue("general", "opened_files", (*it).relativeTo(directory())); +} + +PURL::UrlList Project::absoluteFiles() const +{ + PURL::UrlList abs; + QStringList files = listValues("general", "files", QStringList()); + QStringList::const_iterator it = files.begin(); + for (; it!=files.end(); ++it) abs += PURL::Url::fromPathOrUrl(*it).toAbsolute(directory()); + return abs; +} +void Project::addFile(const PURL::Url &url) +{ + appendListValue("general", "files", url.relativeTo(directory())); +} +void Project::removeFile(const PURL::Url &url) +{ + removeListValue("general", "files", url.relativeTo(directory())); +} +void Project::clearFiles() +{ + clearList("general", "files"); +} + +QString Project::toSourceObject(const PURL::Url &url, const QString &extension, bool forWindows) const +{ + PURL::Url tmp; + if ( extension.isEmpty() ) tmp = url.toFileType(PURL::Object); + else tmp = url.toExtension(extension); + return tmp.relativeTo(directory(), forWindows ? PURL::WindowsSeparator : PURL::UnixSeparator); +} + +QStringList Project::objectsForLinker(const QString &extension, bool forWindows) const +{ + QStringList objs; + // objects files corresponding to src files + PURL::UrlList files = absoluteFiles(); + PURL::UrlList::const_iterator it; + for (it=files.begin(); it!=files.end(); ++it) + if ( (*it).data().group==PURL::Source ) objs += toSourceObject(*it, extension, forWindows); + // objects + for (it=files.begin(); it!=files.end(); ++it) + if ( (*it).fileType()==PURL::Object ) objs += (*it).relativeTo(directory(), forWindows ? PURL::WindowsSeparator : PURL::UnixSeparator); + return objs; +} + +QStringList Project::librariesForLinker(const QString &prefix, bool forWindows) const +{ + QStringList libs; + PURL::UrlList files = absoluteFiles(); + PURL::UrlList::const_iterator it; + for (it=files.begin(); it!=files.end(); ++it) + if ( (*it).fileType()==PURL::Library ) libs += prefix + (*it).relativeTo(directory(), forWindows ? PURL::WindowsSeparator : PURL::UnixSeparator); + return libs; +} + +QString Project::version() const +{ + return Compile::Config::globalValue(this, "version", "0.1"); +} +void Project::setVersion(const QString &version) +{ + Compile::Config::setGlobalValue(this, "version", version); +} + +Tool::OutputType Project::outputType() const +{ + return Tool::OutputType::fromKey(Compile::Config::globalValue(this, "output_type", Tool::OutputType(Tool::OutputType::Executable).key())); +} +void Project::setOutputType(Tool::OutputType type) +{ + Compile::Config::setGlobalValue(this, "output_type", type.key()); +} + +QString Project::description() const +{ + return Compile::Config::globalValue(this, "description", QString::null); +} +void Project::setDescription(const QString &description) +{ + Compile::Config::setGlobalValue(this, "description", description); +} + +PURL::Url Project::customLinkerScript() const +{ + QString s = Compile::Config::globalValue(this, "custom_linker_script", QString::null); + return PURL::Url::fromPathOrUrl(s); +} +void Project::setCustomLinkerScript(const PURL::Url &url) +{ + Compile::Config::setGlobalValue(this, "custom_linker_script", url.filepath()); +} + +QValueList Project::watchedRegisters() const +{ + QValueList watched; + QStringList list = listValues("general", "watched_registers", QStringList()); + QStringList::const_iterator it; + for (it=list.begin(); it!=list.end(); ++it) { + Register::TypeData rtd = Register::TypeData::fromString(*it); + if ( rtd.type()!=Register::Invalid ) watched.append(rtd); + } + return watched; +} +void Project::setWatchedRegisters(const QValueList &watched) +{ + clearList("general", "watched_registers"); + QValueList::const_iterator it; + for (it=watched.begin(); it!=watched.end(); ++it) + appendListValue("general", "watched_registers", (*it).toString()); +} + +QValueList Project::bookmarkLines(const PURL::Url &url) const +{ + QValueList lines; + QStringList list = listValues("editors", "bookmarks", QStringList()); + QStringList::const_iterator it; + for (it=list.begin(); it!=list.end(); ++it) { + QStringList slist = QStringList::split(",", *it); + QStringList::const_iterator sit = slist.begin(); + if ( sit==slist.end() || (*sit)!=url.kurl().url() ) continue; + for (; sit!=slist.end(); ++sit) { + bool ok; + uint line = (*sit).toUInt(&ok); + if (!ok) continue; + lines.append(line); + } + break; + } + return lines; +} +void Project::setBookmarkLines(const PURL::Url &url, const QValueList &lines) +{ + QStringList list = listValues("editors", "bookmarks", QStringList()); + QStringList nlist; + QStringList::const_iterator it; + for (it=list.begin(); it!=list.end(); ++it) { + QStringList slist = QStringList::split(",", *it); + QStringList::const_iterator sit = slist.begin(); + if ( sit!=slist.end() && slist.count()>1 && (*sit)!=url.kurl().url() ) nlist += *it; + } + if ( lines.count()!=0 ) { + QStringList slist = url.kurl().url(); + QValueList::const_iterator lit; + for (lit=lines.begin(); lit!=lines.end(); ++lit) slist += QString::number(*lit); + nlist += slist.join(","); + } + setListValues("editors", "bookmarks", nlist); +} diff --git a/src/libgui/project.h b/src/libgui/project.h new file mode 100644 index 0000000..0dfdeab --- /dev/null +++ b/src/libgui/project.h @@ -0,0 +1,49 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * Copyright (C) 2003 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#ifndef PROJECT_H +#define PROJECT_H + +#include "devices/base/register.h" +#include "common/global/xml_data_file.h" +#include "tools/base/generic_tool.h" + +class Project : public XmlDataFile +{ +public: + Project(const PURL::Url &url) : XmlDataFile(url, "piklab") {} + virtual bool load(QString &error); + + PURL::Directory directory() const { return url().directory(); } + QString name() const { return url().basename(); } + PURL::UrlList absoluteFiles() const; + QString version() const; + QString description() const; + Tool::OutputType outputType() const; + PURL::UrlList openedFiles() const; + PURL::Url customLinkerScript() const; + QValueList watchedRegisters() const; + QString toSourceObject(const PURL::Url &url, const QString &extension, bool forWindows) const; + QStringList objectsForLinker(const QString &extension, bool forWindows) const; + QStringList librariesForLinker(const QString &prefix, bool forWindows) const; + QValueList bookmarkLines(const PURL::Url &url) const; // absolute filepath + + void removeFile(const PURL::Url &url); // take absolute filepath (but inside project dir) + void addFile(const PURL::Url &url); // take absolute filePath (but inside project dir) + void clearFiles(); + void setVersion(const QString &version); + void setDescription(const QString &description); + void setOutputType(Tool::OutputType type); + void setOpenedFiles(const PURL::UrlList &list); + void setCustomLinkerScript(const PURL::Url &url); + void setWatchedRegisters(const QValueList &watched); + void setBookmarkLines(const PURL::Url &url, const QValueList &lines); // absolute filepath +}; + +#endif diff --git a/src/libgui/project_editor.cpp b/src/libgui/project_editor.cpp new file mode 100644 index 0000000..4b86429 --- /dev/null +++ b/src/libgui/project_editor.cpp @@ -0,0 +1,72 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * Copyright (C) 2003 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "project_editor.h" + +#include +#include +#include + +#include "project.h" +#include "tools/list/compile_config.h" +#include "device_gui.h" + +ProjectEditor::ProjectEditor(Project &project, QWidget *parent) + : Dialog(parent, "project_options", true, i18n("Project Options"), Ok|Cancel, Ok, false), + _project(project) +{ + QVBoxLayout *top = new QVBoxLayout(mainWidget(), 0, 10); + TabWidget *tabWidget = new TabWidget(mainWidget()); + top->addWidget(tabWidget); + +// global + QWidget *tab = new QWidget(tabWidget); + tabWidget->addTab(tab, i18n("General")); + QGridLayout *grid = new QGridLayout(tab, 0, 0, 10, 10); + QLabel *label = new QLabel(i18n("Name:"), tab); + grid->addWidget(label, 0, 0); + label = new QLabel(project.name(), tab); + grid->addWidget(label, 0, 1); + label = new QLabel(i18n("Description:"), tab); + grid->addWidget(label, 1, 0); + _description = new QTextEdit(tab); + _description->setText(_project.description()); + grid->addMultiCellWidget(_description, 1,1, 1,2); + label = new QLabel(i18n("Version:"), tab); + grid->addWidget(label, 2, 0); + _version = new QLineEdit(tab); + _version->setText(_project.version()); + grid->addWidget(_version, 2, 1); + label = new QLabel(i18n("Device:"), tab); + grid->addWidget(label, 3, 0); + _device = new DeviceChooser::Button(false, tab); + _device->setDevice(Compile::Config::device(&_project)); + grid->addWidget(_device, 3, 1); + grid->setRowStretch(4, 1); + grid->setColStretch(2, 1); + +// toochain + tab = new QWidget(tabWidget); + tabWidget->addTab(tab, i18n("Toochain")); + grid = new QGridLayout(tab, 0, 0, 10, 10); + _tools = new ToolsConfigWidget(&project, tab); + _tools->loadConfig(); + grid->addMultiCellWidget(_tools, 0,0, 0,2); + grid->setRowStretch(1, 1); + grid->setColStretch(2, 1); +} + +void ProjectEditor::slotOk() +{ + _project.setDescription(_description->text()); + _project.setVersion(_version->text()); + Compile::Config::setDevice(&_project, _device->device()); + _tools->saveConfig(); + accept(); +} diff --git a/src/libgui/project_editor.h b/src/libgui/project_editor.h new file mode 100644 index 0000000..5e83fe2 --- /dev/null +++ b/src/libgui/project_editor.h @@ -0,0 +1,47 @@ +/*************************************************************************** + ProjectEditorWid.cpp - description + ------------------- + begin : lun déc 8 2003 + copyright : (C) 2003 by Alain Gibaud + email : alain.gibaud@univ-valenciennes.fr + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ +#ifndef PROJECT_EDITOR_H +#define PROJECT_EDITOR_H + +#include +#include +#include +#include + +#include "tools/list/tools_config_widget.h" +#include "common/gui/misc_gui.h" +class Project; +namespace DeviceChooser { class Button; } + +class ProjectEditor : public Dialog +{ +Q_OBJECT +public: + ProjectEditor(Project &project, QWidget *parent); + +private slots: + virtual void slotOk(); + +private: + Project &_project; + QTextEdit *_description; + QLineEdit *_version; + DeviceChooser::Button *_device; + ToolsConfigWidget *_tools; +}; + +#endif diff --git a/src/libgui/project_manager.cpp b/src/libgui/project_manager.cpp new file mode 100644 index 0000000..dcc4941 --- /dev/null +++ b/src/libgui/project_manager.cpp @@ -0,0 +1,651 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * Copyright (C) 2003 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "project_manager.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "project.h" +#include "project_wizard.h" +#include "project_editor.h" +#include "toplevel.h" +#include "editor_manager.h" +#include "object_view.h" +#include "devices/list/device_list.h" +#include "tools/list/compile_config.h" +#include "register_view.h" +#include "hex_editor.h" +#include "main_global.h" +#include "common/gui/purl_gui.h" +#include "device_gui.h" + +//---------------------------------------------------------------------------- +ProjectManager::View::View(QWidget *parent) + : ListView(parent, "project_manager"), _project(0), _modified(false) +{ + connect(this, SIGNAL(mouseButtonClicked(int, QListViewItem *, const QPoint &, int)), + SLOT(clicked(int, QListViewItem *, const QPoint &, int))); + connect(this, SIGNAL(contextMenuRequested(QListViewItem *, const QPoint &, int)), + SLOT(contextMenu(QListViewItem *, const QPoint &, int))); + connect(this, SIGNAL(itemRenamed(QListViewItem *, int, const QString &)), + SLOT(renamed(QListViewItem *, int, const QString &))); + connect(this, SIGNAL(moved()), SLOT(filesReordered())); + + header()->hide(); + setSorting(-1); + addColumn(QString::null, 170); + setFullWidth(true); + setRootIsDecorated(false); + setAcceptDrops(true); + setDragEnabled(true); + setDropVisualizer(true); + QTimer::singleShot(0, this, SLOT(init()));; +} + +ProjectManager::View::~View() +{ + delete _project; +} + +void ProjectManager::View::init() +{ + clear(); + _rootItem = new RootItem(this); + setCurrentItem(_rootItem); + KListViewItem *item = new RegisterItem(headerItem(DeviceGroup)); + ensureItemVisible(item); + _deviceItem = new DeviceItem(headerItem(DeviceGroup)); + ensureItemVisible(_deviceItem); + _linkerScriptItem = 0; + (void)headerItem(SourceGroup); +} + +ProjectManager::HeaderItem *ProjectManager::View::findHeaderItem(Group group) const +{ + QListViewItemIterator it(const_cast(this)); + for(; it.current(); ++it) { + if ( it.current()->rtti()!=HeaderRtti ) continue; + HeaderItem *hi = static_cast(it.current()); + if ( hi->group()==group ) return hi; + } + return 0; +} + +ProjectManager::HeaderItem *ProjectManager::View::headerItem(Group group) +{ + HeaderItem *item = findHeaderItem(group); + if (item) return item; + item = new HeaderItem(_rootItem, group); + // reorder groups... + HeaderItem *items[Nb_Groups]; + for (uint i=0; itakeItem(items[i]); + } + for (int i=Nb_Groups-1; i>=0; i--) { + if ( items[i]==0 ) continue; + _rootItem->insertItem(items[i]); + } + return item; +} + +ProjectManager::FileItem *ProjectManager::View::findFileItem(const PURL::Url &url) const +{ + QListViewItemIterator it(const_cast(this)); + for(; it.current(); ++it) { + if ( it.current()->rtti()!=FileRtti ) continue; + FileItem *fi = static_cast(it.current()); + if ( fi->url()==url ) return fi; + } + return 0; +} + +ProjectManager::FileItem *ProjectManager::View::findFileItem(PURL::FileType type) const +{ + QListViewItemIterator it(const_cast(this)); + for(; it.current(); ++it) { + if ( it.current()->rtti()!=FileRtti ) continue; + FileItem *fi = static_cast(it.current()); + if ( fi->ftype()==type ) return fi; + } + return 0; +} + +QListViewItem *ProjectManager::View::findItem(const QString &tag) const +{ + QListViewItemIterator it(const_cast(this)); + for(; it.current(); ++it) { + switch (Rtti(it.current()->rtti())) { + case RootRtti: + case FileRtti: + case LinkerScriptRtti: + case DeviceRtti: continue; + case HeaderRtti: + case RegisterRtti: break; + } + if ( it.current()->text(0)==tag ) return it.current(); + } + return 0; +} + +void ProjectManager::View::select(const Editor *e) +{ + QListViewItem *item = 0; + if ( e->url().isEmpty() ) item = findItem(e->tag()); + else item = findFileItem(e->url()); + if (item) setSelected(item, true); + else clearSelection(); +} + +void ProjectManager::View::contextMenu(QListViewItem *item, const QPoint &p, int) +{ + if ( item==0 ) return; + + PopupMenu pop; + Group group = Nb_Groups; + if ( item->rtti()==HeaderRtti) group = static_cast(item)->group(); + + if ( item->rtti()==LinkerScriptRtti || group==LinkerScriptGroup ) { + if ( _project==0 || Main::toolGroup().linkerScriptType()==PURL::Nb_FileTypes ) return; + pop.insertTitle(i18n("Linker Script")); + pop.insertItem("piklab_addfile", i18n("Set Custom...")); + if ( !_project->customLinkerScript().isEmpty() ) pop.insertItem("editdelete", i18n("Set Default")); + switch( pop.exec(p) ) { + case 1: { + PURL::Url url = PURL::getOpenUrl(":custom_linker_script", PURL::filter(Main::toolGroup().linkerScriptType()), this, i18n("Select Linker Script")); + if ( !url.isEmpty() ) _project->setCustomLinkerScript(url); + break; + } + case 2: _project->setCustomLinkerScript(PURL::Url()); break; + } + _linkerScriptItem->init(); + } else if ( item->rtti()==RootRtti ) { + RootItem *ri = static_cast(item); + if ( _project==0 ) { + if ( ri->url().isEmpty() ) { + pop.insertItem("piklab_createproject", i18n("New Project..."), &Main::toplevel(), SLOT(newProject())); + pop.insertItem("piklab_openproject", i18n("Open Project..."), &Main::toplevel(), SLOT(openProject())); + pop.exec(p); + } else { + pop.insertTitle(i18n("Standalone File")); + pop.insertItem("configure", i18n("Configure...")); + if ( pop.exec(p)==1 ) Main::toplevel().configure(ConfigCenter::Standalone); + } + } else { + pop.insertTitle(i18n("Project")); + pop.insertItem("configure", i18n("Options..."), &Main::toplevel(), SLOT(configureProject())); + pop.insertItem("find", i18n("Find Files..."), &Main::toplevel(), SLOT(runKfind())); + pop.insertSeparator(); + pop.insertItem("piklab_compile", i18n("Build Project"), &Main::toplevel(), SLOT(buildProject())); + pop.insertItem("trashcan_empty", i18n("Clean Project"), &Main::toplevel(), SLOT(cleanBuild())); + pop.insertSeparator(); + pop.insertItem("filenew", i18n("New Source File..."), &Main::toplevel(), SLOT(newSourceFile())); + pop.insertItem("piklab_addfile", i18n("Add Source Files..."), this, SLOT(insertSourceFiles())); + pop.insertItem("piklab_addfile", i18n("Add Object Files..."), this, SLOT(insertObjectFiles())); + if ( Main::currentEditor() ) pop.insertItem("piklab_addcurrentfile", i18n("Add Current File"), this, SLOT(insertCurrentFile())); + pop.exec(p); + } + } else if ( item->rtti()==FileRtti ) { + if ( _project==0 ) return; + FileItem *fi = static_cast(item); + if ( isExternalFile(fi->url()) ) return; + pop.insertTitle(item->text(0)); + pop.insertItem("editdelete", i18n("Remove From Project")); + if ( pop.exec(p)==1 ) removeFile(fi->url()); + } else if ( item->rtti()==HeaderRtti ) { + if ( _project==0 ) return; + if ( group==LinkerObjectGroup ) { + pop.insertTitle(i18n("Objects")); + pop.insertItem("piklab_addfile", i18n("Add Object Files..."), this, SLOT(insertObjectFiles())); + pop.exec(p); + } else if ( group==SourceGroup || group==HeaderGroup ) { + pop.insertTitle(i18n("Sources")); + pop.insertItem("filenew", i18n("New File..."), &Main::toplevel(), SLOT(newSourceFile())); + pop.insertItem("piklab_addfile", i18n("Add Source Files..."), this, SLOT(insertSourceFiles())); + pop.exec(p); + } else if ( group==DeviceGroup ) { + pop.insertItem("filenew", i18n("Select Device..."), &Main::toplevel(), SLOT(showDeviceInfo())); + pop.exec(p); + } + } +} + +void ProjectManager::View::closeProject() +{ + if ( _project==0 && projectUrl().isEmpty() ) return; + if (_project) { + // save opened files + PURL::UrlList files = Main::editorManager().files(); + PURL::UrlList::const_iterator it = files.begin(); + PURL::UrlList opened; + for (; it!=files.end(); ++it) { + if ( !isExternalFile(*it) ) opened += *it; + Main::editorManager().closeEditor(*it); + } + _project->setOpenedFiles(opened); + // save watched registers + _project->setWatchedRegisters(Register::list().watched()); + QString error; + if ( !_project->save(error) ) + MessageBox::detailedSorry(i18n("Could not save project file \"%1\".").arg(_project->url().pretty()), error, Log::Show); + delete _project; + _project = 0; + } + _modified = false; + init(); +} + +void ProjectManager::View::addExternalFiles() +{ + const QMap &ext = projectData().externals; + QMap::const_iterator it; + for (it=ext.begin(); it!=ext.end(); ++it) { + if ( !it.key().exists() ) continue; + addFile(it.key(), it.key().fileType(), it.data()); + } +} + +void ProjectManager::View::setStandalone(const PURL::Url &url, PURL::FileType type) +{ + if ( projectUrl()==url ) return; + closeProject(); + _rootItem->set(url, true); + addFile(url, type, Intrinsic); + _standaloneData[url].type = type; + addExternalFiles(); +} + +PURL::Url ProjectManager::View::standaloneGenerator(const PURL::Url &url, PURL::FileType &type) const +{ + QMap::const_iterator it; + for (it=_standaloneData.begin(); it!=_standaloneData.end(); ++it) { + if ( !it.data().externals.contains(url) ) continue; + if ( !it.key().exists() ) continue; + type = it.data().type; + return it.key(); + } + type = PURL::Nb_FileTypes; + return url; +} + +void ProjectManager::View::insertSourceFiles() +{ + Q_ASSERT(_project); + PURL::UrlList list = PURL::getOpenUrls(":", PURL::sourceFilter(PURL::CompleteFilter), this, i18n("Select Source File")); + if ( list.isEmpty() ) return; + PURL::UrlList::const_iterator it; + for (it=list.begin(); it!=list.end(); ++it) insertFile(*it); +} + +void ProjectManager::View::insertObjectFiles() +{ + Q_ASSERT(_project); + PURL::UrlList list = PURL::getOpenUrls(":", PURL::objectFilter(PURL::CompleteFilter), this, i18n("Select Object File")); + if ( list.isEmpty() ) return; + PURL::UrlList::const_iterator it; + for (it=list.begin(); it!=list.end(); ++it) insertFile(*it); +} + +void ProjectManager::View::insertFile(const PURL::Url &url) +{ + if ( !url.exists() ) { + MessageBox::detailedSorry(i18n("Could not find file."), i18n("File: %1").arg(url.pretty()), Log::Show); + return; + } + PURL::Url purl = url; + MessageBox::Result copy = MessageBox::No; + if ( !url.isInto(_project->directory()) ) { + copy = MessageBox::questionYesNoCancel(i18n("File \"%1\" is not inside the project directory. Do you want to copy the file to your project directory?").arg(url.pretty()), + i18n("Copy and Add"), i18n("Add only")); + if ( copy==MessageBox::Cancel ) return; + if ( copy==MessageBox::Yes ) purl = PURL::Url(_project->directory(), url.filename()); + } + if ( _project->absoluteFiles().contains(purl) ) { + MessageBox::detailedSorry(i18n("File is already in the project."), i18n("File: %1").arg(purl.pretty()), Log::Show); + return; + } + if ( copy==MessageBox::Yes ) { + Log::StringView sview; + if ( !url.copyTo(purl, sview) ) { + MessageBox::detailedSorry(i18n("Copying file to project directory failed."), i18n("File: %1\n").arg(url.pretty()) + sview.string(), Log::Show); + return; + } + } + _project->addFile(purl); + addFile(purl, purl.fileType(), Intrinsic); +} + +bool ProjectManager::View::openProject() +{ + PURL::Url url = PURL::getOpenUrl(":open_project", PURL::projectFilter(PURL::CompleteFilter), this, i18n("Select Project file")); + return openProject(url); +} + +void ProjectManager::View::addExternalFile(const PURL::Url &url, FileOrigin origin) +{ + Q_ASSERT( origin!=Intrinsic ); + addFile(url, url.fileType(), origin); +} + +const ProjectManager::View::ProjectData &ProjectManager::View::projectData() const +{ + if ( _project==0 ) return _standaloneData[projectUrl()]; + return _projectData; +} + +ProjectManager::View::ProjectData &ProjectManager::View::projectData() +{ + if ( _project==0 ) return _standaloneData[projectUrl()]; + return _projectData; +} + +void ProjectManager::View::addFile(const PURL::Url &url, PURL::FileType type, FileOrigin origin) +{ + if ( contains(url) ) return; + QMap &ext = projectData().externals; + if ( type.data().group==PURL::LinkerScript && _linkerScriptItem ) { + _linkerScriptItem->set(url); + ext[url] = Included; + return; + } + PURL::FileProperties properties = type.data().properties; + Group grp = Nb_Groups; + switch (origin) { + case Intrinsic: grp = group(type); break; + case Generated: grp = GeneratedGroup; break; + case Included: grp = IncludedGroup; break; + } + HeaderItem *hitem = headerItem(grp); + QListViewItem *item = new FileItem(hitem, type, url, origin!=Intrinsic); + item->moveItem(hitem->lastChild()); + ensureItemVisible(item); + if ( origin!=Intrinsic ) ext[url] = origin; + if ( type==PURL::Hex && _project==0 ) { + QString extension = PURL::extension(PURL::AsmGPAsm); + PURL::Url durl = PURL::Url::fromPathOrUrl("<" + (url.isEmpty() ? i18n("Disassembly") : url.appendExtension(extension).filename()) + ">"); + if ( findFileItem(durl)==0 ) { + (void)new FileItem(headerItem(ViewGroup), PURL::Coff, durl, true); + ext[durl] = Generated; + } + } + if ( _project && origin==Intrinsic ) _modified = true; +} + +void ProjectManager::View::removeExternalFiles() +{ + QMap &ext = projectData().externals; + QMap::const_iterator it; + for (it=ext.begin(); it!=ext.end(); ++it) { + Main::editorManager().closeEditor(it.key()); + removeFile(it.key()); + } + ext.clear(); + if (_linkerScriptItem) _linkerScriptItem->init(); +} + +void ProjectManager::View::removeFile(const PURL::Url &url) +{ + if ( _project && !isExternalFile(url) ) _project->removeFile(url); + FileItem *item = findFileItem(url); + if ( item==0 ) return; + HeaderItem *group = static_cast(item->parent()); + delete item; + if ( group->childCount()==0 ) delete group; + _modified = true; + emit guiChanged(); +} + +void ProjectManager::View::clicked(int button, QListViewItem *item, const QPoint &, int) +{ + if ( item==0 ) return; + if ( button!=LeftButton ) return; + const Device::Data *data = Main::deviceData(); + Rtti rtti = Rtti(item->rtti()); + if ( data==0 && rtti!=DeviceRtti && rtti!=RootRtti ) { + MessageBox::sorry(i18n("Cannot open without device specified."), Log::Show); + return; + } + Editor *e = 0; + ::BusyCursor bc; + switch (rtti) { + case RootRtti: + Main::toplevel().configureProject(); + break; + case HeaderRtti: { + if ( static_cast(item)->group()!=DeviceGroup ) break; + e = Main::editorManager().openEditor(EditorManager::DeviceEditor); + break; + } + case RegisterRtti: + e = Main::editorManager().openEditor(EditorManager::RegisterEditor); + break; + case DeviceRtti: return; + case LinkerScriptRtti: { + PURL::Url url = Main::projectManager().linkerScriptUrl(); + if ( url.isEmpty() ) break; + e = Main::editorManager().findEditor(url); + if ( e==0 ) { + e = Main::editorManager().createEditor(url.fileType(), url); + if ( !e->open(url) ) { + delete e; + break; + } + if ( e && isExternalFile(url) ) e->setReadOnly(true); + Main::editorManager().addEditor(e); + } else Main::editorManager().showEditor(e); + break; + } + case FileRtti: { + FileItem *fi = static_cast(item); + if ( !(fi->ftype().data().properties & PURL::Editable) ) break; + e = Main::editorManager().findEditor(fi->url()); + if ( e==0 ) { + if ( fi->ftype()==PURL::Coff && _project==0 && !fi->url().exists() ) { + PURL::Url url = findFileItem(PURL::Hex)->url(); + if ( url.isEmpty() ) { + HexEditor *he = ::qt_cast(Main::currentEditor()); + if ( he==0 ) break; + e = new DisassemblyEditor(*he, *data, this); + } else e = new DisassemblyEditor(url, *data, this); + addExternalFile(fi->url(), Generated); + } else e = Main::editorManager().createEditor(fi->url().fileType(), fi->url()); + if ( e==0 ) break; + if ( !e->open(fi->url()) ) { + delete e; + break; + } + if ( isExternalFile(fi->url()) ) e->setReadOnly(true); + Main::editorManager().addEditor(e); + } else Main::editorManager().showEditor(e); + break; + } + } + cancelRenaming(); + emit guiChanged(); +} + +void ProjectManager::View::insertCurrentFile() +{ + insertFile(Main::editorManager().currentEditor()->url()); +} + +bool ProjectManager::View::editProject() +{ + ProjectEditor dialog(*_project, this); + if ( dialog.exec()!=QDialog::Accepted ) return false; + _modified = true; + if (_linkerScriptItem) _linkerScriptItem->init(); + return true; +} + +bool ProjectManager::View::newProject() +{ + ProjectWizard wizard(this); + if ( wizard.exec()==QDialog::Rejected ) return false; + closeProject(); + QString error; + if ( !wizard.project()->save(error) ) { + MessageBox::detailedSorry(i18n("Failed to create new project file"), error, Log::Show); + return false; + } + openProject(wizard.url()); + return true; +} + +void ProjectManager::View::setProject(Project *project) +{ + closeProject(); + Main::editorManager().closeAllEditors(); + _project = project; + _rootItem->set(project->url(), false); + if ( project && Main::toolGroup().linkerScriptType()!=PURL::Nb_FileTypes ) { + _linkerScriptItem = new LinkerScriptItem(headerItem(LinkerScriptGroup)); + ensureItemVisible(_linkerScriptItem); + } +} + +bool ProjectManager::View::openProject(const PURL::Url &url) +{ + if ( url.isEmpty() ) return false; + bool reload = ( _project && _project->url()==url ); + if ( reload && !MessageBox::askContinue(i18n("Project already loaded. Reload?"), i18n("Reload")) ) return false; + static_cast< KRecentFilesAction *>(Main::action("project_open_recent"))->removeURL(url.kurl()); + Project *p = new Project(url); + QString error; + if ( !p->load(error) ) { + MessageBox::detailedSorry(i18n("Could not open project file."), error, Log::Show); + delete p; + return false; + } + setProject(p); + PURL::UrlList files = _project->absoluteFiles(); + PURL::UrlList::const_iterator it; + for(it=files.begin(); it!=files.end(); ++it) addFile(*it, (*it).fileType(), Intrinsic); + _projectData.type = PURL::Project; + _projectData.externals.clear(); + static_cast(Main::action("project_open_recent"))->addURL(url.kurl()); + files = _project->openedFiles(); + for(it = files.begin(); it!=files.end(); ++it) Main::editorManager().openFile(*it); + Register::list().init(); + QValueList watched = _project->watchedRegisters(); + QValueList::const_iterator wit; + for (wit=watched.begin(); wit!=watched.end(); ++wit) Register::list().setWatched(*wit, true); + return true; +} + +bool ProjectManager::View::isExternalFile(const PURL::Url &url) const +{ + if ( projectUrl().isEmpty() ) return false; + return projectData().externals.contains(url); +} + +void ProjectManager::View::modified(const PURL::Url &url) +{ + FileItem *item = findFileItem(url); + if ( item && !isExternalFile(url) ) _modified = true; +} + +void ProjectManager::View::renamed(QListViewItem *item, int, const QString &text) +{ + Q_ASSERT ( item->rtti()==DeviceRtti ); + Main::toplevel().setDevice(text); +} + +void ProjectManager::View::updateGUI() +{ + _deviceItem->updateText(); +} + +QDragObject *ProjectManager::View::dragObject() +{ + if ( currentItem()==0 || currentItem()->rtti()!=FileRtti ) return 0; + const FileItem *item = static_cast(currentItem()); + const HeaderItem *hitem = static_cast(item->parent()); + if ( hitem->group()!=SourceGroup ) return 0; + QStrList uris; + uris.append(QUriDrag::localFileToUri(item->url().filepath())); + return new QUriDrag(uris, viewport()); +} + +bool ProjectManager::View::acceptDrag(QDropEvent* e) const +{ + if ( e->source()!=viewport() ) return false; + const QListViewItem *item = itemAt(e->pos()); + if ( item==0 || item->rtti()!=FileRtti ) return false; + const HeaderItem *hitem = static_cast(item->parent()); + return ( hitem->group()==SourceGroup ); +} + +void ProjectManager::View::filesReordered() +{ + if ( _project==0 ) return; + _project->clearFiles(); + QListViewItem *item = headerItem(SourceGroup)->firstChild(); + for (;item; item=item->nextSibling()) + _project->addFile(static_cast(item)->url()); +} + +QString ProjectManager::View::tooltip(QListViewItem *item, int) const +{ + switch (Rtti(item->rtti())) { + case RootRtti: + case FileRtti: + case LinkerScriptRtti: return static_cast(item)->url().filepath(); + case DeviceRtti: + case RegisterRtti: + case HeaderRtti: break; + } + return QString::null; +} + +PURL::Url ProjectManager::View::linkerScriptUrl() const +{ + QListViewItemIterator it(const_cast(this)); + for(; it.current(); ++it) { + if ( it.current()->rtti()!=LinkerScriptRtti ) continue; + return static_cast(it.current())->url(); + } + return PURL::Url(); +} + +bool ProjectManager::View::needsRecompile() const +{ + // ### this could be perfected... + PURL::Url output = projectUrl().toFileType(PURL::Hex); + QDateTime outputLastModified; + if ( !output.exists(&outputLastModified) ) return true; + PURL::UrlList files; + if ( Main::project() ) files = Main::project()->absoluteFiles(); + else files.append(projectUrl()); + PURL::UrlList::const_iterator it; + for (it=files.begin(); it!=files.end(); ++it) { + QDateTime lastModified; + if ( !(*it).exists(&lastModified) ) continue; + if ( lastModified>outputLastModified ) return true; + } + return false; +} + +PURL::Url ProjectManager::View::selectedUrl() const +{ + QListViewItem *item = currentItem(); + if ( item==0 ) return PURL::Url(); + Rtti rtti = Rtti(item->rtti()); + if ( rtti!=FileRtti ) return PURL::Url(); + return static_cast(item)->url(); +} diff --git a/src/libgui/project_manager.h b/src/libgui/project_manager.h new file mode 100644 index 0000000..2939f33 --- /dev/null +++ b/src/libgui/project_manager.h @@ -0,0 +1,106 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * Copyright (C) 2003 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#ifndef PROJECT_MANAGER_H +#define PROJECT_MANAGER_H + +#include "common/global/purl.h" +#include "common/gui/misc_gui.h" +#include "common/gui/list_view.h" +#include "project_manager_ui.h" +class Project; +class Editor; +namespace Coff { class SectionParser; } + +namespace ProjectManager +{ + +class View : public ListView +{ +Q_OBJECT +public: + View(QWidget *parent); + virtual ~View(); + + bool editProject(); + bool newProject(); + bool openProject(); + bool openProject(const PURL::Url &url); + void closeProject(); + Project *project() const { return _project; } + + void setStandalone(const PURL::Url &url, PURL::FileType type); + PURL::Url projectUrl() const { return _rootItem->url(); } + PURL::Url standaloneGenerator(const PURL::Url &url, PURL::FileType &type) const; + PURL::Url linkerScriptUrl() const; + PURL::Url selectedUrl() const; + void removeFile(const PURL::Url &url); + void select(const Editor *e); + void insertFile(const PURL::Url &url); + bool contains(const PURL::Url &url) const { return findFileItem(url); } + void addExternalFile(const PURL::Url &url, FileOrigin fileOrigin); + bool isExternalFile(const PURL::Url &url) const; + void removeExternalFiles(); + + bool isModified() const { return _modified; } + void setModified(bool modified) { _modified = modified; } + bool needsRecompile() const; + +public slots: + void insertSourceFiles(); + void insertObjectFiles(); + void insertCurrentFile(); + void updateGUI(); + +private slots: + void init(); + void contextMenu(QListViewItem *item, const QPoint &pos, int column); + void clicked(int button, QListViewItem *item, const QPoint &pos, int column); + void renamed(QListViewItem *item, int column, const QString &text); + void modified(const PURL::Url &url); + void filesReordered(); + +signals: + void guiChanged(); + +private: + Project *_project; + RootItem *_rootItem; + DeviceItem *_deviceItem; + LinkerScriptItem *_linkerScriptItem; + class ProjectData { + public: + PURL::FileType type; + QMap externals; + }; + QMap _standaloneData; + ProjectData _projectData; + bool _modified; + + HeaderItem *findHeaderItem(Group group) const; + HeaderItem *headerItem(Group group); + FileItem *findFileItem(const PURL::Url &url) const; + FileItem *findFileItem(PURL::FileType type) const; + QListViewItem *findItem(const QString &name) const; + virtual QDragObject *dragObject(); + virtual bool acceptDrag(QDropEvent* e) const; + virtual QString tooltip(QListViewItem *item, int col) const; + void addExternalFiles(); + void rightClicked(QListViewItem *item, const QPoint &pos); + void leftClicked(QListViewItem *item); + void addFile(const PURL::Url &url, PURL::FileType type, FileOrigin origin); + void setProject(Project *project); + void initListView(); + ProjectData &projectData(); + const ProjectData &projectData() const; +}; + +} // namespace + +#endif diff --git a/src/libgui/project_manager_ui.cpp b/src/libgui/project_manager_ui.cpp new file mode 100644 index 0000000..235d360 --- /dev/null +++ b/src/libgui/project_manager_ui.cpp @@ -0,0 +1,185 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * Copyright (C) 2003 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "project_manager_ui.h" + +#include +#include + +#include "project.h" +#include "devices/list/device_list.h" +#include "main_global.h" +#include "common/gui/purl_gui.h" +#include "device_gui.h" + +//---------------------------------------------------------------------------- +void PopupMenu::insertItem(const QString &icon, const QString &label, QObject *receiver, const char *slot) +{ + KIconLoader loader; + QPixmap pixmap = loader.loadIcon(icon, KIcon::Small); + if (receiver) KPopupMenu::insertItem(pixmap, label, receiver, slot, 0, _index); + else KPopupMenu::insertItem(pixmap, label, _index); + _index++; +} + +//---------------------------------------------------------------------------- +const char *ProjectManager::HeaderItem::GROUP_LABELS[Nb_Groups] = { + I18N_NOOP("Device"), I18N_NOOP("Headers"), I18N_NOOP("Linker Script"), + I18N_NOOP("Sources"), I18N_NOOP("Objects"), I18N_NOOP("Views"), + I18N_NOOP("Generated"), I18N_NOOP("Included") +}; + +ProjectManager::Group ProjectManager::group(PURL::FileType type) +{ + switch (type.data().group) { + case PURL::Source: return SourceGroup; + case PURL::Header: return HeaderGroup; + case PURL::LinkerScript: return LinkerScriptGroup; + case PURL::LinkerObject: return LinkerObjectGroup; + case PURL::Nb_FileGroups: break; + } + return ViewGroup; +} + +ProjectManager::RootItem::RootItem(KListView *listview) + : UrlItem(listview) +{ + setSelectable(false); + setPixmap(0, PURL::icon(PURL::Project)); + set(PURL::Url(), true); +} + +void ProjectManager::RootItem::set(const PURL::Url &url, bool standalone) +{ + _url = url; + _standalone = standalone; + if ( _url.isEmpty() ) setText(0, i18n("")); + else if (_standalone) setText(0, i18n("Standalone File")); + else setText(0, _url.basename()); +} + +ProjectManager::HeaderItem::HeaderItem(RootItem *item, Group group) + : KListViewItem(item), _group(group) +{ + if ( group!=DeviceGroup) setSelectable(false); + setText(0, i18n(GROUP_LABELS[group])); +} + +QListViewItem *ProjectManager::HeaderItem::lastChild() const +{ + QListViewItem *item = firstChild(); + if ( item==0 ) return 0; + for (;;) { + if ( item->nextSibling()==0 ) break; + item = item->nextSibling(); + } + return item; +} + +ProjectManager::FileItem::FileItem(HeaderItem *item, PURL::FileType ftype, + const PURL::Url &url, bool external) + : UrlItem(item), _ftype(ftype), _external(external) +{ + setPixmap(0, PURL::icon(ftype)); + set(url); +} + +void ProjectManager::FileItem::set(const PURL::Url &url) +{ + _url = url; + switch (_ftype.type()) { + case PURL::Hex: setText(0, i18n("Hex File")); break; + case PURL::Coff: setText(0, i18n("Disassembly Listing")); break; + case PURL::Lst: setText(0, i18n("List")); break; + case PURL::Map: setText(0, i18n("Memory Map")); break; + case PURL::Project: + case PURL::Nb_FileTypes: Q_ASSERT(false); break; + default: { + QString s = url.filename(); + if ( _external && group(_ftype)==LinkerScriptGroup ) + s += i18n(" (default)"); + setText(0, s); break; + } + } +} + +void ProjectManager::FileItem::paintCell(QPainter *p, const QColorGroup &cg, + int column, int width, int align) +{ + QFont f = p->font(); + f.setItalic(group(_ftype)!=ViewGroup && _external); + p->setFont(f); + KListViewItem::paintCell(p, cg, column, width, align); +} + +ProjectManager::RegisterItem::RegisterItem(HeaderItem *item) + : KListViewItem(item) +{ + KIconLoader loader; + QPixmap chip = loader.loadIcon("piklab_chip", KIcon::Small); + setPixmap(0, chip); + setText(0, i18n("Registers")); +} + +ProjectManager::DeviceItem::DeviceItem(HeaderItem *item) + : EditListViewItem(item) +{} + +QWidget *ProjectManager::DeviceItem::editWidgetFactory(int) const +{ + QComboBox *combo = new DeviceChooser::ComboBox(Main::project()==0, 0); + QString device = Main::device(); + if ( device!=Device::AUTO_DATA.name ) combo->setCurrentText(device); + QObject::connect(combo, SIGNAL(activated(int)), listView(), SLOT(finishRenaming())); + return combo; +} + +void ProjectManager::DeviceItem::updateText() +{ + QString device = Main::device(); + if ( device==Device::AUTO_DATA.name ) { + const Device::Data *data = Main::deviceData(); + if (data) device = data->name() + " " + i18n(Device::AUTO_DATA.label); + else device = i18n(Device::AUTO_DATA.label); + } + setText(0, device); +} + +ProjectManager::LinkerScriptItem::LinkerScriptItem(HeaderItem *item) + : UrlItem(item) +{ + init(); +} + +void ProjectManager::LinkerScriptItem::init() +{ + _url = PURL::Url(); + PURL::Url lkr; + if ( Main::project() ) lkr = Main::project()->customLinkerScript(); + setText(0, lkr.isEmpty() ? i18n("") : lkr.filename()); + setPixmap(0, lkr.isEmpty() ? QPixmap() : PURL::icon(PURL::Lkr)); +} + +void ProjectManager::LinkerScriptItem::set(const PURL::Url &url) +{ + _url = url; + QString s = url.filename(); + PURL::Url lkr; + if ( Main::project() ) lkr = Main::project()->customLinkerScript(); + if ( lkr.isEmpty() ) s += i18n(" (default)"); + setText(0, s); + setPixmap(0, PURL::icon(PURL::Lkr)); +} + +PURL::Url ProjectManager::LinkerScriptItem::url() const +{ + if ( !_url.isEmpty() ) return _url; + if ( Main::project() ) return Main::project()->customLinkerScript(); + return PURL::Url(); +} diff --git a/src/libgui/project_manager_ui.h b/src/libgui/project_manager_ui.h new file mode 100644 index 0000000..012eb64 --- /dev/null +++ b/src/libgui/project_manager_ui.h @@ -0,0 +1,121 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * Copyright (C) 2003 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#ifndef PROJECT_MANAGER_UI_H +#define PROJECT_MANAGER_UI_H + +#include + +#include "common/global/purl.h" +#include "common/gui/misc_gui.h" +#include "common/gui/list_view.h" + +//----------------------------------------------------------------------------- +class PopupMenu : public KPopupMenu +{ +Q_OBJECT +public: + PopupMenu() : _index(1) {} + void insertItem(const QString &icon, const QString &label, QObject *receiver = 0, const char *slot = 0); + +private: + uint _index; +}; + +//----------------------------------------------------------------------------- +namespace ProjectManager +{ + enum Rtti { RootRtti = 1000, HeaderRtti, FileRtti, DeviceRtti, RegisterRtti, LinkerScriptRtti }; + enum Group { DeviceGroup = 0, HeaderGroup, LinkerScriptGroup, SourceGroup, + LinkerObjectGroup, ViewGroup, GeneratedGroup, IncludedGroup, Nb_Groups }; + extern Group group(PURL::FileType type); + enum FileOrigin { Intrinsic, Generated, Included }; + +class UrlItem : public KListViewItem +{ +public: + UrlItem(KListView *listview) : KListViewItem(listview) {} + UrlItem(KListViewItem *item) : KListViewItem(item) {} + virtual PURL::Url url() const { return _url; } + +protected: + PURL::Url _url; +}; + +class RootItem : public UrlItem +{ +public: + RootItem(KListView *listview); + void set(const PURL::Url &url, bool standAlone); + virtual int rtti() const { return RootRtti; } + +private: + bool _standalone; +}; + +class HeaderItem : public KListViewItem +{ +public: + HeaderItem(RootItem *item, Group group); + virtual int rtti() const { return HeaderRtti; } + Group group() const { return _group; } + QListViewItem *lastChild() const; + +private: + static const char *GROUP_LABELS[Nb_Groups]; + Group _group; +}; + +class FileItem : public UrlItem +{ +public: + FileItem(HeaderItem *item, PURL::FileType type, const PURL::Url &url, bool external); + virtual int rtti() const { return FileRtti; } + PURL::FileType ftype() const { return _ftype; } + +private: + PURL::FileType _ftype; + bool _external; + + void set(const PURL::Url &url); + virtual void paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int align); +}; + +class RegisterItem : public KListViewItem +{ +public: + RegisterItem(HeaderItem *item); + virtual int rtti() const { return RegisterRtti; } +}; + +class DeviceItem : public EditListViewItem +{ +public: + DeviceItem(HeaderItem *item); + void updateText(); + virtual int rtti() const { return DeviceRtti; } + +private: + virtual QWidget *editWidgetFactory(int) const; + virtual bool alwaysAcceptEdit(int) const { return true; } +}; + +class LinkerScriptItem : public UrlItem +{ +public: + LinkerScriptItem(HeaderItem *item); + void set(const PURL::Url &url); + virtual PURL::Url url() const; + void init(); + virtual int rtti() const { return LinkerScriptRtti; } +}; + +} // namespace + +#endif diff --git a/src/libgui/project_wizard.cpp b/src/libgui/project_wizard.cpp new file mode 100644 index 0000000..b4d26df --- /dev/null +++ b/src/libgui/project_wizard.cpp @@ -0,0 +1,283 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "project_wizard.h" + +#include +#include +#include +#include +#include +#include + +#include "common/gui/purl_gui.h" +#include "device_gui.h" +#include "tools/list/tool_list.h" +#include "tools/list/compile_config.h" +#include "main_global.h" +#include "project.h" +#include "tools/list/compile_process.h" +#include "common/gui/editlistbox.h" +#include "devices/list/device_list.h" + +//----------------------------------------------------------------------------- +FileListItem::FileListItem(KListView *view) + : KListViewItem(view), _group(0), _copy(true) +{ + KIconLoader loader; + _pixmap = loader.loadIcon("button_ok", KIcon::Small); +} + +void FileListItem::toggle() +{ + _copy = !_copy; + repaint(); +} + +PURL::FileGroup FileListItem::fileGroup() const +{ + if ( _group==0 ) return PURL::Nb_FileGroups; + PURL::Url url = PURL::Url::fromPathOrUrl(text(1)); + switch (url.data().group) { + case PURL::Source: { + FOR_EACH(PURL::ToolType, type) + if ( _group->implementationType(type)==url.fileType() ) return PURL::Source; + break; + } + case PURL::Header: return PURL::Header; + case PURL::LinkerScript: { + if ( _group->linkerScriptType()==url.fileType() ) return PURL::LinkerScript; + break; + } + case PURL::LinkerObject: return PURL::LinkerObject; + case PURL::Nb_FileGroups: break; + } + return PURL::Nb_FileGroups; +} + +const QPixmap *FileListItem::pixmap(int column) const +{ + + if ( column==0 && _copy ) return &_pixmap; + return KListViewItem::pixmap(column); +} + +//----------------------------------------------------------------------------- +FileListBox::FileListBox(QWidget *parent) + : EditListBox(2, 0, 0, parent, "file_list_box") +{ + _listView->header()->show(); + _listView->header()->setClickEnabled(false); + _listView->header()->setResizeEnabled(false); + _listView->header()->setMovingEnabled(false); + _listView->setColumnText(0, i18n("Copy")); + int spacing = style().pixelMetric(QStyle::PM_HeaderMargin); + QFontMetrics fm(font()); + _listView->header()->resizeSection(0, fm.width(i18n("Copy")) + 2*spacing); // hack + _listView->setColumnText(1, i18n("Filename")); + _listView->setAllColumnsShowFocus(true); + connect(_listView, SIGNAL(clicked(QListViewItem *, const QPoint &, int)), SLOT(clicked(QListViewItem *, const QPoint &, int))); +} + +void FileListBox::addItem() +{ + PURL::UrlList urls = PURL::getOpenUrls(_directory.path(), QString::null, this, i18n("Select Files")); + PURL::UrlList::const_iterator it; + for (it=urls.begin(); it!=urls.end(); ++it) EditListBox::addItem((*it).pretty()); +} + +QListViewItem *FileListBox::createItem() +{ + return new FileListItem(_listView); +} + +void FileListBox::clicked(QListViewItem *item, const QPoint &, int column) +{ + if ( item==0 || column!=0 ) return; + static_cast(item)->toggle(); +} + +void FileListBox::setToolGroup(const Tool::Group &group) +{ + QListViewItem *item = _listView->firstChild(); + for (; item; item = item->nextSibling()) static_cast(item)->setToolGroup(group); +} + +//----------------------------------------------------------------------------- +ProjectWizard::ProjectWizard(QWidget *parent) + : KWizard(parent, "project_wizard"), _project(0) +{ + // first page + _first = new QWidget(this); + addPage(_first, i18n("New Project: Basic Settings")); + setHelpEnabled(_first, false); + QGridLayout *grid = new QGridLayout(_first, 1, 1, 10, 10); + QLabel *label = new QLabel(i18n("Name:"), _first); + grid->addWidget(label, 0, 0); + _name = new KLineEdit(_first); + _name->setFocus(); + grid->addMultiCellWidget(_name, 0,0, 1,2); + label = new QLabel(i18n("Directory:"), _first); + grid->addWidget(label, 1, 0); + _directory = new PURL::DirectoryWidget(":new_project", _first); + grid->addMultiCellWidget(_directory, 1,1, 1,2); + label = new QLabel(i18n("Device:"), _first); + grid->addWidget(label, 2, 0); + _device = new DeviceChooser::Button(false, _first); + _device->setDevice(Main::device()); + grid->addWidget(_device, 2, 1); + label = new QLabel(i18n("Toolchain:"), _first); + grid->addWidget(label, 3, 0); + _toolchain = new KeyComboBox(_first); + Tool::Lister::ConstIterator it; + for (it=Tool::lister().begin(); it!=Tool::lister().end(); ++it) + _toolchain->appendItem(it.key(), it.data()->label()); + _toolchain->setCurrentItem(Main::toolGroup().name()); + grid->addWidget(_toolchain->widget(), 3, 1); + grid->setColStretch(2, 1); + grid->setRowStretch(4, 1); + + // second page + _second = new QWidget(this); + addPage(_second, i18n("New Project: Source Files")); + grid = new QGridLayout(_second, 1, 1, 10, 10); + _bgroup = new QVButtonGroup(i18n("Add Source Files"), _second); + _templateButton = new QRadioButton(i18n("Create template source file."), _bgroup); + _addButton = new QRadioButton(i18n("Add existing files."), _bgroup); + (void)new QRadioButton(i18n("Do not add files now."), _bgroup); + connect(_bgroup, SIGNAL(clicked(int)), SLOT(buttonClicked(int))); + grid->addWidget(_bgroup, 0, 0); + + // third page + _third = new QWidget(this); + addPage(_third, i18n("New Project: Add Files")); + setHelpEnabled(_third, false); + setFinishEnabled(_third, true); + grid = new QGridLayout(_third, 1, 1, 10, 10); + _files = new FileListBox(_third); + grid->addWidget(_files, 0, 0); +} + +void ProjectWizard::next() +{ + if ( currentPage()==_first ) { + QString name = _name->text().stripWhiteSpace(); + if ( name.isEmpty() ) { + MessageBox::sorry(i18n("Project name is empty."), Log::Show); + return; + } + PURL::Directory directory = _directory->directory(); + if ( directory.isEmpty() ) { + MessageBox::sorry(i18n("Directory is empty."), Log::Show); + return; + } + Log::StringView sview; + if ( !directory.exists() ) { + if ( !MessageBox::askContinue(i18n("Directory does not exists. Create it?")) ) return; + if ( !_directory->directory().create(sview) ) { + MessageBox::detailedSorry(i18n("Error creating directory."), sview.string(), Log::Show); + return; + } + } else if ( url().exists() ) { + if ( !MessageBox::askContinue(i18n("Project \"%1\"already exists. Overwrite it?").arg(url().filename())) ) return; + } + if ( !toolchain().check(device(), &Main::compileLog()) ) return; + _files->setDirectory(_directory->directory()); + _files->setToolGroup(toolchain()); + if ( toolchain().name()=="custom" ) { + _templateButton->hide(); + _addButton->setChecked(true); + } else { + _templateButton->show(); + _templateButton->setChecked(true); + } + buttonClicked(0); + } + if ( currentPage()==_third ) { + uint nb = 0; + for (uint i=0; i<_files->count(); i++) + if ( static_cast(_files->item(i))->fileGroup()==PURL::Source ) nb++; + if ( toolchain().compileType()==Tool::SingleFile && nb>1 ) { + if ( !MessageBox::askContinue(i18n("The selected toolchain can only compile a single source file and you have selected %1 source files. Continue anyway? ").arg(nb)) ) return; + } + } + KWizard::next(); +} + +void ProjectWizard::done(int r) +{ + if ( r==Accepted ) { + PURL::UrlList files; + _project = new Project(url()); + Compile::Config::setDevice(_project, device()); + Compile::Config::setToolGroup(_project, toolchain()); + Compile::Config::setCustomCommands(_project, Compile::Config::customCommands(0)); + + if ( _bgroup->selectedId()==0 ) { + PURL::ToolType ttype = PURL::ToolType::Compiler; + PURL::FileType ftype = PURL::Nb_FileTypes; + FOR_EACH(PURL::ToolType, i) { + PURL::FileType type = toolchain().implementationType(i); + if ( type==PURL::Nb_FileTypes ) continue; + ftype = type; + ttype = i; + } + Q_ASSERT( ftype!=PURL::Nb_FileTypes ); + PURL::Url turl = url().toFileType(ftype); + QString text; + const Tool::SourceGenerator *generator = toolchain().sourceGenerator(); + if ( generator==0 ) text = i18n("Template source file generation not implemented yet for this toolchain..."); + else { + bool ok = true; + const Device::Data *data = Device::lister().data(device()); + SourceLine::List lines; + SourceLine::List list = generator->templateSourceFile(ttype, *data, ok); + if ( !ok ) lines.appendTitle(i18n("Template source file generation only partially implemented.")); + lines += list; + text = SourceLine::text(ftype.data().sourceFamily, lines, 4); + } + Log::StringView sview; + if ( turl.write(text, sview) ) files += turl; + else MessageBox::detailedSorry(i18n("Error creating template file."), i18n("File: %1\n").arg(turl.pretty()) + sview.string(), Log::Show); + _project->setOpenedFiles(files); + } else { + Log::StringView sview; + for (uint i=0; i<_files->count(); i++) { + PURL::Url furl = PURL::Url::fromPathOrUrl(_files->text(i)); + if ( static_cast(_files->item(i))->copy() ) { + PURL::Url to(url().directory(), furl.filename()); + if ( furl==to || furl.copyTo(to, sview) ) files += to; + } else files += furl; + } + } + PURL::UrlList::const_iterator it; + for (it=files.begin(); it!=files.end(); ++it) _project->addFile(*it); + } + KWizard::done(r); +} + +PURL::Url ProjectWizard::url() const +{ + return PURL::Url(PURL::Directory(_directory->directory()), _name->text(), PURL::Project); +} + +const Tool::Group &ProjectWizard::toolchain() const +{ + return *Tool::lister().group(_toolchain->currentItem()); +} + +QString ProjectWizard::device() const +{ + return _device->device(); +} + +void ProjectWizard::buttonClicked(int id) +{ + setNextEnabled(_second, id==1); + setFinishEnabled(_second, id!=1); +} diff --git a/src/libgui/project_wizard.h b/src/libgui/project_wizard.h new file mode 100644 index 0000000..312ef01 --- /dev/null +++ b/src/libgui/project_wizard.h @@ -0,0 +1,91 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PROJECT_WIZARD_H +#define PROJECT_WIZARD_H + +#include +#include +#include +#include +#include + +#include "common/global/purl.h" +#include "common/gui/editlistbox.h" +#include "common/gui/key_gui.h" +namespace PURL { class DirectoryWidget; } +namespace DeviceChooser { class Button; } +namespace Tool { class Group; } +class Project; + +//----------------------------------------------------------------------------- +class FileListItem : public KListViewItem +{ +public: + FileListItem(KListView *view); + void setToolGroup(const Tool::Group &group) { _group = &group; } + bool copy() const { return _copy; } + void toggle(); + PURL::FileGroup fileGroup() const; + virtual const QPixmap *pixmap(int column) const; + +private: + const Tool::Group *_group; + QPixmap _pixmap; + bool _copy; +}; + +class FileListBox : public EditListBox +{ +Q_OBJECT +public: + FileListBox(QWidget *parent); + void setDirectory(const PURL::Directory &directory) { _directory = directory; } + void setToolGroup(const Tool::Group &group); + +protected slots: + virtual void addItem(); + virtual void clicked(QListViewItem *item, const QPoint &point, int column); + +private: + PURL::Directory _directory; + + virtual uint textColumn() const { return 1; } + virtual QListViewItem *createItem(); +}; + +//----------------------------------------------------------------------------- +class ProjectWizard : public KWizard +{ +Q_OBJECT +public: + ProjectWizard(QWidget *parent); + PURL::Url url() const; + Project *project() const { return _project; } + +protected slots: + void buttonClicked(int id); + virtual void next(); + virtual void done(int r); + +private: + QWidget *_first, *_second, *_third; + KLineEdit *_name; + PURL::DirectoryWidget *_directory; + DeviceChooser::Button *_device; + KeyComboBox *_toolchain; + QButtonGroup *_bgroup; + QRadioButton *_templateButton, *_addButton; + FileListBox *_files; + Project *_project; + + QString device() const; + const Tool::Group &toolchain() const; +}; + +#endif diff --git a/src/libgui/register_view.cpp b/src/libgui/register_view.cpp new file mode 100644 index 0000000..3c244e8 --- /dev/null +++ b/src/libgui/register_view.cpp @@ -0,0 +1,51 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "register_view.h" + +#include +#include +#include +#include +#include + +#include "devices/base/device_group.h" +#include "devices/gui/device_group_ui.h" +#include "progs/base/prog_group.h" +#include "common/gui/misc_gui.h" +#include "main_global.h" +#include "editor_manager.h" +#include "gui_debug_manager.h" + +//----------------------------------------------------------------------------- +Register::MainView::MainView(const QString &title, const QString &tag, QWidget *parent) + : DeviceEditor(title, tag, parent, "register_view"), _debugging(false) +{} + +void Register::MainView::setDevice(bool force) +{ + bool oldDebugging = _debugging; + _debugging = Main::programmerGroup().isDebugger(); + DeviceEditor::setDevice(force || oldDebugging!=_debugging); +} + +QWidget *Register::MainView::createView(const Device::Data *data, QWidget *parent) +{ + if ( data==0 ) return new QWidget(parent); + Register::View *view = Device::groupui(*data).createRegisterView(parent); + if (view) view->updateView(); + else { + QWidget *w = new QWidget(parent); + QVBoxLayout *vbox = new QVBoxLayout(w, 10, 10); + QLabel *label = new QLabel(i18n("The selected device has no register."), w); + vbox->addWidget(label); + vbox->addStretch(1); + return w; + } + return view; +} diff --git a/src/libgui/register_view.h b/src/libgui/register_view.h new file mode 100644 index 0000000..7d12f0d --- /dev/null +++ b/src/libgui/register_view.h @@ -0,0 +1,42 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef REGISTER_EDITOR_H +#define REGISTER_EDITOR_H + +#include "device_editor.h" +#include "devices/gui/register_view.h" + +namespace Register +{ +class View; + +//----------------------------------------------------------------------------- +class MainView : public DeviceEditor +{ +Q_OBJECT +public: + MainView(const QString &title, const QString &tag, QWidget *parent = 0); + virtual bool isModified() const { return false; } + virtual bool isReadOnly() const { return true; } + virtual void addGui() {} + virtual void removeGui() {} + virtual void setFocus() {} + virtual void setDevice(bool force = false); + Register::View *view() { return static_cast(_view); } + +private: + bool _debugging; + virtual QWidget *createView(const Device::Data *, QWidget *parent); + virtual void setModifiedInternal(bool) {} + virtual void setReadOnlyInternal(bool) {} +}; + +} // namespace + +#endif diff --git a/src/libgui/text_editor.cpp b/src/libgui/text_editor.cpp new file mode 100644 index 0000000..aecbc99 --- /dev/null +++ b/src/libgui/text_editor.cpp @@ -0,0 +1,346 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "text_editor.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "main_global.h" +#include "gui_debug_manager.h" +#include "editor_manager.h" +#include "global_config.h" +#include "toplevel.h" + +//----------------------------------------------------------------------------- +const TextEditor::MarkTypeData TextEditor::MARK_TYPE_DATA[Breakpoint::Nb_MarkTypes] = { + { KTextEditor::MarkInterface::Execution, "piklab_program_counter" }, + { KTextEditor::MarkInterface::markType08, "piklab_program_counter_disabled" }, + { KTextEditor::MarkInterface::BreakpointActive, "piklab_breakpoint_active" }, + { KTextEditor::MarkInterface::BreakpointDisabled, "piklab_breakpoint_disabled" }, + { KTextEditor::MarkInterface::BreakpointReached, "piklab_breakpoint_reached" }, + { KTextEditor::MarkInterface::Error, "piklab_breakpoint_invalid" } +}; + +QPixmap TextEditor::pixmap(Breakpoint::MarkType type) +{ + return SmallIcon(MARK_TYPE_DATA[type].pixmap); +} + +TextEditor::TextEditor(bool withDebugger, QWidget *parent, const char *name) + : Editor(parent, name), _view(0) +{ + KLibFactory *factory = KLibLoader::self()->factory("libkatepart"); + if ( factory==0 ) qFatal("Could not find katepart"); + _document = static_cast(factory->create(this, "kate", "KTextEditor::Document")); + _oldModified = _document->isModified(); + _oldReadOnly = !_document->isReadWrite(); + + QVBoxLayout *top = new QVBoxLayout(this, 0, 10); + _split = new QSplitter(this); + _split->setFrameStyle(QFrame::TabWidgetPanel | QFrame::Sunken); + top->addWidget(_split); + + connect(_document, SIGNAL(hlChanged()), SLOT(highlightChanged())); + setAcceptDrops(true); + addView(); + + for (uint i=0; isetPixmap(KTextEditor::MarkInterface::MarkTypes(MARK_TYPE_DATA[i].type), pixmap(Breakpoint::MarkType(i))); + + if (withDebugger) QTimer::singleShot(0, this, SLOT(addToDebugManager())); +} + +bool TextEditor::open(const PURL::Url &url) +{ + setReadOnly(url.fileType().data().properties & PURL::ReadOnly); + if ( !_document->openURL(url.kurl()) ) return false; + _view->setEol(url.isDosFile() ? Dos : Unix); + highlightChanged(); + return true; +} + +void TextEditor::addToDebugManager() +{ + static_cast(Debugger::manager)->addTextEditor(*this); +} + +bool TextEditor::eventFilter(QObject *, QEvent *e) +{ + if ( e->type()==QEvent::KeyPress ) { + if ( static_cast(e)->key()==Key_Escape ) return true; + } + return false; +} + +void TextEditor::addView() +{ + KTextEditor::View *v = _document->createView(_split); + if ( _view==0 ) _view = static_cast(v); + Q_ASSERT(v); + connect(v, SIGNAL(gotFocus(Kate::View *)), SLOT(gotFocus(Kate::View *))); + connect(v, SIGNAL(cursorPositionChanged()), SLOT(statusChanged())); + connect(v, SIGNAL(dropEventPass(QDropEvent *)), SIGNAL(dropEventPass(QDropEvent *))); + connect(v, SIGNAL(newStatus()), SLOT(statusChanged())); + v->show(); + v->setFocus(); + v->child(0, "KateViewInternal")->installEventFilter(this); + KTextEditor::PopupMenuInterface *pmi = KTextEditor::popupMenuInterface(v); + pmi->installPopup(&Main::popup("ktexteditor_popup")); + + // dispatch available space between views + QValueList list = _split->sizes(); + QValueList::Iterator it; + int sum = 0; + for (it = list.begin(); it!= list.end(); ++it) sum += *it; + sum /= list.size(); + for (it = list.begin(); it!=list.end(); ++it) *it = sum; + _split->setSizes(list); + + emit guiChanged(); +} + +void TextEditor::gotFocus(Kate::View *v) +{ + _view = v; + setFocusProxy(v); + statusChanged(); + emit guiChanged(); +} + +void TextEditor::addGui() +{ + Main::toplevel().guiFactory()->addClient(_view); +} + +void TextEditor::removeGui() +{ + Main::toplevel().guiFactory()->removeClient(_view); +} + +void TextEditor::removeCurrentView() +{ + delete _view; + _view = static_cast(_document->views().last()); + _document->views().last()->setFocus(); + emit guiChanged(); +} + +bool TextEditor::isReadOnly() const +{ + return !_document->isReadWrite(); +} + +void TextEditor::setReadOnlyInternal(bool ro) +{ + _oldReadOnly = ro; + _document->setReadWrite(!ro); +} + +bool TextEditor::isModified() const +{ + return _document->isModified(); +} + +void TextEditor::setModifiedInternal(bool m) +{ + _oldModified = m; + _document->setModified(m); +} + +void TextEditor::statusChanged() +{ + uint line, col; + _view->cursorPosition(&line, &col) ; + QString text = i18n("Line: %1 Col: %2").arg(line+1).arg(col+1); + if( isReadOnly() ) text += " " + i18n("R/O"); + emit statusTextChanged(" " + text + " "); + if ( isReadOnly()!=_oldReadOnly || isModified()!=_oldModified ) emit guiChanged(); + if ( isModified()!=_oldModified ) emit modified(); + _oldModified = isModified(); + _oldReadOnly = isReadOnly(); + Breakpoint::Data data(url(), line); + Breakpoint::updateActions(&data); +} + +uint TextEditor::highlightMode(const QString &name) const +{ + uint mode = 0; + for (; mode<_document->hlModeCount(); mode++) + if ( _document->hlModeName(mode)==name ) break; + return mode; +} + +void TextEditor::highlightChanged() +{ + if ( fileType()==PURL::Nb_FileTypes ) return; + // managed by hand because of collisions with file extensions + // used by other languages/softwares like other ASM and also PHP... + const char *name = fileType().data().highlightModeName; + if ( name==0 ) return; + uint mode = highlightMode(name); + if ( mode>=_document->hlModeCount() || _document->hlMode()==mode ) return; + _document->setHlMode(mode); +} + +uint TextEditor::cursorLine() const +{ + uint line; + _view->cursorPosition(&line, 0); + return line; +} + +void TextEditor::setMark(uint line, Breakpoint::MarkType type) +{ + _view->setIconBorder(true); + _document->setMark(line, MARK_TYPE_DATA[type].type); +} + +void TextEditor::clearMarks(uint type) +{ + QPtrList marks = _document->marks(); + QPtrListIterator it(marks); + for (; it.current(); ++it) + if ( it.current()->type==type ) _document->removeMark(it.current()->line, it.current()->type); +} + +void TextEditor::clearBreakpointMarks() +{ + for (uint i=0; i TextEditor::bookmarkLines() const +{ + QValueList lines; + QPtrList marks = _document->marks(); + QPtrListIterator it(marks); + for (; it.current(); ++it) + if ( it.current()->type==KTextEditor::MarkInterface::Bookmark ) lines.append(it.current()->line); + return lines; +} + +void TextEditor::setBookmarkLines(const QValueList &lines) +{ + clearMarks(KTextEditor::MarkInterface::Bookmark); + QValueList::const_iterator it; + for (it=lines.begin(); it!=lines.end(); ++it) + _document->setMark(*it, KTextEditor::MarkInterface::Bookmark); +} + + +#if 0 +void TextEditor::slotChangedText() +{ + //This slot runs the instrucion set help bar, + // finds the current command word and compares it to the set of instrucions + //Found in the descript Qstringlist. + + + QString currentword; + QString testval; + + Kate::View *v = currentView(); + currentword = v->currentTextLine(); + //prepare the string for compareing + currentword = currentword.simplifyWhiteSpace(); + currentword = currentword.upper(); + + for ( QStringList::Iterator it = descript.begin(); it != descript.end(); ++it ) + { + testval = *it; + if(testval.startsWith(currentword.left(5))) + { + //if (testval.left(5) == currentword.left(5) ) { + lab_curword->setText(*it); + } + // else { + // lab_curword->setText("Pic Instruction Help"); + // } + } + + +} +#endif +#if 0 +void TextEditor::populateList() +{ + //Populate the qstringlist with the pic instruction set, and the text to go along with them + + descript += "CLRF : Clear F OPERANDS: f"; + descript += "ADDWF : Add W to F OPERANDS: f,d"; + descript += "ANDWF : AND W with F OPERANDS: f,d"; + descript += "CLRW : Clear W OPERANDS: NONE"; + descript += "COMF : Complement F OPERANDS: f,d"; + descript += "DECF : Decrement F OPERANDS: f,d"; + descript += "DECSSZ: Decrement F, Skip 0 OPERANDS: f,d"; + descript += "INCF : Increment F OPERANDS: f,d"; + descript += "INCFSZ: Increment F, Skip 0 OPERANDS: f,d"; + descript += "IORWF : Inclusive OR W with F OPERANDS: f,d"; + descript += "MOVF : Move F, OPERANDS: f,d"; + descript += "MOVWF : Move W to F OPERANDS: f,d"; + descript += "NOP : No Operation OPERANDS: NONE"; + descript += "RLF : Rotate Left F through Carry OPERANDS: f,d"; + descript += "RRF : Rotate Right F through Carry OPERANDS: f,d"; + descript += "SUBWF : Subtract W from F OPERANDS: f,d"; + descript += "SWAPF : Swap Nibbles in F OPERANDS: f,d"; + descript += "XORWF : Exclusive OR W with F OPERANDS: f,s"; + descript += "BCF : Bit Clear F OPERANDS: f,b"; + descript += "BSF : Bit Set F OPERANDS: f,b"; + descript += "BTFSC : Bit Test F, Skip if Clear OPERANDS: f,b"; + descript += "BTFSS : Bit Test F, Skip if Set OPERANDS: f,b"; + descript += "ADDLW : Add Literal and W OPERANDS: k"; + descript += "ANDLW : And Literal and W OPERANDS: k"; + descript += "CLRWDT: Clear Watchdog Timer OPERANDS: NONE"; + descript += "CALL : Call Subroutine OPERANDS: k"; + descript += "GOTO : Goto address OPERANDS: k"; + descript += "IORLW : Inclusive OR literal with W OPERANDS: k"; + descript += "MOVLW : Move Literal with W OPERANDS: k"; + descript += "RETFIE: Return From Interrupt OPERANDS: NONE"; + descript += "RETLW : Return with Literal in W OPERANDS: k"; + descript += "RETURN: Return from subroutine OPERANDS: NONE"; + descript += "SLEEP : Go into Standby Mode OPERANDS: NONE"; + descript += "SUBLW : Subtract W from Literal OPERANDS: k"; + descript += "XORLW : Exclusive OR Literal with W OPERANDS: k"; + +} +#endif + +//----------------------------------------------------------------------------- +SimpleTextEditor::SimpleTextEditor(bool withDebugger, PURL::FileType type, QWidget *parent, const char *name) + : TextEditor(withDebugger, parent, name), _type(type), _file(_sview) +{} + +SimpleTextEditor::SimpleTextEditor(bool withDebugger, QWidget *parent, const char *name) + : TextEditor(withDebugger, parent, name), _type(PURL::Nb_FileTypes), _file(_sview) +{} + +bool SimpleTextEditor::open(const PURL::Url &url) +{ + _type = url.fileType(); + return TextEditor::open(url); +} + +bool SimpleTextEditor::setText(const QString &text) +{ + _file.openForWrite(); + _file.appendText(text); + _file.close(); + if ( !_document->openURL(_file.url().kurl()) ) return false; + highlightChanged(); + return true; +} diff --git a/src/libgui/text_editor.h b/src/libgui/text_editor.h new file mode 100644 index 0000000..9c5a994 --- /dev/null +++ b/src/libgui/text_editor.h @@ -0,0 +1,103 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#ifndef TEXT_EDITOR_H +#define TEXT_EDITOR_H + +#include +#include +class QSplitter; + +#include +#include + +#include "common/gui/pfile_ext.h" +#include "editor.h" +#include "progs/manager/breakpoint.h" + +//----------------------------------------------------------------------------- +class TextEditor : public Editor +{ +Q_OBJECT +public: + TextEditor(bool withDebugger, QWidget *parent, const char *name = 0); + virtual PURL::FileType fileType() const { return url().fileType(); } + virtual PURL::Url url() const { return _document->url(); } + virtual bool isModified() const; + virtual bool isReadOnly() const; + virtual void addGui(); + virtual void removeGui(); + virtual void setFocus() { _view->setFocus(); } + static QPixmap pixmap(Breakpoint::MarkType type); + void setMark(uint line, Breakpoint::MarkType type); + void clearBreakpointMarks(); + void setCursor(uint line, uint column) { _view->setCursorPosition(line, column); } + uint cursorLine() const; + virtual bool open(const PURL::Url &url); + virtual bool save(const PURL::Url &url) { return _document->saveAs(url.kurl()); } + virtual bool eventFilter(QObject *o, QEvent *e); + virtual QValueList bookmarkLines() const; + virtual void setBookmarkLines(const QValueList &lines); + +public slots: + void addView(); + void removeCurrentView(); + void gotFocus(Kate::View *); + void highlightChanged(); + virtual void statusChanged(); + void selectAll() { _document->selectAll(); } + void deselect() { _document->clearSelection(); } + void copy() { _view->copy(); } + +protected: + enum EolType { Dos = 1, Unix = 0, Mac = 2 }; + Kate::Document *_document; + Kate::View *_view; + +private slots: + void addToDebugManager(); + +private: + QSplitter *_split; + bool _oldModified, _oldReadOnly; + struct MarkTypeData { + uint type; + const char *pixmap; + }; + static const MarkTypeData MARK_TYPE_DATA[Breakpoint::Nb_MarkTypes]; + +private: + virtual void setModifiedInternal(bool modified); + virtual void setReadOnlyInternal(bool readOnly); + uint highlightMode(const QString &name) const; + void clearMarks(uint type); +}; + +//----------------------------------------------------------------------------- +class SimpleTextEditor : public TextEditor +{ +Q_OBJECT +public: + SimpleTextEditor(bool withDebugger, PURL::FileType type, QWidget *parent, const char *name = 0); + SimpleTextEditor(bool withDebugger, QWidget *parent, const char *name = 0); + void setFileType(PURL::FileType type) { _type = type; } + virtual PURL::FileType fileType() const { return _type; } + bool setText(const QString &text); + virtual bool open(const PURL::Url &url); + +protected: + virtual bool load() { return false; } + +private: + Log::StringView _sview; + PURL::FileType _type; + PURL::TempFile _file; +}; + +#endif diff --git a/src/libgui/toplevel.cpp b/src/libgui/toplevel.cpp new file mode 100644 index 0000000..c757ace --- /dev/null +++ b/src/libgui/toplevel.cpp @@ -0,0 +1,993 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "toplevel.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gui_debug_manager.h" +#include "hex_editor.h" +#include "project_manager.h" +#include "project.h" +#include "global_config.h" +#include "editor.h" +#include "device_gui.h" +#include "text_editor.h" +#include "new_dialogs.h" +#include "common/global/process.h" +#include "common/gui/misc_gui.h" +#include "common/gui/purl_gui.h" +#include "devices/list/device_list.h" +#include "progs/base/prog_config.h" +#include "progs/list/prog_list.h" +#include "progs/gui/prog_group_ui.h" +#include "editor_manager.h" +#include "tools/list/compile_manager.h" +#include "object_view.h" +#include "config_gen.h" +#include "tools/list/compile_config.h" +#include "watch_view.h" +#include "coff/base/text_coff.h" +#include "tools/list/tool_list.h" +#include "breakpoint_view.h" +#include "main_global.h" +#include "gui_prog_manager.h" +#include "devices/gui/register_view.h" +#include "likeback.h" +#include "console.h" +#include "devices/base/device_group.h" +#include "tools/gui/toolchain_config_center.h" +#include "global_config.h" + +//---------------------------------------------------------------------------- +KDockWidget *MainWindow::createDock(const QString &name, const QPixmap &icon, + const QString &title, const DockPosition &position) +{ + KDockWidget *dock = createDockWidget(name, icon, 0, title); + dock->setDockSite(KDockWidget::DockCenter); + DockData ddata; + ddata.title = title; + ddata.position = position; + ddata.dock = dock; + ddata.action = new ViewMenuAction(dock); + connect(ddata.action, SIGNAL(activated(QWidget *)), SLOT(toggleToolView(QWidget *))); + _docks += ddata; + initDockPosition(ddata); + return dock; +} + +MainWindow::MainWindow() + : _configGenerator(0), _pikloopsProcess(0), _kfindProcess(0), _forceProgramAfterBuild(false) +{ + Q_ASSERT( Main::_toplevel==0 ); + Main::_toplevel = this; + +// status bar + _actionStatus = new QLabel(statusBar()); + statusBar()->addWidget(_actionStatus); + _actionProgress = new QProgressBar(statusBar()); + statusBar()->addWidget(_actionProgress); + _debugStatus = new QLabel(statusBar()); + statusBar()->addWidget(_debugStatus, 0, true); + _editorStatus = new QLabel(statusBar()); + statusBar()->addWidget(_editorStatus, 0, true); + _programmerStatus = new ProgrammerStatusWidget(statusBar()); + connect(_programmerStatus, SIGNAL(configure()), SLOT(configureProgrammer())); + connect(_programmerStatus, SIGNAL(selected(const Programmer::Group &)), SLOT(selectProgrammer(const Programmer::Group &))); + statusBar()->addWidget(_programmerStatus->widget(), 0, true); + _toolStatus = new ToolStatusWidget(statusBar()); + connect(_toolStatus, SIGNAL(configureToolchain()), SLOT(configureToolchains())); + connect(_toolStatus, SIGNAL(configure()), SLOT(configureProject())); + connect(_toolStatus, SIGNAL(selected(const Tool::Group &)), SLOT(selectTool(const Tool::Group &))); + statusBar()->addWidget(_toolStatus->widget(), 0, true); + +// interface + _mainDock = createDockWidget("main_dock_widget", QPixmap()); + _mainDock->setDockSite(KDockWidget::DockCorner); + _mainDock->setEnableDocking(KDockWidget::DockNone); + setView(_mainDock); + setMainDockWidget(_mainDock); + + KIconLoader loader; + KDockWidget *dock = createDock("project_manager_dock_widget", PURL::icon(PURL::Project), + i18n("Project Manager"), DockPosition(KDockWidget::DockLeft, 20)); + Main::_projectManager = new ProjectManager::View(dock); + connect(Main::_projectManager, SIGNAL(guiChanged()), SLOT(updateGUI())); + dock->setWidget(Main::_projectManager); + + dock = createDock("watch_view_dock_widget", loader.loadIcon("viewmag", KIcon::Small), + i18n("Watch View"), DockPosition("project_manager_dock_widget")); + Main::_watchView = new Register::WatchView(dock); + dock->setWidget(Main::_watchView); + + Main::_editorManager = new EditorManager(_mainDock); + _mainDock->setWidget(Main::_editorManager); + connect(Main::_editorManager, SIGNAL(guiChanged()), SLOT(updateGUI())); + connect(Main::_editorManager, SIGNAL(modified(const PURL::Url &)), Main::_projectManager, SLOT(modified(const PURL::Url &))); + connect(Main::_editorManager, SIGNAL(statusChanged(const QString &)), _editorStatus, SLOT(setText(const QString &))); + + dock = createDock("compile_log_dock_widget", loader.loadIcon("piklab_compile", KIcon::Small), + i18n("Compile Log"), DockPosition(KDockWidget::DockBottom, 80)); + Main::_compileLog = new Compile::LogWidget(dock); + Main::_compileLog->setFocusPolicy(NoFocus); + dock->setWidget(Main::_compileLog); + + dock = createDock("program_log_dock_widget", loader.loadIcon("piklab_burnchip", KIcon::Small), + i18n("Program Log"), DockPosition("compile_log_dock_widget")); + _programLog = new Log::Widget(dock, "program_log"); + _programLog->setFocusPolicy(NoFocus); + dock->setWidget(_programLog); + + dock = createDock("breakpoints_dock_widget", loader.loadIcon("piklab_breakpoint_active", KIcon::Small), + i18n("Breakpoints"), DockPosition("compile_log_dock_widget")); + Main::_breakpointsView = new Breakpoint::View(dock); + Main::_breakpointsView->setFocusPolicy(NoFocus); + dock->setWidget(Main::_breakpointsView); + + dock = createDock("console_dock_widget", loader.loadIcon("konsole", KIcon::Small), + i18n("Konsole"), DockPosition("compile_log_dock_widget")); + Main::_consoleView = new ConsoleView(dock); + dock->setWidget(Main::_consoleView); + +// managers + Programmer::manager = new Programmer::GuiManager(this); + Programmer::manager->setView(_programLog); + connect(Programmer::manager, SIGNAL(actionMessage(const QString &)), _actionStatus, SLOT(setText(const QString &))); + connect(Programmer::manager, SIGNAL(showProgress(bool)), SLOT(showProgress(bool))); + connect(Programmer::manager, SIGNAL(setTotalProgress(uint)), SLOT(setTotalProgress(uint))); + connect(Programmer::manager, SIGNAL(setProgress(uint)), SLOT(setProgress(uint))); + + Debugger::manager = new Debugger::GuiManager; + connect(Debugger::manager, SIGNAL(targetStateChanged()), SLOT(updateGUI())); + connect(Debugger::manager, SIGNAL(statusChanged(const QString &)), _debugStatus, SLOT(setText(const QString &))); + connect(Debugger::manager, SIGNAL(actionMessage(const QString &)), _actionStatus, SLOT(setText(const QString &))); + + Main::_compileManager = new Compile::Manager(this); + Main::_compileManager->setView(Main::_compileLog); + connect(Main::_compileManager, SIGNAL(success()), SLOT(compileSuccess())); + connect(Main::_compileManager, SIGNAL(failure()), SLOT(compileFailure())); + connect(Main::_compileManager, SIGNAL(updateFile(const Compile::FileData &)), + SLOT(updateFile(const Compile::FileData &))); + +// actions + // file actions + KAction *a = KStdAction::openNew(this, SLOT(newSourceFile()), actionCollection()); + a->setText(i18n("&New Source File...")); + (void)new KAction(i18n("New hex File..."), "filenew", 0, this, SLOT(newHexFile()), + actionCollection(), "file_new_hex"); + KStdAction::open(this, SLOT(openFile()), actionCollection()); + KRecentFilesAction *recent = KStdAction::openRecent(this, SLOT(openRecentFile(const KURL &)), actionCollection()); + recent->setMaxItems(20); + recent->loadEntries(kapp->config(), "recent-files"); + (void)new KAction(i18n("Save All"), 0, 0, Main::_editorManager, SLOT(saveAllFiles()), + actionCollection(), "file_save_all"); + KStdAction::close(Main::_editorManager, SLOT(closeCurrentEditor()), actionCollection()); + (void)new KAction(i18n("C&lose All"), 0, 0, Main::_editorManager, SLOT(closeAllEditors()), + actionCollection(), "file_close_all"); + (void)new KAction(i18n("Close All Others"), 0, 0, Main::_editorManager, SLOT(closeAllOtherEditors()), + actionCollection(), "file_closeother"); + KStdAction::quit(this, SLOT(close()), actionCollection()); + + // edit actions + + // view actions + (void)new KAction(i18n("Back"), "back", Qt::ALT + Qt::Key_Left, + Main::_editorManager, SLOT(goBack()), actionCollection(), "history_back"); + (void)new KAction(i18n("Forward"), "forward", Qt::ALT + Qt::Key_Right, + Main::_editorManager, SLOT(goForward()), actionCollection(), "history_forward"); + (void)new KAction(i18n("Switch to..."), 0, Qt::CTRL + Qt::Key_Slash, + Main::_editorManager, SLOT(switchToEditor()), actionCollection(), "file_switchto"); + (void)new KAction(i18n("Switch Header/Implementation"), 0, Qt::SHIFT + Qt::Key_F12, + Main::_editorManager, SLOT(switchHeaderImplementation()), actionCollection(), "view_switch_source"); + (void)new KAction(QString::null, 0, 0, + Debugger::manager, SLOT(toggleBreakpoint()), actionCollection(), "toggle_breakpoint"); + (void)new KAction(QString::null, 0, 0, + Debugger::manager, SLOT(toggleEnableBreakpoint()), actionCollection(), "enable_breakpoint"); + (void)new KAction(i18n("Show disassembly location"), 0, 0, + Debugger::manager, SLOT(showDisassemblyLocation()), actionCollection(), "show_disassembly_location"); + KActionMenu *toolViewsMenu = new KActionMenu( i18n("Tool Views"), 0, "view_tool_views"); + connect(toolViewsMenu->popupMenu(), SIGNAL(aboutToShow()), SLOT(updateToolViewsActions())); + actionCollection()->insert(toolViewsMenu); + a = new KAction(i18n("&Reset Layout"), 0, 0, this, SLOT(resetDockLayout()), actionCollection(), "view_reset_layout"); + toolViewsMenu->insert(a); + toolViewsMenu->popupMenu()->insertSeparator(); + QValueList::iterator it; + for(it=_docks.begin(); it!=_docks.end(); ++it) toolViewsMenu->insert((*it).action); + + // project actions + (void)new KAction(i18n("New Project..."), "piklab_createproject", 0, + this, SLOT(newProject()), actionCollection(), "project_new"); + (void)new KAction(i18n("Open Project..."), "piklab_openproject", 0, + this , SLOT(openProject()), actionCollection(), "project_open"); + recent = new KRecentFilesAction(i18n("Open Recent Project"), 0, + this, SLOT(openRecentProject(const KURL &)), actionCollection(), "project_open_recent"); + recent->setMaxItems(20); + recent->loadEntries(kapp->config(), "recent-projects"); + (void)new KAction(i18n("Project Options..."), "configure", 0, + this, SLOT(configureProject()), actionCollection(), "project_options"); + (void)new KAction(i18n("Close Project"), "fileclose", 0, + this, SLOT(closeProject()), actionCollection(), "project_close"); + (void)new KAction(i18n("Add Source File..."), "piklab_addfile", 0, + Main::_projectManager, SLOT(insertSourceFiles()), actionCollection(), "project_add_source_file"); + (void)new KAction(i18n("Add Object File..."), "piklab_addfile", 0, + Main::_projectManager, SLOT(insertObjectFiles()), actionCollection(), "project_add_object_file"); + (void)new KAction(i18n("Add Current File"), "piklab_addcurrentfile", 0, + Main::_projectManager, SLOT(insertCurrentFile()), actionCollection(), "project_add_current_file"); + + // build actions + (void)new KAction(i18n("&Build Project"), "piklab_compile", Qt::Key_F8, + this, SLOT(buildProject()), actionCollection(), "build_build_project"); + (void)new KAction(i18n("&Compile File"), 0, Qt::SHIFT + Qt::Key_F8, + this, SLOT(compileFile()), actionCollection(), "build_compile_file"); + (void)new KAction(i18n("Clean"), "trashcan_empty", 0, + this, SLOT(cleanBuild()), actionCollection(), "build_clean"); + (void)new KAction(i18n("Stop"), "stop", 0, + this, SLOT(stopBuild()), actionCollection(), "build_stop"); + + // programmer actions + (void)new KAction(i18n("&Connect"), "connect_creating", 0, + Programmer::manager, SLOT(connectDevice()), actionCollection(), "prog_connect"); + (void)new KToggleAction(i18n("Device Power"), "piklab_power", 0, + Programmer::manager, SLOT(toggleDevicePower()), actionCollection(), "prog_power"); + (void)new KAction(i18n("&Disconnect"), "connect_no", 0, + Programmer::manager, SLOT(disconnectDevice()), actionCollection(), "prog_disconnect"); + (void)new KAction(i18n("&Program"), "piklab_burnchip", Qt::SHIFT + Qt::Key_F5, + this , SLOT(program()), actionCollection(), "prog_program"); + (void)new KAction(i18n("&Verify"), "piklab_verifychip", Qt::SHIFT + Qt::Key_F6, + this , SLOT(verify()), actionCollection(), "prog_verify"); + (void)new KAction(i18n("&Read"), "piklab_readchip", Qt::SHIFT + Qt::Key_F7, + this , SLOT(read()), actionCollection(), "prog_read"); + (void)new KAction(i18n("&Erase"), "piklab_erasechip", 0, + this, SLOT(erase()), actionCollection(), "prog_erase"); + (void)new KAction(i18n("&Blank Check"), "piklab_blankcheck", 0, + this, SLOT(blankCheck()), actionCollection(), "prog_blank_check"); + (void)new KAction(i18n("&Run"), "launch", Qt::SHIFT + Qt::Key_F9, + Programmer::manager, SLOT(run()), actionCollection(), "prog_run"); + (void)new KAction(i18n("&Stop"), "piklab_stop", 0, + Programmer::manager, SLOT(halt()), actionCollection(), "prog_stop"); + (void)new KAction(i18n("R&estart"), "piklab_restart", 0, + Programmer::manager, SLOT(restart()), actionCollection(), "prog_restart"); + (void)new KAction(i18n("&Advanced..."), 0, 0, + Programmer::manager , SLOT(showAdvancedDialog()), actionCollection(), "prog_advanced"); + (void)new KAction(i18n("Settings..."), "configure", 0, + this , SLOT(showProgrammerSettings()), actionCollection(), "prog_settings"); + + // debugger actions + (void)new KAction(i18n("&Start"), "launch", Qt::SHIFT + Qt::Key_F9, + Programmer::manager, SLOT(restart()), actionCollection(), "debug_start"); + (void)new KAction(i18n("&Run"), "piklab_run", Qt::SHIFT + Qt::Key_F9, + Programmer::manager, SLOT(run()), actionCollection(), "debug_run"); + (void)new KAction(i18n("&Step"), "piklab_debug_step", 0, + Programmer::manager, SLOT(step()), actionCollection(), "debug_next"); + //(void)new KAction(i18n("Step &In"), "piklab_debug_stepin", + // 0, this, SLOT(debugStepIn()), actionCollection(), "debug_step_in"); + //(void)new KAction(i18n("Step &Out"), "piklab_debug_stepout", + // 0, this, SLOT(debugStepOut()), actionCollection(), "debug_step_out"); + (void)new KAction(i18n("&Break", "&Halt"), "piklab_debughalt", 0, + Programmer::manager, SLOT(halt()), actionCollection(), "debug_halt"); + (void)new KAction(i18n("&Disconnect/Stop"), "piklab_stop", 0, + Programmer::manager, SLOT(disconnectDevice()), actionCollection(), "debug_stop"); + (void)new KAction(i18n("R&eset"), "piklab_restart", 0, + Programmer::manager, SLOT(restart()), actionCollection(), "debug_reset"); + (void)new KAction(i18n("Show Program Counter"), "piklab_program_counter", 0, + Debugger::manager, SLOT(showPC()), actionCollection(), "debug_show_pc"); + (void)new KAction(i18n("Clear All Breakpoints"), "remove", 0, + Debugger::manager, SLOT(clearBreakpoints()), actionCollection(), "debug_clear_breakpoints"); + (void)new KAction(i18n("Settings..."), "configure", 0, + this , SLOT(showDebuggerSettings()), actionCollection(), "debug_settings"); + + // tools + (void)new KAction(i18n("&Pikloops..."), 0, 0, + this , SLOT(runPikloops()), actionCollection(), "tools_pikloops"); + (void)new KAction(i18n("&Find Files..."), "find", 0, + this , SLOT(runKfind()), actionCollection(), "tools_kfind"); + (void)new KAction(i18n("&Device Information..."), "info", 0, + this , SLOT(showDeviceInfo()), actionCollection(), "tools_device_information"); + (void)new KAction(i18n("&Config Generator..."), 0, 0, + this , SLOT(configGenerator()), actionCollection(), "tools_config_generator"); + (void)new KAction(i18n("&Template Generator..."), 0, 0, + this , SLOT(templateGenerator()), actionCollection(), "tools_template_generator"); + + // settings actions + (void)new KAction(i18n("Configure Toolchains..."), 0, 0, + this, SLOT(configureToolchains()), actionCollection(), "options_configure_toolchains"); + (void)KStdAction::preferences(this, SLOT(configure()), actionCollection()); + + // help + (void)new KAction(i18n("Report Bug..."), "likeback_bug", 0, + LikeBack::instance(), SLOT(iFoundABug()), actionCollection(), "help_report_bug_piklab"); + + setupGUI(); + readDockConfig(); + + // LikeBack buttons + menuBar()->insertItem(new QLabel(menuBar())); // #### first widget is put left-most... + MenuBarButton *button = new MenuBarButton("likeback_like", menuBar()); + QToolTip::add(button, i18n("I like...")); + connect(button, SIGNAL(clicked()), LikeBack::instance(), SLOT(iLike())); + menuBar()->insertItem(button); + button = new MenuBarButton("likeback_dislike", menuBar()); + QToolTip::add(button, i18n("I do not like...")); + connect(button, SIGNAL(clicked()), LikeBack::instance(), SLOT(iDoNotLike())); + menuBar()->insertItem(button); + button = new MenuBarButton("likeback_bug", menuBar()); + QToolTip::add(button, i18n("I found a bug...")); + connect(button, SIGNAL(clicked()), LikeBack::instance(), SLOT(iFoundABug())); + menuBar()->insertItem(button); + button = new MenuBarButton("configure", menuBar()); + QToolTip::add(button, i18n("Configure email...")); + connect(button, SIGNAL(clicked()), LikeBack::instance(), SLOT(askEMail())); + menuBar()->insertItem(button); + button = new MenuBarButton("help", menuBar()); + connect(button, SIGNAL(clicked()), LikeBack::instance(), SLOT(showWhatsThisMessage())); + menuBar()->insertItem(button); + + QTimer::singleShot(0, this, SLOT(initialLoading())); +} + +MainWindow::~MainWindow() +{} + +void MainWindow::readDockConfig() +{ + KDockMainWindow::readDockConfig(kapp->config(), "dock_config"); + + // if there is a new dock: it is not displayed by default... + QMap entries = kapp->config()->entryMap("dock_config"); + QValueList::iterator it; + for(it=_docks.begin(); it!=_docks.end(); ++it) { + QMap::const_iterator eit; + for(eit=entries.begin(); eit!=entries.end(); ++eit) + if ( eit.key().startsWith((*it).dock->name()) ) break; + if ( eit==entries.end() ) initDockPosition(*it); + } + + // readDockConfig also restore the names/tooltips: what if a new version of the application changes these names... + for(it=_docks.begin(); it!=_docks.end(); ++it) (*it).dock->setTabPageLabel((*it).title); + QApplication::postEvent(this, new QEvent(QEvent::CaptionChange)); +} + +void MainWindow::initialLoading() +{ + ::BusyCursor bc; + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + if ( args->count()!=0 ) { // opened urls provided on the command line + for (int i = 0; icount(); i++) { + PURL::Url url(args->url(i)); + if ( url.fileType()==PURL::Project ) { + if ( Main::_projectManager->project()==0 ) Main::_projectManager->openProject(url); + } else Main::_editorManager->openEditor(url); + } + } else { // otherwise reopen last project/files + Main::_projectManager->openProject(GlobalConfig::openedProject()); + PURL::UrlList files = GlobalConfig::openedFiles(); + PURL::UrlList::const_iterator it = files.begin(); + for (; it!=files.end(); ++it) Main::_editorManager->openEditor(*it); + } + updateGUI(); +} + +void MainWindow::openRecentFile(const KURL &kurl) +{ + Main::_editorManager->openFile(PURL::Url(kurl)); +} + +void MainWindow::configureToolbar() +{ + saveMainWindowSettings(KGlobal::config(), "MainWindow"); + KEditToolbar dlg(actionCollection()); + connect(&dlg, SIGNAL(newToolbarConfig()), SLOT(applyToolbarSettings())); + dlg.exec(); +} + +void MainWindow::applyToolbarSettings() +{ + createGUI(); + applyMainWindowSettings(KGlobal::config(), "MainWindow"); +} + +void MainWindow::configure(ConfigCenter::Type showType) +{ + stopOperations(); + ConfigCenter dialog(showType, this); + dialog.exec(); + Programmer::manager->clear(); + updateGUI(); + Debugger::manager->update(true); +} + +void MainWindow::configureToolchains() +{ + stopOperations(); + ToolchainsConfigCenter dialog(Main::toolGroup(), this); + dialog.exec(); + Programmer::manager->clear(); + updateGUI(); + Debugger::manager->update(true); +} + +void MainWindow::selectProgrammer(const Programmer::Group &group) +{ + if ( group.name()==Main::programmerGroup().name() ) return; + bool debugInitialized = Debugger::manager->coff(); + stopOperations(); + GlobalConfig::writeProgrammerGroup(group); + Programmer::manager->clear(); + updateGUI(); + if (debugInitialized) Debugger::manager->init(); + else Debugger::manager->update(true); +} + +void MainWindow::selectTool(const Tool::Group &group) +{ + if ( group.name()==Compile::Config::toolGroup(Main::project()).name() ) return; + bool debugInitialized = Debugger::manager->coff(); + stopOperations(); + Compile::Config::setToolGroup(Main::project(), group); + updateGUI(); + if (debugInitialized) Debugger::manager->init(); + else Debugger::manager->update(true); +} + +void MainWindow::setDevice(const QString &device) +{ + if ( device==i18n(Device::AUTO_DATA.label) ) Compile::Config::setDevice(Main::project(), Device::AUTO_DATA.name); + else Compile::Config::setDevice(Main::project(), device); + updateGUI(); +} + +void MainWindow::showDeviceInfo() +{ + DeviceChooser::Dialog d(Main::device(), (Main::project() ? DeviceChooser::Choose : DeviceChooser::ChooseWithAuto), this); + if ( d.exec() ) { + setDevice(d.device()); + updateGUI(); + } +} + +void MainWindow::configGenerator() +{ + PURL::FileType ftype = (Main::currentEditor() ? Main::currentEditor()->fileType() : PURL::Nb_FileTypes); + PURL::SourceFamily family = (ftype!=PURL::Nb_FileTypes ? ftype.data().sourceFamily : PURL::SourceFamily(PURL::SourceFamily::Nb_Types)); + PURL::ToolType type = (family!=PURL::SourceFamily::Nb_Types ? family.data().toolType : PURL::ToolType(PURL::ToolType::Assembler)); + ConfigGenerator dialog(this); + dialog.set(Main::deviceData(), Main::toolGroup(), type); + dialog.exec(); +} + +void MainWindow::templateGenerator() +{ + PURL::FileType ftype = (Main::currentEditor() ? Main::currentEditor()->fileType() : PURL::Nb_FileTypes); + PURL::SourceFamily family = (ftype!=PURL::Nb_FileTypes ? ftype.data().sourceFamily : PURL::SourceFamily(PURL::SourceFamily::Nb_Types)); + PURL::ToolType type = (family!=PURL::SourceFamily::Nb_Types ? family.data().toolType : PURL::ToolType(PURL::ToolType::Assembler)); + TemplateGenerator dialog(this); + dialog.set(Main::deviceData(), Main::toolGroup(), type); + dialog.exec(); +} + +bool MainWindow::queryClose() +{ + if ( !stopOperations() ) return false; + Main::setState(Main::Closing); + // save list of opened editors + PURL::UrlList toSave; + const PURL::UrlList files = Main::_editorManager->files(); + PURL::UrlList::const_iterator it; + for (it=files.begin(); it!=files.end(); ++it) + if ( !Main::_projectManager->isExternalFile(*it) ) toSave.append(*it); + GlobalConfig::writeOpenedFiles(toSave); + // close editors + if ( !Main::_editorManager->closeAllEditors() ) { + Main::setState(Main::Idle); + return false; + } + // save other settings + ::BusyCursor bc; + writeDockConfig(kapp->config(), "dock_config"); + static_cast(Main::action("project_open_recent"))->saveEntries(kapp->config(), "recent-projects"); + static_cast(Main::action("file_open_recent"))->saveEntries(kapp->config(), "recent-files"); + GlobalConfig::writeOpenedProject(Main::project() ? Main::project()->url() : PURL::Url()); + if ( Main::project() ) Main::_projectManager->closeProject(); + return true; +} + +void MainWindow::newSourceFile() +{ + NewFileDialog dialog(Main::project(), this); + if ( dialog.exec()!=QDialog::Accepted ) return; + if ( !dialog.url().exists() && !dialog.url().create(*Main::_compileLog) ) return; + Main::_editorManager->openEditor(dialog.url()); + if ( dialog.addToProject() ) Main::_projectManager->insertFile(dialog.url()); +} + +void MainWindow::newHexFile() +{ + if ( Main::device()==Device::AUTO_DATA.name ) { + MessageBox::sorry(i18n("You need to specify a device to create a new hex file."), Log::Show); + return; + } + QString s; + for (uint i=0; true; i++) { + s = i18n("Hex") + (i==0 ? QString::null : QString::number(i)); + if ( Main::_editorManager->findEditor(s)==0 ) break; + } + HexEditor *editor = new HexEditor(s, Main::_editorManager); + editor->memoryRead(); + Main::_editorManager->addEditor(editor); +} + +bool MainWindow::openFile() +{ + QString filter; + filter += PURL::sourceFilter(PURL::SimpleFilter); + filter += "\n" + PURL::filter(PURL::Hex); + filter += "\n" + PURL::projectFilter(PURL::SimpleFilter); + filter += "\n*|" + i18n("All Files"); + PURL::Url url = PURL::getOpenUrl(":open_file", filter, this ,i18n("Open File")); + if ( url.fileType()==PURL::Project || url.fileType()==PURL::PikdevProject ) { + stopOperations(); + if ( !Main::_projectManager->openProject(url) ) return false; + updateGUI(); + return true; + } + return Main::_editorManager->openFile(url); +} + +void MainWindow::updateGUI() +{ + bool idle = ( Main::_state==Main::Idle ); + switch (Main::_state) { + case Main::Closing: return; + case Main::Idle: + showProgress(false); + break; + case Main::Compiling: + _actionStatus->setText(Main::_compileManager->label()); + showProgress(true); + makeWidgetDockVisible(Main::_compileLog); + break; + case Main::Programming: + makeWidgetDockVisible(_programLog); + break; + } + + // update editor actions + Main::_editorManager->updateTitles(); + Main::action("file_save_all")->setEnabled(Main::currentEditor()); + Main::action("file_close")->setEnabled(Main::currentEditor()); + Main::action("file_close_all")->setEnabled(Main::currentEditor()); + Main::action("file_closeother")->setEnabled(Main::_editorManager->nbEditors()>1); + Main::action("options_configure")->setEnabled(idle); + PURL::FileType currentType = (Main::currentEditor() ? Main::currentEditor()->fileType() : PURL::Nb_FileTypes); + bool isSource = (currentType==PURL::Nb_FileTypes ? false : currentType.data().group==PURL::Source); + bool isHeader = (currentType==PURL::Nb_FileTypes ? false : currentType.data().group==PURL::Header); + Main::action("view_switch_source")->setEnabled(isSource || isHeader); + Main::action("history_back")->setEnabled(Main::editorManager().history().hasBack()); + Main::action("history_forward")->setEnabled(Main::editorManager().history().hasForward()); + Main::action("show_disassembly_location")->setEnabled(Debugger::manager->coff()!=0 && (isSource || isHeader)); + + // update project + bool inProject = ( Main::currentEditor() && (currentType==PURL::Nb_FileTypes || Main::currentEditor()->url().isEmpty() || Main::_projectManager->contains(Main::currentEditor()->url())) ); + if ( Main::project()==0 && !inProject ) { + if ( Main::currentEditor()==0 ) Main::_projectManager->closeProject(); + else if ( isSource ) Main::_projectManager->setStandalone(Main::currentEditor()->url(), currentType); + else { + PURL::FileType type; + PURL::Url purl = Main::_projectManager->standaloneGenerator(Main::currentEditor()->url(), type); + if ( type!=PURL::Nb_FileTypes ) Main::_projectManager->setStandalone(purl, type); + else if ( currentType==PURL::Hex ) Main::_projectManager->setStandalone(purl, PURL::Hex); + } + } + if ( Main::currentEditor() ) Main::_projectManager->select(Main::currentEditor()); + + // update project actions + Main::action("project_new")->setEnabled(idle); + Main::action("project_open")->setEnabled(idle); + Main::action("project_close")->setEnabled(Main::project() && idle); + Main::action("project_options")->setEnabled(Main::project() && idle); + Main::action("project_add_source_file")->setEnabled(Main::project() && idle); + Main::action("project_add_object_file")->setEnabled(Main::project() && idle); + Main::action("project_add_current_file")->setEnabled(Main::project() && !inProject && idle && isSource); + + // update build actions + static_cast(_toolStatus->widget())->setText(" " + Main::toolGroup().label() + " "); + bool hexProject = ( Main::_projectManager->projectUrl().fileType()==PURL::Hex ); + bool customTool = Main::toolGroup().isCustom(); + Main::action("build_build_project")->setEnabled((Main::project() || (inProject && !hexProject) ) && idle); + PURL::Url selected = Main::_projectManager->selectedUrl(); + bool isSelectedSource = ( !selected.isEmpty() && selected.data().group==PURL::Source ); + Main::action("build_compile_file")->setEnabled(!hexProject && (isSource || isSelectedSource) && idle && !customTool); + Main::action("build_clean")->setEnabled((Main::project() || inProject) && idle && !customTool); + Main::action("build_stop")->setEnabled(Main::_state==Main::Compiling); + + // update programmer status + PortType ptype = Programmer::GroupConfig::portType(Main::programmerGroup()); + static_cast(_programmerStatus->widget())->setText(" " + Main::programmerGroup().statusLabel(ptype) + " "); + QFont f = font(); + bool supported = (Main::deviceData() ? Main::programmerGroup().isSupported(Main::deviceData()->name()) : false); + f.setItalic(!supported); + _programmerStatus->widget()->setFont(f); + bool isProgrammer = ( Main::programmerGroup().properties() & ::Programmer::Programmer ); + PURL::Url purl = Main::_projectManager->projectUrl(); + bool hasHex = ( currentType==PURL::Hex || Main::_projectManager->contains(purl.toFileType(PURL::Hex)) ); + Main::action("prog_connect")->setEnabled(isProgrammer && idle); + Main::action("prog_read")->setEnabled(isProgrammer && idle); + Main::action("prog_program")->setEnabled(isProgrammer && hasHex && idle); + Main::action("prog_verify")->setEnabled(isProgrammer && hasHex && idle); + Main::action("prog_erase")->setEnabled(isProgrammer && idle); + Main::action("prog_blank_check")->setEnabled(isProgrammer && idle); + Programmer::State pstate = (Main::programmer() ? Main::programmer()->state() : Programmer::NotConnected); + static_cast(Main::action("prog_power"))->setEnabled(isProgrammer && idle && pstate!=Programmer::NotConnected); + Main::action("prog_disconnect")->setEnabled(isProgrammer && idle && pstate!=Programmer::NotConnected); + bool isDebugger = ( Main::programmerGroup().properties() & ::Programmer::Debugger ); + bool resetAvailable = ( Main::programmerGroup().properties() & Programmer::CanReleaseReset ); + Main::action("prog_run")->setEnabled(idle && resetAvailable && !isDebugger && pstate!=Programmer::Running); + Main::action("prog_stop")->setEnabled(idle && !isDebugger && pstate==Programmer::Running); + Main::action("prog_restart")->setEnabled(idle && !isDebugger && pstate==Programmer::Running); + const Programmer::GroupUI *pgui = static_cast(Main::programmerGroup().gui()); + Main::action("prog_advanced")->setEnabled(idle && pgui->hasAdvancedDialog()); + + // update debugger status + Debugger::manager->updateDevice(); + Main::action("debug_start")->setEnabled(idle && isDebugger && pstate!=Programmer::Running && pstate!=Programmer::Halted); + Main::action("debug_run")->setEnabled(idle && isDebugger && pstate!=Programmer::Running && !Debugger::manager->isStepping() ); + Main::action("debug_halt")->setEnabled(idle && isDebugger && (pstate==Programmer::Running || Debugger::manager->isStepping()) ); + Main::action("debug_stop")->setEnabled(idle && isDebugger && (pstate==Programmer::Running || pstate==Programmer::Halted)); + Main::action("debug_next")->setEnabled(idle && isDebugger && pstate!=Programmer::Running); + Main::action("debug_reset")->setEnabled(idle && isDebugger && (pstate==Programmer::Running || pstate==Programmer::Halted)); + Main::action("debug_show_pc")->setEnabled(idle && isDebugger && Debugger::manager->coff()!=0 && Debugger::manager->pc().isInitialized() ); + + Main::_projectManager->updateGUI(); + + // caption + QString caption; + if ( Main::project() ) caption += Main::project()->name(); + if ( Main::currentEditor() ) { + if ( Main::project() ) caption += " - "; + caption += Main::currentEditor()->url().filepath(); + } + setCaption(KApplication::kApplication()->makeStdCaption(caption)); + + emit stateChanged(); +} + +void MainWindow::updateToolViewsActions() +{ + QValueList::iterator it; + for(it=_docks.begin(); it!=_docks.end(); ++it) (*it).action->setChecked((*it).dock->mayBeHide()); +} + +void MainWindow::initDockPosition(const DockData &ddata) +{ + const DockPosition &pos = ddata.position; + ddata.dock->manualDock(manager()->getDockWidgetFromName(pos.parent), pos.pos, pos.space); +} + +void MainWindow::resetDockLayout() +{ + QValueList::iterator it; + for (it=_docks.begin(); it!=_docks.end(); ++it) initDockPosition(*it); +} + +void MainWindow::toggleToolView(QWidget *widget) +{ + static_cast(widget)->changeHideShowState(); +} + +void MainWindow::runKfind() +{ + if (_kfindProcess) return; + _kfindProcess = new ::Process::StringOutput; + QString path; + PURL::Url url = Main::projectManager().projectUrl(); + if ( !url.isEmpty() ) path = url.path(); + _kfindProcess->setup("kfind", path, false); + connect(_kfindProcess, SIGNAL(done(int)), SLOT(kfindDone())); + if ( !_kfindProcess->start(0) ) + MessageBox::sorry(i18n("Could not run \"kfind\""), Log::Show); +} + +void MainWindow::kfindDone() +{ + delete _kfindProcess; + _kfindProcess = 0; +} + +void MainWindow::runPikloops() +{ + if (_pikloopsProcess) return; + _pikloopsProcess = new ::Process::StringOutput; + _pikloopsProcess->setup("pikloops", QStringList(), false); + connect(_pikloopsProcess, SIGNAL(done(int)), SLOT(pikloopsDone())); + if ( !_pikloopsProcess->start(0) ) + MessageBox::detailedSorry(i18n("Could not run \"pikloops\""), i18n("The Pikloops utility (%1) is not installed in your system.").arg("http://pikloops.sourceforge.net"), Log::Show); +} + +void MainWindow::pikloopsDone() +{ + delete _pikloopsProcess; + _pikloopsProcess = 0; +} + +//----------------------------------------------------------------------------- +void MainWindow::compileFile() +{ + Editor *e = Main::currentEditor(); + if ( e && e->isModified() ) e->save(); // buffer is systematically saved + stopOperations(); + Main::_compileLog->clear(); + PURL::Url url = (e ? e->url() : Main::_projectManager->selectedUrl()); + bool generated = (e ? Main::_projectManager->isExternalFile(url) : false); + if ( Main::project()==0 || !generated ) Main::_projectManager->removeExternalFiles(); + url = (!generated ? url : Main::_projectManager->projectUrl()); + if ( Main::_compileManager->compileFile(Compile::TodoItem(url, generated)) ) Main::setState(Main::Compiling); + else compileFailure(); +} + +void MainWindow::buildProject() +{ + if ( Main::project()==0 ) { + compileFile(); + return; + } + // save modified buffers + PURL::UrlList files = Main::project()->absoluteFiles(); + PURL::UrlList::const_iterator it; + for (it=files.begin(); it!=files.end(); ++it) { + // save modified editors + Editor *e = Main::_editorManager->findEditor(*it); + if ( e && e->isModified() ) e->save(); + } + bool tmp = _forceProgramAfterBuild; + stopOperations(); + _forceProgramAfterBuild = tmp; + Main::_compileLog->clear(); + Main::_projectManager->removeExternalFiles(); + Compile::LinkType ltype = (Main::programmerGroup().name()=="icd2_debugger" ? Compile::Icd2Linking : Compile::NormalLinking); + if ( Main::_compileManager->buildProject(ltype) ) Main::setState(Main::Compiling); + else compileFailure(); +} + +void MainWindow::compileFailure() +{ + _forceProgramAfterBuild = false; + Main::setState(Main::Idle); +} + +void MainWindow::compileSuccess() +{ + if ( !Main::_compileManager->compileOnly() ) { + Main::_projectManager->setModified(false); + if ( Main::project()->outputType()==Tool::OutputType::Executable ) { + if ( Debugger::manager->init() ) { + const QStringList &included = Debugger::manager->coff()->filenames(); + QStringList::const_iterator it; + for (it=included.begin(); it!=included.end(); ++it) { + PURL::Directory dir = (Main::project() ? Main::project()->directory() : Main::projectManager().projectUrl().directory()); + PURL::Url url = PURL::Url::fromPathOrUrl(*it).toAbsolute(dir); + if ( !url.exists() ) continue; + Main::_projectManager->addExternalFile(url, ProjectManager::Included); + } + } + if ( _forceProgramAfterBuild || readConfigEntry(BaseGlobalConfig::ProgramAfterBuild).toBool() ) program(); + } + } + _forceProgramAfterBuild = false; + Main::setState(Main::Idle); +} + +void MainWindow::updateFile(const Compile::FileData &fdata) +{ + if ( fdata.actions & Compile::InProject ) { + if ( fdata.actions & Compile::Generated ) Main::_projectManager->addExternalFile(fdata.url, ProjectManager::Generated); + else if ( fdata.actions & Compile::Included ) Main::_projectManager->addExternalFile(fdata.url, ProjectManager::Included); + else Q_ASSERT(false); + } + if ( fdata.actions & Compile::Show ) { + Editor *e = Main::_editorManager->openEditor(fdata.url); + if (e) e->setReadOnly(true); + } +} + +void MainWindow::cleanBuild() +{ + stopOperations(); + Main::_compileLog->clear(); + if ( Main::project() ) { + Compile::LinkType ltype = (Main::programmerGroup().name()=="icd2_debugger" ? Compile::Icd2Linking : Compile::NormalLinking); + Main::_compileManager->cleanProject(ltype); + } else { + PURL::FileType type; + PURL::Url url = Main::_projectManager->standaloneGenerator(Main::currentEditor()->url(), type); + Main::_compileManager->cleanFile(url); + } + Main::_projectManager->removeExternalFiles(); +} + +void MainWindow::stopBuild() +{ + Main::_compileManager->kill(); +} + +//----------------------------------------------------------------------------- +void MainWindow::keyPressEvent(QKeyEvent *e) +{ + if ( e->key()==Key_Escape ) stopOperations(); +} + +bool MainWindow::stopOperations() +{ + if ( Main::_state==Main::Programming ) { + _programLog->log(Log::LineType::Warning, i18n("Programming in progress. Cannot be aborted.")); + return false; + } + stopBuild(); + Programmer::manager->stop(); + Debugger::manager->clear(); + return true; +} + +void MainWindow::newProject() +{ + stopOperations(); + Main::_projectManager->newProject(); + updateGUI(); + Main::_compileLog->clear(); +} + +void MainWindow::openProject() +{ + stopOperations(); + Main::_projectManager->openProject(); + updateGUI(); + Main::_compileLog->clear(); +} + +void MainWindow::openRecentProject(const KURL &url) +{ + stopOperations(); + Main::_projectManager->openProject(PURL::Url(url)); + updateGUI(); + Main::_compileLog->clear(); +} + +void MainWindow::configureProject() +{ + stopOperations(); + if ( Main::project()==0 ) configure(ConfigCenter::Standalone); + else Main::_projectManager->editProject(); + updateGUI(); +} + +void MainWindow::closeProject() +{ + stopOperations(); + Main::_projectManager->closeProject(); + updateGUI(); + Main::_compileLog->clear(); +} + +//---------------------------------------------------------------------------- +HexEditor *MainWindow::getHexEditor() +{ + if ( Main::_projectManager->isModified() || Main::_projectManager->needsRecompile() ) { + MessageBox::Result res = MessageBox::Yes; + if ( !readConfigEntry(BaseGlobalConfig::AutoRebuildModified).toBool() ) { + res = MessageBox::questionYesNoCancel(i18n("The project hex file may not be up-to-date since some project files have been modified."), + i18n("Recompile First"), i18n("Continue Anyway")); + if ( res==MessageBox::Cancel ) return 0; + } + if ( res==MessageBox::Yes ) { + _forceProgramAfterBuild = true; + buildProject(); + return 0; + } + } + if ( Main::currentEditor() && Main::currentEditor()->fileType()==PURL::Hex ) + return static_cast(Main::currentEditor()); + PURL::Url purl = Main::_projectManager->projectUrl(); + HexEditor *editor = static_cast(Main::_editorManager->openEditor(purl.toFileType(PURL::Hex))); + if ( editor==0 ) return 0; + editor->setReadOnly(true); + return editor; +} + +void MainWindow::erase() +{ + Programmer::manager->erase(Device::MemoryRange()); +} + +void MainWindow::blankCheck() +{ + Programmer::manager->blankCheck(Device::MemoryRange()); +} + +void MainWindow::program() +{ + HexEditor *editor = getHexEditor(); + if ( editor==0 ) return; + if ( Main::programmerGroup().isDebugger() && !Main::_projectManager->contains(editor->url()) ) { + MessageBox::sorry(i18n("It is not possible to start a debugging session with an hex file not generated with the current project."), Log::Show); + return; + } + Programmer::manager->program(*editor->memory(), Device::MemoryRange()); +} + +void MainWindow::verify() +{ + HexEditor *editor = getHexEditor(); + if ( editor==0 ) return; + Programmer::manager->verify(*editor->memory(), Device::MemoryRange()); +} + +void MainWindow::read() +{ + QString s = i18n("Read"); + Editor *e = Main::_editorManager->findEditor(s); + if (e) Main::_editorManager->closeEditor(e, true); + HexEditor *editor = new HexEditor(s, Main::_editorManager); + editor->setDevice(); + if ( Programmer::manager->read(*editor->memory(), Device::MemoryRange()) ) { + editor->memoryRead(); + Main::_editorManager->addEditor(editor); + } else delete editor; +} + +void MainWindow::showProgress(bool show) +{ + if (show) { + BusyCursor::start(); + _actionStatus->show(); + _actionProgress->show(); + } else { + BusyCursor::stop(); + _actionStatus->hide(); + _actionProgress->hide(); + } +} + +void MainWindow::setTotalProgress(uint nb) +{ + //KIO::Job *job = new KIO::SimpleJob(KURL(), 0, 0, false); + //int id = Observer::self()->newJob(job, true); + //Observer::self()->slotTotalSize(job, total); + //Observer::self()->slotInfoMessage(job, "test"); + //qDebug("set total steps: %i", total); + _actionProgress->setTotalSteps(nb); + _actionProgress->setProgress(0); + QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput); // #### DANGER !!!! +} + +void MainWindow::setProgress(uint nb) +{ + _actionProgress->setProgress(nb); + QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput); // #### DANGER !!!! +} diff --git a/src/libgui/toplevel.h b/src/libgui/toplevel.h new file mode 100644 index 0000000..11a4316 --- /dev/null +++ b/src/libgui/toplevel.h @@ -0,0 +1,132 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#ifndef TOPLEVEL_H +#define TOPLEVEL_H + +#include +#include +#include + +#include "config_center.h" +#include "tools/list/compile_process.h" +#include "toplevel_ui.h" +namespace Programmer { class Group; } +namespace Tool { class Group; } +class ConfigGenerator; +class HexEditor; +namespace Process { class Base; } + +class MainWindow : public KDockMainWindow +{ +Q_OBJECT +public: + MainWindow(); + virtual ~MainWindow(); + void setDevice(const QString &device); + +public slots: + void newSourceFile(); + void newProject(); + void openProject(); + void buildProject(); + void cleanBuild(); + void configure(ConfigCenter::Type showType = ConfigCenter::General); + void configureProject(); + void showDeviceInfo(); + void runPikloops(); + void runKfind(); + void configGenerator(); + void templateGenerator(); + void updateGUI(); + +private slots: + void newHexFile(); + bool openFile(); + void openRecentFile(const KURL &url); + + void compileFile(); + void compileSuccess(); + void compileFailure(); + void updateFile(const Compile::FileData &data); + void stopBuild(); + + void erase(); + void blankCheck(); + void program(); + void verify(); + void read(); + void showProgress(bool show); + void setTotalProgress(uint nbSteps); + void setProgress(uint nbSteps); + + void applyToolbarSettings(); + void configureToolbar(); + void configureToolchains(); + void configureProgrammer() { configure(ConfigCenter::ProgSelect); } + void showProgrammerSettings() { configure(ConfigCenter::ProgOptions); } + void showDebuggerSettings() { configure(ConfigCenter::DebugOptions); } + void selectProgrammer(const Programmer::Group &group); + void selectTool(const Tool::Group &group); + + void updateToolViewsActions(); + void resetDockLayout(); + void toggleToolView(QWidget *widget); + + void pikloopsDone(); + void kfindDone(); + + void openRecentProject(const KURL &url); + void closeProject(); + + void initialLoading(); + +signals: + void stateChanged(); + +private: + Log::Widget *_programLog; + QLabel *_actionStatus, *_debugStatus, *_editorStatus; + ProgrammerStatusWidget *_programmerStatus; + ToolStatusWidget *_toolStatus; + QProgressBar *_actionProgress; + ConfigGenerator *_configGenerator; + ::Process::Base *_pikloopsProcess, *_kfindProcess; + bool _forceProgramAfterBuild; + + class DockPosition { + public: + DockPosition() {} + DockPosition(const QString &pparent) : parent(pparent), pos(KDockWidget::DockCenter), space(0) {} + DockPosition(KDockWidget::DockPosition ppos, uint pspace) : parent("main_dock_widget"), pos(ppos), space(pspace) {} + QString parent; + KDockWidget::DockPosition pos; + uint space; + }; + class DockData { + public: + ViewMenuAction *action; + KDockWidget *dock; + QString title; + DockPosition position; + }; + QValueList _docks; + KDockWidget *_mainDock; + + HexEditor *getHexEditor(); + virtual bool queryClose(); + bool stopOperations(); + void cleanBuild(bool singleFile); + virtual void keyPressEvent(QKeyEvent *e); + void readDockConfig(); + KDockWidget *createDock(const QString &name, const QPixmap &icon, const QString &title, const DockPosition &position); + void initDockPosition(const DockData &ddata); +}; + +#endif diff --git a/src/libgui/toplevel_ui.cpp b/src/libgui/toplevel_ui.cpp new file mode 100644 index 0000000..5e8db32 --- /dev/null +++ b/src/libgui/toplevel_ui.cpp @@ -0,0 +1,79 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "toplevel_ui.h" + +#include +#include + +#include "progs/list/prog_list.h" +#include "tools/list/tool_list.h" + +//---------------------------------------------------------------------------- +ProgrammerStatusWidget::ProgrammerStatusWidget(QWidget *parent) + : QObject(parent), KeyPopupButton(parent) +{ + connect(widget(), SIGNAL(activated(int)), SLOT(activatedSlot(int))); + widget()->appendAction(i18n("Configure..."), "configure", this, SIGNAL(configure())); + widget()->appendSeparator(); + Programmer::Lister::ConstIterator it; + for (it=Programmer::lister().begin(); it!=Programmer::lister().end(); ++it) + appendItem(it.key(), it.data()->label()); +} + +void ProgrammerStatusWidget::activatedSlot(int id) +{ + emit selected(*Programmer::lister().group(key(id))); +} + +//---------------------------------------------------------------------------- +ToolStatusWidget::ToolStatusWidget(QWidget *parent) + : QObject(parent), KeyPopupButton(parent) +{ + connect(widget(), SIGNAL(activated(int)), SLOT(activatedSlot(int))); + widget()->appendAction(i18n("Configure Toolchain..."), "configure", this, SIGNAL(configureToolchain())); + widget()->appendAction(i18n("Configure Compilation..."), "configure", this, SIGNAL(configure())); + widget()->appendSeparator(); + Tool::Lister::ConstIterator it; + for (it=Tool::lister().begin(); it!=Tool::lister().end(); ++it) + appendItem(it.key(), it.data()->label()); +} + +void ToolStatusWidget::activatedSlot(int id) +{ + emit selected(*Tool::lister().group(key(id))); +} + +//---------------------------------------------------------------------------- +ViewMenuAction::ViewMenuAction(KDockWidget *widget) + : KToggleAction(widget->tabPageLabel()), _widget(widget) +{} + +void ViewMenuAction::slotActivated() +{ + KAction::slotActivated(); + emit activated(_widget); +} + +//---------------------------------------------------------------------------- +MenuBarButton::MenuBarButton(const QString &icon, QWidget *parent) + : QToolButton(parent, "menu_bar_button") +{ + QFontMetrics fm(font()); + int h = fm.height() + 2*style().pixelMetric(QStyle::PM_DefaultFrameWidth, this); + setFixedHeight(h); + KIconLoader loader; + setIconSet(loader.loadIconSet(icon, KIcon::Small, fm.height()-2)); + setUsesTextLabel(false); + setAutoRaise(true); +} + +QSize MenuBarButton::sizeHint() const +{ + return QSize(QToolButton::sizeHint().width(), height()); +} diff --git a/src/libgui/toplevel_ui.h b/src/libgui/toplevel_ui.h new file mode 100644 index 0000000..8a5f631 --- /dev/null +++ b/src/libgui/toplevel_ui.h @@ -0,0 +1,77 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef TOPLEVEL_UI_H +#define TOPLEVEL_UI_H + +#include +#include +#include + +#include "common/gui/key_gui.h" +namespace Programmer { class Group; } +namespace Tool { class Group; } + +//---------------------------------------------------------------------------- +class ProgrammerStatusWidget : public QObject, public KeyPopupButton +{ +Q_OBJECT +public: + ProgrammerStatusWidget(QWidget *parent); + +signals: + void configure(); + void selected(const Programmer::Group &group); + +private slots: + void activatedSlot(int id); +}; + +//---------------------------------------------------------------------------- +class ToolStatusWidget : public QObject, public KeyPopupButton +{ +Q_OBJECT +public: + ToolStatusWidget(QWidget *parent); + +signals: + void configureToolchain(); + void configure(); + void selected(const Tool::Group &group); + +private slots: + void activatedSlot(int id); +}; + +//---------------------------------------------------------------------------- +class ViewMenuAction : public KToggleAction +{ +Q_OBJECT +public: + ViewMenuAction(KDockWidget *widget); + +signals: + void activated(QWidget *); + +private slots: + virtual void slotActivated(); + +private: + KDockWidget *_widget; +}; + +//---------------------------------------------------------------------------- +class MenuBarButton : public QToolButton +{ +Q_OBJECT +public: + MenuBarButton(const QString &icon, QWidget *parent); + virtual QSize sizeHint() const; +}; + +#endif diff --git a/src/libgui/watch_view.cpp b/src/libgui/watch_view.cpp new file mode 100644 index 0000000..984dc7c --- /dev/null +++ b/src/libgui/watch_view.cpp @@ -0,0 +1,225 @@ +/*************************************************************************** + * Copyright (C) 2006-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "watch_view.h" + +#include +#include +#include + +#include "main_global.h" +#include "register_view.h" +#include "devices/base/device_group.h" +#include "devices/gui/device_group_ui.h" +#include "gui_debug_manager.h" +#include "editor_manager.h" +#include "common/gui/list_container.h" + +//----------------------------------------------------------------------------- +Register::BaseListView::BaseListView(QWidget *parent) + : ListView(parent), _root(0) +{ + header()->hide(); + setSorting(-1); + setFullWidth(true); + setRootIsDecorated(false); + setAllColumnsShowFocus(true); + connect(this, SIGNAL(mouseButtonClicked(int, QListViewItem *, const QPoint &, int)), + SLOT(itemClicked(int, QListViewItem *, const QPoint &, int))); + connect(this, SIGNAL(contextMenuRequested(QListViewItem *, const QPoint &, int)), + SLOT(contextMenu(QListViewItem *, const QPoint &, int))); +} + +//----------------------------------------------------------------------------- +Register::RegisterListView::RegisterListView(QWidget *parent) + : BaseListView(parent) +{ + addColumn(QString::null); +} + +void Register::RegisterListView::init(const Device::Data *data) +{ + delete _root; + _root = new ListViewItemContainer(i18n("Registers"), this); + KIconLoader loader; + _root->setPixmap(0, loader.loadIcon("piklab_chip", KIcon::Small)); + _root->setSelectable(false); + _root->setOpen(true); + if (data) Device::groupui(*data).fillWatchListContainer(_root, _ids); +} + +void Register::RegisterListView::updateView() +{ + QListViewItemIterator it(_root); + for (; it.current(); ++it) { + int id = _root->id(it.current()); + if ( id==-1 || _ids[id].type()==Invalid ) continue; + bool watched = Register::list().isWatched(_ids[id]); + static_cast(it.current())->setOn(watched); + } +} + +void Register::RegisterListView::itemClicked(int button, QListViewItem *item, const QPoint &, int) +{ + if ( item==0 || button!=LeftButton ) return; + if ( item==firstChild() ) Main::editorManager().openEditor(EditorManager::RegisterEditor); + int id = _root->id(item); + if ( id==-1 || _ids[id].type()==Invalid ) return; + bool watched = Register::list().isWatched(_ids[id]); + static_cast(item)->setOn(!watched); + Debugger::manager->setRegisterWatched(_ids[id], !watched); +} + +//----------------------------------------------------------------------------- +Register::WatchedListView::WatchedListView(QWidget *parent) + : BaseListView(parent), _popup(0), _base(NumberBase::Hex) +{ + setSorting(0); + addColumn(QString::null); + addColumn(QString::null); + addColumn(QString::null); + + _root = new ListViewItemContainer(i18n("Watched"), this); + KIconLoader loader; + _root->setPixmap(0, loader.loadIcon("viewmag", KIcon::Small)); + _root->setSelectable(false); + _root->setOpen(true); +} + +KPopupMenu *Register::WatchedListView::appendFormatMenu(KPopupMenu *parent, uint offset) +{ + KIconLoader loader; + QPixmap icon = loader.loadIcon("fonts", KIcon::Small); + KPopupMenu *popup = new KPopupMenu; + popup->insertTitle(i18n("Format")); + FOR_EACH(NumberBase, base) popup->insertItem(base.label(), offset + base.type()); + parent->insertItem(icon, i18n("Format"), popup); + return popup; +} + +void Register::WatchedListView::init(const Device::Data *data) +{ + delete _popup; + _popup = 0; + if ( data==0 ) return; + _popup = new PopupContainer(i18n("Watch Register"), this); + Device::groupui(*data).fillWatchListContainer(_popup, _ids); + _popup->insertSeparator(); + _formatPopup = appendFormatMenu(_popup, _ids.count()); + KIconLoader loader; + QPixmap icon = loader.loadIcon("cancel", KIcon::Small); + _popup->insertItem(icon, i18n("Clear"), Debugger::manager, SLOT(stopWatchAll())); +} + +void Register::WatchedListView::updateView() +{ + // delete items not watched anymore + for (QListViewItem *item=_root->firstChild(); item;) { + ListViewItem *ritem = static_cast(item); + item = item->nextSibling(); + if ( !Register::list().isWatched(ritem->data()) ) delete ritem; + } + // add new items + bool added = false; + QValueList watched = Register::list().watched(); + QValueVector items(watched.count()); + for (uint k=0; kfirstChild(); + for (; item; item=item->nextSibling()) + if ( static_cast(item)->data()==watched[k] ) break; + if (item) { + items[k] = static_cast(item); + items[k]->updateView(); + } else { + items[k] = Device::groupui(*Main::deviceData()).createWatchItem(watched[k], _root); + items[k]->setBase(_base); + added = true; + } + } +} + +QString Register::WatchedListView::tooltip(const QListViewItem &item, int col) const +{ + if ( item.rtti()==Register::PortBitRtti ) return static_cast(item).tooltip(col); + if ( item.rtti()==Register::RegisterRtti ) return static_cast(item).tooltip(col); + return QString::null; +} + +void Register::WatchedListView::itemClicked(int button, QListViewItem *item, const QPoint &, int col) +{ + if ( item==0 || button!=LeftButton ) return; + else if ( item->rtti()==RegisterRtti ) { + if ( col==2 && Main::programmerState()==Programmer::Halted ) static_cast(item)->startRename(); + else item->setOpen(!item->isOpen()); + } +} + +void Register::WatchedListView::contextMenu(QListViewItem *item, const QPoint &p, int) +{ + if ( item==0 ) return; + if ( item==firstChild() ) { + if ( _popup==0 ) return; + FOR_EACH(NumberBase, base) _formatPopup->setItemChecked(_ids.count()+base.type(), _base==base); + int res = _popup->exec(p); + if ( res<0 ) return; + if ( ressetRegisterWatched(_ids[res], true); + else { + _base = NumberBase::Type(res-_ids.count()); + for (QListViewItem *item=_root->firstChild(); item; item=item->nextSibling()) + static_cast(item)->setBase(_base); + } + } else { + if ( item->rtti()==Register::PortBitRtti ) return; + Register::ListViewItem *ritem = static_cast(item); + KPopupMenu *pop = new KPopupMenu; + pop->insertTitle(ritem->label()); + QPopupMenu *fpop = appendFormatMenu(pop, 0); + FOR_EACH(NumberBase, base) fpop->setItemChecked(base.type(), ritem->base()==base); + pop->insertSeparator(); + KIconLoader loader; + QPixmap icon = loader.loadIcon("edit", KIcon::Small); + int editId = pop->insertItem(icon, i18n("Edit")); + pop->setItemEnabled(editId, Main::programmerState()==Programmer::Halted); + icon = loader.loadIcon("cancel", KIcon::Small); + int removeId = pop->insertItem(icon, i18n("Remove")); + int res = pop->exec(p); + if ( res==editId ) ritem->startRename(); + else if ( res==removeId ) Debugger::manager->setRegisterWatched(ritem->data(), false); + else if ( res>=0 ) ritem->setBase(NumberBase::Type(res)); + delete pop; + } +} + +//----------------------------------------------------------------------------- +Register::WatchView::WatchView(QWidget *parent) + : QWidget(parent, "watch_view"), GenericView(Register::list()), _data(0) +{ + QVBoxLayout *top = new QVBoxLayout(this); + QValueList sizes; + sizes.append(50); + Splitter *splitter = new Splitter(sizes, Qt::Vertical, this, "watch_window_splitter"); + top->addWidget(splitter); + + _registerListView = new RegisterListView(splitter); + _watchedListView = new WatchedListView(splitter); +} + +void Register::WatchView::init(bool force) +{ + if ( !force && _data==Main::deviceData() ) return; + _data = Main::deviceData(); + _registerListView->init(_data); + _watchedListView->init(_data); + updateView(); +} + +void Register::WatchView::updateView() +{ + _registerListView->updateView(); + _watchedListView->updateView(); +} diff --git a/src/libgui/watch_view.h b/src/libgui/watch_view.h new file mode 100644 index 0000000..a7ac24c --- /dev/null +++ b/src/libgui/watch_view.h @@ -0,0 +1,94 @@ +/*************************************************************************** + * Copyright (C) 2006-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef WATCH_VIEW_H +#define WATCH_VIEW_H + +#include "common/gui/list_container.h" +#include "common/common/storage.h" +#include "common/gui/list_view.h" +#include "devices/base/register.h" +namespace Device { class Data; } + +namespace Register +{ + +//----------------------------------------------------------------------------- +class BaseListView : public ListView +{ +Q_OBJECT +public: + BaseListView(QWidget *parent); + virtual void init(const Device::Data *data) = 0; + virtual void updateView() = 0; + +private slots: + virtual void itemClicked(int button, QListViewItem *item, const QPoint &p, int col) = 0; + virtual void contextMenu(QListViewItem *item, const QPoint &p, int col) = 0; + +protected: + ListViewItemContainer *_root; + QValueVector _ids; +}; + +//----------------------------------------------------------------------------- +class RegisterListView : public BaseListView +{ +Q_OBJECT +public: + RegisterListView(QWidget *parent); + virtual void init(const Device::Data *data); + virtual void updateView(); + +private slots: + virtual void itemClicked(int button, QListViewItem *item, const QPoint &p, int col); + virtual void contextMenu(QListViewItem *, const QPoint &, int) {} +}; + +//----------------------------------------------------------------------------- +class WatchedListView : public BaseListView +{ +Q_OBJECT +public: + WatchedListView(QWidget *parent); + virtual QString tooltip(const QListViewItem &item, int col) const; + virtual void init(const Device::Data *data); + virtual void updateView(); + +private slots: + virtual void itemClicked(int button, QListViewItem *item, const QPoint &p, int col); + virtual void contextMenu(QListViewItem *item, const QPoint &p, int col); + +private: + PopupContainer *_popup; + KPopupMenu *_formatPopup; + NumberBase _base; + + static KPopupMenu *appendFormatMenu(KPopupMenu *parent, uint offset); +}; + +//----------------------------------------------------------------------------- +class WatchView : public QWidget, public GenericView +{ +Q_OBJECT +public: + WatchView(QWidget *parent); + void init(bool force); + +public slots: + virtual void updateView(); + +private: + WatchedListView *_watchedListView; + RegisterListView *_registerListView; + const Device::Data *_data; +}; + +} // namespace + +#endif diff --git a/src/piklab-coff/Makefile.am b/src/piklab-coff/Makefile.am new file mode 100644 index 0000000..5884f43 --- /dev/null +++ b/src/piklab-coff/Makefile.am @@ -0,0 +1,16 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +bin_PROGRAMS = piklab-coff +OBJ = $(top_builddir)/src/common/cli/libcli.la \ + $(top_builddir)/src/coff/base/libcoff.la \ + $(top_builddir)/src/common/global/libglobal.la $(top_builddir)/src/devices/list/libdevicelistnoui.la \ + $(top_builddir)/src/devices/pic/pic/libpic.la $(top_builddir)/src/devices/pic/base/libpicbase.la \ + $(top_builddir)/src/devices/pic/xml_data/libpicxml.la \ + $(top_builddir)/src/devices/mem24/mem24/libmem24.la $(top_builddir)/src/devices/mem24/base/libmem24base.la \ + $(top_builddir)/src/devices/mem24/xml_data/libmem24xml.la \ + $(top_builddir)/src/devices/base/libdevicebase.la $(top_builddir)/src/common/common/libcommon.la +piklab_coff_DEPENDENCIES = $(OBJ) +piklab_coff_LDADD = $(OBJ) $(LIB_KIO) +piklab_coff_LDFLAGS = $(all_libraries) $(KDE_RPATH) +piklab_coff_SOURCES = main.cpp diff --git a/src/piklab-coff/main.cpp b/src/piklab-coff/main.cpp new file mode 100644 index 0000000..bc24b53 --- /dev/null +++ b/src/piklab-coff/main.cpp @@ -0,0 +1,282 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "main.h" + +#include "common/global/pfile.h" +#include "common/cli/cli_log.h" +#include "devices/list/device_list.h" +#include "devices/base/device_group.h" +#include "common/global/about.h" +#include "coff/base/text_coff.h" +#include "coff/base/coff_archive.h" + +//----------------------------------------------------------------------------- +const KCmdLineOptions OPTIONS[] = { + KCmdLineLastOption +}; + +const CLI::CommandData CLI::NORMAL_COMMAND_DATA[] = { + { "info", NeedSource, I18N_NOOP("Return general informations.") }, + { "variables", NeedSource, I18N_NOOP("Return informations about variables (for object).") }, + { "symbols", NeedSource, I18N_NOOP("Return informations about symbols.") }, + { "sections", NeedSource, I18N_NOOP("Return informations about sections (for object).") }, + { "lines", NeedSource, I18N_NOOP("Return informations about code lines (for object).") }, + { "files", NeedSource, I18N_NOOP("Return informations about files.") }, + { 0, NoCommandProperty, 0 } +}; +const CLI::CommandData CLI::INTERACTIVE_COMMAND_DATA[] = { + { 0, NoCommandProperty, 0 } +}; + +const CLI::PropertyData CLI::PROPERTY_DATA[] = { + { "device", "device ", "d", I18N_NOOP("Target device."), "device-list", I18N_NOOP("Return the list of supported devices.") }, + { 0, 0, 0, 0, 0, 0 } +}; + +const KCmdLineOptions CLI::OPTIONS[] = { + KCmdLineLastOption +}; + +//----------------------------------------------------------------------------- +CLI::Main::Main() + : MainBase(HasForce), _device(0) +{} + +CLI::Main::~Main() +{} + +CLI::ExitCode CLI::Main::prepareCommand(const QString &command) +{ + const CommandData *data = findCommandData(command); + CommandProperties properties = static_cast(data->properties); + int nbArgs = 0; + if ( properties & NeedSource ) nbArgs++; + if ( properties & NeedDestination ) nbArgs++; + if ( _args->count()count()>nbArgs ) return errorExit(i18n("Too many arguments."), ARG_ERROR); + uint argIndex = 0; + if ( properties & NeedSource ) { + _source = PURL::Url(_args->url(argIndex)); + argIndex++; + PURL::File file(_source, *_view); + if ( !file.openForRead() ) return FILE_ERROR; + } + if ( properties & NeedDestination ) { + _dest = PURL::Url(_args->url(argIndex)); + argIndex++; + if ( !_force && _dest.exists() ) return errorExit(i18n("Destination file already exists."), FILE_ERROR); + } + if ( _device==0 && (properties & NeedDevice) ) return errorExit(i18n("Device not specified."), ARG_ERROR); + return OK; +} + +QString CLI::Main::prettyAuxSymbol(const Coff::AuxSymbol &aux) +{ + QString s = (aux.type()==Coff::AuxSymbolType::Nb_Types ? "?" : aux.type().label()); + switch (aux.type().type()) { + case Coff::AuxSymbolType::Direct: break; + case Coff::AuxSymbolType::File: s += "=" + static_cast(aux).filename(); break; + case Coff::AuxSymbolType::Identifier: s += "=" + static_cast(aux).string(); break; + case Coff::AuxSymbolType::Section: break; + case Coff::AuxSymbolType::Nb_Types: break; + } + return s; +} + +QString CLI::Main::prettySymbol(const Coff::Symbol &sym) +{ + QStringList saux; + for (uint i=0; igroup().name()=="pic" ); + const Pic::Data *pdata = static_cast(coff.device()); + uint nbCharsAddress = (pdata ? pdata->nbCharsAddress() : 8); + + if ( command=="info" ) { + keys = coff.information(); + keys.setTitle(QString::null); + return OK; + } + + if ( command=="variables" ) { + keys.setTitle(i18n("Variables:")); + QMap::const_iterator it; + for (it=coff.variables().begin(); it!=coff.variables().end(); ++it) + keys.append(it.key(), toHexLabelAbs(it.data())); + return OK; + } + + if ( command=="symbols" ) { + keys.setTitle(i18n("Symbols:")); + for (uint i=0; iisAuxSymbol() ) continue; + const Coff::Symbol &sym = static_cast(*coff.symbol(i)); + keys.append(sym.name(), prettySymbol(sym)); + } + return OK; + } + + if ( command=="sections" ) { + keys.setTitle(i18n("Sections:")); + for (uint i=0; iname(), i18n("type=\"%1\" address=%2 size=%3 flags=%4") + .arg(s->type()==Coff::SectionType::Nb_Types ? "?" : s->type().label()) + .arg(toHexLabel(s->address(), nbCharsAddress)).arg(toHexLabel(s->size(), nbCharsAddress)).arg(toHexLabel(s->flags(), 8))); + } + return OK; + } + + if ( command=="lines" ) { + keys.setTitle(i18n("Source Lines:")); + keys.append(i18n(" Filename:Line"), i18n("Address")); + for (uint i=0; ilines().count()); k++) { + if (first) { + first = false; + keys.append(i18n("section \"%1\":").arg(s->name()), QString::null); + } + const Coff::CodeLine *cl = s->lines()[k]; + QString key = cl->filename() + ":" + QString::number(cl->line()); + if ( !cl->address().isValid() ) { + const Coff::Symbol &sym = *cl->symbol(); + keys.append(key, i18n("symbol \"%1\"").arg(sym.name()) + prettySymbol(sym)); + } else keys.append(key, toHexLabel(cl->address(), nbCharsAddress)); + } + } + return OK; + } + + if ( command=="files" ) { + keys.setTitle(i18n("Files:")); + QStringList::const_iterator it; + for (it=coff.filenames().begin(); it!=coff.filenames().end(); ++it) + keys.append(*it, QString::null); + return OK; + } + + return errorExit(i18n("Command not available for COFF of type Object."), ARG_ERROR); +} + +CLI::ExitCode CLI::Main::executeCommand(const QString &command) +{ + CoffType type = Coff::identify(_source, *this); + if ( type==CoffType::Nb_Types ) return ARG_ERROR; + Log::KeyList keys; + if ( command=="info" ) keys.append(i18n("COFF type:"), type.label()); + ExitCode code = ARG_ERROR; + switch (type.type()) { + case CoffType::Archive: code = executeCommandArchive(command, keys); break; + case CoffType::Object: code = executeCommandObject(command, keys); break; + case CoffType::Nb_Types: Q_ASSERT(false); break; + } + if ( code==OK ) keys.display(*_view); + return code; +} + +CLI::ExitCode CLI::Main::prepareRun(bool &interactive) +{ + interactive = false; + return OK; +} + +CLI::ExitCode CLI::Main::executeSetCommand(const QString &property, const QString &value) +{ + if ( property=="device" || property=="processor" ) { + if ( value.isEmpty() ) { + _device = 0; + return OK; + } + QString s = value.upper(); + _device = Device::lister().data(s); + if ( _device==0 ) return errorExit(i18n("Unknown device \"%1\".").arg(s), ARG_ERROR); + return OK; + } + return errorExit(i18n("Unknown property \"%1\".").arg(property), ARG_ERROR); +} + +QString CLI::Main::executeGetCommand(const QString &property) +{ + if ( property=="device" || property=="processor" ) { + if ( _device==0 ) return i18n(""); + return _device->name(); + } + log(Log::LineType::SoftError, i18n("Unknown property \"%1\".").arg(property)); + return QString::null; +} + +CLI::ExitCode CLI::Main::list(const QString &command) +{ + if ( MainBase::list(command)==OK ) return OK; + if ( command=="device-list" ) return deviceList(); + Q_ASSERT(false); + return OK; +} + +CLI::ExitCode CLI::Main::deviceList() +{ + QValueVector devices; + log(Log::LineType::Normal, i18n("Supported devices:")); + devices = Device::lister().supportedDevices(); + qHeapSort(devices); + QString s; + for (uint i=0; i * + * * + * 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. * + ***************************************************************************/ +#ifndef MAIN_H +#define MAIN_H + +#include "common/global/pfile.h" +#include "devices/base/hex_buffer.h" +#include "common/cli/cli_main.h" +namespace Device { class Data; class Memory; } +namespace Coff { class Symbol; class AuxSymbol; } + +namespace CLI +{ +//---------------------------------------------------------------------------- +enum CommandProperty { NoCommandProperty = 0, NeedSource = 1, NeedDestination = 2, NeedDevice = 4 }; +Q_DECLARE_FLAGS(CommandProperties, CommandProperty) +Q_DECLARE_OPERATORS_FOR_FLAGS(CommandProperties) + +//---------------------------------------------------------------------------- +class Main : public MainBase +{ +Q_OBJECT +public: + Main(); + virtual ~Main(); + +private: + const Device::Data *_device; + PURL::Url _source, _dest; + + virtual ExitCode prepareCommand(const QString &command); + virtual ExitCode executeCommand(const QString &command); + virtual ExitCode prepareRun(bool &interactive); + virtual ExitCode executeSetCommand(const QString &property, const QString &value); + ExitCode executeCommandArchive(const QString &command, Log::KeyList &keys); + ExitCode executeCommandObject(const QString &command, Log::KeyList &keys); + virtual QString executeGetCommand(const QString &property); + virtual ExitCode list(const QString &listName); + ExitCode deviceList(); + static QString prettyAuxSymbol(const Coff::AuxSymbol &aux); + static QString prettySymbol(const Coff::Symbol &sym); +}; + +} // namespace + +#endif diff --git a/src/piklab-coff/piklab-coff.pro b/src/piklab-coff/piklab-coff.pro new file mode 100644 index 0000000..901ed21 --- /dev/null +++ b/src/piklab-coff/piklab-coff.pro @@ -0,0 +1,15 @@ +STOPDIR = ../.. +include($${STOPDIR}/app.pro) + +TARGET = piklab-coff +HEADERS += main.h +SOURCES += main.cpp +LIBS += ../coff/base/libcoff.a \ + ../devices/list/libdevicelist.a \ + ../devices/mem24/mem24/libmem24.a ../devices/mem24/xml_data/libmem24xml.a \ + ../devices/mem24/base/libmem24base.a \ + ../devices/pic/pic/libpic.a ../devices/pic/xml_data/libpicxml.a \ + ../devices/pic/base/libpicbase.a \ + ../devices/base/libdevicebase.a \ + ../common/cli/libcli.a ../common/global/libglobal.a \ + ../common/nokde/libnokde.a ../common/common/libcommon.a diff --git a/src/piklab-hex/Makefile.am b/src/piklab-hex/Makefile.am new file mode 100644 index 0000000..b7ccf7e --- /dev/null +++ b/src/piklab-hex/Makefile.am @@ -0,0 +1,15 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +bin_PROGRAMS = piklab-hex +OBJ = $(top_builddir)/src/common/cli/libcli.la \ + $(top_builddir)/src/common/global/libglobal.la $(top_builddir)/src/devices/list/libdevicelistnoui.la \ + $(top_builddir)/src/devices/pic/pic/libpic.la $(top_builddir)/src/devices/pic/base/libpicbase.la \ + $(top_builddir)/src/devices/pic/xml_data/libpicxml.la \ + $(top_builddir)/src/devices/mem24/mem24/libmem24.la $(top_builddir)/src/devices/mem24/base/libmem24base.la \ + $(top_builddir)/src/devices/mem24/xml_data/libmem24xml.la \ + $(top_builddir)/src/devices/base/libdevicebase.la $(top_builddir)/src/common/common/libcommon.la +piklab_hex_DEPENDENCIES = $(OBJ) +piklab_hex_LDADD = $(OBJ) $(LIB_KIO) +piklab_hex_LDFLAGS = $(all_libraries) $(KDE_RPATH) +piklab_hex_SOURCES = main.cpp diff --git a/src/piklab-hex/main.cpp b/src/piklab-hex/main.cpp new file mode 100644 index 0000000..6323770 --- /dev/null +++ b/src/piklab-hex/main.cpp @@ -0,0 +1,291 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "main.h" + +#include "common/global/pfile.h" +#include "common/cli/cli_log.h" +#include "devices/list/device_list.h" +#include "devices/pic/base/pic.h" +#include "devices/pic/pic/pic_memory.h" +#include "devices/base/device_group.h" +#include "common/global/about.h" + +//----------------------------------------------------------------------------- +const KCmdLineOptions OPTIONS[] = { + KCmdLineLastOption +}; + +const CLI::CommandData CLI::NORMAL_COMMAND_DATA[] = { + { "check", NeedSource1 | NeedCorrectInput, I18N_NOOP("Check hex file for correctness (if a device is specified, check if hex file is compatible with it).") }, + { "info", NeedSource1 | NeedCorrectInput, I18N_NOOP("Return information about hex file.") }, + { "fix", NeedSource1 | NeedDestination, I18N_NOOP("Clean hex file and fix errors (wrong CRC, truncated line, truncated file).") }, + { "compare", NeedSource1 | NeedSource2 | NeedCorrectInput, I18N_NOOP("Compare two hex files.") }, + { "checksum", NeedSource1 | NeedCorrectInput | NeedDevice, I18N_NOOP("Return checksum.") }, + { "create", NeedDestination | NeedDevice, I18N_NOOP("Create an hex file for the specified device.") }, + { 0, NoCommandProperty, 0 } +}; +const CLI::CommandData CLI::INTERACTIVE_COMMAND_DATA[] = { + { 0, NoCommandProperty, 0 } +}; + +const CLI::PropertyData CLI::PROPERTY_DATA[] = { + { "device", "device ", "d", I18N_NOOP("Target device."), "device-list", I18N_NOOP("Return the list of supported devices.") }, + { "fill", "fill ", 0, I18N_NOOP("Fill option."), "fill-list", I18N_NOOP("Return the list of supported fill options.") }, + { 0, 0, 0, 0, 0, 0 } +}; + +const KCmdLineOptions CLI::OPTIONS[] = { + KCmdLineLastOption +}; + +const CLI::FillOptions CLI::FILL_OPTIONS[] = { + { "blank", I18N_NOOP("Fill with blank values (default).") }, + { "zero", I18N_NOOP("Fill with zeroes.") }, + { "checksum_check", I18N_NOOP("Fill for checksum verification (cf datasheets).") }, + { 0, 0 } +}; + +//----------------------------------------------------------------------------- +CLI::Main::Main() + : MainBase(HasForce), _device(0), _memory(0) +{} + +CLI::Main::~Main() +{ + delete _memory; +} + +CLI::ExitCode CLI::Main::prepareCommand(const QString &command) +{ + const CommandData *data = findCommandData(command); + CommandProperties properties = static_cast(data->properties); + int nbArgs = 0; + if ( properties & NeedSource1 ) nbArgs++; + if ( properties & NeedSource2 ) nbArgs++; + if ( properties & NeedDestination ) nbArgs++; + if ( _args->count()count()>nbArgs ) return errorExit(i18n("Too many arguments."), ARG_ERROR); + uint argIndex = 0; + if ( properties & NeedSource1 ) { + PURL::Url url = PURL::Url(_args->url(argIndex)); + argIndex++; + PURL::File file(url, *_view); + if ( !file.openForRead() ) return FILE_ERROR; + _errors = _source1.load(file.stream(), _format); + if ( (properties & NeedCorrectInput) && !_errors.isEmpty() ) { + QString s = (properties & NeedSource2 ? i18n("First hex file: ") : QString::null); + for (uint i=0; iurl(argIndex)); + argIndex++; + PURL::File file(url, *_view); + if ( !file.openForRead() ) return FILE_ERROR; + _errors = _source2.load(file.stream(), _format); + if ( (properties & NeedCorrectInput) && !_errors.isEmpty() ) { + QString s = (properties & NeedSource1 ? i18n("Second hex file: ") : QString::null); + for (uint i=0; iurl(argIndex)); + argIndex++; + if ( !_force && _dest.exists() ) return errorExit(i18n("Destination file already exists."), FILE_ERROR); + } + if ( _device==0 && (properties & NeedDevice) ) return errorExit(i18n("Device not specified."), ARG_ERROR); + return OK; +} + +CLI::ExitCode CLI::Main::executeCommand(const QString &command) +{ + if (_device) { + delete _memory; + _memory = _device->group().createMemory(*_device); + } + if ( command=="check" ) { + if ( _device==0 ) return okExit(i18n("Hex file is valid.")); + QStringList warnings; + Device::Memory::WarningTypes wtypes = _memory->fromHexBuffer(_source1, warnings); + if ( wtypes==Device::Memory::NoWarning ) return okExit(i18n("Hex file is compatible with device \"%1\".").arg(_device->name())); + return errorExit(warnings.join("\n"), EXEC_ERROR); + } + if ( command=="info" ) { + Log::KeyList keys; + keys.append(i18n("Format:"), HexBuffer::FORMATS[_format]); + uint nbWords = 0, start = 0, end = 0; + HexBuffer::const_iterator it; + for (it=_source1.begin(); it!=_source1.end(); ++it) { + if ( !it.data().isInitialized() ) continue; + nbWords++; + if ( nbWords==1 ) { + start = it.key(); + end = it.key(); + } else { + start = qMin(start, it.key()); + end = qMax(end, it.key()); + } + } + keys.append(i18n("No. of Words:"), toHexLabelAbs(nbWords)); + if ( nbWords!=0 ) { + uint nbc = nbChars(NumberBase::Hex, end); + keys.append(i18n("Start:"), toHexLabel(start, nbc)); + keys.append(i18n("End:"), toHexLabel(end, nbc)); + } + keys.display(*_view); + return okExit(i18n("Hex file is valid.")); + } + if ( command=="fix" ) { + for (uint i=0; ifromHexBuffer(_source1, warnings); + for (uint i=0; ichecksum(); + log(Log::LineType::Normal, i18n("Checksum: %1").arg(toHexLabel(cs, 4))); + if ( _device->group().name()=="pic" ) { + BitValue ucs = static_cast(_memory)->unprotectedChecksum(); + if ( ucs!=cs ) log(Log::LineType::Information, i18n("Unprotected checksum: %1").arg(toHexLabel(ucs, 4))); + } + return OK; + } + if ( command=="create" ) { + if ( _fill.isEmpty() || _fill=="blank" ) ; // default + else if ( _fill=="zero" ) _memory->fill(0x0); + else if ( _fill=="checksum_check" ) { + if ( _device->group().name()=="pic" ) static_cast(_memory)->checksumCheckFill(); + } else { + bool ok; + uint value = fromAnyLabel(_fill, &ok); + Q_ASSERT(ok); + _memory->fill(value); + } + PURL::File dest(_dest, *_view); + if ( !dest.openForWrite() ) return FILE_ERROR; + _memory->save(dest.stream(), HexBuffer::IHX32); + if ( !dest.close() ) return FILE_ERROR; + return okExit(i18n("File created.")); + } + Q_ASSERT(false); + return ARG_ERROR; +} + +CLI::ExitCode CLI::Main::prepareRun(bool &interactive) +{ + interactive = false; + return OK; +} + +CLI::ExitCode CLI::Main::executeSetCommand(const QString &property, const QString &value) +{ + if ( property=="device" || property=="processor" ) { + if ( value.isEmpty() ) { + _device = 0; + return OK; + } + QString s = value.upper(); + _device = Device::lister().data(s); + if ( _device==0 ) return errorExit(i18n("Unknown device \"%1\".").arg(s), ARG_ERROR); + return OK; + } + if ( property=="fill" ) { + _fill = value; + for (uint i=0; FILL_OPTIONS[i].name; i++) + if ( value==FILL_OPTIONS[i].name ) return OK; + bool ok; + (void)fromAnyLabel(value, &ok); + if ( !ok ) return errorExit(i18n("Number format not recognized."), ARG_ERROR); + return OK; + } + return errorExit(i18n("Unknown property \"%1\".").arg(property), ARG_ERROR); +} + +QString CLI::Main::executeGetCommand(const QString &property) +{ + if ( property=="device" || property=="processor" ) { + if ( _device==0 ) return i18n(""); + return _device->name(); + } + if ( property=="fill" ) { + if ( _fill.isEmpty() ) return i18n(""); + return _fill; + } + log(Log::LineType::SoftError, i18n("Unknown property \"%1\".").arg(property)); + return QString::null; +} + +CLI::ExitCode CLI::Main::list(const QString &command) +{ + if ( MainBase::list(command)==OK ) return OK; + if ( command=="device-list" ) return deviceList(); + if ( command=="fill-list" ) return fillOptionList(); + Q_ASSERT(false); + return OK; +} + +CLI::ExitCode CLI::Main::deviceList() +{ + QValueVector devices; + log(Log::LineType::Normal, i18n("Supported devices:")); + devices = Device::lister().supportedDevices(); + qHeapSort(devices); + QString s; + for (uint i=0; i"), i18n("Fill with the specified numeric value.")); + keys.display(*_view); + return OK; +} + +//----------------------------------------------------------------------------- +int main(int argc, char **argv) +{ + CLI::Main main; + Piklab::AboutData *about = new Piklab::AboutData("piklab-hex", I18N_NOOP("Piklab Hex Utility"), I18N_NOOP("Command-line utility to manipulate hex files.")); + CLI::OptionList list = main.optionList(I18N_NOOP("Hex filename(s).")); + Piklab::init(about, argc, argv, false, list.ptr()); + return main.doRun(); +} diff --git a/src/piklab-hex/main.h b/src/piklab-hex/main.h new file mode 100644 index 0000000..4689bff --- /dev/null +++ b/src/piklab-hex/main.h @@ -0,0 +1,65 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef MAIN_H +#define MAIN_H + +#include "common/global/pfile.h" +#include "devices/base/hex_buffer.h" +#include "common/cli/cli_main.h" + +namespace Device +{ + class Data; + class Memory; +} + +namespace CLI +{ +//---------------------------------------------------------------------------- +enum CommandProperty { NoCommandProperty = 0, NeedSource1 = 1, NeedDestination = 2, + NeedSource2 = 4, NeedCorrectInput = 8, NeedDevice = 16 }; +Q_DECLARE_FLAGS(CommandProperties, CommandProperty) +Q_DECLARE_OPERATORS_FOR_FLAGS(CommandProperties) + +//---------------------------------------------------------------------------- +struct FillOptions { + const char *name, *description; +}; +extern const FillOptions FILL_OPTIONS[]; + +//---------------------------------------------------------------------------- +class Main : public MainBase +{ +Q_OBJECT +public: + Main(); + virtual ~Main(); + +private: + PURL::Url _dest; + HexBuffer _source1, _source2; + HexBuffer::Format _format; + QValueList _errors; + const Device::Data *_device; + Device::Memory *_memory; + QString _fill; + + virtual ExitCode prepareCommand(const QString &command); + virtual ExitCode executeCommand(const QString &command); + virtual ExitCode prepareRun(bool &interactive); + virtual ExitCode executeSetCommand(const QString &property, const QString &value); + virtual QString executeGetCommand(const QString &property); + virtual ExitCode list(const QString &listName); + ExitCode deviceList(); + ExitCode fillOptionList(); +}; + +} // namespace + +#endif diff --git a/src/piklab-hex/piklab-hex.pro b/src/piklab-hex/piklab-hex.pro new file mode 100644 index 0000000..29d882e --- /dev/null +++ b/src/piklab-hex/piklab-hex.pro @@ -0,0 +1,14 @@ +STOPDIR = ../.. +include($${STOPDIR}/app.pro) + +TARGET = piklab-hex +HEADERS += main.h +SOURCES += main.cpp +LIBS += ../devices/list/libdevicelist.a \ + ../devices/mem24/mem24/libmem24.a ../devices/mem24/xml_data/libmem24xml.a \ + ../devices/mem24/base/libmem24base.a \ + ../devices/pic/pic/libpic.a ../devices/pic/xml_data/libpicxml.a \ + ../devices/pic/base/libpicbase.a \ + ../devices/base/libdevicebase.a \ + ../common/cli/libcli.a ../common/global/libglobal.a \ + ../common/nokde/libnokde.a ../common/common/libcommon.a diff --git a/src/piklab-prog/Makefile.am b/src/piklab-prog/Makefile.am new file mode 100644 index 0000000..fd53ef0 --- /dev/null +++ b/src/piklab-prog/Makefile.am @@ -0,0 +1,31 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +bin_PROGRAMS = piklab-prog +OBJ = $(top_builddir)/src/progs/list/libproglistnoui.la \ + $(top_builddir)/src/progs/picdem_bootloader/base/libpicdembootloader.la \ + $(top_builddir)/src/progs/pickit2_bootloader/base/libpickit2bootloader.la \ + $(top_builddir)/src/progs/tbl_bootloader/base/libtblbootloader.la \ + $(top_builddir)/src/progs/bootloader/base/libbootloader.la \ + $(top_builddir)/src/progs/gpsim/base/libgpsim.la $(top_builddir)/src/progs/psp/base/libpsp.la \ + $(top_builddir)/src/progs/pickit1/base/libpickit1.la \ + $(top_builddir)/src/progs/pickit2v2/base/libpickit2v2.la $(top_builddir)/src/progs/pickit2/base/libpickit2.la \ + $(top_builddir)/src/progs/icd1/base/libicd1.la $(top_builddir)/src/progs/icd2/base/libicd2.la \ + $(top_builddir)/src/progs/icd2/icd2_data/libicd2data.la $(top_builddir)/src/progs/direct/base/libdirectprog.la \ + $(top_builddir)/src/devices/mem24/prog/libmem24prog.la $(top_builddir)/src/devices/pic/prog/libpicprog.la \ + $(top_builddir)/src/progs/manager/libprogmanager.la $(top_builddir)/src/progs/base/libprogbase.la \ + \ + $(top_builddir)/src/coff/base/libcoff.la $(top_builddir)/src/common/port/libport.la \ + $(top_builddir)/src/common/cli/libcli.la $(top_builddir)/src/common/global/libglobal.la \ + \ + $(top_builddir)/src/devices/list/libdevicelistnoui.la \ + $(top_builddir)/src/devices/pic/pic/libpic.la $(top_builddir)/src/devices/pic/base/libpicbase.la \ + $(top_builddir)/src/devices/pic/xml_data/libpicxml.la \ + $(top_builddir)/src/devices/mem24/mem24/libmem24.la $(top_builddir)/src/devices/mem24/base/libmem24base.la \ + $(top_builddir)/src/devices/mem24/xml_data/libmem24xml.la \ + $(top_builddir)/src/devices/base/libdevicebase.la \ + $(top_builddir)/src/common/common/libcommon.la +piklab_prog_DEPENDENCIES = $(OBJ) +piklab_prog_LDADD = $(OBJ) $(LIB_KIO) $(LIBUSB_LIBS) $(LIBREADLINE_LIBS) +piklab_prog_LDFLAGS = $(all_libraries) $(KDE_RPATH) +piklab_prog_SOURCES = cmdline.cpp cli_prog_manager.cpp cli_debug_manager.cpp cli_interactive.cpp diff --git a/src/piklab-prog/cli_debug_manager.cpp b/src/piklab-prog/cli_debug_manager.cpp new file mode 100644 index 0000000..418bc06 --- /dev/null +++ b/src/piklab-prog/cli_debug_manager.cpp @@ -0,0 +1,18 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "cli_debug_manager.h" + +#include "progs/base/generic_prog.h" +#include "progs/base/generic_debug.h" + +void Debugger::CliManager::updateView(bool) +{ + if ( Programmer::manager->programmer() && debugger() ) log(Log::LineType::Normal, debugger()->statusString()); + // ### TODO: show current and next PC lines +} diff --git a/src/piklab-prog/cli_debug_manager.h b/src/piklab-prog/cli_debug_manager.h new file mode 100644 index 0000000..8da14fa --- /dev/null +++ b/src/piklab-prog/cli_debug_manager.h @@ -0,0 +1,34 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef CLI_DEBUG_MANAGER_H +#define CLI_DEBUG_MANAGER_H + +#include "progs/manager/debug_manager.h" +#include "cmdline.h" + +namespace Debugger +{ +class CliManager : public Manager +{ +Q_OBJECT +public: + CliManager() {} + virtual PURL::Url coffUrl() const { return CLI::_coffUrl; } + +private: + virtual const Programmer::Group *programmerGroup() const { return CLI::_progGroup; } + virtual const Device::Data *deviceData() const { return CLI::_device; } + virtual Log::View *compileView() { return view(); } + virtual void updateView(bool gotoPC); + virtual bool isProjectSource(const PURL::Url &) const { return true; } +}; + +} // namespace + +#endif diff --git a/src/piklab-prog/cli_interactive.cpp b/src/piklab-prog/cli_interactive.cpp new file mode 100644 index 0000000..148ba62 --- /dev/null +++ b/src/piklab-prog/cli_interactive.cpp @@ -0,0 +1,347 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "cli_interactive.h" + +#if defined(HAVE_READLINE) +# include +# include +#else +# include +#endif +#include +#include +#include + +#include "progs/base/generic_prog.h" +#include "cmdline.h" +#include "cli_prog_manager.h" +#include "common/cli/cli_log.h" +#include "devices/base/device_group.h" +#include "devices/pic/base/pic_register.h" +#include "devices/pic/prog/pic_prog.h" +#include "coff/base/text_coff.h" +#include "devices/pic/prog/pic_debug.h" + +//----------------------------------------------------------------------------- +const CLI::CommandData CLI::INTERACTIVE_COMMAND_DATA[] = { + { "property-list", NoCommandProperty, I18N_NOOP("Display the list of available properties.") }, + { "register-list", NoCommandProperty, I18N_NOOP("Display the list of registers.") }, + { "variable-list", NoCommandProperty, I18N_NOOP("Display the list of variables.") }, + { "range-list", NoCommandProperty, I18N_NOOP("Display the list of memory ranges.") }, + { "help", NoCommandProperty, I18N_NOOP("Display help.") }, + { "quit", NoCommandProperty, I18N_NOOP("Quit.") }, + { "set", NoCommandProperty, I18N_NOOP("Set property value: \"set \" or \" \".") }, + { "unset", NoCommandProperty, I18N_NOOP("Unset property value: \"unset \".") }, + { "get", NoCommandProperty, I18N_NOOP("Get property value: \"get \" or \"\".") }, + { "disconnect", NeedProgrammer, I18N_NOOP("Disconnect programmer.") }, + { "start", NeedDevice | NeedProgrammer, I18N_NOOP("Start or restart debugging session.") }, + { "step", NeedDevice | NeedProgrammer, I18N_NOOP("Step one instruction.") }, + { "x", NeedDevice | NeedProgrammer, I18N_NOOP("Read or set a register or variable: \"x PORTB\" or \"x W 0x1A\".") }, + { "break", NeedDevice | NeedProgrammer, I18N_NOOP("Set a breakpoint \"break e 0x04\" or list all breakpoints \"break\".") }, + { "clear", NeedDevice | NeedProgrammer, I18N_NOOP("Clear a breakpoint \"clear 0\", \"clear e 0x04\", or clear all breakpoints \"clear all\".") }, + { "raw-com", NeedDevice | NeedProgrammer, I18N_NOOP("Write and read raw commands to port from given file.") }, + { 0, NoCommandProperty, 0 } +}; + +const CLI::PropertyData CLI::PROPERTY_DATA[] = { + { "programmer", "programmer ", "p", I18N_NOOP("Programmer to use."), "programmer-list", I18N_NOOP("Return the list of supported programmers.") }, + { "hardware", "hardware ", "h", I18N_NOOP("Programmer hardware configuration to use (for direct programmer)."), "hardware-list", I18N_NOOP("Return the list of supported programmer hardware configurations.") }, + { "device", "device ", "d", I18N_NOOP("Target device."), "device-list", I18N_NOOP("Return the list of supported devices.") }, + { "format", "format ", "f", I18N_NOOP("Hex output file format."), "format-list", I18N_NOOP("Return the list of supported hex file formats.") }, + { "port", "port ", "t", I18N_NOOP("Programmer port (\"usb\" or device such as \"/dev/ttyS0\")"), "port-list", I18N_NOOP("Return the list of detected ports.") }, + { "firmware-dir", "firmware-dir ", 0, I18N_NOOP("Firmware directory."), 0, 0 }, + { "target-self-powered", "target-self-powered ", 0, I18N_NOOP("Set if target device is self-powered."), 0, 0 }, + { "hex", 0, 0, I18N_NOOP("Hex file to be used for programming."), 0, 0 }, + { "coff", 0, 0, I18N_NOOP("COFF file to be used for debugging."), 0, 0 }, + { "processor", 0, 0, I18N_NOOP("Same as \"device\"."), 0, 0 }, + { 0, 0, 0, 0, 0, 0 } +}; + +//----------------------------------------------------------------------------- +void CLI::Interactive::signalHandler(int n) +{ + if ( n!=SIGINT ) return; + fprintf(stdout, " Break\n"); + fflush(stdout); + Programmer::Base *prog = Programmer::manager->programmer(); + if ( prog && prog->state()==Programmer::Running ) Programmer::manager->halt(); + _interactive->redisplayPrompt(); +} + +CLI::Interactive::Interactive(QObject *parent) + : QObject(parent, "interactive") +{ + setView(_view); + ::signal(SIGINT, signalHandler); +#if defined(HAVE_READLINE) + using_history(); +#else + _stdin.open(IO_ReadOnly, stdin); +#endif + QTimer::singleShot(0, this, SLOT(displayPrompt())); +} + +void CLI::Interactive::redisplayPrompt() +{ +#if defined(HAVE_READLINE) + rl_forced_update_display(); +#else + fprintf(stdout, "> "); + fflush(stdout); +#endif +} + +void CLI::Interactive::displayPrompt() +{ +#if defined(HAVE_READLINE) + char *line = readline("> "); + _input = QString(line); + if ( !_input.isEmpty() ) add_history(line); + free(line); +#else + fprintf(stdout, "> "); + fflush(stdout); + char buffer[1000]; + _stdin.readLine(buffer, 1000); + _input = QString(buffer); +#endif + lineRead(); +} + +CLI::ExitCode CLI::Interactive::processLine(const QString &s) +{ + QStringList words = QStringList::split(" ", s); + if ( words.count()==0 ) return ARG_ERROR; + if ( words[0]=="command-list" || words[0]=="property-list" || words[0]=="range-list" + || isPropertyList(words[0]) ) return static_cast
(_main)->list(words[0]); + if ( words[0]=="register-list" ) return registerList(); + if ( words[0]=="variable-list" ) return variableList(); + if ( isProperty(words[0]) ) { + if ( words.count()==1 ) words.prepend("get"); + else if ( words.count()==2 ) words.prepend("set"); + else return errorExit(i18n("This command takes no or one argument"), ARG_ERROR); + } + if ( findCommand(words[0])!=OK ) return ARG_ERROR; + const CommandData *data = findCommandData(words[0]); + if ( words[0]=="quit" ) return EXITING; + if ( words[0]=="set" ) { + if ( words.count()==2 ) return static_cast
(_main)->executeSetCommand(words[1], QString::null); + if ( words.count()!=3 ) return errorExit(i18n("This command takes two arguments."), ARG_ERROR); + return static_cast
(_main)->executeSetCommand(words[1], words[2]); + } + if ( words[0]=="unset" ) { + if ( words.count()!=2 ) return errorExit(i18n("This command takes one argument."), ARG_ERROR); + return static_cast
(_main)->executeSetCommand(words[1], QString::null); + } + if ( words[0]=="get" ) { + if ( words.count()!=2 ) return errorExit(i18n("This command takes one argument."), ARG_ERROR); + QString s = static_cast
(_main)->executeGetCommand(words[1]); + if ( !s.isEmpty() ) log(Log::LineType::Normal, words[1] + ": " + s); + return OK; + } + if ( words[0]=="help" ) return static_cast
(_main)->list("command-list"); + if ( words[0]=="x" ) { + if ( words.count()!=2 && words.count()!=3 ) return errorExit(i18n("This command takes one or two argument."), ARG_ERROR); + return executeRegister(words[1], words.count()==3 ? words[2] : QString::null); + } + if ( words[0]=="break" ) { + if ( words.count()==3 ) { + if ( words[1]=="e" ) { + bool ok; + ulong address = fromAnyLabel(words[2], &ok); + if ( !ok ) return errorExit(i18n("Number format not recognized."), ARG_ERROR); + PURL::Url dummy; + Breakpoint::Data data(dummy, address); + if ( Breakpoint::list().contains(data) ) return okExit(i18n("Breakpoint already set at %1.").arg(toHexLabel(address, nbChars(NumberBase::Hex, address)))); + Breakpoint::list().append(data); + Breakpoint::list().setAddress(data, address); + Breakpoint::list().setState(data, Breakpoint::Active); + return okExit(i18n("Breakpoint set at %1.").arg(toHexLabel(address, nbChars(NumberBase::Hex, address)))); + } + return errorExit(i18n("The first argument should be \"e\"."), ARG_ERROR); + } + if ( words.count()==1 ) { + uint nb = Breakpoint::list().count(); + if ( nb==0 ) return okExit(i18n("No breakpoint set.")); + log(Log::LineType::Normal, i18n("Breakpoints:")); + uint nbc = 0; + if (_device) nbc = _device->nbCharsAddress(); + else for (uint i=0; i=Breakpoint::list().count() ) return errorExit(i18n("Breakpoint index too large."), ARG_ERROR); + Breakpoint::Data data = Breakpoint::list().data(i); + Address address = Breakpoint::list().address(data); + Breakpoint::list().remove(data); + return okExit(i18n("Breakpoint at %1 removed.").arg(toHexLabelAbs(address))); + } + if ( words[0]=="raw-com" ) { + if ( words.count()!=2 ) return errorExit(i18n("This command needs a commands filename."), ARG_ERROR); + } else if ( words[0]=="program" || words[0]=="read" || words[0]=="verify" || words[0]=="erase" || words[0]=="blank_check" ) { + uint hexi = 1; + if ( words.count()>=2 && words[1]=="-r" ) { + hexi = 3; + if ( words.count()==2 ) return errorExit(i18n("You need to specify the range."), ARG_ERROR); + ExitCode code = static_cast
(_main)->extractRange(words[2]); + if ( code!=OK ) return code; + } + if ( data->properties & (InputHex|OutputHex) ) { + if ( uint(words.count())>(hexi+1) ) return errorExit(i18n("Too many arguments."), ARG_ERROR); + if ( uint(words.count())==(hexi+1) )_hexUrl = PURL::Url(runDirectory(), words[hexi]); + if ( _hexUrl.isEmpty() ) return errorExit(i18n("This command needs an hex filename."), ARG_ERROR); + } else if ( uint(words.count())>hexi ) return errorExit(i18n("Too many arguments."), ARG_ERROR); + } else if ( words.count()!=1 ) return errorExit(i18n("This command takes no argument."), ARG_ERROR); + + ExitCode code = static_cast
(_main)->prepareCommand(words[0]); + if ( code!=OK ) return code; + if ( words[0]=="raw-com" ) return executeRawCommands(words[1]); + return static_cast
(_main)->executeCommand(words[0]); +} + +void CLI::Interactive::lineRead() +{ + QString s = _input.stripWhiteSpace(); + _input = QString::null; + if ( processLine(s)==EXITING ) { +#if QT_VERSION<0x040000 + qApp->exit(OK); +#else + QCoreApplication::exit(OK); +#endif + return; + } + QTimer::singleShot(0, this, SLOT(displayPrompt())); +} + +CLI::ExitCode CLI::Interactive::registerList() +{ + if ( _device==0 ) return errorExit(i18n("No device specified."), NOT_SUPPORTED_ERROR); + if ( _device->group().name()!="pic" ) return errorExit(i18n("No register."), NOT_SUPPORTED_ERROR); + const Pic::Data &data = static_cast(*_device); + const Coff::Object *coff = Debugger::manager->coff(); + const Pic::RegistersData &rdata = data.registersData(); + log(Log::LineType::Normal, i18n("Special Function Registers:")); + QValueVector list = Pic::sfrList(data); + for (uint i=0; icoff(); + if ( coff==0 ) return errorExit(i18n("No COFF file specified."), NOT_SUPPORTED_ERROR); + if ( _device->group().name()!="pic" ) return errorExit(i18n("No register."), NOT_SUPPORTED_ERROR); + const Pic::Data &data = static_cast(*_device); + const Pic::RegistersData &rdata = data.registersData(); + QValueVector list = Pic::variableList(data, *coff); + if ( list.count()==0 ) log(Log::LineType::Normal, i18n("No variable.")); + for (uint i=0; i(*_device); + const Coff::Object *coff = Debugger::manager->coff(); + const Pic::RegistersData &rdata = data.registersData(); + bool ok; + Address address = fromAnyLabel(name, &ok); + if (ok) { + if ( address>rdata.addressFromIndex(rdata.nbRegisters()-1) ) return Address(); + return address; + } + QValueVector sfrs = Pic::sfrList(data); + for (uint i=0; i variables = coff->variables(); + if ( variables.contains(name) ) return variables[name]; + return Address(); +} + +CLI::ExitCode CLI::Interactive::executeRegister(const QString &name, const QString &value) +{ + if ( Debugger::manager->debugger()==0 ) return errorExit(i18n("You need to start the debugging session first (with \"start\")."), ARG_ERROR); + const Pic::Data &data = static_cast(*_device); + const Pic::RegistersData &rdata = data.registersData(); + uint nbChars = rdata.nbChars(); + bool ok; + ulong v = fromAnyLabel(value, &ok); + if ( !ok ) return errorExit(i18n("Number format not recognized."), ARG_ERROR); + if ( v>maxValue(NumberBase::Hex, nbChars) ) return errorExit(i18n("The given value is too large (max: %1).").arg(toHexLabel(maxValue(NumberBase::Hex, nbChars), nbChars)), ARG_ERROR); + Register::TypeData rtd; + if ( name.lower()=="w" || name.lower()=="wreg" ) + rtd = static_cast(Debugger::manager->debugger())->deviceSpecific()->wregTypeData(); + else if ( name.lower()=="pc" ) + rtd = Debugger::manager->debugger()->pcTypeData(); + else { + Address address = findRegisterAddress(name); + if ( !address.isValid() ) return errorExit(i18n("Unknown register or variable name."), ARG_ERROR); + rtd = Register::TypeData(address, rdata.nbChars()); + } + if ( value.isEmpty() ) { + if ( !Debugger::manager->readRegister(rtd) ) return ARG_ERROR; + return okExit(i18n("%1 = %2").arg(name.upper()).arg(toHexLabel(Register::list().value(rtd), nbChars))); + } + return (Debugger::manager->writeRegister(rtd, v) ? OK : EXEC_ERROR); +} + +CLI::ExitCode CLI::Interactive::executeRawCommands(const QString &filename) +{ + QFile file(filename); + if ( !file.open(IO_ReadOnly) ) return errorExit(i18n("Could not open filename \"%1\".").arg(filename), ARG_ERROR); + if ( Programmer::manager->programmer()==0 ) { + Programmer::manager->createProgrammer(_device); + if ( !Programmer::manager->programmer()->simpleConnectHardware() ) return EXEC_ERROR; + } + Programmer::Base *programmer = Programmer::manager->programmer(); + for (;;) { + QString s; +#if QT_VERSION<0x040000 + if ( file.readLine(s, 1000)==-1 ) break; +#else + char buffer[1000]; + if ( file.readLine(buffer, 1000)==-1 ) break; + s += buffer; +#endif + bool write = !s.startsWith(" "); + s = s.stripWhiteSpace(); + if ( s.isEmpty() ) continue; + if (write) { + if ( !programmer->hardware()->rawWrite(s) ) return EXEC_ERROR; + } else { + QString rs; + if ( !programmer->hardware()->rawRead(s.length(), rs) ) return EXEC_ERROR; + if ( rs!=s ) log(Log::LineType::Warning, i18n("Read string is different than expected: %1 (%2).").arg(rs).arg(s)); + } + } + return okExit(i18n("End of command file reached.")); +} diff --git a/src/piklab-prog/cli_interactive.h b/src/piklab-prog/cli_interactive.h new file mode 100644 index 0000000..fad6e9d --- /dev/null +++ b/src/piklab-prog/cli_interactive.h @@ -0,0 +1,53 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef CLI_INTERACTIVE_H +#define CLI_INTERACTIVE_H + +#include +#include "common/global/global.h" +#include "common/cli/cli_global.h" +#include "common/global/log.h" +#include "common/common/bitvalue.h" + +namespace CLI +{ +//---------------------------------------------------------------------------- +enum CommandProperty { NoCommandProperty = 0, NeedProgrammer = 1, InputHex = 2, + OutputHex = 4, NeedDevice = 8 }; +Q_DECLARE_FLAGS(CommandProperties, CommandProperty) +Q_DECLARE_OPERATORS_FOR_FLAGS(CommandProperties) + +//---------------------------------------------------------------------------- +class Interactive : public QObject, public Log::Base +{ +Q_OBJECT +public: + Interactive(QObject *parent); + void redisplayPrompt(); + +private slots: + void displayPrompt(); + +private: + QFile _stdin; + QString _input; + void lineRead(); + ExitCode processLine(const QString &s); + ExitCode executeRegister(const QString &name, const QString &value); + ExitCode registerList(); + ExitCode variableList(); + ExitCode executeRawCommands(const QString &filename); + Address findRegisterAddress(const QString &name); + ExitCode start(); + static void signalHandler(int n); +}; + +} // namespace + +#endif diff --git a/src/piklab-prog/cli_prog_manager.cpp b/src/piklab-prog/cli_prog_manager.cpp new file mode 100644 index 0000000..472757a --- /dev/null +++ b/src/piklab-prog/cli_prog_manager.cpp @@ -0,0 +1,65 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "cli_prog_manager.h" + +#include "progs/base/generic_prog.h" +#include "progs/base/prog_group.h" +#include "progs/base/prog_config.h" +#include "progs/base/hardware_config.h" +#include "progs/base/generic_debug.h" + +//---------------------------------------------------------------------------- +Port::Description Programmer::CliManager::portDescription() const +{ + Log::Base *log = const_cast(static_cast(this)); + if ( CLI::_port.isEmpty() ) { + log->log(Log::LineType::Information, i18n("Using port from configuration file.")); + return Programmer::GroupConfig::portDescription(group()); + } + if ( CLI::_port=="usb" ) return Port::Description(PortType::USB, QString::null); + PortType type = Port::findType(CLI::_port); + if ( type==PortType::Nb_Types ) { + log->log(Log::LineType::Warning, i18n("Could not find device \"%1\" as serial or parallel port. Will try to open as serial port.").arg(CLI::_port)); + type = PortType::Serial; + } + return Port::Description(type, CLI::_port); +} + +bool Programmer::CliManager::isTargetSelfPowered() const +{ + bool targetSelfPowered = ::Programmer::Manager::isTargetSelfPowered(); + if ( !CLI::_targetSelfPowered.isEmpty() ) targetSelfPowered = ( CLI::_targetSelfPowered=="true" ); + return targetSelfPowered; +} + +void Programmer::CliManager::createProgrammer(const Device::Data *data) +{ + HardwareDescription hd; + hd.port = portDescription(); + ::Hardware::Config *config = CLI::_progGroup->hardwareConfig(); + if (config) { + if ( CLI::_hardware.isEmpty() ) hd.name = config->currentHardware(hd.port.type); + else hd.name = CLI::_hardware; + } + delete config; + Manager::createProgrammer(data, hd); + if ( !CLI::_firmwareDir.isEmpty() ) _programmer->setFirmwareDirectory(CLI::_firmwareDir.path()); +} + +bool Programmer::CliManager::internalInitProgramming(bool debugging) +{ + if ( !Manager::internalInitProgramming(debugging) ) return false; + if ( _programmer->isActive() ) { + if ( !halt() ) return false; + } else if (debugging) { + if ( ::Debugger::manager->coff()==0 && !::Debugger::manager->init() ) log(Log::LineType::Warning, i18n("Starting debug session without COFF file (no source file information).")); + if ( !group().isSoftware() ) log(Log::LineType::Warning, i18n("Starting debugging session with device memory in an unknown state. You may want to reprogram the device.")); + } + return true; +} diff --git a/src/piklab-prog/cli_prog_manager.h b/src/piklab-prog/cli_prog_manager.h new file mode 100644 index 0000000..27775a4 --- /dev/null +++ b/src/piklab-prog/cli_prog_manager.h @@ -0,0 +1,38 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef CLI_PROG_MANAGER_H +#define CLI_PROG_MANAGER_H + +#include "progs/manager/prog_manager.h" +#include "cli_debug_manager.h" +#include "cmdline.h" + +namespace Programmer +{ +class CliManager : public Manager +{ +Q_OBJECT +public: + CliManager(QObject *parent) : Manager(parent), _state(Idle) {} + Port::Description portDescription() const; + virtual void createProgrammer(const Device::Data *data); + +private: + State _state; + + virtual const Group &group() const { return *CLI::_progGroup; } + virtual void setState(State state) { _state = state; } + virtual const Device::Data *device() const { return CLI::_device; } + virtual bool internalInitProgramming(bool debugging); + virtual bool isTargetSelfPowered() const; +}; + +} // namespace + +#endif diff --git a/src/piklab-prog/cli_purl.cpp b/src/piklab-prog/cli_purl.cpp new file mode 100644 index 0000000..2cd38a5 --- /dev/null +++ b/src/piklab-prog/cli_purl.cpp @@ -0,0 +1,29 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "common/global/purl.h" + +#include +#include + +bool PURL::Base::probablyExists() const +{ + QFileInfo fi(_url.path()); + return fi.exists(); +} + +bool PURL::Url::isDestinationUpToDate(FileType type) const +{ + if ( !(data().properties & Source) ) return true; + Url dest = toFileType(type); + QFileInfo sfi(_url.path()); + if ( !sfi.exists() ) return true; // source does not exists + QFileInfo dfi(dest._url.path()); + if ( !dfi.exists() ) return false; // destination does not exists + return sfi.lastModified() * + * * + * 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. * + ***************************************************************************/ +#include "cmdline.h" + +#if defined(HAVE_READLINE) +# include +# include +#else +# include +#endif +#include +#include + +#include "devices/list/device_list.h" +#include "devices/base/device_group.h" +#include "common/global/about.h" +#include "progs/base/prog_config.h" +#include "progs/base/hardware_config.h" +#include "devices/pic/pic/pic_memory.h" +#include "devices/pic/prog/pic_prog.h" +#include "progs/list/prog_list.h" +#include "common/cli/cli_log.h" +#include "cli_prog_manager.h" +#include "cli_debug_manager.h" + +//----------------------------------------------------------------------------- +const CLI::CommandData CLI::NORMAL_COMMAND_DATA[] = { + { "connect", NeedProgrammer | NeedDevice, + I18N_NOOP("Connect programmer.") }, + { "run", NeedProgrammer | NeedDevice, + I18N_NOOP("Run device (release reset).") }, + { "stop", NeedProgrammer | NeedDevice, + I18N_NOOP("Stop device (hold reset).") }, + { "program", NeedProgrammer | InputHex | NeedDevice, + I18N_NOOP("Program device memory: \"program \".") }, + { "verify", NeedProgrammer | InputHex | NeedDevice, + I18N_NOOP("Verify device memory: \"verify \".") }, + { "read", NeedProgrammer | OutputHex | NeedDevice, + I18N_NOOP("Read device memory: \"read \".") }, + { "erase", NeedProgrammer | NeedDevice, + I18N_NOOP("Erase device memory.") }, + { "blank_check", NeedProgrammer | NeedDevice, + I18N_NOOP("Blank check device memory.") }, + { "upload_firmware", NeedProgrammer | InputHex, + I18N_NOOP("Upload firmware to programmer: \"upload_firmware \".") }, + { 0, NoCommandProperty, 0 } +}; + +const KCmdLineOptions CLI::OPTIONS[] = { + { "r", 0, 0 }, + { "range ", I18N_NOOP("Memory range to operate on."), 0 }, + { "range-list", I18N_NOOP("Return the list of memory ranges."), 0 }, + KCmdLineLastOption +}; + +//----------------------------------------------------------------------------- +const Programmer::Group *CLI::_progGroup = 0; +const Device::Data *CLI::_device = 0; +HexBuffer::Format CLI::_format = HexBuffer::IHX32; +QString CLI::_port, CLI::_targetSelfPowered, CLI::_hardware; +PURL::Directory CLI::_firmwareDir; +PURL::Url CLI::_hexUrl, CLI::_coffUrl; +Device::Memory *CLI::_memory = 0; +CLI::Interactive *CLI::_interactive = 0; + +//----------------------------------------------------------------------------- +CLI::ExitCode CLI::Main::formatList() +{ + log(Log::LineType::Normal, i18n("Supported hex file formats:")); + for (uint i=0; iname())); + return OK; +} + +CLI::ExitCode CLI::Main::hardwareList() +{ + log(Log::LineType::Normal, i18n("Supported hardware configuration for programmers:")); + Programmer::Lister::ConstIterator it; + for (it=Programmer::lister().begin(); it!=Programmer::lister().end(); it++) { + ::Hardware::Config *config = it.data()->hardwareConfig(); + if ( config==0 ) continue; + FOR_EACH(PortType, type) { + if ( !it.data()->isPortSupported(type) ) continue; + log(Log::LineType::Normal, "-" + QString(it.data()->name()) + " [" + type.label() + "]:"); + QStringList list = config->hardwareNames(type); + for (uint k=0; k devices; + if ( _progGroup==0 ) { + log(Log::LineType::Normal, i18n("Supported devices:")); + devices = Programmer::lister().supportedDevices(); + } else { + log(Log::LineType::Normal, i18n("Supported devices for \"%1\":").arg(_progGroup->label())); + devices = _progGroup->supportedDevices(); + } + qHeapSort(devices); + QString s; + for (uint i=0; ilabel())); + else log(Log::LineType::Normal, i18n("Detected ports:")); + FOR_EACH(PortType, type) { + if ( _progGroup && !_progGroup->isPortSupported(type) ) continue; + QString s = "- " + type.label() + ":"; + if ( !Port::isAvailable(type) ) { + log(Log::LineType::Normal, s + i18n(" support disabled.")); + continue; + } + QStringList list = Port::probedDeviceList(type); + if ( list.count()==0 ) log(Log::LineType::Normal, s + i18n(" no port detected.")); + else { + log(Log::LineType::Normal, s); + for (uint k=0; k(data->properties); + if ( _device==0 && (properties & NeedDevice) ) return errorExit(i18n("Device not specified."), ARG_ERROR); + if ( _progGroup==0 && (properties & NeedProgrammer) ) return errorExit(i18n("Programmer not specified."), ARG_ERROR); + + if ( (properties & InputHex) || (properties & OutputHex) ) { + if ( _hexUrl.isEmpty() ) return errorExit(i18n("Hex filename not specified."), ARG_ERROR); + //if ( !_filename.isLocalFile() ) return errorExit(i18n("Only local files are supported."), ARG_ERROR); + PURL::File file(_hexUrl, *_view); + delete _memory; + _memory = 0; + if ( properties & NeedDevice ) _memory = _device->group().createMemory(*_device); + if ( properties & InputHex ) { + if (_memory) { + if ( !file.openForRead() ) return FILE_ERROR; + QStringList errors, warnings; + Device::Memory::WarningTypes warningTypes; + if ( !_memory->load(file.stream(), errors, warningTypes, warnings) ) + return errorExit(i18n("Could not load hex file \"%1\".").arg(errors[0]), FILE_ERROR); + if ( warningTypes!=Device::Memory::NoWarning ) + log(Log::LineType::Warning, i18n("Hex file seems incompatible with device \"%1\".").arg(warnings.join(" "))); + } + } else if ( properties & OutputHex ) { + if ( !_force && _hexUrl.exists() ) return errorExit(i18n("Output hex filename already exists."), FILE_ERROR); + } + } + + return OK; +} + +CLI::Main::Main() + : MainBase(HasForce | HasInteractiveMode) +{ + _range = new Device::MemoryRange; + Programmer::manager = new Programmer::CliManager(this); + Programmer::manager->setView(_view); + Debugger::manager = new Debugger::CliManager; +} + +CLI::Main::~Main() +{ + delete _range; +} + +CLI::ExitCode CLI::Main::list(const QString &command) +{ + if ( MainBase::list(command)==OK ) return OK; + if ( command=="format-list" ) return formatList(); + if ( command=="programmer-list" ) return programmerList(); + if ( command=="hardware-list" ) return hardwareList(); + if ( command=="port-list" ) return portList(); + if ( command=="device-list" ) return deviceList(); + if ( command=="range-list" ) return rangeList(); + Q_ASSERT(false); + return OK; +} + +CLI::ExitCode CLI::Main::prepareRun(bool &interactive) +{ + // argument + if ( _args->count()>1 ) return errorExit(i18n("Too many arguments."), ARG_ERROR); + if ( _args->count()==1 ) { + PURL::Url url(_args->url(0)); + ExitCode code = OK; + if ( url.fileType()==PURL::Hex ) code = executeSetCommand("hex", url.filepath()); + else if ( url.fileType()==PURL::Coff ) code = executeSetCommand("coff", url.filepath()); + else return errorExit(i18n("Argument file type not recognized."), ARG_ERROR); + if ( code!=OK ) return code; + } + + interactive = _args->isSet("cli"); + if (interactive) { + _interactive = new Interactive(this); + log(Log::LineType::Normal, i18n("Interactive mode: type help for help")); + log(Log::LineType::Normal, QString::null); +#if QT_VERSION<0x040000 + return ExitCode(qApp->exec()); +#else + return ExitCode(QCoreApplication::exec()); +#endif + } + + // range + if ( _args->isSet("range-list") ) return list("range-list"); + ExitCode code = extractRange(_args->getOption("range")); + if ( code!=OK ) return code; + + return OK; +} + +CLI::ExitCode CLI::Main::extractRange(const QString &range) +{ + delete _range; + _range = 0; + if ( !range.isEmpty() ) { + if ( _device==0 ) return errorExit(i18n("Cannot specify range without specifying device."), ARG_ERROR); + if ( _device->group().name()=="pic" ) { + FOR_EACH(Pic::MemoryRangeType, type) { + if ( range!=type.key() ) continue; + if ( !static_cast(_device)->isReadable(type) ) return errorExit(i18n("Memory range not present on this device."), ARG_ERROR); + _range = new Pic::MemoryRange(type); + break; + } + if ( _range==0 ) return errorExit(i18n("Memory range not recognized."), ARG_ERROR); + } else return errorExit(i18n("Memory ranges are not supported for the specified device."), ARG_ERROR); + } else _range = new Device::MemoryRange; + return OK; +} + +CLI::ExitCode CLI::Main::executeCommand(const QString &command) +{ + Programmer::Base *programmer = Programmer::manager->programmer(); + if ( command=="connect" ) return (Programmer::manager->connectDevice() ? OK : EXEC_ERROR); + if ( command=="disconnect" ) { + if ( programmer==0 || programmer->state()==Programmer::NotConnected ) + return okExit(i18n("Programmer is already disconnected.")); + return (Programmer::manager->disconnectDevice() ? OK : EXEC_ERROR); + } + if ( command=="run" ) { + if ( programmer && programmer->state()==Programmer::Running ) return okExit(i18n("Programmer is already running.")); + return (Programmer::manager->run() ? OK : EXEC_ERROR); + } + if ( command=="stop" ) { + if ( programmer && programmer->state()!=Programmer::Running ) return okExit(i18n("Programmer is already stopped.")); + return (Programmer::manager->halt() ? OK : EXEC_ERROR); + } + if ( command=="step" ) { + if ( !_progGroup->isDebugger() ) return errorExit(i18n("Debugging is not supported for specified programmer."), NOT_SUPPORTED_ERROR); + if ( programmer && programmer->state()==Programmer::Running ) return (Programmer::manager->halt() ? OK : EXEC_ERROR); + return (Programmer::manager->step() ? OK : EXEC_ERROR); + } + if ( command=="start" ) { + if ( !_progGroup->isDebugger() ) return errorExit(i18n("Debugging is not supported for specified programmer."), NOT_SUPPORTED_ERROR); + return (Programmer::manager->restart() ? OK : EXEC_ERROR); + } + if ( command=="program" ) { + if ( _progGroup->isSoftware() ) return errorExit(i18n("Reading device memory not supported for specified programmer."), NOT_SUPPORTED_ERROR); + return (Programmer::manager->program(*_memory, *_range) ? OK : EXEC_ERROR); + } + if ( command=="verify" ) { + if ( _progGroup->isSoftware() ) + return errorExit(i18n("Reading device memory not supported for specified programmer."), NOT_SUPPORTED_ERROR); + return (Programmer::manager->verify(*_memory, *_range) ? OK : EXEC_ERROR); + } + if ( command=="read" ) { + if ( _progGroup->isSoftware() ) + return errorExit(i18n("Reading device memory not supported for specified programmer."), NOT_SUPPORTED_ERROR); + if ( !Programmer::manager->read(*_memory, *_range) ) return EXEC_ERROR; + PURL::File file(_hexUrl, *_view); + if ( !file.openForWrite() ) return FILE_ERROR; + if ( !_memory->save(file.stream(), _format) ) + return errorExit(i18n("Error while writing file \"%1\".").arg(_hexUrl.pretty()), FILE_ERROR); + return OK; + } + if ( command=="erase" ) { + if ( _progGroup->isSoftware() ) + return errorExit(i18n("Erasing device memory not supported for specified programmer."), NOT_SUPPORTED_ERROR); + return (Programmer::manager->erase(*_range) ? OK : EXEC_ERROR); + } + if ( command=="blank_check" ) { + if ( _progGroup->isSoftware() ) + return errorExit(i18n("Blank-checking device memory not supported for specified programmer."), NOT_SUPPORTED_ERROR); + return (Programmer::manager->blankCheck(*_range) ? OK : EXEC_ERROR); + } + if ( command=="upload_firmware" ) { + if ( !(_progGroup->properties() & ::Programmer::CanUploadFirmware) ) + return errorExit(i18n("Uploading firmware is not supported for the specified programmer."), NOT_SUPPORTED_ERROR); + if ( Programmer::manager->programmer()==0 ) Programmer::manager->createProgrammer(0); // no device specified + return (Programmer::manager->programmer()->uploadFirmware(_hexUrl) ? OK : EXEC_ERROR); + } + Q_ASSERT(false); + return EXEC_ERROR; +} + +CLI::ExitCode CLI::Main::checkProgrammer() +{ + if ( _progGroup==0 ) return OK; + if ( _progGroup->isSoftware() && _progGroup->supportedDevices().isEmpty() ) + return errorExit(i18n("Please check installation of selected software debugger."), NOT_SUPPORTED_ERROR); + if ( _device && !_progGroup->isSupported(_device->name()) ) + return errorExit(i18n("The selected device \"%1\" is not supported by the selected programmer.").arg(_device->name()), NOT_SUPPORTED_ERROR); + if ( !_hardware.isEmpty() ) { + ::Hardware::Config *config = _progGroup->hardwareConfig(); + Port::Description pd = static_cast(Programmer::manager)->portDescription(); + bool ok = (config==0 || config->hardwareNames(pd.type).contains(_hardware)); + delete config; + if ( !ok ) return errorExit(i18n("The selected programmer does not supported the specified hardware configuration (\"%1\").").arg(_hardware), NOT_SUPPORTED_ERROR); + } + return OK; +} + +CLI::ExitCode CLI::Main::executeSetCommand(const QString &property, const QString &value) +{ + if ( property=="programmer" ) { + _progGroup = 0; + if ( value.isEmpty() ) return OK; + _progGroup = Programmer::lister().group(value.lower()); + if (_progGroup) return checkProgrammer(); + return errorExit(i18n("Unknown programmer \"%1\".").arg(value.lower()), ARG_ERROR); + } + if ( property=="hardware" ) { _hardware = value; return OK; } + if ( property=="device" || property=="processor" ) { + if ( value.isEmpty() ) { + _device = 0; + return OK; + } + QString s = value.upper(); + _device = Device::lister().data(s); + Debugger::manager->updateDevice(); + if ( _device==0 ) return errorExit(i18n("Unknown device \"%1\".").arg(s), ARG_ERROR); + Debugger::manager->init(); + return checkProgrammer(); + } + if ( property=="format" ) { + if ( value.isEmpty() ) { + _format = HexBuffer::IHX32; + return OK; + } + QString s = value.lower(); + for (uint i=0; iinit() ) return ARG_ERROR; + return OK; + } + return errorExit(i18n("Unknown property \"%1\"").arg(property), ARG_ERROR); +} + +QString CLI::Main::executeGetCommand(const QString &property) +{ + if ( property=="programmer" ) { + if ( _progGroup==0 ) return i18n(""); + return _progGroup->name(); + } + if ( property=="hardware" ) { + if ( !_hardware.isEmpty() ) return _hardware; + if ( _progGroup==0 ) return i18n(""); + Port::Description pd = static_cast(Programmer::manager)->portDescription(); + ::Hardware::Config *config = _progGroup->hardwareConfig(); + if (config) return config->currentHardware(pd.type) + " " + i18n(""); + delete config; + return i18n(""); + } + if ( property=="device" || property=="processor" ) { + if ( _device==0 ) return i18n(""); + return _device->name(); + } + if ( property=="format" ) return HexBuffer::FORMATS[_format]; + if ( property=="port" ) { + if ( !_port.isEmpty() ) return _port; + if ( _progGroup==0 ) return i18n(""); + Port::Description pd = Programmer::GroupConfig::portDescription(*_progGroup); + QString s = pd.type.key(); + if (pd.type.data().withDevice) s += " (" + pd.device + ")"; + return s + " " + i18n(""); + } + if ( property=="firmware-dir" ) { + if ( !_firmwareDir.isEmpty() ) return _firmwareDir.pretty(); + if ( _progGroup==0 ) return i18n(""); + return Programmer::GroupConfig::firmwareDirectory(*_progGroup) + " " + i18n(""); + } + if ( property=="target-self-powered" ) { + if ( !_targetSelfPowered.isEmpty() ) return _targetSelfPowered; + return QString(readConfigEntry(Programmer::Config::TargetSelfPowered).toBool() ? "true" : "false") + " " + i18n(""); + } + if ( property=="hex" ) { + if ( !_hexUrl.isEmpty() ) return _hexUrl.pretty(); + return i18n(""); + } + if ( property=="coff" ) { + if ( !_coffUrl.isEmpty() ) return _coffUrl.pretty(); + return i18n(""); + } + log(Log::LineType::SoftError, i18n("Unknown property \"%1\"").arg(property)); + return QString::null; +} + +//----------------------------------------------------------------------------- +int main(int argc, char **argv) +{ + CLI::Main main; + Piklab::AboutData *about = new Piklab::AboutData("piklab-prog", I18N_NOOP("Piklab Programmer Utility"), I18N_NOOP("Command-line programmer/debugger.")); + CLI::OptionList list = main.optionList(I18N_NOOP("Hex filename for programming.")); + Piklab::init(about, argc, argv, false, list.ptr()); + return main.doRun(); +} diff --git a/src/piklab-prog/cmdline.h b/src/piklab-prog/cmdline.h new file mode 100644 index 0000000..03d4091 --- /dev/null +++ b/src/piklab-prog/cmdline.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef CMDLINE_H +#define CMDLINE_H + +#include "common/cli/cli_main.h" +#include "cli_interactive.h" +#include "common/global/purl.h" +#include "devices/base/hex_buffer.h" +namespace Device { class Data; class Memory; class MemoryRange; } +namespace Programmer { class Base; class Group; } + +namespace CLI +{ +class Main : public MainBase +{ +Q_OBJECT +public: + Main(); + virtual ~Main(); + virtual ExitCode prepareRun(bool &interactive); + virtual ExitCode prepareCommand(const QString &command); + virtual ExitCode executeCommand(const QString &command); + virtual ExitCode executeSetCommand(const QString &property, const QString &value); + virtual QString executeGetCommand(const QString &property); + virtual ExitCode list(const QString &command); + ExitCode extractRange(const QString &range); + +private: + Device::MemoryRange *_range; + + ExitCode formatList(); + ExitCode programmerList(); + ExitCode hardwareList(); + ExitCode deviceList(); + ExitCode portList(); + ExitCode rangeList(); + ExitCode checkProgrammer(); +}; + +extern const Programmer::Group *_progGroup; +extern QString _hardware; +extern const Device::Data *_device; +extern HexBuffer::Format _format; +extern QString _port, _targetSelfPowered; +extern PURL::Directory _firmwareDir; +extern PURL::Url _hexUrl, _coffUrl; +extern Device::Memory *_memory; +extern Interactive *_interactive; + +} // namespace + +#endif diff --git a/src/piklab-prog/piklab-prog.pro b/src/piklab-prog/piklab-prog.pro new file mode 100644 index 0000000..bd70cb2 --- /dev/null +++ b/src/piklab-prog/piklab-prog.pro @@ -0,0 +1,32 @@ +STOPDIR = ../.. +include($${STOPDIR}/app.pro) + +TARGET = piklab-prog +HEADERS += cli_prog_manager.h cli_debug_manager.h cli_interactive.h cmdline.h +SOURCES += cli_prog_manager.cpp cli_debug_manager.cpp cli_interactive.cpp cmdline.cpp +LIBS += ../progs/manager/libprogmanager.a ../progs/list/libprogslist.a \ + ../progs/picdem_bootloader/base/libpicdem_bootloader.a ../progs/pickit2_bootloader/base/libpickit2_bootloader.a \ + ../progs/tbl_bootloader/base/libtbl_bootloader.a ../progs/bootloader/base/libbootloader.a \ + ../progs/pickit2v2/base/libpickit2v2.a \ + ../progs/gpsim/base/libgpsim.a \ + ../progs/psp/base/libpsp.a ../progs/pickit1/base/libpickit1.a \ + ../progs/pickit2/base/libpickit2.a ../progs/icd1/base/libicd1.a \ + ../progs/icd2/base/libicd2.a \ + ../progs/icd2/icd2_data/libicd2data.a ../progs/direct/base/libdirectprog.a \ + ../devices/pic/prog/libpicprog.a ../devices/mem24/prog/libmem24prog.a \ + ../progs/base/libprogbase.a ../common/port/libport.a ../coff/base/libcoff.a \ + ../devices/list/libdevicelist.a \ + ../devices/mem24/mem24/libmem24.a ../devices/mem24/xml_data/libmem24xml.a \ + ../devices/mem24/base/libmem24base.a \ + ../devices/pic/pic/libpic.a ../devices/pic/xml_data/libpicxml.a \ + ../devices/pic/base/libpicbase.a \ + ../devices/base/libdevicebase.a \ + ../common/cli/libcli.a ../common/global/libglobal.a \ + ../common/nokde/libnokde.a ../common/common/libcommon.a +contains(DEFINES, HAVE_USB) { + unix:LIBS += -lusb + win32:LIBS += $${LIBUSB_PATH}\lib\gcc\libusb.a +} +contains(DEFINES, HAVE_READLINE) { + unix:LIBS += -lhistory -lreadline -lcurses +} diff --git a/src/piklab-test/Makefile.am b/src/piklab-test/Makefile.am new file mode 100644 index 0000000..7159e70 --- /dev/null +++ b/src/piklab-test/Makefile.am @@ -0,0 +1,3 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +SUBDIRS = base misc save_load_memory checksum generators diff --git a/src/piklab-test/base/Makefile.am b/src/piklab-test/base/Makefile.am new file mode 100644 index 0000000..da6c4ba --- /dev/null +++ b/src/piklab-test/base/Makefile.am @@ -0,0 +1,5 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libtest.la +libtest_la_SOURCES = main_test.cpp device_test.cpp generator_check.cpp diff --git a/src/piklab-test/base/device_test.cpp b/src/piklab-test/base/device_test.cpp new file mode 100644 index 0000000..9346a13 --- /dev/null +++ b/src/piklab-test/base/device_test.cpp @@ -0,0 +1,54 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "device_test.h" + +#include "devices/base/device_group.h" +#include "devices/list/device_list.h" + +void DeviceTest::checkArguments() +{ + if ( _args->count()==1 ) { + _device = QString(_args->arg(0)).upper(); + if ( !Device::lister().isSupported(_device) ) qFatal("Specified device \"%s\" not supported.", _device.latin1()); + printf("Testing only %s\n", _device.latin1()); + } +} + +bool DeviceTest::execute() +{ + Device::Lister::ConstIterator it; + for (it=Device::lister().begin(); it!=Device::lister().end(); ++it) { + Group::Base::ConstIterator git; + for (git=it.data()->begin(); git!=it.data()->end(); ++git) { + const Device::Data &data = *git.data().data; + if ( !_device.isEmpty() && data.name()!=_device ) continue; + _message = data.name(); + if ( skip(data) ) { + skipped(); + printf("S"); + } else { + if ( init(data) ) { + printf("*"); + execute(data); + } else printf("S"); + cleanup(data); + } + fflush(stdout); + } + } + return true; +} + +Piklab::OptionList DeviceTest::optionList() const +{ + Piklab::OptionList optionList; + const KCmdLineOptions OPTION = { "+[device]", "Only check the specified device", 0 }; + optionList.append(OPTION); + return optionList; +} diff --git a/src/piklab-test/base/device_test.h b/src/piklab-test/base/device_test.h new file mode 100644 index 0000000..24447ed --- /dev/null +++ b/src/piklab-test/base/device_test.h @@ -0,0 +1,32 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef DEVICE_TEST_H +#define DEVICE_TEST_H + +#include "piklab-test/base/main_test.h" +namespace Device { class Data; } + +class DeviceTest : public Test +{ +public: + virtual Piklab::OptionList optionList() const; + +protected: + virtual bool execute(); + virtual bool skip(const Device::Data &) const { return false; } + virtual bool init(const Device::Data &) { return true; } // returns false if skipped or failed + virtual bool execute(const Device::Data &data) = 0; // returns false if skipped or failed + virtual void cleanup(const Device::Data &) {} + virtual void checkArguments(); + +private: + QString _device; +}; + +#endif diff --git a/src/piklab-test/base/generator_check.cpp b/src/piklab-test/base/generator_check.cpp new file mode 100644 index 0000000..68ad2c5 --- /dev/null +++ b/src/piklab-test/base/generator_check.cpp @@ -0,0 +1,288 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "generator_check.h" + +#include "devices/base/device_group.h" +#include "devices/pic/pic/pic_memory.h" +#include "tools/gputils/gputils.h" +#include "tools/gputils/gputils_generator.h" +#include "tools/sdcc/sdcc.h" +#include "tools/sdcc/sdcc_generator.h" +#include "devices/list/device_list.h" + +//---------------------------------------------------------------------------- +GeneratorCheckHelper::GeneratorCheckHelper() + : _cprocess(0), _lprocess(0), _generator(0) +{} + +GeneratorCheckHelper::~GeneratorCheckHelper() +{ + delete _generator; +} + +void GeneratorCheckHelper::cleanup() +{ + delete _lprocess; + _lprocess = 0; + delete _cprocess; + _cprocess = 0; +} + +//---------------------------------------------------------------------------- +GeneratorCheck::GeneratorCheck(GeneratorCheckHelper *helper) + : _helper(helper), _fdest(0), _fhex(0), _memory1(0) +{ + _view = new CLI::View; +} + +GeneratorCheck::~GeneratorCheck() +{ + delete _view; + delete _helper; +} + +void GeneratorCheck::runTest() +{ + _helper->initSupported(); + DeviceTest::runTest(); +} + +bool GeneratorCheck::init(const Device::Data &data) +{ + PURL::Url dest(PURL::Directory::current(), "test.xxx"); + dest = dest.toFileType(_helper->sourceFileType()); + _fdest = new PURL::File(dest, *_view); + _helper->init(data); + PURL::Url hex(PURL::Directory::current(), "test.hex"); + _fhex = new PURL::File(hex, *_view); + _memory1 = static_cast(data.group().createMemory(data)); + return true; +} + +bool GeneratorCheck::skip(const Device::Data &data) const +{ + return !_helper->isSupported(data); +} + +void GeneratorCheck::cleanup(const Device::Data &) +{ + delete _memory1; + _memory1 = 0; + delete _fhex; + _fhex = 0; +// _fdest->remove(); + delete _fdest; + _fdest = 0; + _helper->cleanup(); +} + +bool GeneratorCheck::execute(const Device::Data &data) +{ + // create asm file from template source code + if ( !_fdest->openForWrite() ) TEST_FAILED_RETURN(""); + _fdest->appendText(_source); + _fdest->close(); + + // run compiler + Process::State state = Process::runSynchronously(*_helper->_cprocess, Process::Start, 2000); // 2s timeout + if ( state!=Process::Exited ) TEST_FAILED_RETURN("Error while running compilation") + if ( _helper->_cprocess->exitCode()!=0 ) TEST_FAILED_RETURN(QString("Error in compilation for %1:\n%2%3").arg(data.name()).arg(_helper->_cprocess->sout()+_helper->_cprocess->serr()).arg(QString::null)) + + // run linker + if (_helper->_lprocess) { + state = Process::runSynchronously(*_helper->_lprocess, Process::Start, 2000); // 2s timeout + if ( state!=Process::Exited ) TEST_FAILED_RETURN("Error while running linking") + if ( _helper->_lprocess->exitCode()!=0 ) TEST_FAILED_RETURN(QString("Error in linking for %1:\n%2%3").arg(data.name()).arg(_helper->_lprocess->sout()+_helper->_lprocess->serr()).arg(QString::null)) + } + + // load hex file + if ( !_fhex->openForRead() ) TEST_FAILED_RETURN("") + QStringList errors, warnings; + Device::Memory::WarningTypes warningTypes; + if ( !_memory1->load(_fhex->stream(), errors, warningTypes, warnings) ) TEST_FAILED_RETURN(QString("Error loading hex into memory: %1").arg(errors.join(" "))) + //if ( warningTypes!=Device::Memory::NoWarning ) TEST_FAILED(QString("Warning loading hex into memory: %1").arg(warnings.join(" "))) + + TEST_PASSED + return true; +} + +//---------------------------------------------------------------------------- +bool ConfigGeneratorCheck::init(const Device::Data &data) +{ + if ( !GeneratorCheck::init(data) ) return false; + _memory2 = static_cast(data.group().createMemory(data)); + return true; +} + +bool ConfigGeneratorCheck::execute(const Device::Data &data) +{ + // create configuration + const Pic::Config &config = static_cast(data).config(); + for (uint l=0; ; l++) { + // set config bits + bool ok = false; + for (uint i=0; isetConfigValue(cmask.name, cmask.values[l].name); + } + } + } + if ( !ok ) break; + + // create source code + PURL::SourceFamily sfamily = _helper->sourceFileType().data().sourceFamily; + PURL::ToolType ttype = sfamily.data().toolType; + SourceLine::List lines = _helper->generator()->includeLines(ttype, data); + lines += _helper->generator()->configLines(ttype, *_memory2, ok); + lines += _helper->configEndLines(); + _source = SourceLine::text(sfamily, lines, 2); + if (!ok) TEST_FAILED_RETURN("Config lines generation incomplete") + + if ( !GeneratorCheck::execute(data) ) return false; + + // check that config bits are the same + uint nbChars = static_cast(data).nbCharsWord(Pic::MemoryRangeType::Config); + for (uint i=0; iword(Pic::MemoryRangeType::Config, i); + BitValue word2 = _memory2->word(Pic::MemoryRangeType::Config, i); + if ( word1==word2 ) continue; + for (uint k=0; ksourceFileType().data().sourceFamily; + PURL::ToolType ttype = sfamily.data().toolType; + SourceLine::List lines = _helper->generator()->templateSourceFile(ttype, data, ok); + _source = SourceLine::text(sfamily, lines, 2); + if (!ok) TEST_FAILED_RETURN(QString("Incomplete template generator for %1").arg(data.name())) + return true; +} + +//---------------------------------------------------------------------------- +GPUtilsGeneratorCheckHelper::GPUtilsGeneratorCheckHelper() +{ + _generator = new GPUtils::SourceGenerator; +} + +void GPUtilsGeneratorCheckHelper::initSupported() +{ + Process::StringOutput p; + QStringList options; + options += "-l"; + p.setup("gpasm", options, false); + Process::runSynchronously(p, Process::Start, 2000); // 2s timeout + _supported = GPUtils::getSupportedDevices(p.sout()); +} + +bool GPUtilsGeneratorCheckHelper::init(const Device::Data &data) +{ + _cprocess = new Process::StringOutput; + QStringList options; + options = "-c"; + options += "-p" + GPUtils::toDeviceName(data.name()); + options += "test.asm"; + _cprocess->setup("gpasm", options, false); + _lprocess = new Process::StringOutput; + options = "-o"; + options += "test.hex"; + options += "test.o"; + _lprocess->setup("gplink", options, false); + return true; +} + +SourceLine::List GPUtilsGeneratorCheckHelper::configEndLines() const +{ + SourceLine::List lines; + lines.appendIndentedCode("end"); + return lines; +} + +//---------------------------------------------------------------------------- +SDCCGeneratorCheckHelper::SDCCGeneratorCheckHelper() +{ + _generator = new SDCC::SourceGenerator; +} + +void SDCCGeneratorCheckHelper::initSupported() +{ + PURL::Url url(PURL::Directory::current(), "test.c"); + Log::StringView view; + PURL::File file(url, view); + if ( file.openForWrite() ) file.appendText("void main(void) {}\n"); + file.close(); + _supported.clear(); + for (uint i=0; isetup("sdcc", options, false); + return true; +} + +SourceLine::List SDCCGeneratorCheckHelper::configEndLines() const +{ + SourceLine::List lines; + lines.appendIndentedCode("void main() {}"); + return lines; +} diff --git a/src/piklab-test/base/generator_check.h b/src/piklab-test/base/generator_check.h new file mode 100644 index 0000000..9ad426a --- /dev/null +++ b/src/piklab-test/base/generator_check.h @@ -0,0 +1,102 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef GPUTILS_GENERATOR_CHECK_H +#define GPUTILS_GENERATOR_CHECK_H + +#include "device_test.h" +#include "common/cli/cli_log.h" +#include "common/global/pfile.h" +#include "coff/base/disassembler.h" +#include "common/global/process.h" +namespace Pic { class Memory; } + +//---------------------------------------------------------------------------- +class GeneratorCheckHelper +{ +public: + GeneratorCheckHelper(); + virtual ~GeneratorCheckHelper(); + virtual void initSupported() = 0; + virtual bool init(const Device::Data &data) = 0; + void cleanup(); + bool isSupported(const Device::Data &data) const { return _supported.contains(&data); } + virtual PURL::FileType sourceFileType() const = 0; + const Tool::SourceGenerator *generator() const { return _generator; } + virtual SourceLine::List configEndLines() const = 0; + +protected: + QValueList _supported; + Process::StringOutput *_cprocess, *_lprocess; + Tool::SourceGenerator *_generator; + + friend class GeneratorCheck; +}; + +class GeneratorCheck : public DeviceTest +{ +public: + GeneratorCheck(GeneratorCheckHelper *helper); + virtual ~GeneratorCheck(); + virtual bool skip(const Device::Data &data) const; + virtual void runTest(); + virtual bool init(const Device::Data &data); + virtual bool execute(const Device::Data &data); + virtual void cleanup(const Device::Data &data); + +protected: + GeneratorCheckHelper *_helper; + CLI::View *_view; + PURL::File *_fdest, *_fhex; + Pic::Memory *_memory1; + QString _source; +}; + +//---------------------------------------------------------------------------- +class ConfigGeneratorCheck : public GeneratorCheck +{ +public: + ConfigGeneratorCheck(GeneratorCheckHelper *helper) : GeneratorCheck(helper), _memory2(0) {} + virtual bool init(const Device::Data &data); + virtual bool execute(const Device::Data &data); + virtual void cleanup(const Device::Data &data); + +private: + Pic::Memory *_memory2; +}; + +//---------------------------------------------------------------------------- +class TemplateGeneratorCheck : public GeneratorCheck +{ +public: + TemplateGeneratorCheck(GeneratorCheckHelper *helper) : GeneratorCheck(helper) {} + virtual bool init(const Device::Data &data); +}; + +//---------------------------------------------------------------------------- +class GPUtilsGeneratorCheckHelper : public GeneratorCheckHelper +{ +public: + GPUtilsGeneratorCheckHelper(); + virtual void initSupported(); + virtual bool init(const Device::Data &data); + virtual PURL::FileType sourceFileType() const { return PURL::AsmGPAsm; } + virtual SourceLine::List configEndLines() const; +}; + +//---------------------------------------------------------------------------- +class SDCCGeneratorCheckHelper : public GeneratorCheckHelper +{ +public: + SDCCGeneratorCheckHelper(); + virtual void initSupported(); + virtual bool init(const Device::Data &data); + virtual PURL::FileType sourceFileType() const { return PURL::CSource; } + virtual SourceLine::List configEndLines() const; +}; +#endif diff --git a/src/piklab-test/base/main_test.cpp b/src/piklab-test/base/main_test.cpp new file mode 100644 index 0000000..10d0414 --- /dev/null +++ b/src/piklab-test/base/main_test.cpp @@ -0,0 +1,32 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "main_test.h" + +//---------------------------------------------------------------------------- +Test::Test() + : _nbPassed(0), _nbFailed(0), _nbSkipped(0) +{} + +void Test::runTest() +{ + _args = KCmdLineArgs::parsedArgs(); + checkArguments(); + fflush(stdout); + execute(); + printf("\n"); + printf("RESULTS: %i PASSED / %i FAILED / %i SKIPPED \n", _nbPassed, _nbFailed, _nbSkipped); +} + +void Test::failed(const QString &message, const char *file, int line) +{ + _nbFailed++; + printf("\n"); + if ( !_message.isEmpty() ) printf("[%s]", _message.latin1()); + printf("FAILED in \"%s\" line #%i: %s\n", file, line, message.latin1()); +} diff --git a/src/piklab-test/base/main_test.h b/src/piklab-test/base/main_test.h new file mode 100644 index 0000000..601b779 --- /dev/null +++ b/src/piklab-test/base/main_test.h @@ -0,0 +1,51 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef MAIN_TEST_H +#define MAIN_TEST_H + +#include "common/global/about.h" + +//---------------------------------------------------------------------------- +#define TEST_SKIPPED_RETURN { skipped(); return false; } +#define TEST_FAILED_RETURN(message) { failed(message, __FILE__, __LINE__); return false; } +#define TEST_FAILED(message) { failed(message, __FILE__, __LINE__); } +#define TEST_PASSED { printf("."); fflush(stdout); passed(); } +#define TEST_MAIN(Type) \ + int main(int argc, char **argv) \ + { \ + Type *check = new Type; \ + Piklab::OptionList opt = check->optionList(); \ + Piklab::init(new Piklab::AboutData("test", 0, 0), argc, argv, false, opt.ptr()); \ + check->runTest(); \ + return 0; \ + } + +//---------------------------------------------------------------------------- +class Test +{ +public: + Test(); + virtual Piklab::OptionList optionList() const { return Piklab::OptionList(); } + virtual void runTest(); + +protected: + KCmdLineArgs *_args; + QString _message; + + void passed() { _nbPassed++; } + void failed(const QString &message, const char *file, int line); + void skipped() { _nbSkipped++; } + virtual bool execute() = 0; // returns false if failed or skipped + virtual void checkArguments() {} + +private: + uint _nbPassed, _nbFailed, _nbSkipped; +}; + +#endif diff --git a/src/piklab-test/checksum/Makefile.am b/src/piklab-test/checksum/Makefile.am new file mode 100644 index 0000000..ed7535d --- /dev/null +++ b/src/piklab-test/checksum/Makefile.am @@ -0,0 +1,18 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_PROGRAMS = checksum_check +OBJ = $(top_builddir)/src/piklab-test/base/libtest.la \ + $(top_builddir)/src/common/cli/libcli.la \ + $(top_builddir)/src/tools/gputils/libgputils.la \ + $(top_builddir)/src/coff/base/libcoff.la \ + $(top_builddir)/src/common/global/libglobal.la $(top_builddir)/src/devices/list/libdevicelistnoui.la \ + $(top_builddir)/src/devices/pic/pic/libpic.la $(top_builddir)/src/devices/pic/base/libpicbase.la \ + $(top_builddir)/src/devices/pic/xml_data/libpicxml.la \ + $(top_builddir)/src/devices/mem24/mem24/libmem24.la $(top_builddir)/src/devices/mem24/base/libmem24base.la \ + $(top_builddir)/src/devices/mem24/xml_data/libmem24xml.la \ + $(top_builddir)/src/devices/base/libdevicebase.la $(top_builddir)/src/common/common/libcommon.la +checksum_check_DEPENDENCIES = $(OBJ) +checksum_check_LDADD = $(OBJ) $(LIB_KIO) +checksum_check_LDFLAGS = $(all_libraries) $(KDE_RPATH) +checksum_check_SOURCES = checksum_check.cpp diff --git a/src/piklab-test/checksum/checksum_check.cpp b/src/piklab-test/checksum/checksum_check.cpp new file mode 100644 index 0000000..fdba104 --- /dev/null +++ b/src/piklab-test/checksum/checksum_check.cpp @@ -0,0 +1,116 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "checksum_check.h" + +#include "devices/base/device_group.h" + +//---------------------------------------------------------------------------- +bool ChecksumCheck::skip(const Device::Data &data) const +{ + return ( data.group().name()!="pic" ); +} + +bool ChecksumCheck::init(const Device::Data &data) +{ + _memory = static_cast(data.group().createMemory(data)); + return true; +} + +void ChecksumCheck::cleanup(const Device::Data &) +{ + delete _memory; + _memory = 0; +} + +void ChecksumCheck::setProtection(const Pic::Data &data, const Pic::Checksum::Data &cdata, + const QString &maskName, const QString &valueName) +{ + const Pic::Protection &protection = data.config().protection(); + if ( !maskName.isEmpty() && !valueName.isEmpty() ) _memory->setConfigValue(maskName, valueName); + if ( !valueName.isEmpty() ) _memory->setUserIdToUnprotectedChecksum(); + for (uint i=0; ivalues.count()-1; k>=0; k--) { + if ( mask->values[k].name.isEmpty() ) continue; + if ( protection.isNoneProtectedValueName(mask->values[k].name) ) continue; + _memory->setConfigValue(pmName, mask->values[k].name); + break; + } + } + if ( !cdata.bbsize.isEmpty() ) _memory->setConfigValue(protection.bootSizeMaskName(), cdata.bbsize); +} + +bool ChecksumCheck::checkChecksum(BitValue checksum, const QString &label) +{ + BitValue c = _memory->checksum(); + if ( c!=checksum ) TEST_FAILED_RETURN(QString("%1 %2/%3").arg(label).arg(toHexLabel(c, 4)).arg(toHexLabel(checksum, 4))) + return true; +} + +void ChecksumCheck::checkChecksum(const Pic::Data &pdata, const QString &maskName, const QString &valueName, bool &ok) +{ + if ( !pdata.checksums().contains(valueName) ) { + const Pic::Config::Mask *mask = pdata.config().findMask(maskName); + QString label = valueName + (mask ? "/" + mask->name : QString::null); + printf("Missing checksum for \"%s\"", label.latin1()); + return; + } + const Pic::Checksum::Data &cdata = pdata.checksums()[valueName]; + _memory->clear(); + setProtection(pdata, cdata, maskName, valueName); + if ( !checkChecksum(cdata.blankChecksum, maskName + ":" + valueName + "/" + "blank") ) ok = false; + _memory->checksumCheckFill(); + setProtection(pdata, cdata, maskName, valueName); + if ( !checkChecksum(cdata.checkChecksum, maskName + ":" + valueName + "/" + "check") ) ok = false; +} + +bool ChecksumCheck::execute(const Device::Data &data) +{ + const Pic::Data &pdata = static_cast(data); + if ( data.name()=="18C601" || data.name()=="18C801" ) TEST_PASSED; + if ( pdata.checksums().isEmpty() ) TEST_FAILED_RETURN("No checksum data"); + bool ok = true; + const Pic::Protection &protection = pdata.config().protection(); + switch ( protection.family() ) { + case Pic::Protection::NoProtection: + checkChecksum(pdata, QString::null, QString::null, ok); + break; + case Pic::Protection::BasicProtection: { + QString maskName = protection.maskName(Pic::Protection::ProgramProtected, Pic::MemoryRangeType::Code); + const Pic::Config::Mask *mask = pdata.config().findMask(maskName); + Q_ASSERT(mask); + for (uint i=0; ivalues.count(); i++) { + QString valueName = mask->values[i].name; + if ( valueName.isEmpty() ) continue; // invalid value + checkChecksum(pdata, maskName, valueName, ok); + } + break; + } + case Pic::Protection::CodeGuard: + checkChecksum(pdata, "GSSEC", "Off", ok); + checkChecksum(pdata, "GSSEC", "High Security", ok); + break; + case Pic::Protection::BlockProtection: { + const QMap &cmap = pdata.checksums(); + QMap::const_iterator it; + for (it=cmap.begin(); it!=cmap.end(); ++it) + checkChecksum(pdata, QString::null, it.key(), ok); + break; + } + case Pic::Protection::Nb_Families: Q_ASSERT(false); break; + } + + if ( !ok ) return false; + TEST_PASSED + return true; +} + +//---------------------------------------------------------------------------- +TEST_MAIN(ChecksumCheck) diff --git a/src/piklab-test/checksum/checksum_check.h b/src/piklab-test/checksum/checksum_check.h new file mode 100644 index 0000000..6483984 --- /dev/null +++ b/src/piklab-test/checksum/checksum_check.h @@ -0,0 +1,35 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef CHECKSUM_CHECK_H +#define CHECKSUM_CHECK_H + +#include "piklab-test/base/device_test.h" +#include "common/cli/cli_log.h" +#include "common/global/pfile.h" +#include "devices/pic/pic/pic_memory.h" + +class ChecksumCheck : public DeviceTest +{ +public: + ChecksumCheck() : _memory(0) {} + virtual bool skip(const Device::Data &data) const; + virtual bool init(const Device::Data &data); + virtual bool execute(const Device::Data &data); + virtual void cleanup(const Device::Data &data); + +private: + Pic::Memory *_memory; + + void setProtection(const Pic::Data &data, const Pic::Checksum::Data &cdata, + const QString &maskName, const QString &valueName); + bool checkChecksum(BitValue checksum, const QString &label); + void checkChecksum(const Pic::Data &data, const QString &maskName, const QString &valueName, bool &ok); +}; + +#endif diff --git a/src/piklab-test/generators/Makefile.am b/src/piklab-test/generators/Makefile.am new file mode 100644 index 0000000..209e3e3 --- /dev/null +++ b/src/piklab-test/generators/Makefile.am @@ -0,0 +1,31 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_PROGRAMS = gputils_config_generator_check gputils_template_generator_check \ + sdcc_config_generator_check + +OBJ = $(top_builddir)/src/piklab-test/base/libtest.la \ + $(top_builddir)/src/common/cli/libcli.la \ + $(top_builddir)/src/tools/sdcc/libsdcc.la $(top_builddir)/src/tools/gputils/libgputils.la \ + $(top_builddir)/src/coff/base/libcoff.la \ + $(top_builddir)/src/common/global/libglobal.la $(top_builddir)/src/devices/list/libdevicelistnoui.la \ + $(top_builddir)/src/devices/pic/pic/libpic.la $(top_builddir)/src/devices/pic/base/libpicbase.la \ + $(top_builddir)/src/devices/pic/xml_data/libpicxml.la \ + $(top_builddir)/src/devices/mem24/mem24/libmem24.la $(top_builddir)/src/devices/mem24/base/libmem24base.la \ + $(top_builddir)/src/devices/mem24/xml_data/libmem24xml.la \ + $(top_builddir)/src/devices/base/libdevicebase.la $(top_builddir)/src/common/common/libcommon.la + +gputils_config_generator_check_DEPENDENCIES = $(OBJ) +gputils_config_generator_check_LDADD = $(OBJ) $(LIB_KIO) +gputils_config_generator_check_LDFLAGS = $(all_libraries) $(KDE_RPATH) +gputils_config_generator_check_SOURCES = gputils_config_generator_check.cpp + +gputils_template_generator_check_DEPENDENCIES = $(OBJ) +gputils_template_generator_check_LDADD = $(OBJ) $(LIB_KIO) +gputils_template_generator_check_LDFLAGS = $(all_libraries) $(KDE_RPATH) +gputils_template_generator_check_SOURCES = gputils_template_generator_check.cpp + +sdcc_config_generator_check_DEPENDENCIES = $(OBJ) +sdcc_config_generator_check_LDADD = $(OBJ) $(LIB_KIO) +sdcc_config_generator_check_LDFLAGS = $(all_libraries) $(KDE_RPATH) +sdcc_config_generator_check_SOURCES = sdcc_config_generator_check.cpp diff --git a/src/piklab-test/generators/gputils_config_generator_check.cpp b/src/piklab-test/generators/gputils_config_generator_check.cpp new file mode 100644 index 0000000..89b2e2e --- /dev/null +++ b/src/piklab-test/generators/gputils_config_generator_check.cpp @@ -0,0 +1,11 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "gputils_config_generator_check.h" + +TEST_MAIN(GPUtilsConfigGeneratorCheck) diff --git a/src/piklab-test/generators/gputils_config_generator_check.h b/src/piklab-test/generators/gputils_config_generator_check.h new file mode 100644 index 0000000..e330871 --- /dev/null +++ b/src/piklab-test/generators/gputils_config_generator_check.h @@ -0,0 +1,20 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef GPUTILS_CONFIG_GENERATOR_CHECK_H +#define GPUTILS_CONFIG_GENERATOR_CHECK_H + +#include "piklab-test/base/generator_check.h" + +class GPUtilsConfigGeneratorCheck : public ConfigGeneratorCheck +{ +public: + GPUtilsConfigGeneratorCheck() : ConfigGeneratorCheck(new GPUtilsGeneratorCheckHelper) {} +}; + +#endif diff --git a/src/piklab-test/generators/gputils_template_generator_check.cpp b/src/piklab-test/generators/gputils_template_generator_check.cpp new file mode 100644 index 0000000..fe5de54 --- /dev/null +++ b/src/piklab-test/generators/gputils_template_generator_check.cpp @@ -0,0 +1,11 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "gputils_template_generator_check.h" + +TEST_MAIN(GPUtilsTemplateGeneratorCheck) diff --git a/src/piklab-test/generators/gputils_template_generator_check.h b/src/piklab-test/generators/gputils_template_generator_check.h new file mode 100644 index 0000000..cc93eb8 --- /dev/null +++ b/src/piklab-test/generators/gputils_template_generator_check.h @@ -0,0 +1,20 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef GPUTILS_TEMPLATE_GENERATOR_CHECK_H +#define GPUTILS_TEMPLATE_GENERATOR_CHECK_H + +#include "piklab-test/base/generator_check.h" + +class GPUtilsTemplateGeneratorCheck : public TemplateGeneratorCheck +{ +public: + GPUtilsTemplateGeneratorCheck() : TemplateGeneratorCheck(new GPUtilsGeneratorCheckHelper) {} +}; + +#endif diff --git a/src/piklab-test/generators/sdcc_config_generator_check.cpp b/src/piklab-test/generators/sdcc_config_generator_check.cpp new file mode 100644 index 0000000..cad2f07 --- /dev/null +++ b/src/piklab-test/generators/sdcc_config_generator_check.cpp @@ -0,0 +1,11 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "sdcc_config_generator_check.h" + +TEST_MAIN(SDCCConfigGeneratorCheck) diff --git a/src/piklab-test/generators/sdcc_config_generator_check.h b/src/piklab-test/generators/sdcc_config_generator_check.h new file mode 100644 index 0000000..8438f0f --- /dev/null +++ b/src/piklab-test/generators/sdcc_config_generator_check.h @@ -0,0 +1,20 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef SDCC_CONFIG_GENERATOR_CHECK_H +#define SDCC_CONFIG_GENERATOR_CHECK_H + +#include "piklab-test/base/generator_check.h" + +class SDCCConfigGeneratorCheck : public ConfigGeneratorCheck +{ +public: + SDCCConfigGeneratorCheck() : ConfigGeneratorCheck(new SDCCGeneratorCheckHelper) {} +}; + +#endif diff --git a/src/piklab-test/misc/Makefile.am b/src/piklab-test/misc/Makefile.am new file mode 100644 index 0000000..e21c3d1 --- /dev/null +++ b/src/piklab-test/misc/Makefile.am @@ -0,0 +1,10 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_PROGRAMS = misc_check +OBJ = $(top_builddir)/src/piklab-test/base/libtest.la $(top_builddir)/src/common/cli/libcli.la \ + $(top_builddir)/src/common/global/libglobal.la $(top_builddir)/src/common/common/libcommon.la +misc_check_DEPENDENCIES = $(OBJ) +misc_check_LDADD = $(OBJ) $(LIB_KIO) +misc_check_LDFLAGS = $(all_libraries) $(KDE_RPATH) +misc_check_SOURCES = misc_check.cpp diff --git a/src/piklab-test/misc/misc_check.cpp b/src/piklab-test/misc/misc_check.cpp new file mode 100644 index 0000000..3f14287 --- /dev/null +++ b/src/piklab-test/misc/misc_check.cpp @@ -0,0 +1,99 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "misc_check.h" + +#include "common/global/purl.h" + +//---------------------------------------------------------------------------- +bool MiscCheck::execute() +{ + { + PURL::Url url = PURL::Url::fromPathOrUrl(QString::null); + if ( !url.isEmpty() ) TEST_FAILED("isEmpty"); + TEST_PASSED; + } + { + PURL::Url url = PURL::Url::fromPathOrUrl(""); + if ( !url.isEmpty() ) TEST_FAILED("isEmpty"); + TEST_PASSED; + } + { + PURL::Url url = PURL::Url::fromPathOrUrl("/"); + if ( url.isEmpty() ) TEST_FAILED("isEmpty"); + if ( url.isRelative() ) TEST_FAILED("isRelative"); + if ( !url.isLocal() ) TEST_FAILED("isLocal"); + if ( url.path()!="/" ) TEST_FAILED(""); + if ( url.filepath()!="/" ) TEST_FAILED(url.filepath()); + if ( url.unterminatedPath()!="/" ) TEST_FAILED(""); + if ( !url.filename().isEmpty() ) TEST_FAILED(url.filename()); + TEST_PASSED; + } + { + PURL::Url url = PURL::Url::fromPathOrUrl("test"); + if ( url.isEmpty() ) TEST_FAILED("isEmpty"); + if ( !url.isRelative() ) TEST_FAILED("isRelative"); + if ( !url.isLocal() ) TEST_FAILED("isLocal"); + if ( url.filename()!="test" ) TEST_FAILED(url.filename()); + TEST_PASSED; + } + { + PURL::Url url = PURL::Url::fromPathOrUrl("/test"); + if ( url.isEmpty() ) TEST_FAILED("isEmpty"); + if ( url.isRelative() ) TEST_FAILED("isRelative"); + if ( !url.isLocal() ) TEST_FAILED("isLocal"); + if ( url.path()!="/" ) TEST_FAILED(""); + if ( url.unterminatedPath()!="/" ) TEST_FAILED(""); + if ( url.filepath()!="/test" ) TEST_FAILED(url.filepath()); + if ( url.filename()!="test" ) TEST_FAILED(url.filename()); + TEST_PASSED; + } + { + PURL::Url url = PURL::Url::fromPathOrUrl("/test/"); + if ( url.isEmpty() ) TEST_FAILED("isEmpty"); + if ( url.isRelative() ) TEST_FAILED("isRelative"); + if ( !url.isLocal() ) TEST_FAILED("isLocal"); + if ( url.path()!="/test/" ) TEST_FAILED(""); + if ( url.unterminatedPath()!="/test" ) TEST_FAILED(""); + if ( url.filepath()!="/test/" ) TEST_FAILED(url.filepath()); + if ( !url.filename().isEmpty() ) TEST_FAILED(url.filename()); + TEST_PASSED; + } + { + PURL::Url url = PURL::Url::fromPathOrUrl("c:/test"); + if ( url.isEmpty() ) TEST_FAILED("isEmpty"); + if ( url.isRelative() ) TEST_FAILED("isRelative"); + if ( !url.isLocal() ) TEST_FAILED("isLocal"); + PURL::Url url2 = PURL::Url::fromPathOrUrl("c:/"); + if ( url.path()!=url2.path() ) TEST_FAILED(url.path()); + if ( url==url2 ) TEST_FAILED(url.path()); + if ( url.filename()!="test" ) TEST_FAILED(url.filename()); + TEST_PASSED; + } + { + PURL::Url url = PURL::Url::fromPathOrUrl("d:/test/"); + if ( url.isEmpty() ) TEST_FAILED("isEmpty"); + if ( url.isRelative() ) TEST_FAILED("isRelative"); + if ( !url.isLocal() ) TEST_FAILED("isLocal"); + if ( !url.filename().isEmpty() ) TEST_FAILED(url.filename()); + TEST_PASSED; + } + { + PURL::Url url(KURL::fromPathOrURL("http://test.net/test")); + if ( url.isEmpty() ) TEST_FAILED("isEmpty"); + if ( url.isRelative() ) TEST_FAILED("isRelative"); + if ( url.isLocal() ) TEST_FAILED("isLocal"); + if ( url.filename()!="test" ) TEST_FAILED(url.filename()); + TEST_PASSED; + } + + return true; +} + +//---------------------------------------------------------------------------- +TEST_MAIN(MiscCheck) diff --git a/src/piklab-test/misc/misc_check.h b/src/piklab-test/misc/misc_check.h new file mode 100644 index 0000000..a36b3cf --- /dev/null +++ b/src/piklab-test/misc/misc_check.h @@ -0,0 +1,20 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef MISC_CHECK_H +#define MISC_CHECK_H + +#include "piklab-test/base/main_test.h" + +class MiscCheck : public Test +{ +protected: + virtual bool execute(); +}; + +#endif diff --git a/src/piklab-test/save_load_memory/Makefile.am b/src/piklab-test/save_load_memory/Makefile.am new file mode 100644 index 0000000..da9365f --- /dev/null +++ b/src/piklab-test/save_load_memory/Makefile.am @@ -0,0 +1,18 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_PROGRAMS = save_load_memory_check +OBJ = $(top_builddir)/src/piklab-test/base/libtest.la \ + $(top_builddir)/src/common/cli/libcli.la \ + $(top_builddir)/src/tools/gputils/libgputils.la \ + $(top_builddir)/src/coff/base/libcoff.la \ + $(top_builddir)/src/common/global/libglobal.la $(top_builddir)/src/devices/list/libdevicelistnoui.la \ + $(top_builddir)/src/devices/pic/pic/libpic.la $(top_builddir)/src/devices/pic/base/libpicbase.la \ + $(top_builddir)/src/devices/pic/xml_data/libpicxml.la \ + $(top_builddir)/src/devices/mem24/mem24/libmem24.la $(top_builddir)/src/devices/mem24/base/libmem24base.la \ + $(top_builddir)/src/devices/mem24/xml_data/libmem24xml.la \ + $(top_builddir)/src/devices/base/libdevicebase.la $(top_builddir)/src/common/common/libcommon.la +save_load_memory_check_DEPENDENCIES = $(OBJ) +save_load_memory_check_LDADD = $(OBJ) $(LIB_KIO) +save_load_memory_check_LDFLAGS = $(all_libraries) $(KDE_RPATH) +save_load_memory_check_SOURCES = save_load_memory_check.cpp diff --git a/src/piklab-test/save_load_memory/save_load_memory_check.cpp b/src/piklab-test/save_load_memory/save_load_memory_check.cpp new file mode 100644 index 0000000..22eb1ea --- /dev/null +++ b/src/piklab-test/save_load_memory/save_load_memory_check.cpp @@ -0,0 +1,64 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "save_load_memory_check.h" + +#include "devices/base/generic_memory.h" +#include "devices/base/device_group.h" + +//---------------------------------------------------------------------------- +SaveLoadMemoryCheck::SaveLoadMemoryCheck() + : _memory1(0), _memory2(0) +{ + _view = new CLI::View; + PURL::Url dest(PURL::Directory::current(), "test.hex"); + _fdest = new PURL::File(dest, *_view); +} + +SaveLoadMemoryCheck::~SaveLoadMemoryCheck() +{ + _fdest->remove(); + delete _fdest; + delete _view; +} + +bool SaveLoadMemoryCheck::init(const Device::Data &data) +{ + _memory1 = data.group().createMemory(data); + _memory2 = data.group().createMemory(data); + return true; +} + +void SaveLoadMemoryCheck::cleanup(const Device::Data &) +{ + delete _memory1; + _memory1 = 0; + delete _memory2; + _memory2 = 0; +} + +bool SaveLoadMemoryCheck::execute(const Device::Data &data) +{ + // create hex file from blank memory + if ( !_fdest->openForWrite() ) TEST_FAILED_RETURN("") + _memory1->save(_fdest->stream(), HexBuffer::IHX32); + + // read hex file + if ( !_fdest->openForRead() ) TEST_FAILED_RETURN("") + QStringList errors, warnings; + Device::Memory::WarningTypes wtypes; + if ( !_memory2->load(_fdest->stream(), errors, wtypes, warnings) ) TEST_FAILED_RETURN(QString("Error loading hex file into memory %1").arg(data.name())) + + // compare checksums + if ( _memory1->checksum()!=_memory2->checksum() ) TEST_FAILED_RETURN("Memory saved and loaded is different") + TEST_PASSED + return true; +} + +//---------------------------------------------------------------------------- +TEST_MAIN(SaveLoadMemoryCheck) diff --git a/src/piklab-test/save_load_memory/save_load_memory_check.h b/src/piklab-test/save_load_memory/save_load_memory_check.h new file mode 100644 index 0000000..f342560 --- /dev/null +++ b/src/piklab-test/save_load_memory/save_load_memory_check.h @@ -0,0 +1,32 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef SAVE_LOAD_MEMORY_CHECK_H +#define SAVE_LOAD_MEMORY_CHECK_H + +#include "piklab-test/base/device_test.h" +#include "common/cli/cli_log.h" +#include "common/global/pfile.h" +namespace Device { class Memory; } + +class SaveLoadMemoryCheck : public DeviceTest +{ +public: + SaveLoadMemoryCheck(); + virtual ~SaveLoadMemoryCheck(); + virtual bool init(const Device::Data &data); + virtual bool execute(const Device::Data &data); + virtual void cleanup(const Device::Data &data); + +private: + CLI::View *_view; + PURL::File *_fdest; + Device::Memory *_memory1, *_memory2; +}; + +#endif diff --git a/src/piklab/Makefile.am b/src/piklab/Makefile.am new file mode 100644 index 0000000..4a40a10 --- /dev/null +++ b/src/piklab/Makefile.am @@ -0,0 +1,63 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +bin_PROGRAMS = piklab +OBJS = $(top_builddir)/src/libgui/libgui.la \ + \ + $(top_builddir)/src/tools/list/libtoollist.la \ + $(top_builddir)/src/tools/cc5x/gui/libcc5xui.la \ + $(top_builddir)/src/tools/mpc/gui/libmpcui.la $(top_builddir)/src/tools/boost/gui/libboostui.la \ + $(top_builddir)/src/tools/jalv2/gui/libjalv2ui.la $(top_builddir)/src/tools/ccsc/gui/libccscui.la \ + $(top_builddir)/src/tools/c18/gui/libc18ui.la $(top_builddir)/src/tools/jal/gui/libjalui.la \ + $(top_builddir)/src/tools/pic30/gui/libpic30ui.la $(top_builddir)/src/tools/picc/gui/libpiccui.la \ + $(top_builddir)/src/tools/sdcc/gui/libsdccui.la $(top_builddir)/src/tools/gputils/gui/libgputilsui.la \ + $(top_builddir)/src/tools/custom/libcustom.la \ + $(top_builddir)/src/tools/cc5x/libcc5x.la \ + $(top_builddir)/src/tools/mpc/libmpc.la $(top_builddir)/src/tools/boost/libboost.la \ + $(top_builddir)/src/tools/jalv2/libjalv2.la $(top_builddir)/src/tools/ccsc/libccsc.la \ + $(top_builddir)/src/tools/c18/libc18.la $(top_builddir)/src/tools/jal/libjal.la \ + $(top_builddir)/src/tools/pic30/libpic30.la $(top_builddir)/src/tools/picc/libpicc.la \ + $(top_builddir)/src/tools/sdcc/libsdcc.la $(top_builddir)/src/tools/gputils/libgputils.la \ + $(top_builddir)/src/tools/gui/libtoolui.la $(top_builddir)/src/tools/base/libtoolbase.la \ + \ + $(top_builddir)/src/progs/list/libproglistui.la \ + $(top_builddir)/src/progs/picdem_bootloader/gui/libpicdembootloaderui.la \ + $(top_builddir)/src/progs/pickit2_bootloader/gui/libpickit2bootloaderui.la \ + $(top_builddir)/src/progs/tbl_bootloader/gui/libtblbootloaderui.la \ + $(top_builddir)/src/progs/bootloader/gui/libbootloaderui.la \ + $(top_builddir)/src/progs/gpsim/gui/libgpsimui.la $(top_builddir)/src/progs/psp/gui/libpspui.la \ + $(top_builddir)/src/progs/pickit2v2/gui/libpickit2v2ui.la \ + $(top_builddir)/src/progs/pickit2/gui/libpickit2ui.la $(top_builddir)/src/progs/pickit1/gui/libpickit1ui.la \ + $(top_builddir)/src/progs/icd1/gui/libicd1ui.la $(top_builddir)/src/progs/icd2/gui/libicd2ui.la \ + $(top_builddir)/src/progs/direct/gui/libdirectui.la \ + $(top_builddir)/src/progs/gui/libprogui.la \ + \ + $(top_builddir)/src/progs/picdem_bootloader/base/libpicdembootloader.la \ + $(top_builddir)/src/progs/pickit2_bootloader/base/libpickit2bootloader.la \ + $(top_builddir)/src/progs/tbl_bootloader/base/libtblbootloader.la \ + $(top_builddir)/src/progs/bootloader/base/libbootloader.la \ + $(top_builddir)/src/progs/gpsim/base/libgpsim.la $(top_builddir)/src/progs/psp/base/libpsp.la \ + $(top_builddir)/src/progs/pickit2v2/base/libpickit2v2.la \ + $(top_builddir)/src/progs/pickit1/base/libpickit1.la $(top_builddir)/src/progs/pickit2/base/libpickit2.la \ + $(top_builddir)/src/progs/icd1/base/libicd1.la $(top_builddir)/src/progs/icd2/base/libicd2.la \ + $(top_builddir)/src/progs/icd2/icd2_data/libicd2data.la $(top_builddir)/src/progs/direct/base/libdirectprog.la \ + $(top_builddir)/src/progs/manager/libprogmanager.la \ + $(top_builddir)/src/devices/pic/prog/libpicprog.la $(top_builddir)/src/devices/mem24/prog/libmem24prog.la \ + $(top_builddir)/src/progs/base/libprogbase.la \ + \ + $(top_builddir)/src/coff/base/libcoff.la $(top_builddir)/src/common/port/libport.la \ + $(top_builddir)/src/common/global/libglobal.la \ + \ + $(top_builddir)/src/devices/list/libdevicelistui.la \ + $(top_builddir)/src/devices/mem24/gui/libmem24ui.la $(top_builddir)/src/devices/pic/gui/libpicui.la \ + $(top_builddir)/src/devices/gui/libdeviceui.la $(top_builddir)/src/common/gui/libcommonui.la \ + \ + $(top_builddir)/src/devices/pic/pic/libpic.la $(top_builddir)/src/devices/pic/base/libpicbase.la \ + $(top_builddir)/src/devices/pic/xml_data/libpicxml.la \ + $(top_builddir)/src/devices/mem24/mem24/libmem24.la $(top_builddir)/src/devices/mem24/base/libmem24base.la \ + $(top_builddir)/src/devices/mem24/xml_data/libmem24xml.la \ + $(top_builddir)/src/devices/base/libdevicebase.la $(top_builddir)/src/common/common/libcommon.la +piklab_LDADD = $(OBJS) -lktexteditor $(LIBUSB_LIBS) $(LIB_KHTML) +piklab_DEPENDENCIES = $(OBJS) +piklab_LDFLAGS = $(all_libraries) $(KDE_RPATH) +piklab_SOURCES = main.cpp diff --git a/src/piklab/main.cpp b/src/piklab/main.cpp new file mode 100644 index 0000000..409be80 --- /dev/null +++ b/src/piklab/main.cpp @@ -0,0 +1,32 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ + +#include "libgui/toplevel.h" +#include "common/global/about.h" +#include "libgui/likeback.h" + +const KCmdLineOptions OPTIONS[] = { + { "+[file]", I18N_NOOP("Optional filenames to be opened upon startup."), 0 }, + { 0, 0, 0} +}; + +int main(int argc, char **argv) +{ + Piklab::AboutData *about = new Piklab::AboutData("piklab", I18N_NOOP("Piklab"), I18N_NOOP( "Graphical development environment for applications based on PIC and dsPIC microcontrollers.")); + Piklab::init(about, argc, argv, true, OPTIONS); + LikeBack::init(true); + LikeBack::setServer("piklab.sourceforge.net", "/likeback/send.php"); + LikeBack::setAllowFeatureWishes(true); + if ( kapp->isRestored() ) RESTORE(MainWindow) + else { + MainWindow *wid = new MainWindow; + wid->show(); + } + return kapp->exec(); +} diff --git a/src/progs/Makefile.am b/src/progs/Makefile.am new file mode 100644 index 0000000..634b7d1 --- /dev/null +++ b/src/progs/Makefile.am @@ -0,0 +1,2 @@ +SUBDIRS = base gui direct icd2 icd1 pickit2 pickit1 pickit2v2 psp gpsim \ + bootloader picdem_bootloader tbl_bootloader pickit2_bootloader list manager \ No newline at end of file diff --git a/src/progs/base/Makefile.am b/src/progs/base/Makefile.am new file mode 100644 index 0000000..c045428 --- /dev/null +++ b/src/progs/base/Makefile.am @@ -0,0 +1,10 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + + +libprogbase_la_LDFLAGS = $(all_libraries) +noinst_LTLIBRARIES = libprogbase.la +libprogbase_la_SOURCES = generic_prog.cpp prog_specific.cpp prog_config.cpp \ + prog_group.cpp generic_debug.cpp hardware_config.cpp debug_config.cpp + + diff --git a/src/progs/base/base.pro b/src/progs/base/base.pro new file mode 100644 index 0000000..b2556e4 --- /dev/null +++ b/src/progs/base/base.pro @@ -0,0 +1,8 @@ +STOPDIR = ../../.. +include($${STOPDIR}/lib.pro) + +TARGET = progbase +HEADERS += generic_prog.h generic_debug.h prog_config.h prog_group.h prog_specific.h \ + hardware_config.h debug_config.h +SOURCES += generic_prog.cpp generic_debug.cpp prog_config.cpp prog_group.cpp prog_specific.cpp \ + hardware_config.cpp debug_config.cpp diff --git a/src/progs/base/debug_config.cpp b/src/progs/base/debug_config.cpp new file mode 100644 index 0000000..387941d --- /dev/null +++ b/src/progs/base/debug_config.cpp @@ -0,0 +1,14 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "debug_config.h" + +const Debugger::Config::Data Debugger::Config::DATA[Nb_Types] = { + { "only_stop_on_source_line", I18N_NOOP("Only stop stepping on source line."), QVariant(true, 0) }, + { "only_stop_on_project_source_line", I18N_NOOP("Only stop stepping on project source line."), QVariant(true, 0) } +}; diff --git a/src/progs/base/debug_config.h b/src/progs/base/debug_config.h new file mode 100644 index 0000000..acd7f09 --- /dev/null +++ b/src/progs/base/debug_config.h @@ -0,0 +1,24 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef DEBUG_CONFIG_H +#define DEBUG_CONFIG_H + +#include "common/global/generic_config.h" +#include "common/common/key_enum.h" + +namespace Debugger +{ + +BEGIN_DECLARE_CONFIG(Config) + OnlyStopOnSourceLine, OnlyStopOnProjectSourceLine +END_DECLARE_CONFIG(Config, "debugger") + +} // namespace + +#endif diff --git a/src/progs/base/generic_debug.cpp b/src/progs/base/generic_debug.cpp new file mode 100644 index 0000000..252d239 --- /dev/null +++ b/src/progs/base/generic_debug.cpp @@ -0,0 +1,111 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "generic_debug.h" + +#include "common/global/global.h" +#include "generic_prog.h" +#include "devices/base/register.h" +#include "devices/base/device_group.h" +#include "devices/pic/base/pic.h" + +//---------------------------------------------------------------------------- +Debugger::Base::Base(Programmer::Base &programmer) + : Log::Base(&programmer), _programmer(programmer), _deviceSpecific(0), + _specific(0), _inputType(PURL::Nb_FileTypes), _coff(0) +{} + +void Debugger::Base::init(DeviceSpecific *deviceSpecific, Specific *specific) +{ + _deviceSpecific = deviceSpecific; + _specific = specific; +} + +Debugger::Base::~Base() +{ + delete _deviceSpecific; + delete _specific; +} + +const Device::Data *Debugger::Base::device() const +{ + return _programmer.device(); +} + +bool Debugger::Base::init() +{ + _programmer.setState(Programmer::Stopped); + log(Log::LineType::Information, i18n("Setting up debugging session.")); + if ( !internalInit() ) { + log(Log::LineType::Error, i18n("Failed to initialize device for debugging.")); + return false; + } + log(Log::LineType::Information, i18n("Ready to start debugging.")); + _programmer.setState(Programmer::Halted); + return update(); +} + +bool Debugger::Base::update() +{ + if ( !updateState() ) return false; + if ( _programmer.state()==::Programmer::Halted ) return _deviceSpecific->updateStatus(); + return true; +} + +bool Debugger::Base::run() +{ + if ( !internalRun() ) return false; + _programmer.setState(::Programmer::Running); + return update(); +} + +bool Debugger::Base::step() +{ + if ( !internalStep() ) return false; + return update(); +} + +bool Debugger::Base::halt() +{ + bool success; + if ( !softHalt(success) ) return false; + if ( !success ) return hardHalt(); + if ( !update() ) return false; + log(Log::LineType::Information, QString("Halted at %1").arg(toHexLabel(pc(), _programmer.device()->nbCharsAddress()))); + _programmer.setState(::Programmer::Halted); + return true; +} + +bool Debugger::Base::reset() +{ + if ( !internalReset() ) return false; + return update(); +} + +QString Debugger::Base::statusString() const +{ + if ( _programmer.state()!=::Programmer::Halted ) return QString::null; + return _deviceSpecific->statusString(); +} + +void Debugger::Base::setupInput(PURL::FileType type, const QString &directory, const QString &filename) +{ + _inputType = type; + _directory = directory; + _filename = filename; +} + +BitValue Debugger::Base::pc() const +{ + return Register::list().value(pcTypeData()); +} + +Register::TypeData Debugger::Base::pcTypeData() const +{ + return Register::TypeData("PC", 2*device()->nbBytesAddress()); +} diff --git a/src/progs/base/generic_debug.h b/src/progs/base/generic_debug.h new file mode 100644 index 0000000..903d451 --- /dev/null +++ b/src/progs/base/generic_debug.h @@ -0,0 +1,90 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef GENERIC_DEBUG_H +#define GENERIC_DEBUG_H + +#include "common/common/purl_base.h" +#include "common/global/global.h" +#include "common/global/log.h" +#include "devices/base/register.h" +namespace Programmer { class Base; } +namespace Coff { class TextObject; } + +namespace Debugger +{ +class DeviceSpecific; +class Specific; + +//---------------------------------------------------------------------------- +class Base : public Log::Base +{ +public: + Base(Programmer::Base &programmer); + virtual ~Base(); + void init(DeviceSpecific *deviceSpecific, Specific *specific); + const Device::Data *device() const; + void setupInput(PURL::FileType type, const QString &directory, const QString &filename); + void setCoff(const Coff::TextObject *coff) { _coff = coff; } + QString directory() const { return _directory; } + bool init(); + bool update(); + bool reset(); + bool run(); + bool halt(); + bool step(); + QString statusString() const; + virtual bool setBreakpoints(const QValueList
&addresses) = 0; + BitValue pc() const; + Register::TypeData pcTypeData() const; + virtual bool readRegister(const Register::TypeData &data, BitValue &value) = 0; + virtual bool writeRegister(const Register::TypeData &data, BitValue value) = 0; + virtual bool updatePortStatus(uint index, QMap &bits) = 0; + +protected: + Programmer::Base &_programmer; + DeviceSpecific *_deviceSpecific; + Specific *_specific; + PURL::FileType _inputType; + QString _directory, _filename; + const Coff::TextObject *_coff; + + virtual bool internalInit() = 0; + virtual bool internalRun() = 0; + virtual bool softHalt(bool &success) = 0; + virtual bool hardHalt() = 0; + virtual bool internalStep() = 0; + virtual bool internalReset() = 0; + virtual bool updateState() = 0; +}; + +//---------------------------------------------------------------------------- +class DeviceSpecific : public Log::Base +{ +public: + DeviceSpecific(Debugger::Base &base) : Log::Base(base), _base(base) {} + virtual bool updateStatus() = 0; + virtual QString statusString() const = 0; + +protected: + Debugger::Base &_base; +}; + +//---------------------------------------------------------------------------- +class Specific : public Log::Base +{ +public: + Specific(Debugger::Base &base) : Log::Base(base), _base(base) {} + +protected: + Debugger::Base &_base; +}; + +} // namespace + +#endif diff --git a/src/progs/base/generic_prog.cpp b/src/progs/base/generic_prog.cpp new file mode 100644 index 0000000..6386eb2 --- /dev/null +++ b/src/progs/base/generic_prog.cpp @@ -0,0 +1,402 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "generic_prog.h" + +#include + +#include "common/global/global.h" +#include "prog_group.h" +#include "prog_config.h" +#include "devices/base/device_group.h" +#include "generic_debug.h" +#include "hardware_config.h" + +//----------------------------------------------------------------------------- +const double Programmer::UNKNOWN_VOLTAGE = -1.0; + +const char * const Programmer::RESULT_TYPE_LABELS[Nb_ResultTypes+1] = { + I18N_NOOP("Pass"), + I18N_NOOP("Low"), + I18N_NOOP("High"), + I18N_NOOP("Fail"), + I18N_NOOP("---") +}; + +const Programmer::Task::Data Programmer::Task::DATA[Nb_Types] = { + { 0, I18N_NOOP("Reading...") }, + { 0, I18N_NOOP("Programming...") }, + { 0, I18N_NOOP("Verifying...") }, + { 0, I18N_NOOP("Erasing...") }, + { 0, I18N_NOOP("Blank Checking...") } +}; + +//----------------------------------------------------------------------------- +Programmer::Base::Base(const Group &group, const Device::Data *device, const char *) + : _hardware(0), _specific(0), _device(device), _debugger(group.createDebugger(*this)), + _state(NotConnected), _targetPowerOn(false), _group(group) +{} + +void Programmer::Base::init(bool targetSelfPowered, Hardware *hardware, DeviceSpecific *ds) +{ + clear(); + _targetSelfPowered = targetSelfPowered; + _hardware = hardware; + _specific = ds; +} + +Programmer::Base::~Base() +{ + delete _debugger; + delete _specific; + delete _hardware; +} + +void Programmer::Base::clear() +{ + _firmwareVersion.clear(); + _mode = NormalMode; + resetError(); +} + +bool Programmer::Base::simpleConnectHardware() +{ + Q_ASSERT(_hardware); + disconnectHardware(); + clear(); + if (_device) { + QString label = _group.label(); + if ( group().isSoftware() ) + log(Log::LineType::Information, i18n("Connecting %1 with device %2...").arg(label).arg(_device->name())); + else { + if ( !_hardware->name().isEmpty() ) label += "[" + _hardware->name() + "]"; + Port::Description pd = _hardware->portDescription(); + QString s = pd.type.label(); + if (pd.type.data().withDevice) s += " (" + pd.device + ")"; + log(Log::LineType::Information, i18n("Connecting %1 on %2 with device %3...").arg(label).arg(s).arg(_device->name())); + } + } + return _hardware->connectHardware(); +} + +bool Programmer::Base::connectHardware() +{ + _progressMonitor.insertTask(i18n("Connecting..."), 2); + log(Log::DebugLevel::Extra, "connect hardware"); + if ( !simpleConnectHardware() ) return false; + _progressMonitor.addTaskProgress(1); + if ( !group().isSoftware() ) { + if ( !readFirmwareVersion() ) return false; + if ( _specific==0 ) return true; + if ( _mode==BootloadMode ) return true; + if ( !setupFirmware() ) return false; + if ( !checkFirmwareVersion() ) return false; + if ( !setTargetPowerOn(false) ) return false; + if ( !setTarget() ) return false; + log(Log::LineType::Information, i18n(" Set target self powered: %1").arg(_targetSelfPowered ? "true" : "false")); + if ( !setTargetPowerOn(!_targetSelfPowered) ) return false; + if ( !internalSetupHardware() ) return false; + if ( !readVoltages() ) return false; + if ( !selfTest(true) ) return false; + } + if ( hasError() ) return false; + log(Log::LineType::Information, i18n("Connected.")); + _state = Stopped; + return true; +} + +void Programmer::Base::disconnectHardware() +{ + _state = NotConnected; + log(Log::DebugLevel::Extra, "disconnect hardware"); + clear(); + _hardware->disconnectHardware(); +} + +PURL::Directory Programmer::Base::firmwareDirectory() +{ + if ( _firmwareDirectory.isEmpty() ) _firmwareDirectory = GroupConfig::firmwareDirectory(group()); + PURL::Directory dir(_firmwareDirectory); + if ( !dir.exists() ) { + log(Log::LineType::Error, i18n("Firmware directory is not configured or does not exist.")); + return PURL::Directory(); + } + return dir; +} + +bool Programmer::Base::checkFirmwareVersion() +{ + if ( _mode==BootloadMode ) log(Log::LineType::Information, i18n("Programmer is in bootload mode.")); + if ( !_firmwareVersion.isValid() ) return true; + log(Log::LineType::Information, i18n("Firmware version is %1").arg(_firmwareVersion.pretty())); + VersionData vd = _firmwareVersion.toWithoutDot(); + VersionData tmp = firmwareVersion(FirmwareVersionType::Max); + if ( tmp.isValid() && tmp.toWithoutDot()setTargetPowerOn(on); +} + +void Programmer::Base::appendTask(Task task, const Device::MemoryRange *range) +{ + _progressMonitor.appendTask(task.label(), nbSteps(task, range)); +} + +bool Programmer::Base::connectDevice() +{ + _progressMonitor.clear(); + bool ok = doConnectDevice(); + endProgramming(); + return ok; +} + +bool Programmer::Base::doConnectDevice() +{ + if ( _state==NotConnected ) { + if ( !connectHardware() ) return false; + if ( !enterMode(NormalMode) ) return false; + if ( !verifyDeviceId() ) return false; + } else { + setTargetPowerOn(!_targetSelfPowered); + } + _state = Stopped; + return true; +} + +bool Programmer::Base::run() +{ + emit actionMessage(i18n("Running...")); + _progressMonitor.clear(); + if ( !doConnectDevice() ) return false; + log(Log::LineType::Information, i18n("Run...")); + internalRun(); + return !hasError(); +} + +bool Programmer::Base::stop() +{ + emit actionMessage(i18n("Breaking...")); + return internalStop(); +} + +void Programmer::Base::endProgramming() +{ + if ( _state==Stopped && readConfigEntry(Config::PowerDownAfterProgramming).toBool() ) + setTargetPowerOn(false); + if ( !(group().properties() & HasConnectedState) ) disconnectHardware(); + _progressMonitor.clear(); +} + +bool Programmer::Base::uploadFirmware(const PURL::Url &url) +{ + _progressMonitor.clear(); + log(Log::DebugLevel::Normal, QString(" Firmware file: %1").arg(url.pretty())); + Log::StringView sview; + PURL::File file(url, sview); + if ( !file.openForRead() ) { + log(Log::LineType::Error, i18n("Could not open firmware file \"%1\".").arg(url.pretty())); + return false; + } + bool ok = doUploadFirmware(file); + _firmwareVersion.clear(); + if (ok) ok = readFirmwareVersion(); + endProgramming(); + return ok; +} + +bool Programmer::Base::doUploadFirmware(PURL::File &file) +{ + emit actionMessage(i18n("Uploading firmware...")); + return internalUploadFirmware(file); +} + +//----------------------------------------------------------------------------- +bool Programmer::Base::erase(const Device::MemoryRange &range) +{ + _progressMonitor.clear(); + appendTask(Task::Erase, &range); + if ( readConfigEntry(Config::BlankCheckAfterErase).toBool() ) appendTask(Task::BlankCheck); + bool ok = doErase(range); + endProgramming(); + return ok; +} + +bool Programmer::Base::doErase(const Device::MemoryRange &range) +{ + if ( !checkErase() ) return false; + if ( !doConnectDevice() ) return false; + _progressMonitor.startNextTask(); + log(Log::LineType::Information, i18n("Erasing...")); + if ( !internalErase(range) ) return false; + log(Log::LineType::Information, i18n("Erasing done")); + if ( readConfigEntry(Config::BlankCheckAfterErase).toBool() ) { + _progressMonitor.startNextTask(); + log(Log::LineType::Information, i18n("Blank checking...")); + if ( !doVerify(BlankCheckVerify, range, 0) ) return false; + log(Log::LineType::Information, i18n("Blank checking done.")); + } + return true; +} + +//----------------------------------------------------------------------------- +bool Programmer::Base::checkCanRead() +{ + if ( !(group().properties() & CanReadMemory) ) { + log(Log::LineType::Error, i18n("The selected programmer cannot read device memory.")); + return false; + } + return true; +} + +bool Programmer::Base::read(Device::Memory &memory, const Device::MemoryRange &range) +{ + if ( !checkCanRead() ) return false; + _progressMonitor.clear(); + appendTask(Task::Read, &range); + bool ok = doRead(memory, range); + endProgramming(); + return ok; +} + +bool Programmer::Base::doRead(Device::Memory &memory, const Device::MemoryRange &range) +{ + if ( !checkRead() ) return false; + if ( !doConnectDevice() ) return false; + _progressMonitor.startNextTask(); + log(Log::LineType::Information, i18n("Reading device memory...")); + memory.clear(); + if ( !internalRead(&memory, range, 0) ) return false; + log(Log::LineType::Information, i18n("Reading done.")); + return true; +} + +//----------------------------------------------------------------------------- +bool Programmer::Base::program(const Device::Memory &memory, const Device::MemoryRange &range) +{ + _progressMonitor.clear(); + appendTask(Task::Write, &range); + bool ok = doProgram(memory, range); + endProgramming(); + return ok; +} + +bool Programmer::Base::doProgram(const Device::Memory &memory, const Device::MemoryRange &range) +{ + if ( !checkProgram(memory) ) return false; + if ( !doConnectDevice() ) return false; + _progressMonitor.startNextTask(); + log(Log::LineType::Information, i18n("Programming device memory...")); + if ( !internalProgram(memory, range) ) return false; + log(Log::LineType::Information, i18n("Programming successful.")); + if ( group().isDebugger() && !_debugger->init() ) return false; + return true; +} + +//----------------------------------------------------------------------------- +bool Programmer::Base::verify(const Device::Memory &memory, const Device::MemoryRange &range) +{ + if ( !checkCanRead() ) return false; + _progressMonitor.clear(); + appendTask(Task::Verify, &range); + bool ok = doVerify(memory, range); + endProgramming(); + return ok; +} + +bool Programmer::Base::doVerify(VerifyAction action, const Device::MemoryRange &range, const Device::Memory *memory) +{ + const Device::Memory *vmemory = memory; + if ( memory==0 ) { + Q_ASSERT( action & BlankCheckVerify ); + vmemory = _device->group().createMemory(*_device); + } + VerifyData vdata(action, *vmemory); + bool ok = internalRead(0, range, &vdata); + if ( memory==0 ) delete vmemory; + return ok; +} + +bool Programmer::Base::doVerify(const Device::Memory &memory, const Device::MemoryRange &range) +{ + if ( !checkRead() ) return false; + if ( !doConnectDevice() ) return false; + _progressMonitor.startNextTask(); + log(Log::LineType::Information, i18n("Verifying...")); + if ( !doVerify(NormalVerify, range, &memory) ) return false; + log(Log::LineType::Information, i18n("Verifying successful.")); + return true; +} + +bool Programmer::Base::blankCheck(const Device::MemoryRange &range) +{ + if ( !checkCanRead() ) return false; + _progressMonitor.clear(); + appendTask(Task::BlankCheck, &range); + bool ok = doBlankCheck(range); + endProgramming(); + return ok; +} + +bool Programmer::Base::doBlankCheck(const Device::MemoryRange &range) +{ + if ( !checkRead() ) return false; + if ( !doConnectDevice() ) return false; + _progressMonitor.startNextTask(); + log(Log::LineType::Information, i18n("Blank checking...")); + if ( !doVerify(BlankCheckVerify, range, 0) ) return false; + log(Log::LineType::Information, i18n("Blank checking successful.")); + return true; +} diff --git a/src/progs/base/generic_prog.h b/src/progs/base/generic_prog.h new file mode 100644 index 0000000..3b4b219 --- /dev/null +++ b/src/progs/base/generic_prog.h @@ -0,0 +1,163 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef GENERIC_PROG_H +#define GENERIC_PROG_H + +#include "common/global/log.h" +#include "common/global/pfile.h" +#include "common/common/version_data.h" +#include "common/port/port_base.h" +#include "common/global/progress_monitor.h" +#include "devices/base/generic_device.h" +#include "devices/base/generic_memory.h" +#include "prog_specific.h" +namespace Debugger { class Base; } +namespace Device { class MemoryRange; } + +namespace Programmer +{ + enum Mode { NormalMode, BootloadMode }; + enum State { NotConnected = 0, Stopped, Running, Halted }; + class Hardware; + class Group; + class DeviceSpecific; + extern const double UNKNOWN_VOLTAGE; + + enum VerifyAction { NormalVerify = 0, BlankCheckVerify = 1, + IgnoreProtectedVerify = 2, OnlyProgrammedVerify = 4 }; + Q_DECLARE_FLAGS(VerifyActions, VerifyAction) + Q_DECLARE_OPERATORS_FOR_FLAGS(VerifyActions) + class VerifyData { + public: + VerifyData(VerifyActions pactions, const Device::Memory &pmemory) : actions(pactions), memory(pmemory) {} + VerifyActions actions; + AddressRangeVector protectedRanges; + const Device::Memory &memory; + }; + + enum ResultType { Pass = 0, Low, High, Fail, Nb_ResultTypes }; + extern const char * const RESULT_TYPE_LABELS[Nb_ResultTypes+1]; + + class HardwareDescription { + public: + Port::Description port; + QString name; + }; + + BEGIN_DECLARE_ENUM(Task) + Read = 0, Write, Verify, Erase, BlankCheck + END_DECLARE_ENUM_STD(Task) + + BEGIN_DECLARE_ENUM(FirmwareVersionType) + Min, Max, Recommended + END_DECLARE_ENUM_NO_DATA(FirmwareVersionType) + +//----------------------------------------------------------------------------- +class Base : public QObject, public Log::Base +{ +Q_OBJECT +public: + Base(const Group &group, const Device::Data *data, const char *name); + virtual ~Base(); + + virtual void log(Log::LineType type, const QString &message); + virtual void log(Log::DebugLevel level, const QString &message); + void init(bool targetSelfPowered, Hardware *hardware, DeviceSpecific *deviceSpecific); + const Device::Data *device() const { return _device; } + const Group &group() const { return _group; } + Hardware *hardware() { return _hardware; } + ProgressMonitor &progressMonitor() { return _progressMonitor; } + ::Debugger::Base *debugger() { return _debugger; } + virtual uint maxNbBreakpoints() const { return 1; } + virtual uint runUpdateWait() const { return 300; } + + bool simpleConnectHardware(); + bool connectHardware(); + void disconnectHardware(); + bool connectDevice(); + bool setTargetPowerOn(bool on); + bool isTargetPowerOn() const { return _targetPowerOn; } + bool isTargetSelfPowered() const { return _targetSelfPowered; } + void setFirmwareDirectory(const PURL::Directory &dir) { _firmwareDirectory = dir; } + const VersionData &firmwareVersion() const { return _firmwareVersion; } + virtual bool readFirmwareVersion() { return true; } + bool uploadFirmware(const PURL::Url &url); + virtual bool readVoltages() { return true; } + virtual bool selfTest(bool ask) { Q_UNUSED(ask); return true; } + void appendTask(Task task, const Device::MemoryRange *range = 0); + + bool erase(const Device::MemoryRange &range); + bool read(Device::Memory &memory, const Device::MemoryRange &range); + bool program(const Device::Memory &memory, const Device::MemoryRange &range); + bool verify(const Device::Memory &memory, const Device::MemoryRange &range); + bool blankCheck(const Device::MemoryRange &range); + bool run(); + bool stop(); + State state() const { return _state; } + void setState(State state) { _state = state; } + bool isConnected() const { return ( _state!=NotConnected ); } + bool isActive() const { return ( _state==Halted || _state==Running ); } + bool enterMode(Mode mode); + bool doConnectDevice(); + virtual void clear(); + +signals: + void actionMessage(const QString &message); + +protected: + Hardware *_hardware; + DeviceSpecific *_specific; + const Device::Data *_device; + ::Debugger::Base *_debugger; + State _state; + bool _targetPowerOn; + const Group &_group; + PURL::Directory _firmwareDirectory; + VersionData _firmwareVersion; + Mode _mode; + bool _targetSelfPowered; + ProgressMonitor _progressMonitor; + + PURL::Directory firmwareDirectory(); + virtual bool setupFirmware() { return true; } + virtual VersionData firmwareVersion(FirmwareVersionType type) const { Q_UNUSED(type); return VersionData(); } + virtual VersionData mplabVersion(FirmwareVersionType type) const { Q_UNUSED(type); return VersionData(); } + virtual bool checkFirmwareVersion(); + virtual bool setTarget() { return true; } + virtual bool internalSetupHardware() { return true; } + virtual bool verifyDeviceId() = 0; + virtual uint nbSteps(Task task, const Device::MemoryRange *range) const = 0; + virtual bool doUploadFirmware(PURL::File &); + virtual bool internalUploadFirmware(PURL::File &) { return false; } + virtual bool internalEnterMode(Mode) { return false; } + + virtual bool checkErase() = 0; + virtual bool internalErase(const Device::MemoryRange &range) = 0; + bool checkCanRead(); + virtual bool checkRead() = 0; + virtual bool internalRead(Device::Memory *memory, const Device::MemoryRange &range, const VerifyData *vdata) = 0; + virtual bool checkProgram(const Device::Memory &memory) = 0; + virtual bool internalProgram(const Device::Memory &memory, const Device::MemoryRange &range) = 0; + virtual bool internalRun() { return false; } + virtual bool internalStop() { return false; } + + void endProgramming(); + bool doErase(const Device::MemoryRange &range); + bool doRead(Device::Memory &memory, const Device::MemoryRange &range); + bool doVerify(const Device::Memory &memory, const Device::MemoryRange &range); + bool doVerify(VerifyAction action, const Device::MemoryRange &range, const Device::Memory *memory); + bool doBlankCheck(const Device::MemoryRange &range); + virtual bool doProgram(const Device::Memory &memory, const Device::MemoryRange &range); + + friend class DeviceSpecific; +}; + +} // namespace + +#endif diff --git a/src/progs/base/hardware_config.cpp b/src/progs/base/hardware_config.cpp new file mode 100644 index 0000000..5a3af7c --- /dev/null +++ b/src/progs/base/hardware_config.cpp @@ -0,0 +1,97 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * Copyright (C) 2003-2005 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "hardware_config.h" + +//----------------------------------------------------------------------------- +bool Hardware::Data::isEqual(const Data &data) const +{ + return ( data.portType==portType ); +} + +void Hardware::Data::readConfig(GenericConfig &config) +{ + portType = config.readEnumEntry("port_type", PortType::Serial); +} + +void Hardware::Data::writeConfig(GenericConfig &config) const +{ + config.writeEnumEntry("port_type", portType); +} + +//----------------------------------------------------------------------------- +void Hardware::Config::writeCurrentHardware(PortType type, const QString &name) +{ + writeEntry(QString("current_hardware_") + type.key(), name); +} + +QString Hardware::Config::currentHardware(PortType type) +{ + QStringList names = hardwareNames(type); + return readEntry(QString("current_hardware_") + type.key(), names[0]); +} + +QString Hardware::Config::label(const QString &name) const +{ + const DataInfo *info = standardHardwareDataInfo(name); + if ( info==0 ) return QString::null; + return i18n(info->label); +} + +QString Hardware::Config::comment(const QString &name) const +{ + const DataInfo *info = standardHardwareDataInfo(name); + if ( info==0 || info->comment==0 ) return QString::null; + return i18n(info->comment); +} + +void Hardware::Config::writeCustomHardware(const QString& name, const Hardware::Data &hdata) +{ + Q_ASSERT( !isStandardHardware(name) ); + QStringList customNames = readListEntry("custom_hardware_names", QStringList()); + if ( !customNames.contains(name) ) { + customNames += name; + writeEntry("custom_hardware_names", customNames); + } + GenericConfig config(group() + "_custom_hardware_" + name); + hdata.writeConfig(config); +} + +void Hardware::Config::deleteCustomHardware(const QString &name) +{ + Q_ASSERT( !isStandardHardware(name) ); + QStringList customNames = readListEntry("custom_hardware_names", QStringList()); + customNames.remove(name); + writeEntry("custom_hardware_names", customNames); + GenericConfig::deleteGroup(group() + "_custom_hardware_" + name); +} + +Hardware::Data *Hardware::Config::hardwareData(const QString &name) const +{ + if ( isStandardHardware(name) ) return standardHardwareData(name); + Hardware::Data *hdata = createHardwareData(); + hdata->name = name; + GenericConfig config(group() + "_custom_hardware_" + name); + hdata->readConfig(config); + return hdata; +} + +QStringList Hardware::Config::hardwareNames(PortType type) +{ + QStringList names = standardHardwareNames(type); + QStringList customNames = readListEntry("custom_hardware_names", QStringList()); + for (uint i=0; iportType==type ) names += customNames[i]; + delete hdata; + } else names += customNames[i]; + } + return names; +} diff --git a/src/progs/base/hardware_config.h b/src/progs/base/hardware_config.h new file mode 100644 index 0000000..5252ff3 --- /dev/null +++ b/src/progs/base/hardware_config.h @@ -0,0 +1,61 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * Copyright (C) 2003-2005 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#ifndef HARDWARE_CONFIG_H +#define HARDWARE_CONFIG_H + +#include "common/global/generic_config.h" +#include "common/port/port.h" + +namespace Hardware +{ +//----------------------------------------------------------------------------- +struct DataInfo +{ + const char *name, *label, *comment; +}; + +class Data +{ +public: + Data() : portType(PortType::Nb_Types) {} + virtual ~Data() {} + virtual void readConfig(GenericConfig &config); + virtual void writeConfig(GenericConfig &config) const; + virtual bool isEqual(const Data &data) const; + PortType portType; + QString name; +}; + +//----------------------------------------------------------------------------- +class Config : public GenericConfig +{ +public: + Config(const char *group) : GenericConfig(group) {} + virtual ~Config() {} + QStringList hardwareNames(PortType type); + bool isStandardHardware(const QString &name) const { return standardHardwareData(name); } + QString label(const QString &name) const; + QString comment(const QString &name) const; + void writeCustomHardware(const QString &name, const Hardware::Data &data); + QString currentHardware(PortType type); + void writeCurrentHardware(PortType type, const QString &name); + void deleteCustomHardware(const QString &name); + Hardware::Data *hardwareData(const QString& name) const; + +protected: + virtual QStringList standardHardwareNames(PortType type) const = 0; + virtual Hardware::Data *standardHardwareData(const QString &name) const = 0; + virtual const DataInfo *standardHardwareDataInfo(const QString &name) const = 0; + virtual Hardware::Data *createHardwareData() const = 0; +}; + +} // namespace + +#endif diff --git a/src/progs/base/prog_config.cpp b/src/progs/base/prog_config.cpp new file mode 100644 index 0000000..8115ce7 --- /dev/null +++ b/src/progs/base/prog_config.cpp @@ -0,0 +1,78 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "prog_config.h" + +//---------------------------------------------------------------------------- +PortType Programmer::GroupConfig::portType(const Group &group) +{ + GenericConfig config(group.name()); + PortType ctype = config.readEnumEntry("port_group"); + if ( group.isPortSupported(ctype) ) return ctype; + FOR_EACH(PortType, type) if ( group.isPortSupported(type) ) return type; + return PortType::Nb_Types; +} +void Programmer::GroupConfig::writePortType(const Group &group, PortType type) +{ + if ( type==PortType::Nb_Types ) return; + GenericConfig config(group.name()); + config.writeEnumEntry("port_group", type); +} + +QString Programmer::GroupConfig::portDevice(const Group &group, PortType portType) +{ + GenericConfig config(group.name()); + QString device = config.readEntry(QString(portType.key()) + "_port_device" , QString::null); + if ( device.isNull() ) { + QStringList list = Port::probedDeviceList(portType); + if ( list.isEmpty() ) return QString::null; + return list[0]; + } + return device; +} +void Programmer::GroupConfig::writePortDevice(const Group &group, PortType type, const QString &device) +{ + if ( type==PortType::Nb_Types ) return; + GenericConfig config(group.name()); + config.writeEntry(QString(type.key()) + "_port_device", device); +} + +Port::Description Programmer::GroupConfig::portDescription(const Group &group) +{ + PortType type = portType(group); + return Port::Description(type, portDevice(group, type)); +} +void Programmer::GroupConfig::writePortDescription(const Group &group, const Port::Description &dp) +{ + writePortType(group, dp.type); + writePortDevice(group, dp.type, dp.device); +} + +QString Programmer::GroupConfig::firmwareDirectory(const Group &group) +{ + GenericConfig config(group.name()); + return config.readEntry("firmware_directory", QString::null); +} +void Programmer::GroupConfig::writeFirmwareDirectory(const Group &group, const QString &path) +{ + GenericConfig config(group.name()); + config.writeEntry("firmware_directory", path); +} + +//---------------------------------------------------------------------------- +const Programmer::Config::Data Programmer::Config::DATA[Nb_Types] = { + { "only_program_non_mask", I18N_NOOP("Only program what is needed (faster)."), QVariant(true, 0) }, + { "verify_after_program", I18N_NOOP("Verify device memory after programming."), QVariant(true, 0) }, + { "only_verify_programmed", I18N_NOOP("Only verify programmed words in code memory (faster)."), QVariant(true, 0) }, + { "power_down_after_programming", I18N_NOOP("Power down target after programming."), QVariant(true, 0) }, + { "target_self_powered", I18N_NOOP("Target is self-powered (when possible)."), QVariant(true, 0) }, + { "blank_check_after_erase", I18N_NOOP("Blank check after erase."), QVariant(false, 0) }, + { "preserve_eeprom", I18N_NOOP("Preserve data EEPROM when programming."), QVariant(false, 0) }, + { "program_eeprom", I18N_NOOP("Program data EEPROM."), QVariant(true, 0) }, + { "run_after_program", I18N_NOOP("Run device after successful programming."), QVariant(false, 0) } +}; diff --git a/src/progs/base/prog_config.h b/src/progs/base/prog_config.h new file mode 100644 index 0000000..0c772c2 --- /dev/null +++ b/src/progs/base/prog_config.h @@ -0,0 +1,42 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PROGRAMMER_CONFIG_H +#define PROGRAMMER_CONFIG_H + +#include "common/port/port.h" +//#include "generic_prog.h" +#include "prog_group.h" +#include "common/global/generic_config.h" + +namespace Programmer +{ +//---------------------------------------------------------------------------- +class GroupConfig +{ +public: + static PortType portType(const Group &group); + static void writePortType(const Group &group, PortType type); + static QString portDevice(const Group &group, PortType type); + static void writePortDevice(const Group &group, PortType type, const QString &device); + static Port::Description portDescription(const Group &group); + static void writePortDescription(const Group &group, const Port::Description &pd); + static QString firmwareDirectory(const Group &group); + static void writeFirmwareDirectory(const Group &group, const QString &path); +}; + +//---------------------------------------------------------------------------- +BEGIN_DECLARE_CONFIG(Config) + OnlyProgramNonMask = 0, VerifyAfterProgram, OnlyVerifyProgrammed, + PowerDownAfterProgramming, TargetSelfPowered, BlankCheckAfterErase, + PreserveEeprom, ProgramEeprom, RunAfterProgram +END_DECLARE_CONFIG(Config, "programmer") + +} // namespace + +#endif diff --git a/src/progs/base/prog_group.cpp b/src/progs/base/prog_group.cpp new file mode 100644 index 0000000..5801318 --- /dev/null +++ b/src/progs/base/prog_group.cpp @@ -0,0 +1,62 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "prog_group.h" + +#include "common/global/global.h" +#include "generic_prog.h" +#include "prog_config.h" +#include "generic_debug.h" +#include "devices/base/device_group.h" + +// order is important +const PURL::FileType Programmer::INPUT_FILE_TYPE_DATA[Nb_InputFileTypes] = { + PURL::Coff, PURL::Cod, PURL::Hex +}; + +QString Programmer::Group::statusLabel(PortType type) const +{ + uint nb = 0; + FOR_EACH(PortType, ptype) if ( isPortSupported(ptype) ) nb++; + if ( nb<=0 ) return label(); + return label() + " (" + type.label() + ")"; +} + +Programmer::Base *Programmer::Group::createProgrammer(bool targetSelfPowered, const Device::Data *data, const HardwareDescription &hd) const +{ + ::Programmer::Base *base = createBase(data); + Hardware *hardware = createHardware(*base, hd); + DeviceSpecific *ds = (data ? createDeviceSpecific(*base) : 0); + base->init(targetSelfPowered, hardware, ds); + return base; +} + +Debugger::Base *Programmer::Group::createDebugger(::Programmer::Base &base) const +{ + ::Debugger::Base *dbase = createDebuggerBase(base); + if (dbase) { + ::Debugger::DeviceSpecific *dspecific = createDebuggerDeviceSpecific(*dbase); + ::Debugger::Specific *specific = createDebuggerSpecific(*dbase); + dbase->init(dspecific, specific); + } + return dbase; +} + +bool Programmer::Group::checkConnection(const HardwareDescription &hd) const +{ + ::Programmer::Base *base = createProgrammer(false, 0, hd); + bool ok = base->simpleConnectHardware(); + delete base; + return ok; +} + +bool Programmer::Group::isSoftware() const +{ + FOR_EACH(PortType, type) if ( isPortSupported(type) ) return false; + return true; +} diff --git a/src/progs/base/prog_group.h b/src/progs/base/prog_group.h new file mode 100644 index 0000000..07807fe --- /dev/null +++ b/src/progs/base/prog_group.h @@ -0,0 +1,69 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PROG_GROUP_H +#define PROG_GROUP_H + +class QWidget; +#include "common/common/group.h" +#include "common/port/port.h" +#include "common/common/purl_base.h" +#include "generic_prog.h" +namespace Device { class Data; } +namespace Debugger { class Base; class Specific; class DeviceSpecific; } +namespace Hardware { class Config; } + +namespace Programmer +{ +class Base; +class Hardware; +class DeviceSpecific; +class ConfigWidget; + +enum Property { NoProperty = 0, Programmer = 1, Debugger = 2, + CanReleaseReset = 4, HasFirmware = 8, CanUploadFirmware = 16, + NeedDeviceSpecificFirmware = 32, HasSelfTest = 64, + CanReadMemory = 128, HasConnectedState = 256 }; +Q_DECLARE_FLAGS(Properties, Property) +Q_DECLARE_OPERATORS_FOR_FLAGS(Properties) + +enum TargetPowerMode { TargetPowerModeFromConfig, TargetSelfPowered, TargetExternallyPowered }; + +enum { Nb_InputFileTypes = 3 }; +extern const PURL::FileType INPUT_FILE_TYPE_DATA[Nb_InputFileTypes]; + +class Group : public ::Group::Base +{ +public: + virtual QString xmlName() const { return name(); } + virtual ::Hardware::Config *hardwareConfig() const { return 0; } + virtual Properties properties() const = 0; + virtual QString statusLabel(PortType type) const; + virtual bool canReadVoltages() const = 0; + virtual TargetPowerMode targetPowerMode() const = 0; + bool isDebugger() const { return ( properties() & Debugger ); } + bool isSoftware() const; + virtual bool isPortSupported(PortType type) const = 0; + virtual bool checkConnection(const HardwareDescription &hd) const; + ::Programmer::Base *createProgrammer(bool targetSelfPowered, const Device::Data *data, const HardwareDescription &hd) const; + ::Debugger::Base *createDebugger(::Programmer::Base &) const; + virtual uint maxNbBreakpoints(const Device::Data *) const { return 0; } + virtual bool isInputFileTypeSupported(PURL::FileType) const { return false; } + virtual ::Programmer::Base *createBase(const Device::Data *data) const = 0; + +protected: + virtual Hardware *createHardware(::Programmer::Base &base, const HardwareDescription &hd) const = 0; + virtual DeviceSpecific *createDeviceSpecific(::Programmer::Base &base) const = 0; + virtual ::Debugger::Base *createDebuggerBase(::Programmer::Base &) const { return 0; } + virtual ::Debugger::Specific *createDebuggerSpecific(::Debugger::Base &) const { return 0; } + virtual ::Debugger::DeviceSpecific *createDebuggerDeviceSpecific(::Debugger::Base &base) const = 0; +}; + +} // namespace + +#endif diff --git a/src/progs/base/prog_specific.cpp b/src/progs/base/prog_specific.cpp new file mode 100644 index 0000000..a372e92 --- /dev/null +++ b/src/progs/base/prog_specific.cpp @@ -0,0 +1,51 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "prog_specific.h" + +#include "generic_prog.h" + +//----------------------------------------------------------------------------- +Programmer::DeviceSpecific::DeviceSpecific(Programmer::Base &base) + : Log::Base(&base), _base(base) +{} + +//----------------------------------------------------------------------------- +Programmer::Hardware::Hardware(Programmer::Base &base, Port::Base *port, const QString &name) + : Log::Base(&base), _port(port), _name(name), _base(base) +{} + +Programmer::Hardware::~Hardware() +{ + delete _port; +} + +bool Programmer::Hardware::connectHardware() +{ + if (_port) _port->close(); + return internalConnectHardware(); +} + +void Programmer::Hardware::disconnectHardware() +{ + if (_port) _port->close(); + internalDisconnectHardware(); +} + +bool Programmer::Hardware::rawWrite(const QString &data) +{ + Q_ASSERT(_port); + QByteArray a = toAscii(data); + return _port->send(a.data(), a.count()); +} + +bool Programmer::Hardware::rawRead(uint size, QString &data) +{ + Q_ASSERT(_port); + return _port->receive(size, data); +} diff --git a/src/progs/base/prog_specific.h b/src/progs/base/prog_specific.h new file mode 100644 index 0000000..1703bcb --- /dev/null +++ b/src/progs/base/prog_specific.h @@ -0,0 +1,61 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PROG_SPECIFIC_H +#define PROG_SPECIFIC_H + +#include + +#include "common/global/log.h" +#include "common/port/port_base.h" +#include "common/global/progress_monitor.h" +#include "hardware_config.h" + +namespace Programmer +{ +class Base; + +//----------------------------------------------------------------------------- +class DeviceSpecific : public Log::Base +{ +public: + DeviceSpecific(::Programmer::Base &base); + virtual bool setTargetPowerOn(bool on) = 0; + +protected: + ::Programmer::Base &_base; + + virtual bool setPowerOff() = 0; + virtual bool setPowerOn() = 0; +}; + +//----------------------------------------------------------------------------- +class Hardware : public Log::Base +{ +public: + Hardware(::Programmer::Base &base, Port::Base *port, const QString &name); + virtual ~Hardware(); + Port::Description portDescription() const { return _port->description(); } + QString name() const { return _name; } + bool connectHardware(); + bool rawWrite(const QString &data); + bool rawRead(uint size, QString &data); + void disconnectHardware(); + +protected: + Port::Base *_port; + QString _name; + ::Programmer::Base &_base; + + virtual bool internalConnectHardware() = 0; + virtual void internalDisconnectHardware() {} +}; + +} // namespace + +#endif diff --git a/src/progs/bootloader/Makefile.am b/src/progs/bootloader/Makefile.am new file mode 100644 index 0000000..490a53d --- /dev/null +++ b/src/progs/bootloader/Makefile.am @@ -0,0 +1,3 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +SUBDIRS = base gui diff --git a/src/progs/bootloader/base/Makefile.am b/src/progs/bootloader/base/Makefile.am new file mode 100644 index 0000000..7c7230d --- /dev/null +++ b/src/progs/bootloader/base/Makefile.am @@ -0,0 +1,5 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libbootloader.la +libbootloader_la_SOURCES = bootloader_prog.cpp bootloader.cpp diff --git a/src/progs/bootloader/base/base.pro b/src/progs/bootloader/base/base.pro new file mode 100644 index 0000000..f53b730 --- /dev/null +++ b/src/progs/bootloader/base/base.pro @@ -0,0 +1,6 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/lib.pro) + +TARGET = bootloader +HEADERS += bootloader.h bootloader_prog.h +SOURCES += bootloader.cpp bootloader_prog.cpp diff --git a/src/progs/bootloader/base/bootloader.cpp b/src/progs/bootloader/base/bootloader.cpp new file mode 100644 index 0000000..a45a23f --- /dev/null +++ b/src/progs/bootloader/base/bootloader.cpp @@ -0,0 +1,9 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "bootloader.h" diff --git a/src/progs/bootloader/base/bootloader.h b/src/progs/bootloader/base/bootloader.h new file mode 100644 index 0000000..08a0730 --- /dev/null +++ b/src/progs/bootloader/base/bootloader.h @@ -0,0 +1,42 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef BOOTLOADER_H +#define BOOTLOADER_H + +#include "devices/pic/prog/pic_prog.h" + +namespace Bootloader +{ +//----------------------------------------------------------------------------- +class Hardware : public ::Programmer::PicHardware +{ +public: + Hardware(::Programmer::Base &base, Port::Base *port) : ::Programmer::PicHardware(base, port, QString::null) {} + virtual bool write(Pic::MemoryRangeType type, const Device::Array &data) = 0; + virtual bool read(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata) = 0; + virtual bool internalConnectHardware() = 0; + virtual bool openPort() { return _port->open(); } +}; + +//----------------------------------------------------------------------------- +class DeviceSpecific : public ::Programmer::PicDeviceSpecific +{ +public: + DeviceSpecific(::Programmer::Base &base) : ::Programmer::PicDeviceSpecific(base) {} + Hardware &hardware() { return static_cast(*_base.hardware()); } + virtual bool setPowerOff() { return false; } + virtual bool setPowerOn() { return false; } + virtual bool setTargetPowerOn(bool) { return true; } + virtual bool doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata) { return hardware().read(type, data, vdata); } + virtual bool doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool) { return hardware().write(type, data); } +}; + +} // namespace + +#endif diff --git a/src/progs/bootloader/base/bootloader_prog.cpp b/src/progs/bootloader/base/bootloader_prog.cpp new file mode 100644 index 0000000..61167f8 --- /dev/null +++ b/src/progs/bootloader/base/bootloader_prog.cpp @@ -0,0 +1,25 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "bootloader_prog.h" + +#include "progs/base/prog_config.h" + +//----------------------------------------------------------------------------- +Bootloader::ProgrammerBase::ProgrammerBase(const Programmer::Group &group, const Pic::Data *data, const char *name) + : Programmer::PicBase(group, data, name) +{} + +//----------------------------------------------------------------------------- +bool Bootloader::Group::checkConnection(const ::Programmer::HardwareDescription &hd) const +{ + ::Programmer::Base *base = createProgrammer(false, 0, hd); + bool ok = static_cast(base->hardware())->openPort(); + delete base; + return ok; +} diff --git a/src/progs/bootloader/base/bootloader_prog.h b/src/progs/bootloader/base/bootloader_prog.h new file mode 100644 index 0000000..7b9749e --- /dev/null +++ b/src/progs/bootloader/base/bootloader_prog.h @@ -0,0 +1,37 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef BOOTLOADER_PROG_H +#define BOOTLOADER_PROG_H + +#include "common/global/generic_config.h" +#include "bootloader.h" + +namespace Bootloader +{ +//----------------------------------------------------------------------------- +class ProgrammerBase : public Programmer::PicBase +{ +Q_OBJECT +public: + ProgrammerBase(const Programmer::Group &group, const Pic::Data *data, const char *name); + +protected: + Hardware &hardware() { return static_cast(*_hardware); } +}; + +//----------------------------------------------------------------------------- +class Group : public ::Programmer::PicGroup +{ +public: + virtual bool checkConnection(const ::Programmer::HardwareDescription &hd) const; +}; + +} // namespace + +#endif diff --git a/src/progs/bootloader/bootloader.pro b/src/progs/bootloader/bootloader.pro new file mode 100644 index 0000000..fe430fe --- /dev/null +++ b/src/progs/bootloader/bootloader.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = base diff --git a/src/progs/bootloader/gui/Makefile.am b/src/progs/bootloader/gui/Makefile.am new file mode 100644 index 0000000..d52b42b --- /dev/null +++ b/src/progs/bootloader/gui/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libbootloaderui.la +libbootloaderui_la_LDFLAGS = $(all_libraries) +libbootloaderui_la_SOURCES = bootloader_ui.cpp diff --git a/src/progs/bootloader/gui/bootloader_ui.cpp b/src/progs/bootloader/gui/bootloader_ui.cpp new file mode 100644 index 0000000..df8595f --- /dev/null +++ b/src/progs/bootloader/gui/bootloader_ui.cpp @@ -0,0 +1,9 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "bootloader_ui.h" diff --git a/src/progs/bootloader/gui/bootloader_ui.h b/src/progs/bootloader/gui/bootloader_ui.h new file mode 100644 index 0000000..386c412 --- /dev/null +++ b/src/progs/bootloader/gui/bootloader_ui.h @@ -0,0 +1,30 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef BOOTLOADER_UI_H +#define BOOTLOADER_UI_H + +#include + +#include "progs/gui/prog_group_ui.h" +#include "progs/gui/prog_config_widget.h" + +namespace Bootloader +{ + +//---------------------------------------------------------------------------- +class GroupUI : public ::Programmer::GroupUI +{ +public: + virtual bool hasAdvancedDialog() const { return false; } + virtual ::Programmer::AdvancedDialog *createAdvancedDialog(::Programmer::Base &, QWidget *) const { return 0; } +}; + +} // namespace + +#endif diff --git a/src/progs/direct/Makefile.am b/src/progs/direct/Makefile.am new file mode 100644 index 0000000..fccf96d --- /dev/null +++ b/src/progs/direct/Makefile.am @@ -0,0 +1,3 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +SUBDIRS = xml base gui diff --git a/src/progs/direct/base/Makefile.am b/src/progs/direct/base/Makefile.am new file mode 100644 index 0000000..99070fe --- /dev/null +++ b/src/progs/direct/base/Makefile.am @@ -0,0 +1,13 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libdirectprog.la +libdirectprog_la_SOURCES = direct_pic.cpp direct_baseline.cpp direct_16.cpp \ + direct_16F.cpp direct_18.cpp direct_18F.cpp direct_prog.cpp direct_prog_config.cpp \ + direct_data.cpp direct_mem24.cpp direct.cpp +libdirectprog_la_DEPENDENCIES = direct_data.cpp + +noinst_DATA = direct.xml +direct_data.cpp: ../xml/xml_direct_parser direct.xml + ../xml/xml_direct_parser +CLEANFILES = direct_data.cpp diff --git a/src/progs/direct/base/base.pro b/src/progs/direct/base/base.pro new file mode 100644 index 0000000..97253b4 --- /dev/null +++ b/src/progs/direct/base/base.pro @@ -0,0 +1,10 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/lib.pro) + +TARGET = directprog +HEADERS += direct.h direct_data.h direct_pic.h direct_mem24.h direct_prog.h \ + direct_prog_config.h direct_baseline.h direct_16.h direct_16F.h \ + direct_18.h direct_18F.h +SOURCES += direct.cpp direct_data.cpp direct_pic.cpp direct_mem24.cpp direct_prog.cpp \ + direct_prog_config.cpp direct_baseline.cpp direct_16.cpp direct_16F.cpp \ + direct_18.cpp direct_18F.cpp diff --git a/src/progs/direct/base/direct.cpp b/src/progs/direct/base/direct.cpp new file mode 100644 index 0000000..fc53cf3 --- /dev/null +++ b/src/progs/direct/base/direct.cpp @@ -0,0 +1,394 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * Copyright (C) Brian C. Lane * + * * + * 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. * + ***************************************************************************/ +#include "direct.h" + +#include + +#include "common/port/parallel.h" +#include "common/port/serial.h" +#include "progs/base/generic_prog.h" +#include "direct_prog_config.h" + +using namespace std; + +//----------------------------------------------------------------------------- +const Direct::PinData Direct::PIN_DATA[Nb_PinTypes] = { + { I18N_NOOP("MCLR (Vpp)"), "0 V", "13 V", "vpp", + I18N_NOOP("The VPP pin is used to select the high voltage programming mode."), + Port::Out, false, I18N_NOOP("Check this box to turn voltage on/off for this pin.") }, + { I18N_NOOP("Power (Vdd)"), "0 V", "5 V", "vdd", + I18N_NOOP("The VDD pin is used to apply 5V to the programmed device.\nMust be set to GND if your programmer doesn't control the VDD line."), + Port::Out, true, I18N_NOOP("Check this box to turn voltage on/off for this pin.") }, + { I18N_NOOP("Clock"), "0 V", "5 V", "clock", + I18N_NOOP("The CLOCK pin is used to synchronize serial data of the DATA IN and DATA OUT pins."), + Port::Out, false, I18N_NOOP("Check this box to turn voltage on/off for this pin.") }, + { I18N_NOOP("Data Out"), "0 V", "5 V", "datao", + I18N_NOOP("The DATA OUT pin is used to send data to the programmed device."), + Port::Out, false, I18N_NOOP("Check this box to turn voltage on/off for this pin.") }, + { I18N_NOOP("Data In"), "0 V", "5 V", "datai", + I18N_NOOP("The DATA IN pin is used to receive data from the programmed device."), + Port::In, false, I18N_NOOP("This pin is driven by the programmed device.\nWithout device, it must follow the \"Data out\" pin (when powered on).") }, + { I18N_NOOP("Data R/W"), "Data in", "Data out", "drw", + I18N_NOOP("The DATA RW pin selects the direction of data buffer.\nMust be set to GND if your programmer does not use bi-directionnal buffer."), + Port::Out, true, I18N_NOOP("Check this box to change DATA buffer direction.") } +}; + +//----------------------------------------------------------------------------- +namespace Direct +{ +class SerialPort : public Port::Serial +{ +public: + SerialPort(const QString &device, Log::Base &base) + : Serial(device, NeedBreak, base) {} + + bool open() { + if ( !Port::Serial::open() ) return false; + if ( !setMode(IgnoreBreak | IgnoreParity, ByteSize8 | EnableReceiver | IgnoreControlLines, S9600, 0) ) return false; + // set up lines for "idle state" ??? + return true; + } +}; +} // namespace + +//----------------------------------------------------------------------------- +Direct::Hardware::Hardware(::Programmer::Base &base, Port::Base *port, const HardwareData &data) + : ::Programmer::PicHardware(base, port, data.name), _data(data.data) +{} + +bool Direct::Hardware::internalConnectHardware() +{ + if ( !_port->open() ) return false; + + // keep the safe state of rw (read)... + setPin(DataOut, Low); + setPin(Clock, Low); + setPin(Vpp, Off); + setPin(Vdd, Off); + setRead(); + + return true; +} + +void Direct::Hardware::setPin(PinType type, bool on) +{ + int pin = _data.pins[type]; + if ( isGroundPin(pin) ) return; + uint p = (pin<0 ? -pin : pin)-1; + //log(Log::DebugLevel::Extra, QString("Hardware::setPin %1 %2: %3 %4").arg(PIN_DATA[type].label).arg(pin).arg(on).arg(_data.clockDelay)); + _port->setPinOn(p, on, (pin<0 ? Port::NegativeLogic : Port::PositiveLogic)); + if ( type==Clock ) Port::usleep(_data.clockDelay); +} + +bool Direct::Hardware::readBit() +{ + int pin = _data.pins[DataIn]; + Q_ASSERT( pin!=0 ); + uint p = (pin<0 ? -pin : pin)-1; + bool on; + _port->readPin(p, (pin<0 ? Port::NegativeLogic : Port::PositiveLogic), on); + //log(Log::DebugLevel::Extra, QString("Hardware::read DataIn %2: %3").arg(pin).arg(on)); + return on; +} + +uint Direct::Hardware::nbPins(Port::IODir dir) const +{ + return _port->pinData(dir).count(); +} + +QString Direct::Hardware::pinLabelForIndex(Port::IODir dir, uint i) const +{ + Port::PinData pd = _port->pinData(dir)[i]; + return QString("%1 (%2)").arg(pd.pin+1).arg(pd.label); +} + +Port::IODir Direct::Hardware::ioTypeForPin(int pin) const +{ + if ( isGroundPin(pin) ) return Port::NoIO; + uint p = (pin<0 ? -pin : pin)-1; + return _port->ioDir(p); +} + +uint Direct::Hardware::pinForIndex(Port::IODir dir, uint i) const +{ + Q_ASSERT( i<=uint(_port->pinData(dir).count()) ); + if ( i==uint(_port->pinData(dir).count()) ) return _port->groundPin()+1; + return _port->pinData(dir)[i].pin+1; +} + +uint Direct::Hardware::indexForPin(Port::IODir dir, int pin) const +{ + QValueVector v = _port->pinData(dir); + Q_ASSERT( pin!=0 ); + uint p = (pin<0 ? -pin : pin)-1; + for (uint i=0; iisGroundPin(p); +} + +bool Direct::operator !=(const HData &d1, const HData &d2) +{ + for (uint i=0; i> t ; + } while(t[0] != 'y' && t[0] != 'n') ; + if( t[0] == 'n') return -1 ; + + + // stage 1 - hard initialization + // setpins("parallel","/dev/parport0", -5, -4, 3, 2, 10) ; + + //Default RW line not used... + HData data = { { 3, 5, 7, 4, 8, 0 }, 0 }; + Log::ConsoleView view; + Direct::Programmer programmer; + programmer.setView(&view); + SerialHardware hw(programmer, "/dev/ttyS0", data); + if ( !hw.connectHardware() ) { + cout << "Direct::Hardware initialization error" <> t ; + } while(t[0] != 'y' && t[0] != 'n') ; + + if( t[0] == 'n') return 2 ; + + // stage 3 - data out check + hw.setPin(DataOut, High); + cout << "16F84 pin 13 (data out) must be 5V"<> t ; + } while(t[0] != 'y' && t[0] != 'n') ; + hw.setPin(DataOut, Low); + + if( t[0] == 'n') return 3 ; + + // stage 4 - clock check + hw.setPin(Clock, High); + cout << "16F84 pin 12 (clock) must be 5V"<> t ; + } while(t[0] != 'y' && t[0] != 'n') ; + hw.setPin(Clock, Low); + + if( t[0] == 'n') return 4 ; + + // stage 5 - VDD check + hw.setPin(Vdd, On); + cout << "16F84 pin 14 (power) must be 5V"<> t ; + } while(t[0] != 'y' && t[0] != 'n') ; + hw.setPin(Vdd, Off) ; + + if( t[0] == 'n') return 5 ; + + // stage 6 - VPP check + hw.setPin(Vpp, On); + cout << "16F84 pin 4 (VDD) must be between 13V and 14V"<> t ; + } while(t[0] != 'y' && t[0] != 'n') ; + hw.setPin(Vpp , Off); + + if( t[0] == 'n') return 6 ; + + // stage 7 - test input data + // set data out hi, because bi-directionnal + // on pin 13 uses the open collector capability of 7407 + hw.setPin(DataOut, High); + int in = hw.readBit(); + if( !in ) + { + cout << "DataIn error (16F84 pin 13) : must be 5V and is not" << endl ; + return 7 ; + } + cout << "Please set 16F84 pin 13 (DataIn) low " << + "(connect it to 16F84 pin 5 - GND)" << endl ; + do + { + cout << "Done ? (y/n) " ; + cin >> t ; + } while(t[0] != 'y' && t[0] != 'n') ; + + in = hw.readBit(); + if(in ) + { + cout << "DataIn error (pin 13) : must be 0V and is not" << endl ; + return 7 ; + } + + cout << "Congratulations! - Direct::Hardware is OK." <> t ; + } while(t[0] != 'y' && t[0] != 'n') ; + if( t[0] == 'n') return -1 ; + + + // stage 1 - hard initialization + //Default Line RW not used... + HData data = { { -5, -4, 3, 2, 10, 25 }, 0 }; + Log::ConsoleView view; + Log::Manager manager; + manager.setView(&view); + ParallelHardware hw("/dev/parport0", manager, data); + if ( !hw.connectHardware() ) { + cout << "Direct::Hardware initialization error" <chip)"<> " ; + cin >> cmd ; + } while(cmd < 1 || cmd > 4) ; + + if(cmd == 4) return 2 ; + else if ( cmd == 1) + { + for(long j=0 ; j < loop ; ++j) + { + hw.setPin(Clock, Low); + hw.setPin(Clock, High); + } + } + + else if ( cmd == 2) + { + for(long j=0 ; j < loop ; ++j) + { + hw.setPin(Clock, Low); + Port::usleep(100); + hw.setPin(Clock, High); + Port::usleep(100); + } + } + + else if ( cmd == 3) { + for (long j=0; j>= 1; + } + hw.setPin(DataOut, High); + } + } + + return 0; +} +*/ diff --git a/src/progs/direct/base/direct.h b/src/progs/direct/base/direct.h new file mode 100644 index 0000000..6a890b0 --- /dev/null +++ b/src/progs/direct/base/direct.h @@ -0,0 +1,90 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * Copyright (C) Brian C. Lane * + * * + * 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. * + ***************************************************************************/ +#ifndef DIRECT_H +#define DIRECT_H + +#include "devices/pic/prog/pic_prog.h" + +namespace Direct +{ +enum State { Low = 0, High = 1, Off = Low, On = High }; +enum PinType { Vpp = 0, Vdd, Clock, DataOut, DataIn, DataRW, Nb_PinTypes }; +struct PinData { + const char *label, *offLabel, *onLabel, *key, *comment; + Port::IODir dir; + bool canBeGround; + const char *testComment; +}; +extern const PinData PIN_DATA[Nb_PinTypes]; + +//----------------------------------------------------------------------------- +class HardwareData; +enum Type { Normal, EPEToolkitMK3 }; +struct HData +{ + int pins[Nb_PinTypes]; + uint clockDelay; + Type type; +}; + +class Hardware : public ::Programmer::PicHardware +{ +public: + static Hardware *create(Port::Base *port, const Device::Data &device, const HData &data); + +public: + Hardware(::Programmer::Base &base, Port::Base *port, const HardwareData &data); + bool readBit(); + void setPin(PinType type, bool on); + void setRead() { setPin(DataRW, true); } + void setWrite() { setPin(DataRW, false); } + + uint nbPins(Port::IODir dir) const; + QString pinLabelForIndex(Port::IODir dir, uint i) const; + Port::IODir ioTypeForPin(int pin) const; + uint pinForIndex(Port::IODir dir, uint i) const; + uint indexForPin(Port::IODir dir, int pin) const; + bool isGroundPin(int pin) const; + Type type() const { return _data.type; } + + // hardware test --- please use it for a newly + // designed/constructed programmer board + // because pin assignation is hard coded in this + // routine, you might have to edit it. ++Gib: + //static int hardware_test(); + // timing test --- please use it to ensure that + // the program meets the timing specifications + //static int timing_test(); + +private: + HData _data; + + virtual bool internalConnectHardware(); + + friend class Programmer; +}; +extern bool operator !=(const HData &d1, const HData &d2); + +class SerialHardware : public Hardware +{ +public: + SerialHardware(::Programmer::Base &base, const QString &portDevice, const HardwareData &data); +}; + +class ParallelHardware : public Hardware +{ +public: + ParallelHardware(::Programmer::Base &base, const QString &portDevice, const HardwareData &data); +}; + +} // namespace + +#endif diff --git a/src/progs/direct/base/direct.xml b/src/progs/direct/base/direct.xml new file mode 100644 index 0000000..4997450 --- /dev/null +++ b/src/progs/direct/base/direct.xml @@ -0,0 +1,291 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/progs/direct/base/direct_16.cpp b/src/progs/direct/base/direct_16.cpp new file mode 100644 index 0000000..124b35e --- /dev/null +++ b/src/progs/direct/base/direct_16.cpp @@ -0,0 +1,150 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * Copyright (C) 2003-2005 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "direct_16.h" + +#include "common/global/global.h" + +//---------------------------------------------------------------------------- +void Direct::pic16::send_bits(BitValue d, uint nbb) +{ + hardware().setWrite(); + for (uint x = nbb; x; --x) { + hardware().setPin(Clock, High); + if ( d.bit(0) ) hardware().setPin(DataOut, High); + else hardware().setPin(DataOut, Low); + Port::usleep(1+_clockDelay); + hardware().setPin(Clock, Low); + Port::usleep(1+_clockDelay); + d >>= 1; + } + hardware().setPin(DataOut, High); + hardware().setRead(); +} + +void Direct::pic16::send_word(BitValue d) +{ + hardware().setWrite(); + d <<= 1; // insert start bit + for (uint x = 0; x<16; x++) { + hardware().setPin(Clock, High); + if ( d.bit(0) ) hardware().setPin(DataOut, High); + else hardware().setPin(DataOut, Low); + Port::usleep(1+_clockDelay) ; // needed for slow programmers/fast PCs + hardware().setPin(Clock, Low); + Port::usleep(1+_clockDelay) ; + d >>= 1; // Move the data over 1 bit + } + hardware().setPin(DataOut, High); // Added for ITU-1 support + hardware().setRead(); +} + +// Read 14 bits of data from the PIC +// clock idles low, change data. 1 start bit, 1 stop bit, data valid on falling edge. +BitValue Direct::pic16::get_word() +{ + hardware().setRead(); + BitValue ind = 0; + hardware().setPin(DataOut, High); + for (uint x = 16; x ; --x) { + hardware().setPin(Clock, High); + Port::usleep(1+_clockDelay); + if ( hardware().readBit() ) ind |= 0x8000; + else ind = ind.maskWith(0x7FFF); + ind >>= 1; + hardware().setPin(Clock, Low); + Port::usleep(1+_clockDelay); + } + return ind; +} + +bool Direct::pic16::incrementPC(uint steps) +{ + for (uint i=0; iactions & ::Programmer::OnlyProgrammedVerify; + const Device::Array wdata = static_cast(vdata->memory).arrayForWriting(type); + if (only) nbWords = findNonMaskEnd(type, wdata)+1; + } + BitValue mask = device().mask(type); + for (uint i = 0; i * + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef DIRECT_16_H +#define DIRECT_16_H + +#include "direct_pic.h" + +namespace Direct +{ +//---------------------------------------------------------------------------- +class pic16 : public Pic8DeviceSpecific +{ +public: + pic16(::Programmer::Base &base) : Pic8DeviceSpecific(base) {} + virtual BitValue get_word(); + virtual BitValue get_byte() { return get_word().maskWith(0xFF); } + virtual void send_word(BitValue word); + virtual void send_bits(BitValue d, uint nbBits); + virtual void send_cmd(BitValue d) { send_bits(d, 6); } + virtual bool doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata); + virtual bool doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force); + +protected: + virtual bool setPowerOn() { return setPowerOnVddFirst(); } + virtual bool skipMaskWords(Pic::MemoryRangeType type, const Device::Array &data, uint &i, bool force); + virtual bool incrementPC(uint steps); + virtual bool gotoMemory(Pic::MemoryRangeType type) = 0; + virtual uint nbWordsCodeProg() const { return 1; } + virtual void startProg(Pic::MemoryRangeType) { pulseEngine("k8,"); } + virtual uint waitProgTime(Pic::MemoryRangeType type) const = 0; + virtual void endProg(Pic::MemoryRangeType) {} + virtual bool writeWords(Pic::MemoryRangeType type, const Device::Array &data, uint &i, bool force); + virtual bool writeWords(Pic::MemoryRangeType type, const Device::Array &data, uint i); + virtual BitValue readWord(Pic::MemoryRangeType type); +}; + +} // namespace + +#endif diff --git a/src/progs/direct/base/direct_16F.cpp b/src/progs/direct/base/direct_16F.cpp new file mode 100644 index 0000000..feeb185 --- /dev/null +++ b/src/progs/direct/base/direct_16F.cpp @@ -0,0 +1,275 @@ +/*************************************************************************** + * Copyright (C) 2003-2005 Alain Gibaud * + * Copyright (C) 2006 Nicolas Hadacek * + * Copyright (C) 2004 Keith Baker [16F7X] * + * * + * 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. * + ***************************************************************************/ +#include "direct_16F.h" + +#include "common/global/global.h" + +//----------------------------------------------------------------------------- +bool Direct::P16F::gotoTestMemory() +{ + pulseEngine("k0,S,", 0x3FFF); // PC set at 0x2000 + return true; +} + +bool Direct::P16F::gotoMemory(Pic::MemoryRangeType type) +{ + switch (type.type()) { + case Pic::MemoryRangeType::Code: return true; + case Pic::MemoryRangeType::Eeprom: return true; + case Pic::MemoryRangeType::UserId: return gotoTestMemory(); + case Pic::MemoryRangeType::DeviceId: return (gotoTestMemory() && incrementPC(6)); + case Pic::MemoryRangeType::Config: return (gotoTestMemory() && incrementPC(7)); + case Pic::MemoryRangeType::Cal: + if ( device().range(type).start==device().range(Pic::MemoryRangeType::Code).end+1 ) + return incrementPC(device().range(type).start.toUInt()); + return (gotoTestMemory() && incrementPC(8)); + case Pic::MemoryRangeType::CalBackup: + case Pic::MemoryRangeType::DebugVector: + case Pic::MemoryRangeType::HardwareStack: + case Pic::MemoryRangeType::ProgramExecutive: + case Pic::MemoryRangeType::Nb_Types: break; + } + Q_ASSERT(false); + return false; +} + +//----------------------------------------------------------------------------- +bool Direct::P16F8X::doEraseRange(Pic::MemoryRangeType type) +{ + if ( type==Pic::MemoryRangeType::Code ) { + pulseEngine("k2,S,k1,k7,k8,w10000,k1,k7", 0x3FFF); // bulk erase code + return true; + } + if ( type==Pic::MemoryRangeType::Eeprom ) { + pulseEngine("k3,S,k1,k7,k8,w10000,k1,k7", 0x3FFF); // bulk erase data + return true; + } + return false; +} + +bool Direct::P16F8X::doErase(bool isProtected) +{ + if (isProtected) { // disable code protection + erase code and data + gotoMemory(Pic::MemoryRangeType::Config); + pulseEngine("k1,k7,k8,w10000,k1,k7"); + } else { + doEraseRange(Pic::MemoryRangeType::Code); + doEraseRange(Pic::MemoryRangeType::Eeprom); + } + doEmulatedEraseRange(Pic::MemoryRangeType::UserId); + doEmulatedEraseRange(Pic::MemoryRangeType::Config); + return true; +} + +//----------------------------------------------------------------------------- +uint Direct::P16F84A::waitProgTime(Pic::MemoryRangeType type) const +{ + if ( type==Pic::MemoryRangeType::Config || type==Pic::MemoryRangeType::UserId ) return 4000 + 4000; // prog +erase + return 4000; +} + +void Direct::P16F84A::startProg(Pic::MemoryRangeType type) +{ + if ( type==Pic::MemoryRangeType::Code || type==Pic::MemoryRangeType::Eeprom ) pulseEngine("k24,"); + else pulseEngine("k8,"); +} + +bool Direct::P16F84A::doEraseRange(Pic::MemoryRangeType type) +{ + if ( type==Pic::MemoryRangeType::Code ) { + pulseEngine("k2,S,k9,k8,w10000", 0x3FFF); // bulk erase code + return true; + } + if ( type==Pic::MemoryRangeType::Eeprom ) { + pulseEngine("k3,S,k11,k8,w10000", 0x3FFF); // bulk erase data + return true; + } + return false; +} + +bool Direct::P16F84A::doErase(bool isProtected) +{ + if (isProtected) { // disable code protection and erase + gotoMemory(Pic::MemoryRangeType::Config); + pulseEngine("k1,k7,k8,w10000,k1,k7"); + } else { + doEraseRange(Pic::MemoryRangeType::Code); + doEraseRange(Pic::MemoryRangeType::Eeprom); + } + doEmulatedEraseRange(Pic::MemoryRangeType::UserId); + doEmulatedEraseRange(Pic::MemoryRangeType::Config); + return true; +} + +//----------------------------------------------------------------------------- +uint Direct::P16F7X::waitProgTime(Pic::MemoryRangeType) const +{ + if ( device().name()=="16F72" ) return 3000; + return 1000; +} + +bool Direct::P16F7X::doEraseRange(Pic::MemoryRangeType type) +{ + if ( type!=Pic::MemoryRangeType::Code ) return false; + Device::Array array; + if ( !doRead(Pic::MemoryRangeType::Config, array, 0) ) return false; + pulseEngine("k9w400000", 0x3FFF); // chip erase (should only need 30ms according to prog sheet) + return doWrite(Pic::MemoryRangeType::Config, array, true); +} + +bool Direct::P16F7X::doErase(bool) +{ + pulseEngine("k9w400000", 0x3FFF); // chip erase (should only need 30ms according to prog sheet) + return doEmulatedEraseRange(Pic::MemoryRangeType::UserId); +} + +//----------------------------------------------------------------------------- +// 16F628 seems to have problems with the standard 16F84 bulk +// erase when disabling code protection : the data memory is not set to 0xFF. +// This code adds a erase/programming pass on the data memory +bool Direct::P16F62X::doErase(bool isProtected) +{ + P16F84A::doErase(isProtected); + if (isProtected) return doEmulatedEraseRange(Pic::MemoryRangeType::Eeprom); + return true; +} + +//----------------------------------------------------------------------------- +bool Direct::P16F81X::doEraseRange(Pic::MemoryRangeType type) +{ + if ( type==Pic::MemoryRangeType::Code ) { + pulseEngine("k9w2000"); // bulk erase code: 2ms + return true; + } + if ( type==Pic::MemoryRangeType::Eeprom ) { + pulseEngine("k11w2000"); // bulk erase data: 2ms + return true; + } + return false; +} + +bool Direct::P16F81X::doErase(bool) +{ + pulseEngine("k31w8000"); // chip erase: 8ms + return true; +} + +//----------------------------------------------------------------------------- +uint Direct::P12F675::waitProgTime(Pic::MemoryRangeType type) const +{ + if ( type==Pic::MemoryRangeType::Eeprom ) return 6000; + return 2500; +} + +bool Direct::P12F675::doEraseRange(Pic::MemoryRangeType type) +{ + if ( type==Pic::MemoryRangeType::Code ) { + pulseEngine("k9,w9000"); // bulk erase code + return true; + } + if ( type==Pic::MemoryRangeType::Eeprom ) { + pulseEngine("k11,w9000"); // bulk erase data + return true; + } + return false; +} + +bool Direct::P12F675::doErase(bool) +{ + pulseEngine("k0,S,", 0x3FFF); + doEraseRange(Pic::MemoryRangeType::Code); + doEraseRange(Pic::MemoryRangeType::Eeprom); + return true; +} + +//----------------------------------------------------------------------------- +uint Direct::P16F62XA::waitProgTime(Pic::MemoryRangeType type) const +{ + if ( type==Pic::MemoryRangeType::Eeprom ) return 6000; + return 2500; +} + +bool Direct::P16F62XA::doEraseRange(Pic::MemoryRangeType type) +{ + if ( type==Pic::MemoryRangeType::Code ) { + pulseEngine("k9,w12000"); // bulk erase code + return true; + } + if ( type==Pic::MemoryRangeType::Eeprom ) { + pulseEngine("k11,w12000"); // bulk erase data + return true; + } + return false; +} + +bool Direct::P16F62XA::doErase(bool) +{ + pulseEngine("k0,S,w100", 0x3FFF); + doEraseRange(Pic::MemoryRangeType::Code); + doEraseRange(Pic::MemoryRangeType::Eeprom); + return true; +} + +//----------------------------------------------------------------------------- +bool Direct::P16F87XA::doEraseRange(Pic::MemoryRangeType type) +{ + if ( type==Pic::MemoryRangeType::Code ) { + pulseEngine("k9,w8000"); // bulk erase code + return true; + } + if ( type==Pic::MemoryRangeType::Eeprom ) { + pulseEngine("k11,w8000"); // bulk erase data + return true; + } + return false; +} + +bool Direct::P16F87XA::doErase(bool) +{ + // I use the command 31 twice because, sometimes, the prog + // memory is not totally erased. Not very elegant, but it works. + pulseEngine("k0,S,k31w8000,k31w8000", 0x3FFF); + return doEmulatedEraseRange(Pic::MemoryRangeType::UserId); +} + +//----------------------------------------------------------------------------- +bool Direct::P16F913::doEraseRange(Pic::MemoryRangeType type) +{ + if ( type==Pic::MemoryRangeType::Code ) { + pulseEngine("k9,w6000"); // bulk erase code + return true; + } + if ( type==Pic::MemoryRangeType::Eeprom ) { + pulseEngine("k11,w6000"); // bulk erase data + return true; + } + return false; +} + +bool Direct::P16F913::doErase(bool) +{ + // flow chart of figure 3.21 of prog sheet + doEraseRange(Pic::MemoryRangeType::Code); + pulseEngine("k0,S,", 0x3FFF); + doEraseRange(Pic::MemoryRangeType::Code); + doEraseRange(Pic::MemoryRangeType::Eeprom); + return true; +} + +//----------------------------------------------------------------------------- +bool Direct::P16F785::doErase(bool) +{ + // flow chart of figure 3.20 of prog sheet + pulseEngine("k0,S,", 0x3FFF); + doEraseRange(Pic::MemoryRangeType::Code); + doEraseRange(Pic::MemoryRangeType::Eeprom); + return true; +} diff --git a/src/progs/direct/base/direct_16F.h b/src/progs/direct/base/direct_16F.h new file mode 100644 index 0000000..0b0fca8 --- /dev/null +++ b/src/progs/direct/base/direct_16F.h @@ -0,0 +1,162 @@ +/*************************************************************************** + * Copyright (C) 2003-2005 Alain Gibaud * + * Copyright (C) 2006 Nicolas Hadacek * + * Copyright (C) 2004 Keith Baker [16F7X] * + * * + * 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. * + ***************************************************************************/ +#ifndef DIRECT_16F_HH +#define DIRECT_16F_HH + +#include "direct_16.h" + +namespace Direct +{ +//----------------------------------------------------------------------------- +class P16F : public pic16 +{ +public: + P16F(::Programmer::Base &base) : pic16(base) {} + bool gotoTestMemory(); + virtual bool gotoMemory(Pic::MemoryRangeType type); +}; + +//----------------------------------------------------------------------------- +class P16F8X : public P16F +{ +public: + P16F8X(::Programmer::Base &base) : P16F(base) {} + virtual bool doErase(bool isProtected); + virtual bool doEraseRange(Pic::MemoryRangeType type); + virtual uint waitProgTime(Pic::MemoryRangeType) const { return 20000; } +}; + +//----------------------------------------------------------------------------- +class P16CR8X : public P16F8X +{ +public: + P16CR8X(::Programmer::Base &base) : P16F8X(base) {} + virtual bool doErase(bool) { return false; } // #### can't the eeprom be bulk erased ??? + virtual bool doEraseRange(Pic::MemoryRangeType) { return false; } + // #### eeprom and config only can be programmed... +}; + +//----------------------------------------------------------------------------- +class P16F84A : public P16F +{ +public: + P16F84A(::Programmer::Base &base) : P16F(base) {} + virtual bool doEraseRange(Pic::MemoryRangeType type); + virtual bool doErase(bool isProtected); + virtual void startProg(Pic::MemoryRangeType type); + virtual uint waitProgTime(Pic::MemoryRangeType type) const; +}; + +typedef class P16F84A P16F87X; + +//----------------------------------------------------------------------------- +class P16F7X : public P16F +{ +public: + P16F7X(::Programmer::Base &base) : P16F(base) {} + virtual bool doEraseRange(Pic::MemoryRangeType type); + virtual bool doErase(bool isProtected); + uint nbWordsCodeProg() const { return 2; } + virtual uint waitProgTime(Pic::MemoryRangeType type) const; + virtual void endProg(Pic::MemoryRangeType) { pulseEngine("k14,"); } + virtual bool setPowerOn() { return setPowerOnVppFirst(); } +}; + +//----------------------------------------------------------------------------- +class P16F62X : public P16F84A +{ +public: + P16F62X(::Programmer::Base &base) : P16F84A(base) {} + virtual bool doErase(bool isProtected); + virtual uint waitProgTime(Pic::MemoryRangeType) const { return 8000; } + virtual bool setPowerOn() { return setPowerOnVppFirst(); } +}; + +//----------------------------------------------------------------------------- +class P16F81X : public P16F +{ +public: + P16F81X(::Programmer::Base &base) : P16F(base) {} + virtual bool doEraseRange(Pic::MemoryRangeType type); + virtual bool doErase(bool isProtected); + uint nbWordsCodeProg() const { return 4; } + virtual void startProg(Pic::MemoryRangeType) { pulseEngine("k24,"); } + virtual uint waitProgTime(Pic::MemoryRangeType) const { return 2000; } + virtual void endProg(Pic::MemoryRangeType) { pulseEngine("k23,"); } +}; + +//----------------------------------------------------------------------------- +class P12F675 : public P16F +{ +public: + P12F675(::Programmer::Base &base) : P16F(base) {} + virtual bool doEraseRange(Pic::MemoryRangeType type); + virtual bool doErase(bool isProtected); + virtual uint waitProgTime(Pic::MemoryRangeType type) const; + virtual bool setPowerOn() { return setPowerOnVppFirst(); } +}; + +//----------------------------------------------------------------------------- +class P16F62XA : public P16F +{ +public: + P16F62XA(::Programmer::Base &base) : P16F(base) {} + virtual bool doEraseRange(Pic::MemoryRangeType type); + virtual bool doErase(bool isProtected); + virtual uint waitProgTime(Pic::MemoryRangeType type) const; + virtual bool setPowerOn() { return setPowerOnVppFirst(); } +}; + +//----------------------------------------------------------------------------- +class P16F87XA : public P16F +{ +public: + P16F87XA(::Programmer::Base &base) : P16F(base) {} + virtual bool doEraseRange(Pic::MemoryRangeType type); + virtual bool doErase(bool isProtected); + virtual uint nbWordsCodeProg() const { return 8; } + virtual uint waitProgTime(Pic::MemoryRangeType) const { return 8000; } +}; + +//----------------------------------------------------------------------------- +class P16F913 : public P16F +{ +public: + P16F913(::Programmer::Base &base) : P16F(base) {} + virtual bool doEraseRange(Pic::MemoryRangeType type); + virtual bool doErase(bool isProtected); + virtual uint nbWordsCodeProg() const { return 4; } + virtual void startProg(Pic::MemoryRangeType) { pulseEngine("k24,"); } + virtual uint waitProgTime(Pic::MemoryRangeType) const { return 2500; } + virtual void endProg(Pic::MemoryRangeType) { pulseEngine("k10,w100"); } + virtual bool setPowerOn() { return setPowerOnVppFirst(); } +}; + +class P16F916 : public P16F913 +{ +public: + P16F916(::Programmer::Base &base) : P16F913(base) {} + virtual uint nbWordsCodeProg() const { return 8; } +}; + +typedef class P16F913 P12F6XX_16F6XX; + +class P16F785 : public P16F913 +{ +public: + P16F785(::Programmer::Base &base) : P16F913(base) {} + virtual bool doEraseRange(Pic::MemoryRangeType type); + virtual bool doErase(bool isProtected); +}; + +} // namespace + +#endif diff --git a/src/progs/direct/base/direct_18.cpp b/src/progs/direct/base/direct_18.cpp new file mode 100644 index 0000000..d512d32 --- /dev/null +++ b/src/progs/direct/base/direct_18.cpp @@ -0,0 +1,109 @@ +/*************************************************************************** + * Copyright (C) 2003-2005 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "direct_18.h" + +// Commands specific to 18F: +// xhh = send a 8 bits constant (hh must be a 2 digits hex constant) +// Xhhhh = send a 16 bits constant (hhhh must be a 4 digits hex constant) +bool Direct::P18::pulse(const char *&cmd, BitValue value, BitValue &res) +{ + switch (*cmd) { + case 'x': { + uint n; + sscanf(++cmd, "%02X", &n); + ++cmd; + log(Log::DebugLevel::Max, "SEND 1 byte constant : " + toHexLabel(n, 2)); + send_bits(n, 8); + break; + } + case 'X': { + uint n; + sscanf(++cmd,"%04X", &n); + cmd += 3; + log(Log::DebugLevel::Max, "SEND 2 bytes constant : " + toHexLabel(n, 4)); + send_bits(n, 16); + break; + } + default: return Pic8DeviceSpecific::pulse(cmd, value, res); + } + return true; +} + +void Direct::P18::send_word(BitValue d) +{ + hardware().setWrite(); + for (uint x = 0; x<16; x++) { + hardware().setPin(Clock, High); + if ( d.bit(0) ) hardware().setPin(DataOut, High); + else hardware().setPin(DataOut, Low); + Port::usleep(_clockDelay+5); + hardware().setPin(Clock, Low); + Port::usleep(_clockDelay+3); + d >>= 1; // Move the data over 1 bit + } + hardware().setPin(DataOut, High); + hardware().setRead(); +} + +BitValue Direct::P18::get_word() +{ + hardware().setRead(); + BitValue ind = 0; + send_cmd(9); + hardware().setPin(DataOut, High); + for (uint x = 0; x<16; x++) { + hardware().setPin(Clock, High); + Port::usleep(_clockDelay+5); + if ( x>7 && hardware().readBit() ) ind |= (1 << x-8); + hardware().setPin(Clock, Low); + Port::usleep(_clockDelay+3); + } + send_cmd(9); + hardware().setPin(DataOut, High); + for (uint x = 0; x<16; x++) { + hardware().setPin(Clock, High); + Port::usleep(_clockDelay+5); + if ( x>7 && hardware().readBit() ) ind |= (1 << x); + hardware().setPin(Clock, Low); + Port::usleep(_clockDelay+3); + } + return ind; +} + +BitValue Direct::P18::get_byte() +{ + hardware().setRead(); + BitValue ind = 0; + send_cmd(2); + hardware().setPin(DataOut, High); + for (uint x = 0; x<16; x++) { + hardware().setPin(Clock, High); + Port::usleep(_clockDelay+5); + if ( x>7 && hardware().readBit() ) ind |= (1 << x-8); + hardware().setPin(Clock, Low); + Port::usleep(_clockDelay+3); + } + return ind; +} + +void Direct::P18::send_bits(BitValue d, uint nbb) +{ + hardware().setWrite(); + for (int x = nbb; x; --x) { + hardware().setPin(Clock, High); + if ( d.bit(0) ) hardware().setPin(DataOut, High); + else hardware().setPin(DataOut, Low); + Port::usleep(_clockDelay+5); + hardware().setPin(Clock, Low); + Port::usleep(_clockDelay+3); + d >>= 1; // Move the data over 1 bit + } + hardware().setPin(DataOut, High); + hardware().setRead(); +} diff --git a/src/progs/direct/base/direct_18.h b/src/progs/direct/base/direct_18.h new file mode 100644 index 0000000..6c2b4f3 --- /dev/null +++ b/src/progs/direct/base/direct_18.h @@ -0,0 +1,34 @@ +/*************************************************************************** + * Copyright (C) 2003-2005 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#ifndef DIRECT_18_HH +#define DIRECT_18_HH + +#include "direct_pic.h" + +namespace Direct +{ + +class P18 : public Pic8DeviceSpecific +{ +public: + P18(::Programmer::Base &base) : Pic8DeviceSpecific(base) {} + virtual bool setPowerOn() { return setPowerOnVddFirst(); } + +protected: + bool pulse(const char *&cmd, BitValue value, BitValue &res); + virtual void send_word(BitValue d); + virtual BitValue get_word(); + virtual BitValue get_byte(); + virtual void send_cmd(BitValue d) { send_bits(d, 4); } + virtual void send_bits(BitValue d, uint nbBits); +}; + +} //namespace + +#endif diff --git a/src/progs/direct/base/direct_18F.cpp b/src/progs/direct/base/direct_18F.cpp new file mode 100644 index 0000000..9860e63 --- /dev/null +++ b/src/progs/direct/base/direct_18F.cpp @@ -0,0 +1,318 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * Copyright (C) 2003-2005 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "direct_18F.h" + +#include "direct_data.h" + +//----------------------------------------------------------------------------- +bool Direct::P18F::skipMaskWords(Pic::MemoryRangeType type, const Device::Array &data, + uint &i, uint nb, bool forceProgram) +{ + if (forceProgram) return false; + for (uint k=0; k> 16)); + pulseEngine("k0,S,k0,X6EF7,", 0x0E00 | ((address & 0x00FF00) >> 8)); + pulseEngine("k0,S,k0,X6EF6,", 0x0E00 | (address & 0x0000FF)); +} + +void Direct::P18F::setPointer(Pic::MemoryRangeType type, uint offset) +{ + if ( type==Pic::MemoryRangeType::Eeprom ) { + pulseEngine("k0,S,k0,X6EA9,", 0x0E00 | (offset & 0x00FF)); + pulseEngine("k0,S,k0,X6EAA,", 0x0E00 | ((offset & 0xFF00) >> 8)); + } else setCodePointer(device().range(type).start.toUInt() + offset); +} + +void Direct::P18F::directAccess(Pic::MemoryRangeType type) +{ + if ( type==Pic::MemoryRangeType::Code || type==Pic::MemoryRangeType::UserId || type==Pic::MemoryRangeType::Eeprom ) pulseEngine("k0,X9CA6"); // unset EECON1:CFGS + else pulseEngine("k0,X8CA6"); // set EECON1:CFGS + if ( type==Pic::MemoryRangeType::Eeprom ) pulseEngine("k0,X9EA6"); // unset EECON1::EEPGD + else pulseEngine("k0,X8EA6"); // set EECON1::EEPGD +} + +bool Direct::P18F::doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata) +{ + data.resize(device().nbWords(type)); + uint offset = 0; + uint nbWords = data.count(); + if (vdata) { + if ( vdata->actions & ::Programmer::OnlyProgrammedVerify ) { + const Device::Array wdata = static_cast(vdata->memory).arrayForWriting(type); + offset = findNonMaskStart(type, wdata); + nbWords = findNonMaskEnd(type, wdata)+1; + } + } + BitValue mask = device().mask(type); + //qDebug("read %s %i", Pic::MEMORY_RANGE_TYPE_DATA[type].label, device().nbWords(type)); + //pulseEngine("w300000"); // what for ? + directAccess(type); + switch (type.type()) { + case Pic::MemoryRangeType::Eeprom: + for (uint i = 0; i> 8; + if ( vdata && !hardware().verifyWord(offset+i+1, data[i+1], type, *vdata) ) return false; + } + break; + default: Q_ASSERT(false); break; + } + return true; +} + +bool Direct::P18F::doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force) +{ + uint inc = device().addressIncrement(type); + //qDebug("write %s %i/%i %i", Pic::MEMORY_RANGE_TYPE_DATA[type].label, nbWords, data.count(), inc); + //pulseEngine("w300000"); ?? + configureSinglePanel(); + directAccess(type); + switch (type.type()) { + case Pic::MemoryRangeType::UserId: { + setPointer(type, 0); + Q_ASSERT( device().nbWords(Pic::MemoryRangeType::UserId)==8 ); + uint i = 0; + for (uint k=0; k<4; k++) { + BitValue word = data[i] | data[i+1] << 8; + if ( (k+1)==4 ) pulseEngine("k15,S,", word); + else pulseEngine("k13,S,", word); + i += 2; + } + program(Code); + break; + } + case Pic::MemoryRangeType::Code: { + uint progWidth = device().nbWordsWriteAlignment(Pic::MemoryRangeType::Code); + for (uint i = 0; i * + * Copyright (C) 2003-2005 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#ifndef DIRECT_18F_H +#define DIRECT_18F_H + +#include "direct_18.h" + +namespace Direct +{ +//----------------------------------------------------------------------------- +class P18F : public P18 +{ +public: + P18F(::Programmer::Base &base) : P18(base) {} + virtual bool doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata); + virtual bool doWrite(Pic::MemoryRangeType, const Device::Array &data, bool force); + virtual bool doEraseCommand(uint cmd1, uint cmd2); + virtual bool doEraseRange(Pic::MemoryRangeType type); + virtual bool doErase(bool isProtected); + + bool skipMaskWords(Pic::MemoryRangeType type, const Device::Array &data, + uint &i, uint nb, bool force); + void setPointer(Pic::MemoryRangeType type, uint offset); + void setCodePointer(uint address); + enum Type { Code, Eeprom, Erase }; + virtual void program(Type type); + virtual uint programHighTime(Type type) const { return (type==Code ? 1000 : 5000); } + virtual uint programLowTime() { return 5; } + virtual void configureSinglePanel() {} + virtual void unlockEeprom(); + virtual void directAccess(Pic::MemoryRangeType type); +}; + +//----------------------------------------------------------------------------- +class P18F1220 : public P18F +{ +public: + P18F1220(::Programmer::Base &base) : P18F(base) {} + virtual void program(Type type); +}; + +//----------------------------------------------------------------------------- +class P18F242 : public P18F +{ +public: + P18F242(::Programmer::Base &base) : P18F(base) {} + virtual void configureSinglePanel(); +}; + +//----------------------------------------------------------------------------- +class P18F2539 : public P18F242 +{ +public: + P18F2539(::Programmer::Base &base) : P18F242(base) {} + virtual bool doErase(bool isProtected); + virtual bool doEraseCommand(uint cmd1, uint cmd2); +}; + +//----------------------------------------------------------------------------- +class P18F2439 : public P18F2539 +{ +public: + P18F2439(::Programmer::Base &base) : P18F2539(base) {} + virtual bool doEraseRange(Pic::MemoryRangeType type); +}; + +//----------------------------------------------------------------------------- +class P18F2221 : public P18F +{ +public: + P18F2221(::Programmer::Base &base) : P18F(base) {} + virtual bool doEraseRange(Pic::MemoryRangeType type); + virtual bool doErase(bool isProtected); + virtual uint programLowTime() { return 100; } + virtual void unlockEeprom() {} +}; + +//----------------------------------------------------------------------------- +class P18F6527 : public P18F2221 +{ +public: + P18F6527(::Programmer::Base &base) : P18F2221(base) {} + virtual bool doErase(bool isProtected); +}; + +//----------------------------------------------------------------------------- +class P18F6310 : public P18F +{ +public: + P18F6310(::Programmer::Base &base) : P18F(base) {} + virtual bool canEraseRange(Pic::MemoryRangeType) const { return false; } + virtual uint programHighTime(Type type) const { return (type==Code ? 2000 : 30000); } + virtual uint programLowTime() { return 120; } + virtual bool doEraseRange(Pic::MemoryRangeType) { return false; } + virtual bool doErase(bool isProtected); +}; + +} // namespace + +#endif diff --git a/src/progs/direct/base/direct_30.cpp b/src/progs/direct/base/direct_30.cpp new file mode 100644 index 0000000..db3c7f4 --- /dev/null +++ b/src/progs/direct/base/direct_30.cpp @@ -0,0 +1,261 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "direct_30.h" + +const uint BULK_ERASE_SEQUENCE[] = { // for all dsPICs + 0x000000, 0x000000, 0x040100, 0x000000, // step 1 + Direct::Pic30::LoopStart + 2, + 0x24008A, 0x883B0A, // step 2 + 0x200F80, 0x880190, 0x200067, // step 3 + 0xBB0300, // step 4 + 0xBB1B86, // step 5 + 0x200558, 0x200AA9, 0x883B38, 0x883B39, // step 6 + 0xA8E761, 0x000000, 0x000000, // step 7 + Direct::Pic30::Pause + 2000000, + 0xA9E761, 0x000000, 0x000000, + Direct::Pic30::LoopEnd, + 0x2407FA, 0x883B0A, // step 9 + 0x200558, 0x883B38, 0x200AA9, 0x883B39, // step 10 + 0xA8E761, 0x000000, 0x000000, // step 11 + Direct::Pic30::Pause + 2000000, + 0xA9E761, 0x000000, 0x000000, + Direct::Pic30::End +}; +const uint READ_APPLICATION_ID_SEQUENCE[] = { + 0x000000, 0x000000, 0x040100, 0x000000, // step 1 + 0x200800, 0x880190, 0x205FE0, 0x207841, // step 2 + 0xBA0890, 0x000000, 0x000000, + Direct::Pic30::RegisterOut, 0x000000, // step 3 + Direct::Pic30::End +}; +const uint READ_CONFIG_SEQUENCE[] = { + 0x000000, 0x000000, 0x040100, 0x000000, // step 1 + 0x200F80, 0x880190, 0xEB0300, 0xEB0380, // step 2 + Direct::Pic30::LoopStart + 7, + 0xBA0BB6, 0x000000, 0x000000, 0x883C20, 0x000000, // step 3 + Direct::Pic30::RegisterOut, 0x000000, // step 4 + 0x040100, 0x000000, // step 5 + Direct::Pic30::LoopEnd, + Direct::Pic30::End +}; +const uint WRITE_CONFIG_SEQUENCE[] = { + 0x000000, 0x000000, 0x040100, 0x000000, // step 1 + Direct::Pic30::FillAddressLow + 0x200007, // step 2 + 0x24008A, 0x883B0A, // step 3 + 0x200F80, 0x880190, // step 4 + Direct::Pic30::FillData + 0x200000, // step 5 + //0xEB0300, ??? + 0xBB1B96, 0x000000, 0x000000, // step 8 + 0x200558, 0x883B38, 0x200AA9, 0x883B39, // step 7 + 0xA8E761, 0x000000, 0x000000, // step 8 + Direct::Pic30::Pause + 2000000, + 0xA9E761, 0x000000, 0x000000, + Direct::Pic30::End +}; +const uint READ_DATA_SEQUENCE[] = { + 0x000000, 0x000000, 0x040100, 0x000000, // step 1 + 0x2007F0, 0x880190, Direct::Pic30::FillAddressLow + 0x200006, // step 2 + 0xEB0380, // step 3 + 0xBA1BB6, 0x000000, 0x000000, + 0xBA1BB6, 0x000000, 0x000000, + 0xBA1BB6, 0x000000, 0x000000, + 0xBA1BB6, 0x000000, 0x000000, + 0x883C20, 0x000000, Direct::Pic30::RegisterOut, 0x000000, // step 4 + 0x883C21, 0x000000, Direct::Pic30::RegisterOut, 0x000000, + 0x883C22, 0x000000, Direct::Pic30::RegisterOut, 0x000000, + 0x883C23, 0x000000, Direct::Pic30::RegisterOut, 0x000000, + Direct::Pic30::End +}; +const uint WRITE_DATA_SEQUENCE[] = { + 0x000000, 0x000000, 0x040100, 0x000000, // step 1 + 0x24005A, 0x883B0A, // step 2 + 0x2007F0, 0x880190, Direct::Pic30::FillAddressLow + 0x200007, // step 3 + Direct::Pic30::LoopStart + 4, + Direct::Pic30::FillData + 0x200000, // step 4 + Direct::Pic30::FillData + 0x200001, + Direct::Pic30::FillData + 0x200002, + Direct::Pic30::FillData + 0x200003, + 0xEB0300, 0x000000, // step 5 + 0xBB1BB6, 0x000000, 0x000000, + 0xBB1BB6, 0x000000, 0x000000, + 0xBB1BB6, 0x000000, 0x000000, + 0xBB1BB6, 0x000000, 0x000000, + Direct::Pic30::LoopEnd, + 0x200558, 0x883B38, 0x200AA9, 0x883B39, // step 7 + 0xA8E761, 0x000000, 0x000000, // step 8 + Direct::Pic30::Pause + 2000000, + 0xA9E761, 0x000000, 0x000000, + Direct::Pic30::End +}; +const uint READ_CODE_SEQUENCE[] = { + 0x000000, 0x000000, 0x040100, 0x000000, // step 1 + Direct::Pic30::FillAddressHigh + 0x200000, // step 2 + 0x880190, Direct::Pic30::FillAddressLow + 0x200006, + 0xEB0380, // step 3 + 0xBA1B96, 0x000000, 0x000000, 0xBADBB6, 0x000000, 0x000000, + 0xBADBD6, 0x000000, 0x000000, 0xBA1BB6, 0x000000, 0x000000, + 0xBA1B96, 0x000000, 0x000000, 0xBADBB6, 0x000000, 0x000000, + 0xBADBD6, 0x000000, 0x000000, 0xBA0BB6, 0x000000, 0x000000, + 0x883C20, 0x000000, Direct::Pic30::RegisterOut, 0x000000, // step 4 + 0x883C21, 0x000000, Direct::Pic30::RegisterOut, 0x000000, + 0x883C22, 0x000000, Direct::Pic30::RegisterOut, 0x000000, + 0x883C23, 0x000000, Direct::Pic30::RegisterOut, 0x000000, + 0x883C24, 0x000000, Direct::Pic30::RegisterOut, 0x000000, + 0x883C25, 0x000000, Direct::Pic30::RegisterOut, 0x000000, + Direct::Pic30::End +}; +const uint WRITE_CODE_SEQUENCE[] = { + 0x000000, 0x000000, 0x040100, 0x000000, // step 1 + 0x24001A, 0x883B0A, // step 2 + Direct::Pic30::FillAddressHigh + 0x200000, // step 3 + 0x880190, Direct::Pic30::FillAddressLow + 0x200007, + Direct::Pic30::LoopStart + 8, + Direct::Pic30::FillData + 0x200000, // step 4 + Direct::Pic30::FillData + 0x200001, + Direct::Pic30::FillData + 0x200002, + Direct::Pic30::FillData + 0x200003, + Direct::Pic30::FillData + 0x200004, + Direct::Pic30::FillData + 0x200005, + 0xEB0300, 0x000000, // step 5 + 0xBB0BB6, 0x000000, 0x000000, 0xBBDBB6, 0x000000, 0x000000, + 0xBBEBB6, 0x000000, 0x000000, 0xBB1BB6, 0x000000, 0x000000, + 0xBB0BB6, 0x000000, 0x000000, 0xBBDBB6, 0x000000, 0x000000, + 0xBBEBB6, 0x000000, 0x000000, 0xBB1BB6, 0x000000, 0x000000, + Direct::Pic30::LoopEnd, + 0x200558, 0x883B38, 0x200AA9, 0x883B39, // step 7 + 0xA8E761, 0x000000, 0x000000, 0x000000, 0x000000, // step 8 + Direct::Pic30::Pause + 2000000, + 0xA9E761, 0x000000, 0x000000, 0x000000, 0x000000, + Direct::Pic30::End +}; + +bool Direct::Pic30::sendCommand(Command cmd) +{ + for (uint i=0; i<4; i++) { + hardware().setPin(DataOut, ((cmd>>i) & 1 ? High : Low)); + hardware().setPin(Clock, High); + Port::nsleep(100); + hardware().setPin(Clock, Low); + Port::nsleep(100); + } + return true; +} + +bool Direct::Pic30::executeSIX(uint opcode) +{ + if ( !sendCommand(SIX) ) return false; + for (uint i=0; i<24; i++) { + hardware().setPin(DataOut, ((opcode>>i) & 1 ? High : Low)); + hardware().setPin(Clock, High); + Port::nsleep(100); + hardware().setPin(Clock, Low); + // seem to need this longer delay here -- maybe + // specific to my programmer hardware? #### from dspicprg + Port::nsleep(5000); + } + return true; +} + +bool Direct::Pic30::executeREGOUT(uint &v) +{ + v = 0; + if ( !sendCommand(REGOUT) ) return false; + hardware().setPin(DataOut, High); + for (uint i=0; i<24; i++) { + hardware().setPin(Clock, High); + Port::nsleep(100); + hardware().setPin(Clock, Low); + // as above, need extra delay here, but even + // longer in this case -- maybe data line takes + // longer to settle when it is being driven by + // the PIC than by the programmer? #### from dspicprg + Port::nsleep(10000); + if ( i>=8 ) { + uint r = hardware().readBit(); + v |= (r << (i-8)); + } + } + return true; +} + +bool Direct::Pic30::doStdpSequence(const uint *sequence, uint address, const char *outData, char *inData) +{ + uint loopStart = 0, loopCound = 0; + for (uint i=0; sequence[i]!=End; i++) { + uint opcode = (sequence[i] & OpcodeMask); + switch (Operation(sequence[i] & OperationMask)) { + case SendSix: + if ( !executeSIX(opcode) ) return false; + break; + case RegisterOut: { + uint v; + if ( !executeREGOUT(v) ) return false; + (*inData) = v & 0xFF; + inData++; + (*inData) = (v >> 8) & 0xFF; + inData++; + break; + } + case Pause: + Port::nsleep(opcode); + break; + case LoopStart: + loopCound = opcode; + loopStart = i; + break; + case LoopEnd: + loopCound--; + if (loopCound) i = loopStart; + break; + case FillData: { + uint v = *outData; + v <<= 4; + outData++; + v |= *outData; + outData++; + v <<= 4; + executeSIX(v | opcode); + break; + } + case FillAddressLow: { + uint v = address & 0xFFFF; + v <<= 4; + executeSIX(v | opcode); + break; + } + case FillAddressHigh: { + uint v = (address & 0xFF0000) >> 16; + v <<= 4; + executeSIX(v | opcode); + break; + } + case End: Q_ASSERT(false); break; + } + } + return true; +} + +bool Direct::Pic30::doErase(bool) +{ + if ( !enterStdpMode() ) return false; + if ( !doStdpSequence(BULK_ERASE_SEQUENCE, 0, 0, 0) ) return false; + return exitStdpMode(); +} + +bool Direct::Pic30::doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *data) +{ + // #### TODO + return false; +} + +bool Direct::Pic30::doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force) +{ + // #### TODO + return false; +} diff --git a/src/progs/direct/base/direct_30.h b/src/progs/direct/base/direct_30.h new file mode 100644 index 0000000..458496e --- /dev/null +++ b/src/progs/direct/base/direct_30.h @@ -0,0 +1,44 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef DIRECT_30_H +#define DIRECT_30_H + +#include "direct_pic.h" + +namespace Direct +{ +//---------------------------------------------------------------------------- +class Pic30 : public PicDeviceSpecific +{ +public: + Pic30(::Programmer::Base &base) : PicDeviceSpecific(base) {} + virtual bool doErase(bool isProtected); + virtual bool doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *data); + virtual bool doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force); + virtual bool setPowerOn() { return setPowerOnVddFirst(); } + +public: + enum Operation { SendSix = 0x0000000, RegisterOut = 0x1000000, Pause = 0x2000000, + LoopStart = 0x3000000, LoopEnd = 0x4000000, FillData = 0x5000000, + FillAddressLow = 0x6000000, FillAddressHigh = 0x7000000, End = 0x8000000 }; + enum Mask { OperationMask = 0xF000000, OpcodeMask = 0x0FFFFFF }; + +private: + bool enterStdpMode() { return pulseEngine("cdB"); } + bool exitStdpMode() { return pulseEngine("cdb"); } + bool doStdpSequence(const uint *sequence, uint address, const char *outData, char *inData); + enum Command { SIX = 0x0, REGOUT = 0x1 }; + bool sendCommand(Command command); + bool executeSIX(uint opcode); + bool executeREGOUT(uint &value); +}; + +} // namespace + +#endif diff --git a/src/progs/direct/base/direct_baseline.cpp b/src/progs/direct/base/direct_baseline.cpp new file mode 100644 index 0000000..996eb12 --- /dev/null +++ b/src/progs/direct/base/direct_baseline.cpp @@ -0,0 +1,88 @@ +/*************************************************************************** + * Copyright (C) 2003-2005 Alain Gibaud * + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "direct_baseline.h" + +//---------------------------------------------------------------------------- +bool Direct::Baseline::gotoMemory(Pic::MemoryRangeType type) +{ + switch (type.type()) { + case Pic::MemoryRangeType::Config: return true; + case Pic::MemoryRangeType::Eeprom: return true; + case Pic::MemoryRangeType::Code: + case Pic::MemoryRangeType::Cal: + case Pic::MemoryRangeType::UserId: + case Pic::MemoryRangeType::CalBackup: return incrementPC(device().range(type).start.toUInt()+1); + case Pic::MemoryRangeType::DeviceId: + case Pic::MemoryRangeType::DebugVector: + case Pic::MemoryRangeType::HardwareStack: + case Pic::MemoryRangeType::ProgramExecutive: + case Pic::MemoryRangeType::Nb_Types: break; + } + Q_ASSERT(false); + return false; +} + +//----------------------------------------------------------------------------- +bool Direct::P12C5XX::writeWords(Pic::MemoryRangeType type, const Device::Array &data, uint i) +{ + BitValue word = data[i]; + // config requires a total of 10ms Pulses == 100 x 100 us + uint total = (type==Pic::MemoryRangeType::Config ? 100 : 8); + uint n = 0; + for (; n * + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef DIRECT_BASELINE_HH +#define DIRECT_BASELINE_HH + +#include "direct_16F.h" + +namespace Direct +{ +//----------------------------------------------------------------------------- +class Baseline : public pic16 +{ +public: + Baseline(::Programmer::Base &base) : pic16(base) {} + virtual bool gotoMemory(Pic::MemoryRangeType type); + virtual bool setPowerOn() { return setPowerOnVppFirst(); } +}; + +//----------------------------------------------------------------------------- +class P12C5XX : public Baseline +{ +public: + P12C5XX(::Programmer::Base &base) : Baseline(base) {} + virtual bool writeWords(Pic::MemoryRangeType type, const Device::Array &data, uint i); + virtual bool doEraseRange(Pic::MemoryRangeType) { return false; } + virtual bool doErase(bool) { return false; } + virtual uint waitProgTime(Pic::MemoryRangeType) const { return 0; } // unused +}; + +//----------------------------------------------------------------------------- +class P10F2XX : public Baseline +{ +public: + P10F2XX(::Programmer::Base &base) : Baseline(base) {} + virtual bool doEraseRange(Pic::MemoryRangeType type); + virtual bool doErase(bool); + virtual uint waitProgTime(Pic::MemoryRangeType) const { return 2000; } + virtual void endProg(Pic::MemoryRangeType) { pulseEngine("k14,w100"); } +}; + +class P16F57 : public P10F2XX +{ +public: + P16F57(::Programmer::Base &base) : P10F2XX(base) {} + virtual uint nbWordsCodeProg() const { return 4; } +}; + +//----------------------------------------------------------------------------- +class P12C67X : public P16F +{ +public: + P12C67X(::Programmer::Base &base) : P16F(base) {} + virtual bool writeWords(Pic::MemoryRangeType type, const Device::Array &data, uint i); + virtual uint waitProgTime(Pic::MemoryRangeType) const { return 0; } // unused + virtual bool doEraseRange(Pic::MemoryRangeType) { return false; } + virtual bool doErase(bool) { return false; } +}; + +} // namespace + +#endif diff --git a/src/progs/direct/base/direct_data.h b/src/progs/direct/base/direct_data.h new file mode 100644 index 0000000..0b84084 --- /dev/null +++ b/src/progs/direct/base/direct_data.h @@ -0,0 +1,21 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef DIRECT_DATA_H +#define DIRECT_DATA_H + +namespace Direct +{ + +struct Data { +}; +extern const Data &data(const QString &device); + +} // namespace + +#endif diff --git a/src/progs/direct/base/direct_mem24.cpp b/src/progs/direct/base/direct_mem24.cpp new file mode 100644 index 0000000..a719add --- /dev/null +++ b/src/progs/direct/base/direct_mem24.cpp @@ -0,0 +1,207 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "direct_mem24.h" + +#include + +#include "common/global/global.h" +#include "common/common/misc.h" + +Direct::Mem24DeviceSpecific::Mem24DeviceSpecific(::Programmer::Base &base) + : ::Programmer::Mem24DeviceSpecific(base) +{} + +bool Direct::Mem24DeviceSpecific::setPowerOn() +{ + hardware().setPin(Clock, Low); + hardware().setPin(DataOut, Low); + hardware().setPin(Vpp, Off); + if ( hardware().isGroundPin(Vdd) ) { + hardware().setPin(Clock, High); + Port::usleep(500000); + } else { + hardware().setPin(Vdd, On); + Port::usleep(10000); + } + return true; +} + +bool Direct::Mem24DeviceSpecific::setPowerOff() +{ + hardware().setPin(Clock, Low); + hardware().setPin(DataOut, Low); + hardware().setPin(Vpp, Off); + hardware().setPin(Vdd, Off); + Port::usleep(10000); + return true; +} + +bool Direct::Mem24DeviceSpecific::verifyPresence() +{ + if ( !start() ) return false; + bool acked; + if ( !writeByte(controlByte(0x0, Write), acked) ) return false; + if ( !acked ) { + log(Log::LineType::Error, i18n("Could not detect EEPROM")); + return false; + } + log(Log::LineType::Information, i18n("EEPROM detected")); + return stop(); +} + +uint Direct::Mem24DeviceSpecific::controlByte(uint address, Operation operation) const +{ + uint cbyte = (operation==Write ? 0xA0 : 0xA1); + uint bsize = device().nbBytes() / device().nbBlocks(); + uint block = address / bsize; + uint nbb = nbBits(device().nbBlocks()-1); + for (uint i=0; i=0; i--) { + uint add = (address >> 8*i) & 0xFF; + log(Log::DebugLevel::Max, QString(" byte #%1: %2").arg(i).arg(toHexLabel(add, 2))); + if ( !writeByteAck(add) ) return false; + } + return true; +} + +bool Direct::Mem24DeviceSpecific::doRead(Device::Array &data, const ::Programmer::VerifyData *vdata) +{ + // sequential read: all device memory + if ( !setAddress(0x0) ) return false; + if ( !start() ) return false; + if ( !writeByteAck(controlByte(0x0, Read)) ) return false; + data.resize(device().nbBytes()); + for (uint i=0; i200 ) { // 200 ms timeout + log(Log::LineType::Error, i18n("Timeout writing at address %1").arg(toHexLabel(address, nbChars(device().nbBytes())))); + return false; + } + } + } + return true; +} + +void Direct::Mem24DeviceSpecific::set(State clock, State data) +{ + hardware().setPin(Clock, clock); + hardware().setPin(DataOut, data); + Port::usleep(5); // #### needed ? +} + +void Direct::Mem24DeviceSpecific::setData(State data) +{ + set(Low, data); + set(High, data); + set(Low, data); +} + +BitValue Direct::Mem24DeviceSpecific::readByte(State ack) +{ + hardware().setRead(); + set(Low, High); + BitValue b = 0; + for (uint i=0; i<8; i++) { + set(High, High); + b <<= 1; + if ( hardware().readBit() ) b |= 0x1; + set(Low, High); + } + hardware().setWrite(); + setData(ack); + return b; +} + +bool Direct::Mem24DeviceSpecific::writeByteAck(BitValue value) +{ + bool acked; + if ( !writeByte(value, acked) ) return false; + if (!acked) { + log(Log::LineType::Error, i18n("Acknowledge bit incorrect")); + return false; + } + return true; +} + +bool Direct::Mem24DeviceSpecific::writeByte(BitValue value, bool &acked) +{ + Q_ASSERT( value<=0xFF ); + hardware().setWrite(); + set(Low, Low); + for (int i=7; i>=0; i--) setData(value.bit(i) ? High : Low); + hardware().setRead(); + set(Low, High); + set(High, High); + acked = !hardware().readBit(); + hardware().setWrite(); + set(Low, High); + return true; +} + +bool Direct::Mem24DeviceSpecific::start() +{ + hardware().setWrite(); + set(Low, High); + set(High, High); + set(High, Low); + set(Low, Low); + return true; +} + +bool Direct::Mem24DeviceSpecific::stop() +{ + hardware().setWrite(); + set(Low, Low); + set(High, Low); + set(High, High); + set(Low, High); + return true; +} diff --git a/src/progs/direct/base/direct_mem24.h b/src/progs/direct/base/direct_mem24.h new file mode 100644 index 0000000..64f2a9d --- /dev/null +++ b/src/progs/direct/base/direct_mem24.h @@ -0,0 +1,47 @@ +/***************************************************************************\ + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef DIRECT_MEM24_H +#define DIRECT_MEM24_H + +#include "devices/mem24/prog/mem24_prog.h" +#include "direct.h" + +namespace Direct +{ + +class Mem24DeviceSpecific : public ::Programmer::Mem24DeviceSpecific +{ +public: + Mem24DeviceSpecific(::Programmer::Base &base); + virtual Hardware &hardware() { return static_cast(*_base.hardware()); } + const Mem24::Data &device() const { return static_cast(*::Programmer::DeviceSpecific::_base.device()); } + virtual bool init() { return true; } + virtual bool setPowerOff(); + virtual bool setPowerOn(); + virtual bool setTargetPowerOn(bool) { return true; } + virtual bool verifyPresence(); + +private: + virtual bool doRead(Device::Array &data, const ::Programmer::VerifyData *vdata); + virtual bool doWrite(const Device::Array &data); + bool start(); + bool stop(); + BitValue readByte(State ack); + bool writeByte(BitValue value, bool &acked); + bool writeByteAck(BitValue value); + void set(State clock, State data); + void setData(State data); + enum Operation { Write, Read }; + uint controlByte(uint address, Operation operation) const; + bool setAddress(uint address); +}; + +} // namespace + +#endif diff --git a/src/progs/direct/base/direct_pic.cpp b/src/progs/direct/base/direct_pic.cpp new file mode 100644 index 0000000..30e4722 --- /dev/null +++ b/src/progs/direct/base/direct_pic.cpp @@ -0,0 +1,187 @@ +/*************************************************************************** + * Copyright (C) 2003-2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "direct_pic.h" + +#include "common/common/misc.h" + +//----------------------------------------------------------------------------- +Direct::PulseEngine::PulseEngine(::Programmer::Base &base) + : _pbase(base) +{ + _clockDelay = 0; +} + +BitValue Direct::PulseEngine::pulseEngine(const QString &cmd, BitValue value) +{ + _pbase.log(Log::DebugLevel::Extra, QString("pulse engine: %1").arg(cmd)); + QByteArray a = toAscii(cmd); + BitValue res = 0; + for (const char *ptr=a.data(); (ptr-a.data()) * + * * + * 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. * + ***************************************************************************/ +#ifndef DIRECT_PIC_H +#define DIRECT_PIC_H + +#include "devices/pic/pic/pic_memory.h" +#include "direct.h" + +namespace Direct +{ +//----------------------------------------------------------------------------- +class PulseEngine +{ +public: + PulseEngine(::Programmer::Base &base); + virtual ~PulseEngine() {} + BitValue pulseEngine(const QString &command, BitValue value = 0); + +protected: + ::Programmer::Base &_pbase; + uint _clockDelay; // additionnal delay for buggy hardware + + virtual bool pulse(const char *&cmd, BitValue value, BitValue &res); + virtual Hardware &hardware() { return static_cast(*_pbase.hardware()); } +}; + +//----------------------------------------------------------------------------- +class PicDeviceSpecific : public ::Programmer::PicDeviceSpecific, public PulseEngine +{ +public: + PicDeviceSpecific(::Programmer::Base &base); + virtual bool canEraseAll() const { return true; } + virtual bool canEraseRange(Pic::MemoryRangeType type) const { return ( type==Pic::MemoryRangeType::Code || type==Pic::MemoryRangeType::Eeprom ); } + virtual bool canReadRange(Pic::MemoryRangeType) const { return true; } + virtual bool canWriteRange(Pic::MemoryRangeType) const { return true; } + virtual bool setPowerOff(); + virtual bool setTargetPowerOn(bool on); + +protected: + virtual bool pulse(const char *&cmd, BitValue value, BitValue &res); + bool setPowerOnVddFirst(); + bool setPowerOnVppFirst(); +}; + +//----------------------------------------------------------------------------- +class Pic8DeviceSpecific : public PicDeviceSpecific +{ +public: + Pic8DeviceSpecific(::Programmer::Base &base) : PicDeviceSpecific(base) {} + +protected: + virtual bool pulse(const char *&cmd, BitValue value, BitValue &res); + virtual void send_word(BitValue word) = 0; + virtual void send_bits(BitValue d, uint nbBits) = 0; + virtual void send_cmd(BitValue d) = 0; + virtual BitValue get_word() = 0; + virtual BitValue get_byte() = 0; +}; + +} // namespace + +#endif diff --git a/src/progs/direct/base/direct_prog.cpp b/src/progs/direct/base/direct_prog.cpp new file mode 100644 index 0000000..3e4f168 --- /dev/null +++ b/src/progs/direct/base/direct_prog.cpp @@ -0,0 +1,62 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "direct_prog.h" + +#include "devices/base/device_group.h" +#include "devices/list/device_list.h" +#include "direct_prog_config.h" +#include "direct_mem24.h" +//#include "direct_30.h" + +Hardware::Config *Direct::DGroup::hardwareConfig() const +{ + return new Config; +} + +void Direct::DGroup::initSupported() +{ + Group::initSupported(); + // const ::Group::Base *gpic = Device::lister().group("pic"); + ::Group::Base::ConstIterator pit; + // for (pit=gpic->begin(); pit!=gpics->end(); ++pit) { + // ::Group::DeviceData data = pit.data(); + // if ( static_cast(data.data)->architecture()!=Pic::Architecture::P30X ) continue; + // data.supportType = ::Group::Untested; + // addDevice(data); + // } + const ::Group::Base *gmem24 = Device::lister().group("mem24"); + for (pit=gmem24->begin(); pit!=gmem24->end(); ++pit) addDevice(pit.key(), pit.data().data, pit.data().support); +} + +::Programmer::Base *Direct::DGroup::createBase(const Device::Data *data) const +{ + if ( data==0 || data->group().name()=="pic" ) return new PicBase(*this, static_cast(data)); + return new Mem24Base(*this, static_cast(data)); +} + +::Programmer::Hardware *Direct::DGroup::createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &hd) const +{ + Config config; + HardwareData *hdata = static_cast(config.hardwareData(hd.name)); + Q_ASSERT( hdata->portType==hd.port.type ); + ::Programmer::Hardware *hardware = 0; + if ( hd.port.type==PortType::Serial ) hardware = new SerialHardware(base, hd.port.device, *hdata); + else hardware = new ParallelHardware(base, hd.port.device, *hdata); + delete hdata; + return hardware; +} + +::Programmer::DeviceSpecific *Direct::DGroup::createDeviceSpecific(::Programmer::Base &base) const +{ + if ( base.device()->group().name()=="pic" ) { + // if ( static_cast(base.device())->architecture()==Pic::Architecture::P30X ) return new Pic30(base); + return Group::createDeviceSpecific(base); + } + return new Mem24DeviceSpecific(base); +} diff --git a/src/progs/direct/base/direct_prog.h b/src/progs/direct/base/direct_prog.h new file mode 100644 index 0000000..34ca0b7 --- /dev/null +++ b/src/progs/direct/base/direct_prog.h @@ -0,0 +1,74 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef DIRECT_PROG_H +#define DIRECT_PROG_H + +#include "common/global/global.h" +#include "progs/base/prog_group.h" +#include "devices/pic/prog/pic_prog.h" +#include "devices/mem24/prog/mem24_prog.h" +#include "direct.h" + +namespace Direct +{ + extern bool isSupported(const QString &device); + class Hardware; + +//---------------------------------------------------------------------------- +class PicBase : public ::Programmer::PicBase +{ +Q_OBJECT +public: + PicBase(const ::Programmer::Group &group, const Pic::Data *data) + : ::Programmer::PicBase(group, data, "pic_direct_programmer") {} + +private: + Hardware &hardware() { return static_cast(*_hardware); } +}; + +//---------------------------------------------------------------------------- +class Mem24Base : public ::Programmer::Mem24Base +{ +Q_OBJECT +public: + Mem24Base(const ::Programmer::Group &group, const Mem24::Data *data) + : ::Programmer::Mem24Base(group, data, "mem24_direct_programmer") {} + +private: + Hardware &hardware() { return static_cast(*_hardware); } +}; + +//---------------------------------------------------------------------------- +class Group : public ::Programmer::PicGroup // methods defined in direct_data.cpp +{ +protected: + virtual void initSupported(); + virtual ::Programmer::DeviceSpecific *createDeviceSpecific(::Programmer::Base &base) const; +}; + +class DGroup : public Group +{ +public: + virtual QString name() const { return "direct"; } + virtual QString label() const { return i18n("Direct Programmer"); } + virtual ::Hardware::Config *hardwareConfig() const; + virtual ::Programmer::Properties properties() const { return ::Programmer::Programmer | ::Programmer::CanReadMemory | ::Programmer::HasConnectedState; } + virtual ::Programmer::TargetPowerMode targetPowerMode() const { return ::Programmer::TargetExternallyPowered; } + virtual bool isPortSupported(PortType type) const { return ( type==PortType::Serial || type==PortType::Parallel ); } + +protected: + virtual void initSupported(); + virtual ::Programmer::Base *createBase(const Device::Data *data) const; + virtual ::Programmer::Hardware *createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &hd) const; + virtual ::Programmer::DeviceSpecific *createDeviceSpecific(::Programmer::Base &base) const; +}; + +} // namespace + +#endif diff --git a/src/progs/direct/base/direct_prog_config.cpp b/src/progs/direct/base/direct_prog_config.cpp new file mode 100644 index 0000000..ffce899 --- /dev/null +++ b/src/progs/direct/base/direct_prog_config.cpp @@ -0,0 +1,145 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * Copyright (C) 2003-2005 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "direct_prog_config.h" + +//----------------------------------------------------------------------------- +struct ConstHardwareData +{ + PortType portType; + Direct::HData data; +}; + +struct ConstStandardHardwareData +{ + ::Hardware::DataInfo info; + ConstHardwareData data; +}; + +const ConstStandardHardwareData STANDARD_HARDWARE_DATA[] = { + { { "Tait classic", I18N_NOOP("Tait classic"), 0 }, + { PortType::Parallel, { { -5, -4, 3, 2, 10, 25 }, 0, Direct::Normal } } }, + { { "Tait 7405/7406", I18N_NOOP("Tait 7405/7406"), 0 }, + { PortType::Parallel, { { 5, 4, -3, -2,-10, 25 }, 0, Direct::Normal } } }, + { { "P16PRO40 classic", I18N_NOOP("P16PRO40 classic"), 0 }, + { PortType::Parallel, { { 5, 4, -3, -2,-10, 25 }, 0, Direct::Normal } } }, + { { "P16PRO40 7407", I18N_NOOP("P16PRO40 7407"), 0 }, + { PortType::Parallel, { { -5, -4, 3, 2, 10, 25 }, 0, Direct::Normal } } }, + { { "P16PRO40-VPP40 classic", I18N_NOOP("P16PRO40-VPP40 classic"), 0 }, + { PortType::Parallel, { { 6, 4, -3, -2,-10, 25 }, 0, Direct::Normal } } }, + { { "P16PRO40-VPP40 7407", I18N_NOOP("P16PRO40-VPP40 7407"), 0 }, + { PortType::Parallel, { { -6, -4, 3, 2, 10, 25 }, 0, Direct::Normal } } }, + { { "EPIC+", I18N_NOOP("EPIC+"), + I18N_NOOP("You must disconnect 7407 pin 2") }, + { PortType::Parallel, { { -5, -4, 3, 2, 10, 25 }, 0, Direct::Normal } } }, + { { "JDM classic", I18N_NOOP("JDM classic"), 0 }, + { PortType::Serial, { { 3, 5, 7, 4, 8, 5 }, 0, Direct::Normal } } }, + { { "JDM classic (delay 10)", I18N_NOOP("JDM classic (delay 10)"), 0 }, + { PortType::Serial, { { 3, 5, 7, 4, 8, 5 }, 10, Direct::Normal } } }, + { { "JDM classic (delay 20)", I18N_NOOP("JDM classic (delay 20)"), 0 }, + { PortType::Serial, { { 3, 5, 7, 4, 8, 5 }, 20, Direct::Normal } } }, + { { "PIC Elmer", I18N_NOOP("PIC Elmer"), 0 }, + { PortType::Serial, { { -3, 5, -7, -4, -8, 5 }, 0, Direct::Normal } } }, + { { "Velleman K8048", I18N_NOOP("Velleman K8048"), 0 }, + { PortType::Serial, { { -3, 5, -7, -4, -8, 5 }, 0, Direct::Normal } } }, + { { "HOODMICRO", I18N_NOOP("HOODMICRO"), + I18N_NOOP("Webpage: htpp://k9spud.com/hoodmicro") }, + { PortType::Serial, { { 4, 5, 7, 3, 8, 5 }, 0, Direct::Normal } } }, + + //Added by Mirko Panciri 10/03/2004... + //Visit http://www.pic-tools.com + //I have tested only the "Asix Piccolo" version... + //I think the lines is the same of "Asix Piccolo Grande"... + { { "Asix Piccolo", I18N_NOOP("Asix Piccolo"), 0 }, + { PortType::Parallel, { { -6, -7, -5, -3,-10, -2 }, 0, Direct::Normal } } }, + { { "Asix Piccolo Grande", I18N_NOOP("Asix Piccolo Grande"), 0 }, + { PortType::Parallel, { { -6, -7, -5, -3,-10, -2 }, 0, Direct::Normal } } }, + + { { "Propic2 Vpp-1", I18N_NOOP("Propic2 Vpp-1"), 0 }, + { PortType::Parallel, { { -5, -4, 3, 2, 10, 25 }, 0, Direct::Normal } } }, + { { "Propic2 Vpp-2", I18N_NOOP("Propic2 Vpp-2"), 0 }, + { PortType::Parallel, { { -6, -4, 3, 2, 10, 25 }, 0, Direct::Normal } } }, + { { "Propic2 Vpp-3", I18N_NOOP("Propic2 Vpp-3"), 0 }, + { PortType::Parallel, { { -7, -4, 3, 2, 10, 25 }, 0, Direct::Normal } } }, + { { "Myke's EL Cheapo", I18N_NOOP("Myke's EL Cheapo"), 0 }, + { PortType::Parallel, { { 16, 25, -1,-17, 13, 25 }, 0, Direct::Normal } } }, + { { "EL Cheapo classic", I18N_NOOP("EL Cheapo classic"), I18N_NOOP("Not tested.") }, + { PortType::Parallel, { { 16, 25, 1, 17,-13, 25 }, 0, Direct::Normal } } }, + { { "Monty-Robot programmer", I18N_NOOP("Monty-Robot programmer"), 0 }, + { PortType::Parallel, { { -5, 4, 2, 3, 10, 25 }, 0, Direct::Normal } } }, + { { "EPE Toolkit mk3", I18N_NOOP("EPE Toolkit mk3"), + I18N_NOOP("This programmer pulses MCLR from 5V to 0V and then 12V to enter programming mode. It uses a multiplexer to switch between 5V and 12V (Vdd is here the multiplexer pin).

Webpage: http://www.epemag.wimborne.co.uk/1001.htm") }, + { PortType::Parallel, { { 5, 6, 3, 2, 10, 25 }, 0, Direct::EPEToolkitMK3 } } }, + + { { "ETT High Vpp", I18N_NOOP("ETT High Vpp"), 0 }, + { PortType::Parallel, { { -5, -4, 3, 2, 10, 25 }, 0, Direct::Normal } } }, + { { "ETT Low Vpp", I18N_NOOP("ETT Low Vpp"), + I18N_NOOP("Compatible with ET-CAB10PIN V2 programmer shipped by Futurlec, with their PIC16F877 controler board.") }, + { PortType::Parallel, { { 3, 5, 2, -1, 10, 25 }, 0, Direct::Normal } } }, + + { { 0, 0, 0 }, + { PortType::Serial, { { 0, 0, 0, 0, 0, 0 }, 0, Direct::Normal } } } +}; + +//----------------------------------------------------------------------------- +void Direct::HardwareData::readConfig(GenericConfig &config) +{ + ::Hardware::Data::readConfig(config); + for (uint i=0; i(cdata).data; + if ( data.clockDelay!=hdata.clockDelay ) return false; + for (uint i=0; iname = csdata.info.name; + data->portType = csdata.data.portType; + data->data = csdata.data.data; + return data; + } + return 0; +} diff --git a/src/progs/direct/base/direct_prog_config.h b/src/progs/direct/base/direct_prog_config.h new file mode 100644 index 0000000..151b141 --- /dev/null +++ b/src/progs/direct/base/direct_prog_config.h @@ -0,0 +1,42 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * Copyright (C) 2003-2005 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#ifndef DIRECT_PROG_CONFIG_H +#define DIRECT_PROG_CONFIG_H + +#include "direct.h" +#include "progs/base/hardware_config.h" + +namespace Direct +{ + +class HardwareData : public ::Hardware::Data +{ +public: + virtual void readConfig(GenericConfig &config); + virtual void writeConfig(GenericConfig &config) const; + virtual bool isEqual(const ::Hardware::Data &data) const; + HData data; +}; + +class Config : public ::Hardware::Config +{ +public: + Config() : ::Hardware::Config("direct_programmer") {} + +protected: + virtual QStringList standardHardwareNames(PortType type) const; + virtual const ::Hardware::DataInfo *standardHardwareDataInfo(const QString &name) const; + virtual ::Hardware::Data *standardHardwareData(const QString &name) const; + virtual ::Hardware::Data *createHardwareData() const { return new HardwareData; } +}; + +} //namespace + +#endif diff --git a/src/progs/direct/direct.pro b/src/progs/direct/direct.pro new file mode 100644 index 0000000..60ac0f5 --- /dev/null +++ b/src/progs/direct/direct.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = xml base diff --git a/src/progs/direct/gui/Makefile.am b/src/progs/direct/gui/Makefile.am new file mode 100644 index 0000000..ec7e698 --- /dev/null +++ b/src/progs/direct/gui/Makefile.am @@ -0,0 +1,5 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +libdirectui_la_LDFLAGS = $(all_libraries) +noinst_LTLIBRARIES = libdirectui.la +libdirectui_la_SOURCES = direct_config_widget.cpp diff --git a/src/progs/direct/gui/direct_config_widget.cpp b/src/progs/direct/gui/direct_config_widget.cpp new file mode 100644 index 0000000..985cacd --- /dev/null +++ b/src/progs/direct/gui/direct_config_widget.cpp @@ -0,0 +1,249 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "direct_config_widget.h" + +#include +#include +#include +#include + +#include "progs/direct/base/direct_prog_config.h" +#include "progs/direct/base/direct_prog.h" + +//----------------------------------------------------------------------------- +::Programmer::ConfigWidget *Direct::GroupUI::createConfigWidget(QWidget *parent) const +{ + return new ConfigWidget(static_cast(group()), parent); +} + +//----------------------------------------------------------------------------- +const char * const INV_PIN_LABEL = I18N_NOOP("Check this option if your hardware uses negative logic for this pin."); +const char * const DELAY_LABEL = I18N_NOOP("Some programming cards need low clock rate:\nadding delay to clock pulses might help."); + +Direct::HConfigWidget::HConfigWidget(::Programmer::Base &base, QWidget *parent, bool edit) + : ::Hardware::HConfigWidget(base, parent, edit) +{ + // pins assignment + QGroupBox *groupb = new QGroupBox(1, Horizontal, i18n("Pin assignment"), this); + _mainVBox->addWidget(groupb); + QWidget *w = new QWidget(groupb); + QGridLayout *grid = new QGridLayout(w, 1, 1, 0, 10); + if (edit) grid->setColStretch(5, 1); + for (uint i=0; iaddWidget(label, i, 0); + _combos[i] = new QComboBox(w); + _combos[i]->setEnabled(edit); + connect(_combos[i], SIGNAL(activated(int)), SLOT(slotPinChanged())); + QToolTip::add(_combos[i], PIN_DATA[i].comment); + grid->addWidget(_combos[i], i, 1); + _invcbs[i] = new QCheckBox(i18n("Inverted"), w); + _invcbs[i]->setEnabled(edit); + QToolTip::add(_invcbs[i], i18n(INV_PIN_LABEL)); + grid->addWidget(_invcbs[i], i, 2); + if (edit) { + _testcbs[i] = new QCheckBox(i18n("on"), w); + QToolTip::add(_testcbs[i], PIN_DATA[i].testComment); + connect(_testcbs[i], SIGNAL(clicked()), SLOT(slotTestPin())); + grid->addWidget(_testcbs[i], i, 3); + _testLabels[i] = new QLabel(w); + QToolTip::add(_testcbs[i], PIN_DATA[i].testComment); + grid->addWidget(_testLabels[i], i, 4); + updateTestStatus(PinType(i), false); + } else { + _testcbs[i] = 0; + _testLabels[i] = 0; + } + } + + QHBoxLayout *hbox = new QHBoxLayout(_mainVBox); + QLabel *label = new QLabel(i18n("Clock delay"), this); + QToolTip::add(label, i18n(DELAY_LABEL)); + hbox->addWidget(label); + _delay = new KIntNumInput(0, Horizontal, this); + _delay->setRange(0, 50, 5); + _delay->setEnabled(edit); + QToolTip::add(_delay, i18n(DELAY_LABEL)); + hbox->addWidget(_delay); + + if (edit) { + _sendBitsButton = new QPushButton(i18n("Send 0xA55A"), this); + _sendBitsButton->setToggleButton(true); + connect(_sendBitsButton, SIGNAL(clicked()), SLOT(sendBits())); + QToolTip::add(_sendBitsButton, i18n("Continuously send 0xA55A on \"Data out\" pin.")); + _editVBox->addWidget(_sendBitsButton); + _editVBox->addStretch(1); + } else _sendBitsButton = 0; + + // timer for sending bits + _timerSendBits = new QTimer(this); + connect(_timerSendBits, SIGNAL(timeout()), SLOT(slotSendBits())); + + // timer for automatically polling DataOut pin + _timerPollDataOut = new QTimer(this); + connect(_timerPollDataOut, SIGNAL(timeout()), SLOT(updateDataIn())); +} + +void Direct::HConfigWidget::sendBits() +{ + if ( _timerSendBits->isActive() ) { + _sendBitsButton->setText(i18n("Send 0xA55A")); + _timerSendBits->stop(); + updateTestPin(DataOut); + } else { + _sendBitsButton->setText(i18n("Stop")); + _timerSendBits->start(1); + } +} + +uint Direct::HConfigWidget::pin(PinType ptype) const +{ + return static_cast(_hardware)->pinForIndex(PIN_DATA[ptype].dir, _combos[ptype]->currentItem()); +} + +void Direct::HConfigWidget::slotPinChanged() +{ + for (uint i = 0; iisGroundPin(pin(ptype)); + _invcbs[ptype]->setEnabled(_edit); + if (ground) _invcbs[ptype]->hide(); + else _invcbs[ptype]->show(); + if (_edit) { + _testcbs[ptype]->setEnabled(PIN_DATA[ptype].dir==Port::Out && _connected); + _testLabels[ptype]->setEnabled(_connected); + if (ground) { + _testcbs[ptype]->hide(); + _testLabels[ptype]->hide(); + } else { + _testcbs[ptype]->show(); + _testLabels[ptype]->show(); + } + } +} + +void Direct::HConfigWidget::slotTestPin() +{ + for (uint i = 0; iisChecked(); + hardware()->setPin(ptype, on); + updateTestStatus(ptype, on); + if ( ptype==Vpp ) updateDataIn(); +} + +void Direct::HConfigWidget::updateTestStatus(PinType ptype, bool on) +{ + if (on) _testLabels[ptype]->setText(i18n(PIN_DATA[ptype].onLabel)); + else _testLabels[ptype]->setText(i18n(PIN_DATA[ptype].offLabel)); +} + +void Direct::HConfigWidget::updateDataIn() +{ + bool on = hardware()->readBit(); + updateTestStatus(DataIn, on); + _testcbs[DataIn]->setChecked(on); +} + +void Direct::HConfigWidget::sendBits(uint d, int nbb) +{ + Q_ASSERT(_connected); + hardware()->setWrite(); + for (; nbb; --nbb) { + hardware()->setPin(Clock, High); + if ( d & 0x01 ) hardware()->setPin(DataOut, High); + else hardware()->setPin(DataOut, Low); + hardware()->setPin(Clock, Low); + d >>= 1; // Move the data over 1 bit + } + hardware()->setPin(DataOut, Low); + hardware()->setRead(); +} + +void Direct::HConfigWidget::slotSendBits() +{ + sendBits(0xA55A, 16); +} + +bool Direct::HConfigWidget::set(const Port::Description &pd, const ::Hardware::Data &data) +{ + // connect port + _timerPollDataOut->stop(); + if ( _timerSendBits->isActive() ) sendBits(); // stop + delete _hardware; + const HardwareData &hdata = static_cast(data); + if ( pd.type==PortType::Serial ) _hardware = new SerialHardware(_base, pd.device, hdata); + else _hardware = new ParallelHardware(_base, pd.device, hdata); + bool ok = _hardware->connectHardware(); + if ( !_edit) _hardware->disconnectHardware(); + else _connected = ok; + + // update GUI + if (_edit) { + for (uint i=0; isetEnabled(_connected); + updateTestStatus(PinType(i), false); + } + if ( _connected ) _timerPollDataOut->start(100); + _sendBitsButton->setEnabled(_connected); + } + + // update pins + for (uint i=0; iclear(); + Port::IODir dir = PIN_DATA[i].dir; + for (uint k=0; knbPins(dir); k++) + _combos[i]->insertItem(hardware()->pinLabelForIndex(dir, k)); + if (PIN_DATA[i].canBeGround) _combos[i]->insertItem("GND"); + _combos[i]->setCurrentItem(hardware()->indexForPin(dir, hdata.data.pins[i])); + _invcbs[i]->setChecked(hdata.data.pins[i]<0); + updatePin(PinType(i)); + } + _delay->setValue(hdata.data.clockDelay); + + return ok; +} + +Hardware::Data *Direct::HConfigWidget::data() const +{ + HardwareData *hdata = new HardwareData; + hdata->portType = _hardware->portDescription().type; + for (uint i=0; idata.pins[i] = pin(PinType(i)); + if ( _invcbs[i]->isChecked() ) hdata->data.pins[i] = -hdata->data.pins[i]; + } + hdata->data.clockDelay = _delay->value(); + return hdata; +} + +//----------------------------------------------------------------------------- +Direct::ConfigWidget::ConfigWidget(const ::Programmer::Group &group, QWidget *parent) + : ::Hardware::ConfigWidget(new ::Direct::PicBase(group, 0), new Config, parent) +{} + +Hardware::HConfigWidget *Direct::ConfigWidget::createHardwareConfigWidget(QWidget *parent, bool edit) const +{ + return new HConfigWidget(*_base, parent, edit); +} diff --git a/src/progs/direct/gui/direct_config_widget.h b/src/progs/direct/gui/direct_config_widget.h new file mode 100644 index 0000000..4a5e4c6 --- /dev/null +++ b/src/progs/direct/gui/direct_config_widget.h @@ -0,0 +1,74 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#ifndef DIRECT_CONFIG_WIDGET +#define DIRECT_CONFIG_WIDGET + +#include + +#include "progs/gui/prog_group_ui.h" +#include "progs/gui/hardware_config_widget.h" +#include "progs/direct/base/direct.h" + +namespace Direct +{ +//---------------------------------------------------------------------------- +class GroupUI : public ::Programmer::GroupUI +{ +public: + virtual ::Programmer::ConfigWidget *createConfigWidget(QWidget *parent) const; + virtual bool hasAdvancedDialog() const { return false; } + virtual ::Programmer::AdvancedDialog *createAdvancedDialog(::Programmer::Base &, QWidget *) const { return 0; } +}; + +//----------------------------------------------------------------------------- +class HConfigWidget : public ::Hardware::HConfigWidget +{ +Q_OBJECT +public: + HConfigWidget(::Programmer::Base &base, QWidget *parent, bool edit); + virtual bool set(const Port::Description &pd, const ::Hardware::Data &data); + virtual ::Hardware::Data *data() const; + +private slots: + void slotTestPin(); + void slotPinChanged(); + void updateDataIn(); + void sendBits(); + void slotSendBits(); + +private: + QComboBox *_combos[Nb_PinTypes]; + QCheckBox *_invcbs[Nb_PinTypes]; + QCheckBox *_testcbs[Nb_PinTypes]; + QLabel *_testLabels[Nb_PinTypes]; + KIntNumInput *_delay; + QPushButton *_sendBitsButton; + QTimer *_timerSendBits, *_timerPollDataOut; + + void sendBits(uint d, int nbb); + void updateTestPin(PinType ptype); + void updateTestStatus(PinType ptype, bool on); + uint pin(PinType ptype) const; + void updatePin(PinType ptype); + Hardware *hardware() { return static_cast(_hardware); } +}; + +//----------------------------------------------------------------------------- +class ConfigWidget : public ::Hardware::ConfigWidget +{ +Q_OBJECT +public: + ConfigWidget(const ::Programmer::Group &group, QWidget *parent); + virtual ::Hardware::HConfigWidget *createHardwareConfigWidget(QWidget *parent, bool edit) const; +}; + +} // namespace + +#endif diff --git a/src/progs/direct/xml/Makefile.am b/src/progs/direct/xml/Makefile.am new file mode 100644 index 0000000..dd1f678 --- /dev/null +++ b/src/progs/direct/xml/Makefile.am @@ -0,0 +1,14 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_PROGRAMS = xml_direct_parser +xml_direct_parser_SOURCES = xml_direct_parser.cpp +OBJECTS = $(top_builddir)/src/devices/list/libdevicelistnoui.la \ + $(top_builddir)/src/devices/pic/pic/libpic.la $(top_builddir)/src/devices/pic/base/libpicbase.la \ + $(top_builddir)/src/devices/pic/xml_data/libpicxml.la \ + $(top_builddir)/src/devices/mem24/mem24/libmem24.la $(top_builddir)/src/devices/mem24/base/libmem24base.la \ + $(top_builddir)/src/devices/mem24/xml_data/libmem24xml.la \ + $(top_builddir)/src/xml_to_data/libxmltodata.la $(top_builddir)/src/devices/base/libdevicebase.la \ + $(top_builddir)/src/common/common/libcommon.la +xml_direct_parser_DEPENDENCIES = $(OBJECTS) +xml_direct_parser_LDADD = $(OBJECTS) $(LIB_KDECORE) diff --git a/src/progs/direct/xml/xml.pro b/src/progs/direct/xml/xml.pro new file mode 100644 index 0000000..740232e --- /dev/null +++ b/src/progs/direct/xml/xml.pro @@ -0,0 +1,17 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/app.pro) + +TARGET = xml_direct_parser +SOURCES += xml_direct_parser.cpp +LIBS += ../../../devices/list/libdevicelist.a \ + ../../../devices/mem24/mem24/libmem24.a ../../../devices/mem24/xml_data/libmem24xml.a \ + ../../../devices/mem24/base/libmem24base.a \ + ../../../devices/pic/pic/libpic.a ../../../devices/pic/xml_data/libpicxml.a \ + ../../../devices/pic/base/libpicbase.a ../../../xml_to_data/libxmltodata.a \ + ../../../devices/base/libdevicebase.a ../../../common/global/libglobal.a \ + ../../../common/nokde/libnokde.a ../../../common/common/libcommon.a + +unix:QMAKE_POST_LINK = cd ../base && ../xml/xml_direct_parser +unix:QMAKE_CLEAN += ../base/direct_data.cpp +win32:QMAKE_POST_LINK = cd ..\base && ..\xml\xml_direct_parser.exe +win32:QMAKE_CLEAN += ..\base\direct_data.cpp diff --git a/src/progs/direct/xml/xml_direct_parser.cpp b/src/progs/direct/xml/xml_direct_parser.cpp new file mode 100644 index 0000000..ee51674 --- /dev/null +++ b/src/progs/direct/xml/xml_direct_parser.cpp @@ -0,0 +1,60 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "xml_to_data/prog_xml_to_data.h" +#include "devices/pic/base/pic.h" +#include "progs/direct/base/direct_data.h" + +namespace Direct +{ +class XmlToData : public ::Programmer::XmlToData +{ +public: + XmlToData() : ::Programmer::XmlToData("direct", "Direct") {} + +private: + virtual void parseData(QDomElement element, Data &data); + virtual void includes(QTextStream &s) const; + virtual void outputFunctions(QTextStream &s) const; +}; + +void Direct::XmlToData::parseData(QDomElement element, Data &) +{ + QString s = element.attribute("pwidth"); + const Device::Data *d = Device::lister().data(currentDevice()); + if ( d==0 ) qFatal("Invalid device name"); +} + +void Direct::XmlToData::includes(QTextStream &s) const +{ + Programmer::XmlToData::includes(s); + s << "#include \"direct_baseline.h\"" << endl; + s << "#include \"direct_16F.h\"" << endl; + s << "#include \"direct_18F.h\"" << endl; +} + +void Direct::XmlToData::outputFunctions(QTextStream &s) const +{ + Programmer::XmlToData::outputFunctions(s); + s << "::Programmer::DeviceSpecific *Direct::Group::createDeviceSpecific(::Programmer::Base &base) const" << endl; + s << "{" << endl; + s << " uint i = family(static_cast(base).device()->name());" << endl; + s << " switch(i) {" << endl; + for (uint i=0; i * + * * + * 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. * + ***************************************************************************/ +#include "gpsim.h" + +#include +#include "progs/base/generic_prog.h" +#include "progs/base/generic_debug.h" + +//----------------------------------------------------------------------------- +GPSim::Process::Process(Log::Base *base) + : ::Process::LineOutput(0, "gpsim_process"), Log::Base(base), _ready(false) +{ + connect(this, SIGNAL(stdoutDataReceived()), SLOT(stdoutDataReceivedSlot())); +} + +void GPSim::Process::stdoutDataReceivedSlot() +{ + if ( _stdout.startsWith("**gpsim> ") || _ready ) { + log(Log::DebugLevel::Extra, "received console prompt", Log::Delayed); + _ready = true; + emit requestSynchronousStop(); + } +} + +void GPSim::Process::addStdoutLine(const QString &line) +{ + log(Log::DebugLevel::Extra, " " + line, Log::Delayed); + if ( line.startsWith("***ERROR:") ) { + log(Log::LineType::Error, line); + return; + } + QString s = line; + QString prompt = "**gpsim> "; + while ( s.startsWith(prompt) ) { + _ready = true; + s = s.mid(prompt.length()); + } + s = s.stripWhiteSpace(); + _stdoutLines += s; +} + +//----------------------------------------------------------------------------- +GPSim::ProcessManager::ProcessManager(Log::Base *base) + : Log::Base(base), _process(base) +{} + +bool GPSim::ProcessManager::start() +{ + _process._ready = false; + _process.setup("gpsim", QStringList("-i"), false); + if ( !_process.start(0) ) { + log(Log::LineType::Error, i18n("Failed to start \"gpsim\".")); + return false; + } + return runSynchronously(); +} + +bool GPSim::ProcessManager::runSynchronously() +{ + ::Process::State state = ::Process::runSynchronously(_process, ::Process::NoRunAction, 5000); + if ( !_process.isRunning() ) { + log(Log::LineType::Error, i18n("\"gpsim\" unexpectedly exited.")); + return false; + } + if ( state==::Process::Timedout ) { + log(Log::LineType::Error, i18n("Timeout waiting for \"gpsim\".")); + return false; + } + return true; +} + +bool GPSim::ProcessManager::sendCommand(const QString &cmd, bool synchronous) +{ + _process._ready = false; + _process._stdoutLines.clear(); + _process._stdout = QString::null; + _process.writeToStdin(cmd + '\n'); + if (synchronous) return runSynchronously(); + return true; +} + +bool GPSim::ProcessManager::sendSignal(uint n, bool synchronous) +{ + _process._ready = false; + _process._stdoutLines.clear(); + _process._stdout = QString::null; + if ( !_process.signal(n) ) { + log(Log::LineType::Error, i18n("Error send a signal to the subprocess.")); + return false; + } + if (synchronous) return runSynchronously(); + return true; +} + +bool GPSim::ProcessManager::getVersion(VersionData &version) +{ + if ( !sendCommand("version", true) ) return false; + QRegExp reg("\\w*\\s*(\\d+\\.\\d+\\.\\d+).*"); + if ( _process.sout().count()==0 || !reg.exactMatch(_process.sout()[0]) ) { + version = VersionData(); + return true; + } + version = VersionData::fromString(reg.cap(1)); + return true; +} + +//----------------------------------------------------------------------------- +GPSim::Hardware::~Hardware() +{ + delete _manager; +} + +bool GPSim::Hardware::internalConnectHardware() +{ + delete _manager; + _manager = new ProcessManager(this); + _manager->process().setWorkingDirectory(_base.debugger()->directory()); + if ( !_manager->start() ) return false; + if ( !_manager->getVersion(_version) ) return false; + if ( !_version.isValid() ) { + log(Log::LineType::Error, i18n("Could not recognize gpsim version.")); + return false; + } + return true; +} + +void GPSim::Hardware::internalDisconnectHardware() +{ + delete _manager; + _manager = 0; +} + +bool GPSim::Hardware::execute(const QString &command, bool synchronous, QStringList *output) +{ + log(Log::DebugLevel::Normal, QString("command: %1").arg(command)); + if (output) output->clear(); + if ( !_manager->sendCommand(command, synchronous) ) return false; + if (output) *output = _manager->process().sout(); + return true; +} + +bool GPSim::Hardware::signal(uint n, bool synchronous, QStringList *output) +{ + log(Log::DebugLevel::Normal, QString("signal: %1").arg(n)); + if (output) output->clear(); + if ( !_manager->sendSignal(n, synchronous) ) return false; + if (output) *output = _manager->process().sout(); + return true; +} diff --git a/src/progs/gpsim/base/gpsim.h b/src/progs/gpsim/base/gpsim.h new file mode 100644 index 0000000..ab004a3 --- /dev/null +++ b/src/progs/gpsim/base/gpsim.h @@ -0,0 +1,85 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef GPSIM_H +#define GPSIM_H + +#include "common/common/version_data.h" +#include "progs/base/prog_specific.h" +#include "common/global/process.h" +#include "common/global/purl.h" + +namespace GPSim +{ +//----------------------------------------------------------------------------- +class Process : public ::Process::LineOutput, public Log::Base +{ +Q_OBJECT +public: + Process(Log::Base *base); + +private slots: + void stdoutDataReceivedSlot(); + +private: + bool _ready; + + virtual void addStdoutLine(const QString &line); + + friend class ProcessManager; +}; + +//----------------------------------------------------------------------------- +class ProcessManager : public Log::Base +{ +public: + ProcessManager(Log::Base *base); + Process &process() { return _process; } + bool isReady() const { return _process._ready; } + bool start(); + bool runSynchronously(); + bool sendCommand(const QString &cmd, bool synchronous); + bool sendSignal(uint n, bool synchronous); + bool getVersion(VersionData &version); + +private: + Process _process; +}; + +//----------------------------------------------------------------------------- +class Hardware : public Programmer::Hardware +{ +public: + Hardware(::Programmer::Base &base) : Programmer::Hardware(base, 0, QString::null), _manager(0) {} + virtual ~Hardware(); + bool isReady() const { return _manager->isReady(); } + bool execute(const QString &command, bool synchronous, QStringList *output = 0); + bool signal(uint n, bool synchronous, QStringList *output = 0); + const VersionData &version() const { return _version; } + +private: + ProcessManager *_manager; + VersionData _version; + + virtual bool internalConnectHardware(); + virtual void internalDisconnectHardware(); +}; + +//----------------------------------------------------------------------------- +class DeviceSpecific : public ::Programmer::DeviceSpecific +{ +public: + DeviceSpecific(::Programmer::Base &base) : ::Programmer::DeviceSpecific(base) {} + virtual bool setPowerOff() { return false; } + virtual bool setPowerOn() { return false; } + virtual bool setTargetPowerOn(bool) { return true; } +}; + +} // namespace + +#endif diff --git a/src/progs/gpsim/base/gpsim_debug.cpp b/src/progs/gpsim/base/gpsim_debug.cpp new file mode 100644 index 0000000..b2bcec5 --- /dev/null +++ b/src/progs/gpsim/base/gpsim_debug.cpp @@ -0,0 +1,282 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "gpsim_debug.h" + +#include +#include + +#include "devices/list/device_list.h" +#include "devices/pic/base/pic_register.h" +#include "coff/base/text_coff.h" +#include "progs/manager/debug_manager.h" + +//---------------------------------------------------------------------------- +GPSim::Debugger::Debugger(Programmer &programmer) + : ::Debugger::PicBase(programmer), _nbBreakpoints(0) +{} + +bool GPSim::Debugger::internalInit() +{ + if ( !hardware()->execute("processor pic" + device()->name().lower(), true) ) return false; + if ( _inputType==PURL::Cod ) return hardware()->execute("load s " + _filename, true); + Q_ASSERT( _inputType==PURL::Hex ); + return hardware()->execute("load h " + _filename, true); +} + +bool GPSim::Debugger::internalRun() +{ + return hardware()->execute("run", false); +} + +bool GPSim::Debugger::hardHalt() +{ + log(Log::LineType::Warning, i18n("Failed to halt target: kill process.")); + _programmer.disconnectHardware(); + return true; +} + +bool GPSim::Debugger::softHalt(bool &success) +{ + success = hardware()->signal(SIGINT, true); + return true; +} + +bool GPSim::Debugger::internalStep() +{ + return hardware()->execute("step", true); +} + +bool GPSim::Debugger::setBreakpoints(const QValueList

&list) +{ + for (uint i=0; i<_nbBreakpoints; i++) + if ( !hardware()->execute("clear " + QString::number(i), true) ) return false; + for (uint i=0; iexecute("break e 0x" + toHex(list[i], nbChars(list[i].toUInt())), true) ) return false; + _nbBreakpoints = list.count(); + return true; +} + +bool GPSim::Debugger::internalReset() +{ + if ( _programmer.state()==::Programmer::Running && !halt() ) return false; + return hardware()->execute("reset", true); +} + +bool GPSim::Debugger::updateState() +{ + if ( hardware()->isReady() ) _programmer.setState(::Programmer::Halted); + else _programmer.setState(::Programmer::Running); + return true; +} + +bool GPSim::Debugger::findRegExp(const QStringList &lines, const QString &pattern, + const QString &label, QString &value) const +{ + QRegExp rexp(pattern); + uint i = 0; + for (; iversion()<=VersionData(0, 21, 7) || hardware()->version()>=VersionData(0, 22, 0) ) + return getRegister("W", value); + QStringList lines; + if ( !hardware()->execute("dump s", true, &lines) ) return false; + QString w = (_coff->symbol("_WREG") ? "_WREG" : "W"); + QString s; + if ( !findRegExp(lines, "^\\s*[0-9A-Fa-f]+\\s+(\\w+)\\s*=\\s*([0-9A-Fa-f]+)", w, s) ) { + log(Log::LineType::Error, i18n("Error reading register \"%1\"").arg(w)); + return false; + } + value = fromHex(s, 0); + return true; +} + +bool GPSim::Debugger::getRegister(const QString &name, BitValue &value) +{ + QStringList lines; + QRegExp r; + if ( hardware()->version()execute("x " + name, true, &lines) ) return false; + r.setPattern("\\w+\\s*[][\\w]+\\s*=\\s*(?:0x|)([0-9A-Fa-f]+)(?:\\W.*|)"); + } else { + if ( !hardware()->execute(name, true, &lines) ) return false; + r.setPattern("[^=]*=\\s*(?:0x|\\$)([0-9A-Fa-f]+)(?:\\W.*|)"); + } + uint i = 0; + for (; iregistersData(); + QString name = toHex(address, rdata.nbCharsAddress()); + if ( hardware()->version()registersData().sfrNames[data.address()]; + if ( name=="WREG" ) return readWreg(value); + if ( !name.isEmpty() ) return getRegister(name.lower(), value); + return getRegister(data.address(), value); +} + +bool GPSim::Debugger::setRegister(const QString &name, BitValue value) +{ + if ( hardware()->version()registersData(); + QString s = QString("%1 = %2").arg(name).arg(toHexLabel(value, rdata.nbChars())); + return hardware()->execute(s, true); +} + +bool GPSim::Debugger::setRegister(Address address, BitValue value) +{ + const Pic::RegistersData &rdata = device()->registersData(); + QString s = QString("ramData[$%1]").arg(toHex(address, rdata.nbCharsAddress())); + return setRegister(s, value); +} + +bool GPSim::Debugger::writeRegister(const Register::TypeData &data, BitValue value) +{ + if ( data.type()==Register::Special ) { + if ( data.name()=="WREG" ) return writeWreg(value); + if ( data.name()=="PC" ) { + log(Log::LineType::Warning, i18n("Writing PC is not supported by gpsim")); + return true; + } + Q_ASSERT(false); + return false; + } + const Pic::RegistersData &rdata = device()->registersData(); + QString name = rdata.sfrNames[data.address()]; + if ( !name.isEmpty() ) return setRegister(name.lower(), value); + return setRegister(data.address(), value); +} + +bool GPSim::Debugger::writeWreg(BitValue value) +{ + return setRegister("W", value); +} + +bool GPSim::Debugger::updatePortStatus(uint index, QMap &bits) +{ + for (uint i=0; iregistersData().hasPortBit(index, i) ) continue; + QString name = device()->registersData().portName(index).lower() + QString::number(i); + QStringList lines; + if ( !hardware()->execute("symbol " + name, true, &lines) ) return false; + QString pattern = "^(\\w+)=([^\\s])+\\s*", value; + if ( !findRegExp(lines, pattern, "bitState", value) || value.length()!=1 ) { + log(Log::LineType::Error, i18n("Error reading state of IO bit: %1").arg(name)); + return false; + } + switch (value[0].latin1()) { + case 'H': + case '1': bits[i].state = Device::High; break; + case 'L': + case '0': bits[i].state = Device::Low; break; + case 'W': bits[i].state = Device::WeakPullUp; break; + case 'w': bits[i].state = Device::WeakPullDown; break; + case 'Z': bits[i].state = Device::HighImpedance; break; + case 'X': bits[i].state = Device::Unknown; break; + default: + bits[i].state = Device::Unknown; + log(Log::LineType::Warning, i18n("Unknown state for IO bit: %1 (%2)").arg(name).arg(value)); + break; + } + if ( !findRegExp(lines, pattern, "Driving", value) || value.length()!=1 ) { + log(Log::LineType::Error, i18n("Error reading driving state of IO bit: %1").arg(name)); + return false; + } + bits[i].driving = ( value[0]=='1' ); + if (bits[i].driving) { + if ( !findRegExp(lines, pattern, "drivingState", value) || value.length()!=1 ) { + log(Log::LineType::Error, i18n("Error reading driving state of IO bit: %1").arg(name)); + return false; + } + bits[i].drivingState = (value[0]=='0' ? Device::IoLow : Device::IoHigh); + bits[i].drivenState = Device::IoUnknown; + } else { + if ( !findRegExp(lines, pattern, "drivenState", value) || value.length()!=1 ) { + log(Log::LineType::Error, i18n("Error reading driven state of IO bit: %1").arg(name)); + return false; + } + bits[i].drivenState = (value[0]=='0' ? Device::IoLow : Device::IoHigh); + bits[i].drivingState = Device::IoUnknown; + } + } + return true; +} + +//---------------------------------------------------------------------------- +QString GPSim::Group::statusLabel() const +{ + return i18n("GPSim (4MHz)"); // #### FIXME: add config +} + +void GPSim::Group::initSupported() +{ + ProcessManager manager(0); + if ( !manager.start() ) return; + VersionData version; + if ( !manager.getVersion(version) ) return; + bool oldGpsim = ( version(Device::lister().data(s)); + if (data) { + if ( data->architecture()==Pic::Architecture::P18F && oldGpsim ) continue; + addDevice(data->name(), data, ::Group::Support::Tested); + } + } +} + +Programmer::Hardware *GPSim::Group::createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &) const +{ + return new Hardware(base); +} + +Programmer::DeviceSpecific *GPSim::Group::createDeviceSpecific(::Programmer::Base &base) const +{ + return new DeviceSpecific(base); +} diff --git a/src/progs/gpsim/base/gpsim_debug.h b/src/progs/gpsim/base/gpsim_debug.h new file mode 100644 index 0000000..ad838b2 --- /dev/null +++ b/src/progs/gpsim/base/gpsim_debug.h @@ -0,0 +1,95 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef GPSIM_DEBUG_H +#define GPSIM_DEBUG_H + +#include "gpsim.h" +#include "devices/pic/prog/pic_prog.h" +#include "devices/pic/prog/pic_debug.h" + +namespace GPSim +{ +//----------------------------------------------------------------------------- +class Programmer : public ::Programmer::PicBase +{ +Q_OBJECT +public: + Programmer(const ::Programmer::Group &group, const Pic::Data *data) + : Programmer::PicBase(group, data, "gpsim_programmer") {} + +private: + virtual VersionData minVersion() const { return VersionData(0, 21, 0); } + virtual bool verifyDeviceId() { return true; } + virtual bool checkErase() { return false; } + virtual bool internalErase(const Device::MemoryRange &) { return false; } + virtual bool checkRead() { return false; } + virtual bool internalRead(Device::Memory &, const Device::MemoryRange &) { return false; } + virtual bool checkProgram(const Device::Memory &) { return false; } + virtual bool internalProgram(const Device::Memory &, const Device::MemoryRange &) { return false; } + virtual bool checkVerify() { return false; } + virtual bool internalVerify(const Device::Memory &, const Device::MemoryRange &, ::Programmer::VerifyActions) { return false; } +}; + +//----------------------------------------------------------------------------- +class Debugger : public ::Debugger::PicBase +{ +public: + Debugger(Programmer &programmer); + virtual bool setBreakpoints(const QValueList
&list); + virtual bool readRegister(const Register::TypeData &data, BitValue &value); + virtual bool writeRegister(const Register::TypeData &data, BitValue value); + virtual bool updatePortStatus(uint index, QMap &bits); + +private: + uint _nbBreakpoints; + + bool findRegExp(const QStringList &lines, const QString &pattern, + const QString &label, QString &value) const; + bool getRegister(const QString &name, BitValue &value); + bool setRegister(const QString &name, BitValue value); + bool getRegister(Address address, BitValue &value); + bool setRegister(Address address, BitValue value); + Hardware *hardware() { return static_cast(_programmer.hardware()); } + const Pic::Data *device() const { return static_cast(_programmer.device()); } + virtual bool internalInit(); + virtual bool updateState(); + virtual bool internalRun(); + virtual bool internalStep(); + virtual bool softHalt(bool &success); + virtual bool hardHalt(); + virtual bool internalReset(); + bool readWreg(BitValue &value); + bool writeWreg(BitValue value); +}; + +//----------------------------------------------------------------------------- +class Group : public ::Programmer::PicGroup +{ +public: + virtual QString name() const { return "gpsim"; } + virtual QString label() const { return i18n("GPSim"); } + virtual QString statusLabel() const; + virtual ::Programmer::Properties properties() const { return ::Programmer::Debugger | ::Programmer::HasConnectedState; } + virtual ::Programmer::TargetPowerMode targetPowerMode() const { return ::Programmer::TargetSelfPowered; } + virtual bool isPortSupported(PortType) const { return false; } + virtual uint maxNbBreakpoints(const Device::Data *) const { return 100; } + virtual bool isInputFileTypeSupported(PURL::FileType type) const { return ( type==PURL::Cod || type==PURL::Hex ); } + +protected: + virtual void initSupported(); + virtual ::Programmer::Base *createBase(const Device::Data *data) const { return new Programmer(*this, static_cast(data)); } + virtual ::Programmer::Hardware *createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &hd) const; + virtual ::Programmer::DeviceSpecific *createDeviceSpecific(::Programmer::Base &base) const; + virtual ::Debugger::Base *createDebuggerBase(::Programmer::Base &base) const { return new Debugger(static_cast(base)); } + virtual ::Debugger::Specific *createDebuggerSpecific(::Debugger::Base &) const { return 0; } +}; + +} // namespace + +#endif diff --git a/src/progs/gpsim/gpsim.pro b/src/progs/gpsim/gpsim.pro new file mode 100644 index 0000000..fe430fe --- /dev/null +++ b/src/progs/gpsim/gpsim.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = base diff --git a/src/progs/gpsim/gui/Makefile.am b/src/progs/gpsim/gui/Makefile.am new file mode 100644 index 0000000..d63f4a8 --- /dev/null +++ b/src/progs/gpsim/gui/Makefile.am @@ -0,0 +1,5 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +libgpsimui_la_LDFLAGS = $(all_libraries) +noinst_LTLIBRARIES = libgpsimui.la +libgpsimui_la_SOURCES = gpsim_group_ui.cpp diff --git a/src/progs/gpsim/gui/gpsim_group_ui.cpp b/src/progs/gpsim/gui/gpsim_group_ui.cpp new file mode 100644 index 0000000..3949b8e --- /dev/null +++ b/src/progs/gpsim/gui/gpsim_group_ui.cpp @@ -0,0 +1,42 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "gpsim_group_ui.h" + +#include + +#include "progs/base/prog_group.h" +#include "progs/gpsim/base/gpsim.h" + +//---------------------------------------------------------------------------- +GPSim::ConfigWidget::ConfigWidget(const ::Programmer::Group &group, QWidget *parent) + : ::Programmer::ConfigWidget(group, parent) +{ + uint row = numRows(); + QLabel *label = new QLabel(i18n("Status:"), this); + addWidget(label, row,row, 0,0); + _status = new QLabel(this); + addWidget(_status, row,row, 1,1); + + QTimer::singleShot(0, this, SLOT(updateStatus())); +} + +void GPSim::ConfigWidget::updateStatus() +{ + VersionData version; + ProcessManager manager(0); + if ( !manager.start() ) _status->setText(i18n("Could not start \"gpsim\"")); + else if ( !manager.getVersion(version) || !version.isValid() ) _status->setText(i18n("Could not detect \"gpsim\" version")); + else _status->setText(i18n("Found version \"%1\"").arg(version.pretty())); +} + +//---------------------------------------------------------------------------- +::Programmer::ConfigWidget *GPSim::GroupUI::createConfigWidget(QWidget *parent) const +{ + return new ConfigWidget(static_cast(group()), parent); +} diff --git a/src/progs/gpsim/gui/gpsim_group_ui.h b/src/progs/gpsim/gui/gpsim_group_ui.h new file mode 100644 index 0000000..485aa69 --- /dev/null +++ b/src/progs/gpsim/gui/gpsim_group_ui.h @@ -0,0 +1,42 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef GPSIM_GROUP_UI_H +#define GPSIM_GROUP_UI_H + +#include "progs/gui/prog_group_ui.h" +#include "progs/gui/prog_config_widget.h" + +namespace GPSim +{ +//---------------------------------------------------------------------------- +class ConfigWidget : public ::Programmer::ConfigWidget +{ +Q_OBJECT +public: + ConfigWidget(const ::Programmer::Group &group, QWidget *parent); + +private slots: + void updateStatus(); + +private: + QLabel *_status; +}; + +//---------------------------------------------------------------------------- +class GroupUI : public ::Programmer::GroupUI +{ +public: + virtual ::Programmer::ConfigWidget *createConfigWidget(QWidget *parent) const; + virtual bool hasAdvancedDialog() const { return false; } + virtual ::Programmer::AdvancedDialog *createAdvancedDialog(::Programmer::Base &, QWidget *) const { return 0; } +}; + +} // namespace + +#endif diff --git a/src/progs/gui/Makefile.am b/src/progs/gui/Makefile.am new file mode 100644 index 0000000..7b32635 --- /dev/null +++ b/src/progs/gui/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +libprogui_la_LDFLAGS = $(all_libraries) +noinst_LTLIBRARIES = libprogui.la +libprogui_la_SOURCES = prog_config_widget.cpp prog_group_ui.cpp \ + hardware_config_widget.cpp prog_config_center.cpp port_selector.cpp debug_config_center.cpp diff --git a/src/progs/gui/debug_config_center.cpp b/src/progs/gui/debug_config_center.cpp new file mode 100644 index 0000000..9286e3e --- /dev/null +++ b/src/progs/gui/debug_config_center.cpp @@ -0,0 +1,17 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "debug_config_center.h" + +#include + +QPixmap Debugger::OptionsConfigWidget::pixmap() const +{ + KIconLoader loader; + return loader.loadIcon("piklab_config_debugger", KIcon::Toolbar, KIcon::SizeMedium); +} diff --git a/src/progs/gui/debug_config_center.h b/src/progs/gui/debug_config_center.h new file mode 100644 index 0000000..a8e496e --- /dev/null +++ b/src/progs/gui/debug_config_center.h @@ -0,0 +1,28 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef DEBUG_CONFIG_CENTER_H +#define DEBUG_CONFIG_CENTER_H + +#include + +#include "common/gui/config_widget.h" +#include "progs/base/debug_config.h" + +namespace Debugger +{ + +BEGIN_DECLARE_CONFIG_WIDGET(Config, OptionsConfigWidget) + virtual QString header() const { return i18n("Debugging Options"); } + virtual QString title() const { return i18n("Debugging Options"); } + virtual QPixmap pixmap() const; +END_DECLARE_CONFIG_WIDGET + +} // namespace + +#endif diff --git a/src/progs/gui/hardware_config_widget.cpp b/src/progs/gui/hardware_config_widget.cpp new file mode 100644 index 0000000..8d82ddb --- /dev/null +++ b/src/progs/gui/hardware_config_widget.cpp @@ -0,0 +1,204 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "hardware_config_widget.h" + +#include +#include + +#include "progs/base/prog_config.h" +#include "devices/base/device_group.h" +#include "common/gui/misc_gui.h" + +//----------------------------------------------------------------------------- +Hardware::HConfigWidget::HConfigWidget(::Programmer::Base &base, QWidget *parent, bool edit) + : QFrame(parent, "hardware_config_widget"), _edit(edit), _connected(false), _base(base) +{ + _hardware = 0; + + QHBoxLayout *top = new QHBoxLayout(this, 0, 10); + _mainVBox = new QVBoxLayout(top); + + if (edit) { + _editVBox = new QVBoxLayout(top); + top->setStretchFactor(_editVBox, 1); + } else _editVBox = 0; +} + +//----------------------------------------------------------------------------- +Hardware::EditDialog::EditDialog(ConfigWidget *cwidget, const QString &name, const Port::Description &pd, Data *data) + : KDialogBase(Plain, i18n("Edit and test hardware"), Ok|Cancel, Cancel, cwidget, "hardware_edit_dialog", true, true), + _cwidget(cwidget), _savedName(name), _oldData(data) +{ + setButtonOK(i18n("Save")); + setButtonCancel(i18n("Close")); + + QGridLayout *grid = new QGridLayout(plainPage(), 1, 1, 0, 10); + grid->setColStretch(2, 1); + + QLabel *label = new QLabel(i18n("Hardware name:"), plainPage()); + grid->addWidget(label, 0, 0); + _name = new QLineEdit(name, plainPage()); + grid->addWidget(_name, 0, 1); + + label = new QLabel(i18n("%1 at %2:").arg(pd.type.label()).arg(pd.device), plainPage()); + grid->addWidget(label, 1, 0); + label = new QLabel(plainPage()); + grid->addWidget(label, 1, 1); + + _hc = cwidget->createHardwareConfigWidget(plainPage(), true); + grid->addMultiCellWidget(_hc, 2,2, 0,2); + + grid->setRowStretch(3, 1); + + bool ok = _hc->set(pd, *data); + label->setText(ok ? i18n("Connected") : i18n("Not Connected")); +} + +void Hardware::EditDialog::slotOk() +{ + if ( _name->text().isEmpty() ) { + MessageBox::sorry(i18n("Could not save configuration: hardware name is empty."), Log::Show); + return; + } + if ( _cwidget->_config->isStandardHardware(_name->text()) ) { + MessageBox::sorry(i18n("The hardware name is already used for a standard hardware."), Log::Show); + return; + } + QStringList names = _cwidget->_config->hardwareNames(PortType::Nb_Types); // all hardwares + if ( names.contains(_name->text()) ) { + if ( !MessageBox::askContinue(i18n("Do you want to overwrite this custom hardware \"%1\"?").arg(_name->text()), + KStdGuiItem::save()) ) return; + } + delete _oldData; + _oldData = _hc->data(); + _cwidget->_config->writeCustomHardware(_name->text(), *_oldData); + _savedName = _name->text(); + KDialogBase::accept(); +} + +void Hardware::EditDialog::slotCancel() +{ + Data *data = _hc->data(); + bool equal = _oldData->isEqual(*data); + delete data; + if ( !equal && !MessageBox::askContinue(i18n("Closing will discard changes you have made. Close anyway?"), KStdGuiItem::close()) ) + return; + KDialogBase::reject(); +} + +//----------------------------------------------------------------------------- +Hardware::ConfigWidget::ConfigWidget(::Programmer::Base *base, Config *config, QWidget *parent) + : ::Programmer::ConfigWidget(base->group(), parent), _base(base), _config(config), _hc(0) +{ +// programmer combo + uint row = numRows(); + _configCombo = new QComboBox(this); + connect(_configCombo, SIGNAL(activated(int)), SLOT(configChanged(int))); + addWidget(_configCombo, row,row, 0,0); + row++; + +// hardware config + QHBoxLayout *hbox = new QHBoxLayout(10); + _hbox = new QHBoxLayout(10); + hbox->addLayout(_hbox); + addLayout(hbox, row,row, 0,1); + row++; + +// comment + _comment = new KTextBrowser(this); + addWidget(_comment, row,row, 0,1); + row++; + +// buttons + QVBoxLayout *vbox = new QVBoxLayout(hbox); + _editButton = new KPushButton(this); + connect(_editButton, SIGNAL(clicked()), SLOT(editClicked())); + vbox->addWidget(_editButton); + _deleteButton = new KPushButton(i18n("Delete"), this); + connect(_deleteButton, SIGNAL(clicked()), SLOT(deleteClicked())); + vbox->addWidget(_deleteButton); + vbox->addStretch(1); +} + +void Hardware::ConfigWidget::saveConfig() +{ + ::Programmer::ConfigWidget::saveConfig(); + _config->writeCurrentHardware(_hc->portDescription().type, _names[_configCombo->currentItem()]); +} + +void Hardware::ConfigWidget::configChanged(int i) +{ + set(_hc->portDescription(), i); +} + +bool Hardware::ConfigWidget::set(const Port::Description &pd, uint i) +{ + Data *hd = _config->hardwareData(_names[i]); + if ( _hc==0 ) { + _hc = createHardwareConfigWidget(this, false); + _hc->show(); + _hbox->addWidget(_hc); + } + bool ok = _hc->set(pd, *hd); + delete hd; + QString s = _config->comment(_names[i]); + if ( s.isEmpty() ) _comment->hide(); + else { + _comment->setText(s); + _comment->show(); + } + bool custom = !_config->isStandardHardware(_names[i]); + _editButton->setText(custom ? i18n("Edit/Test...") : i18n("New/Test...")); + _deleteButton->setEnabled(custom); + return ok; +} + +bool Hardware::ConfigWidget::setPort(const ::Programmer::HardwareDescription &hd) +{ + updateList(hd.port.type); + int i = _names.findIndex(_config->currentHardware(hd.port.type)); + if ( i!=-1 ) _configCombo->setCurrentItem(i); + return set(hd.port, _configCombo->currentItem()); +} + +void Hardware::ConfigWidget::updateList(PortType type) +{ + _configCombo->clear(); + _names = _config->hardwareNames(type); + for (uint i=0; i<_names.count(); i++) { + bool standard = _config->isStandardHardware(_names[i]); + QString s = (standard ? _config->label(_names[i]) : i18n("%1 ").arg(_names[i])); + _configCombo->insertItem(s); + } +} + +void Hardware::ConfigWidget::editClicked() +{ + QString name = _names[_configCombo->currentItem()]; + QString cname = (_config->isStandardHardware(name) ? QString::null : name); + Port::Description pd = _hc->portDescription(); + EditDialog *hcd = new EditDialog(this, cname, pd, _hc->data()); + int res = hcd->exec(); + if ( res==QDialog::Rejected ) return; + updateList(pd.type); + int index = _names.findIndex(hcd->savedName()); + _configCombo->setCurrentItem(index); + configChanged(_configCombo->currentItem()); +} + +void Hardware::ConfigWidget::deleteClicked() +{ + QString name = _names[_configCombo->currentItem()]; + if ( !MessageBox::askContinue(i18n("Do you want to delete custom hardware \"%1\"?").arg(name), + KStdGuiItem::del()) ) return; + _config->deleteCustomHardware(name); + updateList(_hc->portDescription().type); + configChanged(_configCombo->currentItem()); +} diff --git a/src/progs/gui/hardware_config_widget.h b/src/progs/gui/hardware_config_widget.h new file mode 100644 index 0000000..d373990 --- /dev/null +++ b/src/progs/gui/hardware_config_widget.h @@ -0,0 +1,102 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#ifndef HARDWARE_CONFIG_WIDGET +#define HARDWARE_CONFIG_WIDGET + +#include +#include +#include +#include + +#include "progs/base/hardware_config.h" +#include "progs/gui/prog_config_widget.h" +#include "progs/base/generic_prog.h" +#include "progs/base/prog_specific.h" + +namespace Hardware +{ + +//----------------------------------------------------------------------------- +class HConfigWidget : public QFrame +{ +Q_OBJECT +public: + HConfigWidget(::Programmer::Base &base, QWidget *parent, bool edit); + virtual ~HConfigWidget() { delete _hardware; } + virtual bool set(const Port::Description &pd, const Data &data) = 0; + virtual Data *data() const = 0; + Port::Description portDescription() const { return _hardware->portDescription(); } + +protected: + ::Programmer::Hardware *_hardware; + QVBoxLayout *_mainVBox, *_editVBox; + bool _edit, _connected; + ::Programmer::Base &_base; +}; + +//----------------------------------------------------------------------------- +class ConfigWidget; + +class EditDialog : public KDialogBase +{ +Q_OBJECT +public: + EditDialog(ConfigWidget *parent, const QString &name, const Port::Description &pd, Data *data); + QString savedName() const { return _savedName; } + +private slots: + virtual void slotOk(); + virtual void slotCancel(); + +private: + ConfigWidget *_cwidget; + QString _savedName; + Data *_oldData; + HConfigWidget *_hc; + QLineEdit *_name; +}; + +//----------------------------------------------------------------------------- +class ConfigWidget : public ::Programmer::ConfigWidget +{ +Q_OBJECT +public: + ConfigWidget(::Programmer::Base *base, Config *config, QWidget *parent); + virtual ~ConfigWidget() { delete _base; } + virtual void saveConfig(); + virtual bool setPort(const ::Programmer::HardwareDescription &hd); + virtual HConfigWidget *createHardwareConfigWidget(QWidget *parent, bool edit) const = 0; + +private slots: + void editClicked(); + void deleteClicked(); + void configChanged(int i); + +protected: + ::Programmer::Base *_base; + +private: + Config *_config; + QStringList _names; + HConfigWidget *_hc; + QPushButton *_editButton, *_deleteButton; + QComboBox *_configCombo; + KTextBrowser *_comment; + QHBoxLayout *_hbox; + + void updateList(PortType type); + bool set(const Port::Description &pd, uint i); + + friend class EditDialog; +}; + +} // namespace + +#endif diff --git a/src/progs/gui/port_selector.cpp b/src/progs/gui/port_selector.cpp new file mode 100644 index 0000000..2aaaabf --- /dev/null +++ b/src/progs/gui/port_selector.cpp @@ -0,0 +1,144 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "port_selector.h" + +#include +#include + +#include "common/port/serial.h" +#include "common/port/parallel.h" +#include "common/global/about.h" +#include "common/gui/purl_gui.h" +#include "progs/base/prog_config.h" + +const char * const PortSelector::LABELS[PortType::Nb_Types] = { + I18N_NOOP("Serial"), I18N_NOOP("Parallel"), I18N_NOOP("USB") +}; + +PortSelector::PortSelector(QWidget *parent) + : QFrame(parent, "port_selector"), _group(0), _main(0) +{ + _top = new QGridLayout(this, 1, 1, 0, 10); + _top->setRowStretch(1, 1); + + _bgroup = new QButtonGroup; + connect(_bgroup, SIGNAL(clicked(int)), SIGNAL(changed())); +} + +void PortSelector::setGroup(const Programmer::Group &group) +{ + _group = &group; + delete _main; + _main = new QWidget(this); + _top->addWidget(_main, 0, 0); + _grid = new QGridLayout(_main, 1, 1, 0, 10); + _grid->setColStretch(3, 1); + FOR_EACH(PortType, type) { + _combos[type.type()] = 0; + _status[type.type()] = 0; + if ( !group.isPortSupported(type) ) continue; + Port::Description pd(type, Programmer::GroupConfig::portDevice(group, type)); + addPortType(pd); + } + _bgroup->setButton(Programmer::GroupConfig::portType(group).type()); + _main->show(); +} + +void PortSelector::addPortType(const Port::Description &pd) +{ + QString noDeviceMessage, notAvailableMessage; + switch (pd.type.type()) { + case PortType::Serial: + noDeviceMessage = i18n("Your computer might not have any serial port."); + break; + case PortType::Parallel: + noDeviceMessage = i18n("Your computer might not have any parallel port " + "or the /dev/parportX device has not been created.
" + "Use \"mknod /dev/parport0 c 99 0\" to create it
" + "and \"chmod a+rw /dev/parport0\" to make it RW enabled."); + notAvailableMessage = i18n("Piklab has been compiled without support for parallel port."); + break; + case PortType::USB: + notAvailableMessage = i18n("Piklab has been compiled without support for USB port."); + break; + case PortType::Nb_Types: Q_ASSERT(false); break; + } + + QRadioButton *rb = new QRadioButton(i18n(LABELS[pd.type.type()]), _main); + _bgroup->insert(rb, pd.type.type()); + if ( _bgroup->count()==1 ) _bgroup->setButton(pd.type.type()); + _grid->addWidget(rb, 3*(_bgroup->count()-1), 0); + _status[pd.type.type()] = new QLabel(_main); + _grid->addWidget(_status[pd.type.type()], 3*(_bgroup->count()-1), 2); + + QStringList list = Port::probedDeviceList(pd.type); + bool noDevice = ( list.isEmpty() && pd.type.data().withDevice ); + bool notAvailable = !Port::isAvailable(pd.type); + rb->setEnabled(!notAvailable); + if ( noDevice || notAvailable ) { + KTextBrowser *comment = new KTextBrowser(_main); + QString text = (notAvailable ? notAvailableMessage : noDeviceMessage); + text += "

"; + text += i18n("See Piklab homepage for help.").arg(Piklab::URLS[Piklab::Support]); + comment->setText(text); + _grid->addMultiCellWidget(comment, 3*(_bgroup->count()-1)+1,3*(_bgroup->count()-1)+1, 0,3); + } + + if (pd.type.data().withDevice) { + _combos[pd.type.type()] = new QComboBox(true, _main); + for (uint i=0; iinsertItem(list[i]); + if ( !pd.device.isEmpty() && !list.contains(pd.device) ) _combos[pd.type.type()]->insertItem(pd.device); + _combos[pd.type.type()]->setCurrentText(pd.device); + connect(_combos[pd.type.type()], SIGNAL(activated(int)), SIGNAL(changed())); + connect(_combos[pd.type.type()], SIGNAL(textChanged(const QString &)), SLOT(textChanged())); + _grid->addWidget(_combos[pd.type.type()], 3*(_bgroup->count()-1), 1); + } +} + +void PortSelector::setStatus(PortType ptype, const QString &message) +{ + _pending = false; + FOR_EACH(PortType, type) { + if ( _status[type.type()]==0 ) continue; + if ( type!=ptype ) _status[type.type()]->hide(); + else { + _status[type.type()]->show(); + _status[type.type()]->setText(message); + } + } +} + +QString PortSelector::device(PortType type) const +{ + if ( type==PortType::Nb_Types || _combos[type.type()]==0 || !type.data().withDevice ) return QString::null; + return _combos[type.type()]->currentText(); +} + +void PortSelector::saveConfig() +{ + Programmer::GroupConfig::writePortType(*_group, type()); + FOR_EACH(PortType, type) { + if ( !_group->isPortSupported(type) ) continue; + Programmer::GroupConfig::writePortDevice(*_group, type, device(type)); + } +} + +PortType PortSelector::type() const +{ + if ( _bgroup->count()==0 ) return PortType::Nb_Types; + return PortType::Type(_bgroup->selectedId()); +} + +void PortSelector::textChanged() +{ + if (_pending) return; + _status[type().type()]->hide(); + _pending = true; + QTimer::singleShot(1000, this, SIGNAL(changed())); +} diff --git a/src/progs/gui/port_selector.h b/src/progs/gui/port_selector.h new file mode 100644 index 0000000..6304d1a --- /dev/null +++ b/src/progs/gui/port_selector.h @@ -0,0 +1,52 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PORT_SELECTOR_H +#define PORT_SELECTOR_H + +#include +#include +#include +#include +#include + +#include "common/port/port.h" +namespace Programmer { class Group; } + +class PortSelector : public QFrame +{ + Q_OBJECT +public: + PortSelector(QWidget *parent); + void setGroup(const Programmer::Group &group); + Port::Description portDescription() const { return Port::Description(type(), device(type())); } + void saveConfig(); + void setStatus(PortType type, const QString &message); + +signals: + void changed(); + +private slots: + void textChanged(); + +private: + const Programmer::Group *_group; + QGridLayout *_top, *_grid; + QWidget *_main; + QButtonGroup *_bgroup; + QComboBox *_combos[PortType::Nb_Types]; + QLabel *_status[PortType::Nb_Types]; + bool _pending; + static const char * const LABELS[PortType::Nb_Types]; + + void addPortType(const Port::Description &pd); + PortType type() const; + QString device(PortType type) const; +}; + +#endif diff --git a/src/progs/gui/prog_config_center.cpp b/src/progs/gui/prog_config_center.cpp new file mode 100644 index 0000000..3210921 --- /dev/null +++ b/src/progs/gui/prog_config_center.cpp @@ -0,0 +1,122 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "prog_config_center.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "progs/list/prog_list.h" +#include "prog_config_widget.h" +#include "prog_group_ui.h" +#include "libgui/global_config.h" +#include "port_selector.h" +#include "libgui/main_global.h" + +//---------------------------------------------------------------------------- +QPixmap Programmer::OptionsConfigWidget::pixmap() const +{ + KIconLoader loader; + return loader.loadIcon("piklab_config_programmer", KIcon::Toolbar, KIcon::SizeMedium); +} + +//---------------------------------------------------------------------------- +Programmer::SelectConfigWidget::SelectConfigWidget() +{ + uint row = 0; + +// programmer type + QLabel *label = new QLabel(i18n("Programmer in use:"), this); + addWidget(label, row,row, 0,0); + _combo = new KeyComboBox(this); + connect(_combo->widget(), SIGNAL(activated(int)), SLOT(programmerChanged())); + addWidget(_combo->widget(), row,row, 1,1); + row++; + +// tab widget + _tabWidget = new QTabWidget(this); + addWidget(_tabWidget, row,row, 0,2); + row++; + + // port selector + _portSelectorContainer = new Container; + _portSelectorContainer->setMargin(10); + _portSelector = new PortSelector(_portSelectorContainer); + connect(_portSelector, SIGNAL(changed()), SLOT(portChanged())); + _portSelectorContainer->addWidget(_portSelector, 0,0, 0,0); + + // specific programmer config + _stack = new KeyWidgetStack(_tabWidget); + static_cast(_stack->widget())->setMargin(10); + KIconLoader loader; + QPixmap icon = loader.loadIcon("configure", KIcon::Small); + _tabWidget->addTab(_stack->widget(), icon, i18n("Specific")); + ::Programmer::Lister::ConstIterator it; + for (it=::Programmer::lister().begin(); it!=::Programmer::lister().end(); ++it) { + _combo->appendItem(it.key(), it.data()->label()); + ::Programmer::ConfigWidget *pcw = static_cast(it.data()->gui())->createConfigWidget(_stack->widget()); + pcw->loadConfig(); + _stack->appendItem(it.key(), pcw); + } + + // init + _combo->setCurrentItem(GlobalConfig::programmerGroup().name()); + _stack->setCurrentItem(GlobalConfig::programmerGroup().name()); + QTimer::singleShot(0, this, SLOT(programmerChanged())); +} + +void Programmer::SelectConfigWidget::portChanged() +{ + ::BusyCursor bc; // can take a few seconds to connect programmer... + HardwareDescription hd; + hd.port = _portSelector->portDescription(); + ::Hardware::Config *config = Main::programmerGroup().hardwareConfig(); + if (config) hd.name = config->currentHardware(hd.port.type); + delete config; + QWidget *w = _stack->item(_combo->currentItem()); + bool ok = static_cast< ::Programmer::ConfigWidget *>(w)->setPort(hd); + _portSelector->setStatus(hd.port.type, ok ? i18n("Connection: Ok") : i18n("Connection: Error")); +} + +QPixmap Programmer::SelectConfigWidget::pixmap() const +{ + KIconLoader loader; + return loader.loadIcon("piklab_config_programmer", KIcon::Toolbar, KIcon::SizeMedium); +} + +void Programmer::SelectConfigWidget::saveConfig() +{ + _portSelector->saveConfig(); + QString key = _combo->currentItem(); + static_cast(_stack->item(key))->saveConfig(); + GlobalConfig::writeProgrammerGroup(*::Programmer::lister().group(key)); +} + +void Programmer::SelectConfigWidget::programmerChanged() +{ + QString key = _combo->currentItem(); + const ::Programmer::Group &group = *::Programmer::lister().group(key); + bool isHardware = !group.isSoftware(); + bool hasTab = ( _tabWidget->indexOf(_portSelectorContainer)!=-1 ); + if (isHardware) { + if ( !hasTab ) { + KIconLoader loader; + QPixmap icon = loader.loadIcon("connect_creating", KIcon::Small); + _tabWidget->insertTab(_portSelectorContainer, icon, i18n("Port Selection"), 0); + } + } else if (hasTab) _tabWidget->removePage(_portSelectorContainer); + _portSelector->setGroup(group); + _stack->setCurrentItem(key); + if (isHardware) QTimer::singleShot(0, this, SLOT(portChanged())); +} diff --git a/src/progs/gui/prog_config_center.h b/src/progs/gui/prog_config_center.h new file mode 100644 index 0000000..ea5ee6d --- /dev/null +++ b/src/progs/gui/prog_config_center.h @@ -0,0 +1,56 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PROG_CONFIG_CENTER_H +#define PROG_CONFIG_CENTER_H + +#include + +#include "common/gui/config_widget.h" +#include "common/gui/key_gui.h" +#include "progs/base/prog_config.h" +class Container; +class PortSelector; + +namespace Programmer +{ +BEGIN_DECLARE_CONFIG_WIDGET(Config, OptionsConfigWidget) + virtual QString header() const { return i18n("Programmer Options"); } + virtual QString title() const { return i18n("Programmer Options"); } + virtual QPixmap pixmap() const; +END_DECLARE_CONFIG_WIDGET + +//---------------------------------------------------------------------------- +class SelectConfigWidget : public ::ConfigWidget +{ +Q_OBJECT +public: + SelectConfigWidget(); + virtual void loadConfig() {} + virtual QString header() const { return i18n("Programmer Selection"); } + virtual QString title() const { return i18n("Programmer Selection"); } + virtual QPixmap pixmap() const; + +public slots: + virtual void saveConfig(); + +private slots: + void programmerChanged(); + void portChanged(); + +private: + KeyComboBox *_combo; + PortSelector *_portSelector; + KeyWidgetStack *_stack; + Container *_portSelectorContainer; + QTabWidget *_tabWidget; +}; + +} // namespace + +#endif diff --git a/src/progs/gui/prog_config_widget.cpp b/src/progs/gui/prog_config_widget.cpp new file mode 100644 index 0000000..be767c2 --- /dev/null +++ b/src/progs/gui/prog_config_widget.cpp @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "prog_config_widget.h" + +#include +#include +#include +#include +#include + +#include "progs/base/prog_config.h" +#include "progs/base/prog_group.h" + +Programmer::ConfigWidget::ConfigWidget(const Group &group, QWidget *parent) + : ::ConfigWidget(parent), _group(group) +{ + if ( group.properties() & NeedDeviceSpecificFirmware ) { + uint row = numRows(); + QLabel *label = new QLabel(i18n("Firmware directory:"), this); + addWidget(label, row,row, 0,0); + _firmwareDir = new KURLRequester(this); + _firmwareDir->setMode(KFile::Directory | KFile::ExistingOnly); + addWidget(_firmwareDir, row,row, 1,1); + } else _firmwareDir = 0; +} + +void Programmer::ConfigWidget::loadConfig() +{ + if (_firmwareDir) _firmwareDir->setURL(GroupConfig::firmwareDirectory(_group)); +} + +void Programmer::ConfigWidget::saveConfig() +{ + if (_firmwareDir) GroupConfig::writeFirmwareDirectory(_group, _firmwareDir->url()); +} + +bool Programmer::ConfigWidget::setPort(const HardwareDescription &hd) +{ + return _group.checkConnection(hd); +} diff --git a/src/progs/gui/prog_config_widget.h b/src/progs/gui/prog_config_widget.h new file mode 100644 index 0000000..d201cea --- /dev/null +++ b/src/progs/gui/prog_config_widget.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PROG_CONFIG_WIDGET +#define PROG_CONFIG_WIDGET + +class QCheckBox; +class KURLRequester; + +#include "common/gui/config_widget.h" +#include "common/port/port.h" + +namespace Programmer +{ +class Group; +class HardwareDescription; + +class ConfigWidget: public ::ConfigWidget +{ +Q_OBJECT +public: + ConfigWidget(const Group &group, QWidget *parent); + virtual void loadConfig(); + const Group &group() const { return _group; } + virtual void saveConfig(); + virtual bool setPort(const HardwareDescription &hd); + +signals: + void updatePortStatus(bool ok); + +protected: + const Group &_group; + +private: + KURLRequester *_firmwareDir; +}; + +} // namespace + +#endif diff --git a/src/progs/gui/prog_group_ui.cpp b/src/progs/gui/prog_group_ui.cpp new file mode 100644 index 0000000..14cf7b0 --- /dev/null +++ b/src/progs/gui/prog_group_ui.cpp @@ -0,0 +1,182 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "prog_group_ui.h" + +#include +#include +#include + +#include "common/common/misc.h" +#include "common/global/purl.h" +#include "common/gui/purl_gui.h" +#include "progs/base/generic_prog.h" +#include "progs/base/prog_group.h" +#include "progs/base/prog_config.h" +#include "libgui/main_global.h" +#include "libgui/toplevel.h" +#include "devices/base/device_group.h" +#include "devices/pic/prog/pic_prog.h" + +//---------------------------------------------------------------------------- +Programmer::StandaloneMemoryCalibrationEditor::StandaloneMemoryCalibrationEditor(const Pic::Memory &memory, QWidget *parent) + : Pic::MemoryCalibrationEditor(0, const_cast(memory), parent) +{} + +void Programmer::StandaloneMemoryCalibrationEditor::init(bool first) +{ + Pic::MemoryCalibrationEditor::init(first); + KAction *action = new KAction(i18n("Read"), "reload", 0, this, SIGNAL(updateCalibration()), Main::toplevel().actionCollection()); + addAction(action); + action = new KAction(i18n("Regenerating..."), 0, 0, this, SIGNAL(regenerate()), Main::toplevel().actionCollection()); + addAction(action); +} + +//---------------------------------------------------------------------------- +Programmer::ButtonContainer::ButtonContainer(const QString &title, + QObject *receiver, const char *updateSlot, QWidget *parent) + : ::ButtonContainer(title, parent) +{ + if (receiver) button().appendAction(i18n("Read"), "reload", receiver, updateSlot); +} + +//---------------------------------------------------------------------------- +Programmer::AdvancedDialog::AdvancedDialog(Base &base, QWidget *parent, const char *name) + : Dialog(IconList, i18n("Advanced Dialog"), Close, Close, parent, name, true, false), + _base(base), _calEditor(0) +{ + // programmer + KIconLoader loader; + QPixmap pixmap = loader.loadIcon("piklab_burnchip", KIcon::Toolbar, KIcon::SizeMedium); + QFrame *page = addPage(i18n("Programmer"), _base.group().label(), pixmap); + QVBoxLayout *vbox = new QVBoxLayout(page); + _programmerContainer = new Container(page); + vbox->addWidget(_programmerContainer); + + Properties properties = _base.group().properties(); + uint row = _programmerContainer->numRows(); + if ( properties & HasFirmware ) { + _firmwareContainer = new ButtonContainer(i18n("Firmware"), this, SLOT(updateFirmware()), _programmerContainer); + _programmerContainer->addWidget(_firmwareContainer, row,row, 0,1); + if ( _base.group().properties() & CanUploadFirmware ) + _firmwareContainer->button().appendAction(i18n("Uploading..."), "piklab_burnchip", this, SLOT(uploadFirmware())); + QLabel *label = new QLabel(i18n("Version:"), _firmwareContainer); + _firmwareContainer->addWidget(label, 1,1, 0,0); + _firmwareLabel = new QLabel(_firmwareContainer); + _firmwareContainer->addWidget(_firmwareLabel, 1,1, 1,1); + row++; + } else { + _firmwareContainer = 0; + _firmwareLabel = 0; + } + + if ( _base.group().canReadVoltages() ) { + _voltagesContainer = new ButtonContainer(i18n("Voltages"), this, SLOT(updateVoltages()), _programmerContainer); + _programmerContainer->addWidget(_voltagesContainer, row,row, 0,1); + row++; + } else _voltagesContainer = 0; + + if ( properties & HasSelfTest ) { + _selfTestContainer = new ButtonContainer(i18n("Self-test"), this, SLOT(updateSelfTest()), _programmerContainer); + _programmerContainer->addWidget(_selfTestContainer, row,row, 0,1); + row++; + } else _selfTestContainer = 0; + + // calibration + pixmap = loader.loadIcon("configure", KIcon::Toolbar, KIcon::SizeMedium); + page = addPage(i18n("Calibration"), i18n("Calibration"), pixmap); + vbox = new QVBoxLayout(page); + _calibrationContainer = new Container(page); + vbox->addWidget(_calibrationContainer); + const Device::Data *data = Main::deviceData(); + QString s; + if ( data==0 ) s = i18n("No device selected."); + else if ( data->group().name()!="pic" || !static_cast(data)->isReadable(Pic::MemoryRangeType::Cal) ) + s = i18n("This device has no calibration information."); + else if ( !_base.group().isSupported(data->name()) ) s = i18n("The selected device is not supported by this programmer."); + else { + const ::Programmer::PicBase &pbase = static_cast(_base); + _calEditor = new StandaloneMemoryCalibrationEditor(pbase.deviceMemory(), _calibrationContainer); + connect(_calEditor, SIGNAL(updateCalibration()), SLOT(updateCalibration())); + connect(_calEditor, SIGNAL(regenerate()), SLOT(regenerateCalibration())); + _calEditor->init(true); + _calEditor->setReadOnly(true); + _calibrationContainer->addWidget(_calEditor, 0,0, 0,0); + } + if ( !s.isEmpty() ) { + QLabel *label = new QLabel(s, _calibrationContainer); + _calibrationContainer->addWidget(label, 0,0, 0,0); + } +} + +bool Programmer::AdvancedDialog::connectProgrammer() +{ + _base.disconnectHardware(); + if ( !_base.connectHardware() ) { + MessageBox::sorry(i18n("Could not connect programmer."), Log::Show); + return false; + } + return true; +} + +bool Programmer::AdvancedDialog::ensureConnected() +{ + if ( (_base.state()==NotConnected || _base.state()==Running) && !connectProgrammer() ) return false; + return _base.setTargetPowerOn(!readConfigEntry(Config::TargetSelfPowered).toBool()); +} + +void Programmer::AdvancedDialog::updateFirmware() +{ + ::BusyCursor bc; + if ( ensureConnected() ) _base.readFirmwareVersion(); + updateDisplay(); +} + +void Programmer::AdvancedDialog::uploadFirmware() +{ + PURL::Url url = PURL::getOpenUrl(":open_firmware", PURL::filter(PURL::Hex), this ,i18n("Open Firmware")); + if ( url.isEmpty() ) return; + ::BusyCursor bc; + if ( !connectProgrammer() ) return; + if ( _base.uploadFirmware(url) ) + MessageBox::information(i18n("Firmware uploaded successfully."), Log::Show); + else MessageBox::sorry(i18n("Error uploading firmware."), Log::Show); + updateFirmware(); +} + +void Programmer::AdvancedDialog::updateVoltages() +{ + ::BusyCursor bc; + if ( ensureConnected() ) _base.readVoltages(); + updateDisplay(); +} + +void Programmer::AdvancedDialog::updateSelfTest() +{ + ::BusyCursor bc; + if ( ensureConnected() ) _base.selfTest(false); + updateDisplay(); +} + +void Programmer::AdvancedDialog::updateCalibration() +{ + ::BusyCursor bc; + if ( ensureConnected() ) static_cast< ::Programmer::PicBase &>(_base).readCalibration(); + updateDisplay(); +} + +void Programmer::AdvancedDialog::regenerateCalibration() +{ + MessageBox::sorry(i18n("Oscillator calibration regeneration is not available with the selected programmer."), Log::Show); +} + +void Programmer::AdvancedDialog::updateDisplay() +{ + if (_firmwareLabel) _firmwareLabel->setText(_base.firmwareVersion().pretty()); + if (_calEditor) _calEditor->updateDisplay(); +} diff --git a/src/progs/gui/prog_group_ui.h b/src/progs/gui/prog_group_ui.h new file mode 100644 index 0000000..cd97834 --- /dev/null +++ b/src/progs/gui/prog_group_ui.h @@ -0,0 +1,89 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PROG_GROUP_UI_H +#define PROG_GROUP_UI_H + +#include "common/gui/container.h" +#include "common/gui/dialog.h" +#include "progs/base/prog_group.h" +#include "progs/base/generic_prog.h" +#include "devices/pic/gui/pic_memory_editor.h" +class Container; +class PopupButton; + +namespace Programmer +{ +class ConfigWidget; +class Base; +class Group; + +//---------------------------------------------------------------------------- +class StandaloneMemoryCalibrationEditor : public Pic::MemoryCalibrationEditor +{ +Q_OBJECT +public: + StandaloneMemoryCalibrationEditor(const Pic::Memory &memory, QWidget *parent); + virtual void init(bool first); + virtual bool hasAction(Device::Action) const { return false; } + +signals: + void updateCalibration(); + void regenerate(); +}; + +//---------------------------------------------------------------------------- +class ButtonContainer : public ::ButtonContainer +{ +Q_OBJECT +public: + ButtonContainer(const QString &title, QObject *receiver, const char *updateSlot, QWidget *parent); +}; + +//---------------------------------------------------------------------------- +class AdvancedDialog : public Dialog +{ +Q_OBJECT +public: + AdvancedDialog(Base &base, QWidget *parent, const char *name); + virtual void updateDisplay(); + +protected: + Base &_base; + Container *_programmerContainer, *_calibrationContainer; + ButtonContainer *_firmwareContainer, *_voltagesContainer, *_selfTestContainer; + Pic::MemoryCalibrationEditor *_calEditor; + bool connectProgrammer(); + bool ensureConnected(); + +protected slots: + void updateFirmware(); + void uploadFirmware(); + void updateVoltages(); + void updateSelfTest(); + void updateCalibration(); + virtual void regenerateCalibration(); + +private: + QLabel *_firmwareLabel; +}; + +//---------------------------------------------------------------------------- +class GroupUI : public ::Group::BaseGui +{ +public: + virtual ::Programmer::ConfigWidget *createConfigWidget(QWidget *parent) const = 0; + virtual bool hasAdvancedDialog() const = 0; + virtual AdvancedDialog *createAdvancedDialog(Base &base, QWidget *parent) const = 0; +}; + +inline const ::Programmer::GroupUI &groupui(const ::Programmer::Base &base) { return static_cast(*base.group().gui()); } + +} // namespace + +#endif diff --git a/src/progs/icd1/Makefile.am b/src/progs/icd1/Makefile.am new file mode 100644 index 0000000..fccf96d --- /dev/null +++ b/src/progs/icd1/Makefile.am @@ -0,0 +1,3 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +SUBDIRS = xml base gui diff --git a/src/progs/icd1/base/Makefile.am b/src/progs/icd1/base/Makefile.am new file mode 100644 index 0000000..3795dc5 --- /dev/null +++ b/src/progs/icd1/base/Makefile.am @@ -0,0 +1,11 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libicd1.la +libicd1_la_SOURCES = icd1.cpp icd1_prog.cpp icd1_serial.cpp icd1_data.cpp +libicd1_la_DEPENDENCIES = icd1_data.cpp + +noinst_DATA = icd1.xml +icd1_data.cpp: ../xml/xml_icd1_parser icd1.xml + ../xml/xml_icd1_parser +CLEANFILES = icd1_data.cpp diff --git a/src/progs/icd1/base/base.pro b/src/progs/icd1/base/base.pro new file mode 100644 index 0000000..8ff4081 --- /dev/null +++ b/src/progs/icd1/base/base.pro @@ -0,0 +1,6 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/lib.pro) + +TARGET = icd1 +HEADERS += icd1.h icd1_data.h icd1_prog.h icd1_serial.h +SOURCES += icd1.cpp icd1_data.cpp icd1_prog.cpp icd1_serial.cpp diff --git a/src/progs/icd1/base/icd1.cpp b/src/progs/icd1/base/icd1.cpp new file mode 100644 index 0000000..8c2704a --- /dev/null +++ b/src/progs/icd1/base/icd1.cpp @@ -0,0 +1,197 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * Copyright (C) 2002-2003 Stephen Landamore * + * * + * 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. * + ***************************************************************************/ +#include "icd1.h" + +#include "common/global/global.h" +#include "common/common/misc.h" +#include "common/port/port_base.h" + +//----------------------------------------------------------------------------- +Icd1::Hardware::Hardware(::Programmer::Base &base, const QString &portDevice) + : Icd::Hardware(base, new SerialPort(portDevice, base)) +{} + +bool Icd1::Hardware::internalConnect(const QString &mode) +{ + if ( !port()->open() ) return false; + if ( !port()->reset() ) return false; + if ( hasError() ) return false; + QByteArray a = toAscii(mode); + if ( !port()->send(a.data(), a.count()) ) return false; + QString s; + if ( !port()->receive(1, s) ) return false; + port()->setPinOn(Port::Serial::RTS, false, Port::PositiveLogic); + Port::msleep(1); + port()->setPinOn(Port::Serial::RTS, true, Port::PositiveLogic); + if ( s.upper()!=mode ) { + log(Log::LineType::Error, i18n("Failed to set port mode to '%1'.").arg(mode)); + return false; + } + return true; +} + +bool Icd1::Hardware::sendCommand(uint cmd, BitValue *res, uint timeout) +{ + if ( !port()->sendCommand(cmd) ) return false; + uchar byte; + if ( !port()->receiveByte((char &)byte, false, timeout) ) return false; + if (res) *res = byte << 8; + if ( !port()->receiveByte((char &)byte, true, timeout) ) return false; + if (res) *res += byte; + return true; +} + +bool Icd1::Hardware::readBlockCommand(uint nbBytes) +{ + Q_ASSERT( nbBytes<=0xFF ); + if ( !port()->sendCommand(0x7D00 + nbBytes) ) return false; + QByteArray a(nbBytes); + for (uint i=0; ireceiveByte(*(a.data()+i), i!=0) ) return false; + _rx = QString(a); + return true; +} + +bool Icd1::Hardware::setTarget() +{ + return sendCommand(0x6300 + data(_base.device()->name()).part); +} + +bool Icd1::Hardware::getFirmwareVersion(VersionData &version) +{ + BitValue v1, v2; + if ( !sendCommand(0x7F00, &v1) || !sendCommand(0x7021, &v2) ) return false; + version = VersionData(v1.byte(1), v1.byte(0), v2.toUInt()); + return true; +} + +bool Icd1::Hardware::readVoltages(VoltagesData &voltages) +{ + if ( !sendCommand(0x7000) ) return false; + BitValue res; + if ( !sendCommand(0x701C, &res) ) return false; + voltages[Pic::TargetVdd].value = (2.050 / 256) * res.toUInt(); // voltage at AN0 pin + voltages[Pic::TargetVdd].value /= (4.7 / 14.7); // voltage at Vcc + log(Log::DebugLevel::Max, QString("Vdd: %1 %2").arg(toHexLabel(res, 4)).arg(voltages[Pic::TargetVdd].value)); + voltages[Pic::TargetVdd].error = false; + if ( !sendCommand(0x701D, &res) ) return false; + voltages[Pic::TargetVpp].value = (2.050 / 256) * res.byte(0); // voltage at AN1 pin + voltages[Pic::TargetVpp].value /= (10.0 / 110.0); // voltage at Vpp + log(Log::DebugLevel::Max, QString("Vpp: %1 %2").arg(toHexLabel(res, 4)).arg(voltages[Pic::TargetVpp].value)); + voltages[Pic::TargetVpp].error = false; + return sendCommand(0x7001); +} + +bool Icd1::Hardware::uploadFirmware(const Pic::Memory &memory) +{ + // #### TODO + return false; +} + +bool Icd1::Hardware::setTargetReset(Pic::ResetMode mode) +{ + // #### TODO + return false; +} + +bool Icd1::Hardware::selfTest() +{ + BitValue res; + if ( !sendCommand(0x700B, &res, 5000) ) return false; + if ( res!=0 ) { + log(Log::LineType::Warning, i18n("Self-test failed (returned value is %1)").arg(toLabel(res))); + return false; + } + return true; +} + +bool Icd1::Hardware::gotoMemory(Pic::MemoryRangeType type, uint offset) +{ + if ( !sendCommand(0x7000) ) return false; // start sequence + uint cmd = (type==Pic::MemoryRangeType::Eeprom ? 0x7006 : 0x7005); + if ( !sendCommand(cmd) ) return false; + if ( type==Pic::MemoryRangeType::Config || type==Pic::MemoryRangeType::UserId || type==Pic::MemoryRangeType::DeviceId ) { + Q_ASSERT( offset==0 ); + offset = device().range(type).start - Address(0x2000); + if ( !sendCommand(0xC000 + offset) ) return false; + } else if ( !sendCommand(0x2000 + offset) ) return false; + return true; +} + +bool Icd1::Hardware::readMemory(Pic::MemoryRangeType type, uint wordOffset, Device::Array &data, const ::Programmer::VerifyData *vdata) +{ + if ( !gotoMemory(type, wordOffset) ) return false; + for (uint i=0; i * + * Copyright (C) 2002-2003 Stephen Landamore * + * * + * 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. * + ***************************************************************************/ +#ifndef ICD1_H +#define ICD1_H + +#include "progs/icd2/base/icd.h" +#include "icd1_data.h" +#include "icd1_serial.h" + +namespace Icd1 +{ +//----------------------------------------------------------------------------- +class Hardware : public Icd::Hardware +{ +public: + Hardware(::Programmer::Base &base, const QString &portDevice); + SerialPort *port() { return static_cast(_port); } + // initialization + virtual bool uploadFirmware(const Pic::Memory &memory); + virtual bool setTarget(); + +// status + virtual bool getFirmwareVersion(VersionData &version); + virtual bool readVoltages(VoltagesData &voltages); + virtual bool setTargetReset(Pic::ResetMode mode); + bool selfTest(); + +// programming + virtual bool readMemory(Pic::MemoryRangeType type, uint wordOffset, Device::Array &data, const ::Programmer::VerifyData *vdata); + virtual bool writeMemory(Pic::MemoryRangeType type, uint wordOffset, const Device::Array &data); + virtual bool eraseAll(); + +// debugging + virtual bool readRegister(Address address, BitValue &value, uint nbBytes); + virtual bool writeRegister(Address address, BitValue value, uint nbBytes); + virtual bool resumeRun(); + virtual bool step(); + virtual bool haltRun(); + virtual BitValue getProgramCounter(); + +private: + virtual bool internalConnect(const QString &mode); + virtual QString receivedData() const { return _rx; } + bool sendCommand(uint cmd, BitValue *res = 0, uint timeout = Port::Serial::DEFAULT_TIMEOUT); + bool readBlockCommand(uint nbBytes); + bool gotoMemory(Pic::MemoryRangeType type, uint offset); +}; + +} // namespace + +#endif diff --git a/src/progs/icd1/base/icd1.xml b/src/progs/icd1/base/icd1.xml new file mode 100644 index 0000000..4be7e3e --- /dev/null +++ b/src/progs/icd1/base/icd1.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/progs/icd1/base/icd1_data.h b/src/progs/icd1/base/icd1_data.h new file mode 100644 index 0000000..4200578 --- /dev/null +++ b/src/progs/icd1/base/icd1_data.h @@ -0,0 +1,22 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef ICD1_DATA_H +#define ICD1_DATA_H + +#include + +namespace Icd1 +{ + struct Data { + uchar part; + }; + extern const Data &data(const QString &device); +} // namespace + +#endif diff --git a/src/progs/icd1/base/icd1_prog.cpp b/src/progs/icd1/base/icd1_prog.cpp new file mode 100644 index 0000000..13d0d4c --- /dev/null +++ b/src/progs/icd1/base/icd1_prog.cpp @@ -0,0 +1,51 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "icd1_prog.h" + +#include + +#include "progs/base/prog_config.h" +#include "devices/list/device_list.h" +#include "icd1_serial.h" + +//----------------------------------------------------------------------------- +void Icd1::ProgrammerBase::clear() +{ + Icd::ProgrammerBase::clear(); + _selfTestResult = ::Programmer::Nb_ResultTypes; +} + +bool Icd1::ProgrammerBase::selfTest(bool ask) +{ + log(Log::DebugLevel::Normal, " Self-test"); + _selfTestResult = (hardware().selfTest() ? ::Programmer::Pass : ::Programmer::Fail); + if ( _selfTestResult==::Programmer::Fail ) { + if ( ask && !askContinue(i18n("Self-test failed. Do you want to continue anyway?")) ) { + logUserAbort(); + return false; + } + } + return true; +} + +//---------------------------------------------------------------------------- +Programmer::Properties Icd1::Group::properties() const +{ + return ::Programmer::Programmer | ::Programmer::HasFirmware | ::Programmer::CanUploadFirmware | ::Programmer::HasSelfTest | ::Programmer::CanReadMemory | ::Programmer::HasConnectedState; +} + +Programmer::Hardware *Icd1::Group::createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &hd) const +{ + return new Hardware(base, hd.port.device); +} + +Programmer::DeviceSpecific *Icd1::Group::createDeviceSpecific(::Programmer::Base &base) const +{ + return new Icd::DeviceSpecific(base); +} diff --git a/src/progs/icd1/base/icd1_prog.h b/src/progs/icd1/base/icd1_prog.h new file mode 100644 index 0000000..721be49 --- /dev/null +++ b/src/progs/icd1/base/icd1_prog.h @@ -0,0 +1,60 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef ICD1_PROG_H +#define ICD1_PROG_H + +#include "common/global/global.h" +#include "progs/icd2/base/icd_prog.h" +#include "icd1.h" +#include "progs/base/prog_group.h" + +namespace Icd1 +{ +class Hardware; + +//----------------------------------------------------------------------------- +class ProgrammerBase : public Icd::ProgrammerBase +{ +Q_OBJECT +public: + ProgrammerBase(const Programmer::Group &group, const Pic::Data *data) + : Icd::ProgrammerBase(group, data, "icd1_programmer_base") {} + virtual bool selfTest(bool ask); + ::Programmer::ResultType selfTestResult() const { return _selfTestResult; } + +protected: + Hardware &hardware() { return static_cast(*_hardware); } + virtual void clear(); + +private: + ::Programmer::ResultType _selfTestResult; +}; + +//----------------------------------------------------------------------------- +class Group : public Icd::Group +{ +public: + virtual QString name() const { return "icd1"; } + virtual QString label() const { return i18n("ICD1 Programmer"); } + virtual QString xmlName() const { return "icd1"; } + virtual ::Programmer::Properties properties() const; + virtual ::Programmer::TargetPowerMode targetPowerMode() const { return ::Programmer::TargetExternallyPowered; } + virtual bool isPortSupported(PortType type) const { return ( type==PortType::Serial ); } + virtual bool canReadVoltage(Pic::VoltageType type) const { return ( type==Pic::TargetVdd || type==Pic::TargetVpp ); } + +protected: + virtual void initSupported(); + virtual ::Programmer::Base *createBase(const Device::Data *data) const { return new ProgrammerBase(*this, static_cast(data)); } + virtual ::Programmer::Hardware *createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &hd) const; + virtual ::Programmer::DeviceSpecific *createDeviceSpecific(::Programmer::Base &base) const; +}; + +} // namespace + +#endif diff --git a/src/progs/icd1/base/icd1_serial.cpp b/src/progs/icd1/base/icd1_serial.cpp new file mode 100644 index 0000000..a506fdb --- /dev/null +++ b/src/progs/icd1/base/icd1_serial.cpp @@ -0,0 +1,76 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * Copyright (C) 2002-2003 Stephen Landamore * + * * + * 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. * + ***************************************************************************/ +#include "icd1_serial.h" + +#include +#include "common/global/global.h" +#include "common/common/misc.h" +#include "common/common/number.h" + +//----------------------------------------------------------------------------- +Icd1::SerialPort::SerialPort(const QString &device, Log::Base &log) + : Port::Serial(device, NeedDrain | NeedFlush, log) +{} + +bool Icd1::SerialPort::open() +{ + if ( !Port::Serial::open() ) return false; + return setMode(NoInputFlag, ByteSize8 | IgnoreControlLines | EnableReceiver, S57600, 0); +} + +bool Icd1::SerialPort::reset() +{ + // reset + setPinOn(RTS, false, Port::PositiveLogic); + setPinOn(DTR, false, Port::PositiveLogic); + Port::msleep(10); + // remove reset + setPinOn(RTS, true, Port::PositiveLogic); + setPinOn(DTR, true, Port::PositiveLogic); + Port::msleep(10); + return true; +} + +bool Icd1::SerialPort::synchronize() +{ + if ( !setPinOn(RTS, false, Port::PositiveLogic) ) return false; + QTime time; + time.start(); + for (;;) { + bool bit; + if ( !readPin(CTS, Port::PositiveLogic, bit) ) return false; + if ( !bit) break; + if ( uint(time.elapsed())>3000 ) { // 3 seconds + log(Log::LineType::Error, i18n("Timeout synchronizing.")); + return false; + } + } + return setPinOn(RTS, true, Port::PositiveLogic); +} + +bool Icd1::SerialPort::sendCommand(uint cmd) +{ + Q_ASSERT( cmd<=0xFFFF ); + synchronize(); + char c[7] = "$XXXX\r"; + QString cs = toHex(cmd, 4); + log(Log::DebugLevel::Extra, QString("Send command: %1").arg(toPrintable(cs, PrintAlphaNum))); + c[1] = cs[0].latin1(); + c[2] = cs[1].latin1(); + c[3] = cs[2].latin1(); + c[4] = cs[3].latin1(); + return send(c, 7); +} + +bool Icd1::SerialPort::receiveByte(char &byte, bool synchronizeBefore, uint timeout) +{ + if ( synchronizeBefore && !synchronize() ) return false; + return receiveChar(byte, timeout); +} diff --git a/src/progs/icd1/base/icd1_serial.h b/src/progs/icd1/base/icd1_serial.h new file mode 100644 index 0000000..e8d03da --- /dev/null +++ b/src/progs/icd1/base/icd1_serial.h @@ -0,0 +1,31 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * Copyright (C) 2002-2003 Stephen Landamore * + * * + * 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. * + ***************************************************************************/ +#ifndef ICD1_SERIAL_H +#define ICD1_SERIAL_H + +#include "common/port/serial.h" + +namespace Icd1 +{ + +class SerialPort : public Port::Serial +{ +public: + SerialPort(const QString &portDevice, Log::Base &log); + bool open(); + bool reset(); + bool synchronize(); + bool sendCommand(uint cmd); + bool receiveByte(char &byte, bool synchronizeBefore, uint timeout = DEFAULT_TIMEOUT); +}; + +} // namespace + +#endif diff --git a/src/progs/icd1/gui/Makefile.am b/src/progs/icd1/gui/Makefile.am new file mode 100644 index 0000000..183aab9 --- /dev/null +++ b/src/progs/icd1/gui/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +libicd1ui_la_LDFLAGS = $(all_libraries) +noinst_LTLIBRARIES = libicd1ui.la + +libicd1ui_la_SOURCES = icd1_group_ui.cpp diff --git a/src/progs/icd1/gui/icd1_group_ui.cpp b/src/progs/icd1/gui/icd1_group_ui.cpp new file mode 100644 index 0000000..34f28d5 --- /dev/null +++ b/src/progs/icd1/gui/icd1_group_ui.cpp @@ -0,0 +1,41 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "icd1_group_ui.h" + +#include "progs/gui/prog_config_widget.h" +#include "progs/base/prog_group.h" +#include "progs/icd1/base/icd1_prog.h" + +//---------------------------------------------------------------------------- +Icd1::AdvancedDialog::AdvancedDialog(ProgrammerBase &base, QWidget *parent) + : ::Programmer::PicAdvancedDialog(base, parent, "icd1_advanced_dialog") +{ + uint row = _selfTestContainer->numRows(); + QLabel *label = new QLabel(i18n("Result:"), _selfTestContainer); + _selfTestContainer->addWidget(label, row,row, 0,0); + _selfTestLabel = new QLabel(_selfTestContainer); + _selfTestContainer->addWidget(_selfTestLabel, row,row, 1,1); +} + +void Icd1::AdvancedDialog::updateDisplay() +{ + ::Programmer::PicAdvancedDialog::updateDisplay(); + _selfTestLabel->setText(i18n(::Programmer::RESULT_TYPE_LABELS[base().selfTestResult()])); +} + +//---------------------------------------------------------------------------- +::Programmer::ConfigWidget *Icd1::GroupUI::createConfigWidget(QWidget *parent) const +{ + return new ::Programmer::ConfigWidget(static_cast(group()), parent); +} + +::Programmer::AdvancedDialog *Icd1::GroupUI::createAdvancedDialog(::Programmer::Base &base, QWidget *parent) const +{ + return new AdvancedDialog(static_cast(base), parent); +} diff --git a/src/progs/icd1/gui/icd1_group_ui.h b/src/progs/icd1/gui/icd1_group_ui.h new file mode 100644 index 0000000..f60562a --- /dev/null +++ b/src/progs/icd1/gui/icd1_group_ui.h @@ -0,0 +1,43 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef ICD1_GROUP_UI_H +#define ICD1_GROUP_UI_H + +#include "devices/pic/gui/pic_prog_group_ui.h" +#include "progs/icd1/base/icd1_prog.h" + +namespace Icd1 +{ +class Group; + +//---------------------------------------------------------------------------- +class AdvancedDialog : public ::Programmer::PicAdvancedDialog +{ +Q_OBJECT +public: + AdvancedDialog(ProgrammerBase &base, QWidget *parent); + virtual void updateDisplay(); + +private: + QLabel *_selfTestLabel; + ProgrammerBase &base() { return static_cast(_base); } +}; + +//---------------------------------------------------------------------------- +class GroupUI : public ::Programmer::GroupUI +{ +public: + virtual ::Programmer::ConfigWidget *createConfigWidget(QWidget *parent) const; + virtual bool hasAdvancedDialog() const { return true; } + virtual ::Programmer::AdvancedDialog *createAdvancedDialog(::Programmer::Base &base, QWidget *parent) const; +}; + +} // namespace + +#endif diff --git a/src/progs/icd1/icd1.pro b/src/progs/icd1/icd1.pro new file mode 100644 index 0000000..60ac0f5 --- /dev/null +++ b/src/progs/icd1/icd1.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = xml base diff --git a/src/progs/icd1/xml/Makefile.am b/src/progs/icd1/xml/Makefile.am new file mode 100644 index 0000000..dab961c --- /dev/null +++ b/src/progs/icd1/xml/Makefile.am @@ -0,0 +1,14 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_PROGRAMS = xml_icd1_parser +xml_icd1_parser_SOURCES = xml_icd1_parser.cpp +OBJECTS = $(top_builddir)/src/devices/list/libdevicelistnoui.la \ + $(top_builddir)/src/devices/pic/pic/libpic.la $(top_builddir)/src/devices/pic/base/libpicbase.la \ + $(top_builddir)/src/devices/pic/xml_data/libpicxml.la \ + $(top_builddir)/src/devices/mem24/mem24/libmem24.la $(top_builddir)/src/devices/mem24/base/libmem24base.la \ + $(top_builddir)/src/devices/mem24/xml_data/libmem24xml.la \ + $(top_builddir)/src/xml_to_data/libxmltodata.la $(top_builddir)/src/devices/base/libdevicebase.la \ + $(top_builddir)/src/common/common/libcommon.la +xml_icd1_parser_DEPENDENCIES = $(OBJECTS) +xml_icd1_parser_LDADD = $(OBJECTS) $(LIB_KDECORE) diff --git a/src/progs/icd1/xml/xml.pro b/src/progs/icd1/xml/xml.pro new file mode 100644 index 0000000..ebbde6c --- /dev/null +++ b/src/progs/icd1/xml/xml.pro @@ -0,0 +1,18 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/app.pro) + +TARGET = xml_icd1_parser +SOURCES += xml_icd1_parser.cpp +LIBS += ../../../devices/list/libdevicelist.a \ + ../../../devices/mem24/mem24/libmem24.a ../../../devices/mem24/xml_data/libmem24xml.a \ + ../../../devices/mem24/base/libmem24base.a \ + ../../../devices/pic/pic/libpic.a ../../../devices/pic/xml_data/libpicxml.a \ + ../../../devices/pic/base/libpicbase.a ../../../xml_to_data/libxmltodata.a \ + ../../../devices/base/libdevicebase.a ../../../common/global/libglobal.a \ + ../../../common/nokde/libnokde.a ../../../common/common/libcommon.a + +unix:QMAKE_POST_LINK = cd ../base && ../xml/xml_icd1_parser +unix:QMAKE_CLEAN += ../base/icd1_data.cpp +win32:QMAKE_POST_LINK = cd ..\base && ..\xml\xml_icd1_parser.exe +win32:QMAKE_CLEAN += ..\base\icd1_data.cpp + diff --git a/src/progs/icd1/xml/xml_icd1_parser.cpp b/src/progs/icd1/xml/xml_icd1_parser.cpp new file mode 100644 index 0000000..e09f51c --- /dev/null +++ b/src/progs/icd1/xml/xml_icd1_parser.cpp @@ -0,0 +1,41 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "xml_to_data/prog_xml_to_data.h" +#include "progs/icd1/base/icd1_data.h" + +//----------------------------------------------------------------------------- +namespace Icd1 +{ + +class XmlToData : public Programmer::XmlToData +{ +public: + XmlToData() : Programmer::XmlToData("icd1", "Icd1") {} + +private: + virtual void parseData(QDomElement element, Data &data); + virtual void outputData(const Data &data, QTextStream &s) const; +}; + +void Icd1::XmlToData::parseData(QDomElement element, Data &data) +{ + bool ok; + data.part = fromHexLabel(element.attribute("family"), 2, &ok); + if ( !ok ) qFatal("Missing or malformed family attribute"); +} + +void Icd1::XmlToData::outputData(const Data &data, QTextStream &s) const +{ + s << toHexLabel(data.part, 2); +} + +} // namespace + +//----------------------------------------------------------------------------- +XML_MAIN(Icd1::XmlToData) diff --git a/src/progs/icd2/Makefile.am b/src/progs/icd2/Makefile.am new file mode 100644 index 0000000..cde6042 --- /dev/null +++ b/src/progs/icd2/Makefile.am @@ -0,0 +1,3 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +SUBDIRS = icd2_data xml base gui diff --git a/src/progs/icd2/base/Makefile.am b/src/progs/icd2/base/Makefile.am new file mode 100644 index 0000000..9350219 --- /dev/null +++ b/src/progs/icd2/base/Makefile.am @@ -0,0 +1,13 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libicd2.la +libicd2_la_SOURCES = microchip.cpp icd2.cpp icd2_prog.cpp icd2_serial.cpp \ + icd2_usb.cpp icd2_usb_firmware.cpp icd2_data.cpp icd2_debug.cpp icd.cpp \ + icd_prog.cpp icd2_debug_specific.cpp +libicd2_la_DEPENDENCIES = icd2_data.cpp + +noinst_DATA = icd2.xml +icd2_data.cpp: ../xml/xml_icd2_parser icd2.xml + ../xml/xml_icd2_parser +CLEANFILES = icd2_data.cpp diff --git a/src/progs/icd2/base/base.pro b/src/progs/icd2/base/base.pro new file mode 100644 index 0000000..6ca2f2d --- /dev/null +++ b/src/progs/icd2/base/base.pro @@ -0,0 +1,8 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/lib.pro) + +TARGET = icd2 +HEADERS += microchip.h icd.h icd_prog.h icd2.h icd2_data.h \ + icd2_prog.h icd2_debug_specific.h icd2_debug.h icd2_serial.h icd2_usb.h +SOURCES += microchip.cpp icd.cpp icd_prog.cpp icd2.cpp icd2_data.cpp \ + icd2_prog.cpp icd2_debug_specific.cpp icd2_debug.cpp icd2_serial.cpp icd2_usb.cpp icd2_usb_firmware.cpp diff --git a/src/progs/icd2/base/icd.cpp b/src/progs/icd2/base/icd.cpp new file mode 100644 index 0000000..bfb1129 --- /dev/null +++ b/src/progs/icd2/base/icd.cpp @@ -0,0 +1,94 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * Copyright (C) 2002-2003 Stephen Landamore * + * * + * 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. * + ***************************************************************************/ +#include "icd.h" + +#include "common/global/global.h" +#include "common/common/misc.h" +#include "common/port/port_base.h" + +//----------------------------------------------------------------------------- +bool Icd::DeviceSpecific::doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata) +{ + data.resize(device().nbWords(type)); + if ( vdata==0 ) return hardware().readMemory(type, 0, data, vdata); + bool only = ( vdata->actions & ::Programmer::OnlyProgrammedVerify ); + const Device::Array tmp = static_cast(vdata->memory).arrayForWriting(type); + uint wordOffset; + Device::Array pdata = prepareRange(type, tmp, !only, wordOffset); + return hardware().readMemory(type, wordOffset, pdata, vdata); +} + +Device::Array Icd::DeviceSpecific::prepareRange(Pic::MemoryRangeType type, const Device::Array &data, + bool force, uint &wordOffset) +{ + if ( type!=Pic::MemoryRangeType::Code ) { + wordOffset = 0; + return data; + } + wordOffset = (force ? 0 : findNonMaskStart(type, data)); + uint nbWords = 0; + if ( wordOffset!=data.count() ) { + uint end = (force ? data.count() : findNonMaskEnd(type, data)); + nbWords = end - wordOffset + 1; + log(Log::DebugLevel::Normal, QString(" start=%1 nbWords=%2 total=%3 force=%4") + .arg(toHexLabel(wordOffset, device().nbCharsAddress())).arg(toHexLabel(nbWords, device().nbCharsAddress())) + .arg(toHexLabel(data.count(), device().nbCharsAddress())).arg(force ? "true" : "false")); + } + _base.progressMonitor().addTaskProgress(data.count()-nbWords); + return data.mid(wordOffset, nbWords); +} + +bool Icd::DeviceSpecific::doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force) +{ + Q_ASSERT( data.count()==device().nbWords(type) ); + + uint nb = device().nbWordsWriteAlignment(Pic::MemoryRangeType::Code); + if ( device().architecture()==Pic::Architecture::P18J && type==Pic::MemoryRangeType::Config ) { + Q_ASSERT( data.count()%2==0 ); + int delta = nb - data.count()/2; // config memory words contains 1 byte + Q_ASSERT( delta>=0 ); + Device::Array rdata(delta); + uint wordOffset = device().nbWords(Pic::MemoryRangeType::Code) - delta; + if ( !hardware().readMemory(Pic::MemoryRangeType::Code, wordOffset, rdata, 0) ) return false; + Device::Array pdata(nb); + for (uint i=0; i=device().nbWords(Pic::MemoryRangeType::Code) ) { + Device::Array rdata(device().nbWords(Pic::MemoryRangeType::Config)); + if ( !hardware().readMemory(Pic::MemoryRangeType::Code, device().nbWords(Pic::MemoryRangeType::Code), rdata, 0) ) return false; + uint n = rdata.count() / 2; + for (uint i=0; i * + * Copyright (C) 2002-2003 Stephen Landamore * + * * + * 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. * + ***************************************************************************/ +#ifndef ICD_H +#define ICD_H + +#include "microchip.h" +#include "devices/pic/prog/pic_prog.h" +#include "devices/pic/pic/pic_memory.h" + +namespace Icd +{ +//----------------------------------------------------------------------------- +class Hardware : public ::Programmer::PicHardware +{ +public: + Hardware(::Programmer::Base &base, Port::Base *port) : ::Programmer::PicHardware(base, port, QString::null) {} +// initialization + virtual bool uploadFirmware(const Pic::Memory &memory) = 0; + virtual bool setTarget() = 0; + +// status + virtual bool getFirmwareVersion(VersionData &version) = 0; + virtual bool setTargetPowerOn(bool) { return true; } + +// programming + virtual bool readMemory(Pic::MemoryRangeType type, uint wordOffset, Device::Array &data, const ::Programmer::VerifyData *vdata) = 0; + virtual bool writeMemory(Pic::MemoryRangeType type, uint wordOffset, const Device::Array &data) = 0; + virtual bool eraseAll() = 0; + +// debugging + virtual bool readRegister(Address address, BitValue &value, uint nbBytes) = 0; + virtual bool writeRegister(Address address, BitValue value, uint nbBytes) = 0; + virtual bool resumeRun() = 0; + virtual bool step() = 0; + virtual bool haltRun() = 0; + virtual BitValue getProgramCounter() = 0; + +protected: + QString _rx; + virtual bool internalConnect(const QString &mode) = 0; + virtual QString receivedData() const = 0; + virtual bool internalConnectHardware() { return internalConnect("U"); } +}; + +//----------------------------------------------------------------------------- +class DeviceSpecific : public ::Programmer::PicDeviceSpecific +{ +public: + DeviceSpecific(::Programmer::Base &base) : ::Programmer::PicDeviceSpecific(base) {} + virtual bool canEraseAll() const { return true; } + virtual bool canEraseRange(Pic::MemoryRangeType) const { return false; } + virtual bool canReadRange(Pic::MemoryRangeType) const { return true; } + virtual bool canWriteRange(Pic::MemoryRangeType) const { return true; } + Hardware &hardware() { return static_cast(*_base.hardware()); } + virtual bool setPowerOff() { return false; } + virtual bool setPowerOn() { return false; } + virtual bool setTargetPowerOn(bool on) { return hardware().setTargetPowerOn(on); } + virtual bool doEraseRange(Pic::MemoryRangeType) { return false; } + virtual bool doErase(bool); + virtual bool doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata); + Device::Array prepareRange(Pic::MemoryRangeType type, const Device::Array &data, bool force, uint &wordOffset); + virtual bool doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force); +}; + +} // namespace + +#endif diff --git a/src/progs/icd2/base/icd2.cpp b/src/progs/icd2/base/icd2.cpp new file mode 100644 index 0000000..375fc60 --- /dev/null +++ b/src/progs/icd2/base/icd2.cpp @@ -0,0 +1,517 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * Copyright (C) 2002-2003 Stephen Landamore * + * * + * 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. * + ***************************************************************************/ +#include "icd2.h" + +#include "common/global/global.h" +#include "common/common/misc.h" +#include "common/port/port_base.h" +#include "icd2_data.h" +#include "icd2_usb.h" + +//----------------------------------------------------------------------------- +const uchar Icd2::TARGET_MODE_VALUES[Pic::Nb_TargetModes] = { + 0x00, // stopped + 0x01, // running + 0x02 // in programming +}; + +const char * const Icd2::RESET_MODE_VALUES[Pic::Nb_ResetModes] = { + "00", // reset held + "01" // reset released +}; + +//----------------------------------------------------------------------------- +const Icd2::Hardware::VoltageTypeData Icd2::Hardware::VOLTAGE_TYPE_DATA[Pic::Nb_VoltageTypes] = { + { "37", 0.07988 }, // icd Vpp + { "34", 0.03908 }, // target Vdd + { "35", 0.07988 }, // target Vpp +}; + +const char * const Icd2::Hardware::WRITE_MODE_VALUES[Pic::Nb_WriteModes] = { + "00", // write only + "01" // erase then write +}; + +const int Icd2::TestData::RESULT_TYPE_VALUES[::Programmer::Nb_ResultTypes+1] = { + 0x00, // pass + 0x01, // low + 0x80, // high + -2, // not used + -1 +}; + +const char * const Icd2::TestData::VOLTAGE_LABELS[Nb_VoltageTypes] = { + I18N_NOOP("Target Vdd"), I18N_NOOP("Module Vpp"), I18N_NOOP("MCLR ground"), + I18N_NOOP("MCLR Vdd"), I18N_NOOP("MCLR Vpp") +}; + +Icd2::TestData::TestData() +{ + for (uint k=0; ksend("$7F00\x0D", 6); + QString s; + if ( !_port->receive(2, s) ) return false; + if ( s!="02" ) { + log(Log::LineType::Error, i18n("Unexpected answer ($7F00) from ICD2 (%1).").arg(s)); + return false; + } + + // ?? + if ( !command("08", 2) ) return false; + if ( _rx.mid(5, 2)!="00" ) { + log(Log::LineType::Error, i18n("Unexpected answer (08) from ICD2 (%1).").arg(_rx)); + return false; + } + + return !hasError(); +} + +bool Icd2::Hardware::sendCommand(const QString &s) +{ + //format: + QString cs = s.upper(); + QString tx = "<"; + tx += toHex(cs.length() + 6, 2); + tx += cs; + uchar chk = tx[1].latin1() + tx[2].latin1(); + for (uint i=0; isend(a.data(), a.count()); +} + +bool Icd2::Hardware::receiveResponse(const QString &command, uint responseSize, bool poll) +{ + // format: [LLXX...CC] + uint size = responseSize + 8; + if ( poll && _port->type()==PortType::USB ) { + if ( !static_cast(_port)->poll(size, _rx) ) return false; + } else if ( !_port->receive(size, _rx, 180000) ) return false; // is 3 minutes enough ?? (we should really have an abort button here...) + log(Log::DebugLevel::Extra, QString("received answer: '%1'").arg(_rx)); + if ( size!=fromHex(_rx.mid(1, 2), 0) ) { + log(Log::LineType::Error, i18n("Received length too short.")); + return false; + } + if ( uint(_rx.length())!=size ) { + log(Log::LineType::Error, i18n("Received string too short.")); + return false; + } + if ( _rx[0]!='[' || _rx[size-1]!=']' ) { + log(Log::LineType::Error, i18n("Malformed string received \"%1\"").arg(_rx)); + return false; + } + if ( command.mid(0, 2)!=_rx.mid(3, 2) ) { + log(Log::LineType::Error, i18n("Wrong return value (\"%1\"; was expecting \"%2\")") + .arg(_rx.mid(3, 2)).arg(command.mid(0, 2))); + return false; + } + // verify the checksum + uchar chk = 0; + for (uint i=1; itype()==PortType::Serial ? 2*nbBytesWord : 0x100); + uint size = QMIN(maxSize, length-i); + QString tmp; + if ( _port->type()==PortType::USB ) { + if ( !static_cast(_port)->dataReceive(size, tmp) ) return false; + } else if ( !_port->receive(size, tmp) ) return false; + s += tmp; + i += size; + } + + // treat data + if ( s[0]!='{' || s[s.length()-1]!='}' ) { + log(Log::LineType::Error, i18n("Invalid begin or end character for read block.")); + return false; + } + log(Log::DebugLevel::Max, "received: " + s); + data.resize(nbWords); + Q_UINT8 chk = 0; + for (uint i=0; i=0; k--) { + data[i] = data[i] << 8; + data[i] |= fromHex(ts.mid(2*k, 2), 0); + chk += ts[2*k].latin1() + ts[2*k+1].latin1(); + } + } + + QString cs = s.mid(s.length()-3, 2); + if ( chk!=fromHex(cs, 0) ) { + log(Log::LineType::Error, i18n("Bad checksum for read block: %1 (%2 expected).").arg(cs).arg(toHex(chk, 2))); + return false; + } + return true; +} + +bool Icd2::Hardware::readMemory(Pic::MemoryRangeType type, uint wordOffset, + Device::Array &data, const ::Programmer::VerifyData *vdata) +{ + const char *r = readCommand(type); + if ( r==0 ) return false; + uint nbBytesWord = device().nbBytesWord(type); + uint div = 2; + if ( type==Pic::MemoryRangeType::Eeprom || nbBytesWord>=2 ) div = 1; + uint inc = device().addressIncrement(type); + Address start = device().range(type).start; // address + uint todo = inc * data.count(); // address + uint offset = inc * wordOffset; // address + //qDebug("read size=%s div=%i nbBytes=%i", toHex(size, 8).data(), div, nbBytesWord); + data.resize(0); + do { + uint size = QMIN(todo, uint(0x1000)); // addresses + uint nb = size / inc; // word + //qDebug("read %s start=%s size=%s", Pic::MEMORY_RANGE_TYPE_DATA[type].label, toHex(start+offset, 8).data(), toHex(nb, 8).data()); + QString cmd = r + toHex(start+offset, 8) + toHex(nb/div, 8); + if ( !command(cmd, 0) ) return false; + Device::Array pdata; + if ( !readBlock(nbBytesWord, nb, pdata) ) return false; + if ( !receiveResponse(cmd, 0, false) ) return false; + if (vdata) { + for (uint i=0; i=0; k--) { + //if ( i<10 || i>=nbWords-10 ) qDebug("send: %i-%i %s", i, k, ts.mid(2*k, 2).data()); + s += ts.mid(2*k, 2); + chk += ts[2*k].latin1() + ts[2*k+1].latin1(); + } + } + s += toHex(chk, 2); + s += "}"; + log(Log::DebugLevel::Max, "send: " + s); + + // send data + uint i = 0; + while ( idescription().type==PortType::Serial ? 2*nbBytesWord : 0x100); + if ( _port->description().type==PortType::Serial && i==0 ) maxSize = 1; + uint size = QMIN(maxSize, s.length()-i); + QByteArray a = toAscii(s); + if ( _port->type()==PortType::USB ) { + if ( !static_cast(_port)->dataSend(a.data()+i, size) ) return false; + } else if ( !_port->send(a.data()+i, size) ) return false; + i += size; + } + + //qDebug("done sending %i words (chk=%s)", nbWords, toHex(chk, 2).data()); + return true; +} + +bool Icd2::Hardware::writeMemory(Pic::MemoryRangeType type, uint wordOffset, const Device::Array &data) +{ + //qDebug("write memory: offset:%s nbWords:%s (size: %s)", toHex(wordOffset, 4).data(), toHex(nbWords, 4).data(), toHex(data.size(), 4).data()); + const char *w = writeCommand(type); + if ( w==0 ) return true; + uint nbBytesWord = device().nbBytesWord(type); + uint div = 2; + if ( type==Pic::MemoryRangeType::Eeprom || nbBytesWord>=2 ) div = 1; + uint inc = device().addressIncrement(type); + Address start = device().range(type).start; // address + uint todo = inc * data.count(); // address + uint offset = inc * wordOffset; // address + uint index = 0; + //qDebug("write todo=%s div=%i nbBytes=%i dataSize=%i", toHex(todo, 8).data(), div, nbBytesWord, data.size()); + do { + uint size = QMIN(todo, uint(0x1000)); // address + uint nb = size / inc; // word + //qDebug("write %s start=%s nbWords=%s", Pic::MEMORY_RANGE_TYPE_DATA[type].label, toHex(start+offset, 8).data(), toHex(nb, 8).data()); + QString cmd = w + toHex(start+offset+index, 8) + toHex(nb/div, 8); + if ( !command(cmd, 0) ) return false; + if ( !writeBlock(nbBytesWord, data, index/inc, nb) ) return false; + if ( !receiveResponse(cmd, 0, false) ) return false; + index += size; + todo -= size; + if ( type==Pic::MemoryRangeType::Code || type==Pic::MemoryRangeType::Eeprom ) + _base.progressMonitor().addTaskProgress(nb); + } while ( todo!=0 ); + return true; +} + +bool Icd2::Hardware::eraseAll() +{ + setTargetReset(Pic::ResetHeld); + if ( hasError() ) return false; + if ( !sendCommand("29") ) return false; + if ( !receiveResponse("29", 0, true) ) return false; // poll + return true; +} + +bool Icd2::Hardware::haltRun() +{ + return command("2E", 0); +} + +bool Icd2::Hardware::step() +{ + return command("2F", 0); +} + +bool Icd2::Hardware::resumeRun() +{ + return command("30", 0); +} + +bool Icd2::Hardware::setWriteMode(Pic::WriteMode mode) +{ + return command(QString("4B") + WRITE_MODE_VALUES[mode], 0); +} + +bool Icd2::Hardware::writeRegister(Address address, BitValue value, uint nbBytes) +{ + QString cmd = "1B" + toHex(address, 8) + toHex(nbBytes, 8); + if ( !command(cmd, 0) ) return false; + Device::Array data(nbBytes); + for (uint i=0; i * + * Copyright (C) 2002-2003 Stephen Landamore * + * * + * 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. * + ***************************************************************************/ +#ifndef ICD2_H +#define ICD2_H + +#include "icd.h" + +namespace Icd2 +{ +//----------------------------------------------------------------------------- + extern const uchar TARGET_MODE_VALUES[Pic::Nb_TargetModes]; + extern const char * const RESET_MODE_VALUES[Pic::Nb_ResetModes]; + + class TestData { + public: + TestData(); + TestData(const QString &rx); + enum VoltageType { TargetVdd = 0, ModuleVpp, MclrGround, MclrVdd, MclrVpp, + Nb_VoltageTypes }; + bool pass() const; + QString result(VoltageType type) const; + QString pretty(VoltageType type) const; + static const char * const VOLTAGE_LABELS[Nb_VoltageTypes]; + + private: + int _voltages[Nb_VoltageTypes]; + static const int RESULT_TYPE_VALUES[::Programmer::Nb_ResultTypes+1]; + }; + +//----------------------------------------------------------------------------- +class Hardware : public Icd::Hardware +{ +public: + Hardware(::Programmer::Base &base, Port::Base *port) : Icd::Hardware(base, port) {} + bool command(const QString &command, uint responseSize); + +// initialization + virtual bool uploadFirmware(const Pic::Memory &memory); + virtual bool setTarget(); + bool setup(); + +// status + virtual bool getFirmwareVersion(VersionData &version); + uint getFirmwareId(); + bool getDebugExecVersion(VersionData &version); + virtual bool setTargetPowerOn(bool on); + virtual bool readVoltage(Pic::VoltageType type, double &value); + virtual bool readVoltages(VoltagesData &voltages); + virtual bool getTargetMode(Pic::TargetMode &mode); + virtual bool setTargetReset(Pic::ResetMode mode); + bool selfTest(TestData &test); + +// programming + virtual bool readMemory(Pic::MemoryRangeType type, uint wordOffset, Device::Array &data, const ::Programmer::VerifyData *vdata); + virtual bool writeMemory(Pic::MemoryRangeType type, uint wordOffset, const Device::Array &data); + virtual bool eraseAll(); + bool setWriteMode(Pic::WriteMode mode); + +// debugging + virtual bool readRegister(Address address, BitValue &value, uint nbBytes); + virtual bool writeRegister(Address address, BitValue value, uint nbBytes); + virtual bool resumeRun(); + virtual bool step(); + virtual bool haltRun(); + virtual BitValue getProgramCounter(); + +protected: + virtual QString receivedData() const { return _rx.mid(5, _rx.length()-8); } + +private: + struct VoltageTypeData { + const char *command; + double factor; + }; + static const VoltageTypeData VOLTAGE_TYPE_DATA[Pic::Nb_VoltageTypes]; + static const char * const WRITE_MODE_VALUES[Pic::Nb_WriteModes]; + + bool sendCommand(const QString &command); + bool receiveResponse(const QString &command, uint responseSize, bool poll); + bool readBlock(uint nbBytesWord, uint nbWords, Device::Array &data); + bool writeBlock(uint nbBytesWord, const Device::Array &data, uint wordOffset, uint nbWords); + const char *readCommand(Pic::MemoryRangeType type) const; + const char *writeCommand(Pic::MemoryRangeType type) const; +}; + +} // namespace + +#endif diff --git a/src/progs/icd2/base/icd2.xml b/src/progs/icd2/base/icd2.xml new file mode 100644 index 0000000..3c714b2 --- /dev/null +++ b/src/progs/icd2/base/icd2.xml @@ -0,0 +1,214 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/progs/icd2/base/icd2_data.h b/src/progs/icd2/base/icd2_data.h new file mode 100644 index 0000000..ceda394 --- /dev/null +++ b/src/progs/icd2/base/icd2_data.h @@ -0,0 +1,42 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef ICD2_DATA_H +#define ICD2_DATA_H + +#include "common/common/group.h" + +namespace Icd2 +{ + struct Version { + uchar major, minor, dot; + }; + enum { Nb_Firmwares = 15 }; + struct FirmwareVersionData { + uchar mplabMajor, mplabMinor; + Version version[Nb_Firmwares]; + }; + extern const FirmwareVersionData MIN_VERSION_DATA; + extern const FirmwareVersionData MAX_VERSION_DATA; + struct FamilyData { + const char *name; + uchar efid; + const char *debugExec; + uint debugExecOffset; // in the hex file + uint wreg, fsr, status; + }; + extern const FamilyData FAMILY_DATA[]; + struct Data { + uint famid; + ::Group::Support debugSupport; + }; + extern const Data &data(const QString &device); + extern uint family(const QString &device); +} // namespace + +#endif diff --git a/src/progs/icd2/base/icd2_debug.cpp b/src/progs/icd2/base/icd2_debug.cpp new file mode 100644 index 0000000..62f6404 --- /dev/null +++ b/src/progs/icd2/base/icd2_debug.cpp @@ -0,0 +1,348 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "icd2_debug.h" + +#include "common/global/pfile.h" +#include "progs/base/prog_config.h" +#include "devices/pic/base/pic_register.h" +#include "devices/pic/pic/pic_group.h" +#include "icd2_data.h" +#include "icd2_debug_specific.h" + +//----------------------------------------------------------------------------- +Icd2::DebuggerSpecific *Icd2::Debugger::specific() { return static_cast(_specific); } + +bool Icd2::Debugger::waitForTargetMode(Pic::TargetMode mode) +{ + Pic::TargetMode rmode; + for (uint i=0; i<20; i++) { + if ( !programmer().getTargetMode(rmode) ) return false; + if ( rmode==mode ) return true; + Port::msleep(200); + } + log(Log::LineType::Error, QString("Timeout waiting for mode: %1 (target is in mode: %2).") + .arg(i18n(Pic::TARGET_MODE_LABELS[mode])).arg(i18n(Pic::TARGET_MODE_LABELS[rmode]))); + return false; +} + +bool Icd2::Debugger::init(bool last) +{ + _initLast = last; + return ::Debugger::PicBase::init(); +} + +bool Icd2::Debugger::internalInit() +{ + return specific()->init(_initLast); +} + +bool Icd2::Debugger::updateState() +{ + Pic::TargetMode mode; + if ( !programmer().getTargetMode(mode) ) return false; + switch (mode) { + case Pic::TargetStopped: _programmer.setState(::Programmer::Halted); break; + case Pic::TargetRunning: _programmer.setState(::Programmer::Running); break; + case Pic::TargetInProgramming: _programmer.setState(::Programmer::Stopped); break; + case Pic::Nb_TargetModes: Q_ASSERT(false); break; + } + return true; +} + +bool Icd2::Debugger::setBreakpoints(const QValueList

&addresses) +{ + if ( addresses.count()==0 ) return specific()->setBreakpoint(Address()); + for (uint i=0; inbCharsAddress()))); + if ( !specific()->setBreakpoint(addresses[i]) ) return false; + } + return true; +} + +bool Icd2::Debugger::internalRun() +{ + return hardware()->resumeRun(); +} + +bool Icd2::Debugger::hardHalt() +{ + log(Log::LineType::Warning, i18n("Failed to halt target: try a reset.")); + return reset(); +} + +bool Icd2::Debugger::softHalt(bool &success) +{ + if ( !hardware()->haltRun() ) return false; + success = waitForTargetMode(Pic::TargetStopped); + return true; +} + +bool Icd2::Debugger::internalReset() +{ + return specific()->reset(); +} + +bool Icd2::Debugger::internalStep() +{ + return hardware()->step(); +} + +bool Icd2::Debugger::readRegister(const Register::TypeData &data, BitValue &value) +{ + if ( data.type()==Register::Special ) { + if ( data.name()=="WREG" ) return hardware()->readRegister(specific()->addressWREG(), value, 1); + if ( data.name()=="PC" ) { value = hardware()->getProgramCounter().maskWith(specific()->maskPC()); return !hasError(); } + Q_ASSERT(false); + return true; + } + QString name = device()->registersData().sfrNames[data.address()]; + if ( name=="WREG" ) return hardware()->readRegister(specific()->addressWREG(), value, 1); + if ( name=="PCL" ) { value = hardware()->getProgramCounter().maskWith(specific()->maskPC()).byte(0); return !hasError(); } + if ( name=="PCLATH" ) { value = hardware()->getProgramCounter().maskWith(specific()->maskPC()).byte(1); return !hasError(); } + return hardware()->readRegister(specific()->addressRegister(data.address()), value, 1); +} + +bool Icd2::Debugger::writeRegister(const Register::TypeData &data, BitValue value) +{ + if ( data.type()==Register::Special ) { + if ( data.name()=="WREG" ) return hardware()->writeRegister(specific()->addressWREG(), value, 1); + Q_ASSERT(false); + return true; + } + QString name = device()->registersData().sfrNames[data.address()]; + if ( name=="WREG" ) return hardware()->writeRegister(specific()->addressWREG(), value, 1); + return hardware()->writeRegister(specific()->addressRegister(data.address()), value, 1); +} + +//----------------------------------------------------------------------------- +Icd2::DebugProgrammer::DebugProgrammer(const ::Programmer::Group &group, const Pic::Data *data) + : Icd2::ProgrammerBase(group, data, "icd2_programmer") +{} + +void Icd2::DebugProgrammer::clear() +{ + Icd2::ProgrammerBase::clear(); + _debugExecutiveVersion.clear(); +} + +bool Icd2::DebugProgrammer::internalSetupHardware() +{ + if ( _specific==0 ) return true; + const FamilyData &fdata = FAMILY_DATA[family(device()->name())]; + + // find debug executive file + PURL::Directory dir(::Programmer::GroupConfig::firmwareDirectory(group())); + if ( !dir.exists() ) { + log(Log::LineType::Error, i18n("Firmware directory not configured.")); + return false; + } + uint reservedBank = 0; + QString filename; + if ( device()->is18Family() ) { + Debugger *debug = static_cast(debugger()); + reservedBank = static_cast(debug->specific())->reservedBank(); + filename = QString("de18F_BANK%1.hex").arg(QString(toString(NumberBase::Dec, reservedBank, 2))); + } else filename = QString("de%1.hex").arg(fdata.debugExec); + PURL::Url url = dir.findMatchingFilename(filename); + log(Log::DebugLevel::Normal, QString(" Debug executive file: %1").arg(url.pretty())); + if ( !url.exists() ) { + log(Log::LineType::Error, i18n("Could not find debug executive file \"%1\".").arg(url.pretty())); + return false; + } + // upload hex file + Log::StringView sview; + PURL::File file(url, sview); + if ( !file.openForRead() ) { + log(Log::LineType::Error, i18n("Could not open firmware file \"%1\".").arg(url.pretty())); + return false; + } + QStringList errors; + HexBuffer hbuffer; + if ( !hbuffer.load(file.stream(), errors) ) { + log(Log::LineType::Error, i18n("Could not read debug executive file \"%1\": %2.").arg(url.pretty()).arg(errors[0])); + return false; + } + uint nbWords = device()->nbWords(Pic::MemoryRangeType::Code); + uint offset = nbWords - 0x100; + if ( fdata.debugExecOffset!=0 && fdata.debugExecOffset!=offset ) + for (uint i=0; i<0x100; i++) hbuffer.insert(offset+i, hbuffer[fdata.debugExecOffset+i]); + Pic::Memory::WarningTypes warningTypes; + QStringList warnings; + QMap inRange; + Pic::Memory memory(*device()); + memory.fromHexBuffer(Pic::MemoryRangeType::Code, hbuffer, warningTypes, warnings, inRange); + _deArray = memory.arrayForWriting(Pic::MemoryRangeType::Code); + if ( device()->is18Family() ) { + // that's a bit ugly but it cannot be guessed for 18F2455 family... + uint size; + switch (reservedBank) { + case 0: size = 0x0E0; break; + case 12: + case 14: size = 0x140; break; + default: size = 0x120; break; + } + _deStart = nbWords - size; + _deEnd = nbWords - 1; + for (uint i=0; ifindNonMaskStart(Pic::MemoryRangeType::Code, _deArray); + _deEnd = specific()->findNonMaskEnd(Pic::MemoryRangeType::Code, _deArray); + } + log(Log::DebugLevel::Extra, QString("debug executive: \"%1\" %2:%3").arg(url.pretty()).arg(toHexLabel(_deStart, 4)).arg(toHexLabel(_deEnd, 4))); + return Icd2::ProgrammerBase::internalSetupHardware(); +} + +Pic::Memory Icd2::DebugProgrammer::toDebugMemory(const Pic::Memory &mem, bool withDebugExecutive) +{ + Pic::Memory memory = mem; + memory.setDebugOn(true); + if ( memory.hasWatchdogTimerOn() ) { + log(Log::LineType::Warning, i18n("Disabling watchdog timer for debugging")); + memory.setWatchdogTimerOn(false); + } + if ( memory.isProtected(Pic::Protection::ProgramProtected, Pic::MemoryRangeType::Code) ) { + log(Log::LineType::Warning, i18n("Disabling code program protection for debugging")); + memory.setProtection(false, Pic::Protection::ProgramProtected, Pic::MemoryRangeType::Code); + } + if ( memory.isProtected(Pic::Protection::WriteProtected, Pic::MemoryRangeType::Code) ) { + log(Log::LineType::Warning, i18n("Disabling code write protection for debugging")); + memory.setProtection(false, Pic::Protection::WriteProtected, Pic::MemoryRangeType::Code); + } + if ( memory.isProtected(Pic::Protection::ReadProtected, Pic::MemoryRangeType::Code) ) { + log(Log::LineType::Warning, i18n("Disabling code read protection for debugging")); + memory.setProtection(false, Pic::Protection::ReadProtected, Pic::MemoryRangeType::Code); + } + uint address = _deStart * device()->addressIncrement(Pic::MemoryRangeType::Code); + Device::Array data = device()->gotoInstruction(address, false); + for (uint i=0; iis18Family() ) + memory.setWord(Pic::MemoryRangeType::DebugVector, data.count(), 0xFF00); // ?? + if (withDebugExecutive) { + bool ok = true; + for (uint i=_deStart; i<=_deEnd; i++) { + if ( memory.word(Pic::MemoryRangeType::Code, i).isInitialized() ) ok = false; + memory.setWord(Pic::MemoryRangeType::Code, i, _deArray[i]); + } + if ( !ok ) log(Log::LineType::Warning, i18n("Memory area for debug executive was not empty. Overwrite it and continue anyway...")); + } + return memory; +} + +bool Icd2::DebugProgrammer::writeDebugExecutive() +{ + log(Log::LineType::Information, i18n(" Write debug executive")); + Device::Array data = _deArray.mid(_deStart, _deEnd - _deStart + 1); + if ( !hardware()->writeMemory(Pic::MemoryRangeType::Code, _deStart, data) ) return false; + log(Log::LineType::Information, i18n(" Verify debug executive")); + if ( !hardware()->readMemory(Pic::MemoryRangeType::Code, _deStart, data, 0) ) return false; + for (uint i=0; iaddressIncrement(Pic::MemoryRangeType::Code); + Address address = device()->range(Pic::MemoryRangeType::Code).start + inc * (_deStart + i); + log(Log::LineType::Error, i18n("Device memory doesn't match debug executive (at address %1: reading %2 and expecting %3).") + .arg(toHexLabel(address, device()->nbCharsAddress())) + .arg(toHexLabel(data[i], device()->nbCharsWord(Pic::MemoryRangeType::Code))) + .arg(toHexLabel(_deArray[_deStart+i], device()->nbCharsWord(Pic::MemoryRangeType::Code)))); + return false; + } + return true; +} + +bool Icd2::DebugProgrammer::doProgram(const Device::Memory &memory, const Device::MemoryRange &range) +{ + if ( !checkProgram(memory) ) return false; + if ( !doConnectDevice() ) return false; + _progressMonitor.startNextTask(); + // probably needed for all devices that don't have a "erase and write" mode + if ( range.all() && FAMILY_DATA[family(device()->name())].debugExec==QString("16F7X7") ) { + Pic::Memory dmemory(*device()); + dmemory.setWord(Pic::MemoryRangeType::Code, 0, 0x0028); + dmemory.setWord(Pic::MemoryRangeType::Code, 1, 0x0030); + log(Log::LineType::Information, i18n("Programming device for debugging test...")); + if ( !internalProgram(dmemory, range) ) return false; + if ( !static_cast(_debugger)->init(false) ) return false; + log(Log::LineType::Information, i18n("Debugging test successful")); + } + log(Log::LineType::Information, i18n("Programming device memory...")); + if ( !internalProgram(memory, range) ) return false; + log(Log::LineType::Information, i18n("Programming successful")); + return static_cast(_debugger)->init(true); +} + +bool Icd2::DebugProgrammer::programAll(const Pic::Memory &mem) +{ + Pic::Memory memory = toDebugMemory(mem, false); + if ( !programAndVerifyRange(Pic::MemoryRangeType::Code, memory) ) return false; + if ( !writeDebugExecutive() ) return false; + if ( !programAndVerifyRange(Pic::MemoryRangeType::DebugVector, memory) ) return false; + if ( !programAndVerifyRange(Pic::MemoryRangeType::Eeprom, memory) ) return false; + if ( !programAndVerifyRange(Pic::MemoryRangeType::UserId, memory) ) return false; + if ( device()->is18Family() ) { + if ( !hardware()->command("0C00", 0) ) return false; // #### ?? + QString com = "42" + toHex(0xFB5, 8) + toHex(1, 8); // write RSBUG (?) + if ( !hardware()->command(com, 0) ) return false; + if ( !hardware()->command("0C01", 0) ) return false; // #### ?? + } + if ( !programAndVerifyRange(Pic::MemoryRangeType::Config, memory) ) return false; + return true; +} + +bool Icd2::DebugProgrammer::internalRead(Device::Memory *mem, const Device::MemoryRange &range, const ::Programmer::VerifyData *vd) +{ + if ( vd==0 || (vd->actions & ::Programmer::BlankCheckVerify) ) return Icd2::ProgrammerBase::internalRead(mem, range, vd); + Pic::Memory memory = toDebugMemory(static_cast(vd->memory), true); + ::Programmer::VerifyData vdata(vd->actions, memory); + if ( !Icd2::ProgrammerBase::internalRead(0, range, &vdata) ) return false; + if ( range.all() && !readRange(Pic::MemoryRangeType::DebugVector, 0, &vdata) ) return false; + return true; +} + +bool Icd2::DebugProgrammer::readDebugExecutiveVersion() +{ + if ( !hardware()->getDebugExecVersion(_debugExecutiveVersion) ) return false; + log(Log::LineType::Information, i18n(" Debug executive version: %1").arg(_debugExecutiveVersion.pretty())); + return true; +} + +//---------------------------------------------------------------------------- +void Icd2::DebuggerGroup::addDevice(const QString &name, const Device::Data *ddata, ::Group::Support) +{ + if ( FAMILY_DATA[family(name)].debugExec==0 ) return; + Group::addDevice(name, ddata, data(name).debugSupport); +} + +::Debugger::Specific *Icd2::DebuggerGroup::createDebuggerSpecific(::Debugger::Base &base) const +{ + const Pic::Data *data = static_cast< ::Debugger::PicBase &>(base).device(); + if ( data==0 ) return 0; + QString debugExec = FAMILY_DATA[family(data->name())].debugExec; + switch (data->architecture().type()) { + case Pic::Architecture::P16X: + if ( debugExec=="16F872" ) return new P16F872DebuggerSpecific(base); + if ( debugExec=="16F7X7" ) return new P16F7X7DebuggerSpecific(base); + return new P16F87XDebuggerSpecific(base); + case Pic::Architecture::P17C: + case Pic::Architecture::P18C: + case Pic::Architecture::P18F: + case Pic::Architecture::P18J: return new P18FDebuggerSpecific(base); + case Pic::Architecture::P10X: + case Pic::Architecture::P24F: + case Pic::Architecture::P24H: + case Pic::Architecture::P30F: + case Pic::Architecture::P33F: + case Pic::Architecture::Nb_Types: break; + } + Q_ASSERT(false); + return 0; +} diff --git a/src/progs/icd2/base/icd2_debug.h b/src/progs/icd2/base/icd2_debug.h new file mode 100644 index 0000000..bd2a6fe --- /dev/null +++ b/src/progs/icd2/base/icd2_debug.h @@ -0,0 +1,89 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef ICD2_DEBUG_H +#define ICD2_DEBUG_H + +#include "icd2_prog.h" +#include "devices/pic/prog/pic_debug.h" + +namespace Icd2 +{ +class DebuggerSpecific; + +//----------------------------------------------------------------------------- +class DebugProgrammer : public ProgrammerBase +{ +Q_OBJECT +public: + DebugProgrammer(const ::Programmer::Group &group, const Pic::Data *data); + bool readDebugExecutiveVersion(); + const VersionData &debugExecutiveVersion() const { return _debugExecutiveVersion; } + +private: + VersionData _debugExecutiveVersion; + Device::Array _deArray; + uint _deStart, _deEnd; + + virtual void clear(); + virtual bool internalSetupHardware(); + virtual bool doProgram(const Device::Memory &memory, const Device::MemoryRange &range); + virtual bool programAll(const Pic::Memory &memory); + virtual bool internalRead(Device::Memory *memory, const Device::MemoryRange &range, const ::Programmer::VerifyData *vdata); + + bool getDebugExecutive(); + bool writeDebugExecutive(); + Pic::Memory toDebugMemory(const Pic::Memory &memory, bool withDebugExecutive); +}; + +//----------------------------------------------------------------------------- +class Debugger : public ::Debugger::PicBase +{ +public: + Debugger(DebugProgrammer &programmer) : ::Debugger::PicBase(programmer) {} + virtual bool setBreakpoints(const QValueList
&addresses); + Hardware *hardware() { return static_cast(_programmer.hardware()); } + DebugProgrammer &programmer() { return static_cast(_programmer); } + DebuggerSpecific *specific(); + bool waitForTargetMode(Pic::TargetMode mode); + virtual bool readRegister(const Register::TypeData &data, BitValue &value); + virtual bool writeRegister(const Register::TypeData &data, BitValue value); + bool init(bool last); + +protected: + virtual bool internalInit(); + virtual bool internalRun(); + virtual bool internalStep(); + virtual bool softHalt(bool &success); + virtual bool hardHalt(); + virtual bool internalReset(); + virtual bool updateState(); + +private: + bool _initLast; +}; + +//----------------------------------------------------------------------------- +class DebuggerGroup : public Group +{ +public: + virtual QString name() const { return "icd2_debugger"; } + virtual QString label() const { return i18n("ICD2 Debugger"); } + virtual ::Programmer::Properties properties() const { return Group::properties() | ::Programmer::Debugger; } + virtual uint maxNbBreakpoints(const Device::Data *) const { return 1; } + +protected: + virtual void addDevice(const QString &name, const Device::Data *data, ::Group::Support support); + virtual ::Programmer::Base *createBase(const Device::Data *data) const { return new DebugProgrammer(*this, static_cast(data)); } + virtual ::Debugger::Base *createDebuggerBase(::Programmer::Base &base) const { return new Debugger(static_cast(base)); } + virtual ::Debugger::Specific *createDebuggerSpecific(::Debugger::Base &base) const; +}; + +} // namespace + +#endif diff --git a/src/progs/icd2/base/icd2_debug_specific.cpp b/src/progs/icd2/base/icd2_debug_specific.cpp new file mode 100644 index 0000000..56cc178 --- /dev/null +++ b/src/progs/icd2/base/icd2_debug_specific.cpp @@ -0,0 +1,255 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "icd2_debug_specific.h" + +#include "devices/pic/base/pic_register.h" +#include "icd2_data.h" + +//---------------------------------------------------------------------------- +Address Icd2::P16FDebuggerSpecific::addressWREG() const +{ + return FAMILY_DATA[family(device()->name())].wreg; +} + +Address Icd2::P16FDebuggerSpecific::addressRegister(Address address) const +{ + QString name = device()->registersData().sfrNames[address]; + if ( name=="FSR" ) return FAMILY_DATA[family(device()->name())].fsr; + if ( name=="STATUS" ) return FAMILY_DATA[family(device()->name())].status; + return address; +} + +bool Icd2::P16FDebuggerSpecific::reset() +{ + if ( !hardware()->setTargetReset(Pic::ResetHeld) ) return false; + return init(true); +} + +bool Icd2::P16FDebuggerSpecific::setBreakpoint(Address address) +{ + if ( !address.isValid() ) address = 0x1FFF; // outside memory range + BitValue value = address.toUInt() | 0x8000; // read-only INBUG bit + return hardware()->writeRegister(0x18E, value, 2); +} + +bool Icd2::P16FDebuggerSpecific::readBreakpoint(BitValue &value) +{ + if ( !hardware()->readRegister(0x18E, value, 2) ) return false; + value = value.maskWith(0x1FFF); + return true; +} + +bool Icd2::P16FDebuggerSpecific::beginInit(Device::Array *saved) +{ + if ( !hardware()->setTargetReset(Pic::ResetHeld) ) return false; + double vdd; + if ( !hardware()->readVoltage(Pic::TargetVdd, vdd) ) return false; + log(Log::DebugLevel::Normal, QString(" Target Vdd: %1 V").arg(vdd)); + + if (saved) { + saved->resize(1); + if ( !hardware()->readMemory(Pic::MemoryRangeType::Code, 0, *saved, 0) ) return false; // save first instruction + if ( (*saved)[0]!=device()->nopInstruction() ) log(Log::LineType::Warning, i18n(" According to ICD2 manual, instruction at address 0x0 should be \"nop\".")); + } + + return true; +} + +bool Icd2::P16FDebuggerSpecific::endInit(BitValue expectedPC) +{ + if ( !hardware()->setTargetReset(Pic::ResetReleased) ) return false; + if ( !base().waitForTargetMode(Pic::TargetStopped) ) return false; + BitValue value; + if ( !readBreakpoint(value) ) return false; + if ( value==expectedPC+1 ) { + // #### happen for some custom icd2 or sometimes when we had to force a halt (?) + expectedPC = expectedPC+1; + //log(Log::LineType::Information, i18n("Detected custom ICD2")); + } + if ( value!=expectedPC ) { + log(Log::LineType::Error, i18n(" PC is not at address %1 (%2)").arg(toHexLabel(expectedPC, 4)).arg(toHexLabel(value, 4))); + return false; + } + if ( !setBreakpoint(0x0000) ) return false; + + if ( !base().update() ) return false; + if ( base().pc()!=expectedPC ) { + log(Log::LineType::Error, i18n(" PC is not at address %1 (%2)").arg(toHexLabel(expectedPC, 4)).arg(toHexLabel(base().pc(), 4))); + return false; + } + return true; +} + +bool Icd2::P16F872DebuggerSpecific::init(bool) +{ + Device::Array saved; + if ( !beginInit(&saved) ) return false; + + // this seems to be needed + if ( !hardware()->setTargetReset(Pic::ResetReleased) ) return false; + Pic::TargetMode mode; + if ( !programmer().getTargetMode(mode) ) return false; + + if ( !hardware()->setTargetReset(Pic::ResetHeld) ) return false; + if ( !hardware()->setWriteMode(Pic::EraseWriteMode) ) return false; + log(Log::DebugLevel::Normal, " Write \"goto 0x0\" at reset vector and run target."); + Device::Array data = device()->gotoInstruction(0x0000, false); // loop at reset vector + if ( !hardware()->writeMemory(Pic::MemoryRangeType::Code, 0, data) ) return false; + if ( !hardware()->setTargetReset(Pic::ResetReleased) ) return false; // run device + if ( !base().waitForTargetMode(Pic::TargetRunning) ) return false; + log(Log::DebugLevel::Normal, " Try to halt target."); + if ( !hardware()->haltRun() ) return false; + if ( !base().waitForTargetMode(Pic::TargetStopped) ) return false; + if ( !programmer().readDebugExecutiveVersion() ) return false; + log(Log::DebugLevel::Normal, " Set breakpoint at reset vector."); + if ( !setBreakpoint(0x0000) ) return false; + if ( !hardware()->setTargetReset(Pic::ResetHeld) ) return false; + if ( !base().waitForTargetMode(Pic::TargetInProgramming) ) return false; + log(Log::DebugLevel::Normal, " Restore instruction at reset vector and run target."); + if ( !hardware()->writeMemory(Pic::MemoryRangeType::Code, 0, saved) ) return false; // restore instruction + if ( !hardware()->setWriteMode(Pic::WriteOnlyMode) ) return false; + + return endInit(0x0001); +} + +bool Icd2::P16F87XDebuggerSpecific::init(bool) +{ + Device::Array saved; + if ( !beginInit(&saved) ) return false; + + if ( !hardware()->setTargetReset(Pic::ResetHeld) ) return false; + if ( !hardware()->setWriteMode(Pic::EraseWriteMode) ) return false; + log(Log::DebugLevel::Normal, " Write \"goto 0x0\" at reset vector and run target."); + Device::Array data = device()->gotoInstruction(0x0000, false); // loop at reset vector + if ( !hardware()->writeMemory(Pic::MemoryRangeType::Code, 0, data) ) return false; + if ( !hardware()->setTargetReset(Pic::ResetReleased) ) return false; // run device + Pic::TargetMode mode; + if ( !programmer().getTargetMode(mode) ) return false; + if ( mode==Pic::TargetRunning && !hardware()->haltRun() ) return false; + if ( !base().waitForTargetMode(Pic::TargetStopped) ) return false; + if ( !programmer().readDebugExecutiveVersion() ) return false; + log(Log::DebugLevel::Normal, " Set breakpoint at reset vector."); + if ( !setBreakpoint(0x0000) ) return false; + if ( !hardware()->setTargetReset(Pic::ResetHeld) ) return false; + if ( !base().waitForTargetMode(Pic::TargetInProgramming) ) return false; + log(Log::DebugLevel::Normal, " Restore instruction at reset vector and run target."); + if ( !hardware()->writeMemory(Pic::MemoryRangeType::Code, 0, saved) ) return false; // restore instruction + if ( !hardware()->setWriteMode(Pic::WriteOnlyMode) ) return false; + + return endInit(0x0001); +} + +bool Icd2::P16F7X7DebuggerSpecific::init(bool last) +{ + Device::Array saved; + if ( !beginInit(last ? &saved : 0) ) return false; + + log(Log::DebugLevel::Normal, " Run target."); + if ( !hardware()->setTargetReset(Pic::ResetReleased) ) return false; + if ( !base().waitForTargetMode(Pic::TargetStopped) ) return false; + if ( !programmer().readDebugExecutiveVersion() ) return false; + + BitValue value; + if ( !readBreakpoint(value) ) return false; + BitValue expectedPC = (last ? 0x0001 : 0x0000); + if ( value==expectedPC+1 ) { + expectedPC = expectedPC+1; + log(Log::DebugLevel::Normal, "Probably detected custom ICD2"); + } + if ( value!=expectedPC ) + log(Log::DebugLevel::Normal, i18n(" PC is not at address %1 (%2)").arg(toHexLabel(expectedPC, 4)).arg(toHexLabel(value, 4))); + if ( !setBreakpoint(0x0000) ) return false; + + if ( !base().update() ) return false; + // #### not sure if there is a better way to get initial values (we are stopped here...) + Register::list().setValue(base().pcTypeData(), value); + Register::list().setValue(base().registerTypeData("STATUS"), 0x0); + Register::list().setValue(deviceSpecific()->wregTypeData(), 0x0); + + return true; +} + +//---------------------------------------------------------------------------- +Icd2::P18FDebuggerSpecific::P18FDebuggerSpecific(::Debugger::Base &base) + : DebuggerSpecific(base) +{ + const Pic::RegistersData &rdata = device()->registersData(); + // find last used bank (but not #15) + _reservedBank = rdata.nbBanks - 1; // #14 + for (uint i=1; i0; _reservedBank--) + if ( !rdata.bankHasSfrs(_reservedBank) ) break; + // also take care of USB RAM + if ( (device()->architecture()==Pic::Architecture::P18F || device()->architecture()==Pic::Architecture::P18J) + && device()->hasFeature(Pic::Feature::USB) ) { + if ( _reservedBank==7 ) _reservedBank = 3; // 18F2455 family: 4 USB RAM banks + // 18F87J50 family ? + } +} + +Address Icd2::P18FDebuggerSpecific::addressWREG()const +{ + return reservedRegisterOffset() | 0x0FF; +} + +Address Icd2::P18FDebuggerSpecific::addressRegister(Address address) const +{ + QString name = device()->registersData().sfrNames[address]; + if ( name=="PCLATU" ) return reservedRegisterOffset() | 0x0F4; + if ( name=="PCLATH" ) return reservedRegisterOffset() | 0x0F5; + if ( name=="FSR0H" ) return reservedRegisterOffset() | 0x0FB; + if ( name=="FSR0L" ) return reservedRegisterOffset() | 0x0FC; + if ( name=="BSR" ) return reservedRegisterOffset() | 0x0FD; + if ( name=="STATUS" ) return reservedRegisterOffset() | 0x0FE; + return address; +} + +bool Icd2::P18FDebuggerSpecific::setBreakpoint(Address address) +{ + BitValue value = (address.isValid() ? address.toUInt() << 15 : 0x0FFFFF00); // ?? + return hardware()->writeRegister(0xFB6, value, 4); +} + +bool Icd2::P18FDebuggerSpecific::readBreakpoint(BitValue &value) +{ + if ( !hardware()->readRegister(0xFB6, value, 4) ) return false; + value >>= 15; + return true; +} + +bool Icd2::P18FDebuggerSpecific::reset() +{ + if ( !hardware()->writeRegister(0xFB5, 0x00, 1) ) return false; // #### ?? + if ( !hardware()->writeRegister(0xFB5, 0x01, 1) ) return false; // #### ?? + if ( !hardware()->command("2D", 0) ) return false; // reset + if ( !hardware()->writeRegister(0xFB5, 0x00, 1) ) return false; // #### ?? + if ( !base().update() ) return false; + BitValue expectedPC = 0x0000; + if ( base().pc()==0x0001) { + expectedPC = 0x0001; + log(Log::LineType::Information, i18n("Detected custom ICD2")); + } + if ( base().pc()!=expectedPC ) { + log(Log::LineType::Error, i18n(" PC is not at address %1 (%2)").arg(toHexLabel(expectedPC, 4)).arg(toHexLabel(base().pc(), 4))); + return false; + } + return true; +} + +bool Icd2::P18FDebuggerSpecific::init(bool) +{ + if ( !hardware()->setTargetReset(Pic::ResetReleased) ) return false; + if ( !base().waitForTargetMode(Pic::TargetStopped) ) return false; + return reset(); +} diff --git a/src/progs/icd2/base/icd2_debug_specific.h b/src/progs/icd2/base/icd2_debug_specific.h new file mode 100644 index 0000000..d14887b --- /dev/null +++ b/src/progs/icd2/base/icd2_debug_specific.h @@ -0,0 +1,98 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef ICD2_DEBUG_SPECIFIC_H +#define ICD2_DEBUG_SPECIFIC_H + +#include "icd2_debug.h" + +namespace Icd2 +{ +//----------------------------------------------------------------------------- +class DebuggerSpecific : public ::Debugger::Specific +{ +public: + DebuggerSpecific(::Debugger::Base &base) : ::Debugger::Specific(base) {} + Debugger &base() { return static_cast(_base); } + const Debugger &base() const { return static_cast(_base); } + const Pic::Data *device() const { return base().device(); } + Hardware *hardware() { return base().programmer().hardware(); } + DebugProgrammer &programmer() { return base().programmer(); } + ::Debugger::PicSpecific *deviceSpecific() { return base().deviceSpecific(); } + virtual Address addressWREG() const = 0; + virtual BitValue maskPC() const = 0; + virtual Address addressRegister(Address address) const = 0; + virtual bool setBreakpoint(Address address) = 0; + virtual bool readBreakpoint(BitValue &value) = 0; + virtual bool init(bool last) = 0; + virtual bool reset() = 0; +}; + +//----------------------------------------------------------------------------- +class P16FDebuggerSpecific : public DebuggerSpecific +{ +public: + P16FDebuggerSpecific(::Debugger::Base &base) : DebuggerSpecific(base) {} + virtual Address addressBreakpointRegister() const { return 0x18E; } + virtual BitValue writeMaskBreakpointRegister() const { return 0x8000; } + virtual BitValue readMaskBreakpointRegister() const { return 0x1FFF; } + virtual Address addressWREG() const; + virtual BitValue maskPC() const { return 0x1FFF; } + virtual Address addressRegister(Address address) const; + virtual bool setBreakpoint(Address address); + virtual bool readBreakpoint(BitValue &value); + virtual bool reset(); + +protected: + bool beginInit(Device::Array *saved); + bool endInit(BitValue expectedPC); +}; + +class P16F872DebuggerSpecific : public P16FDebuggerSpecific +{ +public: + P16F872DebuggerSpecific(::Debugger::Base &base) : P16FDebuggerSpecific(base) {} + virtual bool init(bool last); +}; + +class P16F87XDebuggerSpecific : public P16FDebuggerSpecific +{ +public: + P16F87XDebuggerSpecific(::Debugger::Base &base) : P16FDebuggerSpecific(base) {} + virtual bool init(bool last); +}; + +class P16F7X7DebuggerSpecific : public P16FDebuggerSpecific +{ +public: + P16F7X7DebuggerSpecific(::Debugger::Base &base) : P16FDebuggerSpecific(base) {} + virtual bool init(bool last); +}; + +//----------------------------------------------------------------------------- +class P18FDebuggerSpecific : public DebuggerSpecific +{ +public: + P18FDebuggerSpecific(::Debugger::Base &base); + virtual Address addressWREG() const; + virtual BitValue maskPC() const { return 0xFFFF; } + virtual Address addressRegister(Address address) const; + virtual bool setBreakpoint(Address address); + virtual bool readBreakpoint(BitValue &value); + virtual bool init(bool last); + virtual bool reset(); + uint reservedBank() const { return _reservedBank; } + +private: + uint _reservedBank; // bank where are the debugging sfrs + uint reservedRegisterOffset() const { return reservedBank() << 8; } +}; + +} // namespace + +#endif diff --git a/src/progs/icd2/base/icd2_prog.cpp b/src/progs/icd2/base/icd2_prog.cpp new file mode 100644 index 0000000..7b2a59b --- /dev/null +++ b/src/progs/icd2/base/icd2_prog.cpp @@ -0,0 +1,142 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "icd2_prog.h" + +#include "common/global/pfile.h" +#include "progs/base/prog_config.h" +#include "devices/list/device_list.h" +#include "icd2_serial.h" +#include "icd2_usb.h" +#include "icd2_data.h" + +//----------------------------------------------------------------------------- +void Icd2::ProgrammerBase::clear() +{ + Icd::ProgrammerBase::clear(); + _firmwareId = 0; + _testData = TestData(); +} + +bool Icd2::ProgrammerBase::readFirmwareVersion() +{ + if ( !hardware()->setup() ) return false; + if ( !Icd::ProgrammerBase::readFirmwareVersion() ) return false; + _firmwareId = hardware()->getFirmwareId(); + return !hasError(); +} + +bool Icd2::ProgrammerBase::internalSetupHardware() +{ + ::Programmer::Config config; + if ( !_targetSelfPowered && device()->architecture()==Pic::Architecture::P30F + && !askContinue(i18n("It is not recommended to power dsPICs from ICD. Continue anyway?")) ) { + logUserAbort(); + return false; + } + return Icd::ProgrammerBase::internalSetupHardware(); +} + +bool Icd2::ProgrammerBase::selfTest(bool ask) +{ + log(Log::DebugLevel::Normal, " Self-test"); + if ( !hardware()->selfTest(_testData) ) return false; + if ( !_testData.pass() ) { + QString s; + for (uint i=0; iversion[_firmwareId-1]; + return VersionData(v.major, v.minor, v.dot); +} + +VersionData Icd2::ProgrammerBase::mplabVersion(::Programmer::FirmwareVersionType type) const +{ + const FirmwareVersionData *vd = (type==::Programmer::FirmwareVersionType::Min ? &MIN_VERSION_DATA : &MAX_VERSION_DATA); + return VersionData(vd->mplabMajor, vd->mplabMinor, 0); +} + +bool Icd2::ProgrammerBase::setupFirmware() +{ + const FamilyData &fdata = FAMILY_DATA[family(device()->name())]; + log(Log::DebugLevel::Normal, QString(" Firmware id is %1 and we want %2").arg(_firmwareId).arg(fdata.efid)); + if ( fdata.efid==_firmwareId ) return true; + log(Log::LineType::Information, i18n(" Incorrect firmware loaded.")); + + // find firmware file + PURL::Directory dir = firmwareDirectory(); + if ( dir.isEmpty() ) return false; + QString nameFilter = "ICD" + QString::number(fdata.efid).rightJustify(2, '0') + "??????.hex"; + QStringList files = dir.files(nameFilter); + if ( files.isEmpty() ) { + log(Log::LineType::Error, i18n("Could not find firmware file \"%1\" in directory \"%2\".").arg(nameFilter).arg(dir.path())); + return false; + } + + // upload hex file + PURL::Url url(dir, files[files.count()-1]); + log(Log::DebugLevel::Normal, QString(" Firmware file: %1").arg(url.pretty())); + Log::StringView sview; + PURL::File file(url, sview); + if ( !file.openForRead() ) { + log(Log::LineType::Error, i18n("Could not open firmware file \"%1\".").arg(url.pretty())); + return false; + } + if ( !doUploadFirmware(file) ) return false; + + // check firmware + if ( !readFirmwareVersion() ) return false; + if ( fdata.efid!=_firmwareId ) { + log(Log::LineType::Error, i18n("Firmware still incorrect after uploading.")); + return false; + } + log(Log::LineType::Information, i18n(" Firmware succesfully uploaded.")); + return true; +} + +//----------------------------------------------------------------------------- +Icd2::Programmer::Programmer(const ::Programmer::Group &group, const Pic::Data *data) + : Icd2::ProgrammerBase(group, data, "icd2_programmer") +{} + +//---------------------------------------------------------------------------- +Programmer::Properties Icd2::Group::properties() const +{ + return ::Programmer::Programmer | ::Programmer::HasFirmware | ::Programmer::CanUploadFirmware + | ::Programmer::NeedDeviceSpecificFirmware | ::Programmer::CanReleaseReset + | ::Programmer::HasSelfTest | ::Programmer::CanReadMemory | ::Programmer::HasConnectedState; +} + +bool Icd2::Group::canReadVoltage(Pic::VoltageType type) const +{ + return ( type==Pic::ProgrammerVpp || type==Pic::TargetVdd || type==Pic::TargetVpp ); +} + +Programmer::Hardware *Icd2::Group::createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &hd) const +{ + if ( hd.port.type==PortType::Serial ) return new SerialHardware(base, hd.port.device); + return new USBHardware(base); +} + +Programmer::DeviceSpecific *Icd2::Group::createDeviceSpecific(::Programmer::Base &base) const +{ + return new Icd::DeviceSpecific(base); +} diff --git a/src/progs/icd2/base/icd2_prog.h b/src/progs/icd2/base/icd2_prog.h new file mode 100644 index 0000000..e8be727 --- /dev/null +++ b/src/progs/icd2/base/icd2_prog.h @@ -0,0 +1,84 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef ICD2_PROG_H +#define ICD2_PROG_H + +#include "common/global/global.h" +#include "icd_prog.h" +#include "icd2.h" +#include "progs/base/prog_group.h" + +namespace Icd2 +{ +class Hardware; + +//----------------------------------------------------------------------------- +class ProgrammerBase : public Icd::ProgrammerBase +{ +Q_OBJECT +public: + ProgrammerBase(const Programmer::Group &group, const Pic::Data *data, const char *name) + : Icd::ProgrammerBase(group, data, name) {} + Hardware *hardware() { return static_cast(_hardware); } + const TestData &testData() const { return _testData; } + virtual bool selfTest(bool ask); + virtual bool readFirmwareVersion(); + uchar firmwareId() const { return _firmwareId; } + virtual bool setTarget() { return hardware()->setTarget(); } + +protected: + virtual void clear(); + virtual bool setupFirmware(); + virtual VersionData firmwareVersion(Programmer::FirmwareVersionType type) const; + virtual VersionData mplabVersion(Programmer::FirmwareVersionType type) const; + virtual bool internalSetupHardware(); + +private: + uchar _firmwareId; + TestData _testData; +}; + +//----------------------------------------------------------------------------- +class Programmer : public ProgrammerBase +{ +Q_OBJECT +public: + Programmer(const ::Programmer::Group &group, const Pic::Data *data); +}; + +//----------------------------------------------------------------------------- +class Group : public Icd::Group +{ +public: + virtual QString xmlName() const { return "icd2"; } + virtual ::Programmer::Properties properties() const; + virtual ::Programmer::TargetPowerMode targetPowerMode() const { return ::Programmer::TargetPowerModeFromConfig; } + virtual bool isPortSupported(PortType type) const { return ( type==PortType::Serial || type==PortType::USB ); } + virtual bool canReadVoltage(Pic::VoltageType type) const; + +protected: + virtual void initSupported(); + virtual ::Programmer::Hardware *createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &hd) const; + virtual ::Programmer::DeviceSpecific *createDeviceSpecific(::Programmer::Base &base) const; +}; + +//----------------------------------------------------------------------------- +class ProgrammerGroup : public Group +{ +public: + virtual QString name() const { return "icd2"; } + virtual QString label() const { return i18n("ICD2 Programmer"); } + +protected: + virtual ::Programmer::Base *createBase(const Device::Data *data) const { return new Programmer(*this, static_cast(data)); } +}; + +} // namespace + +#endif diff --git a/src/progs/icd2/base/icd2_serial.cpp b/src/progs/icd2/base/icd2_serial.cpp new file mode 100644 index 0000000..1ab738c --- /dev/null +++ b/src/progs/icd2/base/icd2_serial.cpp @@ -0,0 +1,66 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * Copyright (C) 2002-2003 Stephen Landamore * + * * + * 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. * + ***************************************************************************/ +#include "icd2_serial.h" + +#include "common/global/global.h" +#include "common/common/misc.h" + +//----------------------------------------------------------------------------- +Icd2::SerialPort::SerialPort(const QString &device, Log::Base &log) + : Port::Serial(device, NeedDrain | NeedFlush, log) +{} + +bool Icd2::SerialPort::open(Speed speed) +{ + if ( !Port::Serial::open() ) return false; + return setMode(NoInputFlag, ByteSize8 | EnableReceiver | HardwareFlowControl, speed, 0); +} + +//----------------------------------------------------------------------------- +Icd2::SerialHardware::SerialHardware(::Programmer::Base &base, const QString &portDevice) + : Hardware(base, new SerialPort(portDevice, base)) +{} + +bool Icd2::SerialHardware::internalConnect(const QString &mode) +{ + if ( !static_cast(_port)->open(Port::Serial::S19200) ) return false; + if ( !reset() ) return false; + if ( !_port->send("Z", 1) ) return false; + QString s; + if ( !_port->receive(4, s) ) return false; + if ( !reset() ) return false; + QByteArray a = toAscii(mode); + if ( !_port->send(a.data(), a.count()) ) return false; + if ( !_port->receive(1, s) ) return false; + if ( s.upper()!=mode ) { + log(Log::LineType::Error, i18n("Failed to set port mode to '%1'.").arg(mode)); + return false; + } + //log(Log::Debug, "set fast speed"); + //if ( !setFastSpeed() ) return false; + return true; +} + +bool Icd2::SerialHardware::reset() +{ + static_cast(_port)->setPinOn(Port::Serial::DTR, false, Port::PositiveLogic); // Trigger DTR to reset icd2 + Port::msleep(10); + static_cast(_port)->setPinOn(Port::Serial::DTR, true, Port::PositiveLogic); // remove reset + Port::msleep(10); + return true; +} + +bool Icd2::SerialHardware::setFastSpeed() +{ + if ( !command("4D", 0) ) return false; // go faster + static_cast(_port)->open(Port::Serial::S57600); + Port::msleep(100); // ...we do need to delay here + return !hasError(); +} diff --git a/src/progs/icd2/base/icd2_serial.h b/src/progs/icd2/base/icd2_serial.h new file mode 100644 index 0000000..546e7b3 --- /dev/null +++ b/src/progs/icd2/base/icd2_serial.h @@ -0,0 +1,41 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * Copyright (C) 2002-2003 Stephen Landamore * + * * + * 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. * + ***************************************************************************/ +#ifndef ICD2_SERIAL_H +#define ICD2_SERIAL_H + +#include "icd2.h" +#include "common/port/serial.h" + +namespace Icd2 +{ + +//----------------------------------------------------------------------------- +class SerialPort : public Port::Serial +{ +public: + SerialPort(const QString &portDevice, Log::Base &log); + bool open(Speed speed); +}; + +//----------------------------------------------------------------------------- +class SerialHardware : public Hardware +{ +public: + SerialHardware(::Programmer::Base &base, const QString &portDevice); + +private: + bool setFastSpeed(); + bool reset(); + virtual bool internalConnect(const QString &mode); +}; + +} // namespace + +#endif diff --git a/src/progs/icd2/base/icd2_usb.cpp b/src/progs/icd2/base/icd2_usb.cpp new file mode 100644 index 0000000..945ef6f --- /dev/null +++ b/src/progs/icd2/base/icd2_usb.cpp @@ -0,0 +1,174 @@ +/*************************************************************************** + * Copyright (C) 2005 Lorenz M�senlechner & Matthias Kranz * + * * + * Copyright (C) 2005 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "icd2_usb.h" + +#include "microchip.h" +#include "common/common/misc.h" + +//------------------------------------------------------------------------------ +const Icd2::USBPort::SequenceData Icd2::USBPort::SEQUENCE_DATA[Nb_SequenceTypes] = { + { 0x00 }, // receive + { 0x01 }, // send + { 0x02 }, // connect + { 0x00 } // poll +}; + +Icd2::USBPort::USBPort(uint deviceId, Log::Base &log) + : Port::USB(log, Microchip::VENDOR_ID, deviceId, 1, 0), _dataSend(false) +{} + +bool Icd2::USBPort::doSequence(SequenceType type, char *data, uint size) +{ + QByteArray tx(0x12); + for (uint i=0; i> 8) & 0xFF; + tx[0x0A] = _ctype & 0xFF; + tx[0x0B] = (_ctype >> 8) & 0xFF; + if ( !write(0x01, tx.data(), tx.size()) ) return false; + + switch (type) { + case Connect: break; + case Receive: + if ( !read(0x82, data, size, 0) ) return false; + break; + case Poll: + if ( !read(0x82, data, size, &_poll) ) return false; + break; + case Send: + if ( !write(0x01, data, size) ) return false; + break; + case Nb_SequenceTypes: Q_ASSERT(false); break; + } + + QByteArray rx(0x08); + if ( !read(0x81, rx.data(), rx.size(), 0) ) return false; + //Q_ASSERT( rx[0]==tx[1] ); + + _seqnum++; + if ( _seqnum==0xFF ) _seqnum = 0xC0; + return true; +} + +bool Icd2::USBPort::connectDevice(const QString &mode) +{ + _seqnum = 0xC1; // preset seqnum + + _ctype = 0x00; + if ( !doSequence(Connect, 0, 0) ) return false; + if ( !send("Z", 1) ) return false; + QString s; + if ( !receive(4, s) ) return false; + + _ctype = 0x00; + if ( !doSequence(Connect, 0, 0) ) return false; + for (uint i=0; true; i++) { + if ( i==10 ) { + log(Log::LineType::Error, i18n("Problem connecting ICD2: please try again after unplug-replug.")); + return false; + } + _ctype = 0x02; + QByteArray a = toAscii(mode); + if ( !doSequence(Send, a.data(), a.count()) ) return false; + char c; + _ctype = 0x02; + if ( !doSequence(Receive, &c, 1) ) return false; + if ( c==mode.lower()[0] ) break; + } + + return true; +} + +bool Icd2::USBPort::internalReceive(uint size, char *data, uint) +{ + if (_dataSend) { + //_ctype = qMin(0x65, qRound(4.8 * size)); // timing ?? (1.6 for my ICD2) + _ctype = 0xC9; + } else _ctype = 0xC9; + bool ok = doSequence(Receive, data, size); + if (_dataSend) _dataSend = false; + return ok; +} + +bool Icd2::USBPort::internalSend(const char *data, uint size, uint) +{ + if (_dataSend) { + //_ctype = qMin(0x65, qRound(4.8 * size)); // timing ?? (1.6 for my ICD2) + _ctype = 0xC9; + } else _ctype = 0xC9; + bool ok = doSequence(Send, (char *)data, size); + if (_dataSend) _dataSend = false; + return ok; +} + +bool Icd2::USBPort::poll(uint size, QString &s) +{ + QMemArray a; + if ( !poll(size, a) ) return false; + s.fill(0, size); + for (uint i=0; i &a) +{ + a.resize(size); + for (;;) { + _ctype = 0x65;//0x01; + if ( !doSequence(Poll, (char *)a.data(), size) ) return false; + if (_poll) break; + } + //log(Log::DebugLevel::Max, QString("Receiced: \"%1\"").arg(toPrintable((const char *)a.data(), size))); + return true; +} + +bool Icd2::USBPort::dataSend(const char *data, uint size) +{ + _dataSend = true; + return Port::USB::send(data, size); +} + +bool Icd2::USBPort::dataReceive(uint size, QString &s) +{ + _dataSend = true; + return Port::USB::receive(size, s); +} + +//------------------------------------------------------------------------------ +Icd2::USBHardware::USBHardware(::Programmer::Base &base) + : Hardware(base, new USBPort(ID_CLIENT, base)) +{} + +bool Icd2::USBHardware::internalConnect(const QString &mode) +{ + // load control messages for USB device if needed + log(Log::DebugLevel::Extra, QString("need firmware ? %1").arg(USBPort::findDevice(Microchip::VENDOR_ID, ID_FIRMWARE)!=0)); + if ( Port::USB::findDevice(Microchip::VENDOR_ID, ID_FIRMWARE) ) { + USBPort port(ID_FIRMWARE, *this); + if ( !port.open() ) return false; + uint i = 0; + while ( CONTROL_MESSAGE_DATA[i].bytes!=0 ) { + if ( !port.sendControlMessage(CONTROL_MESSAGE_DATA[i]) ) return false; + i++; + } + port.close(); + for (uint i=0; i<10; i++) { + log(Log::DebugLevel::Extra, QString("client here ? %1").arg(USBPort::findDevice(Microchip::VENDOR_ID, ID_CLIENT)!=0)); + if ( Port::USB::findDevice(Microchip::VENDOR_ID, ID_CLIENT) ) break; + Port::msleep(1000); + } + } + + if ( !_port->open() ) return false; + return static_cast(_port)->connectDevice(mode); +} diff --git a/src/progs/icd2/base/icd2_usb.h b/src/progs/icd2/base/icd2_usb.h new file mode 100644 index 0000000..c2677a6 --- /dev/null +++ b/src/progs/icd2/base/icd2_usb.h @@ -0,0 +1,63 @@ +/*************************************************************************** + * Copyright (C) 2005 Lorenz Mösenlechner & Matthias Kranz * + * * + * Copyright (C) 2005 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef ICD2_USB_H +#define ICD2_USB_H + +#include "icd2.h" +#include "common/port/usb_port.h" + +namespace Icd2 +{ + +//----------------------------------------------------------------------------- +class USBPort : public Port::USB +{ +public: + USBPort(uint deviceId, Log::Base &log); + bool connectDevice(const QString &mode); + bool poll(uint size, QString &s); + bool poll(uint size, QMemArray &data); + bool dataSend(const char *data, uint size); + bool dataReceive(uint size, QString &s); + +private: + uchar _seqnum; + bool _poll; + uint _ctype; + bool _dataSend; + + enum SequenceType { Receive = 0, Send, Connect, Poll, Nb_SequenceTypes }; + struct SequenceData { + char type; + }; + static const SequenceData SEQUENCE_DATA[Nb_SequenceTypes]; + bool doSequence(SequenceType type, char *data, uint size); + virtual bool internalSend(const char *data, uint size, uint timeout = 0); + virtual bool internalReceive(uint size, char *data, uint timeout = 0); +}; + +//------------------------------------------------------------------------------ +class USBHardware : public Hardware +{ +public: + USBHardware(::Programmer::Base &base); + +private: + static const Port::USB::ControlMessageData CONTROL_MESSAGE_DATA[]; + enum { ID_FIRMWARE = 0x8000, // ICD2 id before usb firmware is transmitted + ID_CLIENT = 0x8001 // ICD2 id after firmware is transmitted + }; + virtual bool internalConnect(const QString &mode); +}; + +} // namespace + +#endif diff --git a/src/progs/icd2/base/icd2_usb_firmware.cpp b/src/progs/icd2/base/icd2_usb_firmware.cpp new file mode 100644 index 0000000..c7947cf --- /dev/null +++ b/src/progs/icd2/base/icd2_usb_firmware.cpp @@ -0,0 +1,613 @@ +/*************************************************************************** + * Copyright (C) 2005 Lorenz Mösenlechner & Matthias Kranz * + * * + * Copyright (C) 2005 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "icd2_usb.h" + +const Port::USB::ControlMessageData Icd2::USBHardware::CONTROL_MESSAGE_DATA[] = { +{ 0x40, 0xA0, 0x7F92, "01" }, +{ 0x40, 0xA0, 0x146C, "C200907FA5E05418FF131313541F4450" }, +{ 0x40, 0xA0, 0x147C, "F51C139201D2E8907FAB74FFF0907FA9" }, +{ 0x40, 0xA0, 0x148C, "F0907FAAF05391EF907F95E044C0F090" }, +{ 0x40, 0xA0, 0x149C, "7FAFE04401F0907FAEE04405F0D2AF12" }, +{ 0x40, 0xA0, 0x14AC, "175F3000FD121100C20080F622" }, +{ 0x40, 0xA0, 0x1100, "907FE9E0245D600D1470030212442402" }, +{ 0x40, 0xA0, 0x1110, "600302124A907FEAE0750800F509A3E0" }, +{ 0x40, 0xA0, 0x1120, "FEE42509F509EE3508F508907FEEE075" }, +{ 0x40, 0xA0, 0x1130, "0A00F50BA3E0FEE4250BF50BEE350AF5" }, +{ 0x40, 0xA0, 0x1140, "0A907FE8E064C060030211D4E50B450A" }, +{ 0x40, 0xA0, 0x1150, "700302124AC3E50B9440E50A94005008" }, +{ 0x40, 0xA0, 0x1160, "850A0C850B0D8006750C00750D40907F" }, +{ 0x40, 0xA0, 0x1170, "E9E0B4A325AE0CAF0DAA08A9097B01C0" }, +{ 0x40, 0xA0, 0x1180, "03C002C0017A7F790078007C7FAD03D0" }, +{ 0x40, 0xA0, 0x1190, "01D002D003121356800FAF09AE08AD0D" }, +{ 0x40, 0xA0, 0x11A0, "7A7F79007B001215A4907FB5E50DF0E5" }, +{ 0x40, 0xA0, 0x11B0, "0D2509F509E50C3508F508C3E50B950D" }, +{ 0x40, 0xA0, 0x11C0, "F50BE50A950CF50A907FB4E020E20302" }, +{ 0x40, 0xA0, 0x11D0, "114C80F4907FE8E06440706EE50B450A" }, +{ 0x40, 0xA0, 0x11E0, "6068E4907FC5F0907FB4E020E3F9907F" }, +{ 0x40, 0xA0, 0x11F0, "C5E0750C00F50D907FE9E0B4A315AE0C" }, +{ 0x40, 0xA0, 0x1200, "AF0DA809AC087D017B017A7E79C01213" }, +{ 0x40, 0xA0, 0x1210, "56800FAF09AE08AD0D7A7F79007B0012" }, +{ 0x40, 0xA0, 0x1220, "14B9E50D2509F509E50C3508F508C3E5" }, +{ 0x40, 0xA0, 0x1230, "0B950DF50BE50A950CF50A907FB4E044" }, +{ 0x40, 0xA0, 0x1240, "02F08098907FEAE0F51C" }, +{ 0x40, 0xA0, 0x124A, "22" }, +{ 0x40, 0xA0, 0x1558, "AB07AA06AC05" }, +{ 0x40, 0xA0, 0x155E, "E4FD300111EAFFAE050DEE2400F582E4" }, +{ 0x40, 0xA0, 0x156E, "34E0F583EFF0EBAE050D74002EF582E4" }, +{ 0x40, 0xA0, 0x157E, "34E0F583EBF0AF050D74002FF582E434" }, +{ 0x40, 0xA0, 0x158E, "E0F583ECF0AF1C7AE07B001217207F0A" }, +{ 0x40, 0xA0, 0x159E, "7E0012173C" }, +{ 0x40, 0xA0, 0x15A3, "22" }, +{ 0x40, 0xA0, 0x14B9, "8E0E8F0F8D108A118B12" }, +{ 0x40, 0xA0, 0x14C3, "E4F513E513C395105020050FE50FAE0E" }, +{ 0x40, 0xA0, 0x14D3, "7002050E14FFE5122513F582E43511F5" }, +{ 0x40, 0xA0, 0x14E3, "83E0FD121558051380D9" }, +{ 0x40, 0xA0, 0x14ED, "22" }, +{ 0x40, 0xA0, 0x15A4, "8E0E8F0F8D108A118B12" }, +{ 0x40, 0xA0, 0x15AE, "E4FD300112E50EFFAE050DEE2403F582" }, +{ 0x40, 0xA0, 0x15BE, "E434E0F583EFF0E50FAE050D74032EF5" }, +{ 0x40, 0xA0, 0x15CE, "82E434E0F583E50FF0AF1C7AE07B0312" }, +{ 0x40, 0xA0, 0x15DE, "1720AF1CAD10AB12AA11121704" }, +{ 0x40, 0xA0, 0x15EB, "22" }, +{ 0x40, 0xA0, 0x166E, "C0E0C083C082C085C084C086758600D2" }, +{ 0x40, 0xA0, 0x167E, "005391EF907FAB7401F0D086D084D085" }, +{ 0x40, 0xA0, 0x168E, "D082D083D0E032" }, +{ 0x40, 0xA0, 0x1644, "C0E0C083C082C085C084C08675860090" }, +{ 0x40, 0xA0, 0x1654, "7FC4E4F05391EF907FAB7404F0D086D0" }, +{ 0x40, 0xA0, 0x1664, "84D085D082D083D0E032" }, +{ 0x40, 0xA0, 0x1695, "C0E0C083C082C085C084C08675860053" }, +{ 0x40, 0xA0, 0x16A5, "91EF907FAB7402F0D086D084D085D082" }, +{ 0x40, 0xA0, 0x16B5, "D083D0E032" }, +{ 0x40, 0xA0, 0x16BA, "C0E0C083C082C085C084C08675860053" }, +{ 0x40, 0xA0, 0x16CA, "91EF907FAB7410F0D086D084D085D082" }, +{ 0x40, 0xA0, 0x16DA, "D083D0E032" }, +{ 0x40, 0xA0, 0x14FF, "32" }, +{ 0x40, 0xA0, 0x16DF, "C0E0C083C082C085C084C08675860053" }, +{ 0x40, 0xA0, 0x16EF, "91EF907FAB7408F0D086D084D085D082" }, +{ 0x40, 0xA0, 0x16FF, "D083D0E032" }, +{ 0x40, 0xA0, 0x1767, "32" }, +{ 0x40, 0xA0, 0x1768, "32" }, +{ 0x40, 0xA0, 0x1769, "32" }, +{ 0x40, 0xA0, 0x176A, "32" }, +{ 0x40, 0xA0, 0x176B, "32" }, +{ 0x40, 0xA0, 0x176C, "32" }, +{ 0x40, 0xA0, 0x176D, "32" }, +{ 0x40, 0xA0, 0x176E, "32" }, +{ 0x40, 0xA0, 0x176F, "32" }, +{ 0x40, 0xA0, 0x1770, "32" }, +{ 0x40, 0xA0, 0x1771, "32" }, +{ 0x40, 0xA0, 0x1772, "32" }, +{ 0x40, 0xA0, 0x1773, "32" }, +{ 0x40, 0xA0, 0x1774, "32" }, +{ 0x40, 0xA0, 0x1775, "32" }, +{ 0x40, 0xA0, 0x1776, "32" }, +{ 0x40, 0xA0, 0x0043, "021500" }, +{ 0x40, 0xA0, 0x1500, "02166E0002169500021644000216DF00" }, +{ 0x40, 0xA0, 0x1510, "0216BA000214FF000217670002176800" }, +{ 0x40, 0xA0, 0x1520, "0217690002176A0002176B0002176C00" }, +{ 0x40, 0xA0, 0x1530, "02176D0002176E0002176F0002177000" }, +{ 0x40, 0xA0, 0x1540, "02177100021772000217730002177400" }, +{ 0x40, 0xA0, 0x1550, "0217750002177600" }, +{ 0x40, 0xA0, 0x173C, "8E148F15E5151515AE14700215144E60" }, +{ 0x40, 0xA0, 0x174C, "051214EE80EE22" }, +{ 0x40, 0xA0, 0x175F, "E4F51BD2E9D2AF22" }, +{ 0x40, 0xA0, 0x1619, "A907E51B7023907FA5E04480F0E925E0" }, +{ 0x40, 0xA0, 0x1629, "907FA6F08D16AF03A9077517018A1889" }, +{ 0x40, 0xA0, 0x1639, "19E4F51A751B01D322C322" }, +{ 0x40, 0xA0, 0x15EC, "A907E51B7025907FA5E04480F0E925E0" }, +{ 0x40, 0xA0, 0x15FC, "4401907FA6F08D16AF03A9077517018A" }, +{ 0x40, 0xA0, 0x160C, "188919E4F51A751B03D322C322" }, +{ 0x40, 0xA0, 0x004B, "02137F" }, +{ 0x40, 0xA0, 0x137F, "C0E0C083C082C085C084C086758600C0" }, +{ 0x40, 0xA0, 0x138F, "D075D000C000C001C002C003C006C007" }, +{ 0x40, 0xA0, 0x139F, "907FA5E030E206751B0602144E907FA5" }, +{ 0x40, 0xA0, 0x13AF, "E020E10CE51B64026006751B0702144E" }, +{ 0x40, 0xA0, 0x13BF, "AF1BEF24FE604814602C24FE60772404" }, +{ 0x40, 0xA0, 0x13CF, "600302144EAB17AA18A919AF1A051A8F" }, +{ 0x40, 0xA0, 0x13DF, "8275830012124B907FA6F0E51A651670" }, +{ 0x40, 0xA0, 0x13EF, "5E751B058059907FA6E0AB17AA18A919" }, +{ 0x40, 0xA0, 0x13FF, "AE1A8E82758300121278751B028040E5" }, +{ 0x40, 0xA0, 0x140F, "1624FEB51A07907FA5E04420F0E51614" }, +{ 0x40, 0xA0, 0x141F, "B51A0A907FA5E04440F0751B00907FA6" }, +{ 0x40, 0xA0, 0x142F, "E0AB17AA18A919AE1A8E827583001212" }, +{ 0x40, 0xA0, 0x143F, "78051A800A907FA5E04440F0751B0053" }, +{ 0x40, 0xA0, 0x144F, "91DFD007D006D003D002D001D000D0D0" }, +{ 0x40, 0xA0, 0x145F, "D086D084D085D082D083D0E032" }, +{ 0x40, 0xA0, 0x1704, "1215ECE51B24FA600E146006240770F3" }, +{ 0x40, 0xA0, 0x1714, "D322E4F51BD322E4F51BD322" }, +{ 0x40, 0xA0, 0x1720, "121619E51B24FA600E146006240770F3" }, +{ 0x40, 0xA0, 0x1730, "D322E4F51BD322E4F51BD322" }, +{ 0x40, 0xA0, 0x14EE, "7400F58690FDA57C05A3E582458370F9" }, +{ 0x40, 0xA0, 0x14FE, "22" }, +{ 0x40, 0xA0, 0x0000, "021753" }, +{ 0x40, 0xA0, 0x1753, "787FE4F6D8FD75812002146C" }, +{ 0x40, 0xA0, 0x124B, "BB010CE58229F582E5833AF583E02250" }, +{ 0x40, 0xA0, 0x125B, "06E92582F8E622BBFE06E92582F8E222" }, +{ 0x40, 0xA0, 0x126B, "E58229F582E5833AF583E49322" }, +{ 0x40, 0xA0, 0x1278, "F8BB010DE58229F582E5833AF583E8F0" }, +{ 0x40, 0xA0, 0x1288, "225006E92582C8F622BBFE05E92582C8" }, +{ 0x40, 0xA0, 0x1298, "F222" }, +{ 0x40, 0xA0, 0x129A, "E709F608DFFA8046E709F208DFFA803E" }, +{ 0x40, 0xA0, 0x12AA, "88828C83E709F0A3DFFA8032E309F608" }, +{ 0x40, 0xA0, 0x12BA, "DFFA806EE309F208DFFA806688828C83" }, +{ 0x40, 0xA0, 0x12CA, "E309F0A3DFFA805A89828A83E0A3F608" }, +{ 0x40, 0xA0, 0x12DA, "DFFA804E89828A83E0A3F208DFFA8042" }, +{ 0x40, 0xA0, 0x12EA, "80D280FA80C680D4805580F280298010" }, +{ 0x40, 0xA0, 0x12FA, "80A680EA809A80A880DA80E280CA8029" }, +{ 0x40, 0xA0, 0x130A, "88848C8589828A83E493A30586F0A305" }, +{ 0x40, 0xA0, 0x131A, "86DFF5DEF3800B89828A83E493A3F608" }, +{ 0x40, 0xA0, 0x132A, "DFF9ECFAA9F0EDFB2288848C8589828A" }, +{ 0x40, 0xA0, 0x133A, "83E0A30586F0A30586DFF6DEF480E389" }, +{ 0x40, 0xA0, 0x134A, "828A83E493A3F208DFF980D688F0ED24" }, +{ 0x40, 0xA0, 0x135A, "02B4040050CCF582EB2402B4040050C2" }, +{ 0x40, 0xA0, 0x136A, "23234582F582EF4E60B8EF60010EE582" }, +{ 0x40, 0xA0, 0x137A, "239012EA73" }, +{ 0x40, 0xA0, 0x7F92, "00" }, +{ 0x40, 0xA0, 0x7F92, "01" }, +{ 0x40, 0xA0, 0x0100, "907FE9E0700302029B14700302031724" }, +{ 0x40, 0xA0, 0x0110, "FE700302038E24FB7003020295147003" }, +{ 0x40, 0xA0, 0x0120, "02028F14700302028314700302028924" }, +{ 0x40, 0xA0, 0x0130, "0560030203E2120F7A40030203EE907F" }, +{ 0x40, 0xA0, 0x0140, "EBE024FE601914604724026003020279" }, +{ 0x40, 0xA0, 0x0150, "E50C907FD4F0E50D907FD5F00203EE90" }, +{ 0x40, 0xA0, 0x0160, "7FEAE0FF121710AA06A9077B018B498A" }, +{ 0x40, 0xA0, 0x0170, "4A894BEA49600FEE907FD4F0AF01EF90" }, +{ 0x40, 0xA0, 0x0180, "7FD5F00203EE907FB4E04401F00203EE" }, +{ 0x40, 0xA0, 0x0190, "907FEAE0FF1216E4AA06A9077B018B49" }, +{ 0x40, 0xA0, 0x01A0, "8A4A894BEA49700302026F" }, +{ 0x40, 0xA0, 0x01AB, "AB498B508A5189521217F4F553907FEE" }, +{ 0x40, 0xA0, 0x01BB, "E0FFE553D39F4003E0F553E553700302" }, +{ 0x40, 0xA0, 0x01CB, "0261754F00754E00754D00754C00E553" }, +{ 0x40, 0xA0, 0x01DB, "C394405004AF5380027F40E4FCFDFEAB" }, +{ 0x40, 0xA0, 0x01EB, "4FAA4EA94DA84CC31218625038E55225" }, +{ 0x40, 0xA0, 0x01FB, "4FF582E54E3551F583E0FF7400254FF5" }, +{ 0x40, 0xA0, 0x020B, "82E4347FF583EFF07A0079007800E54F" }, +{ 0x40, 0xA0, 0x021B, "2401F54FEA354EF54EE9354DF54DE835" }, +{ 0x40, 0xA0, 0x022B, "4CF54C80A9E553C394405004AF538002" }, +{ 0x40, 0xA0, 0x023B, "7F40907FB5EFF0E553C394405004AF53" }, +{ 0x40, 0xA0, 0x024B, "80027F40C3E5539FF553907FB4E020E2" }, +{ 0x40, 0xA0, 0x025B, "030201C680F4E4907FB5F0907FB47402" }, +{ 0x40, 0xA0, 0x026B, "F0" }, +{ 0x40, 0xA0, 0x026C, "0203EE907FB4E04401F00203EE907FB4" }, +{ 0x40, 0xA0, 0x027C, "E04401F00203EE120FA60203EE120F9A" }, +{ 0x40, 0xA0, 0x028C, "0203EE120F7C0203EE120F880203EE12" }, +{ 0x40, 0xA0, 0x029C, "0FB840030203EE907FE8E0247F602414" }, +{ 0x40, 0xA0, 0x02AC, "60312402705BA200E433FF25E0FFA202" }, +{ 0x40, 0xA0, 0x02BC, "E4334F907F00F0E4A3F0907FB57402F0" }, +{ 0x40, 0xA0, 0x02CC, "0203EEE4907F00F0A3F0907FB57402F0" }, +{ 0x40, 0xA0, 0x02DC, "0203EE907FECE0F45480FFC4540FFFE0" }, +{ 0x40, 0xA0, 0x02EC, "54072F25E024B4F582E4347FF583E054" }, +{ 0x40, 0xA0, 0x02FC, "01907F00F0E4A3F0907FB57402F00203" }, +{ 0x40, 0xA0, 0x030C, "EE907FB4E04401F00203EE120FBA4003" }, +{ 0x40, 0xA0, 0x031C, "0203EE907FE8E024FE601D2402600302" }, +{ 0x40, 0xA0, 0x032C, "03EE907FEAE0B40105C2000203EE907F" }, +{ 0x40, 0xA0, 0x033C, "B4E04401F00203EE907FEAE0703B907F" }, +{ 0x40, 0xA0, 0x034C, "ECE0F45480FFC4540FFFE054072F25E0" }, +{ 0x40, 0xA0, 0x035C, "24B4F582E4347FF583E4F0907FECE054" }, +{ 0x40, 0xA0, 0x036C, "80FF131313541FFFE054072F907FD7F0" }, +{ 0x40, 0xA0, 0x037C, "E4F550" }, +{ 0x40, 0xA0, 0x037F, "E04420F08069907FB4E04401F0806012" }, +{ 0x40, 0xA0, 0x038F, "0FBC505B907FE8E024FE60182402704F" }, +{ 0x40, 0xA0, 0x039F, "907FEAE0B40104D2008044907FB4E044" }, +{ 0x40, 0xA0, 0x03AF, "01F0803B907FEAE07020907FECE0F454" }, +{ 0x40, 0xA0, 0x03BF, "80FFC4540FFFE054072F25E024B4F582" }, +{ 0x40, 0xA0, 0x03CF, "E4347FF5837401F08015907FB4E04401" }, +{ 0x40, 0xA0, 0x03DF, "F0800C120FBE5007907FB4E04401F090" }, +{ 0x40, 0xA0, 0x03EF, "7FB4E04402F0" }, +{ 0x40, 0xA0, 0x03F5, "22" }, +{ 0x40, 0xA0, 0x0033, "0203F6" }, +{ 0x40, 0xA0, 0x03F6, "53D8EF32" }, +{ 0x40, 0xA0, 0x000B, "0203FA" }, +{ 0x40, 0xA0, 0x03FA, "C0E0C0D0C000C001C002C004C005C006" }, +{ 0x40, 0xA0, 0x040A, "C007C28C758AD1758C63D28CAF0BAE0A" }, +{ 0x40, 0xA0, 0x041A, "AD09AC087A0079007800EF2401F50BEA" }, +{ 0x40, 0xA0, 0x042A, "3EF50AE93DF509E83CF508D007D006D0" }, +{ 0x40, 0xA0, 0x043A, "05D004D002D001D000D0D0D0E032" }, +{ 0x40, 0xA0, 0x0448, "750B00750A00750900750800C28C5389" }, +{ 0x40, 0xA0, 0x0458, "F0438901758AD1758C63C2B9D2A9D28C" }, +{ 0x40, 0xA0, 0x0468, "22" }, +{ 0x40, 0xA0, 0x0469, "754400754300754200754100C203C200" }, +{ 0x40, 0xA0, 0x0479, "C202C201120F037E067F228E0C8F0D75" }, +{ 0x40, 0xA0, 0x0489, "0E06750F347510067511A8EE54E07003" }, +{ 0x40, 0xA0, 0x0499, "0205897545007546808E478F48C374F6" }, +{ 0x40, 0xA0, 0x04A9, "9FFF74069ECF2402CF3400FEE48F408E" }, +{ 0x40, 0xA0, 0x04B9, "3FF53EF53DF53CF53BF53AF539AF40AE" }, +{ 0x40, 0xA0, 0x04C9, "3FAD3EAC3DAB3CAA3BA93AA839C31218" }, +{ 0x40, 0xA0, 0x04D9, "62502CE546253CF582E53B3545F58374" }, +{ 0x40, 0xA0, 0x04E9, "CDF07A0079007800E53C2401F53CEA35" }, +{ 0x40, 0xA0, 0x04F9, "3BF53BE9353AF53AE83539F53980BE75" }, +{ 0x40, 0xA0, 0x0509, "3C00753B00753A00753900AF40AE3FAD" }, +{ 0x40, 0xA0, 0x0519, "3EAC3DAB3CAA3BA93AA839C312186250" }, +{ 0x40, 0xA0, 0x0529, "39AE3BAF3CE5482FF582EE3547F583E0" }, +{ 0x40, 0xA0, 0x0539, "FDE5462FF582EE3545F583EDF07A0079" }, +{ 0x40, 0xA0, 0x0549, "007800E53C2401F53CEA353BF53BE935" }, +{ 0x40, 0xA0, 0x0559, "3AF53AE83539F53980B185450C85460D" }, +{ 0x40, 0xA0, 0x0569, "74222480FF740634FFFEC3E50F9FF50F" }, +{ 0x40, 0xA0, 0x0579, "E50E9EF50EC3E5119FF511E5109EF510" }, +{ 0x40, 0xA0, 0x0589, "C2AFD2E843D820120448907FAFE04401" }, +{ 0x40, 0xA0, 0x0599, "F0907FAEE0441DF0D2AFC2AAC2A82001" }, +{ 0x40, 0xA0, 0x05A9, "4A200105D20B12169375440075430075" }, +{ 0x40, 0xA0, 0x05B9, "42007541007F407E927D047C00AB44AA" }, +{ 0x40, 0xA0, 0x05C9, "43A942A841C312186250D32001D07A00" }, +{ 0x40, 0xA0, 0x05D9, "79007800E5442401F544EA3543F543E9" }, +{ 0x40, 0xA0, 0x05E9, "3542F542E83541F54180CA538EF83001" }, +{ 0x40, 0xA0, 0x05F9, "05120100C20130031A120F705015C203" }, +{ 0x40, 0xA0, 0x0609, "121672200007907FD6E020E7F3121658" }, +{ 0x40, 0xA0, 0x0619, "120F75120F4C80D6" }, +{ 0x40, 0xA0, 0x0621, "22" }, +{ 0x40, 0xA0, 0x0622, "12010001FFFFFF40D804018003000000" }, +{ 0x40, 0xA0, 0x0632, "000109027400010100804B090400000E" }, +{ 0x40, 0xA0, 0x0642, "FFFFFF00070501024000010705020240" }, +{ 0x40, 0xA0, 0x0652, "00010705030240000107050402400001" }, +{ 0x40, 0xA0, 0x0662, "07050502400001070506024000010705" }, +{ 0x40, 0xA0, 0x0672, "07024000010705810240000107058202" }, +{ 0x40, 0xA0, 0x0682, "40000107058302400001070584024000" }, +{ 0x40, 0xA0, 0x0692, "01070585024000010705860240000107" }, +{ 0x40, 0xA0, 0x06A2, "058702400001040309042A034D006900" }, +{ 0x40, 0xA0, 0x06B2, "630072006F0063006800690070002000" }, +{ 0x40, 0xA0, 0x06C2, "54006500630068006E006F006C006F00" }, +{ 0x40, 0xA0, 0x06D2, "67007900200349004300440032002000" }, +{ 0x40, 0xA0, 0x06E2, "55005300420020004400650076006900" }, +{ 0x40, 0xA0, 0x06F2, "630065000000" }, +{ 0x40, 0xA0, 0x1289, "436F7079726967687420284329203230" }, +{ 0x40, 0xA0, 0x1299, "3032204D6963726F6368697020546563" }, +{ 0x40, 0xA0, 0x12A9, "686E6F6C6F67792C20496E632E000000" }, +{ 0x40, 0xA0, 0x12B9, "00004672616D65776F726B7320636F70" }, +{ 0x40, 0xA0, 0x12C9, "79726967687420284329203139393820" }, +{ 0x40, 0xA0, 0x12D9, "416E63686F722043686970732C20496E" }, +{ 0x40, 0xA0, 0x12E9, "632E0000" }, +{ 0x40, 0xA0, 0x11B5, "60C01A50FF13CBFF1507FF15DD000000" }, +{ 0x40, 0xA0, 0x11C5, "00000000000000000000000000000000" }, +{ 0x40, 0xA0, 0x11D5, "00000000000000000000000000000000" }, +{ 0x40, 0xA0, 0x11E5, "00000000000000000000000000000000" }, +{ 0x40, 0xA0, 0x11F5, "00000000000000000000000000000000" }, +{ 0x40, 0xA0, 0x1205, "00000000000000000000000000000000" }, +{ 0x40, 0xA0, 0x1215, "00000000000000000000000000000000" }, +{ 0x40, 0xA0, 0x1225, "00000000000000000000000000000000" }, +{ 0x40, 0xA0, 0x1235, "00000000000000000000000000000000" }, +{ 0x40, 0xA0, 0x1245, "00000000000000000000000000000000" }, +{ 0x40, 0xA0, 0x1255, "00000000000000000000000000000000" }, +{ 0x40, 0xA0, 0x1265, "00000000000000000000000000000000" }, +{ 0x40, 0xA0, 0x1275, "00000000421B120000421B150000421B" }, +{ 0x40, 0xA0, 0x1285, "100000" }, +{ 0x40, 0xA0, 0x06F8, "8B128A138914751700751800AB12AA13" }, +{ 0x40, 0xA0, 0x0708, "A9141217F4FF7E008E158F16C3E51694" }, +{ 0x40, 0xA0, 0x0718, "40E515648094805063AE15AF16901A50" }, +{ 0x40, 0xA0, 0x0728, "75F003EF1218C3EE75F003A42583F583" }, +{ 0x40, 0xA0, 0x0738, "E0FBA3E0FAA3E0F9EA496040AB12AA13" }, +{ 0x40, 0xA0, 0x0748, "A914C003C002C001AE15AF16901A5075" }, +{ 0x40, 0xA0, 0x0758, "F003EF1218C3EE75F003A42583F583E0" }, +{ 0x40, 0xA0, 0x0768, "FBA3E0FAA3E0F989828A83D001D002D0" }, +{ 0x40, 0xA0, 0x0778, "0312077E8002E4738E178F18AE17AF18" }, +{ 0x40, 0xA0, 0x0788, "22" }, +{ 0x40, 0xA0, 0x0789, "C2AFAF0BAE0AAD09AC088F1C8E1B8D1A" }, +{ 0x40, 0xA0, 0x0799, "8C19D2AFAF1CAE1BAD1AAC1922" }, +{ 0x40, 0xA0, 0x07A6, "907FC7E4F022" }, +{ 0x40, 0xA0, 0x07AC, "8E228F23901B10E0FEA3E0FF8E248F25" }, +{ 0x40, 0xA0, 0x07BC, "901B10E522F0A3E523F0AE24AF2522" }, +{ 0x40, 0xA0, 0x07CB, "901B10E0FEA3E0FF22" }, +{ 0x40, 0xA0, 0x07D4, "901A00EBF0A3EAF0A3E9F0901A031218" }, +{ 0x40, 0xA0, 0x07E4, "86901B12E4F0A37402F0901A09E0FEA3" }, +{ 0x40, 0xA0, 0x07F4, "E0FFEF30E018901A00E0FBA3E0FAA3E0" }, +{ 0x40, 0xA0, 0x0804, "F9901A1AEBF0A3EAF0A3E9F08016901A" }, +{ 0x40, 0xA0, 0x0814, "00E0FBA3E0FAA3E0F9901A13EBF0A3EA" }, +{ 0x40, 0xA0, 0x0824, "F0A3E9F0901A1DE4F0A37401F0901A09" }, +{ 0x40, 0xA0, 0x0834, "E0FEA3E0FFEEFF7E00901A17EFF0901A" }, +{ 0x40, 0xA0, 0x0844, "03E0FCA3E0FDA3E0FEA3E0FF901A0F12" }, +{ 0x40, 0xA0, 0x0854, "18867F007E007D007C00901A0FE0F8A3" }, +{ 0x40, 0xA0, 0x0864, "E0F9A3E0FAA3E0FBD31218625003020A" }, +{ 0x40, 0xA0, 0x0874, "72120D3C901A18EEF0FEA3EFF0FFEF4E" }, +{ 0x40, 0xA0, 0x0884, "7040901B10E0FEA3E0FFEF4E60E3901A" }, +{ 0x40, 0xA0, 0x0894, "03E0FCA3E0FDA3E0FEA3E0FF901A0FE0" }, +{ 0x40, 0xA0, 0x08A4, "F8A3E0F9A3E0FAA3E0FBC3EF9BFFEE9A" }, +{ 0x40, 0xA0, 0x08B4, "FEED99FDEC98FC901A03121886020A72" }, +{ 0x40, 0xA0, 0x08C4, "80AF901A18E0FE" }, +{ 0x40, 0xA0, 0x08CB, "A3E0FFE4FCFD901A0B121886907FE374" }, +{ 0x40, 0xA0, 0x08DB, "7EF0907FE47440F0901A09E0FEA3E0FF" }, +{ 0x40, 0xA0, 0x08EB, "EF20E0030209E2907FE5E0FF901A16EF" }, +{ 0x40, 0xA0, 0x08FB, "F0901A1DE0FEA3E0FFEF64014E600302" }, +{ 0x40, 0xA0, 0x090B, "09BE7B017A1A7916C003C002C001901A" }, +{ 0x40, 0xA0, 0x091B, "1AE0FBA3E0FAA3E0F989828A83D001D0" }, +{ 0x40, 0xA0, 0x092B, "02D0031209338002E473EF4E70030209" }, +{ 0x40, 0xA0, 0x093B, "BE901A03E0FCA3E0FDA3E0FEA3E0FFC0" }, +{ 0x40, 0xA0, 0x094B, "04C005C006C007901A18E0FEA3E0FFE4" }, +{ 0x40, 0xA0, 0x095B, "FCFDA804A905AA06AB07901A0BE0FCA3" }, +{ 0x40, 0xA0, 0x096B, "E0FDA3E0FEA3E0FFC3EF9BFBEE9AFAED" }, +{ 0x40, 0xA0, 0x097B, "99F9EC98F8901A0FE0FCA3E0FDA3E0FE" }, +{ 0x40, 0xA0, 0x098B, "A3E0FFC3EF9BFBEE9AFAED99F9EC98F8" }, +{ 0x40, 0xA0, 0x099B, "D007D006D005D004C3EF9BFFEE9AFEED" }, +{ 0x40, 0xA0, 0x09AB, "99FDEC98FC901A03121886901A1DE4F0" }, +{ 0x40, 0xA0, 0x09BB, "A3E4F0901A19E024FFF0901A18E034FF" }, +{ 0x40, 0xA0, 0x09CB, "F0" }, +{ 0x40, 0xA0, 0x09CC, "901A18E0FEA3E0FFD3EF9400EE940040" }, +{ 0x40, 0xA0, 0x09DC, "030208F28044907FE5E0FF901A13E0FB" }, +{ 0x40, 0xA0, 0x09EC, "A3E0FAA3E0F9EF12183A901A07E0FEA3" }, +{ 0x40, 0xA0, 0x09FC, "E0FF901A14EE8FF012184C901A19E024" }, +{ 0x40, 0xA0, 0x0A0C, "FFF0901A18E034FFF0901A18E0FEA3E0" }, +{ 0x40, 0xA0, 0x0A1C, "FFD3EF9400EE940050BC901A0FE0FCA3" }, +{ 0x40, 0xA0, 0x0A2C, "E0FDA3E0FEA3E0FF901A0BE0F8A3E0F9" }, +{ 0x40, 0xA0, 0x0A3C, "A3E0FAA3E0FBC3EF9BFFEE9AFEED99FD" }, +{ 0x40, 0xA0, 0x0A4C, "EC98FC901A0F121886901A0FE0FCA3E0" }, +{ 0x40, 0xA0, 0x0A5C, "FDA3E0FEA3E0FFEC4D4E4F7003020856" }, +{ 0x40, 0xA0, 0x0A6C, "1207A6020856901A03E0FCA3E0FDA3E0" }, +{ 0x40, 0xA0, 0x0A7C, "FEA3E0FF22" }, +{ 0x40, 0xA0, 0x0A81, "901A1FEBF0A3EAF0A3E9F0901A221218" }, +{ 0x40, 0xA0, 0x0A91, "86901B12E4F0A37401F0901A28E0FEA3" }, +{ 0x40, 0xA0, 0x0AA1, "E0FFEF30E018901A1FE0FBA3E0FAA3E0" }, +{ 0x40, 0xA0, 0x0AB1, "F9901A38EBF0A3EAF0A3E9F08016901A" }, +{ 0x40, 0xA0, 0x0AC1, "1FE0FBA3E0FAA3E0F9901A35EBF0A3EA" }, +{ 0x40, 0xA0, 0x0AD1, "F0A3E9F0901A28E0FEA3E0FFEEFF7E00" }, +{ 0x40, 0xA0, 0x0AE1, "901A34EFF0901A22E0FCA3E0FDA3E0FE" }, +{ 0x40, 0xA0, 0x0AF1, "A3E0FF901A2E1218867F007E007D007C" }, +{ 0x40, 0xA0, 0x0B01, "00901A2EE0F8A3E0F9A3E0FAA3E0FBD3" }, +{ 0x40, 0xA0, 0x0B11, "1218625003020D2D7F407E007D007C00" }, +{ 0x40, 0xA0, 0x0B21, "901A2EE0F8A3E0F9A3E0FAA3E0FBD312" }, +{ 0x40, 0xA0, 0x0B31, "1862400C901A2A121892000000408014" }, +{ 0x40, 0xA0, 0x0B41, "901A2EE0FCA3E0FDA3E0FEA3E0FF901A" }, +{ 0x40, 0xA0, 0x0B51, "2A121886901A2DE0FF901A32EFF0907F" }, +{ 0x40, 0xA0, 0x0B61, "B8E0FFEF30E140901B10E0FEA3E0FFEF" }, +{ 0x40, 0xA0, 0x0B71, "4E60EB901A22E0FCA3E0FDA3E0FEA3E0" }, +{ 0x40, 0xA0, 0x0B81, "FF901A2EE0F8" }, +{ 0x40, 0xA0, 0x0B87, "A3E0F9A3E0FAA3E0FBC3EF9BFFEE9AFE" }, +{ 0x40, 0xA0, 0x0B97, "ED99FDEC98FC901A22121886020D2D80" }, +{ 0x40, 0xA0, 0x0BA7, "B7907FE3747EF0907FE4E4F0901A28E0" }, +{ 0x40, 0xA0, 0x0BB7, "FEA3E0FFEF20E003020CBB7B017A1A79" }, +{ 0x40, 0xA0, 0x0BC7, "33C003C002C001901A38E0FBA3E0FAA3" }, +{ 0x40, 0xA0, 0x0BD7, "E0F989828A83D001D002D003120BE880" }, +{ 0x40, 0xA0, 0x0BE7, "02E473901A3BEEF0FEA3EFF0FFEF4E70" }, +{ 0x40, 0xA0, 0x0BF7, "03020C9B901A3BE0FEA3E0FFEF64024E" }, +{ 0x40, 0xA0, 0x0C07, "7017901A32E0FFE4FCFDFE901A2DE0FE" }, +{ 0x40, 0xA0, 0x0C17, "C3EE9FFF907FB9EFF0901A22E0FCA3E0" }, +{ 0x40, 0xA0, 0x0C27, "FDA3E0FEA3E0FFC004C005C006C00790" }, +{ 0x40, 0xA0, 0x0C37, "1A32E0FFE4FCFDFEA804A905AA06AB07" }, +{ 0x40, 0xA0, 0x0C47, "901A2AE0FCA3E0FDA3E0FEA3E0FFC3EF" }, +{ 0x40, 0xA0, 0x0C57, "9BFBEE9AFAED99F9EC98F8901A2EE0FC" }, +{ 0x40, 0xA0, 0x0C67, "A3E0FDA3E0FEA3E0FFC3EF9BFBEE9AFA" }, +{ 0x40, 0xA0, 0x0C77, "ED99F9EC98" }, +{ 0x40, 0xA0, 0x0C7C, "F8D007D006D005D004C3EF9BFFEE9AFE" }, +{ 0x40, 0xA0, 0x0C8C, "ED99FDEC98FC901A22121886020D2D90" }, +{ 0x40, 0xA0, 0x0C9C, "1A33E0FF907FE5EFF0901A32E014F090" }, +{ 0x40, 0xA0, 0x0CAC, "1A32E0FFEFD394004003020BC2803690" }, +{ 0x40, 0xA0, 0x0CBC, "1A35E0FBA3E0FAA3E0F91217F4FF907F" }, +{ 0x40, 0xA0, 0x0CCC, "E5EFF0901A26E0FEA3E0FF901A36EE8F" }, +{ 0x40, 0xA0, 0x0CDC, "F012184C901A32E014F0901A32E0FFEF" }, +{ 0x40, 0xA0, 0x0CEC, "D3940050CA901A2DE0FF907FB9EFF090" }, +{ 0x40, 0xA0, 0x0CFC, "1A2EE0FCA3E0FDA3E0FEA3E0FF901A2A" }, +{ 0x40, 0xA0, 0x0D0C, "E0F8A3E0F9A3E0FAA3E0FBC3EF9BFFEE" }, +{ 0x40, 0xA0, 0x0D1C, "9AFEED99FDEC98FC901A2E121886020A" }, +{ 0x40, 0xA0, 0x0D2C, "FA901A22E0FCA3E0FDA3E0FEA3E0FF22" }, +{ 0x40, 0xA0, 0x0D3C, "C2AF901B15E0FEA3E0FF8E1D8F1E901B" }, +{ 0x40, 0xA0, 0x0D4C, "15E4F0A3E4F0D2AFAE1DAF1E22" }, +{ 0x40, 0xA0, 0x0D59, "8B268A278928901B12E4F0A37404F0C2" }, +{ 0x40, 0xA0, 0x0D69, "04907FB6E0FFEF30E111901B10E0FEA3" }, +{ 0x40, 0xA0, 0x0D79, "E0FFEF4E60EB020E5680E6901A3EE0FF" }, +{ 0x40, 0xA0, 0x0D89, "907E80EFF0907E81E4F0AB26AA27A928" }, +{ 0x40, 0xA0, 0x0D99, "EA49607AAB26AA27A9281217F4FF907E" }, +{ 0x40, 0xA0, 0x0DA9, "82EFF0AB26AA27A92875820175830012" }, +{ 0x40, 0xA0, 0x0DB9, "180DFF907E83EFF0AB26AA27A9287582" }, +{ 0x40, 0xA0, 0x0DC9, "0275830012180DFF907E84EFF0AB26AA" }, +{ 0x40, 0xA0, 0x0DD9, "27A92875820375830012180DFF907E85" }, +{ 0x40, 0xA0, 0x0DE9, "EFF0AB26AA27A9287582047583001218" }, +{ 0x40, 0xA0, 0x0DF9, "0DFF907E86EFF0AB26AA27A928758205" }, +{ 0x40, 0xA0, 0x0E09, "75830012180DFF907E87EFF0801E907E" }, +{ 0x40, 0xA0, 0x0E19, "82E4F0907E83E4F0907E84E4F0907E85" }, +{ 0x40, 0xA0, 0x0E29, "E4F0907E86E4F0907E87E4F0907FB774" }, +{ 0x40, 0xA0, 0x0E39, "08F0907FB6E0FFEF30E110901B10E0FE" }, +{ 0x40, 0xA0, 0x0E49, "A3E0FFEF4E60EB800480E7D204901B12" }, +{ 0x40, 0xA0, 0x0E59, "E4F0A3E4F0A20422" }, +{ 0x40, 0xA0, 0x0E61, "A2009206A2059200A20622" }, +{ 0x40, 0xA0, 0x0E6C, "A2029208A2079202A20822" }, +{ 0x40, 0xA0, 0x0E77, "A203920AA2099203A20A22" }, +{ 0x40, 0xA0, 0x0E82, "901B12E0FEA3E0FF8E298F2A901B12E4" }, +{ 0x40, 0xA0, 0x0E92, "F0A3E4F0AE29AF2A22" }, +{ 0x40, 0xA0, 0x0E9B, "901B12E0FEA3E0FF8E2B8F2C901B12E4" }, +{ 0x40, 0xA0, 0x0EAB, "F0A37401F0AE2BAF2C22" }, +{ 0x40, 0xA0, 0x0EB5, "901B12E0FEA3E0FF8E2D8F2E901B12E4" }, +{ 0x40, 0xA0, 0x0EC5, "F0A37402F0AE2DAF2E22" }, +{ 0x40, 0xA0, 0x0ECF, "901B12E0FEA3E0FF8E2F8F30901B12E4" }, +{ 0x40, 0xA0, 0x0EDF, "F0A37403F0AE2FAF3022" }, +{ 0x40, 0xA0, 0x0EE9, "901B12E0FEA3E0FF8E318F32901B12E4" }, +{ 0x40, 0xA0, 0x0EF9, "F0A37404F0AE31AF3222" }, +{ 0x40, 0xA0, 0x0F03, "907FDFE0FFEF4402FF907FDFEFF0907F" }, +{ 0x40, 0xA0, 0x0F13, "DEE0FFEF4406FF907FDEEFF0907FAD74" }, +{ 0x40, 0xA0, 0x0F23, "02F0901B147401F0901A4FE4F0C203C2" }, +{ 0x40, 0xA0, 0x0F33, "00C2029078497401F0907FDD7401F090" }, +{ 0x40, 0xA0, 0x0F43, "7FE27440F01212ED22" }, +{ 0x40, 0xA0, 0x0F4C, "901B12E0FEA3E0FFEF64034E70157B01" }, +{ 0x40, 0xA0, 0x0F5C, "7A1A793D1206F8EF4E7008901B12E4F0" }, +{ 0x40, 0xA0, 0x0F6C, "A3E4F022" }, +{ 0x40, 0xA0, 0x0F70, "121339D322" }, +{ 0x40, 0xA0, 0x0F75, "12133BD322" }, +{ 0x40, 0xA0, 0x0F7A, "D322" }, +{ 0x40, 0xA0, 0x0F7C, "907FEAE0FF901B14EFF0D322" }, +{ 0x40, 0xA0, 0x0F88, "901B14E0FF907F00EFF0907FB57401F0" }, +{ 0x40, 0xA0, 0x0F98, "D322" }, +{ 0x40, 0xA0, 0x0F9A, "907FEAE0FF901A4FEFF0D322" }, +{ 0x40, 0xA0, 0x0FA6, "901A4FE0FF907F00EFF0907FB57401F0" }, +{ 0x40, 0xA0, 0x0FB6, "D322" }, +{ 0x40, 0xA0, 0x0FB8, "D322" }, +{ 0x40, 0xA0, 0x0FBA, "D322" }, +{ 0x40, 0xA0, 0x0FBC, "D322" }, +{ 0x40, 0xA0, 0x0FBE, "D322" }, +{ 0x40, 0xA0, 0x0FC0, "C0E0C083C082C085C084C086758600D2" }, +{ 0x40, 0xA0, 0x0FD0, "015391EF907FAB7401F0D086D084D085" }, +{ 0x40, 0xA0, 0x0FE0, "D082D083D0E032" }, +{ 0x40, 0xA0, 0x0FE7, "C0E0C083C082C085C084C08675860053" }, +{ 0x40, 0xA0, 0x0FF7, "91EF907FAB7404F0D086D084D085D082" }, +{ 0x40, 0xA0, 0x1007, "D083D0E032" }, +{ 0x40, 0xA0, 0x100C, "C0E0C083C082C085C084C08675860053" }, +{ 0x40, 0xA0, 0x101C, "91EF907FAB7402F0D086D084D085D082" }, +{ 0x40, 0xA0, 0x102C, "D083D0E032" }, +{ 0x40, 0xA0, 0x1031, "C0E0C083C082C085C084C08675860090" }, +{ 0x40, 0xA0, 0x1041, "7FC7E4F0907FC9E4F0907FCBE4F0907F" }, +{ 0x40, 0xA0, 0x1051, "CDE4F0907FCFE4F0907FD1E4F0907FD3" }, +{ 0x40, 0xA0, 0x1061, "E4F05391EF907FAB7410F0D086D084D0" }, +{ 0x40, 0xA0, 0x1071, "85D082D083D0E032" }, +{ 0x40, 0xA0, 0x1079, "C0E0C083C082C085C084C08675860053" }, +{ 0x40, 0xA0, 0x1089, "91EF907FAB7420F0D086D084D085D082" }, +{ 0x40, 0xA0, 0x1099, "D083D0E032" }, +{ 0x40, 0xA0, 0x109E, "C0E0C083C082C085C084C086758600D2" }, +{ 0x40, 0xA0, 0x10AE, "035391EF907FAB7408F0D086D084D085" }, +{ 0x40, 0xA0, 0x10BE, "D082D083D0E032" }, +{ 0x40, 0xA0, 0x10C5, "32" }, +{ 0x40, 0xA0, 0x10C6, "32" }, +{ 0x40, 0xA0, 0x10C7, "32" }, +{ 0x40, 0xA0, 0x10C8, "C0E0C0F0C083C082C085C084C0867586" }, +{ 0x40, 0xA0, 0x10D8, "00C0D0C000C001C002C003C004C005C0" }, +{ 0x40, 0xA0, 0x10E8, "06C007901B12E0FEA3E0FFEF8EF01218" }, +{ 0x40, 0xA0, 0x10F8, "CF11240000117C000111110002117C00" }, +{ 0x40, 0xA0, 0x1108, "03117C00040000117C907FC7E0FF7E00" }, +{ 0x40, 0xA0, 0x1118, "901B15EEF0A3EFF0805D8058907E40E0" }, +{ 0x40, 0xA0, 0x1128, "FFEFB44011907E42E0FF7E00901B10EE" }, +{ 0x40, 0xA0, 0x1138, "F0A3EFF0803E753300753400C3E53494" }, +{ 0x40, 0xA0, 0x1148, "12E533648094805026AF3474402FF582" }, +{ 0x40, 0xA0, 0x1158, "E4347EF583E0FFAE34743D2EF582E434" }, +{ 0x40, 0xA0, 0x1168, "1AF583EFF00534E5347002053380CD12" }, +{ 0x40, 0xA0, 0x1178, "0ECF80031207A65391EF907FAA7402F0" }, +{ 0x40, 0xA0, 0x1188, "D007D006D005D004D003D002D001D000" }, +{ 0x40, 0xA0, 0x1198, "D0D0D086D084D085D082D083D0F0D0E0" }, +{ 0x40, 0xA0, 0x11A8, "32" }, +{ 0x40, 0xA0, 0x11A9, "32" }, +{ 0x40, 0xA0, 0x11AA, "32" }, +{ 0x40, 0xA0, 0x11AB, "32" }, +{ 0x40, 0xA0, 0x11AC, "32" }, +{ 0x40, 0xA0, 0x11AD, "32" }, +{ 0x40, 0xA0, 0x11AE, "32" }, +{ 0x40, 0xA0, 0x11AF, "32" }, +{ 0x40, 0xA0, 0x11B0, "32" }, +{ 0x40, 0xA0, 0x11B1, "32" }, +{ 0x40, 0xA0, 0x11B2, "32" }, +{ 0x40, 0xA0, 0x11B3, "32" }, +{ 0x40, 0xA0, 0x11B4, "32" }, +{ 0x40, 0xA0, 0x12ED, "90784A7480F0C207120E6CC205120E61" }, +{ 0x40, 0xA0, 0x12FD, "907F9D74FFF0907F977447F0E4907F95" }, +{ 0x40, 0xA0, 0x130D, "F0907F9E74FBF0E4907F93F0907F9C74" }, +{ 0x40, 0xA0, 0x131D, "FFF0D2A0E4FFFE0FBF00010EBE92F8BF" }, +{ 0x40, 0xA0, 0x132D, "48F5C2A0D2A5D2A6D2A7D322" }, +{ 0x40, 0xA0, 0x1339, "D322" }, +{ 0x40, 0xA0, 0x133B, "D322" }, +{ 0x40, 0xA0, 0x133D, "8B498A4A894BE4F54CF54D1207898F51" }, +{ 0x40, 0xA0, 0x134D, "8E508D4F8C4E120789C3EF9551FFEE95" }, +{ 0x40, 0xA0, 0x135D, "50FEED954FFDEC954EFCAB38AA37A936" }, +{ 0x40, 0xA0, 0x136D, "A835C31218625008754C00754D028049" }, +{ 0x40, 0xA0, 0x137D, "30A2D3E4907F9DF0C2A5C2A7D2A7AB49" }, +{ 0x40, 0xA0, 0x138D, "AA4AA94B90000112180D30E717907F9A" }, +{ 0x40, 0xA0, 0x139D, "E0F552E92401F9E43AFA1217F4547F12" }, +{ 0x40, 0xA0, 0x13AD, "183A8097907F9AE0AB49AA4AA94B1218" }, +{ 0x40, 0xA0, 0x13BD, "3AD2A5907F9D74FFF0AE4CAF4D22" }, +{ 0x40, 0xA0, 0x13CB, "E4F54390000D12180DF53990000C1218" }, +{ 0x40, 0xA0, 0x13DB, "0DF53A90000B12180DF53B90000A1218" }, +{ 0x40, 0xA0, 0x13EB, "0DF53CAF3CAE3BAD3AAC398F388E378D" }, +{ 0x40, 0xA0, 0x13FB, "368C3590000512180DF5399000041218" }, +{ 0x40, 0xA0, 0x140B, "0DF53A90000312180DF53B9000021218" }, +{ 0x40, 0xA0, 0x141B, "0DF53C120E9B1207A6753D00753E017B" }, +{ 0x40, 0xA0, 0x142B, "FF7A13793DAF3CAE3BAD3AAC39E4901A" }, +{ 0x40, 0xA0, 0x143B, "26F0A3F0A3E53DF0A3E53EF0120A818F" }, +{ 0x40, 0xA0, 0x144B, "428E418D408C3FAB3CAA3BA93AA839C3" }, +{ 0x40, 0xA0, 0x145B, "1218626036754302854244AF42AE41AD" }, +{ 0x40, 0xA0, 0x146B, "40AC3F78081218738F45AF42AE41AD40" }, +{ 0x40, 0xA0, 0x147B, "AC3F78101218738F46AF42AE41AD40AC" }, +{ 0x40, 0xA0, 0x148B, "3F78181218738F47E4F5487B007A0079" }, +{ 0x40, 0xA0, 0x149B, "43120D59120E821207A67E007F0122" }, +{ 0x40, 0xA0, 0x14AA, "8B478A488949E4F54AF54B1207898F4F" }, +{ 0x40, 0xA0, 0x14BA, "8E4E8D4D8C4C120789C3EF954FFFEE95" }, +{ 0x40, 0xA0, 0x14CA, "4EFEED954DFDEC954CFCAB38AA37A936" }, +{ 0x40, 0xA0, 0x14DA, "A835C31218625008754A00754B018018" }, +{ 0x40, 0xA0, 0x14EA, "30A2D3C2A5C2A6AB47AA48A9491217F4" }, +{ 0x40, 0xA0, 0x14FA, "907F97F0D2A6D2A5AE4AAF4B22" }, +{ 0x40, 0xA0, 0x1507, "E4F53D90000D12180DF53990000C1218" }, +{ 0x40, 0xA0, 0x1517, "0DF53A90000B12180DF53B90000A1218" }, +{ 0x40, 0xA0, 0x1527, "0DF53CAF3CAE3BAD3AAC398F388E378D" }, +{ 0x40, 0xA0, 0x1537, "368C3590000512180DF5399000041218" }, +{ 0x40, 0xA0, 0x1547, "0DF53A90000312180DF53B9000021218" }, +{ 0x40, 0xA0, 0x1557, "0DF53C120EB51207A67BFF7A1479AAAF" }, +{ 0x40, 0xA0, 0x1567, "3CAE3BAD3AAC39E4901A07F0A3F0A3F0" }, +{ 0x40, 0xA0, 0x1577, "A304F01207D48F468E458D448C43AB3C" }, +{ 0x40, 0xA0, 0x1587, "AA3BA93AA839C31218626036753D0185" }, +{ 0x40, 0xA0, 0x1597, "463EAF46AE45AD44AC4378081218738F" }, +{ 0x40, 0xA0, 0x15A7, "3FAF46AE45AD44AC4378101218738F40" }, +{ 0x40, 0xA0, 0x15B7, "AF46AE45AD44AC4378181218738F41E4" }, +{ 0x40, 0xA0, 0x15C7, "F5427B007A00793D120D59120E821207" }, +{ 0x40, 0xA0, 0x15D7, "A67E007F0122" }, +{ 0x40, 0xA0, 0x15DD, "8B398A3A893B1212EDE4F53CFB7A0079" }, +{ 0x40, 0xA0, 0x15ED, "3C120D59120E821207A67E007F0122" }, +{ 0x40, 0xA0, 0x0043, "021600" }, +{ 0x40, 0xA0, 0x1600, "020FC00002100C00020FE70002109E00" }, +{ 0x40, 0xA0, 0x1610, "02103100021079000210C5000210C600" }, +{ 0x40, 0xA0, 0x1620, "0210C7000210C8000211A9000211AA00" }, +{ 0x40, 0xA0, 0x1630, "0211AB000211AC000211AD000211AE00" }, +{ 0x40, 0xA0, 0x1640, "0211AF000211B0000211B1000211B200" }, +{ 0x40, 0xA0, 0x1650, "0211B3000211B400" }, +{ 0x40, 0xA0, 0x1658, "907FD6E030E712E04401F07F147E0012" }, +{ 0x40, 0xA0, 0x1668, "1751907FD6E054FEF022" }, +{ 0x40, 0xA0, 0x1672, "907FD6E04480F0438701000000000022" }, +{ 0x40, 0xA0, 0x1693, "907FD6E04408F0" }, +{ 0x40, 0xA0, 0x169A, "E4F549" }, +{ 0x40, 0xA0, 0x169D, "E054FBF0" }, +{ 0x40, 0xA0, 0x16A1, "E4F549" }, +{ 0x40, 0xA0, 0x16A4, "E04408F0300B04E04402F07FDC7E0512" }, +{ 0x40, 0xA0, 0x16B4, "1751907F92E030E3077FDC7E05121751" }, +{ 0x40, 0xA0, 0x16C4, "907FAB74FFF0907FA9F0907FAAF05391" }, +{ 0x40, 0xA0, 0x16D4, "EF907FD6E054F7F0" }, +{ 0x40, 0xA0, 0x16DC, "E4F549" }, +{ 0x40, 0xA0, 0x16DF, "E04404F022" }, +{ 0x40, 0xA0, 0x16E4, "A907" }, +{ 0x40, 0xA0, 0x16E6, "AE10AF118F828E83A3E064037017AD01" }, +{ 0x40, 0xA0, 0x16F6, "19ED7001228F828E83E07C002FFDEC3E" }, +{ 0x40, 0xA0, 0x1706, "FEAF0580DF7E007F00" }, +{ 0x40, 0xA0, 0x170F, "22" }, +{ 0x40, 0xA0, 0x1710, "AD07" }, +{ 0x40, 0xA0, 0x1712, "E4FCAE0EAF0F8F828E83A3E06402702A" }, +{ 0x40, 0xA0, 0x1722, "AB040CEBB50501228F828E83A3A3E0FA" }, +{ 0x40, 0xA0, 0x1732, "A3E08A54F5556254E5546255E5556254" }, +{ 0x40, 0xA0, 0x1742, "2FFBE5543EFEAF0380CC7E007F00" }, +{ 0x40, 0xA0, 0x1750, "22" }, +{ 0x40, 0xA0, 0x1751, "8E4A8F4BE54B154BAE4A7002154A4E60" }, +{ 0x40, 0xA0, 0x1761, "0512168280EE22" }, +{ 0x40, 0xA0, 0x1682, "7400F58690FDA57C05A3E582458370F9" }, +{ 0x40, 0xA0, 0x1692, "22" }, +{ 0x40, 0xA0, 0x0000, "021768" }, +{ 0x40, 0xA0, 0x1768, "787FE4F6D8FD7581550217AF" }, +{ 0x40, 0xA0, 0x17F4, "BB010689828A83E0225002E722BBFE02" }, +{ 0x40, 0xA0, 0x1804, "E32289828A83E49322" }, +{ 0x40, 0xA0, 0x180D, "BB010CE58229F582E5833AF583E02250" }, +{ 0x40, 0xA0, 0x181D, "06E92582F8E622BBFE06E92582F8E222" }, +{ 0x40, 0xA0, 0x182D, "E58229F582E5833AF583E49322" }, +{ 0x40, 0xA0, 0x183A, "BB010689828A83F0225002F722BBFE01" }, +{ 0x40, 0xA0, 0x184A, "F322" }, +{ 0x40, 0xA0, 0x184C, "C5F0F8A3E028F0C5F0F8E58215827002" }, +{ 0x40, 0xA0, 0x185C, "1583E038F022" }, +{ 0x40, 0xA0, 0x1862, "EB9FF5F0EA9E42F0E99D42F0E89C45F0" }, +{ 0x40, 0xA0, 0x1872, "22" }, +{ 0x40, 0xA0, 0x1873, "E8600FECC313FCED13FDEE13FEEF13FF" }, +{ 0x40, 0xA0, 0x1883, "D8F122" }, +{ 0x40, 0xA0, 0x1886, "ECF0A3EDF0A3EEF0A3EFF022" }, +{ 0x40, 0xA0, 0x1892, "A8828583F0D083D0821218A91218A912" }, +{ 0x40, 0xA0, 0x18A2, "18A91218A9E473E493A3C583C5F0C583" }, +{ 0x40, 0xA0, 0x18B2, "C8C582C8F0A3C583C5F0C583C8C582C8" }, +{ 0x40, 0xA0, 0x18C2, "22" }, +{ 0x40, 0xA0, 0x18C3, "A42582F582E5F03583F58322" }, +{ 0x40, 0xA0, 0x18CF, "D083D082F8E4937012740193700DA3A3" }, +{ 0x40, 0xA0, 0x18DF, "93F8740193F5828883E473740293B5F0" }, +{ 0x40, 0xA0, 0x18EF, "067403936860E9A3A3A3A380D8" }, +{ 0x40, 0xA0, 0x1774, "020469E493A3F8E493A34003F68001F2" }, +{ 0x40, 0xA0, 0x1784, "08DFF48029E493A3F85407240CC8C333" }, +{ 0x40, 0xA0, 0x1794, "C4540F4420C8834004F456800146F6DF" }, +{ 0x40, 0xA0, 0x17A4, "E4800B01020408102040809011B5E47E" }, +{ 0x40, 0xA0, 0x17B4, "019360BCA3FF543F30E509541FFEE493" }, +{ 0x40, 0xA0, 0x17C4, "A360010ECF54C025E060A840B8E493A3" }, +{ 0x40, 0xA0, 0x17D4, "FAE493A3F8E493A3C8C582C8CAC583CA" }, +{ 0x40, 0xA0, 0x17E4, "F0A3C8C582C8CAC583CADFE9DEE780BE" }, +{ 0x40, 0xA0, 0x1288, "00" }, +{ 0x40, 0xA0, 0x7F92, "01" }, +{ 0x40, 0xA0, 0x7F92, "00" }, +{ 0, 0, 0, 0 } +}; diff --git a/src/progs/icd2/base/icd_prog.cpp b/src/progs/icd2/base/icd_prog.cpp new file mode 100644 index 0000000..6fadf06 --- /dev/null +++ b/src/progs/icd2/base/icd_prog.cpp @@ -0,0 +1,39 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "icd_prog.h" + +#include "common/global/pfile.h" +#include "progs/base/prog_config.h" +#include "devices/list/device_list.h" + +bool Icd::ProgrammerBase::doUploadFirmware(PURL::File &file) +{ + const Device::Data &data = *Device::lister().data("16F876"); + Pic::Memory memory(static_cast(data)); + QStringList errors, warnings; + Pic::Memory::WarningTypes warningTypes; + if ( !memory.load(file.stream(), errors, warningTypes, warnings) ) { + log(Log::LineType::Error, i18n("Could not read firmware hex file \"%1\": %2.").arg(file.url().pretty()).arg(errors[0])); + return false; + } + if ( warningTypes!=Pic::Memory::NoWarning ) { + log(Log::LineType::Error, i18n("Firmware hex file seems incompatible with device 16F876 inside ICD.")); + return false; + } + if ( !hardware().uploadFirmware(memory) ) { + log(Log::LineType::Error, i18n("Failed to upload firmware.")); + return false; + } + return true; +} + +bool Icd::ProgrammerBase::readFirmwareVersion() +{ + return hardware().getFirmwareVersion(_firmwareVersion); +} diff --git a/src/progs/icd2/base/icd_prog.h b/src/progs/icd2/base/icd_prog.h new file mode 100644 index 0000000..ba6d9bb --- /dev/null +++ b/src/progs/icd2/base/icd_prog.h @@ -0,0 +1,40 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef ICD_PROG_H +#define ICD_PROG_H + +#include "common/global/global.h" +#include "icd.h" +namespace PURL { class File; } + +namespace Icd +{ +//---------------------------------------------------------------------------- +class ProgrammerBase : public ::Programmer::PicBase +{ +Q_OBJECT +public: + ProgrammerBase(const Programmer::Group &group, const Pic::Data *data, const char *name) + : ::Programmer::PicBase(group, data, name) {} + virtual bool readFirmwareVersion(); + +protected: + Hardware &hardware() { return static_cast(*_hardware); } + virtual bool doUploadFirmware(PURL::File &file); +}; + +//---------------------------------------------------------------------------- +class Group : public ::Programmer::PicGroup +{ +public: +}; + +} // namespace + +#endif diff --git a/src/progs/icd2/base/microchip.cpp b/src/progs/icd2/base/microchip.cpp new file mode 100644 index 0000000..b5229f6 --- /dev/null +++ b/src/progs/icd2/base/microchip.cpp @@ -0,0 +1,11 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "microchip.h" + +const uint Microchip::VENDOR_ID = 0x04d8; diff --git a/src/progs/icd2/base/microchip.h b/src/progs/icd2/base/microchip.h new file mode 100644 index 0000000..627b2ad --- /dev/null +++ b/src/progs/icd2/base/microchip.h @@ -0,0 +1,19 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef MICROCHIP_H +#define MICROCHIP_H + +#include + +namespace Microchip +{ + extern const uint VENDOR_ID; +} // namespace + +#endif diff --git a/src/progs/icd2/base/promate2.xml b/src/progs/icd2/base/promate2.xml new file mode 100644 index 0000000..9e85009 --- /dev/null +++ b/src/progs/icd2/base/promate2.xml @@ -0,0 +1,235 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/progs/icd2/gui/Makefile.am b/src/progs/icd2/gui/Makefile.am new file mode 100644 index 0000000..df597a0 --- /dev/null +++ b/src/progs/icd2/gui/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +libicd2ui_la_LDFLAGS = $(all_libraries) +noinst_LTLIBRARIES = libicd2ui.la + +libicd2ui_la_SOURCES = icd2_group_ui.cpp diff --git a/src/progs/icd2/gui/icd2_group_ui.cpp b/src/progs/icd2/gui/icd2_group_ui.cpp new file mode 100644 index 0000000..6f00788 --- /dev/null +++ b/src/progs/icd2/gui/icd2_group_ui.cpp @@ -0,0 +1,81 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "icd2_group_ui.h" + +#include "common/gui/misc_gui.h" +#include "progs/gui/prog_config_widget.h" +#include "progs/base/prog_group.h" +#include "progs/icd2/base/icd2_debug.h" + +//---------------------------------------------------------------------------- +Icd2::AdvancedDialog::AdvancedDialog(ProgrammerBase &base, QWidget *parent) + : ::Programmer::PicAdvancedDialog(base, parent, "icd2_advanced_dialog") +{ + uint row = _firmwareContainer->numRows(); + QLabel *label = new QLabel(i18n("Id:"), _firmwareContainer); + _firmwareContainer->addWidget(label, row,row, 0,0); + _firmwareIdLabel = new QLabel(_firmwareContainer); + _firmwareContainer->addWidget(_firmwareIdLabel, row,row, 1,1); + row++; + + row = _programmerContainer->numRows(); + if ( base.group().properties() & ::Programmer::Debugger ) { + ButtonContainer *container = new ::Programmer::ButtonContainer(i18n("Debug Executive"), this, SLOT(updateDebugExecutive()), _programmerContainer); + _programmerContainer->addWidget(container, row,row, 0,1); + label = new QLabel(i18n("Version:"), container); + container->addWidget(label, 1,1, 0,0); + _debugExecLabel = new QLabel(container); + container->addWidget(_debugExecLabel, 1,1, 1,1); + row++; + } else _debugExecLabel = 0; + + for (uint i=0; iaddWidget(label, 1+i,1+i, 0,0); + _tests[i] = new QLabel(_selfTestContainer); + _selfTestContainer->addWidget(_tests[i], 1+i,1+i, 1,1); + } +} + +void Icd2::AdvancedDialog::updateDebugExecutive() +{ + ::BusyCursor bc; + if ( ensureConnected() ) { + Pic::TargetMode mode; + if ( !base().getTargetMode(mode) ) return; + if ( mode==Pic::TargetInProgramming ) + MessageBox::sorry(i18n("You need to initiate debugging to read the debug executive version."), Log::Show); + else static_cast(base()).readDebugExecutiveVersion(); + } + updateDisplay(); +} + +void Icd2::AdvancedDialog::updateDisplay() +{ + ::Programmer::PicAdvancedDialog::updateDisplay(); + uchar id = base().firmwareId(); + _firmwareIdLabel->setText(id==0 ? "---" : toHexLabel(id, 2)); + if (_debugExecLabel) { + const VersionData &vd = static_cast(base()).debugExecutiveVersion(); + _debugExecLabel->setText(vd.isValid() ? vd.pretty() : "---"); + } + for (uint i=0; isetText(base().testData().result(TestData::VoltageType(i))); +} + +//---------------------------------------------------------------------------- +::Programmer::ConfigWidget *Icd2::GroupUI::createConfigWidget(QWidget *parent) const +{ + return new ::Programmer::ConfigWidget(static_cast(group()), parent); +} + +::Programmer::AdvancedDialog *Icd2::GroupUI::createAdvancedDialog(::Programmer::Base &base, QWidget *parent) const +{ + return new AdvancedDialog(static_cast(base), parent); +} diff --git a/src/progs/icd2/gui/icd2_group_ui.h b/src/progs/icd2/gui/icd2_group_ui.h new file mode 100644 index 0000000..93d66e7 --- /dev/null +++ b/src/progs/icd2/gui/icd2_group_ui.h @@ -0,0 +1,48 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef ICD2_GROUP_UI_H +#define ICD2_GROUP_UI_H + +#include "devices/pic/gui/pic_prog_group_ui.h" +#include "progs/icd2/base/icd2_prog.h" + +namespace Icd2 +{ +class ProgrammerBase; +class Group; + +//---------------------------------------------------------------------------- +class AdvancedDialog : public ::Programmer::PicAdvancedDialog +{ +Q_OBJECT +public: + AdvancedDialog(ProgrammerBase &base, QWidget *parent); + virtual void updateDisplay(); + +private slots: + void updateDebugExecutive(); + +private: + QLabel *_firmwareIdLabel, *_debugExecLabel; + QLabel *_tests[TestData::Nb_VoltageTypes]; + ProgrammerBase &base() { return static_cast(_base); } +}; + +//---------------------------------------------------------------------------- +class GroupUI : public ::Programmer::GroupUI +{ +public: + virtual ::Programmer::ConfigWidget *createConfigWidget(QWidget *parent) const; + virtual bool hasAdvancedDialog() const { return true; } + virtual ::Programmer::AdvancedDialog *createAdvancedDialog(::Programmer::Base &base, QWidget *parent) const; +}; + +} // namespace + +#endif diff --git a/src/progs/icd2/icd2.pro b/src/progs/icd2/icd2.pro new file mode 100644 index 0000000..a67dbb2 --- /dev/null +++ b/src/progs/icd2/icd2.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = icd2_data xml base diff --git a/src/progs/icd2/icd2_data/Makefile.am b/src/progs/icd2/icd2_data/Makefile.am new file mode 100644 index 0000000..4c5b34e --- /dev/null +++ b/src/progs/icd2/icd2_data/Makefile.am @@ -0,0 +1,5 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +libicd2data_la_LDFLAGS = -no-undefined $(all_libraries) +noinst_LTLIBRARIES = libicd2data.la +libicd2data_la_SOURCES = icd2_data.cpp diff --git a/src/progs/icd2/icd2_data/icd2_data.cpp b/src/progs/icd2/icd2_data/icd2_data.cpp new file mode 100644 index 0000000..ba3f5ce --- /dev/null +++ b/src/progs/icd2/icd2_data/icd2_data.cpp @@ -0,0 +1,84 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * Copyright (C) 2002-2003 Stephen Landamore * + * * + * 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. * + ***************************************************************************/ +#include "progs/icd2/base/icd2_data.h" + +const Icd2::FirmwareVersionData Icd2::MIN_VERSION_DATA = { + 7, 21, // MPLAB 7.21 + {{ 2, 6, 5 }, // 01 + { 0, 0, 0 }, // 02 [none] + { 0, 0, 0 }, // 03 [none] + { 2, 6, 6 }, // 04 + { 1, 2, 5 }, // 05 + { 1, 2, 2 }, // 06 + { 1, 2, 9 }, // 07 + { 1, 3, 4 }, // 08 + { 1, 0, 0 }, // 09 + { 1, 3, 1 }, // 10 + { 0, 0, 27 }, // 11 + { 1, 2, 0 }, // 12 + { 0, 0, 0 }, // 13 [none] + { 0, 0, 0 }, // 14 + { 0, 0, 0 }} // 15 +}; + +const Icd2::FirmwareVersionData Icd2::MAX_VERSION_DATA = { + 7, 41, // MPLAB 7.41 + {{ 2, 7, 0 }, // 01 + { 0, 0, 0 }, // 02 [none] + { 0, 0, 0 }, // 03 [none] + { 2, 6, 8 }, // 04 + { 1, 3, 9 }, // 05 + { 1, 2, 2 }, // 06 + { 1, 4, 0 }, // 07 + { 1, 5, 0 }, // 08 + { 1, 0, 0 }, // 09 + { 1, 4, 4 }, // 10 + { 1, 0, 4 }, // 11 + { 1, 2, 0 }, // 12 + { 0, 0, 0 }, // 13 [none] + { 2, 0, 6 }, // 14 + { 1, 1, 0 }} // 15 +}; + +const Icd2::FamilyData Icd2::FAMILY_DATA[] = { + { "12F629", 1, "12F629", 0x0300, 0x0DF, 0x0DE, 0x0D4/*?*/ }, // 12F629/675 + { "16F676", 1, "16F676", 0x0300, 0x0DF, 0x0DE, 0x0D4/*?*/ }, // 16F630/676 + { "16F648A", 1, "16F648A", 0x0F00, 0x16F, 0x16E, 0x1F0/*?*/ }, // 16F627A/628A/648A + { "16F716", 1, "16F716", 0x0700, 0x06F, 0x06E, 0x0F0/*?*/ }, + { "16F7X7", 1, "16F7X7", 0x1F00, 0x16F, 0x16E, 0x1F0/*?*/ }, // 16F737/747/767/777 + { "16F819", 1, "16F819", 0x0700, 0x16F, 0x16E, 0x1F0/*?*/ }, // 16F818/819 + { "16F88", 1, "16F88", 0x0F00, 0x1EF, 0x1EE, 0x1F0/*?*/ }, // 16F87/88 + { "16F872", 1, "16F872", 0x0700, 0x1BF, 0x1BE, 0x1F0 }, // 16F870/871/872 + { "16F874", 1, "16F874", 0x0F00, 0x1FF, 0x1FE, 0x17F/*?*/ }, // 16F873/873A/874/874A + { "16F877", 1, "16F877", 0x1F00, 0x1EF, 0x1EE, 0x1F0/*?*/ }, // 16F876/876A/877/877A + { "16F7X", 1, 0, 0, 0, 0, 0 }, // 16F73 + { 0, 2, 0, 0, 0, 0, 0 }, // 30F for revision A2 (legacy: not in MPLAB 7) + { 0, 3, "30F", 0, 0, 0, 0 }, // 30F for revision A3/B0 (legacy: not in MPLAB 7) + { "18F_4", 4, "", 0, 0, 0, 0 }, // debug executive filename is computed at runtime + { "18F_5", 5, "", 0, 0, 0, 0 }, // debug executive filename is computed at runtime + { "18CX01", 6, 0,/*"18CX01"*/0, 0, 0, 0 }, // 16C601/801 + { "10F2XX", 7, 0, 0, 0, 0, 0 }, + { "16F5X", 7, 0, 0, 0, 0, 0 }, // 16F505/506 + { "12F635", 8, "12F635", 0x0700, 0x06F, 0x06E, 0x0F0/*?*/ }, // 12F635/683 16F636/639 + { "16F785", 8, "16F916", 0x0700, 0x06F, 0x06E, 0x1F0/*?*/ }, // 16F785 + { "16F916", 8, "16F916", 0x1F00, 0x16F, 0x16E, 0x1F0/*?*/ }, // 16F913/914/916/917/946 + { "16F684", 8, "16F684", 0x0700, 0x16F, 0x16E, 0x1F0/*?*/ }, // 16F684 + { "16F688", 8, "16F688", 0x0F00, 0x16F, 0x16E, 0x1F0/*?*/ }, // 16F685/687/688/689/690 + { "16F677", 8, 0, 0, 0, 0, 0 }, // 16F677 + { "16F629", 9, 0, 0, 0, 0, 0 }, // 16F629 + { "30F", 10, 0/*"30F_REVB"*/,0, 0, 0, 0 }, // 30F revision B1 and above + { "18F_J", 11, 0, 0, 0, 0, 0 }, // 18FXXJXX (?) + { "16F72", 12, 0, 0, 0, 0, 0 }, // 16F72/8X/627/628/84A + { "24F", 14, 0/*"24F"*/,0, 0, 0, 0 }, // from MPLAB 7.3 + { "33F", 14, 0/*"33F"*/,0, 0, 0, 0 }, // from MPLAB 7.3 + { "16F61X", 15, 0, 0, 0, 0, 0 }, // 12F61X/16F61X + + { 0, 0, 0, 0, 0, 0, 0 } +}; diff --git a/src/progs/icd2/icd2_data/icd2_data.pro b/src/progs/icd2/icd2_data/icd2_data.pro new file mode 100644 index 0000000..e53d0ab --- /dev/null +++ b/src/progs/icd2/icd2_data/icd2_data.pro @@ -0,0 +1,5 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/lib.pro) + +TARGET = icd2data +SOURCES += icd2_data.cpp diff --git a/src/progs/icd2/xml/Makefile.am b/src/progs/icd2/xml/Makefile.am new file mode 100644 index 0000000..52af4ee --- /dev/null +++ b/src/progs/icd2/xml/Makefile.am @@ -0,0 +1,15 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_PROGRAMS = xml_icd2_parser +xml_icd2_parser_SOURCES = xml_icd2_parser.cpp +OBJECTS = $(top_builddir)/src/progs/icd2/icd2_data/libicd2data.la \ + $(top_builddir)/src/devices/list/libdevicelistnoui.la \ + $(top_builddir)/src/devices/pic/pic/libpic.la $(top_builddir)/src/devices/pic/base/libpicbase.la \ + $(top_builddir)/src/devices/pic/xml_data/libpicxml.la \ + $(top_builddir)/src/devices/mem24/mem24/libmem24.la $(top_builddir)/src/devices/mem24/base/libmem24base.la \ + $(top_builddir)/src/devices/mem24/xml_data/libmem24xml.la \ + $(top_builddir)/src/xml_to_data/libxmltodata.la $(top_builddir)/src/devices/base/libdevicebase.la \ + $(top_builddir)/src/common/common/libcommon.la +xml_icd2_parser_DEPENDENCIES = $(OBJECTS) +xml_icd2_parser_LDADD = $(OBJECTS) $(LIB_KDECORE) diff --git a/src/progs/icd2/xml/xml.pro b/src/progs/icd2/xml/xml.pro new file mode 100644 index 0000000..a9a5d97 --- /dev/null +++ b/src/progs/icd2/xml/xml.pro @@ -0,0 +1,17 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/app.pro) + +TARGET = xml_icd2_parser +SOURCES += xml_icd2_parser.cpp +LIBS += ../icd2_data/libicd2data.a ../../../devices/list/libdevicelist.a \ + ../../../devices/mem24/mem24/libmem24.a ../../../devices/mem24/xml_data/libmem24xml.a \ + ../../../devices/mem24/base/libmem24base.a \ + ../../../devices/pic/pic/libpic.a ../../../devices/pic/xml_data/libpicxml.a \ + ../../../devices/pic/base/libpicbase.a ../../../xml_to_data/libxmltodata.a \ + ../../../devices/base/libdevicebase.a ../../../common/global/libglobal.a \ + ../../../common/nokde/libnokde.a ../../../common/common/libcommon.a + +unix:QMAKE_POST_LINK = cd ../base && ../xml/xml_icd2_parser +unix:QMAKE_CLEAN += ../base/icd2_data.cpp +win32:QMAKE_POST_LINK = cd ..\base && ..\xml\xml_icd2_parser.exe +win32:QMAKE_CLEAN += ..\base\icd2_data.cpp diff --git a/src/progs/icd2/xml/xml_icd2_parser.cpp b/src/progs/icd2/xml/xml_icd2_parser.cpp new file mode 100644 index 0000000..7ce2ad9 --- /dev/null +++ b/src/progs/icd2/xml/xml_icd2_parser.cpp @@ -0,0 +1,53 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "xml_to_data/prog_xml_to_data.h" +#include "progs/icd2/base/icd2_data.h" + +//----------------------------------------------------------------------------- +namespace Icd2 +{ + +class XmlToData : public Programmer::XmlToData +{ +public: + XmlToData() : Programmer::XmlToData("icd2", "Icd2") {} + +private: + virtual uint familyIndex(const QString &family) const; + virtual void parseData(QDomElement element, Data &data); + virtual void outputData(const Data &data, QTextStream &s) const; +}; + +uint Icd2::XmlToData::familyIndex(const QString &family) const +{ + uint i = 0; + for (; Icd2::FAMILY_DATA[i].efid!=0; i++) + if ( family==Icd2::FAMILY_DATA[i].name ) break; + if ( Icd2::FAMILY_DATA[i].efid==0 ) qFatal(QString("Family \"%1\" is unknown").arg(family)); + return i; +} + +void Icd2::XmlToData::parseData(QDomElement element, Data &data) +{ + bool ok; + data.famid = fromHexLabel(element.attribute("famid"), 2, &ok); + if ( !ok ) qFatal("Missing or malformed famid attribute"); + data.debugSupport = extractSupport(element.attribute("debug_support_type")); +} + +void Icd2::XmlToData::outputData(const Data &data, QTextStream &s) const +{ + s << toHexLabel(data.famid, 2) << ", "; + s << "::Group::Support::Type(" << data.debugSupport.type() << ")"; +} + +} // namespace + +//----------------------------------------------------------------------------- +XML_MAIN(Icd2::XmlToData) diff --git a/src/progs/list/Makefile.am b/src/progs/list/Makefile.am new file mode 100644 index 0000000..9cc833f --- /dev/null +++ b/src/progs/list/Makefile.am @@ -0,0 +1,8 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libproglistui.la libproglistnoui.la +libproglistui_la_LDFLAGS = $(all_libraries) +libproglistui_la_SOURCES = prog_list.cpp prog_list_ui.cpp +libproglistnoui_la_LDFLAGS = $(all_libraries) +libproglistnoui_la_SOURCES = prog_list.cpp prog_list_noui.cpp diff --git a/src/progs/list/list.pro b/src/progs/list/list.pro new file mode 100644 index 0000000..d6711fd --- /dev/null +++ b/src/progs/list/list.pro @@ -0,0 +1,6 @@ +STOPDIR = ../../.. +include($${STOPDIR}/lib.pro) + +TARGET = progslist +HEADERS += prog_list.h +SOURCES += prog_list.cpp prog_list_noui.cpp diff --git a/src/progs/list/prog_list.cpp b/src/progs/list/prog_list.cpp new file mode 100644 index 0000000..eb69472 --- /dev/null +++ b/src/progs/list/prog_list.cpp @@ -0,0 +1,15 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "prog_list.h" + +namespace Programmer +{ + Lister _lister; + const Lister &lister() { return _lister; } +} diff --git a/src/progs/list/prog_list.h b/src/progs/list/prog_list.h new file mode 100644 index 0000000..204fbaa --- /dev/null +++ b/src/progs/list/prog_list.h @@ -0,0 +1,28 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PROG_LIST_H +#define PROG_LIST_H + +#include "common/common/lister.h" +#include "progs/base/prog_group.h" + +namespace Programmer +{ + +class Lister : public ::Group::Lister +{ +public: + Lister(); + const Group &defaultGroup(Property property); +}; +extern const Lister &lister(); + +} // namespace + +#endif diff --git a/src/progs/list/prog_list_noui.cpp b/src/progs/list/prog_list_noui.cpp new file mode 100644 index 0000000..f7ec669 --- /dev/null +++ b/src/progs/list/prog_list_noui.cpp @@ -0,0 +1,38 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "prog_list.h" + +#include "progs/direct/base/direct_prog.h" +#include "progs/icd2/base/icd2_prog.h" +#include "progs/icd2/base/icd2_debug.h" +#include "progs/icd1/base/icd1_prog.h" +#include "progs/pickit2/base/pickit2_prog.h" +#include "progs/pickit1/base/pickit1_prog.h" +#include "progs/psp/base/psp_prog.h" +#include "progs/gpsim/base/gpsim_debug.h" +#include "progs/picdem_bootloader/base/picdem_bootloader_prog.h" +#include "progs/pickit2_bootloader/base/pickit2_bootloader_prog.h" +#include "progs/tbl_bootloader/base/tbl_bootloader_prog.h" +#include "progs/pickit2v2/base/pickit2v2_prog.h" + +Programmer::Lister::Lister() +{ + addGroup(new Direct::DGroup, 0); + addGroup(new Icd2::ProgrammerGroup, 0); + addGroup(new Icd2::DebuggerGroup, 0); + addGroup(new Icd1::Group, 0); + addGroup(new Pickit2::Group, 0); + //addGroup(new Pickit2V2::Group, 0); + addGroup(new Pickit1::Group, 0); + addGroup(new Psp::Group, 0); + addGroup(new GPSim::Group, 0); + addGroup(new PicdemBootloader::Group, 0); + addGroup(new Pickit2Bootloader::Group, 0); + addGroup(new TinyBootloader::Group, 0); +} diff --git a/src/progs/list/prog_list_ui.cpp b/src/progs/list/prog_list_ui.cpp new file mode 100644 index 0000000..6f57a42 --- /dev/null +++ b/src/progs/list/prog_list_ui.cpp @@ -0,0 +1,49 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "prog_list.h" + +#include "progs/direct/base/direct_prog.h" +#include "progs/direct/gui/direct_config_widget.h" +#include "progs/icd2/base/icd2_prog.h" +#include "progs/icd2/base/icd2_debug.h" +#include "progs/icd2/gui/icd2_group_ui.h" +#include "progs/icd1/base/icd1_prog.h" +#include "progs/icd1/gui/icd1_group_ui.h" +#include "progs/pickit2/base/pickit2_prog.h" +#include "progs/pickit2/gui/pickit2_group_ui.h" +#include "progs/pickit2v2/base/pickit2v2_prog.h" +#include "progs/pickit2v2/gui/pickit2v2_group_ui.h" +#include "progs/pickit1/base/pickit1_prog.h" +#include "progs/pickit1/gui/pickit1_group_ui.h" +#include "progs/psp/base/psp_prog.h" +#include "progs/psp/gui/psp_group_ui.h" +#include "progs/gpsim/base/gpsim_debug.h" +#include "progs/gpsim/gui/gpsim_group_ui.h" +#include "progs/picdem_bootloader/base/picdem_bootloader_prog.h" +#include "progs/picdem_bootloader/gui/picdem_bootloader_ui.h" +#include "progs/pickit2_bootloader/base/pickit2_bootloader_prog.h" +#include "progs/pickit2_bootloader/gui/pickit2_bootloader_ui.h" +#include "progs/tbl_bootloader/base/tbl_bootloader_prog.h" +#include "progs/tbl_bootloader/gui/tbl_bootloader_ui.h" + +Programmer::Lister::Lister() +{ + addGroup(new Direct::DGroup, new Direct::GroupUI); + addGroup(new Icd2::ProgrammerGroup, new Icd2::GroupUI); + addGroup(new Icd2::DebuggerGroup, new Icd2::GroupUI); + addGroup(new Icd1::Group, new Icd1::GroupUI); + addGroup(new Pickit2::Group, new Pickit2::GroupUI); + //addGroup(new Pickit2V2::Group, new Pickit2V2::GroupUI); + addGroup(new Pickit1::Group, new Pickit1::GroupUI); + addGroup(new Psp::Group, new Psp::GroupUI); + addGroup(new GPSim::Group, new GPSim::GroupUI); + addGroup(new PicdemBootloader::Group, new PicdemBootloader::GroupUI); + addGroup(new Pickit2Bootloader::Group, new Pickit2Bootloader::GroupUI); + addGroup(new TinyBootloader::Group, new TinyBootloader::GroupUI); +} diff --git a/src/progs/manager/Makefile.am b/src/progs/manager/Makefile.am new file mode 100644 index 0000000..565dae5 --- /dev/null +++ b/src/progs/manager/Makefile.am @@ -0,0 +1,5 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +libprogmanager_la_LDFLAGS = $(all_libraries) +noinst_LTLIBRARIES = libprogmanager.la +libprogmanager_la_SOURCES = breakpoint.cpp debug_manager.cpp prog_manager.cpp diff --git a/src/progs/manager/breakpoint.cpp b/src/progs/manager/breakpoint.cpp new file mode 100644 index 0000000..15e08e0 --- /dev/null +++ b/src/progs/manager/breakpoint.cpp @@ -0,0 +1,74 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "breakpoint.h" + +#include "coff/base/coff.h" + +//---------------------------------------------------------------------------- +namespace Breakpoint +{ + List *_list = 0; +} +Breakpoint::List &Breakpoint::list() +{ + if ( _list==0 ) _list = new List; + return *_list; +} + +void Breakpoint::List::append(const Data &data) +{ + Q_ASSERT( !contains(data) ); + StateData sdata; + sdata.data = data; + _list.append(sdata); + delayedChanged(); +} + +void Breakpoint::List::remove(const Data &data) +{ + Q_ASSERT( contains(data) ); + _list.remove(find(data)); + delayedChanged(); +} + +void Breakpoint::List::clear() +{ + _list.clear(); + delayedChanged(); +} + +QValueList::iterator Breakpoint::List::find(const Data &data) +{ + QValueList::iterator it; + for (it=_list.begin(); it!=_list.end(); ++it) + if ( (*it).data==data ) return it; + return _list.end(); +} + +QValueList::const_iterator Breakpoint::List::find(const Data &data) const +{ + QValueList::const_iterator it; + for (it=_list.begin(); it!=_list.end(); ++it) + if ( (*it).data==data ) return it; + return _list.end(); +} + +void Breakpoint::List::setState(const Data &data, State state) +{ + Q_ASSERT( contains(data) ); + (*find(data)).state = state; + delayedChanged(); +} + +void Breakpoint::List::setAddress(const Data &data, Address address) +{ + Q_ASSERT( contains(data) ); + (*find(data)).address = address; + delayedChanged(); +} diff --git a/src/progs/manager/breakpoint.h b/src/progs/manager/breakpoint.h new file mode 100644 index 0000000..fca0570 --- /dev/null +++ b/src/progs/manager/breakpoint.h @@ -0,0 +1,70 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef BREAKPOINT_H +#define BREAKPOINT_H + +#include "common/common/storage.h" +#include "common/global/purl.h" +#include "devices/base/generic_device.h" + +namespace Breakpoint +{ +class List; +enum State { Unknown, Active, Disabled }; +enum MarkType { ProgramCounterActive = 0, ProgramCounterDisabled, + BreakpointActive, BreakpointDisabled, BreakpointReached, + BreakpointInvalid, Nb_MarkTypes }; + +//---------------------------------------------------------------------------- +class Data { +public: + Data(const PURL::Url &purl = PURL::Url(), uint pline = 0) : url(purl), line(pline) {} + bool operator <(const Data &data) const { return ( url _list; + QValueList::const_iterator find(const Data &data) const; + QValueList::iterator find(const Data &data); +}; + +} // namespace + +#endif diff --git a/src/progs/manager/debug_manager.cpp b/src/progs/manager/debug_manager.cpp new file mode 100644 index 0000000..7889432 --- /dev/null +++ b/src/progs/manager/debug_manager.cpp @@ -0,0 +1,392 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "debug_manager.h" + +#include +#include + +#include "coff/base/text_coff.h" +#include "coff/base/cdb_parser.h" +#include "progs/base/generic_prog.h" +#include "progs/base/generic_debug.h" +#include "progs/base/prog_group.h" +#include "devices/base/register.h" +#include "progs/base/debug_config.h" +#include "prog_manager.h" + +Debugger::Manager *Debugger::manager = 0; + +Debugger::Manager::Manager() + : QObject(Programmer::manager, "debug_manager"), Log::Base(Programmer::manager), GenericView(Breakpoint::list()), + _coff(0), _data(0) +{ + connect(&_runTimer, SIGNAL(timeout()), SLOT(slotRunTimeout())); + connect(&_stepTimer, SIGNAL(timeout()), SLOT(doStep())); +} + +Debugger::Manager::~Manager() +{ + delete _coff; +} + +bool Debugger::Manager::isStepping() const +{ + return (programmer() ? programmer()->state()==Programmer::Halted : false) && _stepTimer.isActive(); +} + +Debugger::Base *Debugger::Manager::debugger() const +{ + return (programmer() ? programmer()->debugger() : 0); +} + +void Debugger::Manager::updateDevice() +{ + const Device::Data *data = deviceData(); + if ( data==_data ) return; + _data = data; + Register::list().clearWatched(); + clear(); +} + +bool Debugger::Manager::checkState(bool &first) +{ + if ( programmer()->state()==Programmer::NotConnected ) { + if ( !prepareDebugging() ) return false; + if ( !programmer()->connectHardware() ) return false; + } + first = ( debugger()->hasError() || programmer()->state()==Programmer::Stopped ); + if (first) { + log(Log::LineType::Normal, "--------------------------------------------------"); + programmer()->debugger()->setCoff(_coff); + if ( !programmer()->debugger()->init() ) return false; + } + return true; +} + +bool Debugger::Manager::init() +{ + if ( !internalInit() ) return false; + return update(true); +} + +bool Debugger::Manager::internalInit() +{ + clear(); + if ( !coffUrl().exists() ) return false; + Log::Base log; + log.setView(compileView()); + log.log(Log::LineType::Information, i18n("Parsing COFF file: %1").arg(coffUrl().pretty())); + _coff = new Coff::TextObject(_data, coffUrl()); + if ( !_coff->parse(log) ) { + delete _coff; + _coff = 0; + return false; + } + computeBreakpointAddresses(); + return true; +} + +void Debugger::Manager::clearBreakpoints() +{ + Breakpoint::list().clear(); +} + +void Debugger::Manager::freeActiveBreakpoint() +{ + uint nb = 0; + Breakpoint::Data last; + for (uint i=0; imaxNbBreakpoints(deviceData()); + Q_ASSERT( nb<=max && max!=0 ); + if ( nb==max ) { + log(Log::LineType::Warning, i18n("The number of active breakpoints is higher than the maximum for the current debugger (%1): disabling the last breakpoint.").arg(max)); + Breakpoint::list().setState(last, Breakpoint::Disabled); + } +} + +BitValue Debugger::Manager::pc() const +{ + return (debugger() ? debugger()->pc() : BitValue()); +} + +Breakpoint::MarkType Debugger::Manager::breakpointType(const Breakpoint::Data &data) const +{ + if ( _coff==0 ) return Breakpoint::BreakpointDisabled; + Address address = Breakpoint::list().address(data); + if ( !address.isValid() ) return Breakpoint::BreakpointInvalid; + if ( Breakpoint::list().state(data)!=Breakpoint::Active ) return Breakpoint::BreakpointDisabled; + if ( address==pc() ) { + if ( programmer()->state()==::Programmer::Halted ) return Breakpoint::BreakpointReached; + return Breakpoint::ProgramCounterDisabled; + } + return Breakpoint::BreakpointActive; +} + +bool Debugger::Manager::checkBreakpoint(const Breakpoint::Data &bdata, bool onlyWarn, Address &address) +{ + address = Address(); + if ( _coff==0 ) return true; + QValueVector
addresses = _coff->addresses(bdata.url, bdata.line); + if ( addresses.isEmpty() ) { + QString s = i18n("Breakpoint at non-code line."); + if (onlyWarn) log(Log::LineType::Warning, s); + else sorry(s); + return false; + } + if ( addresses.count()>1 ) log(Log::LineType::Warning, i18n("Breakpoint corresponds to several addresses. Using the first one.")); + address = addresses[0]; + return true; +} + +void Debugger::Manager::computeBreakpointAddresses() +{ + if ( programmerGroup()==0 ) return; + int nb = programmerGroup()->maxNbBreakpoints(deviceData()); + for (int i=Breakpoint::list().count()-1; i>=0; i--) { + const Breakpoint::Data &data = Breakpoint::list().data(i); + Address address; + checkBreakpoint(data, true, address); + Breakpoint::list().setAddress(data, address); + if ( _coff==0 ) Breakpoint::list().setState(data, Breakpoint::Unknown); + else if ( Breakpoint::list().address(data).isValid() && nb>0 ) { + Breakpoint::list().setState(data, Breakpoint::Active); + nb--; + } + } +} + +QValueList
Debugger::Manager::activeBreakpointAddresses() const +{ + QValueList
addresses; + for (uint i=0; iclear(); + delete _coff; + _coff = 0; + _currentSourceLines.clear(); + computeBreakpointAddresses(); + update(true); +} + +bool Debugger::Manager::update(bool gotoPC) +{ + _readRegisters.clear(); + if ( !updateRegisters() ) return false; + if ( debugger() ) emit statusChanged(debugger()->statusString()); + else emit statusChanged(QString::null); + _currentSourceLines.clear(); + if (_coff) _currentSourceLines = _coff->sourceLinesForAddress(pc().toUInt()); + updateView(gotoPC); + return true; +} + +bool Debugger::Manager::updateRegister(const Register::TypeData &data) +{ + // read related registers + const Device::RegistersData *rdata = deviceData()->registersData(); + Q_ASSERT(rdata); + QValueList related = rdata->relatedRegisters(data); + for (uint k=0; kportIndex(data.address()); + if ( index!=-1 ) { + QMap data; + if ( !debugger()->updatePortStatus(index, data) ) return false; + Register::list().setPortData(index, data); + } + } + return true; +} + +bool Debugger::Manager::updateRegisters() +{ + if ( programmer()==0 || programmer()->state()!=Programmer::Halted ) return true; + QValueList watched = Register::list().watched(); + for (uint i=0; isetBreakpoints(activeBreakpointAddresses()) ) return false; + if ( !debugger()->run() ) return false; + log(Log::LineType::Information, i18n("Running...")); + if ( !update(true) ) return false; + _runTimer.start(programmer()->runUpdateWait()); + return true; +} + +bool Debugger::Manager::halt() +{ + _stepTimer.stop(); + _runTimer.stop(); + if ( !debugger()->halt() ) return false; + return update(true); +} + +bool Debugger::Manager::reset() +{ + _stepTimer.stop(); + _runTimer.stop(); + log(Log::LineType::Normal, "--------------------------------------------------"); + if ( !debugger()->reset() ) return false; + return doStep(true, false); +} + +bool Debugger::Manager::checkIfContinueStepping(bool &continueStepping) +{ + continueStepping = false; + if ( !readConfigEntry(Config::OnlyStopOnSourceLine).toBool() ) return true; + if ( !update(false) ) return false; + QMap::const_iterator it; + for (it=_currentSourceLines.begin(); it!=_currentSourceLines.end(); ++it) { + PURL::FileGroup group = it.key().fileType().data().group; + if ( group!=PURL::Source && group!=PURL::Header ) continue; + if ( !it.key().exists() ) continue; + if ( readConfigEntry(Config::OnlyStopOnProjectSourceLine).toBool() && !isProjectSource(it.key()) ) continue; + QValueVector
addresses = _coff->addresses(it.key(), it.data()); + qHeapSort(addresses); + Q_ASSERT( addresses.count()!=0 ); + if ( pc()!=addresses[0] ) continue; // we only break if pc is on the first instruction of the source line + break; + } + continueStepping = ( it==_currentSourceLines.end() ); + return true; +} + +bool Debugger::Manager::doStep(bool first, bool continued) +{ + if ( programmer()->state()!=Programmer::Halted ) return true; // has been stopped + if ( continued && !_stepTimer.isActive() ) return true; // has been stopped + _stepTimer.stop(); + if ( !first && !debugger()->step() ) return false; + bool continueStepping; + if ( !checkIfContinueStepping(continueStepping) ) return false; + if (continueStepping) _stepTimer.start(0); + else updateView(true); + return true; +} + +bool Debugger::Manager::step() +{ + bool first; + if ( !checkState(first) ) return false; + if ( !debugger()->setBreakpoints(activeBreakpointAddresses()) ) return false; + log(Log::LineType::Information, i18n("Step")); + programmer()->setState(Programmer::Halted); + return doStep(first, false); +} + +void Debugger::Manager::slotRunTimeout() +{ + if ( programmer()->state()!=Programmer::Running ) return; // has been stopped + if ( !_runTimer.isActive() ) return; // has been stopped + _runTimer.stop(); + if ( !debugger()->update() ) return; + if ( programmer()->state()==Programmer::Running ) { + _runTimer.start(programmer()->runUpdateWait()); + return; + } + log(Log::LineType::Information, i18n("Reached breakpoint.")); + update(true); + emit targetStateChanged(); +} + +void Debugger::Manager::setRegisterWatched(const Register::TypeData &data, bool watched) +{ + if (watched) { + if ( Register::list().isWatched(data) ) return; + Register::list().setWatched(data, true); + if ( programmer() && programmer()->state()==Programmer::Halted ) updateRegister(data); + } else Register::list().setWatched(data, false); +} + +bool Debugger::Manager::readRegister(const Register::TypeData &data) +{ + Q_ASSERT( data.type()==Register::Regular || data.type()==Register::Special ); + if ( _readRegisters.contains(data) ) return true; + BitValue value; + if ( !debugger()->readRegister(data, value) ) return false; + Register::list().setValue(data, value); + _readRegisters.append(data); + return true; +} + +bool Debugger::Manager::writeRegister(const Register::TypeData &data, BitValue value) +{ + Q_ASSERT( data.type()==Register::Regular || data.type()==Register::Special ); + if ( !debugger()->writeRegister(data, value) ) return false; + _readRegisters.clear(); + if ( !updateRegister(data) ) return false; + emit statusChanged(debugger()->statusString()); + return true; +} + +bool Debugger::Manager::readAllRegisters() +{ + const Device::RegistersData *rdata = _data->registersData(); + for (uint i=0; inbRegisters(); i++) { + Register::TypeData rtd(rdata->addressFromIndex(i), rdata->nbChars()); + if ( !updateRegister(rtd) ) return false; + } + return true; +} + +void Debugger::Manager::stopWatchAll() +{ + Register::list().clearWatched(); +} + +bool Debugger::Manager::prepareDebugging() +{ + if ( programmerGroup()->isSoftware() && programmerGroup()->isDebugger() ) { + PURL::Url curl = coffUrl(); + if ( curl.isEmpty() ) { + log(Log::LineType::Error, i18n("Cannot start debugging session without input file (not specified).")); + return false; + } + PURL::Url first; + uint i = 0; + for (; iisInputFileTypeSupported(type) ) continue; + PURL::Url url = curl.toFileType(type); + if ( first.isEmpty() ) first = url; + if ( !url.exists() ) continue; + debugger()->setupInput(type, url.directory().path(), url.filename()); + break; + } + if ( i==Programmer::Nb_InputFileTypes ) { + log(Log::LineType::Error, i18n("Cannot start debugging session without input file (%1).").arg(first.pretty())); + return false; + } + } + return true; +} diff --git a/src/progs/manager/debug_manager.h b/src/progs/manager/debug_manager.h new file mode 100644 index 0000000..90b8584 --- /dev/null +++ b/src/progs/manager/debug_manager.h @@ -0,0 +1,99 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef DEBUG_MANAGER_H +#define DEBUG_MANAGER_H + +#include + +#include "common/global/log.h" +#include "common/global/purl.h" +#include "common/common/storage.h" +#include "devices/base/generic_device.h" +#include "devices/base/register.h" +#include "breakpoint.h" +#include "prog_manager.h" +#include "progs/base/generic_debug.h" +namespace Coff { class TextObject; } +namespace CDB { class Object; } + +namespace Debugger +{ +class Manager : public QObject, public Log::Base, public GenericView +{ +Q_OBJECT +public: + Manager(); + virtual ~Manager(); + virtual PURL::Url coffUrl() const = 0; + virtual const Programmer::Group *programmerGroup() const = 0; + Programmer::Base *programmer() const { return Programmer::manager->programmer(); } + virtual const Device::Data *deviceData() const = 0; + Debugger::Base *debugger() const; + virtual void updateDevice(); + bool prepareDebugging(); + bool init(); + const Coff::TextObject *coff() const { return _coff; } + virtual void clear(); + Breakpoint::MarkType breakpointType(const Breakpoint::Data &data) const; + bool run(); + bool halt(); + bool reset(); + bool step(); + bool readRegister(const Register::TypeData &data); + bool writeRegister(const Register::TypeData &data, BitValue value); + BitValue pc() const; + bool isStepping() const; + +public slots: + void clearBreakpoints(); + virtual bool update(bool gotoPC); + void setRegisterWatched(const Register::TypeData &data, bool watched); + bool readAllRegisters(); + void stopWatchAll(); + +signals: + void statusChanged(const QString &text); + void targetStateChanged(); + void actionMessage(const QString &text); + +protected: + Coff::TextObject *_coff; + QMap _currentSourceLines; + + void freeActiveBreakpoint(); + bool checkBreakpoint(const Breakpoint::Data &bdata, bool onlyWarn, Address &address); + bool updateRegisters(); + virtual bool internalInit(); + virtual bool checkState(bool &first); + virtual Log::View *compileView() = 0; + virtual bool isProjectSource(const PURL::Url &url) const = 0; + virtual bool checkIfContinueStepping(bool &continueStepping); + +private slots: + void slotRunTimeout(); + bool doStep(bool first = false, bool continued = true); + +private: + const Device::Data *_data; + QTimer _runTimer, _stepTimer; + QValueList _readRegisters; + + void computeBreakpointAddresses(); + QValueList
activeBreakpointAddresses() const; + void updateBreakpointsDisplay(); + virtual void updateView() { updateView(false); } + virtual void updateView(bool gotoPC) = 0; + bool updateRegister(const Register::TypeData &data); +}; + +extern Manager *manager; + +} // namespace + +#endif diff --git a/src/progs/manager/manager.pro b/src/progs/manager/manager.pro new file mode 100644 index 0000000..44b80d0 --- /dev/null +++ b/src/progs/manager/manager.pro @@ -0,0 +1,6 @@ +STOPDIR = ../../.. +include($${STOPDIR}/lib.pro) + +TARGET = progmanager +HEADERS += breakpoint.h prog_manager.h debug_manager.h +SOURCES += breakpoint.cpp prog_manager.cpp debug_manager.cpp diff --git a/src/progs/manager/prog_manager.cpp b/src/progs/manager/prog_manager.cpp new file mode 100644 index 0000000..bc824c9 --- /dev/null +++ b/src/progs/manager/prog_manager.cpp @@ -0,0 +1,217 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "prog_manager.h" + +#include "progs/base/generic_prog.h" +#include "progs/base/prog_group.h" +#include "progs/base/generic_debug.h" +#include "progs/base/prog_config.h" +#include "debug_manager.h" + +//---------------------------------------------------------------------------- +Programmer::Manager *Programmer::manager = 0; + +Programmer::Manager::Manager(QObject *parent) + : QObject(parent, "programmer_manager"), _programmer(0) +{} + +Programmer::Manager::~Manager() +{ + delete _programmer; +} + +void Programmer::Manager::clear() +{ + delete _programmer; + _programmer = 0; +} + +void Programmer::Manager::createProgrammer(const Device::Data *data, const HardwareDescription &hd) +{ + if ( _programmer && _programmer->device()==data && !hasError() ) return; + delete _programmer; + _programmer = group().createProgrammer(isTargetSelfPowered(), data, hd); + _programmer->Log::Base::setParent(this); + connect(_programmer, SIGNAL(actionMessage(const QString &)), SIGNAL(actionMessage(const QString &))); + connect(&_programmer->progressMonitor(), SIGNAL(setLabel(const QString &)), SIGNAL(actionMessage(const QString &))); + connect(&_programmer->progressMonitor(), SIGNAL(setTotalProgress(uint)), SIGNAL(setTotalProgress(uint))); + connect(&_programmer->progressMonitor(), SIGNAL(setProgress(uint)), SIGNAL(setProgress(uint))); + connect(&_programmer->progressMonitor(), SIGNAL(showProgress(bool)), SIGNAL(showProgress(bool))); +} + +bool Programmer::Manager::initProgramming(bool debugging) +{ + if ( !internalInitProgramming(debugging) ) return false; + setState(Programming); + return true; +} + +bool Programmer::Manager::internalInitProgramming(bool) +{ + if ( device()==0 ) { + sorry(i18n("You need to specify the device for programming.")); + return false; + } + if ( !group().isSupported(device()->name()) ) { + if ( group().isSoftware() && group().supportedDevices().isEmpty() ) + sorry(i18n("Could not detect supported devices for \"%1\". Please check installation.").arg(group().label())); + else sorry(i18n("The current programmer \"%1\" does not support device \"%2\".").arg(group().label()).arg(device()->name())); + return false; + } + createProgrammer(device()); + return true; +} + +void Programmer::Manager::endProgramming() +{ + ::Debugger::manager->update(true); + setState(Idle); +} + +bool Programmer::Manager::program(const Device::Memory &memory, const Device::MemoryRange &range) +{ + if ( !initProgramming(false) ) return false; + bool ok = _programmer->program(memory, range); + endProgramming(); + if ( ok && !group().isDebugger() && readConfigEntry(Config::RunAfterProgram).toBool() ) return run(); + return ok; +} + +bool Programmer::Manager::verify(const Device::Memory &memory, const Device::MemoryRange &range) +{ + if ( !initProgramming(false) ) return false; + bool ok = _programmer->verify(memory, range); + endProgramming(); + return ok; +} + +bool Programmer::Manager::read(Device::Memory &memory, const Device::MemoryRange &range) +{ + if ( !initProgramming(false) ) return false; + bool ok = _programmer->read(memory, range); + endProgramming(); + return ok; +} + +bool Programmer::Manager::erase(const Device::MemoryRange &range) +{ + if ( !initProgramming(false) ) return false; + bool ok = _programmer->erase(range); + endProgramming(); + return ok; +} + +bool Programmer::Manager::blankCheck(const Device::MemoryRange &range) +{ + if ( !initProgramming(false) ) return false; + bool ok = _programmer->blankCheck(range); + endProgramming(); + return ok; +} + +bool Programmer::Manager::connectDevice() +{ + if ( !initProgramming(false) ) return false; + _programmer->disconnectHardware(); + bool ok = ::Debugger::manager->prepareDebugging(); + if (ok) ok = _programmer->connectDevice(); + if ( ok && group().isSoftware() && group().isDebugger() ) { + ok = _programmer->debugger()->init(); + if (ok) ::Debugger::manager->update(true); + } + endProgramming(); + return ok; +} + +bool Programmer::Manager::setDevicePower(bool on) +{ + if ( !initProgramming(false) ) return false; + bool ok = true; + if ( _programmer->isTargetSelfPowered() ) + sorry(i18n("Cannot toggle target power since target is self-powered."), QString::null); + else { + emit actionMessage(i18n("Toggle Device Power...")); + ok = _programmer->setTargetPowerOn(on); + } + endProgramming(); + return ok; +} + +bool Programmer::Manager::disconnectDevice() +{ + ::Debugger::manager->clear(); + emit actionMessage(i18n("Disconnecting...")); + bool debugger = group().isDebugger(); + _programmer->setTargetPowerOn(false); + _programmer->disconnectHardware(); + endProgramming(); + if (debugger) log(Log::LineType::Information, i18n("Stopped.")); + return true; +} + +bool Programmer::Manager::run() +{ + bool debugger = group().isDebugger(); + if ( !initProgramming(debugger) ) return false; + bool ok = (debugger ? ::Debugger::manager->run() : _programmer->run()); + setState(Idle); + return ok; +} + +bool Programmer::Manager::halt() +{ + bool debugger = group().isDebugger(); + bool ok = (debugger ? ::Debugger::manager->halt() : _programmer->stop()); + if (debugger) setState(Idle); + else { + endProgramming(); + log(Log::LineType::Information, i18n("Stopped.")); + } + return ok; +} + +void Programmer::Manager::stop() +{ + if (_programmer) _programmer->disconnectHardware(); +} + +bool Programmer::Manager::restart() +{ + bool ok; + if (group().isDebugger()) { + if ( _programmer==0 || _programmer->state()==::Programmer::NotConnected + || _programmer->state()==::Programmer::Stopped ) return step(); + if ( !initProgramming(true) ) return false; + ok = ::Debugger::manager->reset(); + log(Log::LineType::Information, i18n("Reset.", "Reset.")); + setState(Idle); + } else { + log(Log::LineType::Information, i18n("Restarting...")); + ok = _programmer->stop(); + Port::msleep(200); + if (ok) ok = _programmer->run(); + endProgramming(); + } + return ok; +} + +bool Programmer::Manager::step() +{ + if ( !initProgramming(true) ) return false; + bool ok = ::Debugger::manager->step(); + setState(Idle); + return ok; +} + +bool Programmer::Manager::isTargetSelfPowered() const +{ + if ( group().targetPowerMode()==TargetPowerModeFromConfig ) return readConfigEntry(Config::TargetSelfPowered).toBool(); + return ( group().targetPowerMode()==TargetSelfPowered ); +} diff --git a/src/progs/manager/prog_manager.h b/src/progs/manager/prog_manager.h new file mode 100644 index 0000000..11f7401 --- /dev/null +++ b/src/progs/manager/prog_manager.h @@ -0,0 +1,74 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#ifndef PROG_MANAGER_H +#define PROG_MANAGER_H + +#include + +#include "common/global/log.h" +namespace Device { class Data; class Memory; class MemoryRange; } +namespace Port { class Description; } + +namespace Programmer +{ +class Base; +class Group; +class HardwareDescription; + +class Manager : public QObject, public Log::Base +{ +Q_OBJECT +public: + Manager(QObject *parent); + virtual ~Manager(); + ::Programmer::Base *programmer() { return _programmer; } + virtual void createProgrammer(const Device::Data *data) = 0; + bool initProgramming(bool debugging); + void endProgramming(); + void clear(); + void stop(); + bool program(const Device::Memory &memory, const Device::MemoryRange &range); + bool verify(const Device::Memory &memory, const Device::MemoryRange &range); + bool read(Device::Memory &memory, const Device::MemoryRange &range); + bool erase(const Device::MemoryRange &range); + bool blankCheck(const Device::MemoryRange &range); + bool setDevicePower(bool on); + enum State { Idle, Programming }; + virtual void setState(State state) = 0; + +public slots: + bool connectDevice(); + bool disconnectDevice(); + bool run(); + bool halt(); + bool restart(); + bool step(); + +signals: + void actionMessage(const QString &message); + void showProgress(bool show); + void setTotalProgress(uint steps); + void setProgress(uint steps); + +protected: + ::Programmer::Base *_programmer; + + virtual const Group &group() const = 0; + virtual bool internalInitProgramming(bool debugging); + virtual const Device::Data *device() const = 0; + virtual bool isTargetSelfPowered() const; + virtual void createProgrammer(const Device::Data *data, const HardwareDescription &hd); +}; + +extern Manager *manager; + +} // namespace + +#endif diff --git a/src/progs/picdem_bootloader/Makefile.am b/src/progs/picdem_bootloader/Makefile.am new file mode 100644 index 0000000..fccf96d --- /dev/null +++ b/src/progs/picdem_bootloader/Makefile.am @@ -0,0 +1,3 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +SUBDIRS = xml base gui diff --git a/src/progs/picdem_bootloader/base/Makefile.am b/src/progs/picdem_bootloader/base/Makefile.am new file mode 100644 index 0000000..13a3add --- /dev/null +++ b/src/progs/picdem_bootloader/base/Makefile.am @@ -0,0 +1,11 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libpicdembootloader.la +libpicdembootloader_la_SOURCES = picdem_bootloader_data.cpp picdem_bootloader.cpp picdem_bootloader_prog.cpp +libpicdembootloader_la_DEPENDENCIES = picdem_bootloader_data.cpp + +noinst_DATA = picdem_bootloader.xml +picdem_bootloader_data.cpp: ../xml/xml_picdem_bootloader_parser picdem_bootloader.xml + ../xml/xml_picdem_bootloader_parser +CLEANFILES = picdem_bootloader_data.cpp diff --git a/src/progs/picdem_bootloader/base/base.pro b/src/progs/picdem_bootloader/base/base.pro new file mode 100644 index 0000000..8551799 --- /dev/null +++ b/src/progs/picdem_bootloader/base/base.pro @@ -0,0 +1,6 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/lib.pro) + +TARGET = picdem_bootloader +HEADERS += picdem_bootloader.h picdem_bootloader_prog.h picdem_bootloader_data.h +SOURCES += picdem_bootloader.cpp picdem_bootloader_prog.cpp picdem_bootloader_data.cpp diff --git a/src/progs/picdem_bootloader/base/picdem_bootloader.cpp b/src/progs/picdem_bootloader/base/picdem_bootloader.cpp new file mode 100644 index 0000000..f22eecb --- /dev/null +++ b/src/progs/picdem_bootloader/base/picdem_bootloader.cpp @@ -0,0 +1,184 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "picdem_bootloader.h" + +#include "progs/icd2/base/microchip.h" + +//----------------------------------------------------------------------------- +uint PicdemBootloader::Config::readVendorId() +{ + Config config; + return qMin(config.readUIntEntry("vendor_id", Microchip::VENDOR_ID), uint(0xFFFF)); +} +void PicdemBootloader::Config::writeVendorId(uint id) +{ + Config config; + config.writeEntry("vendor_id", id); +} + +uint PicdemBootloader::Config::readProductId() +{ + Config config; + return qMin(config.readUIntEntry("product_id", 0x000B), uint(0xFFFF)); +} +void PicdemBootloader::Config::writeProductId(uint id) +{ + Config config; + config.writeEntry("product_id", id); +} + +//----------------------------------------------------------------------------- +PicdemBootloader::Port::Port(Log::Base &log) + : Port::USB(log, Config::readVendorId(), Config::readProductId(), 1, 0) +{} + +bool PicdemBootloader::Port::receive(uint nb, QMemArray &data) +{ + data.resize(nb); + if ( !read(0x81, (char *)data.data(), nb) ) return false; + log(Log::DebugLevel::Max, QString("received: \"%1\"").arg(toPrintable(data, PrintEscapeAll))); + return true; +} + +bool PicdemBootloader::Port::send(const QMemArray &cmd) +{ + log(Log::DebugLevel::Extra, QString("send: \"%1\"").arg(toPrintable(cmd, PrintEscapeAll))); + return write(0x01, (const char *)cmd.data(), cmd.count()); +} + +bool PicdemBootloader::Port::sendAndReceive(QMemArray &data, uint nb) +{ + if ( !send(data) ) return false; + return receive(nb, data); +} + +QMemArray PicdemBootloader::Port::command(uchar instruction, uint address, uint len, uint nb) const +{ + QMemArray cmd(5+nb); + cmd[0] = instruction; + cmd[1] = len; + cmd[2] = address & 0xFF; + cmd[3] = (address >> 8) & 0xFF; + cmd[4] = (address >> 16) & 0xFF; + return cmd; +} + +//----------------------------------------------------------------------------- +PicdemBootloader::Hardware::Hardware(::Programmer::Base &base) + : Bootloader::Hardware(base, new Port(base)) +{} + +bool PicdemBootloader::Hardware::internalConnectHardware() +{ + if ( !openPort() ) return false; + QMemArray cmd(5); + cmd.fill(0); + if ( !port().sendAndReceive(cmd, 4) ) return false; + VersionData version(cmd[3], cmd[2], 0); + log(Log::LineType::Information, i18n("Bootloader version %1 detected").arg(version.pretty())); + if ( version.majorNum()!=1 ) { + log(Log::LineType::Error, i18n("Only bootloader version 1.x is supported")); + return false; + } + return true; +} + +uchar PicdemBootloader::Hardware::writeInstruction(Pic::MemoryRangeType type) +{ + switch (type.type()) { + case Pic::MemoryRangeType::Code: return 0x02; + case Pic::MemoryRangeType::Eeprom: return 0x05; + case Pic::MemoryRangeType::UserId: return 0x07; + default: Q_ASSERT(false); break; + } + return 0x00; +} + +bool PicdemBootloader::Hardware::write(Pic::MemoryRangeType type, const Device::Array &data) +{ + Q_ASSERT( data.count()==device().nbWords(type) ); + if ( type==Pic::MemoryRangeType::Code ) { // check that there is nothing in bootloader reserved area + for (uint i=0; i=0x400 ) continue; + if ( data[i]==device().mask(Pic::MemoryRangeType::Code) ) continue; + uint address = device().addressIncrement(Pic::MemoryRangeType::Code) * i; + log(Log::LineType::Warning, " " + i18n("Code is present in bootloader reserved area (at address %1). It will be ignored.").arg(toHexLabel(address, device().nbCharsAddress()))); + break; + } + } + uint nbBytesWord = device().nbBytesWord(type); + uint nbBytes = nbBytesWord * device().nbWords(type); + uint offset = (type==Pic::MemoryRangeType::Code ? 0x0800 : 0x00); + for (; offset cmd = port().command(0x02, device().range(type).start.toUInt() + offset, 16, 16); + for (uint k=0; k<16; k += nbBytesWord) { + uint index = (offset + k) / nbBytesWord; + cmd[5 + k] = data[index].byte(0); + if ( nbBytesWord==2 ) cmd[5 + k+1] = data[index].byte(1); + } + if ( !port().sendAndReceive(cmd, 1) ) return false; + } + return true; +} + +uchar PicdemBootloader::Hardware::readInstruction(Pic::MemoryRangeType type) +{ + switch (type.type()) { + case Pic::MemoryRangeType::Code: return 0x01; + case Pic::MemoryRangeType::Eeprom: return 0x04; + case Pic::MemoryRangeType::Config: + case Pic::MemoryRangeType::DeviceId: + case Pic::MemoryRangeType::UserId: return 0x06; + default: Q_ASSERT(false); break; + } + return 0x00; +} + +bool PicdemBootloader::Hardware::read(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata) +{ + data.resize(device().nbWords(type)); + Device::Array varray; + if (vdata) varray = static_cast(vdata->memory).arrayForWriting(type); + uint nbBytesWord = device().nbBytesWord(type); + uint nbBytes = nbBytesWord * device().nbWords(type); + uint nb = QMIN(uint(16), nbBytes); + for (uint offset=0; offset cmd = port().command(readInstruction(type), device().range(type).start.toUInt() + offset, nb, 0); + if ( !port().sendAndReceive(cmd, 5+nb) ) return false; + for (uint k=0; k=0x0800 && data[index]!=varray[index] ) { + log(Log::LineType::Error, i18n("Device memory does not match hex file (at address 0x%2: reading 0x%3 and expecting 0x%4).") + .arg(QString(toHex(index/2, device().nbCharsAddress()))) + .arg(QString(toHex(data[index], device().nbCharsWord(type)))) + .arg(QString(toHex(varray[index], device().nbCharsWord(type))))); + return false; + } + } + } + return true; +} + +bool PicdemBootloader::Hardware::erase(Pic::MemoryRangeType type) +{ + if ( type==Pic::MemoryRangeType::Eeprom ) { + Pic::Memory memory(device()); + Device::Array data = memory.arrayForWriting(Pic::MemoryRangeType::Eeprom); + return write(Pic::MemoryRangeType::Eeprom, data); + } + uint nbBytesWord = device().nbBytesWord(type); + uint nbBytes = nbBytesWord * device().nbWords(type); + for (uint offset=0x0800; offset cmd = port().command(0x03, device().range(type).start.toUInt() + offset, 1, 0); + if ( !port().sendAndReceive(cmd, 1) ) return false; + } + return true; +} diff --git a/src/progs/picdem_bootloader/base/picdem_bootloader.h b/src/progs/picdem_bootloader/base/picdem_bootloader.h new file mode 100644 index 0000000..3081382 --- /dev/null +++ b/src/progs/picdem_bootloader/base/picdem_bootloader.h @@ -0,0 +1,72 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PICDEM_BOOTLOADER_H +#define PICDEM_BOOTLOADER_H + +#include "progs/bootloader/base/bootloader.h" +#include "common/port/usb_port.h" + +namespace PicdemBootloader +{ +//----------------------------------------------------------------------------- +class Config : public GenericConfig +{ +public: + static uint readVendorId(); + static void writeVendorId(uint id); + static uint readProductId(); + static void writeProductId(uint id); + +private: + Config() : GenericConfig("picdem_bootloader") {} +}; + +//----------------------------------------------------------------------------- +class Port : public ::Port::USB +{ +public: + Port(Log::Base &base); + bool receive(uint nb, QMemArray &array); + bool send(const QMemArray &array); + bool sendAndReceive(QMemArray &data, uint nb); + QMemArray command(uchar instruction, uint address, uint len, uint nb) const; +}; + +//----------------------------------------------------------------------------- +class Hardware : public Bootloader::Hardware +{ +public: + Hardware(::Programmer::Base &base); + Port &port() { return static_cast(*_port); } + virtual bool write(Pic::MemoryRangeType type, const Device::Array &data); + virtual bool read(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata); + virtual bool erase(Pic::MemoryRangeType type); + virtual bool internalConnectHardware(); + +private: + static uchar readInstruction(Pic::MemoryRangeType type); + static uchar writeInstruction(Pic::MemoryRangeType type); +}; + +//----------------------------------------------------------------------------- +class DeviceSpecific : public Bootloader::DeviceSpecific +{ +public: + DeviceSpecific(::Programmer::Base &base) : Bootloader::DeviceSpecific(base) {} + virtual bool canEraseAll() const { return true; } + virtual bool canEraseRange(Pic::MemoryRangeType type) const { return ( type==Pic::MemoryRangeType::Eeprom || type==Pic::MemoryRangeType::Code ); } + virtual bool canReadRange(Pic::MemoryRangeType) const { return true; } + virtual bool canWriteRange(Pic::MemoryRangeType type) const { return ( type==Pic::MemoryRangeType::Eeprom || type==Pic::MemoryRangeType::Code ); } + virtual bool doEraseRange(Pic::MemoryRangeType type) { return static_cast(hardware()).erase(type); } + virtual bool doErase(bool) { return doEraseRange(Pic::MemoryRangeType::Code) && doEraseRange(Pic::MemoryRangeType::Eeprom); } +}; + +} // namespace + +#endif diff --git a/src/progs/picdem_bootloader/base/picdem_bootloader.xml b/src/progs/picdem_bootloader/base/picdem_bootloader.xml new file mode 100644 index 0000000..1cbfecb --- /dev/null +++ b/src/progs/picdem_bootloader/base/picdem_bootloader.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/src/progs/picdem_bootloader/base/picdem_bootloader_data.h b/src/progs/picdem_bootloader/base/picdem_bootloader_data.h new file mode 100644 index 0000000..bf2a40f --- /dev/null +++ b/src/progs/picdem_bootloader/base/picdem_bootloader_data.h @@ -0,0 +1,19 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PICDEM_BOOTLOADER_DATA_H +#define PICDEM_BOOTLOADER_DATA_H + +namespace PicdemBootloader +{ + struct Data {}; + extern bool isSupported(const QString &device); + extern const Data &data(const QString &device); +} // namespace + +#endif diff --git a/src/progs/picdem_bootloader/base/picdem_bootloader_prog.cpp b/src/progs/picdem_bootloader/base/picdem_bootloader_prog.cpp new file mode 100644 index 0000000..72fc384 --- /dev/null +++ b/src/progs/picdem_bootloader/base/picdem_bootloader_prog.cpp @@ -0,0 +1,14 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "picdem_bootloader_prog.h" + +//----------------------------------------------------------------------------- +PicdemBootloader::ProgrammerBase::ProgrammerBase(const Programmer::Group &group, const Pic::Data *data) + : Bootloader::ProgrammerBase(group, data, "picdem_bootloader_programmer_base") +{} diff --git a/src/progs/picdem_bootloader/base/picdem_bootloader_prog.h b/src/progs/picdem_bootloader/base/picdem_bootloader_prog.h new file mode 100644 index 0000000..698d612 --- /dev/null +++ b/src/progs/picdem_bootloader/base/picdem_bootloader_prog.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PICDEM_BOOTLOADER_PROG_H +#define PICDEM_BOOTLOADER_PROG_H + +#include "progs/bootloader/base/bootloader_prog.h" +#include "picdem_bootloader.h" + +namespace PicdemBootloader +{ + +//----------------------------------------------------------------------------- +class ProgrammerBase : public Bootloader::ProgrammerBase +{ +Q_OBJECT +public: + ProgrammerBase(const Programmer::Group &group, const Pic::Data *data); +}; + +//----------------------------------------------------------------------------- +class Group : public ::Bootloader::Group +{ +public: + virtual QString name() const { return "picdem_bootloader"; } + virtual QString label() const { return i18n("Picdem Bootloader"); } + virtual ::Programmer::Properties properties() const { return ::Programmer::Programmer | ::Programmer::CanReadMemory; } + virtual ::Programmer::TargetPowerMode targetPowerMode() const { return ::Programmer::TargetSelfPowered; } + virtual bool isPortSupported(PortType type) const { return type==PortType::USB; } + virtual bool canReadVoltage(Pic::VoltageType) const { return false; } + +protected: + virtual void initSupported(); + virtual ::Programmer::Base *createBase(const Device::Data *data) const { return new ProgrammerBase(*this, static_cast(data)); } + virtual ::Programmer::Hardware *createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &) const { return new Hardware(base); } + virtual ::Programmer::DeviceSpecific *createDeviceSpecific(::Programmer::Base &base) const { return new DeviceSpecific(base); } +}; + +} // namespace + +#endif diff --git a/src/progs/picdem_bootloader/gui/Makefile.am b/src/progs/picdem_bootloader/gui/Makefile.am new file mode 100644 index 0000000..57d10bb --- /dev/null +++ b/src/progs/picdem_bootloader/gui/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libpicdembootloaderui.la +libpicdembootloaderui_la_LDFLAGS = $(all_libraries) +libpicdembootloaderui_la_SOURCES = picdem_bootloader_ui.cpp diff --git a/src/progs/picdem_bootloader/gui/picdem_bootloader_ui.cpp b/src/progs/picdem_bootloader/gui/picdem_bootloader_ui.cpp new file mode 100644 index 0000000..c958249 --- /dev/null +++ b/src/progs/picdem_bootloader/gui/picdem_bootloader_ui.cpp @@ -0,0 +1,48 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "picdem_bootloader_ui.h" + +#include "progs/picdem_bootloader/base/picdem_bootloader.h" + +//----------------------------------------------------------------------------- +PicdemBootloader::ConfigWidget::ConfigWidget(const ::Programmer::Group &group, QWidget *parent) + : ::Programmer::ConfigWidget(group, parent) +{ + uint row = numRows(); + + QLabel *label = new QLabel(i18n("USB Vendor Id:"), this); + addWidget(label, row,row, 0,0); + _vendorId = new HexWordEditor(4, this); + addWidget(_vendorId, row,row, 1,1); + row++; + + label = new QLabel(i18n("USB Product Id:"), this); + addWidget(label, row,row, 0,0); + _productId = new HexWordEditor(4, this); + addWidget(_productId, row,row, 1,1); + row++; +} + +void PicdemBootloader::ConfigWidget::saveConfig() +{ + Config::writeVendorId(_vendorId->value().toUInt()); + Config::writeProductId(_productId->value().toUInt()); +} + +void PicdemBootloader::ConfigWidget::loadConfig() +{ + _vendorId->setValue(Config::readVendorId()); + _productId->setValue(Config::readProductId()); +} + +//----------------------------------------------------------------------------- +::Programmer::ConfigWidget *PicdemBootloader::GroupUI::createConfigWidget(QWidget *parent) const +{ + return new ConfigWidget(static_cast(group()), parent); +} diff --git a/src/progs/picdem_bootloader/gui/picdem_bootloader_ui.h b/src/progs/picdem_bootloader/gui/picdem_bootloader_ui.h new file mode 100644 index 0000000..50777af --- /dev/null +++ b/src/progs/picdem_bootloader/gui/picdem_bootloader_ui.h @@ -0,0 +1,37 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PICDEM_BOOTLOADER_UI_H +#define PICDEM_BOOTLOADER_UI_H + +#include "progs/bootloader/gui/bootloader_ui.h" + +namespace PicdemBootloader +{ +//---------------------------------------------------------------------------- +class ConfigWidget: public ::Programmer::ConfigWidget +{ +Q_OBJECT +public: + ConfigWidget(const ::Programmer::Group &group, QWidget *parent); + virtual void loadConfig(); + virtual void saveConfig(); + +private: + HexWordEditor *_vendorId, *_productId; +}; + +//---------------------------------------------------------------------------- +class GroupUI : public ::Bootloader::GroupUI +{ +public: + virtual ::Programmer::ConfigWidget *createConfigWidget(QWidget *parent) const; +}; +} // namespace + +#endif diff --git a/src/progs/picdem_bootloader/picdem_bootloader.pro b/src/progs/picdem_bootloader/picdem_bootloader.pro new file mode 100644 index 0000000..60ac0f5 --- /dev/null +++ b/src/progs/picdem_bootloader/picdem_bootloader.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = xml base diff --git a/src/progs/picdem_bootloader/xml/Makefile.am b/src/progs/picdem_bootloader/xml/Makefile.am new file mode 100644 index 0000000..5ed38e6 --- /dev/null +++ b/src/progs/picdem_bootloader/xml/Makefile.am @@ -0,0 +1,14 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_PROGRAMS = xml_picdem_bootloader_parser +xml_picdem_bootloader_parser_SOURCES = xml_picdem_bootloader_parser.cpp +OBJECTS = $(top_builddir)/src/devices/list/libdevicelistnoui.la \ + $(top_builddir)/src/devices/pic/pic/libpic.la $(top_builddir)/src/devices/pic/base/libpicbase.la \ + $(top_builddir)/src/devices/pic/xml_data/libpicxml.la \ + $(top_builddir)/src/devices/mem24/mem24/libmem24.la $(top_builddir)/src/devices/mem24/base/libmem24base.la \ + $(top_builddir)/src/devices/mem24/xml_data/libmem24xml.la \ + $(top_builddir)/src/xml_to_data/libxmltodata.la $(top_builddir)/src/devices/base/libdevicebase.la \ + $(top_builddir)/src/common/common/libcommon.la +xml_picdem_bootloader_parser_DEPENDENCIES = $(OBJECTS) +xml_picdem_bootloader_parser_LDADD = $(OBJECTS) $(LIB_KDECORE) diff --git a/src/progs/picdem_bootloader/xml/xml.pro b/src/progs/picdem_bootloader/xml/xml.pro new file mode 100644 index 0000000..4e2eb15 --- /dev/null +++ b/src/progs/picdem_bootloader/xml/xml.pro @@ -0,0 +1,17 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/app.pro) + +TARGET = xml_picdem_bootloader_parser +SOURCES += xml_picdem_bootloader_parser.cpp +LIBS += ../../../devices/list/libdevicelist.a \ + ../../../devices/mem24/mem24/libmem24.a ../../../devices/mem24/xml_data/libmem24xml.a \ + ../../../devices/mem24/base/libmem24base.a \ + ../../../devices/pic/pic/libpic.a ../../../devices/pic/xml_data/libpicxml.a \ + ../../../devices/pic/base/libpicbase.a ../../../xml_to_data/libxmltodata.a \ + ../../../devices/base/libdevicebase.a ../../../common/global/libglobal.a \ + ../../../common/nokde/libnokde.a ../../../common/common/libcommon.a + +unix:QMAKE_POST_LINK = cd ../base && ../xml/xml_picdem_bootloader_parser +unix:QMAKE_CLEAN += ../base/picdem_bootloader_data.cpp +win32:QMAKE_POST_LINK = cd ..\base && ..\xml\xml_picdem_bootloader_parser.exe +win32:QMAKE_CLEAN += ..\base\picdem_bootloader_data.cpp diff --git a/src/progs/picdem_bootloader/xml/xml_picdem_bootloader_parser.cpp b/src/progs/picdem_bootloader/xml/xml_picdem_bootloader_parser.cpp new file mode 100644 index 0000000..745b6a0 --- /dev/null +++ b/src/progs/picdem_bootloader/xml/xml_picdem_bootloader_parser.cpp @@ -0,0 +1,39 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "xml_to_data/prog_xml_to_data.h" + +#include "progs/picdem_bootloader/base/picdem_bootloader_data.h" +#include "devices/base/device_group.h" +#include "devices/pic/base/pic.h" + +//----------------------------------------------------------------------------- +namespace PicdemBootloader +{ + +class XmlToData : public Programmer::XmlToData +{ +public: + XmlToData() : Programmer::XmlToData("picdem_bootloader", "PicdemBootloader") {} + +private: + virtual void parseData(QDomElement element, Data &data); +}; + +void PicdemBootloader::XmlToData::parseData(QDomElement, Data &) +{ + const Device::Data *ddata = Device::lister().data(currentDevice()); + if ( ddata->group().name()!="pic" ) qFatal("non-pic device not supported"); + const Pic::Data *pdata = static_cast(ddata); + if ( !pdata->hasFeature(Pic::Feature::USB) ) qFatal("device does not have USB"); +} + +} // namespace + +//----------------------------------------------------------------------------- +XML_MAIN(PicdemBootloader::XmlToData) diff --git a/src/progs/pickit1/Makefile.am b/src/progs/pickit1/Makefile.am new file mode 100644 index 0000000..fccf96d --- /dev/null +++ b/src/progs/pickit1/Makefile.am @@ -0,0 +1,3 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +SUBDIRS = xml base gui diff --git a/src/progs/pickit1/base/Makefile.am b/src/progs/pickit1/base/Makefile.am new file mode 100644 index 0000000..74d56f0 --- /dev/null +++ b/src/progs/pickit1/base/Makefile.am @@ -0,0 +1,11 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libpickit1.la +libpickit1_la_SOURCES = pickit1.cpp pickit1_prog.cpp pickit1_data.cpp +libpickit1_la_DEPENDENCIES = pickit1_data.cpp + +noinst_DATA = pickit1.xml +pickit1_data.cpp: ../xml/xml_pickit1_parser pickit1.xml + ../xml/xml_pickit1_parser +CLEANFILES = pickit1_data.cpp diff --git a/src/progs/pickit1/base/base.pro b/src/progs/pickit1/base/base.pro new file mode 100644 index 0000000..bdd257b --- /dev/null +++ b/src/progs/pickit1/base/base.pro @@ -0,0 +1,6 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/lib.pro) + +TARGET = pickit1 +HEADERS += pickit1.h pickit1_prog.h pickit1_data.h +SOURCES += pickit1.cpp pickit1_prog.cpp pickit1_data.cpp diff --git a/src/progs/pickit1/base/pickit1.cpp b/src/progs/pickit1/base/pickit1.cpp new file mode 100644 index 0000000..c5ab021 --- /dev/null +++ b/src/progs/pickit1/base/pickit1.cpp @@ -0,0 +1,102 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "pickit1.h" + +bool Pickit1::Baseline::init() +{ + Array cmd; + cmd[0] = 'c'; + cmd[1] = 0x00; // Load Configuration + cmd[2] = 0x02; // Load Program latches + cmd[3] = 0x03; // Load Data latches + cmd[4] = 0x04; // Read Program memory + cmd[5] = 0x05; // Read Data latches + cmd[6] = 0x06; // Increment Address + cmd[7] = 0x08; // Begin programming internally timed + if ( !hardware().port().command(cmd) ) return false; + cmd[0] = 0x08; // Begin Programming externally timed + cmd[1] = 0x0E; // End externally time programming cycle + cmd[2] = 0x09; // Bulk Erase program memory + cmd[3] = 0x0B; // Bulk Erase Data memory + cmd[4] = 0xFF; // Read Program memory + cmd[5] = 0xFF; // Read Data latches + cmd[6] = 0xFF; // Increment Address + cmd[7] = 0xFF; // Begin programming internally timed + return hardware().port().command(cmd); +} + +bool Pickit1::Baseline::incrementPC(uint nb) +{ + if ( (nb & 0xFF)!=0 ) return Pickit::Baseline::incrementPC(nb); + // work around bugs in firmware + Array cmd; + uint high = (nb >> 8) & 0xFF; + log(Log::DebugLevel::Extra, QString("work around bug in firmware (nb_inc=%1 high=%2)") + .arg(toHexLabel(nb, 4)).arg(toHexLabel(high, 2))); + if ( high==1 ) { + cmd[0] = 'I'; + cmd[1] = 0x40; + cmd[2] = 0x00; + cmd[3] = 'I'; + cmd[4] = 0xC0; + cmd[5] = 0x00; + } else { + cmd[0] = 'I'; + cmd[1] = 0x00; + cmd[2] = high-1; + } + return hardware().port().command(cmd); +} + +//---------------------------------------------------------------------------- +bool Pickit1::P16F::init() +{ + Array cmd; + cmd[0] = 'c'; + cmd[1] = 0x00; // Load Configuration + cmd[2] = 0x02; // Load Program latches + cmd[3] = 0x03; // Load Data latches + cmd[4] = 0x04; // Read Program memory + cmd[5] = 0x05; // Read Data latches + cmd[6] = 0x06; // Increment Address + cmd[7] = 0x08; // Begin programming internally timed + if ( !hardware().port().command(cmd) ) return false; + cmd[0] = 0x18; // Begin Programming externally timed + cmd[1] = 0x0A; // End externally time programming cycle + cmd[2] = 0x09; // Bulk Erase program memory + cmd[3] = 0x0B; // Bulk Erase Data memory + cmd[4] = 0xFF; // Read Program memory + cmd[5] = 0xFF; // Read Data latches + cmd[6] = 0xFF; // Increment Address + cmd[7] = 0xFF; // Begin programming internally timed + return hardware().port().command(cmd); +} + +bool Pickit1::P16F716::init() +{ + Array cmd; + cmd[0] = 'c'; + cmd[1] = 0x00; // Load Configuration + cmd[2] = 0x02; // Load Program latches + cmd[3] = 0x03; // Load Data latches + cmd[4] = 0x04; // Read Program memory + cmd[5] = 0x05; // Read Data latches + cmd[6] = 0x06; // Increment Address + cmd[7] = 0x08; // Begin programming internally timed + if ( !hardware().port().command(cmd) ) return false; + cmd[0] = 0x18; // Begin Programming externally timed + cmd[1] = 0x0E; // End externally time programming cycle + cmd[2] = 0x09; // Bulk Erase program memory + cmd[3] = 0x0B; // Bulk Erase Data memory + cmd[4] = 0xFF; // Read Program memory + cmd[5] = 0xFF; // Read Data latches + cmd[6] = 0xFF; // Increment Address + cmd[7] = 0xFF; // Begin programming internally timed + return hardware().port().command(cmd); +} diff --git a/src/progs/pickit1/base/pickit1.h b/src/progs/pickit1/base/pickit1.h new file mode 100644 index 0000000..75e1d82 --- /dev/null +++ b/src/progs/pickit1/base/pickit1.h @@ -0,0 +1,73 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PICKIT1_H +#define PICKIT1_H + +#include "progs/pickit2/base/pickit.h" +#include "pickit1_data.h" + +namespace Pickit1 +{ +//----------------------------------------------------------------------------- +class Array : public Pickit::Array +{ +public: + Array() : Pickit::Array(8, 'Z', PrintAlphaNum) {} +}; + +//----------------------------------------------------------------------------- +class USBPort : public Pickit::USBPort +{ +public: + USBPort(Log::Base &log) : Pickit::USBPort(0x0032, log) {} + virtual Pickit::Array array() const { return Array(); } + +private: + virtual uint readEndPoint() const { return 0x81; } + virtual uint writeEndPoint() const { return 0x01; } +}; + +//----------------------------------------------------------------------------- +class Hardware : public Pickit::Hardware +{ +public: + Hardware(::Programmer::Base &base) : Pickit::Hardware(base, new USBPort(base)) {} +}; + +//---------------------------------------------------------------------------- +class Baseline : public Pickit::Baseline +{ +public: + Baseline(::Programmer::Base &base) : Pickit::Baseline(base) {} + virtual char entryMode() const { return data(device().name()).entryMode; } + virtual bool init(); + virtual uint nbWrites(Pic::MemoryRangeType) const { return 1; } + virtual bool incrementPC(uint nb); +}; + +//---------------------------------------------------------------------------- +class P16F : public Pickit::P16F +{ +public: + P16F(::Programmer::Base &base) : Pickit::P16F(base) {} + virtual char entryMode() const { return data(device().name()).entryMode; } + virtual bool init(); + virtual uint nbWrites(Pic::MemoryRangeType) const { return 1; } +}; + +class P16F716 : public P16F +{ +public: + P16F716(::Programmer::Base &base) : P16F(base) {} + virtual bool init(); +}; + +} // namespace + +#endif diff --git a/src/progs/pickit1/base/pickit1.xml b/src/progs/pickit1/base/pickit1.xml new file mode 100644 index 0000000..899b504 --- /dev/null +++ b/src/progs/pickit1/base/pickit1.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/progs/pickit1/base/pickit1_data.h b/src/progs/pickit1/base/pickit1_data.h new file mode 100644 index 0000000..767fc4b --- /dev/null +++ b/src/progs/pickit1/base/pickit1_data.h @@ -0,0 +1,23 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PICKIT1_DATA_H +#define PICKIT1_DATA_H + +#include + +namespace Pickit1 +{ + struct Data { + char entryMode; + bool regenerateOsccal; + }; + extern const Data &data(const QString &device); +} // namespace + +#endif diff --git a/src/progs/pickit1/base/pickit1_prog.cpp b/src/progs/pickit1/base/pickit1_prog.cpp new file mode 100644 index 0000000..b43a19c --- /dev/null +++ b/src/progs/pickit1/base/pickit1_prog.cpp @@ -0,0 +1,28 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "pickit1_prog.h" + +#include "pickit1.h" + +//---------------------------------------------------------------------------- +bool Pickit1::Base::deviceHasOsccalRegeneration() const +{ + return data(device()->name()).regenerateOsccal; +} + +bool Pickit1::Base::setTarget() +{ + return static_cast(_specific)->init(); +} + +//---------------------------------------------------------------------------- +Programmer::Hardware *Pickit1::Group::createHardware(Programmer::Base &base, const ::Programmer::HardwareDescription &) const +{ + return new Hardware(base); +} diff --git a/src/progs/pickit1/base/pickit1_prog.h b/src/progs/pickit1/base/pickit1_prog.h new file mode 100644 index 0000000..c0763b4 --- /dev/null +++ b/src/progs/pickit1/base/pickit1_prog.h @@ -0,0 +1,47 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PICKIT1_PROG_H +#define PICKIT1_PROG_H + +#include "progs/pickit2/base/pickit_prog.h" + +namespace Pickit1 +{ +//---------------------------------------------------------------------------- +class Base : public Pickit::Base +{ +Q_OBJECT +public: + Base(const Programmer::Group &group, const Pic::Data *data) : Pickit::Base(group, data) {} + virtual bool deviceHasOsccalRegeneration() const; + virtual bool canReadVoltage(Pic::VoltageType) const { return false; } + virtual bool setTarget(); + +private: + virtual VersionData firmwareVersion(Programmer::FirmwareVersionType) const { return VersionData(2, 0, 0); } +}; + +//---------------------------------------------------------------------------- +class Group : public Pickit::Group +{ +public: + virtual QString name() const { return "pickit1"; } + virtual QString label() const { return i18n("PICkit1"); } + virtual Programmer::Properties properties() const { return ::Programmer::Programmer | ::Programmer::HasFirmware | ::Programmer::CanReadMemory | ::Programmer::HasConnectedState; } + +protected: + virtual void initSupported(); + virtual Programmer::Base *createBase(const Device::Data *data) const { return new ::Pickit1::Base(*this, static_cast(data)); } + virtual Programmer::Hardware *createHardware(Programmer::Base &base, const ::Programmer::HardwareDescription &hd) const; + virtual Programmer::DeviceSpecific *createDeviceSpecific(Programmer::Base &base) const; +}; + +} // namespace + +#endif diff --git a/src/progs/pickit1/gui/Makefile.am b/src/progs/pickit1/gui/Makefile.am new file mode 100644 index 0000000..239184b --- /dev/null +++ b/src/progs/pickit1/gui/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libpickit1ui.la +libpickit1ui_la_SOURCES = pickit1_group_ui.cpp +libpickit1ui_la_LDFLAGS = $(all_libraries) diff --git a/src/progs/pickit1/gui/pickit1_group_ui.cpp b/src/progs/pickit1/gui/pickit1_group_ui.cpp new file mode 100644 index 0000000..2c862fb --- /dev/null +++ b/src/progs/pickit1/gui/pickit1_group_ui.cpp @@ -0,0 +1,23 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "pickit1_group_ui.h" + +#include "progs/gui/prog_config_widget.h" +#include "progs/pickit2/gui/pickit2_group_ui.h" +#include "progs/pickit1/base/pickit1_prog.h" + +::Programmer::ConfigWidget *Pickit1::GroupUI::createConfigWidget(QWidget *parent) const +{ + return new ::Programmer::ConfigWidget(static_cast(group()), parent); +} + +::Programmer::AdvancedDialog *Pickit1::GroupUI::createAdvancedDialog(::Programmer::Base &base, QWidget *parent) const +{ + return new Pickit::AdvancedDialog(static_cast(base), parent, "pickit1_advanced_dialog"); +} diff --git a/src/progs/pickit1/gui/pickit1_group_ui.h b/src/progs/pickit1/gui/pickit1_group_ui.h new file mode 100644 index 0000000..5fb8ad6 --- /dev/null +++ b/src/progs/pickit1/gui/pickit1_group_ui.h @@ -0,0 +1,27 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PICKIT1_GROUP_UI_H +#define PICKIT1_GROUP_UI_H + +#include "devices/pic/gui/pic_prog_group_ui.h" + +namespace Pickit1 +{ + +class GroupUI : public ::Programmer::GroupUI +{ +public: + virtual ::Programmer::ConfigWidget *createConfigWidget(QWidget *parent) const; + virtual bool hasAdvancedDialog() const { return true; } + virtual ::Programmer::AdvancedDialog *createAdvancedDialog(::Programmer::Base &base, QWidget *parent) const; +}; + +} // namespace + +#endif diff --git a/src/progs/pickit1/pickit1.pro b/src/progs/pickit1/pickit1.pro new file mode 100644 index 0000000..60ac0f5 --- /dev/null +++ b/src/progs/pickit1/pickit1.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = xml base diff --git a/src/progs/pickit1/xml/Makefile.am b/src/progs/pickit1/xml/Makefile.am new file mode 100644 index 0000000..f0cc91a --- /dev/null +++ b/src/progs/pickit1/xml/Makefile.am @@ -0,0 +1,14 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_PROGRAMS = xml_pickit1_parser +xml_pickit1_parser_SOURCES = xml_pickit1_parser.cpp +OBJECTS = $(top_builddir)/src/devices/list/libdevicelistnoui.la \ + $(top_builddir)/src/devices/pic/pic/libpic.la $(top_builddir)/src/devices/pic/base/libpicbase.la \ + $(top_builddir)/src/devices/pic/xml_data/libpicxml.la \ + $(top_builddir)/src/devices/mem24/mem24/libmem24.la $(top_builddir)/src/devices/mem24/base/libmem24base.la \ + $(top_builddir)/src/devices/mem24/xml_data/libmem24xml.la \ + $(top_builddir)/src/xml_to_data/libxmltodata.la $(top_builddir)/src/devices/base/libdevicebase.la \ + $(top_builddir)/src/common/common/libcommon.la +xml_pickit1_parser_DEPENDENCIES = $(OBJECTS) +xml_pickit1_parser_LDADD = $(OBJECTS) $(LIB_KDECORE) diff --git a/src/progs/pickit1/xml/xml.pro b/src/progs/pickit1/xml/xml.pro new file mode 100644 index 0000000..e368c49 --- /dev/null +++ b/src/progs/pickit1/xml/xml.pro @@ -0,0 +1,18 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/app.pro) + +TARGET = xml_pickit1_parser +SOURCES += xml_pickit1_parser.cpp +LIBS += ../../../devices/list/libdevicelist.a \ + ../../../devices/mem24/mem24/libmem24.a ../../../devices/mem24/xml_data/libmem24xml.a \ + ../../../devices/mem24/base/libmem24base.a \ + ../../../devices/pic/pic/libpic.a ../../../devices/pic/xml_data/libpicxml.a \ + ../../../devices/pic/base/libpicbase.a ../../../xml_to_data/libxmltodata.a \ + ../../../devices/base/libdevicebase.a ../../../common/global/libglobal.a \ + ../../../common/nokde/libnokde.a ../../../common/common/libcommon.a + +unix:QMAKE_POST_LINK = cd ../base && ../xml/xml_pickit1_parser +unix:QMAKE_CLEAN += ../base/pickit1_data.cpp +win32:QMAKE_POST_LINK = cd ..\base && ..\xml\xml_pickit1_parser.exe +win32:QMAKE_CLEAN += ..\base\pickit1_data.cpp + diff --git a/src/progs/pickit1/xml/xml_pickit1_parser.cpp b/src/progs/pickit1/xml/xml_pickit1_parser.cpp new file mode 100644 index 0000000..e5d1b78 --- /dev/null +++ b/src/progs/pickit1/xml/xml_pickit1_parser.cpp @@ -0,0 +1,61 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "xml_to_data/prog_xml_to_data.h" +#include "progs/pickit1/base/pickit1_data.h" + +namespace Pickit1 +{ + +class XmlToData : public Programmer::XmlToData +{ +public: + XmlToData() : Programmer::XmlToData("pickit1", "Pickit1") {} + +private: + virtual void parseData(QDomElement element, Data &data); + virtual void outputData(const Data &data, QTextStream &s) const; + virtual void outputFunctions(QTextStream &s) const; +}; + +void Pickit1::XmlToData::parseData(QDomElement element, Data &data) +{ + QString s = element.attribute("entry"); + if ( s.length()!=1 || (s[0]!='O' && s[0]!='P') ) qFatal("Invalid or missing entry mode"); + data.entryMode = s[0].latin1(); + s = element.attribute("regen"); + if ( s.isEmpty() || s=="false" ) data.regenerateOsccal = false; + else if ( s=="true" ) data.regenerateOsccal = true; + else qFatal("Invalid regen value"); +} + +void Pickit1::XmlToData::outputData(const Data &data, QTextStream &s) const +{ + s << "'" << data.entryMode << "', " << (data.regenerateOsccal ? "true" : "false"); +} + +void Pickit1::XmlToData::outputFunctions(QTextStream &s) const +{ + Programmer::XmlToData::outputFunctions(s); + s << "::Programmer::DeviceSpecific *Group::createDeviceSpecific(Programmer::Base &base) const" << endl; + s << "{" << endl; + s << " uint i = family(static_cast< ::Pickit1::Base &>(base).device()->name());" << endl; + s << " switch(i) {" << endl; + for (uint i=0; i * + * * + * 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. * + ***************************************************************************/ +#include "pickit.h" + +#include "devices/base/device_group.h" +#include "progs/base/prog_group.h" + +//----------------------------------------------------------------------------- +Pickit::Array::Array(uint length, uchar fillChar, PrintMode mode) + : _fillChar(fillChar), _mode(mode), _data(length) +{ + _data.fill(fillChar); +} + +QString Pickit::Array::pretty() const +{ + int end = _data.count() - 1; + for (; end>=0; end--) + if ( _data[end]!=_fillChar ) break; + QString s; + for (int i=0; i<=end; i++) s += toPrintable(_data[i], _mode); + return s; +} + +//----------------------------------------------------------------------------- +Pickit::USBPort::USBPort(uint deviceId, Log::Base &log) + : Port::USB(log, Microchip::VENDOR_ID, deviceId, CONFIG_VENDOR, 0) +{} + +bool Pickit::USBPort::command(uchar c) +{ + Array a = array(); + a._data[0] = c; + return command(a); +} + +bool Pickit::USBPort::command(const char *s) +{ + Array a = array(); + if (s) { + Q_ASSERT( strlen(s)<=a.length() ); + for (uint i=0; i &words, uint offset) +{ + log(Log::DebugLevel::Max, QString("receive words nbBytesWord=%1 nbRead=%2 offset=%3").arg(nbBytesWord).arg(nbRead).arg(offset)); + Array a = array(); + QMemArray data(nbRead*a.length()); + uint l = 0; + for (uint i=0; i=data.count() ) break; + } + return port().command(cmd); +} + +bool Pickit::Hardware::regenerateOsccal(BitValue &newValue) +{ + if ( !setTargetPower(Osc2_5kHz) ) return false; + if ( !setTargetPower(PowerOn + Osc2_5kHz) ) return false; + Port::usleep(400000); // 400 ms + if ( !setTargetPower(PowerOff) ) return false; + Pickit::Array cmd = port().array(); + cmd[0] = 'P'; + cmd[1] = 'I'; + cmd[2] = 120; + cmd[3] = 0; + cmd[4] = 'r'; + cmd[5] = 'p'; + if ( !port().command(cmd) ) return false; + QValueVector words; + if ( !port().receiveWords(1, 1, words) ) return false; + newValue = words[7] | 0x3400; + return true; +} + +//---------------------------------------------------------------------------- +bool Pickit::DeviceSpecific::setPowerOn() +{ + return hardware().port().command(entryMode()); +} + +bool Pickit::DeviceSpecific::setPowerOff() +{ + return hardware().port().command('p'); +} + +bool Pickit::DeviceSpecific::setTargetPowerOn(bool on) +{ + return hardware().setTargetPower(on ? PowerOn : PowerOff); +} + +//---------------------------------------------------------------------------- +bool Pickit::BMDeviceSpecific::doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata) +{ + data.resize(device().nbWords(type)); + gotoMemory(type); + QValueVector words; + switch (type.type()) { + case Pic::MemoryRangeType::Config: + case Pic::MemoryRangeType::Code: + case Pic::MemoryRangeType::Cal: + case Pic::MemoryRangeType::CalBackup: + case Pic::MemoryRangeType::UserId: + case Pic::MemoryRangeType::DeviceId: + for (uint i=0; i=data.count() ) break; + } + } + break; + case Pic::MemoryRangeType::Eeprom: + for (uint i=0; i=data.count() ) break; + } + } + break; + case Pic::MemoryRangeType::DebugVector: + case Pic::MemoryRangeType::HardwareStack: + case Pic::MemoryRangeType::ProgramExecutive: + case Pic::MemoryRangeType::Nb_Types: Q_ASSERT(false); return false; + } + if ( type==Pic::MemoryRangeType::Code || type==Pic::MemoryRangeType::Eeprom ) + _base.progressMonitor().addTaskProgress(data.count()); + return true; +} + +bool Pickit::BMDeviceSpecific::incrementPC(uint nb) +{ + Pickit::Array cmd = hardware().port().array(); + cmd[0] = 'I'; + cmd[1] = nb & 0xFF; + cmd[2] = (nb >> 8) & 0xFF; + return hardware().port().command(cmd); +} + +bool Pickit::BMDeviceSpecific::doEraseRange(Pic::MemoryRangeType type) +{ + Q_ASSERT( type==Pic::MemoryRangeType::Code ); + return hardware().port().command('E'); +} + +bool Pickit::BMDeviceSpecific::doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force) +{ + // #### TODO: speed optimize... + Q_UNUSED(force); + gotoMemory(type); + uint nb = nbWrites(type); + switch (type.type()) { + case Pic::MemoryRangeType::Config: + case Pic::MemoryRangeType::Code: + case Pic::MemoryRangeType::Cal: + case Pic::MemoryRangeType::UserId: + for (uint i=0; i * + * * + * 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. * + ***************************************************************************/ +#ifndef PICKIT_H +#define PICKIT_H + +#include "progs/icd2/base/microchip.h" +#include "common/port/usb_port.h" +#include "devices/pic/pic/pic_memory.h" +#include "devices/pic/prog/pic_prog.h" + +namespace Pickit +{ +enum PowerType { PowerOff = 0, PowerOn = 1, Osc2_5kHz = 2 }; + +//----------------------------------------------------------------------------- +class Array +{ +public: + uint length() const { return _data.count(); } + QString pretty() const; + uchar &operator[](uint i) { return _data[i]; } + uchar operator[](uint i) const { return _data[i]; } + +protected: + Array(uint length, uchar fillChar, PrintMode mode); + +private: + uchar _fillChar; + PrintMode _mode; + QMemArray _data; + + friend class USBPort; +}; + +//----------------------------------------------------------------------------- +class USBPort : public Port::USB +{ +public: + USBPort(uint deviceId, Log::Base &manager); + virtual Array array() const = 0; + bool command(const Array &cmd); + bool command(uchar c); + bool command(const char *s); + bool receive(Array &data); + bool getMode(VersionData &version, ::Programmer::Mode &mode); + bool receiveWords(uint nbBytesWord, uint nbRead, QValueVector &data, uint offset = 0); + +protected: + virtual uint writeEndPoint() const = 0; + virtual uint readEndPoint() const = 0; + +private: + virtual uint timeout(uint) const { return 10000; } // 10s + enum { CONFIG_HID = 1, // use HID for pickit configuration + CONFIG_VENDOR = 2 // vendor specific configuration + }; +}; + +//----------------------------------------------------------------------------- +class Hardware : public ::Programmer::PicHardware +{ +public: + Hardware(::Programmer::Base &base, USBPort *port); + bool setTargetPower(uint value); + USBPort &port() { return static_cast(*_port); } + const USBPort &port() const { return static_cast(*_port); } + bool writeWords(uint max, char c, uint nbBytesWord, + uint &i, const Device::Array &data); + bool regenerateOsccal(BitValue &newValue); + +protected: + virtual bool internalConnectHardware(); +}; + +//----------------------------------------------------------------------------- +class DeviceSpecific : public ::Programmer::PicDeviceSpecific +{ +public: + DeviceSpecific(::Programmer::Base &base) : ::Programmer::PicDeviceSpecific(base) {} + virtual bool canEraseAll() const { return true; } + virtual bool canEraseRange(Pic::MemoryRangeType type) const { return ( type==Pic::MemoryRangeType::Code || type==Pic::MemoryRangeType::Eeprom ); } + virtual bool canReadRange(Pic::MemoryRangeType) const { return true; } + virtual bool canWriteRange(Pic::MemoryRangeType) const { return true; } + Hardware &hardware() { return static_cast(*_base.hardware()); } + virtual bool init() = 0; + virtual bool setPowerOn(); + virtual bool setPowerOff(); + virtual bool setTargetPowerOn(bool on); + virtual char entryMode() const = 0; +}; + +//----------------------------------------------------------------------------- +class BMDeviceSpecific : public DeviceSpecific +{ +public: + BMDeviceSpecific(::Programmer::Base &base) : DeviceSpecific(base) {} + virtual bool gotoMemory(Pic::MemoryRangeType type) = 0; + virtual bool doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata); + virtual bool incrementPC(uint nb); + virtual uint nbWrites(Pic::MemoryRangeType type) const = 0; + virtual char writeCode() const = 0; + virtual char writeData() const = 0; + virtual bool doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force); + virtual bool doEraseRange(Pic::MemoryRangeType type); +}; + +//----------------------------------------------------------------------------- +class Baseline : public BMDeviceSpecific +{ +public: + Baseline(::Programmer::Base &base) : BMDeviceSpecific(base) {} + virtual bool doErase(bool) { return doEraseRange(Pic::MemoryRangeType::Code); } + virtual bool gotoMemory(Pic::MemoryRangeType type); + virtual char writeCode() const { return 'w'; } + virtual char writeData() const { return 'D'; } +}; + +class P16F : public BMDeviceSpecific +{ +public: + P16F(::Programmer::Base &base) : BMDeviceSpecific(base) {} + virtual bool gotoMemory(Pic::MemoryRangeType type); + virtual bool doEraseRange(Pic::MemoryRangeType type); + virtual bool doErase(bool); + virtual char writeCode() const { return 'W'; } + virtual char writeData() const { return 'D'; } +}; + +} // namespace + +#endif diff --git a/src/progs/pickit2/base/pickit2.cpp b/src/progs/pickit2/base/pickit2.cpp new file mode 100644 index 0000000..6458fa2 --- /dev/null +++ b/src/progs/pickit2/base/pickit2.cpp @@ -0,0 +1,447 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "pickit2.h" + +#include "common/global/global.h" +#include "devices/list/device_list.h" +#include "common/port/port.h" + +//----------------------------------------------------------------------------- +void Pickit2::USBPort::fillCommand(Pickit::Array &cmd, uchar command, uint nbBytes, + uint address, uint i, bool longAddress) const +{ + cmd[i] = command; + cmd[i+1] = nbBytes; + cmd[i+2] = address & 0xFF; + cmd[i+3] = (address >> 8) & 0xFF; + if (longAddress) cmd[i+4] = (address >> 16) & 0xFF; +} + +Pickit::Array Pickit2::USBPort::createCommand(uchar c, uint nbBytes, uint address, bool longAddress) const +{ + Array cmd; + fillCommand(cmd, c, nbBytes, address, 0, longAddress); + return cmd; +} + +bool Pickit2::USBPort::readFirmwareCodeMemory(Device::Array &data, const Device::Array *vdata, ProgressMonitor &monitor) +{ + const Pic::Data *device = static_cast(Device::lister().data("18F2455")); + log(Log::DebugLevel::Normal, " Read pickit2 firmware"); + for (uint i=0; istart; end--) if ( data[i + end].isInitialized() ) break; + uint nb = end - start + 1; + Pickit::Array cmd = createCommand(1, 2*nb, 2*i); + if ( !command(cmd) ) return false; + QValueVector read; + if ( !receiveWords(1, 1, read) ) return false; + for (uint k=0; k=0x1000 && index<0x3FF0 && data[index]!=(*vdata)[index] ) { + log(Log::LineType::Error, i18n("Firmware memory does not match hex file (at address 0x%2: reading 0x%3 and expecting 0x%4).") + .arg(QString(toHex(index/2, device->nbCharsAddress()))) + .arg(QString(toHex(data[index], device->nbCharsWord(Pic::MemoryRangeType::Code)))) + .arg(QString(toHex((*vdata)[index], device->nbCharsWord(Pic::MemoryRangeType::Code))))); + return false; + } + } + } + monitor.addTaskProgress(data.count()); + return true; +} + +bool Pickit2::USBPort::eraseFirmwareCodeMemory() +{ + log(Log::DebugLevel::Normal, " Erase pickit2 firmware"); + Pickit::Array cmd = createCommand(3, 0xC0, 0x2000); + if ( !command(cmd) ) return false; // erase 0x2000-0x4FFF + Port::usleep(1000000); + cmd = createCommand(3, 0xC0, 0x5000); + if ( !command(cmd) ) return false; // erase 0x5000-0x7FFF + Port::usleep(1000000); + return true; +} + +bool Pickit2::USBPort::writeFirmwareCodeMemory(const Device::Array &data, ProgressMonitor &monitor) +{ + log(Log::DebugLevel::Normal, " Write pickit2 firmware"); + for (uint i=0x1000; istart; end--) if ( data[i + end].isInitialized() ) break; + uint nb = end - start + 1; + Pickit::Array cmd = createCommand(2, 2*nb, 2*i); + for (uint k=0; k> 8; + uint cvpp = uint(18.61 * vpp); + cmd[3] = 0x40; + cmd[4] = cvpp; + cmd[5] = uchar(4.5 * (cvdd >> 8)); // linit to 75% of vdd + cmd[6] = uchar(0.75 * cvpp); // linit to 75% of vpp + if ( !port().command(cmd) ) return false; + // wait until vpp is stabilized + for (uint i=0; i<30; i++) { + Port::usleep(50000); + VoltagesData voltages; + if ( !readVoltages(voltages) ) return false; + if ( voltages[Pic::TargetVpp].value<(vpp+0.5) ) break; + } + return true; +} + +//----------------------------------------------------------------------------- +bool Pickit2::Baseline::init() +{ + Array cmd; + cmd[0] = 'c'; + cmd[1] = 0x00; // Load Configuration + cmd[2] = 0x02; // Load Program latches + cmd[3] = 0x03; // Load Data latches + cmd[4] = 0x04; // Read Program memory + cmd[5] = 0x05; // Read Data latches + cmd[6] = 0x06; // Increment Address + cmd[7] = 0x08; // Begin programming internally timed + cmd[8] = 0x08; // Begin Programming externally timed + cmd[9] = 0x0E; // End externally time programming cycle + cmd[10] = 0x09; // Bulk Erase program memory + cmd[11] = 0x0B; // Bulk Erase Data memory + cmd[12] = 0xFF; // Read Program memory + cmd[13] = 0xFF; // Read Data latches + cmd[14] = 0xFF; // Increment Address + cmd[15] = 0xFF; // Begin programming internally timed + return hardware().port().command(cmd); +} + +//----------------------------------------------------------------------------- +bool Pickit2::P16F::init() +{ + Array cmd; + cmd[0] = 'c'; + cmd[1] = 0x00; // Load Configuration + cmd[2] = 0x02; // Load Program latches + cmd[3] = 0x03; // Load Data latches + cmd[4] = 0x04; // Read Program memory + cmd[5] = 0x05; // Read Data latches + cmd[6] = 0x06; // Increment Address + cmd[7] = 0x08; // Begin programming internally timed + cmd[8] = 0x18; // Begin Programming externally timed + cmd[9] = 0x0A; // End externally time programming cycle + cmd[10] = 0x09; // Bulk Erase program memory + cmd[11] = 0x0B; // Bulk Erase Data memory + cmd[12] = 0xFF; // Read Program memory + cmd[13] = 0xFF; // Read Data latches + cmd[14] = 0xFF; // Increment Address + cmd[15] = 0xFF; // Begin programming internally timed + return hardware().port().command(cmd); +} + +//----------------------------------------------------------------------------- +bool Pickit2::P16F87XA::init() +{ + Array cmd; + cmd[0] = 'c'; + cmd[1] = 0x00; // Load Configuration + cmd[2] = 0x02; // Load Program latches + cmd[3] = 0x03; // Load Data latches + cmd[4] = 0x04; // Read Program memory + cmd[5] = 0x05; // Read Data latches + cmd[6] = 0x06; // Increment Address + cmd[7] = 0x08; // Begin programming internally timed + cmd[8] = 0x18; // Begin Programming externally timed + cmd[9] = 0x17; // End externally time programming cycle + cmd[10] = 0x1F; // Bulk Erase program memory + cmd[11] = 0x1F; // Bulk Erase Data memory + cmd[12] = 0xFF; // Read Program memory + cmd[13] = 0xFF; // Read Data latches + cmd[14] = 0xFF; // Increment Address + cmd[15] = 0xFF; // Begin programming internally timed + return hardware().port().command(cmd); +} + +//----------------------------------------------------------------------------- +bool Pickit2::P16F7X::init() +{ + Array cmd; + cmd[0] = 'c'; + cmd[1] = 0x00; // Load Configuration + cmd[2] = 0x02; // Load Program latches + cmd[3] = 0x03; // Load Data latches + cmd[4] = 0x04; // Read Program memory + cmd[5] = 0x05; // Read Data latches + cmd[6] = 0x06; // Increment Address + cmd[7] = 0x08; // Begin programming internally timed + cmd[8] = 0x08; // Begin Programming externally timed + cmd[9] = 0x0E; // End externally time programming cycle + cmd[10] = 0x09; // Bulk Erase program memory + cmd[11] = 0x0B; // Bulk Erase Data memory + cmd[12] = 0xFF; // Read Program memory + cmd[13] = 0xFF; // Read Data latches + cmd[14] = 0xFF; // Increment Address + cmd[15] = 0xFF; // Begin programming internally timed + return hardware().port().command(cmd); +} + +bool Pickit2::P16F716::init() +{ + Array cmd; + cmd[0] = 'c'; + cmd[1] = 0x00; // Load Configuration + cmd[2] = 0x02; // Load Program latches + cmd[3] = 0x03; // Load Data latches + cmd[4] = 0x04; // Read Program memory + cmd[5] = 0x05; // Read Data latches + cmd[6] = 0x06; // Increment Address + cmd[7] = 0x08; // Begin programming internally timed + cmd[8] = 0x18; // Begin Programming externally timed + cmd[9] = 0x0E; // End externally time programming cycle + cmd[10] = 0x09; // Bulk Erase program memory + cmd[11] = 0x0B; // Bulk Erase Data memory + cmd[12] = 0xFF; // Read Program memory + cmd[13] = 0xFF; // Read Data latches + cmd[14] = 0xFF; // Increment Address + cmd[15] = 0xFF; // Begin programming internally timed + return hardware().port().command(cmd); +} + +//----------------------------------------------------------------------------- +bool Pickit2::P18F::init() +{ + Array cmd; + cmd[0] = 'c'; + cmd[1] = 0x00; // Load Configuration + cmd[2] = 0x02; // Load Program latches + cmd[3] = 0x03; // Load Data latches + cmd[4] = 0x04; // Read Program memory + cmd[5] = 0x05; // Read Data latches + cmd[6] = 0x06; // Increment Address + cmd[7] = 0x08; // Begin programming internally timed + cmd[8] = 0x18; // Begin Programming externally timed + cmd[9] = 0x0A; // End externally time programming cycle + cmd[10] = 0x09; // Bulk Erase program memory + cmd[11] = 0x0B; // Bulk Erase Data memory + cmd[12] = 0xFF; // Read Program memory + cmd[13] = 0xFF; // Read Data latches + cmd[14] = 0xFF; // Increment Address + cmd[15] = 0xFF; // Begin programming internally timed + return hardware().port().command(cmd); +} + +bool Pickit2::P18F::doEraseCommand(uint cmd1, uint cmd2) +{ + Array cmd; + cmd[0] = 0x85; + cmd[1] = cmd1; + cmd[2] = cmd2; + return hardware().port().command(cmd); +} + +bool Pickit2::P18F::doEraseRange(Pic::MemoryRangeType type) +{ + if ( type==Pic::MemoryRangeType::Eeprom ) return doEraseCommand(0x84, 0x00); + Q_ASSERT( type==Pic::MemoryRangeType::Code ); + if ( !doEraseCommand(0x81, 0x00) ) return false; // boot + for (uint i=0; i(hardware().port()); + data.resize(device().nbWords(type)); + QValueVector words; + switch (type.type()) { + case Pic::MemoryRangeType::DeviceId: + case Pic::MemoryRangeType::UserId: + case Pic::MemoryRangeType::Config: { + Pickit::Array cmd = port.createCommand(0x80, data.count(), device().range(type).start.toUInt()); + if ( !port.command(cmd) ) return false; + if ( !hardware().port().receiveWords(1, 1, words) ) return false; + for (uint k=0; k(hardware().port()); + switch (type.type()) { + case Pic::MemoryRangeType::UserId: { + Pickit::Array cmd = port.createCommand(0x82, data.count() / 2, device().range(type).start.toUInt()); + for (uint i=0; i * + * * + * 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. * + ***************************************************************************/ +#ifndef PICKIT2_H +#define PICKIT2_H + +#include "pickit.h" +#include "pickit2_data.h" + +namespace Pickit2 +{ +//----------------------------------------------------------------------------- +class Array : public Pickit::Array +{ +public: + Array() : Pickit::Array(64, 'Z', PrintAlphaNum) {} +}; + +//----------------------------------------------------------------------------- +class USBPort : public Pickit::USBPort +{ +public: + USBPort(Log::Base &log) : Pickit::USBPort(0x0033, log) {} + virtual Pickit::Array array() const { return Array(); } + void fillCommand(Pickit::Array &cmd1, uchar cmd2, uint nbBytes, uint address, uint i, bool longAddress = true) const; + Pickit::Array createCommand(uchar cmd, uint nbBytes, uint address, bool longAddress = true) const; + + bool readFirmwareCodeMemory(Device::Array &data, const Device::Array *vdata, ProgressMonitor &monitor); + //bool readFirmwareEepromMemory(Device::Array &data); + bool eraseFirmwareCodeMemory(); + bool writeFirmwareCodeMemory(const Device::Array &data, ProgressMonitor &monitor); + //bool writeFirmwareEepromMemory(const Device::Array &data); + bool resetFirmwareDevice(::Programmer::Mode mode) { return command(mode==::Programmer::BootloadMode ? 'B' : 0xFF); } + bool uploadFirmware(const Pic::Memory &memory, ProgressMonitor &monitor); + +private: + virtual uint readEndPoint() const { return 0x81; } + virtual uint writeEndPoint() const { return 0x01; } +}; + +//----------------------------------------------------------------------------- +class Hardware : public Pickit::Hardware +{ +public: + Hardware(::Programmer::Base &base) : Pickit::Hardware(base, new USBPort(base)) {} + virtual bool readVoltages(VoltagesData &voltages); + bool setVddVpp(double vdd, double vpp); +}; + +//----------------------------------------------------------------------------- +class Baseline : public Pickit::Baseline +{ +public: + Baseline(::Programmer::Base &base) : Pickit::Baseline(base) {} + virtual bool init(); + virtual char entryMode() const { return data(device().name()).entryMode; } + virtual uint nbWrites(Pic::MemoryRangeType type) const { return (type==Pic::MemoryRangeType::Eeprom ? 4 : 16); } +}; + +//----------------------------------------------------------------------------- +class P16F : public Pickit::P16F +{ +public: + P16F(::Programmer::Base &base) : Pickit::P16F(base) {} + virtual bool init(); + virtual char entryMode() const { return data(device().name()).entryMode; } + virtual uint nbWrites(Pic::MemoryRangeType type) const { return (type==Pic::MemoryRangeType::Code ? 16 : 4); } +}; + +class P16F87XA : public P16F +{ +public: + P16F87XA(::Programmer::Base &base) : P16F(base) {} + virtual bool init(); +}; + +class P16F7X : public P16F +{ +public: + P16F7X(::Programmer::Base &base) : P16F(base) {} + virtual bool init(); + virtual char writeCode() const { return 'w'; } +}; + +class P16F716 : public P16F +{ +public: + P16F716(::Programmer::Base &base) : P16F(base) {} + virtual bool init(); +}; + +//----------------------------------------------------------------------------- +class P18F : public Pickit::DeviceSpecific +{ +public: + P18F(::Programmer::Base &base) : Pickit::DeviceSpecific(base) {} + Hardware &hardware() { return static_cast(Pickit::DeviceSpecific::hardware()); } + virtual bool init(); + virtual bool doEraseRange(Pic::MemoryRangeType type); + virtual bool doErase(bool) { return doEraseCommand(0x87, 0x0F); } + bool doEraseCommand(uint cmd1, uint cmd2); + virtual bool doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata); + virtual bool doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force); + virtual char entryMode() const { return data(device().name()).entryMode; } +}; + +class P18F2X20 : public P18F +{ +public: + P18F2X20(::Programmer::Base &base) : P18F(base) {} + virtual bool doEraseRange(Pic::MemoryRangeType type); + virtual bool doErase(bool) { return doEraseCommand(0x80); } + bool doEraseCommand(uint cmd); +}; + +} // namespace + +#endif diff --git a/src/progs/pickit2/base/pickit2.xml b/src/progs/pickit2/base/pickit2.xml new file mode 100644 index 0000000..044b7bc --- /dev/null +++ b/src/progs/pickit2/base/pickit2.xml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/progs/pickit2/base/pickit2_data.h b/src/progs/pickit2/base/pickit2_data.h new file mode 100644 index 0000000..abae867 --- /dev/null +++ b/src/progs/pickit2/base/pickit2_data.h @@ -0,0 +1,24 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PICKIT2_DATA_H +#define PICKIT2_DATA_H + +#include + +namespace Pickit2 +{ + struct Data { + char entryMode, progMode; + uchar progWidth; + bool regenerateOsccal; + }; + extern const Data &data(const QString &device); +} // namespace + +#endif diff --git a/src/progs/pickit2/base/pickit2_prog.cpp b/src/progs/pickit2/base/pickit2_prog.cpp new file mode 100644 index 0000000..88b73b9 --- /dev/null +++ b/src/progs/pickit2/base/pickit2_prog.cpp @@ -0,0 +1,78 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "pickit2_prog.h" + +#include "devices/list/device_list.h" +#include "pickit2.h" + +//---------------------------------------------------------------------------- +VersionData Pickit2::Base::firmwareVersion(Programmer::FirmwareVersionType type) const +{ + switch (type.type()) { + case Programmer::FirmwareVersionType::Min: return VersionData(1, 10, 0); + case Programmer::FirmwareVersionType::Recommended: + case Programmer::FirmwareVersionType::Max: return VersionData(1, 20, 0); + case Programmer::FirmwareVersionType::Nb_Types: break; + } + Q_ASSERT(false); + return VersionData(); +} + +bool Pickit2::Base::deviceHasOsccalRegeneration() const +{ + return data(device()->name()).regenerateOsccal; +} + +bool Pickit2::Base::setTarget() +{ + // #### FIXME: this needs to test for 18J first to protected them + if ( !static_cast(hardware()).setVddVpp(5.0, 12.0) ) return false; + return static_cast(_specific)->init(); +} + +bool Pickit2::Base::internalEnterMode(::Programmer::Mode mode) +{ + USBPort &port = static_cast(hardware().port()); + if ( !port.resetFirmwareDevice(mode) ) return false; + log(Log::DebugLevel::Extra, "disconnecting and try to reconnect PICkit2 in new mode..."); + disconnectHardware(); + Port::usleep(3000000); + return connectHardware(); +} + +bool Pickit2::Base::doUploadFirmware(PURL::File &file) +{ + const Pic::Data &data = static_cast(*Device::lister().data("18F2550")); + Pic::Memory memory(static_cast(data)); + QStringList errors, warnings; + Pic::Memory::WarningTypes warningTypes; + if ( !memory.load(file.stream(), errors, warningTypes, warnings) ) { + log(Log::LineType::Error, i18n("Could not read firmware hex file \"%1\" (%2).").arg(file.url().pretty()).arg(errors[0])); + return false; + } + if ( warningTypes!=Pic::Memory::NoWarning ) { + log(Log::LineType::Error, i18n("Firmware hex file seems incompatible with device 18F2550 inside PICkit2.")); + return false; + } + log(Log::LineType::Information, i18n(" Uploading PICkit2 firmware...")); + if ( !enterMode(::Programmer::BootloadMode) ) return false; + _progressMonitor.insertTask(i18n("Uploading Firmware..."), 2*data.nbWords(Pic::MemoryRangeType::Code)); + if ( !static_cast(hardware().port()).uploadFirmware(memory, _progressMonitor) ) { + log(Log::LineType::Error, i18n("Failed to upload firmware.")); + return false; + } + log(Log::LineType::Information, i18n("Firmware succesfully uploaded.")); + return enterMode(::Programmer::NormalMode); +} + +//---------------------------------------------------------------------------- +Programmer::Hardware *Pickit2::Group::createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &) const +{ + return new Hardware(base); +} diff --git a/src/progs/pickit2/base/pickit2_prog.h b/src/progs/pickit2/base/pickit2_prog.h new file mode 100644 index 0000000..5a67e2a --- /dev/null +++ b/src/progs/pickit2/base/pickit2_prog.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PICKIT2_PROG_H +#define PICKIT2_PROG_H + +#include "common/global/global.h" +#include "pickit_prog.h" + +namespace Pickit2 +{ +//---------------------------------------------------------------------------- +class Base : public Pickit::Base +{ +Q_OBJECT +public: + Base(const Programmer::Group &group, const Pic::Data *data) : Pickit::Base(group, data) {} + virtual bool deviceHasOsccalRegeneration() const; + virtual bool setTarget(); + +private: + virtual VersionData firmwareVersion(Programmer::FirmwareVersionType type) const; + virtual bool internalEnterMode(::Programmer::Mode mode); + virtual bool doUploadFirmware(PURL::File &file); +}; + +//---------------------------------------------------------------------------- +class Group : public Pickit::Group +{ +public: + virtual QString name() const { return "pickit2"; } + virtual QString label() const { return i18n("PICkit2 Firmware 1.x"); } + virtual Programmer::Properties properties() const { return ::Programmer::Programmer | ::Programmer::HasFirmware | ::Programmer::CanUploadFirmware | ::Programmer::CanReadMemory | ::Programmer::HasConnectedState; } + virtual bool canReadVoltage(Pic::VoltageType type) const { return ( type==Pic::TargetVdd || type==Pic::TargetVpp ); } + +protected: + virtual void initSupported(); + virtual Programmer::Base *createBase(const Device::Data *data) const { return new ::Pickit2::Base(*this, static_cast(data)); } + virtual Programmer::Hardware *createHardware(Programmer::Base &base, const ::Programmer::HardwareDescription &hd) const; + virtual Programmer::DeviceSpecific *createDeviceSpecific(Programmer::Base &base) const; +}; + +} // namespace + +#endif diff --git a/src/progs/pickit2/base/pickit_prog.cpp b/src/progs/pickit2/base/pickit_prog.cpp new file mode 100644 index 0000000..c11dd08 --- /dev/null +++ b/src/progs/pickit2/base/pickit_prog.cpp @@ -0,0 +1,54 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "pickit_prog.h" + +#include "common/global/global.h" +#include "pickit.h" +#include "progs/base/prog_config.h" + +Pickit::Base::Base(const Programmer::Group &group, const Pic::Data *data) + : ::Programmer::PicBase(group, data, "pickit_programmer") +{} + +Pickit::Hardware &Pickit::Base::hardware() +{ + return static_cast(*_hardware); +} + +bool Pickit::Base::readFirmwareVersion() +{ + return hardware().port().getMode(_firmwareVersion, _mode); +} + +bool Pickit::Base::regenerateOsccal(const PURL::Url &url) +{ + log(Log::DebugLevel::Normal, QString(" Calibration firmware file: %1").arg(url.pretty())); + Log::StringView sview; + PURL::File file(url, sview); + if ( !file.openForRead() ) { + log(Log::LineType::Error, i18n("Could not open firmware file \"%1\".").arg(url.pretty())); + return false; + } + Pic::Memory memory(*device()); + QStringList errors, warnings; + Pic::Memory::WarningTypes warningTypes; + if ( !memory.load(file.stream(), errors, warningTypes, warnings) ) { + log(Log::LineType::Error, i18n("Could not read calibration firmware file \"%1\" (%2).").arg(url.pretty()).arg(errors[0])); + return false; + } + if ( warningTypes!=Pic::Memory::NoWarning ) { + log(Log::LineType::Error, i18n("Calibration firmware file seems incompatible with selected device %1.").arg(device()->name())); + return false; + } + if ( !askContinue(i18n("This will overwrite the device code memory. Continue anyway?")) ) return false; + if ( !program(memory, Pic::MemoryRange(Pic::MemoryRangeType::Nb_Types)) ) return false; + Device::Array array(1); + if ( !static_cast(hardware()).regenerateOsccal(array[0]) ) return false; + return programCalibration(array); +} diff --git a/src/progs/pickit2/base/pickit_prog.h b/src/progs/pickit2/base/pickit_prog.h new file mode 100644 index 0000000..b35fc92 --- /dev/null +++ b/src/progs/pickit2/base/pickit_prog.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PICKIT_PROG_H +#define PICKIT_PROG_H + +#include "common/global/global.h" +#include "progs/icd2/base/microchip.h" +#include "progs/base/prog_group.h" +#include "pickit.h" + +namespace Pickit +{ +class Hardware; + +//---------------------------------------------------------------------------- +class Base : public Programmer::PicBase +{ +Q_OBJECT +public: + Base(const Programmer::Group &group, const Pic::Data *data); + virtual bool deviceHasOsccalRegeneration() const = 0; + bool regenerateOsccal(const PURL::Url &url); + virtual bool readFirmwareVersion(); + +protected: + Hardware &hardware(); +}; + +//---------------------------------------------------------------------------- +class Group : public Programmer::PicGroup +{ +public: + virtual ::Programmer::TargetPowerMode targetPowerMode() const { return ::Programmer::TargetExternallyPowered; } + virtual bool isPortSupported(PortType type) const { return ( type==PortType::USB ); } +}; + +} // namespace + +#endif diff --git a/src/progs/pickit2/gui/Makefile.am b/src/progs/pickit2/gui/Makefile.am new file mode 100644 index 0000000..d2fa763 --- /dev/null +++ b/src/progs/pickit2/gui/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libpickit2ui.la +libpickit2ui_la_SOURCES = pickit2_group_ui.cpp +libpickit2ui_la_LDFLAGS = $(all_libraries) \ No newline at end of file diff --git a/src/progs/pickit2/gui/pickit2_group_ui.cpp b/src/progs/pickit2/gui/pickit2_group_ui.cpp new file mode 100644 index 0000000..f36395a --- /dev/null +++ b/src/progs/pickit2/gui/pickit2_group_ui.cpp @@ -0,0 +1,52 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "pickit2_group_ui.h" + +#include + +#include "common/global/purl.h" +#include "common/gui/misc_gui.h" +#include "progs/gui/prog_config_widget.h" +#include "progs/base/prog_group.h" +#include "progs/pickit2/base/pickit2_prog.h" +#include "progs/pickit2/base/pickit2.h" + +//---------------------------------------------------------------------------- +Pickit::AdvancedDialog::AdvancedDialog(Base &base, QWidget *parent, const char *name) + : ::Programmer::PicAdvancedDialog(base, parent, name) +{} + +void Pickit::AdvancedDialog::regenerateCalibration() +{ + if ( !base().deviceHasOsccalRegeneration() ) { + MessageBox::sorry(i18n("Osccal regeneration not available for the selected device."), Log::Show); + return; + } + KFileDialog dialog(":open_autohex", PURL::filter(PURL::Hex), this, "autohex_dialog", true); + dialog.setOperationMode(KFileDialog::Opening); + dialog.setCaption(i18n("Open Calibration Firmware")); + dialog.setMode(KFile::File); + //dialog.ops->clearHistory(); + dialog.setSelection("autocal.hex"); + dialog.exec(); + PURL::Url url(dialog.selectedURL()); + if ( url.isEmpty() ) return; + base().regenerateOsccal(url); +} + +//---------------------------------------------------------------------------- +::Programmer::ConfigWidget *Pickit2::GroupUI::createConfigWidget(QWidget *parent) const +{ + return new ::Programmer::ConfigWidget(static_cast(group()), parent); +} + +::Programmer::AdvancedDialog *Pickit2::GroupUI::createAdvancedDialog(::Programmer::Base &base, QWidget *parent) const +{ + return new Pickit::AdvancedDialog(static_cast(base), parent, "pickit2_advanced_dialog"); +} diff --git a/src/progs/pickit2/gui/pickit2_group_ui.h b/src/progs/pickit2/gui/pickit2_group_ui.h new file mode 100644 index 0000000..f79aa1f --- /dev/null +++ b/src/progs/pickit2/gui/pickit2_group_ui.h @@ -0,0 +1,42 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PICKIT2_GROUP_UI_H +#define PICKIT2_GROUP_UI_H + +#include "devices/pic/gui/pic_prog_group_ui.h" +#include "progs/pickit2/base/pickit_prog.h" + +//---------------------------------------------------------------------------- +namespace Pickit +{ +class AdvancedDialog : public ::Programmer::PicAdvancedDialog +{ +Q_OBJECT +public: + AdvancedDialog(Base &base, QWidget *parent, const char *name); + Base &base() { return static_cast(_base); } + +public slots: + virtual void regenerateCalibration(); +}; +} // namespace + +//---------------------------------------------------------------------------- +namespace Pickit2 +{ +class GroupUI : public ::Programmer::GroupUI +{ +public: + virtual ::Programmer::ConfigWidget *createConfigWidget(QWidget *parent) const; + virtual bool hasAdvancedDialog() const { return true; } + virtual ::Programmer::AdvancedDialog *createAdvancedDialog(::Programmer::Base &base, QWidget *parent) const; +}; +} // namespace + +#endif diff --git a/src/progs/pickit2/pickit2.pro b/src/progs/pickit2/pickit2.pro new file mode 100644 index 0000000..60ac0f5 --- /dev/null +++ b/src/progs/pickit2/pickit2.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = xml base diff --git a/src/progs/pickit2/xml/Makefile.am b/src/progs/pickit2/xml/Makefile.am new file mode 100644 index 0000000..5e8197e --- /dev/null +++ b/src/progs/pickit2/xml/Makefile.am @@ -0,0 +1,14 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_PROGRAMS = xml_pickit2_parser +xml_pickit2_parser_SOURCES = xml_pickit2_parser.cpp +OBJECTS = $(top_builddir)/src/devices/list/libdevicelistnoui.la \ + $(top_builddir)/src/devices/pic/pic/libpic.la $(top_builddir)/src/devices/pic/base/libpicbase.la \ + $(top_builddir)/src/devices/pic/xml_data/libpicxml.la \ + $(top_builddir)/src/devices/mem24/mem24/libmem24.la $(top_builddir)/src/devices/mem24/base/libmem24base.la \ + $(top_builddir)/src/devices/mem24/xml_data/libmem24xml.la \ + $(top_builddir)/src/xml_to_data/libxmltodata.la $(top_builddir)/src/devices/base/libdevicebase.la \ + $(top_builddir)/src/common/common/libcommon.la +xml_pickit2_parser_DEPENDENCIES = $(OBJECTS) +xml_pickit2_parser_LDADD = $(OBJECTS) $(LIB_KDECORE) diff --git a/src/progs/pickit2/xml/xml.pro b/src/progs/pickit2/xml/xml.pro new file mode 100644 index 0000000..0604fbb --- /dev/null +++ b/src/progs/pickit2/xml/xml.pro @@ -0,0 +1,17 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/app.pro) + +TARGET = xml_pickit2_parser +SOURCES += xml_pickit2_parser.cpp +LIBS += ../../../devices/list/libdevicelist.a \ + ../../../devices/mem24/mem24/libmem24.a ../../../devices/mem24/xml_data/libmem24xml.a \ + ../../../devices/mem24/base/libmem24base.a \ + ../../../devices/pic/pic/libpic.a ../../../devices/pic/xml_data/libpicxml.a \ + ../../../devices/pic/base/libpicbase.a ../../../xml_to_data/libxmltodata.a \ + ../../../devices/base/libdevicebase.a ../../../common/global/libglobal.a \ + ../../../common/nokde/libnokde.a ../../../common/common/libcommon.a + +unix:QMAKE_POST_LINK = cd ../base && ../xml/xml_pickit2_parser +unix:QMAKE_CLEAN += ../base/pickit2_data.cpp +win32:QMAKE_POST_LINK = cd ..\base && ..\xml\xml_pickit2_parser.exe +win32:QMAKE_CLEAN += ..\base\pickit2_data.cpp diff --git a/src/progs/pickit2/xml/xml_pickit2_parser.cpp b/src/progs/pickit2/xml/xml_pickit2_parser.cpp new file mode 100644 index 0000000..ffc82f7 --- /dev/null +++ b/src/progs/pickit2/xml/xml_pickit2_parser.cpp @@ -0,0 +1,75 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "xml_to_data/prog_xml_to_data.h" +#include "progs/pickit2/base/pickit2_data.h" + +namespace Pickit2 +{ + +class XmlToData : public Programmer::XmlToData +{ +public: + XmlToData() : Programmer::XmlToData("pickit2", "Pickit2") {} + +private: + virtual void parseData(QDomElement element, Data &data); + virtual void outputData(const Data &data, QTextStream &s) const; + virtual void outputFunctions(QTextStream &s) const; +}; + +void Pickit2::XmlToData::parseData(QDomElement element, Data &data) +{ + QString s = element.attribute("entry"); + if ( s.length()!=1 || (s[0]!='O' && s[0]!='P') ) qFatal("Invalid or missing entry mode"); + data.entryMode = s[0].latin1(); + s = element.attribute("pmode"); + if ( s.length()!=1 || (s[0]!='0' && s[0]!='1' && s[0]!='4' && s[0]!='n') ) + qFatal("Invalid or missing program mode"); + data.progMode = s[0].latin1(); + s = element.attribute("pwidth"); + if ( data.progMode!='n' ) { + if ( s.length()!=0 ) qFatal("Program width should not be defined"); + data.progWidth = 0; + } else { + bool ok; + data.progWidth = s.toUInt(&ok); + if ( !ok ) qFatal("Invalid or missing program width"); + } + s = element.attribute("regen"); + if ( s.isEmpty() || s=="false" ) data.regenerateOsccal = false; + else if ( s=="true" ) data.regenerateOsccal = true; + else qFatal("Invalid regen value"); +} + +void Pickit2::XmlToData::outputData(const Data &data, QTextStream &s) const +{ + s << "'" << data.entryMode << "', '" << data.progMode; + s << "', " << data.progWidth << ", " << (data.regenerateOsccal ? "true" : "false"); +} + +void Pickit2::XmlToData::outputFunctions(QTextStream &s) const +{ + Programmer::XmlToData::outputFunctions(s); + s << "::Programmer::DeviceSpecific *Group::createDeviceSpecific(::Programmer::Base &base) const" << endl; + s << "{" << endl; + s << " uint i = family(static_cast< ::Pickit2::Base &>(base).device()->name());" << endl; + s << " switch(i) {" << endl; + for (uint i=0; i * + * * + * 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. * + ***************************************************************************/ +#include "pickit2_bootloader.h" + +//----------------------------------------------------------------------------- +Pickit2Bootloader::Hardware::Hardware(::Programmer::Base &base) + : Bootloader::Hardware(base, new Pickit2::USBPort(base)) +{} + +bool Pickit2Bootloader::Hardware::internalConnectHardware() +{ + if ( !openPort() ) return false; + ::Programmer::Mode mode; + VersionData version; + if ( !port().getMode(version, mode) ) return false; + if ( mode!=::Programmer::BootloadMode ) { + log(Log::LineType::Information, i18n("Trying to enter bootloader mode...")); + if ( !port().resetFirmwareDevice(::Programmer::BootloadMode) ) return false; + for (uint i=0;; i++) { + port().close(); + Port::usleep(500000); // ?? + if ( !openPort() ) continue; + if ( !port().getMode(version, mode) ) continue; + if ( i==4 || mode!=::Programmer::BootloadMode ) { + log(Log::LineType::Error, i18n("Could not detect device in bootloader mode.")); + return false; + } + } + } + log(Log::LineType::Information, i18n("Bootloader version %1 detected.").arg(version.pretty())); + if ( version.majorNum()!=2 ) { + log(Log::LineType::Error, i18n("Only bootloader version 2.x is supported.")); + return false; + } + return true; +} + +bool Pickit2Bootloader::Hardware::write(Pic::MemoryRangeType type, const Device::Array &data) +{ + Q_ASSERT( data.count()==device().nbWords(type) ); + Q_ASSERT( type==Pic::MemoryRangeType::Code ); + // check that there is nothing in bootloader reserved area + for (uint i=0; i=0x1000 && i<0x3FF0 ) continue; + if ( data[i]==device().mask(Pic::MemoryRangeType::Code) ) continue; + uint address = device().addressIncrement(Pic::MemoryRangeType::Code) * i; + log(Log::LineType::Warning, " " + i18n("Code is present in bootloader reserved area (at address %1). It will be ignored.").arg(toHexLabel(address, device().nbCharsAddress()))); + break; + } + return port().writeFirmwareCodeMemory(data, _base.progressMonitor()); +} + +bool Pickit2Bootloader::Hardware::read(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata) +{ + Q_ASSERT( type==Pic::MemoryRangeType::Code ); + data.resize(device().nbWords(type)); + Device::Array varray; + if (vdata) varray = static_cast(vdata->memory).arrayForWriting(Pic::MemoryRangeType::Code); + return port().readFirmwareCodeMemory(data, vdata ? &varray : 0, _base.progressMonitor()); +} + +//----------------------------------------------------------------------------- +bool Pickit2Bootloader::DeviceSpecific::doEraseRange(Pic::MemoryRangeType type) +{ + Q_ASSERT( type==Pic::MemoryRangeType::Code ); + return static_cast(hardware()).port().eraseFirmwareCodeMemory(); +} diff --git a/src/progs/pickit2_bootloader/base/pickit2_bootloader.h b/src/progs/pickit2_bootloader/base/pickit2_bootloader.h new file mode 100644 index 0000000..7af0957 --- /dev/null +++ b/src/progs/pickit2_bootloader/base/pickit2_bootloader.h @@ -0,0 +1,43 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PICKIT2_BOOTLOADER_H +#define PICKIT2_BOOTLOADER_H + +#include "progs/bootloader/base/bootloader.h" +#include "progs/pickit2/base/pickit2.h" + +namespace Pickit2Bootloader +{ +//----------------------------------------------------------------------------- +class Hardware : public Bootloader::Hardware +{ +public: + Hardware(::Programmer::Base &base); + Pickit2::USBPort &port() { return static_cast(*_port); } + virtual bool write(Pic::MemoryRangeType type, const Device::Array &data); + virtual bool read(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata); + virtual bool internalConnectHardware(); +}; + +//----------------------------------------------------------------------------- +class DeviceSpecific : public Bootloader::DeviceSpecific +{ +public: + DeviceSpecific(::Programmer::Base &base) : Bootloader::DeviceSpecific(base) {} + virtual bool canEraseAll() const { return true; } + virtual bool canEraseRange(Pic::MemoryRangeType type) const { return ( type==Pic::MemoryRangeType::Code ); } + virtual bool canReadRange(Pic::MemoryRangeType type) const { return ( type==Pic::MemoryRangeType::Code ); } + virtual bool canWriteRange(Pic::MemoryRangeType type) const { return ( type==Pic::MemoryRangeType::Code ); } + virtual bool doEraseRange(Pic::MemoryRangeType type); + virtual bool doErase(bool) { return doEraseRange(Pic::MemoryRangeType::Code); } +}; + +} // namespace + +#endif diff --git a/src/progs/pickit2_bootloader/base/pickit2_bootloader.xml b/src/progs/pickit2_bootloader/base/pickit2_bootloader.xml new file mode 100644 index 0000000..2e87949 --- /dev/null +++ b/src/progs/pickit2_bootloader/base/pickit2_bootloader.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/src/progs/pickit2_bootloader/base/pickit2_bootloader_data.h b/src/progs/pickit2_bootloader/base/pickit2_bootloader_data.h new file mode 100644 index 0000000..87aead1 --- /dev/null +++ b/src/progs/pickit2_bootloader/base/pickit2_bootloader_data.h @@ -0,0 +1,19 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PICKIT2_BOOTLOADER_DATA_H +#define PICKIT2_BOOTLOADER_DATA_H + +namespace Pickit2Bootloader +{ + struct Data {}; + extern bool isSupported(const QString &device); + extern const Data &data(const QString &device); +} // namespace + +#endif diff --git a/src/progs/pickit2_bootloader/base/pickit2_bootloader_prog.cpp b/src/progs/pickit2_bootloader/base/pickit2_bootloader_prog.cpp new file mode 100644 index 0000000..7f734ba --- /dev/null +++ b/src/progs/pickit2_bootloader/base/pickit2_bootloader_prog.cpp @@ -0,0 +1,14 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "pickit2_bootloader_prog.h" + +//----------------------------------------------------------------------------- +Pickit2Bootloader::ProgrammerBase::ProgrammerBase(const Programmer::Group &group, const Pic::Data *data) + : Bootloader::ProgrammerBase(group, data, "pickit2_bootloader_programmer_base") +{} diff --git a/src/progs/pickit2_bootloader/base/pickit2_bootloader_prog.h b/src/progs/pickit2_bootloader/base/pickit2_bootloader_prog.h new file mode 100644 index 0000000..461d734 --- /dev/null +++ b/src/progs/pickit2_bootloader/base/pickit2_bootloader_prog.h @@ -0,0 +1,47 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PICKIT2_BOOTLOADER_PROG_H +#define PICKIT2_BOOTLOADER_PROG_H + +#include "progs/bootloader/base/bootloader_prog.h" +#include "pickit2_bootloader.h" + +namespace Pickit2Bootloader +{ + +//----------------------------------------------------------------------------- +class ProgrammerBase : public ::Bootloader::ProgrammerBase +{ +Q_OBJECT +public: + ProgrammerBase(const Programmer::Group &group, const Pic::Data *data); + virtual bool verifyDeviceId() { return true; } +}; + +//----------------------------------------------------------------------------- +class Group : public ::Bootloader::Group +{ +public: + virtual QString name() const { return "pickit2_bootloader"; } + virtual QString label() const { return i18n("Pickit2 Bootloader"); } + virtual ::Programmer::Properties properties() const { return ::Programmer::Programmer | ::Programmer::CanReadMemory; } + virtual ::Programmer::TargetPowerMode targetPowerMode() const { return ::Programmer::TargetSelfPowered; } + virtual bool isPortSupported(PortType type) const { return type==PortType::USB; } + virtual bool canReadVoltage(Pic::VoltageType) const { return false; } + +protected: + virtual void initSupported(); + virtual ::Programmer::Base *createBase(const Device::Data *data) const { return new ProgrammerBase(*this, static_cast(data)); } + virtual ::Programmer::Hardware *createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &) const { return new Hardware(base); } + virtual ::Programmer::DeviceSpecific *createDeviceSpecific(::Programmer::Base &base) const { return new DeviceSpecific(base); } +}; + +} // namespace + +#endif diff --git a/src/progs/pickit2_bootloader/gui/Makefile.am b/src/progs/pickit2_bootloader/gui/Makefile.am new file mode 100644 index 0000000..b9be2b0 --- /dev/null +++ b/src/progs/pickit2_bootloader/gui/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libpickit2bootloaderui.la +libpickit2bootloaderui_la_LDFLAGS = $(all_libraries) +libpickit2bootloaderui_la_SOURCES = pickit2_bootloader_ui.cpp diff --git a/src/progs/pickit2_bootloader/gui/pickit2_bootloader_ui.cpp b/src/progs/pickit2_bootloader/gui/pickit2_bootloader_ui.cpp new file mode 100644 index 0000000..89bf5c7 --- /dev/null +++ b/src/progs/pickit2_bootloader/gui/pickit2_bootloader_ui.cpp @@ -0,0 +1,20 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "pickit2_bootloader_ui.h" + +//----------------------------------------------------------------------------- +Pickit2Bootloader::ConfigWidget::ConfigWidget(const::Programmer::Group &group, QWidget *parent) + : ::Programmer::ConfigWidget(group, parent) +{} + +//----------------------------------------------------------------------------- +::Programmer::ConfigWidget *Pickit2Bootloader::GroupUI::createConfigWidget(QWidget *parent) const +{ + return new ConfigWidget(static_cast(group()), parent); +} diff --git a/src/progs/pickit2_bootloader/gui/pickit2_bootloader_ui.h b/src/progs/pickit2_bootloader/gui/pickit2_bootloader_ui.h new file mode 100644 index 0000000..d715574 --- /dev/null +++ b/src/progs/pickit2_bootloader/gui/pickit2_bootloader_ui.h @@ -0,0 +1,36 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PICKIT2_BOOTLOADER_UI_H +#define PICKIT2_BOOTLOADER_UI_H + +#include "progs/bootloader/gui/bootloader_ui.h" + +//----------------------------------------------------------------------------- +namespace Pickit2Bootloader +{ +class ConfigWidget: public ::Programmer::ConfigWidget +{ +Q_OBJECT +public: + ConfigWidget(const::Programmer::Group &group, QWidget *parent); + virtual void loadConfig() {} + virtual void saveConfig() {} +}; + + +//---------------------------------------------------------------------------- +class GroupUI : public ::Bootloader::GroupUI +{ +public: + virtual ::Programmer::ConfigWidget *createConfigWidget(QWidget *parent) const; +}; + +} // namespace + +#endif diff --git a/src/progs/pickit2_bootloader/pickit2_bootloader.pro b/src/progs/pickit2_bootloader/pickit2_bootloader.pro new file mode 100644 index 0000000..60ac0f5 --- /dev/null +++ b/src/progs/pickit2_bootloader/pickit2_bootloader.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = xml base diff --git a/src/progs/pickit2_bootloader/xml/Makefile.am b/src/progs/pickit2_bootloader/xml/Makefile.am new file mode 100644 index 0000000..899aa3b --- /dev/null +++ b/src/progs/pickit2_bootloader/xml/Makefile.am @@ -0,0 +1,14 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_PROGRAMS = xml_pickit2_bootloader_parser +xml_pickit2_bootloader_parser_SOURCES = xml_pickit2_bootloader_parser.cpp +OBJECTS = $(top_builddir)/src/devices/list/libdevicelistnoui.la \ + $(top_builddir)/src/devices/pic/pic/libpic.la $(top_builddir)/src/devices/pic/base/libpicbase.la \ + $(top_builddir)/src/devices/pic/xml_data/libpicxml.la \ + $(top_builddir)/src/devices/mem24/mem24/libmem24.la $(top_builddir)/src/devices/mem24/base/libmem24base.la \ + $(top_builddir)/src/devices/mem24/xml_data/libmem24xml.la \ + $(top_builddir)/src/xml_to_data/libxmltodata.la $(top_builddir)/src/devices/base/libdevicebase.la \ + $(top_builddir)/src/common/common/libcommon.la +xml_pickit2_bootloader_parser_DEPENDENCIES = $(OBJECTS) +xml_pickit2_bootloader_parser_LDADD = $(OBJECTS) $(LIB_KDECORE) diff --git a/src/progs/pickit2_bootloader/xml/xml.pro b/src/progs/pickit2_bootloader/xml/xml.pro new file mode 100644 index 0000000..2e2aef1 --- /dev/null +++ b/src/progs/pickit2_bootloader/xml/xml.pro @@ -0,0 +1,17 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/app.pro) + +TARGET = xml_pickit2_bootloader_parser +SOURCES += xml_pickit2_bootloader_parser.cpp +LIBS += ../../../devices/list/libdevicelist.a \ + ../../../devices/mem24/mem24/libmem24.a ../../../devices/mem24/xml_data/libmem24xml.a \ + ../../../devices/mem24/base/libmem24base.a \ + ../../../devices/pic/pic/libpic.a ../../../devices/pic/xml_data/libpicxml.a \ + ../../../devices/pic/base/libpicbase.a ../../../xml_to_data/libxmltodata.a \ + ../../../devices/base/libdevicebase.a ../../../common/global/libglobal.a \ + ../../../common/nokde/libnokde.a ../../../common/common/libcommon.a + +unix:QMAKE_POST_LINK = cd ../base && ../xml/xml_pickit2_bootloader_parser +unix:QMAKE_CLEAN += ../base/pickit2_bootloader_data.cpp +win32:QMAKE_POST_LINK = cd ..\base && ..\xml\xml_pickit2_bootloader_parser.exe +win32:QMAKE_CLEAN += ..\base\pickit2_bootloader_data.cpp diff --git a/src/progs/pickit2_bootloader/xml/xml_pickit2_bootloader_parser.cpp b/src/progs/pickit2_bootloader/xml/xml_pickit2_bootloader_parser.cpp new file mode 100644 index 0000000..150e814 --- /dev/null +++ b/src/progs/pickit2_bootloader/xml/xml_pickit2_bootloader_parser.cpp @@ -0,0 +1,39 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "xml_to_data/prog_xml_to_data.h" + +#include "progs/pickit2_bootloader/base/pickit2_bootloader_data.h" +#include "devices/base/device_group.h" +#include "devices/pic/base/pic.h" + +//----------------------------------------------------------------------------- +namespace Pickit2Bootloader +{ + +class XmlToData : public Programmer::XmlToData +{ +public: + XmlToData() : Programmer::XmlToData("pickit2_bootloader", "Pickit2Bootloader") {} + +private: + virtual void parseData(QDomElement element, Data &data); +}; + +void Pickit2Bootloader::XmlToData::parseData(QDomElement, Data &) +{ + const Device::Data *ddata = Device::lister().data(currentDevice()); + if ( ddata->group().name()!="pic" ) qFatal("non-pic device not supported"); + const Pic::Data *pdata = static_cast(ddata); + if ( !pdata->hasFeature(Pic::Feature::USB) ) qFatal("device does not have USB"); +} + +} // namespace + +//----------------------------------------------------------------------------- +XML_MAIN(Pickit2Bootloader::XmlToData) diff --git a/src/progs/pickit2v2/Makefile.am b/src/progs/pickit2v2/Makefile.am new file mode 100644 index 0000000..490a53d --- /dev/null +++ b/src/progs/pickit2v2/Makefile.am @@ -0,0 +1,3 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +SUBDIRS = base gui diff --git a/src/progs/pickit2v2/base/Makefile.am b/src/progs/pickit2v2/base/Makefile.am new file mode 100644 index 0000000..b5a7688 --- /dev/null +++ b/src/progs/pickit2v2/base/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libpickit2v2.la +libpickit2v2_la_DEPENDENCIES = pickit2v2_data.cpp +libpickit2v2_la_SOURCES = pickit2v2.cpp pickit2v2_data.cpp pickit2v2_prog.cpp diff --git a/src/progs/pickit2v2/base/base.pro b/src/progs/pickit2v2/base/base.pro new file mode 100644 index 0000000..70ccaef --- /dev/null +++ b/src/progs/pickit2v2/base/base.pro @@ -0,0 +1,6 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/lib.pro) + +TARGET = pickit2v2 +HEADERS += pickit2v2.h pickit2v2_prog.h pickit2v2_data.h +SOURCES += pickit2v2.cpp pickit2v2_prog.cpp pickit2v2_data.cpp diff --git a/src/progs/pickit2v2/base/pickit2v2.cpp b/src/progs/pickit2v2/base/pickit2v2.cpp new file mode 100644 index 0000000..31dd6ca --- /dev/null +++ b/src/progs/pickit2v2/base/pickit2v2.cpp @@ -0,0 +1,432 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "pickit2v2.h" + +#include "progs/base/prog_config.h" +#include "progs/icd2/base/microchip.h" +#include "pickit2v2_data.h" + +//----------------------------------------------------------------------------- +const Pickit2V2::FamilyData *Pickit2V2::familyData(const Pic::Data &device) +{ + for (uint i=0; FAMILY_DATA[i].architecture!=Pic::Architecture::Nb_Types; i++) + if ( FAMILY_DATA[i].architecture==device.architecture() ) return &FAMILY_DATA[i]; + Q_ASSERT(false); + return 0; +} + +//----------------------------------------------------------------------------- +Pickit2V2::Hardware::Hardware(::Programmer::Base &base) + : ::Programmer::PicHardware(base, new USBPort(base), QString::null), + _scriptBufferChecksum(0), _deviceSet(false) +{} + +bool Pickit2V2::Hardware::internalConnectHardware() +{ + return port().open(); +} + +bool Pickit2V2::Hardware::setTarget() +{ + //setIcspSpeed(0); // #### ?? + _fastProgramming = true; // #### ?? + uint checksum; + if ( !getScriptBufferChecksum(checksum) ) return false; + if ( !_deviceSet || _scriptBufferChecksum!=checksum ) { + if ( !downloadScripts() ) return false; + } + _deviceSet = true; + return true; +} + +bool Pickit2V2::Hardware::readStatus(ushort &status) +{ + if ( !port().command(ReadStatus) ) return false; + Array a; + if ( !port().receive(a) ) return false; + status = (a[1] << 8) + a[0]; + return true; +} + +bool Pickit2V2::Hardware::sendScript(const ushort *script, uint length) +{ + Array cmd; + cmd[0] = ClearUploadBuffer; + cmd[1] = ExecuteScript; + cmd[2] = length; + for (uint i=0; i210 ) vfault = 210; + Array cmd; + cmd[0] = SetVdd; + cmd[1] = v & 0xFF; + cmd[2] = v >> 8; + cmd[3] = vfault; + return port().command(cmd); +} + +bool Pickit2V2::Hardware::setVppVoltage(double value, double threshold) +{ + Array cmd; + cmd[0] = SetVpp; + cmd[1] = 0x40; + cmd[2] = uchar(qRound(18.61*value)); + cmd[3] = uchar(qRound(18.61*value*threshold)); + return port().command(cmd); +} + +bool Pickit2V2::Hardware::setVddOn(bool on) +{ + log(Log::DebugLevel::Extra, QString("Vdd set to %1, self powered is %2").arg(on).arg(_base.isTargetSelfPowered())); + ushort script[2]; + script[0] = (on ? VddGroundOff : VddOff); + if ( _base.isTargetSelfPowered() ) script[1] = (on ? VddOff : VddGroundOff); + else script[1] = (on ? VddOn : VddGroundOn); + return sendScript(script, 2); +} + +bool Pickit2V2::Hardware::setIcspSpeed(uchar speed) +{ + ushort script[2]; + script[0] = SetIcspSpeed; + script[1] = speed; + return sendScript(script, 2); +} + +bool Pickit2V2::Hardware::getMode(VersionData &version, ::Programmer::Mode &mode) +{ + if ( !port().command(FirmwareVersion) ) return false; + Array data; + if ( !port().receive(data) ) return false; + if ( data[0]=='B' ) { + mode = ::Programmer::BootloadMode; + version = VersionData(); + } else { + mode = ::Programmer::NormalMode; + version = VersionData(data[0], data[1], data[2]); + } + return true; +} + +bool Pickit2V2::Hardware::readVoltages(VoltagesData &voltagesData) +{ + if ( !port().command(ReadVoltages) ) return false; + Array array; + if ( !port().receive(array) ) return false; + double vadc = 256 * array[1] + array[0]; + voltagesData[Pic::TargetVdd].value = 5.0 * (vadc / 65536); + voltagesData[Pic::TargetVdd].error = false; + vadc = 256 * array[3] + array[2]; + voltagesData[Pic::TargetVpp].value = 13.7 * (vadc / 65536); + voltagesData[Pic::TargetVpp].error = false; + return true; +} + +bool Pickit2V2::Hardware::downloadAddress(Address address) +{ + log(Log::DebugLevel::Max, QString("download address %1").arg(toHexLabel(address, 6))); + Array cmd; + cmd[0] = ClearDownloadBuffer; + cmd[1] = DownloadData; + cmd[2] = 3; + cmd[3] = address.toUInt() & 0xFF; + cmd[4] = (address.toUInt() >> 8) & 0xFF; + cmd[5] = (address.toUInt() >> 16) & 0xFF; + return port().command(cmd); +} + +bool Pickit2V2::Hardware::runScript(ScriptType stype, uint repetitions, uint nbNoLens) +{ + log(Log::DebugLevel::Max, QString("run script %1: repetitions=%2 nbNoLen=%3") + .arg(toHexLabel(stype, 2)).arg(repetitions).arg(nbNoLens)); +#if 0 // ALTERNATE METHOD + const Data &d = data(device().name()); + for (uint i=0; i words; + if ( type==Pic::MemoryRangeType::Config || type==Pic::MemoryRangeType::Cal ) { + if ( !runScript(stype, 1, 0) ) return false; + if ( !port().command(UploadData) ) return false; + // config memory return includes a length byte that we need to ignore + if ( !port().receiveWords(nbBytesWord, nbReceive, words, 1) ) return false; + } else { + if ( !runScript(stype, nbRuns, nbReceive) ) return false; + if ( !port().receiveWords(nbBytesWord, nbReceive, words) ) return false; + } + log(Log::DebugLevel::Max, QString("nbRunWords=%1 readNbWords=%2 index=%3/%4").arg(nbRunWords).arg(words.count()).arg(i).arg(nbWords)); + for (uint k=0; k=nbWords ) break; + data[i] = words[k]; + if (fdata->progMemShift) data[i] >>= 1; + data[i] = data[i].maskWith(device().mask(type)); // ### correct ? + if ( vdata && !verifyWord(i, data[i], type, *vdata) ) return false; + if ( type==Pic::MemoryRangeType::Code && i!=0x0 && i%0x8000==0 ) setAddress = true; + i++; + } + } + if ( !runScript(ProgExit) ) return false; + return true; +} + +bool Pickit2V2::Hardware::eraseAll() +{ + const Data &d = data(device().name()); + if ( d.scriptIndexes[ConfigErase]!=0 ) { + if ( !runScript(ProgEntry) ) return false; + if ( d.scriptIndexes[ConfigWritePrepare]!=0 ) { + if ( !downloadAddress(0) ) return false; + if ( !runScript(ConfigWritePrepare) ) return false; + } + if ( !runScript(ConfigErase) ) return false; + if ( !runScript(ProgExit) ) return false; + } + if ( !runScript(ProgEntry) ) return false; + if ( d.scriptIndexes[EraseChipPrepare]!=0 && !runScript(EraseChipPrepare) ) return false; + if ( !runScript(ChipErase) ) return false; + if ( !runScript(ProgExit) ) return false; + return true; +} + +bool Pickit2V2::Hardware::eraseRange(Pic::MemoryRangeType type) +{ + if ( type==Pic::MemoryRangeType::Code ) { + if ( !runScript(ProgEntry) ) return false; + if ( !runScript(ProgMemoryErase) ) return false; + if ( !runScript(ProgExit) ) return false; + return true; + } + if ( type==Pic::MemoryRangeType::Eeprom ) { + if ( !runScript(ProgEntry) ) return false; + if ( !runScript(EepromErase) ) return false; + if ( !runScript(ProgExit) ) return false; + return true; + } + Q_ASSERT(false); + return false; +} + +bool Pickit2V2::Hardware::prepareWrite(Pic::MemoryRangeType type, uint wordIndex) +{ + ScriptType stype = prepareWriteScript(type); + if ( stype==Nb_ScriptTypes || data(device().name()).scriptIndexes[stype]==0 ) return true; + switch (type.type()) { + case Pic::MemoryRangeType::Code: + case Pic::MemoryRangeType::Config: + if ( !device().architecture().data().hasAddressAccess ) return true; + if ( !downloadAddress(0x10000 * (wordIndex / 0x8000)) ) return false; + break; + case Pic::MemoryRangeType::Eeprom: { + Address address = (device().nbBytesWord(Pic::MemoryRangeType::Eeprom)==4 ? device().range(Pic::MemoryRangeType::Eeprom).start : 0x000000); + if ( !downloadAddress(address) ) return false; + break; + } + case Pic::MemoryRangeType::UserId: break; + default: return true; + case Pic::MemoryRangeType::Nb_Types: Q_ASSERT(false); return false; + } + return runScript(stype); +} + +bool Pickit2V2::Hardware::writeMemory(Pic::MemoryRangeType otype, const Device::Array &data, bool force) +{ + Q_UNUSED(force); + return false; // ### TODO +} + +//----------------------------------------------------------------------------- +bool Pickit2V2::DeviceSpecific::canEraseRange(Pic::MemoryRangeType type) const +{ + const Data &d = data(device().name()); + if ( type==Pic::MemoryRangeType::Code ) return d.scriptIndexes[ProgMemoryErase]; + if ( type==Pic::MemoryRangeType::Eeprom ) return d.scriptIndexes[EepromErase]; + return false; +} + +bool Pickit2V2::DeviceSpecific::canReadRange(Pic::MemoryRangeType type) const +{ + const Data &d = data(device().name()); + if ( type==Pic::MemoryRangeType::Cal ) return d.scriptIndexes[OsccalRead]; + return true; +} + +bool Pickit2V2::DeviceSpecific::canWriteRange(Pic::MemoryRangeType type) const +{ + const Data &d = data(device().name()); + if ( type==Pic::MemoryRangeType::Cal ) return d.scriptIndexes[OsccalWrite]; + return true; +} + +bool Pickit2V2::DeviceSpecific::doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force) +{ + Q_ASSERT( data.size()==device().nbWords(type) ); + return hardware().writeMemory(type, data, force); +} diff --git a/src/progs/pickit2v2/base/pickit2v2.h b/src/progs/pickit2v2/base/pickit2v2.h new file mode 100644 index 0000000..7c6f294 --- /dev/null +++ b/src/progs/pickit2v2/base/pickit2v2.h @@ -0,0 +1,145 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PICKIT2V2_H +#define PICKIT2V2_H + +#include "progs/pickit2/base/pickit2.h" +#include "pickit2v2_data.h" + +namespace Pickit2V2 +{ +//----------------------------------------------------------------------------- +enum FirmwareCommand { + EnterBootloader = 0x42, NoOperation = 0x5A, FirmwareVersion = 0x76, + + SetVdd = 0xA0, SetVpp = 0xA1, ReadStatus = 0xA2, ReadVoltages = 0xA3, + DownloadScript = 0xA4, RunScript = 0xA5, ExecuteScript = 0xA6, + ClearDownloadBuffer = 0xA7, DownloadData = 0xA8, ClearUploadBuffer = 0xA9, + UploadData = 0xAA, ClearScriptBuffer = 0xAB, UploadDataNoLen = 0xAC, + EndOfBuffer = 0xAD, Reset = 0xAE, ScriptBufferChecksum = 0xAF, + + SetVoltageCalibrations = 0xB0, WriteInternalEEprom = 0xB1, + ReadInternalEEprom = 0xB2, EnterUARTMode = 0xB3, ExitUARTMode = 0xB4 +}; + +enum ScriptCommand { + VddOn = 0xFF, VddOff = 0xFE, VddGroundOn = 0xFD, VddGroundOff = 0xFC, + VppOn = 0xFB, VppOff = 0xFA, VppPwmOn = 0xF9, VppPwmOff = 0xF8, + MclrGroundOn = 0xF7, MclrGroundOff = 0xF6, BusyLedOn = 0xF5, BusyLedOff = 0xF4, + SetIcspPins = 0xF3, WriteByteLiteral = 0xF2, WriteByteBuffer = 0xF1, + ReadByteBuffer = 0xF0, ReadByte = 0xEF, WriteBitsLiteral = 0xEE, + WriteBitsBuffer = 0xED, ReadBitsBuffer = 0xEC, ReadBits = 0xEB, + SetIcspSpeed = 0xEA, Loop = 0xE9, DelayLong = 0xE8, DelayShort = 0xE7, + IfEqGoto = 0xE6, IfGtGoto = 0xE5, GotoIndex = 0xE4, ExitScript = 0xE3, + + PeekSfr = 0xE2, PokeSfr = 0xE1, IcdSlaveRx = 0xE0, IcdSlaveTxLiteral = 0xDF, + IcdSlaveTxBuffer = 0xDE, LoopBuffer = 0xDD, IcspStatesBuffer = 0xDC, + PopDownload = 0xDB, CoreInst18 = 0xDA, CoreInst24 = 0xD9, Nop24 = 0xD8, + Visi24 = 0xD7, Rd2ByteBuffer = 0xD6, Rd2BitsBuffer = 0xD5, WriteBufWordW = 0xD4, + WriteBufByteW = 0xD3, ConstWriteDl = 0xD2, WriteBitsLitHld = 0xD1, + WriteBitsBufHld = 0xD0, SetAux = 0xCF, AuxStateBuffer = 0xCE, I2cStart = 0xCD, + I2cStop = 0xCC, I2cWriteByteLiteral = 0xCB, I2cWriteByteBuffer = 0xCA, + I2cReadByteAck = 0xC9, I2cReadByteNack = 0xC8, SpiWriteByteLiteral = 0xC7, + SpiWriteByteBuffer = 0xC6, SpiReadByteBuffer = 0xC5, SpiReadWriteByteLiteral = 0xC4, + SpiReadWriteByteBuffer = 0xC3 +}; +extern const FamilyData *familyData(const Pic::Data &device); + +//----------------------------------------------------------------------------- +class Array : public Pickit::Array +{ +public: + Array() : Pickit::Array(64, EndOfBuffer, PrintEscapeAll) {} +}; + +//----------------------------------------------------------------------------- +class USBPort : public Pickit2::USBPort +{ +public: + USBPort(Log::Base &manager) : Pickit2::USBPort(manager) {} + virtual Pickit::Array array() const { return Array(); } +}; + +enum StatusFlag { + DownloadBufferOverflow = 0x8000, ScriptBufferOverflow = 0x4000, + RunScriptOnEmptyScript = 0x2000, ScriptAbortDownloadEmpty = 0x1000, + ScriptAbortUploadFull = 0x0800, IcdTransferTimeout = 0x0400, + UARTModeEnabled = 0x0200, ResetSinceLastStatusRead = 0x0100, + ButtonPressed = 0x0040, VppError = 0x0020, VddError = 0x0010, + VppIsOn = 0x0008, VppGroundIsOn = 0x0004, + VddIsOn = 0x0002, VddGroundIsOn = 0x0001 }; +Q_DECLARE_FLAGS(StatusFlags, StatusFlag) +Q_DECLARE_OPERATORS_FOR_FLAGS(StatusFlags) + +//----------------------------------------------------------------------------- +class Hardware : public ::Programmer::PicHardware +{ +public: + Hardware(::Programmer::Base &base); + USBPort &port() { return static_cast(*_port); } + const USBPort &port() const { return static_cast(*_port); } + + bool getMode(VersionData &version, ::Programmer::Mode &mode); + bool setTargetReset(Pic::ResetMode mode); + bool setVddVoltage(double value, double threshold); + bool setVppVoltage(double value, double threshold); + bool setVddOn(bool on); + bool executeScript(uint i); + bool setTarget(); + bool setFastProgramming(bool fast); + virtual bool readVoltages(VoltagesData &voltagesData); + bool readStatus(ushort &status); + bool readMemory(Pic::MemoryRangeType type, ::Device::Array &data, const ::Programmer::VerifyData *vdata); + bool writeMemory(Pic::MemoryRangeType type, const ::Device::Array &data, bool force); + bool eraseAll(); + bool eraseRange(Pic::MemoryRangeType type); + +private: + enum { UploadBufferNbBytes = 128, DownloadBufferNbBytes = 256 }; + uint _scriptBufferChecksum; + bool _deviceSet, _fastProgramming; + + virtual bool internalConnectHardware(); + bool getScriptBufferChecksum(uint &checksum); + bool downloadScript(ScriptType type, uint i); + bool downloadScripts(); + bool sendScript(const ushort *script, uint length); + bool resetPickit2() { return port().command(Reset); } + bool setIcspSpeed(uchar speed); + bool downloadAddress(Address address); + bool runScript(ScriptType stype, uint repetitions = 1, uint nbNoLens = 0); + bool prepareRead(Pic::MemoryRangeType type, uint wordIndex); + bool prepareWrite(Pic::MemoryRangeType type, uint wordIndex); +}; + +//----------------------------------------------------------------------------- +class DeviceSpecific : public ::Programmer::PicDeviceSpecific +{ +public: + DeviceSpecific(::Programmer::Base &base) : ::Programmer::PicDeviceSpecific(base) {} + virtual bool canEraseAll() const { return true; } + virtual bool canEraseRange(Pic::MemoryRangeType type) const; + virtual bool canReadRange(Pic::MemoryRangeType) const; + virtual bool canWriteRange(Pic::MemoryRangeType) const; + Hardware &hardware() { return static_cast(*_base.hardware()); } + virtual bool setPowerOn() { return true; } + virtual bool setPowerOff() { return true; } + virtual bool setTargetPowerOn(bool on) { return hardware().setVddOn(on); } + virtual bool doErase(bool) { return hardware().eraseAll(); } + virtual bool doEraseRange(Pic::MemoryRangeType type) { return hardware().eraseRange(type); } + virtual bool doRead(Pic::MemoryRangeType type, ::Device::Array &data, const ::Programmer::VerifyData *vdata) { + return hardware().readMemory(type, data, vdata); + } + virtual bool doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force); + +}; + +} // namespace + +#endif diff --git a/src/progs/pickit2v2/base/pickit2v2_data.cpp b/src/progs/pickit2v2/base/pickit2v2_data.cpp new file mode 100644 index 0000000..b93fad4 --- /dev/null +++ b/src/progs/pickit2v2/base/pickit2v2_data.cpp @@ -0,0 +1,951 @@ +// this file is autogenerated, do not edit ! + +#include "devices/list/device_list.h" +#include "pickit2v2_prog.h" +#include "pickit2v2_data.h" + +namespace Pickit2V2 +{ +struct CData { + const char *name; + Data data; +}; + +const CData PIC10F200_DATA = { "10F200", { 32, 0, 1, 0, + { 1, 2, 0, 36, 0, 31, 0, 40, 0, 0, 0, 0, 0, 37, 0, 43, 0, 47, 0, 49, 39, 44, 45, 0, 0, 0, 0, 134, 0 } } }; +const CData PIC10F202_DATA = { "10F202", { 32, 0, 1, 0, + { 1, 2, 0, 36, 0, 31, 0, 40, 0, 0, 0, 0, 0, 37, 0, 43, 0, 48, 0, 50, 39, 44, 46, 0, 0, 0, 0, 134, 0 } } }; +const CData PIC10F204_DATA = { "10F204", { 32, 0, 1, 0, + { 1, 2, 0, 36, 0, 31, 0, 40, 0, 0, 0, 0, 0, 37, 0, 43, 0, 47, 0, 49, 39, 44, 45, 0, 0, 0, 0, 134, 0 } } }; +const CData PIC10F206_DATA = { "10F206", { 32, 0, 1, 0, + { 1, 2, 0, 36, 0, 31, 0, 40, 0, 0, 0, 0, 0, 37, 0, 43, 0, 48, 0, 50, 39, 44, 46, 0, 0, 0, 0, 134, 0 } } }; +const CData PIC10F220_DATA = { "10F220", { 32, 0, 1, 0, + { 1, 2, 0, 36, 0, 31, 0, 40, 0, 0, 0, 0, 0, 37, 0, 43, 0, 47, 0, 49, 39, 44, 45, 0, 0, 0, 0, 134, 0 } } }; +const CData PIC10F222_DATA = { "10F222", { 32, 0, 1, 0, + { 1, 2, 0, 36, 0, 31, 0, 40, 0, 0, 0, 0, 0, 37, 0, 43, 0, 48, 0, 50, 39, 44, 46, 0, 0, 0, 0, 134, 0 } } }; +const CData PIC12F508_DATA = { "12F508", { 32, 0, 1, 0, + { 1, 2, 0, 36, 0, 31, 0, 40, 0, 0, 0, 0, 0, 37, 0, 43, 0, 48, 0, 50, 39, 44, 46, 0, 0, 0, 0, 134, 0 } } }; +const CData PIC12F509_DATA = { "12F509", { 32, 0, 1, 0, + { 1, 2, 0, 36, 0, 31, 0, 40, 0, 0, 0, 0, 0, 37, 0, 43, 0, 38, 0, 42, 39, 44, 54, 0, 0, 0, 0, 134, 0 } } }; +const CData PIC12F510_DATA = { "12F510", { 32, 0, 1, 0, + { 1, 2, 0, 36, 0, 31, 0, 40, 0, 0, 0, 0, 0, 37, 0, 43, 0, 38, 0, 42, 39, 44, 54, 0, 0, 0, 0, 134, 0 } } }; +const CData PIC12F519_DATA = { "12F519", { 32, 32, 1, 1, + { 1, 2, 0, 36, 0, 31, 0, 40, 167, 36, 167, 40, 0, 37, 0, 43, 0, 162, 0, 163, 164, 165, 166, 168, 169, 0, 0, 134, 0 } } }; +const CData PIC12F609_DATA = { "12F609", { 32, 0, 1, 0, + { 1, 2, 3, 5, 0, 0, 0, 109, 0, 0, 0, 0, 0, 8, 0, 72, 0, 7, 0, 79, 0, 139, 77, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC12F615_DATA = { "12F615", { 32, 0, 1, 0, + { 1, 2, 3, 5, 0, 0, 0, 109, 0, 0, 0, 0, 0, 8, 0, 72, 0, 7, 0, 79, 0, 139, 77, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC12F629_DATA = { "12F629", { 32, 32, 1, 1, + { 1, 2, 3, 5, 0, 31, 0, 28, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 29, 30, 4, 110, 0, 0, 0, 132, 0 } } }; +const CData PIC12F635_DATA = { "12F635", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 13, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 136, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC12F675_DATA = { "12F675", { 32, 32, 1, 1, + { 1, 2, 3, 5, 0, 31, 0, 28, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 29, 30, 4, 110, 0, 0, 0, 132, 0 } } }; +const CData PIC12F683_DATA = { "12F683", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 13, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 138, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC12HV609_DATA = { "12HV609", { 32, 0, 1, 0, + { 1, 2, 3, 5, 0, 0, 0, 109, 0, 0, 0, 0, 0, 8, 0, 72, 0, 7, 0, 79, 0, 139, 77, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC12HV615_DATA = { "12HV615", { 32, 0, 1, 0, + { 1, 2, 3, 5, 0, 0, 0, 109, 0, 0, 0, 0, 0, 8, 0, 72, 0, 7, 0, 79, 0, 139, 77, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC16F505_DATA = { "16F505", { 32, 0, 1, 0, + { 1, 2, 0, 36, 0, 31, 0, 40, 0, 0, 0, 0, 0, 37, 0, 43, 0, 38, 0, 42, 39, 44, 54, 0, 0, 0, 0, 134, 0 } } }; +const CData PIC16F506_DATA = { "16F506", { 32, 0, 1, 0, + { 1, 2, 0, 36, 0, 31, 0, 40, 0, 0, 0, 0, 0, 37, 0, 43, 0, 38, 0, 42, 39, 44, 54, 0, 0, 0, 0, 134, 0 } } }; +const CData PIC16F526_DATA = { "16F526", { 32, 32, 1, 1, + { 1, 2, 0, 36, 0, 31, 0, 40, 167, 36, 167, 40, 0, 37, 0, 43, 0, 162, 0, 163, 164, 165, 166, 168, 169, 0, 0, 134, 0 } } }; +const CData PIC16F54_DATA = { "16F54", { 32, 0, 1, 0, + { 1, 2, 0, 36, 0, 31, 0, 40, 0, 0, 0, 0, 0, 37, 0, 43, 0, 48, 0, 50, 0, 0, 46, 0, 0, 0, 0, 134, 0 } } }; +const CData PIC16F57_DATA = { "16F57", { 32, 0, 4, 0, + { 1, 2, 0, 36, 0, 31, 0, 53, 0, 0, 0, 0, 0, 37, 0, 43, 0, 52, 0, 51, 0, 0, 41, 0, 0, 0, 0, 134, 0 } } }; +const CData PIC16F59_DATA = { "16F59", { 32, 0, 4, 0, + { 1, 2, 0, 36, 0, 31, 0, 53, 0, 0, 0, 0, 0, 37, 0, 43, 0, 52, 0, 51, 0, 0, 41, 0, 0, 0, 0, 134, 0 } } }; +const CData PIC16F610_DATA = { "16F610", { 32, 0, 1, 0, + { 1, 2, 3, 5, 0, 0, 0, 109, 0, 0, 0, 0, 0, 8, 0, 72, 0, 7, 0, 79, 0, 139, 77, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC16F616_DATA = { "16F616", { 32, 0, 4, 0, + { 1, 2, 3, 5, 0, 0, 0, 78, 0, 0, 0, 0, 0, 8, 0, 72, 0, 7, 0, 79, 0, 139, 77, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC16F627_DATA = { "16F627", { 32, 32, 1, 1, + { 1, 2, 3, 5, 0, 31, 0, 105, 0, 6, 0, 10, 0, 34, 0, 107, 0, 7, 0, 106, 0, 0, 101, 126, 0, 0, 0, 132, 0 } } }; +const CData PIC16F627A_DATA = { "16F627A", { 32, 32, 1, 1, + { 1, 2, 3, 5, 0, 31, 0, 28, 0, 6, 0, 10, 0, 8, 0, 80, 0, 7, 0, 11, 0, 0, 4, 110, 0, 0, 0, 132, 0 } } }; +const CData PIC16F628_DATA = { "16F628", { 32, 32, 1, 1, + { 1, 2, 3, 5, 0, 31, 0, 105, 0, 6, 0, 10, 0, 34, 0, 107, 0, 7, 0, 106, 0, 0, 101, 126, 0, 0, 0, 132, 0 } } }; +const CData PIC16F628A_DATA = { "16F628A", { 32, 32, 1, 1, + { 1, 2, 3, 5, 0, 31, 0, 28, 0, 6, 0, 10, 0, 8, 0, 80, 0, 7, 0, 11, 0, 0, 4, 110, 0, 0, 0, 132, 0 } } }; +const CData PIC16F630_DATA = { "16F630", { 32, 32, 1, 1, + { 1, 2, 3, 5, 0, 31, 0, 28, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 29, 30, 4, 110, 0, 0, 0, 132, 0 } } }; +const CData PIC16F631_DATA = { "16F631", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 13, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 0, 4, 110, 0, 0, 0, 132, 0 } } }; +const CData PIC16F636_DATA = { "16F636", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 13, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 136, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16F639_DATA = { "16F639", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 13, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 136, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16F648A_DATA = { "16F648A", { 32, 32, 1, 1, + { 1, 2, 3, 5, 0, 31, 0, 28, 0, 6, 0, 10, 0, 8, 0, 80, 0, 7, 0, 11, 0, 0, 4, 110, 0, 0, 0, 132, 0 } } }; +const CData PIC16F676_DATA = { "16F676", { 32, 32, 1, 1, + { 1, 2, 3, 5, 0, 31, 0, 28, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 29, 30, 4, 110, 0, 0, 0, 132, 0 } } }; +const CData PIC16F677_DATA = { "16F677", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 13, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 0, 4, 110, 0, 0, 0, 132, 0 } } }; +const CData PIC16F684_DATA = { "16F684", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 13, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 138, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16F685_DATA = { "16F685", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 13, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 138, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16F687_DATA = { "16F687", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 13, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 138, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16F688_DATA = { "16F688", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 13, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 138, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16F689_DATA = { "16F689", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 13, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 138, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16F690_DATA = { "16F690", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 13, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 138, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16F716_DATA = { "16F716", { 32, 0, 4, 0, + { 1, 2, 3, 5, 0, 31, 0, 118, 0, 0, 0, 0, 0, 8, 0, 120, 0, 7, 0, 119, 0, 0, 77, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC16F72_DATA = { "16F72", { 32, 0, 2, 0, + { 1, 2, 3, 5, 0, 0, 0, 81, 0, 0, 0, 0, 0, 8, 0, 84, 0, 7, 0, 83, 0, 0, 82, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC16F73_DATA = { "16F73", { 32, 0, 2, 0, + { 1, 2, 3, 5, 0, 0, 0, 81, 0, 0, 0, 0, 0, 8, 0, 84, 0, 7, 0, 83, 0, 0, 82, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC16F737_DATA = { "16F737", { 32, 0, 2, 0, + { 1, 2, 3, 5, 0, 31, 0, 81, 0, 0, 0, 0, 0, 34, 0, 85, 0, 7, 0, 83, 0, 0, 82, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC16F74_DATA = { "16F74", { 32, 0, 2, 0, + { 1, 2, 3, 5, 0, 0, 0, 81, 0, 0, 0, 0, 0, 8, 0, 84, 0, 7, 0, 83, 0, 0, 82, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC16F747_DATA = { "16F747", { 32, 0, 2, 0, + { 1, 2, 3, 5, 0, 31, 0, 81, 0, 0, 0, 0, 0, 34, 0, 85, 0, 7, 0, 83, 0, 0, 82, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC16F76_DATA = { "16F76", { 32, 0, 2, 0, + { 1, 2, 3, 5, 0, 0, 0, 81, 0, 0, 0, 0, 0, 8, 0, 84, 0, 7, 0, 83, 0, 0, 82, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC16F767_DATA = { "16F767", { 32, 0, 2, 0, + { 1, 2, 3, 5, 0, 31, 0, 81, 0, 0, 0, 0, 0, 34, 0, 85, 0, 7, 0, 83, 0, 0, 82, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC16F77_DATA = { "16F77", { 32, 0, 2, 0, + { 1, 2, 3, 5, 0, 0, 0, 81, 0, 0, 0, 0, 0, 8, 0, 84, 0, 7, 0, 83, 0, 0, 82, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC16F777_DATA = { "16F777", { 32, 0, 2, 0, + { 1, 2, 3, 5, 0, 31, 0, 81, 0, 0, 0, 0, 0, 34, 0, 85, 0, 7, 0, 83, 0, 0, 82, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC16F785_DATA = { "16F785", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 13, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 136, 4, 110, 0, 0, 0, 132, 0 } } }; +const CData PIC16F818_DATA = { "16F818", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 87, 0, 6, 0, 90, 0, 34, 0, 91, 0, 7, 0, 88, 0, 0, 86, 111, 114, 174, 173, 132, 0 } } }; +const CData PIC16F819_DATA = { "16F819", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 87, 0, 6, 0, 90, 0, 34, 0, 91, 0, 7, 0, 88, 0, 0, 86, 111, 114, 174, 173, 132, 0 } } }; +const CData PIC16F84A_DATA = { "16F84A", { 32, 32, 1, 1, + { 1, 2, 3, 5, 0, 31, 0, 105, 0, 6, 0, 10, 0, 34, 0, 107, 0, 7, 0, 106, 0, 0, 101, 113, 0, 0, 0, 132, 0 } } }; +const CData PIC16F87_DATA = { "16F87", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 87, 0, 6, 0, 90, 0, 34, 0, 89, 0, 7, 0, 88, 0, 0, 86, 111, 114, 174, 173, 132, 0 } } }; +const CData PIC16F870_DATA = { "16F870", { 32, 32, 1, 1, + { 1, 2, 3, 5, 0, 31, 0, 105, 0, 6, 0, 10, 0, 34, 0, 107, 0, 7, 0, 106, 0, 0, 101, 113, 0, 0, 0, 132, 0 } } }; +const CData PIC16F871_DATA = { "16F871", { 32, 32, 1, 1, + { 1, 2, 3, 5, 0, 31, 0, 105, 0, 6, 0, 10, 0, 34, 0, 107, 0, 7, 0, 106, 0, 0, 101, 113, 0, 0, 0, 132, 0 } } }; +const CData PIC16F872_DATA = { "16F872", { 32, 32, 1, 1, + { 1, 2, 3, 5, 0, 31, 0, 105, 0, 6, 0, 10, 0, 34, 0, 107, 0, 7, 0, 106, 0, 0, 101, 113, 0, 0, 0, 132, 0 } } }; +const CData PIC16F873_DATA = { "16F873", { 32, 32, 1, 1, + { 1, 2, 3, 5, 0, 31, 0, 105, 0, 6, 0, 10, 0, 34, 0, 107, 0, 7, 0, 106, 0, 0, 101, 113, 0, 0, 0, 132, 0 } } }; +const CData PIC16F873A_DATA = { "16F873A", { 32, 32, 8, 1, + { 1, 2, 3, 5, 0, 31, 0, 92, 0, 6, 0, 90, 0, 34, 0, 80, 0, 7, 0, 88, 0, 0, 86, 111, 114, 0, 0, 132, 0 } } }; +const CData PIC16F874_DATA = { "16F874", { 32, 32, 1, 1, + { 1, 2, 3, 5, 0, 31, 0, 105, 0, 6, 0, 10, 0, 34, 0, 107, 0, 7, 0, 106, 0, 0, 101, 113, 0, 0, 0, 132, 0 } } }; +const CData PIC16F874A_DATA = { "16F874A", { 32, 32, 8, 1, + { 1, 2, 3, 5, 0, 31, 0, 92, 0, 6, 0, 90, 0, 34, 0, 80, 0, 7, 0, 88, 0, 0, 86, 111, 114, 0, 0, 132, 0 } } }; +const CData PIC16F876_DATA = { "16F876", { 32, 32, 1, 1, + { 1, 2, 3, 5, 0, 31, 0, 105, 0, 6, 0, 10, 0, 34, 0, 107, 0, 7, 0, 106, 0, 0, 101, 113, 0, 0, 0, 132, 0 } } }; +const CData PIC16F876A_DATA = { "16F876A", { 32, 32, 8, 1, + { 1, 2, 3, 5, 0, 31, 0, 92, 0, 6, 0, 90, 0, 34, 0, 80, 0, 7, 0, 88, 0, 0, 86, 111, 114, 0, 0, 132, 0 } } }; +const CData PIC16F877_DATA = { "16F877", { 32, 32, 1, 1, + { 1, 2, 3, 5, 0, 31, 0, 105, 0, 6, 0, 10, 0, 34, 0, 107, 0, 7, 0, 106, 0, 0, 101, 113, 0, 0, 0, 132, 0 } } }; +const CData PIC16F877A_DATA = { "16F877A", { 32, 32, 8, 1, + { 1, 2, 3, 5, 0, 31, 0, 92, 0, 6, 0, 90, 0, 34, 0, 80, 0, 7, 0, 88, 0, 0, 86, 111, 114, 0, 0, 132, 0 } } }; +const CData PIC16F88_DATA = { "16F88", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 87, 0, 6, 0, 90, 0, 34, 0, 89, 0, 7, 0, 88, 0, 0, 86, 111, 114, 174, 173, 132, 0 } } }; +const CData PIC16F882_DATA = { "16F882", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 127, 0, 6, 0, 10, 0, 34, 0, 35, 0, 7, 0, 33, 0, 137, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16F883_DATA = { "16F883", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 127, 0, 6, 0, 10, 0, 34, 0, 35, 0, 7, 0, 33, 0, 137, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16F884_DATA = { "16F884", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 127, 0, 6, 0, 10, 0, 34, 0, 35, 0, 7, 0, 33, 0, 137, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16F886_DATA = { "16F886", { 32, 32, 8, 1, + { 1, 2, 3, 5, 0, 31, 0, 32, 0, 6, 0, 10, 0, 34, 0, 35, 0, 7, 0, 33, 0, 137, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16F887_DATA = { "16F887", { 32, 32, 8, 1, + { 1, 2, 3, 5, 0, 31, 0, 32, 0, 6, 0, 10, 0, 34, 0, 35, 0, 7, 0, 33, 0, 137, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16F913_DATA = { "16F913", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 13, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 136, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16F914_DATA = { "16F914", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 13, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 136, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16F916_DATA = { "16F916", { 32, 32, 8, 1, + { 1, 2, 3, 5, 0, 31, 0, 9, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 136, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16F917_DATA = { "16F917", { 32, 32, 8, 1, + { 1, 2, 3, 5, 0, 31, 0, 9, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 136, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16F946_DATA = { "16F946", { 32, 32, 8, 1, + { 1, 2, 3, 5, 0, 31, 0, 9, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 136, 4, 110, 0, 172, 102, 132, 0 } } }; +const CData PIC16HV610_DATA = { "16HV610", { 32, 0, 1, 0, + { 1, 2, 3, 5, 0, 0, 0, 109, 0, 0, 0, 0, 0, 8, 0, 72, 0, 7, 0, 79, 0, 139, 77, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC16HV616_DATA = { "16HV616", { 32, 0, 4, 0, + { 1, 2, 3, 5, 0, 0, 0, 78, 0, 0, 0, 0, 0, 8, 0, 72, 0, 7, 0, 79, 0, 139, 77, 0, 0, 0, 0, 132, 0 } } }; +const CData PIC16HV785_DATA = { "16HV785", { 32, 32, 4, 1, + { 1, 2, 3, 5, 0, 31, 0, 13, 0, 6, 0, 10, 0, 8, 0, 12, 0, 7, 0, 11, 0, 136, 4, 110, 0, 0, 0, 132, 0 } } }; +const CData PIC18F1220_DATA = { "18F1220", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F1230_DATA = { "18F1230", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F1320_DATA = { "18F1320", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F1330_DATA = { "18F1330", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2220_DATA = { "18F2220", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F2221_DATA = { "18F2221", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2320_DATA = { "18F2320", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F2321_DATA = { "18F2321", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2331_DATA = { "18F2331", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F2410_DATA = { "18F2410", { 64, 0, 16, 0, + { 1, 2, 55, 56, 0, 57, 63, 103, 0, 0, 0, 0, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F242_DATA = { "18F242", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F2420_DATA = { "18F2420", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2423_DATA = { "18F2423", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2431_DATA = { "18F2431", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F2450_DATA = { "18F2450", { 64, 0, 8, 0, + { 1, 2, 55, 56, 0, 57, 63, 94, 0, 0, 0, 0, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2455_DATA = { "18F2455", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2458_DATA = { "18F2458", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F248_DATA = { "18F248", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F2480_DATA = { "18F2480", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F24J10_DATA = { "18F24J10", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F24K20_DATA = { "18F24K20", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 130, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2510_DATA = { "18F2510", { 64, 0, 16, 0, + { 1, 2, 55, 56, 0, 57, 63, 103, 0, 0, 0, 0, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2515_DATA = { "18F2515", { 64, 0, 32, 0, + { 1, 2, 55, 56, 0, 57, 63, 104, 0, 0, 0, 0, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F252_DATA = { "18F252", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F2520_DATA = { "18F2520", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2523_DATA = { "18F2523", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2525_DATA = { "18F2525", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 104, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2550_DATA = { "18F2550", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2553_DATA = { "18F2553", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F258_DATA = { "18F258", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F2580_DATA = { "18F2580", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2585_DATA = { "18F2585", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 104, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F25J10_DATA = { "18F25J10", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F25K20_DATA = { "18F25K20", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 130, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2610_DATA = { "18F2610", { 64, 0, 32, 0, + { 1, 2, 55, 56, 0, 57, 63, 104, 0, 0, 0, 0, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2620_DATA = { "18F2620", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 104, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2680_DATA = { "18F2680", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 104, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2682_DATA = { "18F2682", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 104, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 117, 0, 0, 0, 135, 0 } } }; +const CData PIC18F2685_DATA = { "18F2685", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 104, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 117, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4220_DATA = { "18F4220", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F4221_DATA = { "18F4221", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4320_DATA = { "18F4320", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F4321_DATA = { "18F4321", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4331_DATA = { "18F4331", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F4410_DATA = { "18F4410", { 64, 0, 16, 0, + { 1, 2, 55, 56, 0, 57, 63, 103, 0, 0, 0, 0, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F442_DATA = { "18F442", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F4420_DATA = { "18F4420", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4423_DATA = { "18F4423", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4431_DATA = { "18F4431", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F4450_DATA = { "18F4450", { 64, 0, 8, 0, + { 1, 2, 55, 56, 0, 57, 63, 94, 0, 0, 0, 0, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4455_DATA = { "18F4455", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4458_DATA = { "18F4458", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F448_DATA = { "18F448", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F4480_DATA = { "18F4480", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F44J10_DATA = { "18F44J10", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F44K20_DATA = { "18F44K20", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 130, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4510_DATA = { "18F4510", { 64, 0, 16, 0, + { 1, 2, 55, 56, 0, 57, 63, 103, 0, 0, 0, 0, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4515_DATA = { "18F4515", { 64, 0, 32, 0, + { 1, 2, 55, 56, 0, 57, 63, 104, 0, 0, 0, 0, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F452_DATA = { "18F452", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F4520_DATA = { "18F4520", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4523_DATA = { "18F4523", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4525_DATA = { "18F4525", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 104, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4550_DATA = { "18F4550", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4553_DATA = { "18F4553", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F458_DATA = { "18F458", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 58, 59, 68, 69, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F4580_DATA = { "18F4580", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4585_DATA = { "18F4585", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 104, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F45J10_DATA = { "18F45J10", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F45K20_DATA = { "18F45K20", { 64, 32, 16, 1, + { 1, 2, 55, 56, 0, 57, 63, 103, 97, 98, 99, 100, 0, 60, 66, 130, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4610_DATA = { "18F4610", { 64, 0, 32, 0, + { 1, 2, 55, 56, 0, 57, 63, 104, 0, 0, 0, 0, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4620_DATA = { "18F4620", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 104, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4680_DATA = { "18F4680", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 104, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 115, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4682_DATA = { "18F4682", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 104, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 117, 0, 0, 0, 135, 0 } } }; +const CData PIC18F4685_DATA = { "18F4685", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 104, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 93, 117, 0, 0, 0, 135, 0 } } }; +const CData PIC18F6310_DATA = { "18F6310", { 64, 0, 8, 0, + { 1, 2, 55, 56, 0, 57, 63, 129, 0, 0, 0, 0, 0, 60, 66, 130, 0, 61, 0, 131, 0, 0, 128, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F6390_DATA = { "18F6390", { 64, 0, 8, 0, + { 1, 2, 55, 56, 0, 57, 63, 129, 0, 0, 0, 0, 0, 60, 66, 130, 0, 61, 0, 131, 0, 0, 128, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F63J11_DATA = { "18F63J11", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F63J90_DATA = { "18F63J90", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F6410_DATA = { "18F6410", { 64, 0, 8, 0, + { 1, 2, 55, 56, 0, 57, 63, 129, 0, 0, 0, 0, 0, 60, 66, 130, 0, 61, 0, 131, 0, 0, 128, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F6490_DATA = { "18F6490", { 64, 0, 8, 0, + { 1, 2, 55, 56, 0, 57, 63, 129, 0, 0, 0, 0, 0, 60, 66, 130, 0, 61, 0, 131, 0, 0, 128, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F64J11_DATA = { "18F64J11", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F64J90_DATA = { "18F64J90", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F6520_DATA = { "18F6520", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 108, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F6525_DATA = { "18F6525", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 108, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F6527_DATA = { "18F6527", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 96, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 95, 117, 0, 176, 177, 135, 0 } } }; +const CData PIC18F6585_DATA = { "18F6585", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 108, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F65J10_DATA = { "18F65J10", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F65J11_DATA = { "18F65J11", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F65J15_DATA = { "18F65J15", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F65J50_DATA = { "18F65J50", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F65J90_DATA = { "18F65J90", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F6620_DATA = { "18F6620", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 108, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F6621_DATA = { "18F6621", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 108, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F6622_DATA = { "18F6622", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 96, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 95, 117, 0, 176, 177, 135, 0 } } }; +const CData PIC18F6627_DATA = { "18F6627", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 96, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 95, 117, 0, 176, 177, 135, 0 } } }; +const CData PIC18F6628_DATA = { "18F6628", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 96, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 95, 117, 0, 176, 177, 135, 0 } } }; +const CData PIC18F6680_DATA = { "18F6680", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 108, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F66J10_DATA = { "18F66J10", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F66J11_DATA = { "18F66J11", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F66J15_DATA = { "18F66J15", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F66J16_DATA = { "18F66J16", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F66J50_DATA = { "18F66J50", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F66J55_DATA = { "18F66J55", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F66J60_DATA = { "18F66J60", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F66J65_DATA = { "18F66J65", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F6720_DATA = { "18F6720", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 108, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F6722_DATA = { "18F6722", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 96, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 95, 117, 0, 176, 177, 135, 0 } } }; +const CData PIC18F6723_DATA = { "18F6723", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 96, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 95, 117, 0, 176, 177, 135, 0 } } }; +const CData PIC18F67J10_DATA = { "18F67J10", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F67J11_DATA = { "18F67J11", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F67J50_DATA = { "18F67J50", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F67J60_DATA = { "18F67J60", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F8310_DATA = { "18F8310", { 64, 0, 8, 0, + { 1, 2, 55, 56, 0, 57, 63, 129, 0, 0, 0, 0, 0, 60, 66, 130, 0, 61, 0, 131, 0, 0, 128, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F8390_DATA = { "18F8390", { 64, 0, 8, 0, + { 1, 2, 55, 56, 0, 57, 63, 129, 0, 0, 0, 0, 0, 60, 66, 130, 0, 61, 0, 131, 0, 0, 128, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F83J11_DATA = { "18F83J11", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F83J90_DATA = { "18F83J90", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F8410_DATA = { "18F8410", { 64, 0, 8, 0, + { 1, 2, 55, 56, 0, 57, 63, 129, 0, 0, 0, 0, 0, 60, 66, 130, 0, 61, 0, 131, 0, 0, 128, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F8490_DATA = { "18F8490", { 64, 0, 8, 0, + { 1, 2, 55, 56, 0, 57, 63, 129, 0, 0, 0, 0, 0, 60, 66, 130, 0, 61, 0, 131, 0, 0, 128, 0, 0, 0, 0, 135, 0 } } }; +const CData PIC18F84J11_DATA = { "18F84J11", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F84J90_DATA = { "18F84J90", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F8520_DATA = { "18F8520", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 108, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F8525_DATA = { "18F8525", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 108, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F8527_DATA = { "18F8527", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 96, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 95, 117, 0, 176, 177, 135, 0 } } }; +const CData PIC18F8585_DATA = { "18F8585", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 108, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F85J10_DATA = { "18F85J10", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F85J11_DATA = { "18F85J11", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F85J15_DATA = { "18F85J15", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F85J50_DATA = { "18F85J50", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F85J90_DATA = { "18F85J90", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F8620_DATA = { "18F8620", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 108, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F8621_DATA = { "18F8621", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 108, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F8622_DATA = { "18F8622", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 96, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 95, 117, 0, 176, 177, 135, 0 } } }; +const CData PIC18F8627_DATA = { "18F8627", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 96, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 95, 117, 0, 176, 177, 135, 0 } } }; +const CData PIC18F8628_DATA = { "18F8628", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 96, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 95, 117, 0, 176, 177, 135, 0 } } }; +const CData PIC18F8680_DATA = { "18F8680", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 108, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F86J10_DATA = { "18F86J10", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F86J11_DATA = { "18F86J11", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F86J15_DATA = { "18F86J15", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F86J16_DATA = { "18F86J16", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F86J50_DATA = { "18F86J50", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F86J55_DATA = { "18F86J55", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F86J60_DATA = { "18F86J60", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F86J65_DATA = { "18F86J65", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F8720_DATA = { "18F8720", { 64, 32, 4, 1, + { 1, 2, 55, 56, 0, 57, 63, 64, 97, 98, 99, 108, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 62, 0, 0, 176, 175, 135, 0 } } }; +const CData PIC18F8722_DATA = { "18F8722", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 96, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 95, 117, 0, 176, 177, 135, 0 } } }; +const CData PIC18F8723_DATA = { "18F8723", { 64, 32, 32, 1, + { 1, 2, 55, 56, 0, 57, 63, 96, 97, 98, 99, 100, 0, 60, 66, 67, 0, 61, 0, 65, 0, 0, 95, 117, 0, 176, 177, 135, 0 } } }; +const CData PIC18F87J10_DATA = { "18F87J10", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F87J11_DATA = { "18F87J11", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F87J50_DATA = { "18F87J50", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F87J60_DATA = { "18F87J60", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F96J60_DATA = { "18F96J60", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F96J65_DATA = { "18F96J65", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18F97J60_DATA = { "18F97J60", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18LF24J10_DATA = { "18LF24J10", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18LF25J10_DATA = { "18LF25J10", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18LF44J10_DATA = { "18LF44J10", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC18LF45J10_DATA = { "18LF45J10", { 64, 0, 32, 0, + { 70, 2, 55, 56, 0, 57, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24FJ128GA006_DATA = { "24FJ128GA006", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24FJ128GA008_DATA = { "24FJ128GA008", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24FJ128GA010_DATA = { "24FJ128GA010", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24FJ16GA002_DATA = { "24FJ16GA002", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24FJ16GA004_DATA = { "24FJ16GA004", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24FJ32GA002_DATA = { "24FJ32GA002", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24FJ32GA004_DATA = { "24FJ32GA004", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24FJ48GA002_DATA = { "24FJ48GA002", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24FJ48GA004_DATA = { "24FJ48GA004", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24FJ64GA002_DATA = { "24FJ64GA002", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24FJ64GA004_DATA = { "24FJ64GA004", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24FJ64GA006_DATA = { "24FJ64GA006", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24FJ64GA008_DATA = { "24FJ64GA008", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24FJ64GA010_DATA = { "24FJ64GA010", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24FJ96GA006_DATA = { "24FJ96GA006", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24FJ96GA008_DATA = { "24FJ96GA008", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24FJ96GA010_DATA = { "24FJ96GA010", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24HJ128GP206_DATA = { "24HJ128GP206", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24HJ128GP210_DATA = { "24HJ128GP210", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24HJ128GP306_DATA = { "24HJ128GP306", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24HJ128GP310_DATA = { "24HJ128GP310", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24HJ128GP506_DATA = { "24HJ128GP506", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24HJ128GP510_DATA = { "24HJ128GP510", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24HJ12GP201_DATA = { "24HJ12GP201", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24HJ12GP202_DATA = { "24HJ12GP202", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24HJ256GP206_DATA = { "24HJ256GP206", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24HJ256GP210_DATA = { "24HJ256GP210", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24HJ256GP610_DATA = { "24HJ256GP610", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24HJ64GP206_DATA = { "24HJ64GP206", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24HJ64GP210_DATA = { "24HJ64GP210", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24HJ64GP506_DATA = { "24HJ64GP506", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC24HJ64GP510_DATA = { "24HJ64GP510", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC30F1010_DATA = { "30F1010", { 42, 0, 32, 0, + { 21, 2, 22, 143, 159, 23, 26, 158, 0, 0, 0, 0, 0, 121, 156, 157, 133, 154, 160, 158, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC30F2010_DATA = { "30F2010", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 180 } } }; +const CData PIC30F2011_DATA = { "30F2011", { 42, 0, 32, 0, + { 1, 2, 140, 143, 112, 142, 146, 147, 0, 0, 0, 0, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 0 } } }; +const CData PIC30F2012_DATA = { "30F2012", { 42, 0, 32, 0, + { 1, 2, 140, 143, 112, 142, 146, 147, 0, 0, 0, 0, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 0 } } }; +const CData PIC30F2020_DATA = { "30F2020", { 42, 0, 32, 0, + { 21, 2, 22, 143, 159, 23, 26, 158, 0, 0, 0, 0, 0, 121, 156, 157, 133, 154, 160, 158, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC30F2023_DATA = { "30F2023", { 42, 0, 32, 0, + { 21, 2, 22, 143, 159, 23, 26, 158, 0, 0, 0, 0, 0, 121, 156, 157, 133, 154, 160, 158, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC30F3010_DATA = { "30F3010", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 180 } } }; +const CData PIC30F3011_DATA = { "30F3011", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 180 } } }; +const CData PIC30F3012_DATA = { "30F3012", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 180 } } }; +const CData PIC30F3013_DATA = { "30F3013", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 180 } } }; +const CData PIC30F3014_DATA = { "30F3014", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 180 } } }; +const CData PIC30F4011_DATA = { "30F4011", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 180 } } }; +const CData PIC30F4012_DATA = { "30F4012", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 180 } } }; +const CData PIC30F4013_DATA = { "30F4013", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 180 } } }; +const CData PIC30F5011_DATA = { "30F5011", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 152, 0, 0, 0 } } }; +const CData PIC30F5013_DATA = { "30F5013", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 152, 0, 0, 0 } } }; +const CData PIC30F5015_DATA = { "30F5015", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 180 } } }; +const CData PIC30F5016_DATA = { "30F5016", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 180 } } }; +const CData PIC30F6010A_DATA = { "30F6010A", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 180 } } }; +const CData PIC30F6011A_DATA = { "30F6011A", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 180 } } }; +const CData PIC30F6012A_DATA = { "30F6012A", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 180 } } }; +const CData PIC30F6013A_DATA = { "30F6013A", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 180 } } }; +const CData PIC30F6014A_DATA = { "30F6014A", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 180 } } }; +const CData PIC30F6015_DATA = { "30F6015", { 42, 64, 32, 16, + { 1, 2, 140, 143, 112, 142, 146, 147, 142, 145, 148, 149, 0, 144, 150, 151, 153, 154, 155, 147, 0, 0, 141, 0, 0, 179, 178, 0, 180 } } }; +const CData PIC33FJ128GP206_DATA = { "33FJ128GP206", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ128GP306_DATA = { "33FJ128GP306", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ128GP310_DATA = { "33FJ128GP310", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ128GP706_DATA = { "33FJ128GP706", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ128GP708_DATA = { "33FJ128GP708", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ128GP710_DATA = { "33FJ128GP710", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ128MC506_DATA = { "33FJ128MC506", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ128MC510_DATA = { "33FJ128MC510", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ128MC706_DATA = { "33FJ128MC706", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ128MC708_DATA = { "33FJ128MC708", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ128MC710_DATA = { "33FJ128MC710", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ12GP201_DATA = { "33FJ12GP201", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ12GP202_DATA = { "33FJ12GP202", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ12MC201_DATA = { "33FJ12MC201", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ12MC202_DATA = { "33FJ12MC202", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ256GP506_DATA = { "33FJ256GP506", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ256GP510_DATA = { "33FJ256GP510", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ256GP710_DATA = { "33FJ256GP710", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ256MC510_DATA = { "33FJ256MC510", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ256MC710_DATA = { "33FJ256MC710", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ64GP206_DATA = { "33FJ64GP206", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ64GP306_DATA = { "33FJ64GP306", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ64GP310_DATA = { "33FJ64GP310", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ64GP706_DATA = { "33FJ64GP706", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ64GP708_DATA = { "33FJ64GP708", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ64GP710_DATA = { "33FJ64GP710", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ64MC506_DATA = { "33FJ64MC506", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ64MC508_DATA = { "33FJ64MC508", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ64MC510_DATA = { "33FJ64MC510", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ64MC706_DATA = { "33FJ64MC706", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; +const CData PIC33FJ64MC710_DATA = { "33FJ64MC710", { 42, 0, 64, 0, + { 21, 2, 22, 24, 0, 23, 26, 123, 0, 0, 0, 0, 0, 121, 0, 125, 0, 122, 0, 124, 0, 0, 25, 0, 0, 0, 0, 0, 0 } } }; + +const CData *DATA_LIST[] = { +&PIC10F200_DATA,&PIC10F202_DATA,&PIC10F204_DATA,&PIC10F206_DATA,&PIC10F220_DATA,&PIC10F222_DATA,&PIC12F508_DATA,&PIC12F509_DATA,&PIC12F510_DATA,&PIC12F519_DATA,&PIC12F609_DATA,&PIC12F615_DATA,&PIC12F629_DATA,&PIC12F635_DATA,&PIC12F675_DATA,&PIC12F683_DATA,&PIC12HV609_DATA,&PIC12HV615_DATA,&PIC16F505_DATA,&PIC16F506_DATA, +&PIC16F526_DATA,&PIC16F54_DATA,&PIC16F57_DATA,&PIC16F59_DATA,&PIC16F610_DATA,&PIC16F616_DATA,&PIC16F627_DATA,&PIC16F627A_DATA,&PIC16F628_DATA,&PIC16F628A_DATA,&PIC16F630_DATA,&PIC16F631_DATA,&PIC16F636_DATA,&PIC16F639_DATA,&PIC16F648A_DATA,&PIC16F676_DATA,&PIC16F677_DATA,&PIC16F684_DATA,&PIC16F685_DATA,&PIC16F687_DATA, +&PIC16F688_DATA,&PIC16F689_DATA,&PIC16F690_DATA,&PIC16F716_DATA,&PIC16F72_DATA,&PIC16F73_DATA,&PIC16F737_DATA,&PIC16F74_DATA,&PIC16F747_DATA,&PIC16F76_DATA,&PIC16F767_DATA,&PIC16F77_DATA,&PIC16F777_DATA,&PIC16F785_DATA,&PIC16F818_DATA,&PIC16F819_DATA,&PIC16F84A_DATA,&PIC16F87_DATA,&PIC16F870_DATA,&PIC16F871_DATA, +&PIC16F872_DATA,&PIC16F873_DATA,&PIC16F873A_DATA,&PIC16F874_DATA,&PIC16F874A_DATA,&PIC16F876_DATA,&PIC16F876A_DATA,&PIC16F877_DATA,&PIC16F877A_DATA,&PIC16F88_DATA,&PIC16F882_DATA,&PIC16F883_DATA,&PIC16F884_DATA,&PIC16F886_DATA,&PIC16F887_DATA,&PIC16F913_DATA,&PIC16F914_DATA,&PIC16F916_DATA,&PIC16F917_DATA,&PIC16F946_DATA, +&PIC16HV610_DATA,&PIC16HV616_DATA,&PIC16HV785_DATA,&PIC18F1220_DATA,&PIC18F1230_DATA,&PIC18F1320_DATA,&PIC18F1330_DATA,&PIC18F2220_DATA,&PIC18F2221_DATA,&PIC18F2320_DATA,&PIC18F2321_DATA,&PIC18F2331_DATA,&PIC18F2410_DATA,&PIC18F242_DATA,&PIC18F2420_DATA,&PIC18F2423_DATA,&PIC18F2431_DATA,&PIC18F2450_DATA,&PIC18F2455_DATA,&PIC18F2458_DATA, +&PIC18F248_DATA,&PIC18F2480_DATA,&PIC18F24J10_DATA,&PIC18F24K20_DATA,&PIC18F2510_DATA,&PIC18F2515_DATA,&PIC18F252_DATA,&PIC18F2520_DATA,&PIC18F2523_DATA,&PIC18F2525_DATA,&PIC18F2550_DATA,&PIC18F2553_DATA,&PIC18F258_DATA,&PIC18F2580_DATA,&PIC18F2585_DATA,&PIC18F25J10_DATA,&PIC18F25K20_DATA,&PIC18F2610_DATA,&PIC18F2620_DATA,&PIC18F2680_DATA, +&PIC18F2682_DATA,&PIC18F2685_DATA,&PIC18F4220_DATA,&PIC18F4221_DATA,&PIC18F4320_DATA,&PIC18F4321_DATA,&PIC18F4331_DATA,&PIC18F4410_DATA,&PIC18F442_DATA,&PIC18F4420_DATA,&PIC18F4423_DATA,&PIC18F4431_DATA,&PIC18F4450_DATA,&PIC18F4455_DATA,&PIC18F4458_DATA,&PIC18F448_DATA,&PIC18F4480_DATA,&PIC18F44J10_DATA,&PIC18F44K20_DATA,&PIC18F4510_DATA, +&PIC18F4515_DATA,&PIC18F452_DATA,&PIC18F4520_DATA,&PIC18F4523_DATA,&PIC18F4525_DATA,&PIC18F4550_DATA,&PIC18F4553_DATA,&PIC18F458_DATA,&PIC18F4580_DATA,&PIC18F4585_DATA,&PIC18F45J10_DATA,&PIC18F45K20_DATA,&PIC18F4610_DATA,&PIC18F4620_DATA,&PIC18F4680_DATA,&PIC18F4682_DATA,&PIC18F4685_DATA,&PIC18F6310_DATA,&PIC18F6390_DATA,&PIC18F63J11_DATA, +&PIC18F63J90_DATA,&PIC18F6410_DATA,&PIC18F6490_DATA,&PIC18F64J11_DATA,&PIC18F64J90_DATA,&PIC18F6520_DATA,&PIC18F6525_DATA,&PIC18F6527_DATA,&PIC18F6585_DATA,&PIC18F65J10_DATA,&PIC18F65J11_DATA,&PIC18F65J15_DATA,&PIC18F65J50_DATA,&PIC18F65J90_DATA,&PIC18F6620_DATA,&PIC18F6621_DATA,&PIC18F6622_DATA,&PIC18F6627_DATA,&PIC18F6628_DATA,&PIC18F6680_DATA, +&PIC18F66J10_DATA,&PIC18F66J11_DATA,&PIC18F66J15_DATA,&PIC18F66J16_DATA,&PIC18F66J50_DATA,&PIC18F66J55_DATA,&PIC18F66J60_DATA,&PIC18F66J65_DATA,&PIC18F6720_DATA,&PIC18F6722_DATA,&PIC18F6723_DATA,&PIC18F67J10_DATA,&PIC18F67J11_DATA,&PIC18F67J50_DATA,&PIC18F67J60_DATA,&PIC18F8310_DATA,&PIC18F8390_DATA,&PIC18F83J11_DATA,&PIC18F83J90_DATA,&PIC18F8410_DATA, +&PIC18F8490_DATA,&PIC18F84J11_DATA,&PIC18F84J90_DATA,&PIC18F8520_DATA,&PIC18F8525_DATA,&PIC18F8527_DATA,&PIC18F8585_DATA,&PIC18F85J10_DATA,&PIC18F85J11_DATA,&PIC18F85J15_DATA,&PIC18F85J50_DATA,&PIC18F85J90_DATA,&PIC18F8620_DATA,&PIC18F8621_DATA,&PIC18F8622_DATA,&PIC18F8627_DATA,&PIC18F8628_DATA,&PIC18F8680_DATA,&PIC18F86J10_DATA,&PIC18F86J11_DATA, +&PIC18F86J15_DATA,&PIC18F86J16_DATA,&PIC18F86J50_DATA,&PIC18F86J55_DATA,&PIC18F86J60_DATA,&PIC18F86J65_DATA,&PIC18F8720_DATA,&PIC18F8722_DATA,&PIC18F8723_DATA,&PIC18F87J10_DATA,&PIC18F87J11_DATA,&PIC18F87J50_DATA,&PIC18F87J60_DATA,&PIC18F96J60_DATA,&PIC18F96J65_DATA,&PIC18F97J60_DATA,&PIC18LF24J10_DATA,&PIC18LF25J10_DATA,&PIC18LF44J10_DATA,&PIC18LF45J10_DATA, +&PIC24FJ128GA006_DATA,&PIC24FJ128GA008_DATA,&PIC24FJ128GA010_DATA,&PIC24FJ16GA002_DATA,&PIC24FJ16GA004_DATA,&PIC24FJ32GA002_DATA,&PIC24FJ32GA004_DATA,&PIC24FJ48GA002_DATA,&PIC24FJ48GA004_DATA,&PIC24FJ64GA002_DATA,&PIC24FJ64GA004_DATA,&PIC24FJ64GA006_DATA,&PIC24FJ64GA008_DATA,&PIC24FJ64GA010_DATA,&PIC24FJ96GA006_DATA,&PIC24FJ96GA008_DATA,&PIC24FJ96GA010_DATA,&PIC24HJ128GP206_DATA,&PIC24HJ128GP210_DATA,&PIC24HJ128GP306_DATA, +&PIC24HJ128GP310_DATA,&PIC24HJ128GP506_DATA,&PIC24HJ128GP510_DATA,&PIC24HJ12GP201_DATA,&PIC24HJ12GP202_DATA,&PIC24HJ256GP206_DATA,&PIC24HJ256GP210_DATA,&PIC24HJ256GP610_DATA,&PIC24HJ64GP206_DATA,&PIC24HJ64GP210_DATA,&PIC24HJ64GP506_DATA,&PIC24HJ64GP510_DATA,&PIC30F1010_DATA,&PIC30F2010_DATA,&PIC30F2011_DATA,&PIC30F2012_DATA,&PIC30F2020_DATA,&PIC30F2023_DATA,&PIC30F3010_DATA,&PIC30F3011_DATA, +&PIC30F3012_DATA,&PIC30F3013_DATA,&PIC30F3014_DATA,&PIC30F4011_DATA,&PIC30F4012_DATA,&PIC30F4013_DATA,&PIC30F5011_DATA,&PIC30F5013_DATA,&PIC30F5015_DATA,&PIC30F5016_DATA,&PIC30F6010A_DATA,&PIC30F6011A_DATA,&PIC30F6012A_DATA,&PIC30F6013A_DATA,&PIC30F6014A_DATA,&PIC30F6015_DATA,&PIC33FJ128GP206_DATA,&PIC33FJ128GP306_DATA,&PIC33FJ128GP310_DATA,&PIC33FJ128GP706_DATA, +&PIC33FJ128GP708_DATA,&PIC33FJ128GP710_DATA,&PIC33FJ128MC506_DATA,&PIC33FJ128MC510_DATA,&PIC33FJ128MC706_DATA,&PIC33FJ128MC708_DATA,&PIC33FJ128MC710_DATA,&PIC33FJ12GP201_DATA,&PIC33FJ12GP202_DATA,&PIC33FJ12MC201_DATA,&PIC33FJ12MC202_DATA,&PIC33FJ256GP506_DATA,&PIC33FJ256GP510_DATA,&PIC33FJ256GP710_DATA,&PIC33FJ256MC510_DATA,&PIC33FJ256MC710_DATA,&PIC33FJ64GP206_DATA,&PIC33FJ64GP306_DATA,&PIC33FJ64GP310_DATA,&PIC33FJ64GP706_DATA, +&PIC33FJ64GP708_DATA,&PIC33FJ64GP710_DATA,&PIC33FJ64MC506_DATA,&PIC33FJ64MC508_DATA,&PIC33FJ64MC510_DATA,&PIC33FJ64MC706_DATA,&PIC33FJ64MC710_DATA,0 +}; + +const CData *cdata(const QString &device) +{ +for(uint i=0; DATA_LIST[i]; i++) + if ( device==DATA_LIST[i]->name ) return DATA_LIST[i]; +return 0; +} +::Group::Support support(const QString &) +{ + return ::Group::Support::Untested; +} +const Data &data(const QString &device) +{ + return cdata(device)->data; +} +void Group::initSupported() +{ + for (uint i=0; DATA_LIST[i]; i++) { + const Device::Data *data = Device::lister().data(DATA_LIST[i]->name); + if ( data==0 ) continue; + addDevice(data->name(), data, ::Group::Support::Untested); + } +} + +const FamilyData FAMILY_DATA[] = { + { Pic::Architecture::Type(1), 12, 0x0001, 0x0002, 0x0003, true }, + { Pic::Architecture::Type(0), 12, 0x0001, 0x0002, 0x0000, true }, + { Pic::Architecture::Type(4), 12, 0x0001, 0x0002, 0x0037, false }, + { Pic::Architecture::Nb_Types, 0.0, 0x0000, 0x0000, 0x0000, false } +}; + +const ScriptData SCRIPT_DATA[] = { + { "HVProgEntry1", 5, 18, { 0xAAFA, 0xAAF7, 0xAAF9, 0xAAF5, 0xAAF3, 0xBB00, 0xAAE8, 0x0014, 0xAAF6, 0xAAFB, 0xAAE7, 0x007F, 0xAAF7, 0xAAFA, 0xAAFB, 0xAAF6, 0xAAE8, 0x0013 } }, + { "HVProgExit1", 4, 8, { 0xAAFA, 0xAAF7, 0xAAF8, 0xAAF3, 0xBB03, 0xAAE8, 0x000A, 0xAAF4 } }, + { "MR_RdDevID1", 0, 18, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB05, 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0 } }, + { "MR_ChpEraseEE10msI", 0, 17, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB02, 0xAAEE, 0xBB06, 0xBB0B, 0xAAE8, 0xBB02 } }, + { "MR_ProgMemRd32.1", 0, 11, { 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB08, 0x001F } }, + { "MR_EERd32.1", 0, 11, { 0xAAEE, 0xBB06, 0xBB05, 0xAAF0, 0xAAF0, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB08, 0x001F } }, + { "MR_UsrIDRd4.1", 0, 18, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB08, 0xBB03 } }, + { "MR_CfgRd1.1", 0, 18, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB06, 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0 } }, + { "MR_PrgMemWr8Int.1", 1, 24, { 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAE9, 0xBB08, 0xBB06, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x008D, 0xAAEE, 0xBB06, 0xBB06 } }, + { "MR_EEWr1Int.1", 0, 13, { 0xAAEE, 0xBB06, 0xBB03, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE8, 0x0001, 0xAAEE, 0xBB06, 0xBB06 } }, + { "MR_UsrIDWrInt.1", 0, 23, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x008D, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000D, 0xBB03 } }, + { "MR_CfgWr1Int.1", 0, 16, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB06, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x008D } }, + { "MR_PrgMemWr4Int.1", 0, 24, { 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAE9, 0xBB08, 0xBB02, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x0076, 0xAAEE, 0xBB06, 0xBB06 } }, + { "DBG_Halt.1", 1, 10, { 0xAAF3, 0xBB04, 0xAAE7, 0x002F, 0xAAF3, 0xBB00, 0xAAE7, 0x0005, 0xAAF3, 0xBB01 } }, + { "DBG_RdDEVer.1", 1, 11, { 0xAAF5, 0xAADF, 0xBB02, 0xAAE0, 0xAAE6, 0xBB00, 0xBB05, 0xAAE0, 0xAAE0, 0xAAE0, 0xAAF4 } }, + { "DBG_Run.1", 1, 10, { 0xAAF5, 0xAADF, 0xBB19, 0xAAE0, 0xAAF4, 0xAAE6, 0xBB00, 0xBB04, 0xAAE3, 0xAAE0 } }, + { "DBG_BulkWrData.1", 1, 18, { 0xAAF5, 0xAADF, 0xBB04, 0xAAE0, 0xAAE6, 0xBB00, 0x000C, 0xAADE, 0xAADE, 0xAADE, 0xAADE, 0xAADE, 0xAADD, 0xBB01, 0xAAF4, 0xAAE3, 0xAAE0, 0xAAF4 } }, + { "DBG_BulkRdData.1", 1, 18, { 0xAAF5, 0xAADF, 0xBB03, 0xAAE0, 0xAAE6, 0xBB00, 0x000C, 0xAADE, 0xAADE, 0xAADE, 0xAADE, 0xAAE0, 0xAADD, 0xBB01, 0xAAF4, 0xAAE3, 0xAAE0, 0xAAF4 } }, + { "DBG_SStep.1", 1, 10, { 0xAAF5, 0xAADF, 0xBB1A, 0xAAE0, 0xAAF4, 0xAAE6, 0xBB00, 0xBB04, 0xAAE3, 0xAAE0 } }, + { "DBG_Status.1", 0, 1, { 0xAADC } }, + { "24_ProgEntry.1", 1, 31, { 0xAAFA, 0xAAF7, 0xAAF9, 0xAAF5, 0xAAF3, 0xBB00, 0xAAE8, 0x0014, 0xAAF6, 0xAAFB, 0xAAE7, 0x00EB, 0xAAFA, 0xAAF7, 0xAAE7, 0x002F, 0xAAF2, 0xBBB2, 0xAAF2, 0xBBC2, 0xAAF2, 0xBB12, 0xAAF2, 0xBB8A, 0xAAF6, 0xAAFB, 0xAAE8, 0x0009, 0xAAEE, 0xBB05, 0xBB00 } }, + { "24_RdDevID.1", 0, 47, { 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD9, 0xBBF0, 0xBB0F, 0xBB20, 0xAAD9, 0xBB90, 0xBB01, 0xBB88, 0xAAD9, 0xBB06, 0xBB00, 0xBB20, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB07, 0xBB00, 0xBB20, 0xAAD9, 0xBBB6, 0xBB0B, 0xBBBA, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB20, 0xBB3C, 0xBB88, 0xAAD8, 0xAAD7, 0xAAD8 } }, + { "24_SetAddr.1", 0, 29, { 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD4, 0xBB06, 0xAAD3, 0xBB00, 0xAAD9, 0xBB90, 0xBB01, 0xBB88, 0xAAD9, 0xBB47, 0xBB78, 0xBB20, 0xAAD8 } }, + { "24_ProgMemRd42.1", 0, 28, { 0xAAD9, 0xBB96, 0xBB0B, 0xBBBA, 0xAAD8, 0xAAD8, 0xAAD7, 0xAAD9, 0xBBB6, 0xBB8B, 0xBBBA, 0xAAD8, 0xAAD8, 0xAAEE, 0xBB04, 0xBB01, 0xAAF2, 0xBB00, 0xAAD6, 0xAAEF, 0xAAE9, 0x0014, 0x0029, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8 } }, + { "24_ChpErase450ms.1", 0, 39, { 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD9, 0xBBFA, 0xBB04, 0xBB24, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAE9, 0xBB01, 0xBB00, 0xAAE8, 0x0050 } }, + { "24_ProgMemWrPrep.1", 0, 33, { 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD9, 0xBB1A, 0xBB00, 0xBB24, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88, 0xAAD4, 0xBB07, 0xAAD3, 0xBB00, 0xAAD9, 0xBB90, 0xBB01, 0xBB88, 0xAAD8 } }, + { "24_ProgMemWr64.1", 0, 50, { 0xAAD4, 0xBB00, 0xAAD3, 0xBB01, 0xAAD4, 0xBB03, 0xAAD3, 0xBB02, 0xAAD9, 0xBB80, 0xBB0B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB81, 0xBB9B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB82, 0xBB8B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB83, 0xBB1B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAE9, 0x0020, 0x001F, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAE9, 0xBB01, 0x0003, 0xAAE7, 0xBC64 } }, + { "MR_ProgMemWr1Int.1", 0, 13, { 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x0076, 0xAAEE, 0xBB06, 0xBB06 } }, + { "MR_RdOSCCAL.1", 0, 13, { 0xAAE4, 0xBB05, 0xAAEE, 0xBB06, 0xBB06, 0xAADD, 0xBB03, 0xAADB, 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0 } }, + { "MR_WrOSCCALInt.1", 0, 18, { 0xAAE4, 0xBB05, 0xAAEE, 0xBB06, 0xBB06, 0xAADD, 0xBB03, 0xAADB, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x0076 } }, + { "MR_AddrSet.1", 0, 16, { 0xAAFA, 0xAAF7, 0xAAE7, 0x005E, 0xAAF6, 0xAAFB, 0xAAE7, 0x002F, 0xAAE4, 0xBB05, 0xAAEE, 0xBB06, 0xBB06, 0xAADD, 0xBB03, 0xAADB } }, + { "MR_PrgMemWr8Int.2", 0, 24, { 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAE9, 0xBB08, 0xBB06, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x008D, 0xAAEE, 0xBB06, 0xBB06 } }, + { "MR_UsrIDWrInt.2", 0, 23, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x008D, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000D, 0xBB03 } }, + { "MR_CfgRd2.1", 0, 24, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB06, 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB08, 0xBB01 } }, + { "MR_CfgWr2Int.1", 0, 29, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB06, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x008D, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x008D } }, + { "BL_PrgMemRd32.1", 0, 11, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0, 0xAAE9, 0xBB08, 0x001F } }, + { "BL_CfgRd1.1", 0, 5, { 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0 } }, + { "BL_UsrIDRd4@x400", 0, 26, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x00FF, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0, 0xAAE9, 0xBB08, 0xBB03 } }, + { "BL_OSCCALRd1.1", 0, 11, { 0xAAEE, 0xBB06, 0xBB06, 0xAADD, 0xBB03, 0xAADB, 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0 } }, + { "BL_PrgMemWr1Ext.1", 0, 16, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB0E } }, + { "BL_ChpErase@x800", 0, 38, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x00FF, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x00FF, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB02 } }, + { "BL_UsrIDWr4Ext@x400", 1, 36, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x00FF, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB0E, 0xAAE7, 0xBB05, 0xAAE9, 0x0012, 0xBB03 } }, + { "BL_CfgWr1Ext", 0, 13, { 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB0E } }, + { "BL_OSCCALWrExt", 0, 19, { 0xAAEE, 0xBB06, 0xBB06, 0xAADD, 0xBB03, 0xAADB, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB0E } }, + { "BL_ChpErase@x100", 0, 23, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x003F, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB02 } }, + { "BL_ChpErase@x200", 0, 23, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x007F, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB02 } }, + { "BL_UsrIDRd4@x100", 0, 26, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x003F, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0, 0xAAE9, 0xBB08, 0xBB03 } }, + { "BL_UsrIDRd4@x200", 0, 26, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x007F, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0, 0xAAE9, 0xBB08, 0xBB03 } }, + { "BL_UsrIDWr4Ext@x100", 1, 36, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x003F, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB0E, 0xAAE7, 0xBB05, 0xAAE9, 0x0012, 0xBB03 } }, + { "BL_UsrIDWr4Ext@x200", 1, 36, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x007F, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB0E, 0xAAE7, 0xBB05, 0xAAE9, 0x0012, 0xBB03 } }, + { "BL_UsrIDWr4Ext@x800", 0, 51, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x00FF, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x00FF, 0xAAEE, 0xBB06, 0x0006, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB0E, 0xAAE7, 0xBB05, 0xAAE9, 0x0012, 0xBB03 } }, + { "BL_UsrIDRd4@x800", 0, 41, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x00FF, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x00FF, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0, 0xAAE9, 0xBB08, 0xBB03 } }, + { "BL_PrgMemWr4Ext.1", 0, 19, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAE9, 0xBB08, 0xBB03, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB0E } }, + { "BL_ChpErase@x400", 0, 23, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x00FF, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB02 } }, + { "18F_DevIDRd.1", 1, 30, { 0xAADA, 0xBB00, 0xBB00, 0xAADA, 0xBB3F, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBBFF, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAADA, 0xBBFE, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB09, 0xAAF2, 0xBB00, 0xAAF0, 0xAAE9, 0xBB06, 0xBB01 } }, + { "18F_PrgMemRd64", 0, 9, { 0xAAEE, 0xBB04, 0xBB09, 0xAAF2, 0xBB00, 0xAAF0, 0xAAE9, 0x0006, 0x007F } }, + { "18F_SetAddr.1", 0, 27, { 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E } }, + { "18F_EERdPrepSmall.1", 0, 17, { 0xAADA, 0xBBA6, 0xBB9E, 0xAADA, 0xBBA6, 0xBB9C, 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADB, 0xAADB, 0xAADA, 0xBBA9, 0xBB6E } }, + { "18F_EERd32Small.1", 0, 21, { 0xAADA, 0xBBA6, 0xBB80, 0xAADA, 0xBBA8, 0xBB50, 0xAADA, 0xBBF5, 0xBB6E, 0xAAEE, 0xBB04, 0xBB02, 0xAAF2, 0xBB00, 0xAAF0, 0xAADA, 0xBBA9, 0xBB2A, 0xAAE9, 0x0012, 0x001F } }, + { "18F_CfgRd7.1", 0, 27, { 0xAADA, 0xBB30, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBB00, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAADA, 0xBB00, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB09, 0xAAF2, 0xBB00, 0xAAF0, 0xAAE9, 0xBB06, 0x000D } }, + { "18F_UsrIDRd4.1", 0, 27, { 0xAADA, 0xBB20, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBB00, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAADA, 0xBB00, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB09, 0xAAF2, 0xBB00, 0xAAF0, 0xAAE9, 0xBB06, 0x0007 } }, + { "18F_ChpErase.x80", 0, 37, { 0xAADA, 0xBB3C, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBB00, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAADA, 0xBB04, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB0C, 0xAAF2, 0xBB80, 0xAAF2, 0xBB80, 0xAADA, 0xBB00, 0xBB00, 0xAAEE, 0xBB04, 0xBB00, 0xAAE8, 0xBB01, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00 } }, + { "18F_PrgMemWrPrep.1", 0, 33, { 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBBA6, 0xBB8E, 0xAADA, 0xBBA6, 0xBB9C } }, + { "18F_ProgMemWr4.1ms", 0, 35, { 0xAAEE, 0xBB04, 0xBB0D, 0xAAF1, 0xAAF1, 0xAAE9, 0xBB05, 0xBB02, 0xAAEE, 0xBB04, 0xBB0F, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB03, 0xBB00, 0xAAF3, 0xBB04, 0xAAE7, 0x002F, 0xAAF3, 0xBB00, 0xAAE7, 0xBB05, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB04, 0xBB0D, 0xAAF2, 0xBBFF, 0xAAF2, 0xBBFF } }, + { "18F_UsrIDWr4.1ms", 0, 47, { 0xAADA, 0xBB20, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBB00, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAADA, 0xBBF6, 0xBB6E, 0xAADA, 0xBBA6, 0xBB8E, 0xAADA, 0xBBA6, 0xBB9C, 0xAAEE, 0xBB04, 0xBB0D, 0xAAF1, 0xAAF1, 0xAAE9, 0xBB05, 0xBB02, 0xAAEE, 0xBB04, 0xBB0F, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB03, 0xBB00, 0xAAF3, 0xBB04, 0xAAE7, 0x002F, 0xAAF3, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00 } }, + { "18F_CfgWrPrep", 0, 30, { 0xAADA, 0xBBA6, 0xBB8E, 0xAADA, 0xBBA6, 0xBB8C, 0xAADA, 0xBB00, 0xBBEF, 0xAADA, 0xBB00, 0xBBF8, 0xAADA, 0xBB30, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBB00, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAADA, 0xBBF6, 0xBB6E, 0xAADB, 0xAADB, 0xAADB } }, + { "18F_CfgWr7_1ms", 0, 51, { 0xAAEE, 0xBB04, 0xBB0F, 0xAAF1, 0xAAF2, 0xBB00, 0xAAEE, 0xBB03, 0xBB00, 0xAAF3, 0xBB04, 0xAAE7, 0x002F, 0xAAF3, 0xBB00, 0xAAE7, 0xBB05, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAADA, 0xBBF6, 0xBB2A, 0xAAEE, 0xBB04, 0xBB0F, 0xAAF2, 0xBB00, 0xAAF1, 0xAAEE, 0xBB03, 0xBB00, 0xAAF3, 0xBB04, 0xAAE7, 0x002F, 0xAAF3, 0xBB00, 0xAAE7, 0xBB05, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAADA, 0xBBF6, 0xBB2A, 0xAAE9, 0x0030, 0x0006 } }, + { "18F_EEWrPrepSmall", 0, 17, { 0xAADA, 0xBBA6, 0xBB9E, 0xAADA, 0xBBA6, 0xBB9C, 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADA, 0xBBA9, 0xBB6E, 0xAADB, 0xAADB } }, + { "18F_EEWr1Small5ms", 0, 38, { 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADA, 0xBBA8, 0xBB6E, 0xAADA, 0xBBA6, 0xBB84, 0xAADA, 0xBB55, 0xBB0E, 0xAADA, 0xBBA7, 0xBB6E, 0xAADA, 0xBBAA, 0xBB0E, 0xAADA, 0xBBA7, 0xBB6E, 0xAADA, 0xBBA6, 0xBB82, 0xAADA, 0xBB00, 0xBB00, 0xAADA, 0xBB00, 0xBB00, 0xAAE8, 0xBB01, 0xAADA, 0xBBA9, 0xBB2A } }, + { "18J_ProgEntry", 1, 28, { 0xAAFA, 0xAAF7, 0xAAF9, 0xAAF5, 0xAAF3, 0xBB00, 0xAAE8, 0x0014, 0xAAF6, 0xAAFB, 0xAAE7, 0x002F, 0xAAFA, 0xAAF7, 0xAAE7, 0x002F, 0xAAF2, 0xBBB2, 0xAAF2, 0xBBC2, 0xAAF2, 0xBB12, 0xAAF2, 0xBB0A, 0xAAF6, 0xAAFB, 0xAAE7, 0x00EB } }, + { "18J_ChpErase400ms", 0, 52, { 0xAADA, 0xBB3C, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBB00, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAADA, 0xBB05, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB0C, 0xAAF2, 0xBB01, 0xAAF2, 0xBB01, 0xAADA, 0xBB04, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB0C, 0xAAF2, 0xBB80, 0xAAF2, 0xBB80, 0xAADA, 0xBB00, 0xBB00, 0xAAEE, 0xBB04, 0xBB00, 0xAAE8, 0x004A, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAE8, 0xBB19 } }, + { "MR_CfgWr1Ext.1", 0, 21, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB06, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x0076, 0xAAEE, 0xBB06, 0xBB0A, 0xAAE7, 0xBB05 } }, + { "MR_DbgVctWr2Int.1", 0, 29, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB03, 0xAAEE, 0xBB06, 0x0002, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x008D, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000D, 0xBB01 } }, + { "MR_DbgVctRd2.1", 0, 24, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB03, 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB08, 0xBB01 } }, + { "18J_PrgMemWrPrep", 0, 30, { 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBBA6, 0xBB84 } }, + { "18J_PrgMemWr32", 0, 35, { 0xAAEE, 0xBB04, 0xBB0D, 0xAAF1, 0xAAF1, 0xAAE9, 0xBB05, 0x001E, 0xAAEE, 0xBB04, 0xBB0F, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB03, 0xBB00, 0xAAF3, 0xBB04, 0xAAE8, 0x0001, 0xAAE7, 0x00D6, 0xAAF3, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB04, 0xBB0D, 0xAAF2, 0xBBFF, 0xAAF2, 0xBBFF } }, + { "MR_ChpErase10ms", 0, 12, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB02 } }, + { "MR_PrgMemWr4Ext.1", 0, 29, { 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB08, 0xBB02, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x0076, 0xAAEE, 0xBB06, 0xBB0A, 0xAAE7, 0xBB05, 0xAAEE, 0xBB06, 0xBB06 } }, + { "MR_UsrIDWr4Ext.1", 0, 28, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x0076, 0xAAEE, 0xBB06, 0xBB0A, 0xAAE7, 0xBB05, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x0012, 0xBB03 } }, + { "MR_CfgWr1Int.2", 0, 23, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x008D } }, + { "MR_PrgMemWr2Ext.1", 0, 26, { 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x002F, 0xAAEE, 0xBB06, 0xBB0E, 0xAAE7, 0xBB05, 0xAAEE, 0xBB06, 0xBB06 } }, + { "MR_ChpErase30ms", 0, 12, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB06 } }, + { "MR_UsrIDWr4Ext.2", 0, 28, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x002F, 0xAAEE, 0xBB06, 0xBB0E, 0xAAE7, 0xBB05, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x0012, 0xBB03 } }, + { "MR_CfgWr1Ext.2", 0, 28, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x002F, 0xAAEE, 0xBB06, 0xBB0E, 0xAAE7, 0xBB05 } }, + { "MR_CfgWr2Ext.2", 0, 34, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x002F, 0xAAEE, 0xBB06, 0xBB0E, 0xAAE7, 0xBB05, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x0012, 0xBB01 } }, + { "MR_ChpErase\"Chip\"1F", 0, 12, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB1F, 0xAAE8, 0xBB02 } }, + { "MR_PrgMemWr4Ext.2", 1, 29, { 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB08, 0xBB02, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB17, 0xAAE7, 0xBB05, 0xAAEE, 0xBB06, 0xBB06 } }, + { "MR_UsrIDWr4Ext.3", 1, 28, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB17, 0xAAE7, 0xBB05, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x0012, 0xBB03 } }, + { "MR_CfgWr2Ext.3", 0, 34, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x002F, 0xAAEE, 0xBB06, 0xBB17, 0xAAE7, 0x0005, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x0012, 0xBB01 } }, + { "MR_EEWr1Ext.1", 2, 24, { 0xAAEE, 0xBB06, 0xBB03, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x00BC, 0xAAEE, 0xBB06, 0xBB17, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB17, 0xAAEE, 0xBB06, 0xBB06 } }, + { "MR_CfgWr1Ext.3", 1, 28, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB17, 0xAAE7, 0x0005 } }, + { "MR_PrgMemWr8Ext.2", 0, 29, { 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB08, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x002F, 0xAAEE, 0xBB06, 0xBB17, 0xAAE7, 0xBB05, 0xAAEE, 0xBB06, 0xBB06 } }, + { "18F_ChpErase.x3F8F", 1, 50, { 0xAADA, 0xBB3C, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBB00, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAADA, 0xBB05, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB0C, 0xAAF2, 0xBB3F, 0xAAF2, 0xBB3F, 0xAADA, 0xBB04, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB0C, 0xAAF2, 0xBB8F, 0xAAF2, 0xBB8F, 0xAADA, 0xBB00, 0xBB00, 0xAAEE, 0xBB04, 0xBB00, 0xAAE8, 0xBB01, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00 } }, + { "18F_ProgMemWr8.1ms", 0, 35, { 0xAAEE, 0xBB04, 0xBB0D, 0xAAF1, 0xAAF1, 0xAAE9, 0xBB05, 0xBB06, 0xAAEE, 0xBB04, 0xBB0F, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB03, 0xBB00, 0xAAF3, 0xBB04, 0xAAE7, 0x002F, 0xAAF3, 0xBB00, 0xAAE7, 0xBB05, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB04, 0xBB0D, 0xAAF2, 0xBBFF, 0xAAF2, 0xBBFF } }, + { "18F_ChpErase.xFF87", 0, 50, { 0xAADA, 0xBB3C, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBB00, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAADA, 0xBB05, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB0C, 0xAAF2, 0xBBFF, 0xAAF2, 0xBBFF, 0xAADA, 0xBB04, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB0C, 0xAAF2, 0xBB87, 0xAAF2, 0xBB87, 0xAADA, 0xBB00, 0xBB00, 0xAAEE, 0xBB04, 0xBB00, 0xAAE8, 0xBB01, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00 } }, + { "18F_ProgMemWr32.1ms-", 0, 35, { 0xAAEE, 0xBB04, 0xBB0D, 0xAAF1, 0xAAF1, 0xAAE9, 0xBB05, 0x001E, 0xAAEE, 0xBB04, 0xBB0F, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB03, 0xBB00, 0xAAF3, 0xBB04, 0xAAE7, 0x002F, 0xAAF3, 0xBB00, 0xAAE7, 0xBB05, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB04, 0xBB0D, 0xAAF2, 0xBBFF, 0xAAF2, 0xBBFF } }, + { "18F_EERdPrepLarge.1", 0, 31, { 0xAADA, 0xBBA6, 0xBB9E, 0xAADA, 0xBBA6, 0xBB9C, 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADA, 0xBBA9, 0xBB6E, 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADA, 0xBBAA, 0xBB6E, 0xAADB, 0xAADA, 0xBB99, 0xBB0E, 0xAADA, 0xBBF5, 0xBB6E } }, + { "18F_EERd32Large.1", 0, 33, { 0xAADA, 0xBBA6, 0xBB80, 0xAADA, 0xBBA8, 0xBB50, 0xAADA, 0xBBF5, 0xBB6E, 0xAADA, 0xBB00, 0xBB00, 0xAADA, 0xBB00, 0xBB00, 0xAAEE, 0xBB04, 0xBB02, 0xAAF2, 0xBB00, 0xAAF0, 0xAADA, 0xBBA9, 0xBB2A, 0xAADA, 0xBBD8, 0xBBB0, 0xAADA, 0xBBAA, 0xBB2A, 0xAAE9, 0x001E, 0x001F } }, + { "18F_EEWrPrepLarge.1", 0, 25, { 0xAADA, 0xBBA6, 0xBB9E, 0xAADA, 0xBBA6, 0xBB9C, 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADA, 0xBBA9, 0xBB6E, 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADA, 0xBBAA, 0xBB6E, 0xAADB } }, + { "18F_EEWr1Large5ms", 0, 35, { 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADA, 0xBBA8, 0xBB6E, 0xAADA, 0xBBA6, 0xBB84, 0xAADA, 0xBBA6, 0xBB82, 0xAADA, 0xBB00, 0xBB00, 0xAAE9, 0xBB03, 0xBB03, 0xAAE8, 0x0001, 0xAADA, 0xBB00, 0xBB00, 0xAADA, 0xBBA9, 0xBB2A, 0xAADA, 0xBBD8, 0xBBB0, 0xAADA, 0xBBAA, 0xBB2A } }, + { "MR_ChpErase87x", 0, 56, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBBFE, 0xAAF2, 0xBB7F, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB06, 0xAAEE, 0xBB06, 0xBB01, 0xAAEE, 0xBB06, 0xBB07, 0xAAEE, 0xBB06, 0xBB08, 0xAAE8, 0xBB02, 0xAAEE, 0xBB06, 0xBB01, 0xAAEE, 0xBB06, 0xBB07, 0xAAE8, 0xBB02, 0xAAEE, 0xBB06, 0xBB03, 0xAAF2, 0xBBFE, 0xAAF2, 0xBB7F, 0xAAEE, 0xBB06, 0xBB01, 0xAAEE, 0xBB06, 0xBB07, 0xAAEE, 0xBB06, 0xBB08, 0xAAE8, 0xBB02, 0xAAEE, 0xBB06, 0xBB01, 0xAAEE, 0xBB06, 0xBB07 } }, + { "MR_RowErase16.1", 0, 13, { 0xAAEE, 0xBB06, 0xBB11, 0xAAE8, 0xBB01, 0xAAE7, 0x0019, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0x000F } }, + { "18F_ProgMemWr16.1ms", 0, 35, { 0xAAEE, 0xBB04, 0xBB0D, 0xAAF1, 0xAAF1, 0xAAE9, 0xBB05, 0x000E, 0xAAEE, 0xBB04, 0xBB0F, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB03, 0xBB00, 0xAAF3, 0xBB04, 0xAAE7, 0x002F, 0xAAF3, 0xBB00, 0xAAE7, 0xBB05, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB04, 0xBB0D, 0xAAF2, 0xBBFF, 0xAAF2, 0xBBFF } }, + { "18F_ProgMemWr32.1ms", 0, 35, { 0xAAEE, 0xBB04, 0xBB0D, 0xAAF1, 0xAAF1, 0xAAE9, 0xBB05, 0x001E, 0xAAEE, 0xBB04, 0xBB0F, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB03, 0xBB00, 0xAAF3, 0xBB04, 0xAAE7, 0x002F, 0xAAF3, 0xBB00, 0xAAE7, 0xBB05, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB04, 0xBB0D, 0xAAF2, 0xBBFF, 0xAAF2, 0xBBFF } }, + { "MR_ProgMemWr1Int.2", 0, 13, { 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x00BC, 0xAAEE, 0xBB06, 0xBB06 } }, + { "MR_UsrIDWrInt.3", 0, 23, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x00BC, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000D, 0xBB03 } }, + { "MR_CfgWr1Int.2", 0, 23, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x00BC } }, + { "18F_EEWr1LargeAA55", 0, 44, { 0xAAEE, 0xBB04, 0xBB00, 0xAAF1, 0xAAF2, 0xBB0E, 0xAADA, 0xBBA8, 0xBB6E, 0xAADA, 0xBBA6, 0xBB84, 0xAADA, 0xBB55, 0xBB0E, 0xAADA, 0xBBA7, 0xBB6E, 0xAADA, 0xBBAA, 0xBB0E, 0xAADA, 0xBBA7, 0xBB6E, 0xAADA, 0xBBA6, 0xBB82, 0xAADA, 0xBB00, 0xBB00, 0xAADA, 0xBB00, 0xBB00, 0xAAE8, 0xBB01, 0xAADA, 0xBBA9, 0xBB2A, 0xAADA, 0xBBD8, 0xBBB0, 0xAADA, 0xBBAA, 0xBB2A } }, + { "MR_ProgMemWr1Ext.1", 0, 18, { 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x0076, 0xAAEE, 0xBB06, 0xBB0A, 0xAAE7, 0xBB05, 0xAAEE, 0xBB06, 0xBB06 } }, + { "MR_PMemErase10msI", 0, 12, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB02 } }, + { "MR_PMemEraseExt", 0, 18, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB09, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB17 } }, + { "30_ChpErasePrep", 0, 23, { 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8, 0xAAD9, 0xBB06, 0xBB5C, 0xBB20, 0xAAD9, 0xBB16, 0xBB3B, 0xBB88, 0xAAD9, 0xBB06, 0xBB08, 0xBB20, 0xAAD9, 0xBB26, 0xBB3B, 0xBB88 } }, + { "MR_PMemErase87x", 0, 32, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBBFE, 0xAAF2, 0xBB7F, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB06, 0xAAEE, 0xBB06, 0xBB01, 0xAAEE, 0xBB06, 0xBB07, 0xAAEE, 0xBB06, 0xBB08, 0xAAE8, 0xBB02, 0xAAEE, 0xBB06, 0xBB01, 0xAAEE, 0xBB06, 0xBB07, 0xAAE8, 0xBB02 } }, + { "MR_EEMemEraseExt", 0, 11, { 0xAAEE, 0xBB06, 0xBB0B, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB17 } }, + { "18F_PMemErase.xF83", 0, 50, { 0xAADA, 0xBB3C, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBB00, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAADA, 0xBB05, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB0C, 0xAAF2, 0xBB0F, 0xAAF2, 0xBB0F, 0xAADA, 0xBB04, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB0C, 0xAAF2, 0xBB83, 0xAAF2, 0xBB83, 0xAADA, 0xBB00, 0xBB00, 0xAAEE, 0xBB04, 0xBB00, 0xAAE8, 0xBB01, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00 } }, + { "18F_EraseTest2", 0, 43, { 0xBBD2, 0xBB83, 0xBBD2, 0xBB88, 0xAADA, 0xBB3C, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBB00, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAADA, 0xBB04, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB0C, 0xAAF1, 0xAAF2, 0xBB00, 0xAADA, 0xBB00, 0xBB00, 0xAAEE, 0xBB04, 0xBB00, 0xAAE8, 0xBB01, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAE9, 0x0024, 0xBB01 } }, + { "18F_PMemErase.xFF83", 0, 50, { 0xAADA, 0xBB3C, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBB00, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAADA, 0xBB05, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB0C, 0xAAF2, 0xBBFF, 0xAAF2, 0xBBFF, 0xAADA, 0xBB04, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB0C, 0xAAF2, 0xBB83, 0xAAF2, 0xBB83, 0xAADA, 0xBB00, 0xBB00, 0xAAEE, 0xBB04, 0xBB00, 0xAAE8, 0xBB01, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00 } }, + { "MR_PrgMemWr4Ext.3", 0, 29, { 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB08, 0xBB02, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB0E, 0xAAE7, 0xBB05, 0xAAEE, 0xBB06, 0xBB06 } }, + { "MR_UsrIDWr4Ext.4", 0, 28, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x0076, 0xAAEE, 0xBB06, 0xBB0E, 0xAAE7, 0xBB05, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x0012, 0xBB03 } }, + { "MR_CfgWr1Ext.4", 1, 27, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB06, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x0076, 0xAAEE, 0xBB06, 0xBB0E, 0xAAE7, 0xBB05, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000D, 0x0001 } }, + { "33_CfgRd8", 0, 48, { 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD9, 0xBB80, 0xBB0F, 0xBB20, 0xAAD9, 0xBB90, 0xBB01, 0xBB88, 0xAAD9, 0xBB00, 0xBB03, 0xBBEB, 0xAAD9, 0xBB47, 0xBB78, 0xBB20, 0xAAD8, 0xAAD9, 0xBBB6, 0xBB0B, 0xBBBA, 0xAAD8, 0xAAD8, 0xAAD7, 0xAAE9, 0xBB08, 0xBB07, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8 } }, + { "33_UserIDRd4", 0, 54, { 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD9, 0xBB80, 0xBB0F, 0xBB20, 0xAAD9, 0xBB90, 0xBB01, 0xBB88, 0xAAD9, 0xBB06, 0xBB01, 0xBB20, 0xAAD9, 0xBB47, 0xBB78, 0xBB20, 0xAAD8, 0xAAD9, 0xBBB6, 0xBB0B, 0xBBBA, 0xAAD8, 0xAAD8, 0xAAEE, 0xBB04, 0xBB01, 0xAAF2, 0xBB00, 0xAAD6, 0xAAEF, 0xAAE9, 0x000D, 0xBB03, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8 } }, + { "33_ProgMemWr64.1", 0, 50, { 0xAAD4, 0xBB00, 0xAAD3, 0xBB01, 0xAAD4, 0xBB03, 0xAAD3, 0xBB02, 0xAAD9, 0xBB80, 0xBB0B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB81, 0xBB9B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB82, 0xBB8B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB83, 0xBB1B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAE9, 0x0020, 0x001F, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAE9, 0xBB01, 0x0003, 0xAAE7, 0x0048 } }, + { "33_UsrIDWr4", 0, 60, { 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD9, 0xBB07, 0xBB01, 0xBB20, 0xAAD9, 0xBB0A, 0xBB00, 0xBB24, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88, 0xAAD9, 0xBB80, 0xBB0F, 0xBB20, 0xAAD9, 0xBB90, 0xBB01, 0xBB88, 0xAAD3, 0xBB00, 0xAAD9, 0xBB80, 0xBB1B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA8, 0xAAD8, 0xAAD8, 0xAAE8, 0xBB06, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA9, 0xAAD8, 0xAAE9, 0x0015, 0xBB03 } }, + { "33_CfgWr8", 0, 60, { 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD9, 0xBB07, 0xBB00, 0xBB20, 0xAAD9, 0xBB0A, 0xBB00, 0xBB24, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88, 0xAAD9, 0xBB80, 0xBB0F, 0xBB20, 0xAAD9, 0xBB90, 0xBB01, 0xBB88, 0xAAD4, 0xBB00, 0xAAD9, 0xBB80, 0xBB1B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA8, 0xAAD8, 0xAAD8, 0xAAE8, 0x0006, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA9, 0xAAD8, 0xAAE9, 0x0015, 0xBB07 } }, + { "MR_PMemErase15msI", 0, 15, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBBFE, 0xAAF2, 0xBB7F, 0xAAEE, 0xBB06, 0xBB09, 0xAAEE, 0xBB06, 0xBB08, 0xAAE8, 0xBB03 } }, + { "MR_PrgMemWr4Int.2", 0, 24, { 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAE9, 0xBB08, 0xBB02, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x008D, 0xAAEE, 0xBB06, 0xBB06 } }, + { "18F_ChpErase.x018A", 0, 50, { 0xAADA, 0xBB3C, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBB00, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAADA, 0xBB05, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB0C, 0xAAF2, 0xBB01, 0xAAF2, 0xBB01, 0xAADA, 0xBB04, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB0C, 0xAAF2, 0xBB8A, 0xAAF2, 0xBB8A, 0xAADA, 0xBB00, 0xBB00, 0xAAEE, 0xBB04, 0xBB00, 0xAAE8, 0xBB06, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00 } }, + { "18F_ProgMemWr8.2ms", 0, 35, { 0xAAEE, 0xBB04, 0xBB0D, 0xAAF1, 0xAAF1, 0xAAE9, 0xBB05, 0x0006, 0xAAEE, 0xBB04, 0xBB0F, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB03, 0xBB00, 0xAAF3, 0xBB04, 0xAAE7, 0x005E, 0xAAF3, 0xBB00, 0xAAE7, 0xBB06, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB04, 0xBB0D, 0xAAF2, 0xBBFF, 0xAAF2, 0xBBFF } }, + { "18F_CfgWr7_2ms", 0, 60, { 0xAADA, 0xBBA6, 0xBB84, 0xAAEE, 0xBB04, 0xBB0F, 0xAAF1, 0xAAF2, 0xBB00, 0xAAEE, 0xBB03, 0xBB00, 0xAAF3, 0xBB04, 0xAAE7, 0x005E, 0xAAF3, 0xBB00, 0xAAE7, 0x000C, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAADA, 0xBB00, 0xBB00, 0xAADA, 0xBBF6, 0xBB2A, 0xAAEE, 0xBB04, 0xBB0F, 0xAAF2, 0xBB00, 0xAAF1, 0xAAEE, 0xBB03, 0xBB00, 0xAAF3, 0xBB04, 0xAAE7, 0x005E, 0xAAF3, 0xBB00, 0xAAE7, 0xBB12, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAADA, 0xBB00, 0xBB00, 0xAADA, 0xBBF6, 0xBB2A, 0xAAE9, 0x0036, 0x0006 } }, + { "18F_UsrIDWr4.2ms", 0, 49, { 0xAADA, 0xBB20, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBB00, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAADA, 0xBBF6, 0xBB6E, 0xAADA, 0xBBA6, 0xBB9C, 0xAADA, 0xBBA6, 0xBB84, 0xAAEE, 0xBB04, 0xBB0D, 0xAAF1, 0xAAF1, 0xAAE9, 0xBB05, 0xBB02, 0xAAEE, 0xBB04, 0xBB0F, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB03, 0xBB00, 0xAAF3, 0xBB04, 0xAAE7, 0x005E, 0xAAF3, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAE7, 0xBB06 } }, + { "MR_TstMemRd8", 0, 11, { 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB08, 0xBB07 } }, + { "30S_UsrIDRdPrep", 0, 33, { 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD9, 0xBB06, 0xBB5C, 0xBB20, 0xAAD9, 0xBB00, 0xBB08, 0xBB20, 0xAAD9, 0xBB90, 0xBB01, 0xBB88, 0xAAD9, 0xBB47, 0xBB78, 0xBB20, 0xAAD8 } }, + { "BL_TestMemRd8", 0, 11, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0, 0xAAE9, 0xBB08, 0x0007 } }, + { "18F_TstMemRd8.1", 0, 9, { 0xAAEE, 0xBB04, 0xBB09, 0xAAF2, 0xBB00, 0xAAF0, 0xAAE9, 0xBB06, 0x000F } }, + { "MR_CalWrdsErWr91x", 0, 46, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB07, 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB02, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x008D, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB02, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x008D } }, + { "MR_CalWrdsErWr88x", 0, 28, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB08, 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB02, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x008D } }, + { "MR_CalWrdsErWr6xx-1", 0, 28, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB07, 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB02, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x008D } }, + { "MR_CalWrdErWr61x", 0, 33, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB07, 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB02, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x0076, 0xAAEE, 0xBB06, 0xBB0A, 0xAAE7, 0xBB05 } }, + { "30_RdDevID", 0, 49, { 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8, 0xAAE9, 0xBB07, 0xBB01, 0xAAD9, 0xBBF0, 0xBB0F, 0xBB20, 0xAAD9, 0xBB90, 0xBB01, 0xBB88, 0xAAD9, 0xBB06, 0xBB00, 0xBB20, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB80, 0xBB03, 0xBBEB, 0xAAD9, 0xBBB6, 0xBB0B, 0xBBBA, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB20, 0xBB3C, 0xBB88, 0xAAD8, 0xAAEE, 0xBB04, 0xBB01, 0xAAF2, 0xBB00, 0xAAF0, 0xAAF0, 0xAAD8 } }, + { "30_ChpErase4ms", 0, 49, { 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8, 0xAAD9, 0xBBFA, 0xBB07, 0xBB24, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88, 0xAAD9, 0xBB58, 0xBB05, 0xBB20, 0xAAD9, 0xBBA9, 0xBB0A, 0xBB20, 0xAAD9, 0xBB38, 0xBB3B, 0xBB88, 0xAAD9, 0xBB39, 0xBB3B, 0xBB88, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAE7, 0x00BC, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA9, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8 } }, + { "30_SetAddr.1", 1, 35, { 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8, 0xAAE9, 0xBB07, 0xBB01, 0xAAD4, 0xBB06, 0xAAD3, 0xBB00, 0xAAD9, 0xBB90, 0xBB01, 0xBB88, 0xAAD9, 0xBB16, 0xBB3B, 0xBB88, 0xAAD9, 0xBB20, 0xBB3B, 0xBB88, 0xAAD9, 0xBB05, 0xBB02, 0xBB20, 0xAAD9, 0xBB47, 0xBB78, 0xBB20, 0xAAD8 } }, + { "30_ProgMemRd42.1", 0, 34, { 0xAAD9, 0xBB96, 0xBB0B, 0xBBBA, 0xAAD8, 0xAAD8, 0xAAEE, 0xBB04, 0xBB01, 0xAAF2, 0xBB00, 0xAAF0, 0xAAF0, 0xAAD9, 0xBBB6, 0xBB8B, 0xBBBA, 0xAAD8, 0xAAD8, 0xAAEE, 0xBB04, 0xBB01, 0xAAF2, 0xBB00, 0xAAF0, 0xAAEF, 0xAAE9, 0x001A, 0x0029, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8 } }, + { "30_CfgRd7", 0, 48, { 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB80, 0xBB0F, 0xBB20, 0xAAD9, 0xBB90, 0xBB01, 0xBB88, 0xAAD9, 0xBB06, 0xBB00, 0xBB20, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB80, 0xBB03, 0xBBEB, 0xAAD9, 0xBBB6, 0xBB0B, 0xBBBA, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB20, 0xBB3C, 0xBB88, 0xAAD8, 0xAAEE, 0xBB04, 0xBB01, 0xAAF2, 0xBB00, 0xAAF0, 0xAAF0, 0xAAD8, 0xAAE9, 0x0013, 0xBB06 } }, + { "30_EERd64.1", 0, 21, { 0xAAD9, 0xBBB6, 0xBB0B, 0xBBBA, 0xAAD8, 0xAAD8, 0xAAEE, 0xBB04, 0xBB01, 0xAAF2, 0xBB00, 0xAAF0, 0xAAF0, 0xAAE9, 0x000D, 0x003F, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8 } }, + { "30_ProgMemWrPrep.1", 1, 41, { 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB1A, 0xBB00, 0xBB24, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88, 0xAAD4, 0xBB07, 0xAAD3, 0xBB00, 0xAAD9, 0xBB90, 0xBB01, 0xBB88, 0xAAD8, 0xAAD9, 0xBB00, 0xBB03, 0xBBEB, 0xAAD9, 0xBB16, 0xBB3B, 0xBB88, 0xAAD9, 0xBB26, 0xBB3B, 0xBB88, 0xAAD9, 0xBB05, 0xBB04, 0xBB20 } }, + { "30_ProgMemWr32.1", 0, 61, { 0xAAD4, 0xBB00, 0xAAD3, 0xBB01, 0xAAD9, 0xBB80, 0xBB0B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB81, 0xBB9B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAE9, 0x0010, 0x001F, 0xAAD9, 0xBB58, 0xBB05, 0xBB20, 0xAAD9, 0xBB38, 0xBB3B, 0xBB88, 0xAAD9, 0xBBA9, 0xBB0A, 0xBB20, 0xAAD9, 0xBB39, 0xBB3B, 0xBB88, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAE7, 0x005E, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA9, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88 } }, + { "30_EEWrPrep.1", 0, 25, { 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB5A, 0xBB00, 0xBB24, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88, 0xAAD4, 0xBB07, 0xAAD3, 0xBB00, 0xAAD9, 0xBB90, 0xBB01, 0xBB88, 0xAAD8 } }, + { "30_EEWr16.1", 0, 61, { 0xAAD4, 0xBB00, 0xAAD4, 0xBB01, 0xAAD9, 0xBB80, 0xBB1B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB81, 0xBB1B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAE9, 0x0010, 0x0007, 0xAAD9, 0xBB58, 0xBB05, 0xBB20, 0xAAD9, 0xBB38, 0xBB3B, 0xBB88, 0xAAD9, 0xBBA9, 0xBB0A, 0xBB20, 0xAAD9, 0xBB39, 0xBB3B, 0xBB88, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAE7, 0x005E, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA9, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88 } }, + { "30_CfgWrPrep.1", 0, 28, { 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB8A, 0xBB00, 0xBB24, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88, 0xAAD4, 0xBB07, 0xAADB, 0xAAD9, 0xBB81, 0xBB0F, 0xBB20, 0xAAD9, 0xBB91, 0xBB01, 0xBB88, 0xAAD8 } }, + { "30_CfgWr7.1", 0, 53, { 0xAAD4, 0xBB00, 0xAAD9, 0xBB80, 0xBB1B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB58, 0xBB05, 0xBB20, 0xAAD9, 0xBB38, 0xBB3B, 0xBB88, 0xAAD9, 0xBBA9, 0xBB0A, 0xBB20, 0xAAD9, 0xBB39, 0xBB3B, 0xBB88, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAE7, 0x005E, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA9, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88, 0xAAD8, 0xAAD8, 0xAAE9, 0x0032, 0x0006 } }, + { "30_CfgClear7.1", 0, 55, { 0xAAD9, 0xBB00, 0xBB00, 0xBB20, 0xAAD9, 0xBB80, 0xBB1B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB58, 0xBB05, 0xBB20, 0xAAD9, 0xBB38, 0xBB3B, 0xBB88, 0xAAD9, 0xBBA9, 0xBB0A, 0xBB20, 0xAAD9, 0xBB39, 0xBB3B, 0xBB88, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAE7, 0x005E, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA9, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88, 0xAAD8, 0xAAD8, 0xAAE9, 0x0030, 0x0006 } }, + { "30_UsrIDRdPrep", 0, 25, { 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB06, 0xBB5C, 0xBB20, 0xAAD9, 0xBB00, 0xBB08, 0xBB20, 0xAAD9, 0xBB90, 0xBB01, 0xBB88, 0xAAD9, 0xBB47, 0xBB78, 0xBB20, 0xAAD8 } }, + { "30_UsrIDRd32.1", 0, 34, { 0xAAD9, 0xBB96, 0xBB0B, 0xBBBA, 0xAAD8, 0xAAD8, 0xAAEE, 0xBB04, 0xBB01, 0xAAF2, 0xBB00, 0xAAF0, 0xAAF0, 0xAAD9, 0xBBB6, 0xBB8B, 0xBBBA, 0xAAD8, 0xAAD8, 0xAAEE, 0xBB04, 0xBB01, 0xAAF2, 0xBB00, 0xAAF0, 0xAAEF, 0xAAE9, 0x001A, 0x001F, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8 } }, + { "30_UsrIDWrPrep.1", 0, 29, { 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB1A, 0xBB00, 0xBB24, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88, 0xAAD9, 0xBB07, 0xBB5C, 0xBB20, 0xAAD9, 0xBB00, 0xBB08, 0xBB20, 0xAAD9, 0xBB90, 0xBB01, 0xBB88, 0xAAD8 } }, + { "30S_CfgWrPrep", 0, 27, { 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAADB, 0xAADB, 0xAADB, 0xAAD9, 0xBB07, 0xBB00, 0xBB20, 0xAAD9, 0xBB8A, 0xBB00, 0xBB24 } }, + { "30S_CfgWr8", 0, 45, { 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88, 0xAAD9, 0xBB80, 0xBB0F, 0xBB20, 0xAAD9, 0xBB90, 0xBB01, 0xBB88, 0xAAD4, 0xBB00, 0xAAD9, 0xBB80, 0xBB1B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAE8, 0xBB01, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA9, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAE9, 0x002A, 0xBB07 } }, + { "30S_ProgMemWr32", 0, 46, { 0xAAD4, 0xBB00, 0xAAD3, 0xBB01, 0xAAD9, 0xBB80, 0xBB0B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB81, 0xBB9B, 0xBBBB, 0xAAD8, 0xAAD8, 0xAAE9, 0x0010, 0x001F, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAE7, 0xBB94, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA9, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88 } }, + { "30S_ChpErasePrep", 0, 27, { 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB06, 0xBB5C, 0xBB20, 0xAAD9, 0xBB16, 0xBB3B, 0xBB88, 0xAAD9, 0xBB06, 0xBB08, 0xBB20, 0xAAD9, 0xBB26, 0xBB3B, 0xBB88 } }, + { "30S_UsrIDWrPrep.1", 0, 32, { 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD9, 0xBB00, 0xBB02, 0xBB04, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB1A, 0xBB00, 0xBB24, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88, 0xAAD9, 0xBB07, 0xBB5C, 0xBB20, 0xAAD9, 0xBB00, 0xBB08, 0xBB20, 0xAAD9, 0xBB90, 0xBB01, 0xBB88, 0xAAD8 } }, + { "MR_DbgVctWr2Ext.3", 0, 34, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB03, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x002F, 0xAAEE, 0xBB06, 0xBB17, 0xAAE7, 0x0005, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x0012, 0xBB01 } }, + { "BL_UsrIDRd4@x440", 0, 32, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x00FF, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0x003F, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0, 0xAAE9, 0xBB08, 0xBB03 } }, + { "BL_UsrIDWr4Ext@x440", 1, 42, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x00FF, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0x003F, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB0E, 0xAAE7, 0xBB05, 0xAAE9, 0x0012, 0xBB03 } }, + { "BL_OSCCALRd1@x3FF", 0, 23, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x00FF, 0xAADB, 0xAADB, 0xAADB, 0xAAEE, 0xBB06, 0xBB04, 0xAAF0, 0xAAF0 } }, + { "BL_OSCCALWrExt@x3FF", 0, 31, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x00FF, 0xAADB, 0xAADB, 0xAADB, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB0E } }, + { "BL_ChpErase-519", 0, 45, { 0xAAEE, 0xBB06, 0xBB02, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB0E, 0xAAE7, 0x000A, 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB02, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000F, 0x00DA, 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB02 } }, + { "BL_EEPrep-x400", 0, 15, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x00FF } }, + { "BL_PMemErase-519", 0, 28, { 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB02, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000F, 0x00DA, 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB02 } }, + { "BL_EEMemErase-519", 0, 23, { 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000C, 0x00FF, 0xAAEE, 0xBB06, 0xBB06, 0xAAEE, 0xBB06, 0xBB09, 0xAAE8, 0xBB02 } }, + { "18F_DbgVctWr2.2ms", 0, 49, { 0xAADA, 0xBB20, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBB00, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAADA, 0xBB28, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAADA, 0xBBA6, 0xBB8E, 0xAADA, 0xBBA6, 0xBB9C, 0xAAEE, 0xBB04, 0xBB0D, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB04, 0xBB0F, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB03, 0xBB00, 0xAAF3, 0xBB04, 0xAAE7, 0x005E, 0xAAF3, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAE7, 0xBB06 } }, + { "18F_DbgVctRd2.1", 0, 27, { 0xAADA, 0xBB20, 0xBB0E, 0xAADA, 0xBBF8, 0xBB6E, 0xAADA, 0xBB00, 0xBB0E, 0xAADA, 0xBBF7, 0xBB6E, 0xAADA, 0xBB28, 0xBB0E, 0xAADA, 0xBBF6, 0xBB6E, 0xAAEE, 0xBB04, 0xBB09, 0xAAF2, 0xBB00, 0xAAF0, 0xAAE9, 0xBB06, 0x0003 } }, + { "MR_CfgRowErase.1", 0, 14, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB11, 0xAAE8, 0xBB01, 0xAAE7, 0x0019 } }, + { "MR_RowErase32.2", 0, 21, { 0xAAEE, 0xBB06, 0xBB02, 0xAAF2, 0xBBFE, 0xAAF2, 0xBB7F, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB17, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0x001F } }, + { "MR_CfgRowErase.2", 0, 15, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x005E, 0xAAEE, 0xBB06, 0xBB17 } }, + { "18F_RowErase32.5ms.1", 0, 47, { 0xAADA, 0xBBA6, 0xBB84, 0xAADA, 0xBBA6, 0xBB88, 0xAADA, 0xBB55, 0xBB0E, 0xAADA, 0xBBA7, 0xBB6E, 0xAADA, 0xBBAA, 0xBB0E, 0xAADA, 0xBBA7, 0xBB6E, 0xAADA, 0xBBA6, 0xBB82, 0xAADA, 0xBB00, 0xBB00, 0xAAE8, 0xBB01, 0xAADA, 0xBBA6, 0xBB94, 0xAADA, 0xBB40, 0xBB0E, 0xAADA, 0xBBF6, 0xBB26, 0xAADA, 0xBBD8, 0xBBB0, 0xAADA, 0xBBF7, 0xBB2A, 0xAADA, 0xBBD8, 0xBBB0, 0xAADA, 0xBBF8, 0xBB2A } }, + { "18F_UsrIDRowErs.5ms", 0, 29, { 0xAADA, 0xBBA6, 0xBB84, 0xAADA, 0xBBA6, 0xBB88, 0xAADA, 0xBB55, 0xBB0E, 0xAADA, 0xBBA7, 0xBB6E, 0xAADA, 0xBBAA, 0xBB0E, 0xAADA, 0xBBA7, 0xBB6E, 0xAADA, 0xBBA6, 0xBB82, 0xAADA, 0xBB00, 0xBB00, 0xAAE8, 0xBB01, 0xAADA, 0xBBA6, 0xBB94 } }, + { "18F_RowErase32.5ms.2", 0, 50, { 0xAADA, 0xBBA6, 0xBB84, 0xAADA, 0xBBA6, 0xBB88, 0xAADA, 0xBBA6, 0xBB82, 0xAAEE, 0xBB03, 0xBB00, 0xAAF3, 0xBB04, 0xAAE7, 0x002F, 0xAAF3, 0xBB00, 0xAAE7, 0x0005, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAADA, 0xBB40, 0xBB0E, 0xAADA, 0xBBF6, 0xBB26, 0xAADA, 0xBBD8, 0xBBB0, 0xAADA, 0xBBF7, 0xBB2A, 0xAADA, 0xBBD8, 0xBBB0, 0xAADA, 0xBBF8, 0xBB2A, 0xAAE7, 0xBB47, 0xAADA, 0xBB00, 0xBB00, 0xAADA, 0xBB00, 0xBB00 } }, + { "30_RowErase32.1", 0, 61, { 0xAAD9, 0xBB1A, 0xBB07, 0xBB24, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88, 0xAAD9, 0xBB58, 0xBB05, 0xBB20, 0xAAD9, 0xBB38, 0xBB3B, 0xBB88, 0xAAD9, 0xBBA9, 0xBB0A, 0xBB20, 0xAAD9, 0xBB39, 0xBB3B, 0xBB88, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAE7, 0x005E, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA9, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8, 0xAAD9, 0xBB05, 0xBB03, 0xBB43, 0xAAD9, 0xBB42, 0xBB00, 0xBBAF, 0xAAD9, 0xBB64, 0xBB27, 0xBBEC, 0xAAD9, 0xBB16, 0xBB3B, 0xBB88 } }, + { "30_UsrIDErase.1", 0, 61, { 0xAAD9, 0xBB06, 0xBB5C, 0xBB20, 0xAAD9, 0xBB16, 0xBB3B, 0xBB88, 0xAAD9, 0xBB06, 0xBB08, 0xBB20, 0xAAD9, 0xBB26, 0xBB3B, 0xBB88, 0xAAD9, 0xBB1A, 0xBB07, 0xBB24, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88, 0xAAD9, 0xBB58, 0xBB05, 0xBB20, 0xAAD9, 0xBB38, 0xBB3B, 0xBB88, 0xAAD9, 0xBBA9, 0xBB0A, 0xBB20, 0xAAD9, 0xBB39, 0xBB3B, 0xBB88, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAE7, 0x005E, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA9, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8 } }, + { "30_EERowErase8.1", 0, 61, { 0xAAD9, 0xBB5A, 0xBB07, 0xBB24, 0xAAD9, 0xBB0A, 0xBB3B, 0xBB88, 0xAAD9, 0xBB58, 0xBB05, 0xBB20, 0xAAD9, 0xBB38, 0xBB3B, 0xBB88, 0xAAD9, 0xBBA9, 0xBB0A, 0xBB20, 0xAAD9, 0xBB39, 0xBB3B, 0xBB88, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAD8, 0xAAE7, 0x005E, 0xAAD9, 0xBB61, 0xBBE7, 0xBBA9, 0xAAD8, 0xAAD8, 0xAAD9, 0xBB00, 0xBB01, 0xBB04, 0xAAD8, 0xAAD9, 0xBB05, 0xBB03, 0xBB43, 0xAAD9, 0xBB42, 0xBB00, 0xBBAF, 0xAAD9, 0xBB64, 0xBB27, 0xBBEC, 0xAAD9, 0xBB16, 0xBB3B, 0xBB88 } }, + { "MR_DbgVctWr2Ext.2", 0, 34, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB03, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB08, 0xAAE7, 0x002F, 0xAAEE, 0xBB06, 0xBB0E, 0xAAE7, 0x0005, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x0012, 0xBB01 } }, + { "HVProgEntryVpp1st", 0, 22, { 0xAAFA, 0xAAF7, 0xAAFE, 0xAAFD, 0xAAF9, 0xAAF5, 0xAAF3, 0xBB00, 0xAAE8, 0x0014, 0xAAF6, 0xAAFB, 0xAAFC, 0xAAFF, 0xAAE7, 0x007F, 0xAAF7, 0xAAFA, 0xAAFB, 0xAAF6, 0xAAE8, 0x0013 } }, + { "DoNothing", 0, 1, { 0xAAE3 } }, + { "HCS_Write12", 0, 33, { 0xAAF5, 0xAAEA, 0x0064, 0xAAF3, 0xBB00, 0xAAE8, 0x000A, 0xAAF3, 0xBB04, 0xAAE7, 0x00BC, 0xAAF3, 0xBB0C, 0xAAE7, 0x00BC, 0xAAF3, 0xBB04, 0xAAE7, 0xBB03, 0xAAF3, 0xBB00, 0xAAE7, 0x00BC, 0xAAD0, 0xBB08, 0xAAD0, 0xBB08, 0xAAE8, 0x000A, 0xAAE9, 0xBB06, 0x000B, 0xAAF4 } }, + { "HCS_Verify12", 0, 11, { 0xAAF5, 0xAAEA, 0x0064, 0xAAD6, 0xAAD6, 0xAAE9, 0xBB02, 0x000B, 0xAAF4, 0xAAF3, 0xBB03 } }, + { "HCS_Write18", 0, 33, { 0xAAF5, 0xAAEA, 0x0064, 0xAAF3, 0xBB00, 0xAAE8, 0x000A, 0xAAF3, 0xBB04, 0xAAE7, 0x00BC, 0xAAF3, 0xBB0C, 0xAAE7, 0x00BC, 0xAAF3, 0xBB04, 0xAAE7, 0xBB03, 0xAAF3, 0xBB00, 0xAAE7, 0x00BC, 0xAAD0, 0xBB08, 0xAAD0, 0xBB08, 0xAAE8, 0x000A, 0xAAE9, 0xBB06, 0x0011, 0xAAF4 } }, + { "HCS_Verify18", 0, 11, { 0xAAF5, 0xAAEA, 0x0064, 0xAAD6, 0xAAD6, 0xAAE9, 0xBB02, 0x0011, 0xAAF4, 0xAAF3, 0xBB03 } }, + { "HCS_Write360-361", 0, 34, { 0xAAEA, 0x0064, 0xAAD0, 0xBB07, 0xAAD0, 0xBB08, 0xAAD0, 0xBB08, 0xAAD0, 0xBB08, 0xAAF3, 0xBB06, 0xAAE8, 0x000A, 0xAAF3, 0xBB00, 0xAAD0, 0xBB08, 0xAAD0, 0xBB08, 0xAAD0, 0xBB08, 0xAAD0, 0xBB08, 0xAAF3, 0xBB06, 0xAAE8, 0xBB10, 0xAAF3, 0xBB00, 0xAAE9, 0x000E, 0x000A, 0xAAF4 } }, + { "HCS_VPPSetup", 0, 25, { 0xAADB, 0xAADB, 0xAADB, 0xAAF5, 0xAAFA, 0xAAF7, 0xAAF9, 0xAAF3, 0xBB00, 0xAAE8, 0x0014, 0xAAEA, 0x0064, 0xAAF3, 0xBB00, 0xAAE8, 0x000A, 0xAAF3, 0xBB04, 0xAAE7, 0x00B2, 0xAAF3, 0xBB0C, 0xAAE8, 0xBB01 } }, + { "HCS_Verify360-361", 0, 14, { 0xAAF5, 0xAAEA, 0x0064, 0xAAD6, 0xAAD6, 0xAAE9, 0xBB02, 0x000B, 0xAAF3, 0xBB03, 0xAAFA, 0xAAF7, 0xAAF8, 0xAAF4 } }, + { "EE24_ProgEntry", 0, 7, { 0xAAF5, 0xAAF3, 0xBB06, 0xAACF, 0xBB01, 0xAAE8, 0xBB02 } }, + { "EE24_ProgExit", 0, 7, { 0xAAF4, 0xAAF3, 0xBB03, 0xAACF, 0xBB01, 0xAAE8, 0xBB02 } }, + { "EE24_RdPrep1Adr", 0, 4, { 0xAACD, 0xAACA, 0xAADB, 0xAACA } }, + { "EE24_Rd64", 0, 16, { 0xAACD, 0xAACA, 0xAADB, 0xAADB, 0xAAC9, 0xAAC9, 0xAAC9, 0xAAC9, 0xAAE9, 0xBB04, 0x000E, 0xAAC9, 0xAAC9, 0xAAC9, 0xAAC8, 0xAACC } }, + { "EE24_Wr8Adr1.5ms", 0, 15, { 0xAACD, 0xAACA, 0xAADB, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACC, 0xAAE7, 0x00EB } }, + { "EE24_RdPrep2Adr", 0, 4, { 0xAACD, 0xAACA, 0xAACA, 0xAACA } }, + { "EE24_Wr32Adr2.5ms", 0, 18, { 0xAACD, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAAE9, 0xBB08, 0xBB03, 0xAACC, 0xAAE7, 0x00EB } }, + { "EE24_Wr1Adr1.5ms", 0, 8, { 0xAACD, 0xAACA, 0xAADB, 0xAACA, 0xAACA, 0xAACC, 0xAAE7, 0x00EB } }, + { "EE24_Rd16", 0, 16, { 0xAACD, 0xAACA, 0xAADB, 0xAADB, 0xAAC9, 0xAAC9, 0xAAC9, 0xAAC9, 0xAAE9, 0xBB04, 0x0002, 0xAAC9, 0xAAC9, 0xAAC9, 0xAAC8, 0xAACC } }, + { "EE24_Wr16Adr1.5ms", 0, 18, { 0xAACD, 0xAACA, 0xAADB, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAAE9, 0xBB08, 0xBB01, 0xAACC, 0xAAE7, 0x00EB } }, + { "EE25_ProgEntry", 0, 32, { 0xAAFA, 0xAAF7, 0xAAF9, 0xAAF5, 0xAAF3, 0xBB02, 0xAACF, 0xBB00, 0xAAE8, 0x0014, 0xAAF6, 0xAAFB, 0xAAE8, 0x000A, 0xAAFA, 0xAAF7, 0xAAC7, 0xBB06, 0xAAFC, 0xAAFB, 0xAAE7, 0xBB01, 0xAAFA, 0xAAF7, 0xAAC7, 0xBB01, 0xAAC7, 0xBB00, 0xAAF6, 0xAAFB, 0xAAE7, 0x00EB } }, + { "EE25_ProgExit", 4, 10, { 0xAAFA, 0xAAF7, 0xAAF8, 0xAAF3, 0xBB03, 0xAACF, 0xBB01, 0xAAE8, 0x000A, 0xAAF4 } }, + { "EE25_Rd64Adr1", 0, 18, { 0xAAFA, 0xAAF7, 0xAAC6, 0xAADB, 0xAAC6, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAE9, 0xBB08, 0xBB07, 0xAAF6, 0xAAFB } }, + { "EE25_Wr16Adr1.5ms", 0, 24, { 0xAAFA, 0xAAF7, 0xAAC7, 0xBB06, 0xAAF6, 0xAAFB, 0xAAE7, 0xBB01, 0xAAFA, 0xAAF7, 0xAAC6, 0xAADB, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAE9, 0xBB04, 0xBB03, 0xAAF6, 0xAAFB, 0xAAE7, 0x00EB } }, + { "EE25_Wr16Adr2.5ms", 0, 24, { 0xAAFA, 0xAAF7, 0xAAC7, 0xBB06, 0xAAF6, 0xAAFB, 0xAAE7, 0xBB01, 0xAAFA, 0xAAF7, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAE9, 0xBB04, 0xBB03, 0xAAF6, 0xAAFB, 0xAAE7, 0x00EB } }, + { "EE25_Rd64Adr2", 0, 18, { 0xAAFA, 0xAAF7, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAE9, 0xBB08, 0xBB07, 0xAAF6, 0xAAFB } }, + { "EE93_ProgEntry", 0, 10, { 0xAAFA, 0xAAF7, 0xAAF9, 0xAAF5, 0xAAF3, 0xBB02, 0xAACF, 0xBB00, 0xAAE8, 0x0014 } }, + { "EE93_Rd8Adr2.8", 0, 11, { 0xAAF6, 0xAAFB, 0xAADB, 0xAAC6, 0xAAC6, 0xAAC5, 0xAAE9, 0xBB01, 0x0007, 0xAAFA, 0xAAF7 } }, + { "EE93_PrgMemWrPrep", 0, 8, { 0xAAF6, 0xAAFB, 0xAAC7, 0xBB26, 0xAAC7, 0xBB00, 0xAAFA, 0xAAF7 } }, + { "EE93_PrgMemWr1A2.8", 0, 12, { 0xAAF6, 0xAAFB, 0xAADB, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAFA, 0xAAF7, 0xAAE8, 0xBB01, 0xAAE7, 0x001A } }, + { "EE93_ChpErase", 0, 20, { 0xAAF6, 0xAAFB, 0xAAC7, 0xBB26, 0xAAC7, 0xBB00, 0xAAFA, 0xAAF7, 0xAAE7, 0xBB05, 0xAAF6, 0xAAFB, 0xAAC7, 0xBB24, 0xAAC7, 0xBB00, 0xAAFA, 0xAAF7, 0xAAE8, 0xBB02 } }, + { "EE93_Rd1Adr2.16", 0, 9, { 0xAAF6, 0xAAFB, 0xAADB, 0xAAC6, 0xAAC6, 0xAAC5, 0xAAC5, 0xAAFA, 0xAAF7 } }, + { "EE93_PrgMemWr1A2.16", 0, 13, { 0xAAF6, 0xAAFB, 0xAADB, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAFA, 0xAAF7, 0xAAE8, 0xBB01, 0xAAE7, 0x0031 } }, + { "EE24_Wr64Adr2.5ms", 0, 18, { 0xAACD, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAAE9, 0xBB08, 0xBB07, 0xAACC, 0xAAE7, 0x00EB } }, + { "EE24_Wr128Adr2.5ms", 0, 18, { 0xAACD, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAACA, 0xAAE9, 0xBB08, 0x000F, 0xAACC, 0xAAE7, 0x00EB } }, + { "EE25_Wr32Adr2.5ms", 0, 24, { 0xAAFA, 0xAAF7, 0xAAC7, 0xBB06, 0xAAF6, 0xAAFB, 0xAAE7, 0xBB01, 0xAAFA, 0xAAF7, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAE9, 0xBB04, 0xBB07, 0xAAF6, 0xAAFB, 0xAAE7, 0x00EB } }, + { "EE25_Wr64Adr2.5ms", 0, 24, { 0xAAFA, 0xAAF7, 0xAAC7, 0xBB06, 0xAAF6, 0xAAFB, 0xAAE7, 0xBB01, 0xAAFA, 0xAAF7, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAE9, 0xBB04, 0x000F, 0xAAF6, 0xAAFB, 0xAAE7, 0x00EB } }, + { "EE25_Wr128Adr3.5ms", 0, 26, { 0xAAFA, 0xAAF7, 0xAAC7, 0xBB06, 0xAAF6, 0xAAFB, 0xAAE7, 0xBB01, 0xAAFA, 0xAAF7, 0xAAC7, 0xBB02, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAE9, 0xBB04, 0x001F, 0xAAF6, 0xAAFB, 0xAAE7, 0x00EB } }, + { "EE25_Rd64Adr3", 0, 20, { 0xAAFA, 0xAAF7, 0xAAC7, 0xBB03, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAC5, 0xAAE9, 0xBB08, 0x0007, 0xAAF6, 0xAAFB } }, + { "MR_DbgVctWr2Int.3", 0, 29, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB03, 0xAAEE, 0xBB06, 0x0002, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x00BC, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x000D, 0xBB01 } }, + { "MR_DbgVctWr2Ext.4", 0, 34, { 0xAAEE, 0xBB06, 0xBB00, 0xAAF2, 0xBB00, 0xAAF2, 0xBB00, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0xBB03, 0xBB03, 0xAAEE, 0xBB06, 0xBB02, 0xAAF1, 0xAAF1, 0xAAEE, 0xBB06, 0xBB18, 0xAAE7, 0x0076, 0xAAEE, 0xBB06, 0xBB0E, 0xAAE7, 0x0005, 0xAAEE, 0xBB06, 0xBB06, 0xAAE9, 0x0012, 0xBB01 } }, + { "DBG_Halt.BL", 1, 8, { 0xAAF3, 0xBB06, 0xAAE7, 0x002F, 0xAAF3, 0xBB02, 0xAAE7, 0x0005 } }, + { "DBG_Run.BL", 0, 10, { 0xAAF5, 0xAAC1, 0xBB19, 0xAAC2, 0xAAF4, 0xAAE6, 0xBB00, 0xBB04, 0xAAE3, 0xAAC2 } }, + { "DBG_RdDEVer.BL", 0, 11, { 0xAAF5, 0xAAC1, 0xBB02, 0xAAC2, 0xAAE6, 0xBB00, 0xBB05, 0xAAC2, 0xAAC2, 0xAAC2, 0xAAF4 } }, + { "DBG_SStep.BL", 0, 10, { 0xAAF5, 0xAAC1, 0xBB1A, 0xAAC2, 0xAAF4, 0xAAE6, 0xBB00, 0xBB04, 0xAAE3, 0xAAC2 } }, + { "DBG_BulkWrData.BL", 0, 18, { 0xAAF5, 0xAAC1, 0xBB04, 0xAAC2, 0xAAE6, 0xBB00, 0x000C, 0xAAC0, 0xAAC0, 0xAAC0, 0xAAC0, 0xAAC0, 0xAADD, 0xBB01, 0xAAF4, 0xAAE3, 0xAAC2, 0xAAF4 } }, + { "DBG_BulkRdData.BL", 0, 18, { 0xAAF5, 0xAAC1, 0xBB03, 0xAAC2, 0xAAE6, 0xBB00, 0x000C, 0xAAC0, 0xAAC0, 0xAAC0, 0xAAC0, 0xAAC2, 0xAADD, 0xBB01, 0xAAF4, 0xAAE3, 0xAAC2, 0xAAF4 } }, + { "EE25_Wr128Adr2.5ms", 0, 24, { 0xAAFA, 0xAAF7, 0xAAC7, 0xBB06, 0xAAF6, 0xAAFB, 0xAAE7, 0xBB01, 0xAAFA, 0xAAF7, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAC6, 0xAAE9, 0xBB04, 0x001F, 0xAAF6, 0xAAFB, 0xAAE7, 0x00EB } }, + { "HVProgEntryVppClose", 0, 22, { 0xAAFA, 0xAAF7, 0xAAFE, 0xAAFD, 0xAAF9, 0xAAF5, 0xAAF3, 0xBB00, 0xAAE8, 0x003C, 0xAAFC, 0xAAFF, 0xAAF6, 0xAAFB, 0xAAE7, 0x007F, 0xAAF7, 0xAAFA, 0xAAFB, 0xAAF6, 0xAAE8, 0x0013 } }, + { 0, 0, 0, {} } +}; +} // namespace diff --git a/src/progs/pickit2v2/base/pickit2v2_data.h b/src/progs/pickit2v2/base/pickit2v2_data.h new file mode 100644 index 0000000..272fe92 --- /dev/null +++ b/src/progs/pickit2v2/base/pickit2v2_data.h @@ -0,0 +1,103 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PICKIT2V2_DATA_H +#define PICKIT2V2_DATA_H + +#include + +namespace Pickit2V2 +{ + +enum ScriptType { + ProgEntry = 0x00, ProgExit = 0x01, DeviceIdRead = 0x02, ProgMemoryRead = 0x03, + EraseChipPrepare = 0x04, ProgMemoryAddressSet = 0x05, ProgMemoryWritePrepare = 0x06, + ProgMemoryWrite = 0x07, EepromReadPrepare = 0x08, EepromRead = 0x09, EepromWritePrepare = 0x0A, + EepromWrite = 0x0B, ConfigReadPrepare = 0x0C, ConfigRead = 0x0D, ConfigWritePrepare = 0x0E, + ConfigWrite = 0x0F, UserIdReadPrepare = 0x10, UserIdRead = 0x11, UserIdWritePrepare = 0x12, + UserIdWrite = 0x13, OsccalRead = 0x14, OsccalWrite = 0x15, ChipErase = 0x16, + ProgMemoryErase = 0x17, EepromErase = 0x18, ConfigErase = 0x19, + RowErase = 0x1A, TestMemoryRead = 0x1B, EEpromRowErase = 0x1C, + Nb_ScriptTypes = 0x1D +}; + +inline ScriptType prepareReadScript(Pic::MemoryRangeType type) +{ + switch (type.type()) { + case Pic::MemoryRangeType::Code: return ProgMemoryAddressSet; + case Pic::MemoryRangeType::Eeprom: return EepromReadPrepare; + case Pic::MemoryRangeType::Config: return ConfigReadPrepare; + case Pic::MemoryRangeType::UserId: return UserIdReadPrepare; + default: break; + } + return Nb_ScriptTypes; +} + +inline ScriptType readScript(Pic::MemoryRangeType type) +{ + switch (type.type()) { + case Pic::MemoryRangeType::Code: return ProgMemoryRead; + case Pic::MemoryRangeType::Eeprom: return EepromRead; + case Pic::MemoryRangeType::Config: return ConfigRead; + case Pic::MemoryRangeType::UserId: return UserIdRead; + case Pic::MemoryRangeType::Cal: return OsccalRead; + default: break; + } + return Nb_ScriptTypes; +} + +inline ScriptType prepareWriteScript(Pic::MemoryRangeType type) +{ + switch (type.type()) { + case Pic::MemoryRangeType::Code: return ProgMemoryWritePrepare; + case Pic::MemoryRangeType::Eeprom: return EepromWritePrepare; + case Pic::MemoryRangeType::Config: return ConfigWritePrepare; + case Pic::MemoryRangeType::UserId: return UserIdWritePrepare; + default: break; + } + return Nb_ScriptTypes; +} + +inline ScriptType writeScript(Pic::MemoryRangeType type) +{ + switch (type.type()) { + case Pic::MemoryRangeType::Code: return ProgMemoryWrite; + case Pic::MemoryRangeType::Eeprom: return EepromWrite; + case Pic::MemoryRangeType::Config: return ConfigWrite; + case Pic::MemoryRangeType::UserId: return UserIdWrite; + case Pic::MemoryRangeType::Cal: return OsccalWrite; + default: break; + } + return Nb_ScriptTypes; +} + +struct Data { + uchar codeMemoryNbReadWords, eepromMemoryNbReadWords; + uchar codeMemoryNbWriteWords, eepromMemoryNbWriteWords; + uchar scriptIndexes[Nb_ScriptTypes]; +}; +extern const Data &data(const QString &device); + +struct FamilyData { + Pic::Architecture architecture; + double vpp; + ushort progEntryScript, progExitScript, readDevIdScript; + bool progMemShift; +}; +extern const FamilyData FAMILY_DATA[]; + +struct ScriptData { + const char *name; + ushort version, length; + const ushort data[64]; +}; +extern const ScriptData SCRIPT_DATA[]; + +} // namespace + +#endif diff --git a/src/progs/pickit2v2/base/pickit2v2_prog.cpp b/src/progs/pickit2v2/base/pickit2v2_prog.cpp new file mode 100644 index 0000000..3a44bca --- /dev/null +++ b/src/progs/pickit2v2/base/pickit2v2_prog.cpp @@ -0,0 +1,117 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "pickit2v2_prog.h" + +#include "devices/list/device_list.h" +#include "progs/base/prog_config.h" +#include "pickit2v2.h" + +//---------------------------------------------------------------------------- +Pickit2V2::Base::Base(const Programmer::Group &group, const Pic::Data *data) + : Pickit2::Base(group, data) +{} + +VersionData Pickit2V2::Base::firmwareVersion(Programmer::FirmwareVersionType type) const +{ + switch (type.type()) { + case Programmer::FirmwareVersionType::Min: return VersionData(2, 10, 0); + case Programmer::FirmwareVersionType::Recommended: return VersionData(2, 10, 0); + case Programmer::FirmwareVersionType::Max: return VersionData(2, 10, 0); + case Programmer::FirmwareVersionType::Nb_Types: break; + } + Q_ASSERT(false); + return VersionData(); +} + +Pickit2V2::Hardware &Pickit2V2::Base::hardware() +{ + return static_cast(*_hardware); +} + +bool Pickit2V2::Base::identifyDevice() +{ + double vdd = 3.3; // set 3.3V to check for fragile devices + if ( !_targetSelfPowered ) { + if ( !hardware().setVddVoltage(vdd, 0.85)) return false; + } + QString message = i18n("Unknown device"); + for (uint i=0; FAMILY_DATA[i].architecture!=Pic::Architecture::Nb_Types; i++) { + const FamilyData &fdata = FAMILY_DATA[i]; + if ( fdata.readDevIdScript==0 ) { + if ( device()->architecture()==fdata.architecture ) return true; // not autodetectable + continue; + } + hardware().setVddOn(false); + if ( fdata.vpp==0.0 ) hardware().setVppVoltage(vdd, 0.7); + else hardware().setVppVoltage(fdata.vpp, 0.7); + hardware().setVddOn(true); + if ( !hardware().executeScript(fdata.progEntryScript) ) return false; + if ( !hardware().executeScript(fdata.readDevIdScript) ) return false; + if ( !hardware().port().command(UploadData) ) return false; + Array data; + if ( !hardware().port().receive(data) ) return false; + if ( !hardware().executeScript(fdata.progExitScript) ) return false; + uint rawId = (data[2]<<8) + data[1]; + if (fdata.progMemShift) rawId >>= 1; + log(Log::DebugLevel::Normal, QString("Read id for family %1: %2").arg(fdata.architecture.key()).arg(toHexLabelAbs(rawId))); + QMap ids; + ::Group::Base::ConstIterator it; + for (it=group().begin(); it!=group().end(); ++it) { + const Pic::Data *data = static_cast(it.data().data); + if ( data->architecture()!=fdata.architecture ) continue; + Device::IdData idata; + if ( data->matchId(rawId, idata) ) ids[it.key()] = idata; + } + if ( ids.count()!=0 ) { + log(Log::LineType::Information, i18n("Read id: %1").arg(device()->idNames(ids).join("; "))); + if ( ids.contains(device()->name()) ) return true; + message = i18n("Read id does not match the specified device name \"%1\".").arg(device()->name()); + break; + } + } + if ( !askContinue(message) ) { + logUserAbort(); + return false; + } + log(Log::LineType::Information, i18n("Continue with the specified device name: \"%1\"...").arg(device()->name())); + return true; +} + +bool Pickit2V2::Base::setTarget() +{ + if ( !identifyDevice() ) return false; + return hardware().setTarget(); +} + +bool Pickit2V2::Base::selfTest(bool ask) +{ + ushort status; + if ( !hardware().readStatus(status) ) return false; + QString error; + if ( status & VppError ) error += i18n("Vpp voltage level error; "); + if ( status & VddError ) error += i18n("Vdd voltage level error; "); + if ( error.isEmpty() ) return true; + log(Log::LineType::Warning, i18n("Self-test failed: %1").arg(error)); + if ( ask && !askContinue(i18n("Self-test failed (%1). Do you want to continue anyway?").arg(error)) ) { + logUserAbort(); + return false; + } + return true; +} + +//---------------------------------------------------------------------------- +Programmer::Hardware *Pickit2V2::Group::createHardware(Programmer::Base &base, const Programmer::HardwareDescription &) const +{ + return new Hardware(base); +} + +Programmer::DeviceSpecific *Pickit2V2::Group::createDeviceSpecific(Programmer::Base &base) const +{ + return new DeviceSpecific(base); +} diff --git a/src/progs/pickit2v2/base/pickit2v2_prog.h b/src/progs/pickit2v2/base/pickit2v2_prog.h new file mode 100644 index 0000000..3653649 --- /dev/null +++ b/src/progs/pickit2v2/base/pickit2v2_prog.h @@ -0,0 +1,54 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PICKIT2V2_PROG_H +#define PICKIT2V2_PROG_H + +#include "progs/pickit2/base/pickit2_prog.h" + +namespace Pickit2V2 +{ +class Hardware; + +//---------------------------------------------------------------------------- +class Base : public Pickit2::Base +{ +Q_OBJECT +public: + Base(const Programmer::Group &group, const Pic::Data *data); + virtual bool setTarget(); + +private: + Hardware &hardware(); + virtual VersionData firmwareVersion(Programmer::FirmwareVersionType type) const; + virtual bool verifyDeviceId() { return true; } // it is done by "setTarget" + virtual bool selfTest(bool ask); + bool identifyDevice(); +}; + +//---------------------------------------------------------------------------- +class Group : public Programmer::PicGroup +{ +public: + virtual QString name() const { return "pickit2v2"; } + virtual QString label() const { return i18n("PICkit2 Firmware 2.x"); } + virtual Programmer::Properties properties() const { return ::Programmer::Programmer | ::Programmer::HasFirmware | ::Programmer::CanUploadFirmware | ::Programmer::CanReadMemory | ::Programmer::HasConnectedState; } + virtual bool canReadVoltage(Pic::VoltageType type) const { return ( type==Pic::TargetVdd || type==Pic::TargetVpp ); } + virtual ::Programmer::TargetPowerMode targetPowerMode() const { return ::Programmer::TargetPowerModeFromConfig; } + virtual bool isPortSupported(PortType type) const { return ( type==PortType::USB ); } + +protected: + virtual void initSupported(); + virtual Programmer::Base *createBase(const Device::Data *data) const { return new ::Pickit2V2::Base(*this, static_cast(data)); } + virtual Programmer::Hardware *createHardware(Programmer::Base &base, const Programmer::HardwareDescription &hd) const; + virtual Programmer::DeviceSpecific *createDeviceSpecific(Programmer::Base &base) const; +}; + +} // namespace + +#endif diff --git a/src/progs/pickit2v2/gui/Makefile.am b/src/progs/pickit2v2/gui/Makefile.am new file mode 100644 index 0000000..dae6832 --- /dev/null +++ b/src/progs/pickit2v2/gui/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libpickit2v2ui.la +libpickit2v2ui_la_SOURCES = pickit2v2_group_ui.cpp +libpickit2v2ui_la_LDFLAGS = $(all_libraries) \ No newline at end of file diff --git a/src/progs/pickit2v2/gui/pickit2v2_group_ui.cpp b/src/progs/pickit2v2/gui/pickit2v2_group_ui.cpp new file mode 100644 index 0000000..b3596fd --- /dev/null +++ b/src/progs/pickit2v2/gui/pickit2v2_group_ui.cpp @@ -0,0 +1,22 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "pickit2v2_group_ui.h" + +#include "progs/gui/prog_config_widget.h" +#include "progs/pickit2v2/base/pickit2v2_prog.h" + +::Programmer::ConfigWidget *Pickit2V2::GroupUI::createConfigWidget(QWidget *parent) const +{ + return new ::Programmer::ConfigWidget(static_cast(group()), parent); +} + +::Programmer::AdvancedDialog *Pickit2V2::GroupUI::createAdvancedDialog(::Programmer::Base &base, QWidget *parent) const +{ + return new ::Programmer::AdvancedDialog(static_cast(base), parent, "pickit2v2_advanced_dialog"); +} diff --git a/src/progs/pickit2v2/gui/pickit2v2_group_ui.h b/src/progs/pickit2v2/gui/pickit2v2_group_ui.h new file mode 100644 index 0000000..6c5ff64 --- /dev/null +++ b/src/progs/pickit2v2/gui/pickit2v2_group_ui.h @@ -0,0 +1,25 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PICKIT2V2_GROUP_UI_H +#define PICKIT2V2_GROUP_UI_H + +#include "devices/pic/gui/pic_prog_group_ui.h" + +namespace Pickit2V2 +{ +class GroupUI : public ::Programmer::GroupUI +{ +public: + virtual ::Programmer::ConfigWidget *createConfigWidget(QWidget *parent) const; + virtual bool hasAdvancedDialog() const { return true; } + virtual ::Programmer::AdvancedDialog *createAdvancedDialog(::Programmer::Base &base, QWidget *parent) const; +}; +} // namespace + +#endif diff --git a/src/progs/pickit2v2/pickit2v2.pro b/src/progs/pickit2v2/pickit2v2.pro new file mode 100644 index 0000000..fe430fe --- /dev/null +++ b/src/progs/pickit2v2/pickit2v2.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = base diff --git a/src/progs/progs.pro b/src/progs/progs.pro new file mode 100644 index 0000000..3b9a442 --- /dev/null +++ b/src/progs/progs.pro @@ -0,0 +1,3 @@ +TEMPLATE = subdirs +SUBDIRS = base list direct icd2 icd1 pickit2 pickit1 psp gpsim pickit2v2 \ + bootloader tbl_bootloader pickit2_bootloader picdem_bootloader manager diff --git a/src/progs/psp/Makefile.am b/src/progs/psp/Makefile.am new file mode 100644 index 0000000..fccf96d --- /dev/null +++ b/src/progs/psp/Makefile.am @@ -0,0 +1,3 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +SUBDIRS = xml base gui diff --git a/src/progs/psp/base/Makefile.am b/src/progs/psp/base/Makefile.am new file mode 100644 index 0000000..93ce348 --- /dev/null +++ b/src/progs/psp/base/Makefile.am @@ -0,0 +1,11 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libpsp.la +libpsp_la_SOURCES = psp_prog.cpp psp_serial.cpp psp_data.cpp psp.cpp +libpsp_la_DEPENDENCIES = psp_data.cpp + +noinst_DATA = psp.xml +psp_data.cpp: ../xml/xml_psp_parser psp.xml + ../xml/xml_psp_parser +CLEANFILES = psp_data.cpp diff --git a/src/progs/psp/base/base.pro b/src/progs/psp/base/base.pro new file mode 100644 index 0000000..4dca18d --- /dev/null +++ b/src/progs/psp/base/base.pro @@ -0,0 +1,6 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/lib.pro) + +TARGET = psp +HEADERS += psp.h psp_prog.h psp_data.h psp_serial.h +SOURCES += psp.cpp psp_prog.cpp psp_data.cpp psp_serial.cpp diff --git a/src/progs/psp/base/psp.cpp b/src/progs/psp/base/psp.cpp new file mode 100644 index 0000000..1b76bf5 --- /dev/null +++ b/src/progs/psp/base/psp.cpp @@ -0,0 +1,346 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * Copyright (C) 2002-2003 Stephen Landamore * + * * + * 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. * + ***************************************************************************/ +#include "psp.h" + +#include "common/global/global.h" +#include "common/common/misc.h" + +//----------------------------------------------------------------------------- +QMemArray Psp::createConfigInfo(const Pic::Data &data) +{ + QMemArray array(33); + array.fill(0x00); + + const Pic::Config &config = data.config(); + for (uint i=0; i Psp::createDeviceInfo(const Pic::Data &data) +{ + QMemArray config = createConfigInfo(data); + QMemArray array(45); + array.fill(0x00); + + // memory code length + BitValue v = data.nbWords(Pic::MemoryRangeType::Code); + array[0] = v.byte(1); + array[1] = v.byte(0); + // address word width + v = data.mask(Pic::MemoryRangeType::Code); + array[2] = v.byte(1); + array[3] = v.byte(0); + // data word width + array[4] = v.byte(1); + array[5] = v.byte(0); + + if ( data.isReadable(Pic::MemoryRangeType::UserId) ) { + // user id width + v = data.userIdRecommendedMask(); + if ( data.nbBytesWord(Pic::MemoryRangeType::UserId)==1 ) v += v << 8; + array[6] = v.byte(1); + array[7] = v.byte(0); + // user id mask + array[8] = v.byte(1); + array[9] = v.byte(0); + } + + // memory config mask + array[10] = config[0]; + array[11] = config[1]; + array[12] = config[16]; + array[13] = config[17]; + + if ( data.isReadable(Pic::MemoryRangeType::Eeprom) ) { + // memory eeprom width + v = data.mask(Pic::MemoryRangeType::Eeprom); + array[14] = v.byte(1); + array[15] = v.byte(0); + // memory eeprom mask + array[16] = v.byte(1); + array[17] = v.byte(0); + } + + if ( data.isReadable(Pic::MemoryRangeType::Cal) ) { + // memory calibration width + v = data.mask(Pic::MemoryRangeType::Cal); + array[18] = v.byte(1); + array[19] = v.byte(0); + // memory calibration mask + array[20] = v.byte(1); + array[21] = v.byte(0); + } + + // memory code start + array[22] = 0x00; + array[23] = 0x00; + // memory code length + array[24] = 0x00; // array[0]; in lplab and for some devices in picp... + array[25] = 0x01; // array[1]; in lplab and for some devices in picp... + + if ( data.isReadable(Pic::MemoryRangeType::UserId) ) { + // user id start + v = data.range(Pic::MemoryRangeType::UserId).start.toUInt(); + array[26] = v.byte(1); + array[27] = v.byte(0); + // user id length + v = data.nbWords(Pic::MemoryRangeType::UserId); + if ( data.nbBytesWord(Pic::MemoryRangeType::UserId)==1 ) v >>= 1; + array[28] = v.byte(0); + } + + if ( data.isReadable(Pic::MemoryRangeType::Config) ) { + // config start + v = data.range(Pic::MemoryRangeType::Config).start.toUInt(); + array[29] = v.byte(1); + array[30] = v.byte(0); + // config length + v = data.nbWords(Pic::MemoryRangeType::Config); + if ( data.nbBytesWord(Pic::MemoryRangeType::Config)==1 ) v >>= 1; + array[31] = v.byte(0); + } + + if ( data.isReadable(Pic::MemoryRangeType::Config) ) { + // eeprom start + array[32] = 0x00; + array[33] = 0x00; + // eeprom length + v = data.nbWords(Pic::MemoryRangeType::Eeprom); + array[34] = v.byte(1); + array[35] = v.byte(0); + } + + if ( data.isReadable(Pic::MemoryRangeType::Cal) ) { + // calibration start + v = data.range(Pic::MemoryRangeType::Cal).start.toUInt(); + array[36] = v.byte(1); + array[37] = v.byte(0); + // calibration length + v = data.nbWords(Pic::MemoryRangeType::Cal); + array[38] = v.byte(1); + array[39] = v.byte(0); + } + + // programming + const Psp::Data &pdata = Psp::data(data.name()); + array[40] = pdata.overprogram; + array[41] = pdata.tries; + array[42] = pdata.algorithm; + if ( data.memoryTechnology()==Device::MemoryTechnology::Flash ) array[43] |= 0x01; + if ( data.isReadable(Pic::MemoryRangeType::UserId) ) array[43] |= 0x02; + if ( data.isReadable(Pic::MemoryRangeType::Config) ) array[43] |= 0x04; + if ( data.isReadable(Pic::MemoryRangeType::Eeprom) ) array[43] |= 0x08; + if ( data.isReadable(Pic::MemoryRangeType::Cal) ) array[43] |= 0x10; + if ( data.config().findMask("PARITY") ) array[43] |= 0x20; + + // checksum + for (uint i=0; i<44; i++) array[44] += array[i]; + + return array; +} + +//----------------------------------------------------------------------------- +Psp::Hardware::Hardware(::Programmer::Base &base, const QString &portDevice) + : Programmer::PicHardware(base, new SerialPort(portDevice, base), QString::null) +{} + +bool Psp::Hardware::internalConnectHardware() +{ + if ( !port()->open() ) return false; + if ( !port()->reset() ) return false; + // #### TODO: detect Warp13 or JuPic + QMemArray a; + if ( !port()->command(0x88, 1, a) ) return false; + if ( a[0]!=0xAB ) { + log(Log::LineType::Error, i18n("Wrong programmer connected")); + return false; + } + return true; +} + +bool Psp::Hardware::getFirmwareVersion(VersionData &version) +{ + QMemArray a1; + if ( !port()->commandAck(0x8D, 2, &a1) ) return false; + if ( a1[1]==0xFF ) { + log(Log::LineType::Warning, i18n("Invalid firmware version")); + version = VersionData(0xFF, 0, 0); + } else { + QMemArray a2; + if ( !port()->receive(2, a2) ) return false; + version = VersionData(a1[1], a2[0], a2[1]); + } + return true; +} + +bool Psp::Hardware::setTarget() +{ + log(Log::DebugLevel::Max, "set target"); + // load device info + if ( !port()->commandAck(0x81) ) return false; + QMemArray a = createDeviceInfo(device()); + if ( !port()->send(a) ) return false; + if ( !port()->receiveEnd() ) return false; + + // load config info + if ( !port()->commandAck(0x82) ) return false; + a = createConfigInfo(device()); + if ( !port()->send(a) ) return false; + if ( !port()->receiveEnd() ) return false; + + return true; +} + +bool Psp::Hardware::setRange(uint start, uint size) +{ + QMemArray a(6); + a[0] = 0x8E; + a[1] = start >> 16; + a[2] = (start >> 8) & 0xFF; + a[3] = start & 0xFF; + a[4] = size >> 8; + a[5] = size & 0xFF; + if ( !port()->send(a) ) return false; + QMemArray r; + if ( !port()->receive(6, r) ) return false; + for (uint i=0; i<6; i++) { + if ( r[i]!=a[i] ) { + log(Log::LineType::Error, i18n("Failed to set range")); + return false; + } + } + return true; +} + +char Psp::Hardware::readCommand(Pic::MemoryRangeType type) +{ + switch (type.type()) { + case Pic::MemoryRangeType::Code: return 'T'; + case Pic::MemoryRangeType::Eeprom: return 'd'; + case Pic::MemoryRangeType::Config: return 'f'; + case Pic::MemoryRangeType::UserId: return 'e'; + case Pic::MemoryRangeType::Cal: return 'c'; + case Pic::MemoryRangeType::DeviceId: + case Pic::MemoryRangeType::CalBackup: + case Pic::MemoryRangeType::DebugVector: + case Pic::MemoryRangeType::ProgramExecutive: + case Pic::MemoryRangeType::HardwareStack: + case Pic::MemoryRangeType::Nb_Types: break; + } + return 0; +} + +char Psp::Hardware::writeCommand(Pic::MemoryRangeType type) +{ + switch (type.type()) { + case Pic::MemoryRangeType::Code: return 'Q'; + case Pic::MemoryRangeType::Eeprom: return 'i'; + case Pic::MemoryRangeType::Config: return 'g'; + case Pic::MemoryRangeType::UserId: return 'h'; + case Pic::MemoryRangeType::Cal: return 'q'; + case Pic::MemoryRangeType::DeviceId: + case Pic::MemoryRangeType::CalBackup: + case Pic::MemoryRangeType::DebugVector: + case Pic::MemoryRangeType::ProgramExecutive: + case Pic::MemoryRangeType::HardwareStack: + case Pic::MemoryRangeType::Nb_Types: break; + } + return 0; +} + +bool Psp::Hardware::readMemory(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata) +{ + QMemArray a; + uint nbWords = device().nbWords(type); + data.resize(nbWords); + uint nbBytes = nbWords * device().nbBytesWord(type); + char c = readCommand(type); + switch (type.type()) { + case Pic::MemoryRangeType::Code: + if ( !setRange(0, nbWords) ) return false; + if ( !port()->commandAck(c) ) return false; + for (uint i=0; ireceive(2, a) ) return false; + data[i] = (a[0] << 8) + a[1]; +// log(Log::DebugLevel::Max, QString("code data %1: %2 (%3, %4)").arg(i).arg(toHexLabel(data[i], 4)) +// .arg(toHexLabel(a[0], 2)).arg(toHexLabel(a[1], 2))); + } + if ( !port()->receiveEnd() ) return false; + break; + case Pic::MemoryRangeType::Eeprom: + if ( !port()->commandAck(c) ) return false; + for (uint i=0; ireceive(1, a) ) return false; + data[i] = a[0]; + } + if ( !port()->receiveEnd() ) return false; + break; + case Pic::MemoryRangeType::UserId: + if ( !port()->commandAckEnd(c, nbBytes+2, a) ) return false; + for (uint i=0; icommandAckEnd(c, nbBytes+2, a) ) return false; + for (uint i=0; icommandAckEnd(c, nbBytes+2, a) ) return false; + for (uint i=0; icommandAck(writeCommand(type)) ) return false; + for (uint i=0; isendData(data[i].toUInt(), nbBytes) ) return false; + return port()->receiveEnd(); +} + +bool Psp::Hardware::eraseAll() +{ + QMemArray a; + if ( !port()->commandAck(0x8F, 2, &a) ) return false; + if ( a[1]!=0x00 ) { + log(Log::LineType::Error, i18n("Erase failed")); + return false; + } + return true; +} diff --git a/src/progs/psp/base/psp.h b/src/progs/psp/base/psp.h new file mode 100644 index 0000000..ad4a160 --- /dev/null +++ b/src/progs/psp/base/psp.h @@ -0,0 +1,63 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * Copyright (C) 2002-2003 Stephen Landamore * + * * + * 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. * + ***************************************************************************/ +#ifndef PSP_H +#define PSP_H + +#include "devices/pic/prog/pic_prog.h" +#include "psp_serial.h" +#include "psp_data.h" + +namespace Psp +{ + extern QMemArray createConfigInfo(const Pic::Data &data); + extern QMemArray createDeviceInfo(const Pic::Data &data); + +//----------------------------------------------------------------------------- +class Hardware : public Programmer::PicHardware +{ +public: + Hardware(::Programmer::Base &base, const QString &portDevice); + SerialPort *port() { return static_cast(_port); } + virtual bool uploadFirmware(const Pic::Memory &) { return false; } + virtual bool setTarget(); + virtual bool getFirmwareVersion(VersionData &version); + virtual bool readMemory(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata); + virtual bool writeMemory(Pic::MemoryRangeType type, const Device::Array &data, bool force); + virtual bool eraseAll(); + virtual bool internalConnectHardware(); + +private: + bool setRange(uint start, uint end); + static char readCommand(Pic::MemoryRangeType type); + static char writeCommand(Pic::MemoryRangeType type); +}; + +//----------------------------------------------------------------------------- +class DeviceSpecific : public ::Programmer::PicDeviceSpecific +{ +public: + DeviceSpecific(::Programmer::Base &base) : ::Programmer::PicDeviceSpecific(base) {} + virtual bool canEraseAll() const { return true; } + virtual bool canEraseRange(Pic::MemoryRangeType) const { return false; } + virtual bool canReadRange(Pic::MemoryRangeType type) const { return ( type!=Pic::MemoryRangeType::DeviceId ); } + virtual bool canWriteRange(Pic::MemoryRangeType) const { return true; } + Hardware &hardware() { return static_cast(*_base.hardware()); } + virtual bool setPowerOff() { return false; } + virtual bool setPowerOn() { return false; } + virtual bool setTargetPowerOn(bool) { return true; } + virtual bool doEraseRange(Pic::MemoryRangeType) { return false; } + virtual bool doErase(bool) { return hardware().eraseAll(); } + virtual bool doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata) { return hardware().readMemory(type, data, vdata); } + virtual bool doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force) { return hardware().writeMemory(type, data, force); } +}; + +} // namespace + +#endif diff --git a/src/progs/psp/base/psp.xml b/src/progs/psp/base/psp.xml new file mode 100644 index 0000000..a009584 --- /dev/null +++ b/src/progs/psp/base/psp.xml @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/progs/psp/base/psp_data.h b/src/progs/psp/base/psp_data.h new file mode 100644 index 0000000..c643961 --- /dev/null +++ b/src/progs/psp/base/psp_data.h @@ -0,0 +1,23 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PSP_DATA_H +#define PSP_DATA_H + +#include + +namespace Psp +{ + struct Data { + uint algorithm, overprogram, tries; + }; + extern bool isSupported(const QString &device); + extern const Data &data(const QString &device); +} // namespace + +#endif diff --git a/src/progs/psp/base/psp_prog.cpp b/src/progs/psp/base/psp_prog.cpp new file mode 100644 index 0000000..891cb73 --- /dev/null +++ b/src/progs/psp/base/psp_prog.cpp @@ -0,0 +1,31 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "psp_prog.h" + +//---------------------------------------------------------------------------- +bool Psp::Base::readFirmwareVersion() +{ + return hardware().getFirmwareVersion(_firmwareVersion); +} + +//---------------------------------------------------------------------------- +Programmer::Properties Psp::Group::properties() const +{ + return ::Programmer::Programmer | ::Programmer::HasFirmware | ::Programmer::CanReadMemory | ::Programmer::HasConnectedState; // | ::Programmer::CanUploadFirmware; +} + +Programmer::Hardware *Psp::Group::createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &hd) const +{ + return new Hardware(base, hd.port.device); +} + +Programmer::DeviceSpecific *Psp::Group::createDeviceSpecific(::Programmer::Base &base) const +{ + return new DeviceSpecific(base); +} diff --git a/src/progs/psp/base/psp_prog.h b/src/progs/psp/base/psp_prog.h new file mode 100644 index 0000000..ef525cd --- /dev/null +++ b/src/progs/psp/base/psp_prog.h @@ -0,0 +1,53 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PSP_PROG_H +#define PSP_PROG_H + +#include "common/global/global.h" +#include "psp.h" + +namespace Psp +{ +//----------------------------------------------------------------------------- +class Base : public Programmer::PicBase +{ +Q_OBJECT +public: + Base(const Programmer::Group &group, const Pic::Data *data) + : Programmer::PicBase(group, data, "psp_programmer_base") {} + virtual bool readFirmwareVersion(); + virtual bool setTarget() { return hardware().setTarget(); } + +protected: + Hardware &hardware() { return static_cast(*_hardware); } + virtual VersionData firmwareVersion(Programmer::FirmwareVersionType type) const { return (type==Programmer::FirmwareVersionType::Min ? VersionData(4, 30, 3) : VersionData()); } +}; + +//----------------------------------------------------------------------------- +class Group : public ::Programmer::PicGroup +{ +public: + virtual QString name() const { return "psp"; } + virtual QString label() const { return i18n("Picstart Plus"); } + virtual QString xmlName() const { return "psp"; } + virtual ::Programmer::Properties properties() const; + virtual ::Programmer::TargetPowerMode targetPowerMode() const { return ::Programmer::TargetExternallyPowered; } + virtual bool isPortSupported(PortType type) const { return ( type==PortType::Serial ); } + virtual bool canReadVoltage(Pic::VoltageType type) const { return ( type==Pic::TargetVdd || type==Pic::TargetVpp ); } + +protected: + virtual void initSupported(); + virtual ::Programmer::Base *createBase(const Device::Data *data) const { return new ::Psp::Base(*this, static_cast(data)); } + virtual ::Programmer::Hardware *createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &hd) const; + virtual ::Programmer::DeviceSpecific *createDeviceSpecific(::Programmer::Base &base) const; +}; + +} // namespace + +#endif diff --git a/src/progs/psp/base/psp_serial.cpp b/src/progs/psp/base/psp_serial.cpp new file mode 100644 index 0000000..964d604 --- /dev/null +++ b/src/progs/psp/base/psp_serial.cpp @@ -0,0 +1,110 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * Copyright (C) 2002-2003 Stephen Landamore * + * * + * 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. * + ***************************************************************************/ +#include "psp_serial.h" + +#include "common/global/global.h" +#include "common/common/misc.h" +#include "common/common/number.h" + +//----------------------------------------------------------------------------- +Psp::SerialPort::SerialPort(const QString &device, Log::Base &log) + : Port::Serial(device, NeedFlush, log) +{} + +bool Psp::SerialPort::open() +{ + if ( !Port::Serial::open() ) return false; + return setMode(NoInputFlag, ByteSize8 | IgnoreControlLines | EnableReceiver, S19200, 100); +} + +bool Psp::SerialPort::reset() +{ + if ( !setHardwareFlowControl(false) ) return false; + // reset + setPinOn(DTR, false, Port::PositiveLogic); + Port::msleep(250); + // remove reset + setPinOn(DTR, true, Port::PositiveLogic); + for (uint i=0; i<=100; i++) { + bool bit; + if ( !readPin(CTS, Port::PositiveLogic, bit) ) return false; + if ( bit ) break; + if ( i==100 ) { + log(Log::LineType::Error, i18n("Could not contact Picstart+")); + return false; + } + Port::msleep(1); + } + if ( !setHardwareFlowControl(true) ) return false; + return flush(0); +} + +bool Psp::SerialPort::command(uchar c, uint nbBytes, QMemArray &a) +{ + log(Log::DebugLevel::Extra, QString("Command %1").arg(toHexLabel(c, 2))); + if ( !sendChar(c) ) return false; + return receive(nbBytes, a); +} + +bool Psp::SerialPort::checkAck(uchar ec, uchar rc) +{ + if ( ec==rc ) return true; + log(Log::LineType::Error, i18n("Incorrect ack: expecting %1, received %2") + .arg(QString(toHex(ec, 2))).arg(QString(toHex(rc, 2)))); + return false; +} + +bool Psp::SerialPort::checkEnd(uchar c) +{ + if ( c==0 ) return true; + log(Log::LineType::Error, i18n("Incorrect received data end: expecting 00, received %1") + .arg(QString(toHex(c, 2)))); + return false; +} + +bool Psp::SerialPort::commandAck(uchar c, uint nbBytes, QMemArray *a) +{ + Q_ASSERT( nbBytes>=1 ); + QMemArray tmp; + if ( !command(c, nbBytes, tmp) ) return false; + if ( !checkAck(c, tmp[0]) ) return false; + if (a) *a = tmp; + return true; +} + +bool Psp::SerialPort::receiveEnd() +{ + QMemArray a; + if ( !receive(1, a) ) return false; + if ( !checkEnd(a[0]) ) return false; + return true; +} + +bool Psp::SerialPort::commandAckEnd(uchar c, uint nbBytes, QMemArray &a) +{ + Q_ASSERT( nbBytes>=2 ); + if ( !command(c, nbBytes, a) ) return false; + if ( !checkAck(c, a[0]) ) return false; + if ( !checkEnd(a[nbBytes-1]) ) return false; + return true; +} + +bool Psp::SerialPort::sendData(uint value, uint nbBytes) +{ + Q_ASSERT( nbBytes==1 || nbBytes==2 ); + Q_ASSERT( value a(nbBytes); + if ( nbBytes==2 ) { + a[0] = value / 256; + a[1] = value & 0xFF; + } else a[0] = value; + if ( !send(a) ) return false; + return receive(nbBytes, a); +} diff --git a/src/progs/psp/base/psp_serial.h b/src/progs/psp/base/psp_serial.h new file mode 100644 index 0000000..6f379dd --- /dev/null +++ b/src/progs/psp/base/psp_serial.h @@ -0,0 +1,37 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * Copyright (C) 2002-2003 Stephen Landamore * + * * + * 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. * + ***************************************************************************/ +#ifndef PSP_SERIAL_H +#define PSP_SERIAL_H + +#include "common/port/serial.h" + +namespace Psp +{ + +class SerialPort : public Port::Serial +{ +public: + SerialPort(const QString &portDevice, Log::Base &log); + bool open(); + bool reset(); + bool command(uchar c, uint nbBytes, QMemArray &a); + bool commandAck(uchar c, uint nbBytes = 1, QMemArray *a = 0); + bool commandAckEnd(uchar c, uint nbBytes, QMemArray &a); + bool receiveEnd(); + bool sendData(uint value, uint nbBytes); + +private: + bool checkAck(uchar ec, uchar rc); + bool checkEnd(uchar c); +}; + +} // namespace + +#endif diff --git a/src/progs/psp/gui/Makefile.am b/src/progs/psp/gui/Makefile.am new file mode 100644 index 0000000..c11240d --- /dev/null +++ b/src/progs/psp/gui/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libpspui.la +libpspui_la_LDFLAGS = $(all_libraries) +libpspui_la_SOURCES = psp_group_ui.cpp diff --git a/src/progs/psp/gui/psp_group_ui.cpp b/src/progs/psp/gui/psp_group_ui.cpp new file mode 100644 index 0000000..e3f2546 --- /dev/null +++ b/src/progs/psp/gui/psp_group_ui.cpp @@ -0,0 +1,22 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "psp_group_ui.h" + +#include "progs/gui/prog_config_widget.h" +#include "devices/pic/gui/pic_prog_group_ui.h" + +::Programmer::ConfigWidget *Psp::GroupUI::createConfigWidget(QWidget *parent) const +{ + return new ::Programmer::ConfigWidget(static_cast(group()), parent); +} + +::Programmer::AdvancedDialog *Psp::GroupUI::createAdvancedDialog(::Programmer::Base &base, QWidget *parent) const +{ + return new ::Programmer::PicAdvancedDialog(static_cast< ::Programmer::PicBase &>(base), parent, "psp_advanced_dialog"); +} diff --git a/src/progs/psp/gui/psp_group_ui.h b/src/progs/psp/gui/psp_group_ui.h new file mode 100644 index 0000000..fc1534a --- /dev/null +++ b/src/progs/psp/gui/psp_group_ui.h @@ -0,0 +1,28 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PSP_GROUP_UI_H +#define PSP_GROUP_UI_H + +#include "devices/pic/gui/pic_prog_group_ui.h" + +namespace Psp +{ +class Group; + +class GroupUI : public ::Programmer::GroupUI +{ +public: + virtual ::Programmer::ConfigWidget *createConfigWidget(QWidget *parent) const; + virtual bool hasAdvancedDialog() const { return true; } + virtual ::Programmer::AdvancedDialog *createAdvancedDialog(::Programmer::Base &base, QWidget *parent) const; +}; + +} // namespace + +#endif diff --git a/src/progs/psp/psp.pro b/src/progs/psp/psp.pro new file mode 100644 index 0000000..60ac0f5 --- /dev/null +++ b/src/progs/psp/psp.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = xml base diff --git a/src/progs/psp/xml/Makefile.am b/src/progs/psp/xml/Makefile.am new file mode 100644 index 0000000..156e485 --- /dev/null +++ b/src/progs/psp/xml/Makefile.am @@ -0,0 +1,14 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_PROGRAMS = xml_psp_parser +xml_psp_parser_SOURCES = xml_psp_parser.cpp +OBJECTS = $(top_builddir)/src/devices/list/libdevicelistnoui.la \ + $(top_builddir)/src/devices/pic/pic/libpic.la $(top_builddir)/src/devices/pic/base/libpicbase.la \ + $(top_builddir)/src/devices/pic/xml_data/libpicxml.la \ + $(top_builddir)/src/devices/mem24/mem24/libmem24.la $(top_builddir)/src/devices/mem24/base/libmem24base.la \ + $(top_builddir)/src/devices/mem24/xml_data/libmem24xml.la \ + $(top_builddir)/src/xml_to_data/libxmltodata.la $(top_builddir)/src/devices/base/libdevicebase.la \ + $(top_builddir)/src/common/common/libcommon.la +xml_psp_parser_DEPENDENCIES = $(OBJECTS) +xml_psp_parser_LDADD = $(OBJECTS) $(LIB_KDECORE) diff --git a/src/progs/psp/xml/xml.pro b/src/progs/psp/xml/xml.pro new file mode 100644 index 0000000..0c88b4c --- /dev/null +++ b/src/progs/psp/xml/xml.pro @@ -0,0 +1,17 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/app.pro) + +TARGET = xml_psp_parser +SOURCES += xml_psp_parser.cpp +LIBS += ../../../devices/list/libdevicelist.a \ + ../../../devices/mem24/mem24/libmem24.a ../../../devices/mem24/xml_data/libmem24xml.a \ + ../../../devices/mem24/base/libmem24base.a \ + ../../../devices/pic/pic/libpic.a ../../../devices/pic/xml_data/libpicxml.a \ + ../../../devices/pic/base/libpicbase.a ../../../xml_to_data/libxmltodata.a \ + ../../../devices/base/libdevicebase.a ../../../common/global/libglobal.a \ + ../../../common/nokde/libnokde.a ../../../common/common/libcommon.a + +unix:QMAKE_POST_LINK = cd ../base && ../xml/xml_psp_parser +unix:QMAKE_CLEAN += ../base/psp_data.cpp +win32:QMAKE_POST_LINK = cd ..\base && ..\xml\xml_psp_parser.exe +win32:QMAKE_CLEAN += ..\base\psp_data.cpp diff --git a/src/progs/psp/xml/xml_psp_parser.cpp b/src/progs/psp/xml/xml_psp_parser.cpp new file mode 100644 index 0000000..5cdd289 --- /dev/null +++ b/src/progs/psp/xml/xml_psp_parser.cpp @@ -0,0 +1,45 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "xml_to_data/prog_xml_to_data.h" +#include "progs/psp/base/psp_data.h" + +//----------------------------------------------------------------------------- +namespace Psp +{ + +class XmlToData : public Programmer::XmlToData +{ +public: + XmlToData() : Programmer::XmlToData("psp", "Psp") {} + +private: + virtual void parseData(QDomElement element, Data &data); + virtual void outputData(const Data &data, QTextStream &s) const; +}; + +void Psp::XmlToData::parseData(QDomElement element, Data &data) +{ + bool ok; + data.algorithm = element.attribute("algorithm").toUInt(&ok); + if ( !ok ) qFatal("Missing or invalid algorithm"); + data.overprogram = element.attribute("overprogram").toUInt(&ok); + if ( !ok ) qFatal("Missing or invalid overprogram"); + data.tries = element.attribute("tries").toUInt(&ok); + if ( !ok ) qFatal("Missing or invalid tries"); +} + +void Psp::XmlToData::outputData(const Data &data, QTextStream &s) const +{ + s << data.algorithm << ", " << data.overprogram << ", " << data.tries; +} + +} // namespace + +//----------------------------------------------------------------------------- +XML_MAIN(Psp::XmlToData) diff --git a/src/progs/sdcdb/Makefile b/src/progs/sdcdb/Makefile new file mode 100644 index 0000000..e57c92d --- /dev/null +++ b/src/progs/sdcdb/Makefile @@ -0,0 +1,733 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# KDE tags expanded automatically by am_edit - $Revision: 877 $ +# src/progs/sdcdb/Makefile. Generated from Makefile.in by configure. + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +srcdir = . +top_srcdir = ../../.. + +pkgdatadir = $(datadir)/piklab +pkglibdir = $(libdir)/piklab +pkgincludedir = $(includedir)/piklab +top_builddir = ../../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = /usr/bin/install -c -p +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = i486-pc-linux-gnu +host_triplet = i486-pc-linux-gnu +target_triplet = i486-pc-linux-gnu +subdir = src/progs/sdcdb +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +#>- RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ +#>- html-recursive info-recursive install-data-recursive \ +#>- install-exec-recursive install-info-recursive \ +#>- install-recursive installcheck-recursive installdirs-recursive \ +#>- pdf-recursive ps-recursive uninstall-info-recursive \ +#>- uninstall-recursive +#>+ 6 +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-exec-recursive install-info-recursive \ + install-recursive installcheck-recursive installdirs-recursive \ + pdf-recursive ps-recursive uninstall-info-recursive \ + uninstall-recursive nmcheck-recursive bcheck-recursive +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +#>- DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +#>+ 1 +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) $(KDE_DIST) +ACLOCAL = ${SHELL} /home/miriam/piklab/piklab-0.15.2/admin/missing --run aclocal-1.9 +AMDEP_FALSE = # +AMDEP_TRUE = +AMTAR = ${SHELL} /home/miriam/piklab/piklab-0.15.2/admin/missing --run tar +AR = ar +ARTSCCONFIG = /usr/bin/artsc-config +AUTOCONF = $(SHELL) $(top_srcdir)/admin/cvs.sh configure || touch configure +AUTODIRS = +AUTOHEADER = ${SHELL} /home/miriam/piklab/piklab-0.15.2/admin/missing --run autoheader +AUTOMAKE = ${SHELL} /home/miriam/piklab/piklab-0.15.2/admin/missing --run automake-1.9 +AWK = mawk +BSD_FALSE = +BSD_TRUE = # +CC = i486-linux-gnu-gcc +CCDEPMODE = depmode=gcc3 +CFLAGS = -std=iso9899:1990 -W -Wall -Wchar-subscripts -Wshadow -Wpointer-arith -Wmissing-prototypes -Wwrite-strings -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -O2 -Wall -g -O2 -Wformat-security -Wmissing-format-attribute +CONF_FILES = $(top_srcdir)/./admin/configure.in.min $(top_srcdir)/configure.in.in $(top_srcdir)/configure.in.mid +CPP = i486-linux-gnu-gcc -E +CPPFLAGS = -DQT_THREAD_SUPPORT -D_REENTRANT -L/usr/lib +CXX = i486-linux-gnu-g++ +CXXCPP = i486-linux-gnu-g++ -E +CXXDEPMODE = depmode=gcc3 +CXXFLAGS = -Wno-long-long -Wundef -ansi -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -Wcast-align -Wconversion -Wchar-subscripts -Wall -W -Wpointer-arith -O2 -Wformat-security -Wmissing-format-attribute -Wno-non-virtual-dtor -fno-exceptions -fno-check-new -fno-common -DQT_CLEAN_NAMESPACE -DQT_NO_ASCII_CAST -DQT_NO_STL -DQT_NO_COMPAT -DQT_NO_TRANSLATION +CYGPATH_W = echo +DCOPIDL = /usr/bin/dcopidl +DCOPIDL2CPP = /usr/bin/dcopidl2cpp +DCOPIDLNG = +DCOP_DEPENDENCIES = $(DCOPIDL) +DEFS = -DHAVE_CONFIG_H +DEPDIR = .deps +ECHO = echo +ECHO_C = +ECHO_N = -n +ECHO_T = +EGREP = /bin/grep -E +ENABLE_PERMISSIVE_FLAG = -fpermissive +EXEEXT = +F77 = +FFLAGS = +FRAMEWORK_COREAUDIO = +GMSGFMT = /usr/bin/msgfmt +GREP = /bin/grep +HAVE_GCC_VISIBILITY = 0 +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_PROGRAM = ${INSTALL} $(INSTALL_STRIP_FLAG) +INSTALL_SCRIPT = ${INSTALL} +INSTALL_STRIP_PROGRAM = ${SHELL} $(install_sh) -c -s +KCFG_DEPENDENCIES = +KCONFIG_COMPILER = +KDECONFIG = /usr/bin/kde-config +KDE_CHECK_PLUGIN = $(KDE_PLUGIN) -rpath $(libdir) +KDE_EXTRA_RPATH = +KDE_INCLUDES = -I/usr/include/kde +KDE_LDFLAGS = -L/usr/lib +KDE_MT_LDFLAGS = +KDE_MT_LIBS = -lpthread +KDE_NO_UNDEFINED = -Wl,--no-undefined -Wl,--allow-shlib-undefined +KDE_PLUGIN = -avoid-version -module -no-undefined $(KDE_NO_UNDEFINED) $(KDE_RPATH) $(KDE_MT_LDFLAGS) +KDE_RPATH = -R $(libdir) -R $(kde_libraries) -R $(qt_libraries) -R $(x_libraries) +KDE_USE_CLOSURE_FALSE = +KDE_USE_CLOSURE_TRUE = # +KDE_USE_FINAL_FALSE = +KDE_USE_FINAL_TRUE = # +KDE_USE_FPIE = -fPIE +KDE_USE_NMCHECK_FALSE = +KDE_USE_NMCHECK_TRUE = # +KDE_USE_PIE = -pie +KDE_XSL_STYLESHEET = /usr/share/apps/ksgmltools2/customization/kde-chunk.xsl +LDFLAGS = -Wl,-z,defs -Wl,--as-needed +LDFLAGS_AS_NEEDED = +LDFLAGS_NEW_DTAGS = +LIBCOMPAT = +LIBCRYPT = -lcrypt +LIBDL = -ldl +LIBJPEG = -ljpeg +LIBOBJS = +LIBPNG = -lpng -lz -lm +LIBPTHREAD = -lpthread +LIBREADLINE_LIBS = -lhistory -lreadline -lcurses +LIBRESOLV = -lresolv +LIBS = +LIBSM = -lSM -lICE +LIBSOCKET = +LIBTOOL = $(SHELL) $(top_builddir)/libtool --silent +LIBUCB = +LIBUSBCONFIG = yes +LIBUSB_CFLAGS = +LIBUSB_LIBS = -L/usr/lib -lusb +LIBUTIL = -lutil +LIBZ = -lz +LIB_KAB = -lkab +LIB_KABC = -lkabc +LIB_KDECORE = -lkdecore +LIB_KDED = +LIB_KDEPIM = -lkdepim +LIB_KDEPRINT = -lkdeprint +LIB_KDEUI = -lkdeui +LIB_KDNSSD = -lkdnssd +LIB_KFILE = -lkio +LIB_KFM = +LIB_KHTML = -lkhtml +LIB_KIMPROXY = -lkimproxy +LIB_KIO = -lkio +LIB_KJS = -lkjs +LIB_KNEWSTUFF = -lknewstuff +LIB_KPARTS = -lkparts +LIB_KSPELL = -lkspell +LIB_KSYCOCA = -lkio +LIB_KUNITTEST = -lkunittest +LIB_KUTILS = -lkutils +LIB_POLL = +LIB_QPE = +LIB_QT = -lqt-mt $(LIBZ) $(LIBPNG) -lXext $(LIB_X11) $(LIBSM) -lpthread +LIB_SMB = -lsmb +LIB_X11 = -lX11 $(LIBSOCKET) +LIB_XEXT = -lXext +LIB_XRENDER = +LINUX_FALSE = # +LINUX_TRUE = +LN_S = ln -s +LTLIBOBJS = +MAKEINFO = ${SHELL} /home/miriam/piklab/piklab-0.15.2/admin/missing --run makeinfo +MAKEKDEWIDGETS = +MCOPIDL = /usr/bin/mcopidl +MEINPROC = /usr/bin/meinproc +MOC = /usr/share/qt3/bin/moc +MSGFMT = /usr/bin/msgfmt +NOOPT_CFLAGS = -O0 +NOOPT_CXXFLAGS = -O0 +NULL_FALSE = +NULL_TRUE = # +OBJEXT = o +PACKAGE = piklab +PACKAGE_BUGREPORT = +PACKAGE_NAME = +PACKAGE_STRING = +PACKAGE_TARNAME = +PACKAGE_VERSION = +PATH_SEPARATOR = : +PERL = /usr/bin/perl +QTE_NORTTI = +QT_INCLUDES = -I/usr/share/qt3/include +QT_LDFLAGS = -L/usr/share/qt3/lib +RANLIB = ranlib +SET_MAKE = +SHELL = /bin/sh +STRIP = strip +TOPSUBDIRS = doc man po src +UIC = /usr/share/qt3/bin/uic -L $(kde_widgetdir) -nounload +UIC_TR = tr2i18n +USER_INCLUDES = +USER_LDFLAGS = +USE_EXCEPTIONS = -fexceptions +USE_RTTI = +USE_THREADS = +VERSION = 0.15.2 +WOVERLOADED_VIRTUAL = +XGETTEXT = /usr/bin/xgettext +XMKMF = +XMLLINT = /usr/bin/xmllint +X_EXTRA_LIBS = +X_INCLUDES = -I. +X_LDFLAGS = -L/usr/lib +X_PRE_LIBS = +X_RPATH = -R $(x_libraries) +ac_ct_CC = +ac_ct_CXX = +ac_ct_F77 = +all_includes = -I/usr/include/kde -I/usr/share/qt3/include -I. +all_libraries = -L/usr/share/qt3/lib -L/usr/lib +am__fastdepCC_FALSE = # +am__fastdepCC_TRUE = +am__fastdepCXX_FALSE = # +am__fastdepCXX_TRUE = +am__include = include +am__leading_dot = . +am__quote = +am__tar = ${AMTAR} chof - "$$tardir" +am__untar = ${AMTAR} xf - +bindir = ${exec_prefix}/bin +build = i486-pc-linux-gnu +build_alias = i486-linux-gnu +build_cpu = i486 +build_os = linux-gnu +build_vendor = pc +datadir = ${datarootdir} +datarootdir = ${prefix}/share +doc_SUBDIR_included_FALSE = # +doc_SUBDIR_included_TRUE = +docdir = ${datarootdir}/doc/${PACKAGE} +dvidir = ${docdir} +exec_prefix = ${prefix} +host = i486-pc-linux-gnu +host_alias = i486-linux-gnu +host_cpu = i486 +host_os = linux-gnu +host_vendor = pc +htmldir = ${docdir} +include_ARTS_FALSE = # +include_ARTS_TRUE = +include_x11_FALSE = # +include_x11_TRUE = +includedir = ${prefix}/include +infodir = ${prefix}/share/info +install_sh = /home/miriam/piklab/piklab-0.15.2/admin/install-sh +kde_appsdir = ${datadir}/applnk +kde_bindir = ${exec_prefix}/bin +kde_confdir = ${datadir}/config +kde_datadir = ${datadir}/apps +kde_htmldir = ${datadir}/doc/HTML +kde_icondir = ${datadir}/icons +kde_includes = /usr/include/kde +kde_kcfgdir = ${datadir}/config.kcfg +kde_libraries = /usr/lib +kde_libs_htmldir = /usr/share/doc/kde/HTML +kde_libs_prefix = /usr +kde_locale = ${datadir}/locale +kde_mimedir = ${datadir}/mimelnk +kde_moduledir = ${libdir}/kde3 +kde_qtver = 3 +kde_servicesdir = ${datadir}/services +kde_servicetypesdir = ${datadir}/servicetypes +kde_sounddir = ${datadir}/sounds +kde_styledir = ${libdir}/kde3/plugins/styles +kde_templatesdir = ${datadir}/templates +kde_wallpaperdir = ${datadir}/wallpapers +kde_widgetdir = /usr/lib/kde3/plugins/designer +kdeinitdir = $(kde_moduledir) +libdir = ${exec_prefix}/lib +libexecdir = ${exec_prefix}/libexec +localedir = ${datarootdir}/locale +localstatedir = ${prefix}/var +man_SUBDIR_included_FALSE = # +man_SUBDIR_included_TRUE = +mandir = ${prefix}/share/man +mkdir_p = mkdir -p -- +oldincludedir = /usr/include +pdfdir = ${docdir} +po_SUBDIR_included_FALSE = # +po_SUBDIR_included_TRUE = +prefix = /usr +program_transform_name = s,x,x, +psdir = ${docdir} +qt_includes = /usr/share/qt3/include +qt_libraries = /usr/share/qt3/lib +sbindir = ${exec_prefix}/sbin +sharedstatedir = ${prefix}/com +src_SUBDIR_included_FALSE = # +src_SUBDIR_included_TRUE = +sysconfdir = ${prefix}/etc +target = i486-pc-linux-gnu +target_alias = +target_cpu = i486 +target_os = linux-gnu +target_vendor = pc +unsermake_enable_pch_FALSE = +unsermake_enable_pch_TRUE = # +x_includes = . +x_libraries = /usr/lib +xdg_appsdir = ${datadir}/applications/kde +xdg_directorydir = ${datadir}/desktop-directories +xdg_menudir = ${sysconfdir}/xdg/menus +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +SUBDIRS = base gui +#>- all: all-recursive +#>+ 1 +all: docs-am all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) +#>- @for dep in $?; do \ +#>- case '$(am__configure_deps)' in \ +#>- *$$dep*) \ +#>- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ +#>- && exit 0; \ +#>- exit 1;; \ +#>- esac; \ +#>- done; \ +#>- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/progs/sdcdb/Makefile'; \ +#>- cd $(top_srcdir) && \ +#>- $(AUTOMAKE) --gnu src/progs/sdcdb/Makefile +#>+ 12 + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/progs/sdcdb/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/progs/sdcdb/Makefile + cd $(top_srcdir) && perl admin/am_edit src/progs/sdcdb/Makefile.in +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done + list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(mkdir_p) "$(distdir)/$$subdir" \ + || exit 1; \ + distdir=`$(am__cd) $(distdir) && pwd`; \ + top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ + (cd $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$top_distdir" \ + distdir="$$distdir/$$subdir" \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +#>- clean: clean-recursive +#>+ 1 +clean: kde-rpo-clean clean-recursive + +#>- clean-am: clean-generic clean-libtool mostlyclean-am +#>+ 1 +clean-am: clean-bcheck clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-libtool \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +info: info-recursive + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-recursive + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-info-am + +uninstall-info: uninstall-info-recursive + +.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am \ + clean clean-generic clean-libtool clean-recursive ctags \ + ctags-recursive distclean distclean-generic distclean-libtool \ + distclean-recursive distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic maintainer-clean-recursive \ + mostlyclean mostlyclean-generic mostlyclean-libtool \ + mostlyclean-recursive pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: + +#>+ 2 +KDE_DIST=Makefile.in sdcdb.pro Makefile.am + +#>+ 2 +docs-am: + +#>+ 15 +force-reedit: + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/progs/sdcdb/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/progs/sdcdb/Makefile + cd $(top_srcdir) && perl admin/am_edit src/progs/sdcdb/Makefile.in + + +#>+ 21 +clean-bcheck: + rm -f *.bchecktest.cc *.bchecktest.cc.class a.out + +bcheck: bcheck-recursive + +bcheck-am: + @for i in ; do \ + if test $(srcdir)/$$i -nt $$i.bchecktest.cc; then \ + echo "int main() {return 0;}" > $$i.bchecktest.cc ; \ + echo "#include \"$$i\"" >> $$i.bchecktest.cc ; \ + echo "$$i"; \ + if ! $(CXX) $(DEFS) -I. -I$(srcdir) -I$(top_builddir) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) --dump-class-hierarchy -c $$i.bchecktest.cc; then \ + rm -f $$i.bchecktest.cc; exit 1; \ + fi ; \ + echo "" >> $$i.bchecktest.cc.class; \ + perl $(top_srcdir)/admin/bcheck.pl $$i.bchecktest.cc.class || { rm -f $$i.bchecktest.cc; exit 1; }; \ + rm -f a.out; \ + fi ; \ + done + + +#>+ 3 +final: + $(MAKE) all-am + +#>+ 3 +final-install: + $(MAKE) install-am + +#>+ 3 +no-final: + $(MAKE) all-am + +#>+ 3 +no-final-install: + $(MAKE) install-am + +#>+ 3 +kde-rpo-clean: + -rm -f *.rpo + +#>+ 3 +nmcheck: +nmcheck-am: nmcheck diff --git a/src/progs/sdcdb/Makefile.am b/src/progs/sdcdb/Makefile.am new file mode 100644 index 0000000..490a53d --- /dev/null +++ b/src/progs/sdcdb/Makefile.am @@ -0,0 +1,3 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +SUBDIRS = base gui diff --git a/src/progs/sdcdb/base/Makefile b/src/progs/sdcdb/base/Makefile new file mode 100644 index 0000000..a2e6af5 --- /dev/null +++ b/src/progs/sdcdb/base/Makefile @@ -0,0 +1,724 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# KDE tags expanded automatically by am_edit - $Revision: 877 $ +# src/progs/sdcdb/base/Makefile. Generated from Makefile.in by configure. + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + + +srcdir = . +top_srcdir = ../../../.. + +pkgdatadir = $(datadir)/piklab +pkglibdir = $(libdir)/piklab +pkgincludedir = $(includedir)/piklab +top_builddir = ../../../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = /usr/bin/install -c -p +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = i486-pc-linux-gnu +host_triplet = i486-pc-linux-gnu +target_triplet = i486-pc-linux-gnu +subdir = src/progs/sdcdb/base +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libsdcdb_la_LIBADD = +am_libsdcdb_la_OBJECTS = sdcdb.lo sdcdb_debug.lo +#>- libsdcdb_la_OBJECTS = $(am_libsdcdb_la_OBJECTS) +#>+ 5 +libsdcdb_la_final_OBJECTS = libsdcdb_la.all_cpp.lo +libsdcdb_la_nofinal_OBJECTS = sdcdb.lo sdcdb_debug.lo\ +sdcdb_debug.moc.lo +libsdcdb_la_OBJECTS = $(libsdcdb_la_nofinal_OBJECTS) +#libsdcdb_la_OBJECTS = $(libsdcdb_la_final_OBJECTS) +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/admin/depcomp +am__depfiles_maybe = depfiles +#>- CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ +#>- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +#>+ 2 +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) +#>- LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) \ +#>- $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ +#>- $(AM_CXXFLAGS) $(CXXFLAGS) +#>+ 3 +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) +CXXLD = $(CXX) +#>- CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \ +#>- $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +#>+ 2 +CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(KDE_CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(libsdcdb_la_SOURCES) +DIST_SOURCES = $(libsdcdb_la_SOURCES) +ETAGS = etags +CTAGS = ctags +#>- DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +#>+ 1 +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) $(KDE_DIST) +ACLOCAL = ${SHELL} /home/miriam/piklab/piklab-0.15.2/admin/missing --run aclocal-1.9 +AMDEP_FALSE = # +AMDEP_TRUE = +AMTAR = ${SHELL} /home/miriam/piklab/piklab-0.15.2/admin/missing --run tar +AR = ar +ARTSCCONFIG = /usr/bin/artsc-config +AUTOCONF = $(SHELL) $(top_srcdir)/admin/cvs.sh configure || touch configure +AUTODIRS = +AUTOHEADER = ${SHELL} /home/miriam/piklab/piklab-0.15.2/admin/missing --run autoheader +AUTOMAKE = ${SHELL} /home/miriam/piklab/piklab-0.15.2/admin/missing --run automake-1.9 +AWK = mawk +BSD_FALSE = +BSD_TRUE = # +CC = i486-linux-gnu-gcc +CCDEPMODE = depmode=gcc3 +CFLAGS = -std=iso9899:1990 -W -Wall -Wchar-subscripts -Wshadow -Wpointer-arith -Wmissing-prototypes -Wwrite-strings -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -O2 -Wall -g -O2 -Wformat-security -Wmissing-format-attribute +CONF_FILES = $(top_srcdir)/./admin/configure.in.min $(top_srcdir)/configure.in.in $(top_srcdir)/configure.in.mid +CPP = i486-linux-gnu-gcc -E +CPPFLAGS = -DQT_THREAD_SUPPORT -D_REENTRANT -L/usr/lib +CXX = i486-linux-gnu-g++ +CXXCPP = i486-linux-gnu-g++ -E +CXXDEPMODE = depmode=gcc3 +CXXFLAGS = -Wno-long-long -Wundef -ansi -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -Wcast-align -Wconversion -Wchar-subscripts -Wall -W -Wpointer-arith -O2 -Wformat-security -Wmissing-format-attribute -Wno-non-virtual-dtor -fno-exceptions -fno-check-new -fno-common -DQT_CLEAN_NAMESPACE -DQT_NO_ASCII_CAST -DQT_NO_STL -DQT_NO_COMPAT -DQT_NO_TRANSLATION +CYGPATH_W = echo +DCOPIDL = /usr/bin/dcopidl +DCOPIDL2CPP = /usr/bin/dcopidl2cpp +DCOPIDLNG = +DCOP_DEPENDENCIES = $(DCOPIDL) +DEFS = -DHAVE_CONFIG_H +DEPDIR = .deps +ECHO = echo +ECHO_C = +ECHO_N = -n +ECHO_T = +EGREP = /bin/grep -E +ENABLE_PERMISSIVE_FLAG = -fpermissive +EXEEXT = +F77 = +FFLAGS = +FRAMEWORK_COREAUDIO = +GMSGFMT = /usr/bin/msgfmt +GREP = /bin/grep +HAVE_GCC_VISIBILITY = 0 +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_PROGRAM = ${INSTALL} $(INSTALL_STRIP_FLAG) +INSTALL_SCRIPT = ${INSTALL} +INSTALL_STRIP_PROGRAM = ${SHELL} $(install_sh) -c -s +KCFG_DEPENDENCIES = +KCONFIG_COMPILER = +KDECONFIG = /usr/bin/kde-config +KDE_CHECK_PLUGIN = $(KDE_PLUGIN) -rpath $(libdir) +KDE_EXTRA_RPATH = +KDE_INCLUDES = -I/usr/include/kde +KDE_LDFLAGS = -L/usr/lib +KDE_MT_LDFLAGS = +KDE_MT_LIBS = -lpthread +KDE_NO_UNDEFINED = -Wl,--no-undefined -Wl,--allow-shlib-undefined +KDE_PLUGIN = -avoid-version -module -no-undefined $(KDE_NO_UNDEFINED) $(KDE_RPATH) $(KDE_MT_LDFLAGS) +KDE_RPATH = -R $(libdir) -R $(kde_libraries) -R $(qt_libraries) -R $(x_libraries) +KDE_USE_CLOSURE_FALSE = +KDE_USE_CLOSURE_TRUE = # +KDE_USE_FINAL_FALSE = +KDE_USE_FINAL_TRUE = # +KDE_USE_FPIE = -fPIE +KDE_USE_NMCHECK_FALSE = +KDE_USE_NMCHECK_TRUE = # +KDE_USE_PIE = -pie +KDE_XSL_STYLESHEET = /usr/share/apps/ksgmltools2/customization/kde-chunk.xsl +LDFLAGS = -Wl,-z,defs -Wl,--as-needed +LDFLAGS_AS_NEEDED = +LDFLAGS_NEW_DTAGS = +LIBCOMPAT = +LIBCRYPT = -lcrypt +LIBDL = -ldl +LIBJPEG = -ljpeg +LIBOBJS = +LIBPNG = -lpng -lz -lm +LIBPTHREAD = -lpthread +LIBREADLINE_LIBS = -lhistory -lreadline -lcurses +LIBRESOLV = -lresolv +LIBS = +LIBSM = -lSM -lICE +LIBSOCKET = +LIBTOOL = $(SHELL) $(top_builddir)/libtool --silent +LIBUCB = +LIBUSBCONFIG = yes +LIBUSB_CFLAGS = +LIBUSB_LIBS = -L/usr/lib -lusb +LIBUTIL = -lutil +LIBZ = -lz +LIB_KAB = -lkab +LIB_KABC = -lkabc +LIB_KDECORE = -lkdecore +LIB_KDED = +LIB_KDEPIM = -lkdepim +LIB_KDEPRINT = -lkdeprint +LIB_KDEUI = -lkdeui +LIB_KDNSSD = -lkdnssd +LIB_KFILE = -lkio +LIB_KFM = +LIB_KHTML = -lkhtml +LIB_KIMPROXY = -lkimproxy +LIB_KIO = -lkio +LIB_KJS = -lkjs +LIB_KNEWSTUFF = -lknewstuff +LIB_KPARTS = -lkparts +LIB_KSPELL = -lkspell +LIB_KSYCOCA = -lkio +LIB_KUNITTEST = -lkunittest +LIB_KUTILS = -lkutils +LIB_POLL = +LIB_QPE = +LIB_QT = -lqt-mt $(LIBZ) $(LIBPNG) -lXext $(LIB_X11) $(LIBSM) -lpthread +LIB_SMB = -lsmb +LIB_X11 = -lX11 $(LIBSOCKET) +LIB_XEXT = -lXext +LIB_XRENDER = +LINUX_FALSE = # +LINUX_TRUE = +LN_S = ln -s +LTLIBOBJS = +MAKEINFO = ${SHELL} /home/miriam/piklab/piklab-0.15.2/admin/missing --run makeinfo +MAKEKDEWIDGETS = +MCOPIDL = /usr/bin/mcopidl +MEINPROC = /usr/bin/meinproc +MOC = /usr/share/qt3/bin/moc +MSGFMT = /usr/bin/msgfmt +NOOPT_CFLAGS = -O0 +NOOPT_CXXFLAGS = -O0 +NULL_FALSE = +NULL_TRUE = # +OBJEXT = o +PACKAGE = piklab +PACKAGE_BUGREPORT = +PACKAGE_NAME = +PACKAGE_STRING = +PACKAGE_TARNAME = +PACKAGE_VERSION = +PATH_SEPARATOR = : +PERL = /usr/bin/perl +QTE_NORTTI = +QT_INCLUDES = -I/usr/share/qt3/include +QT_LDFLAGS = -L/usr/share/qt3/lib +RANLIB = ranlib +SET_MAKE = +SHELL = /bin/sh +STRIP = strip +TOPSUBDIRS = doc man po src +UIC = /usr/share/qt3/bin/uic -L $(kde_widgetdir) -nounload +UIC_TR = tr2i18n +USER_INCLUDES = +USER_LDFLAGS = +USE_EXCEPTIONS = -fexceptions +USE_RTTI = +USE_THREADS = +VERSION = 0.15.2 +WOVERLOADED_VIRTUAL = +XGETTEXT = /usr/bin/xgettext +XMKMF = +XMLLINT = /usr/bin/xmllint +X_EXTRA_LIBS = +X_INCLUDES = -I. +X_LDFLAGS = -L/usr/lib +X_PRE_LIBS = +X_RPATH = -R $(x_libraries) +ac_ct_CC = +ac_ct_CXX = +ac_ct_F77 = +all_includes = -I/usr/include/kde -I/usr/share/qt3/include -I. +all_libraries = -L/usr/share/qt3/lib -L/usr/lib +am__fastdepCC_FALSE = # +am__fastdepCC_TRUE = +am__fastdepCXX_FALSE = # +am__fastdepCXX_TRUE = +am__include = include +am__leading_dot = . +am__quote = +am__tar = ${AMTAR} chof - "$$tardir" +am__untar = ${AMTAR} xf - +bindir = ${exec_prefix}/bin +build = i486-pc-linux-gnu +build_alias = i486-linux-gnu +build_cpu = i486 +build_os = linux-gnu +build_vendor = pc +datadir = ${datarootdir} +datarootdir = ${prefix}/share +doc_SUBDIR_included_FALSE = # +doc_SUBDIR_included_TRUE = +docdir = ${datarootdir}/doc/${PACKAGE} +dvidir = ${docdir} +exec_prefix = ${prefix} +host = i486-pc-linux-gnu +host_alias = i486-linux-gnu +host_cpu = i486 +host_os = linux-gnu +host_vendor = pc +htmldir = ${docdir} +include_ARTS_FALSE = # +include_ARTS_TRUE = +include_x11_FALSE = # +include_x11_TRUE = +includedir = ${prefix}/include +infodir = ${prefix}/share/info +install_sh = /home/miriam/piklab/piklab-0.15.2/admin/install-sh +kde_appsdir = ${datadir}/applnk +kde_bindir = ${exec_prefix}/bin +kde_confdir = ${datadir}/config +kde_datadir = ${datadir}/apps +kde_htmldir = ${datadir}/doc/HTML +kde_icondir = ${datadir}/icons +kde_includes = /usr/include/kde +kde_kcfgdir = ${datadir}/config.kcfg +kde_libraries = /usr/lib +kde_libs_htmldir = /usr/share/doc/kde/HTML +kde_libs_prefix = /usr +kde_locale = ${datadir}/locale +kde_mimedir = ${datadir}/mimelnk +kde_moduledir = ${libdir}/kde3 +kde_qtver = 3 +kde_servicesdir = ${datadir}/services +kde_servicetypesdir = ${datadir}/servicetypes +kde_sounddir = ${datadir}/sounds +kde_styledir = ${libdir}/kde3/plugins/styles +kde_templatesdir = ${datadir}/templates +kde_wallpaperdir = ${datadir}/wallpapers +kde_widgetdir = /usr/lib/kde3/plugins/designer +kdeinitdir = $(kde_moduledir) +libdir = ${exec_prefix}/lib +libexecdir = ${exec_prefix}/libexec +localedir = ${datarootdir}/locale +localstatedir = ${prefix}/var +man_SUBDIR_included_FALSE = # +man_SUBDIR_included_TRUE = +mandir = ${prefix}/share/man +mkdir_p = mkdir -p -- +oldincludedir = /usr/include +pdfdir = ${docdir} +po_SUBDIR_included_FALSE = # +po_SUBDIR_included_TRUE = +prefix = /usr +program_transform_name = s,x,x, +psdir = ${docdir} +qt_includes = /usr/share/qt3/include +qt_libraries = /usr/share/qt3/lib +sbindir = ${exec_prefix}/sbin +sharedstatedir = ${prefix}/com +src_SUBDIR_included_FALSE = # +src_SUBDIR_included_TRUE = +sysconfdir = ${prefix}/etc +target = i486-pc-linux-gnu +target_alias = +target_cpu = i486 +target_os = linux-gnu +target_vendor = pc +unsermake_enable_pch_FALSE = +unsermake_enable_pch_TRUE = # +x_includes = . +x_libraries = /usr/lib +xdg_appsdir = ${datadir}/applications/kde +xdg_directorydir = ${datadir}/desktop-directories +xdg_menudir = ${sysconfdir}/xdg/menus +INCLUDES = -I$(top_srcdir)/src $(all_includes) +#>- METASOURCES = AUTO +noinst_LTLIBRARIES = libsdcdb.la +libsdcdb_la_LDFLAGS = $(all_libraries) +libsdcdb_la_SOURCES = sdcdb.cpp sdcdb_debug.cpp +#>- all: all-am +#>+ 1 +all: docs-am all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) +#>- @for dep in $?; do \ +#>- case '$(am__configure_deps)' in \ +#>- *$$dep*) \ +#>- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ +#>- && exit 0; \ +#>- exit 1;; \ +#>- esac; \ +#>- done; \ +#>- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/progs/sdcdb/base/Makefile'; \ +#>- cd $(top_srcdir) && \ +#>- $(AUTOMAKE) --gnu src/progs/sdcdb/base/Makefile +#>+ 12 + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/progs/sdcdb/base/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/progs/sdcdb/base/Makefile + cd $(top_srcdir) && perl admin/am_edit src/progs/sdcdb/base/Makefile.in +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libsdcdb.la: $(libsdcdb_la_OBJECTS) $(libsdcdb_la_DEPENDENCIES) + $(CXXLINK) $(libsdcdb_la_LDFLAGS) $(libsdcdb_la_OBJECTS) $(libsdcdb_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +include ./$(DEPDIR)/sdcdb.Plo +include ./$(DEPDIR)/sdcdb_debug.Plo + +.cpp.o: + if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ + then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +# source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: + if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ + then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +# source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: + if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ + then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +# source='$<' object='$@' libtool=yes \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +#>- clean: clean-am +#>+ 1 +clean: kde-rpo-clean clean-am + +#>- clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ +#>- mostlyclean-am +#>+ 2 +clean-am: clean-metasources clean-bcheck clean-final clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-exec \ + install-exec-am install-info install-info-am install-man \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am \ + uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: + +#>+ 3 +sdcdb_debug.moc.cpp: $(srcdir)/sdcdb_debug.h + $(MOC) $(srcdir)/sdcdb_debug.h -o sdcdb_debug.moc.cpp + +#>+ 2 +mocs: sdcdb_debug.moc.cpp + +#>+ 3 +clean-metasources: + -rm -f sdcdb_debug.moc.cpp + +#>+ 2 +KDE_DIST=base.pro Makefile.in sdcdb_debug.h Makefile.am + +#>+ 2 +docs-am: + +#>+ 15 +force-reedit: + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/progs/sdcdb/base/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/progs/sdcdb/base/Makefile + cd $(top_srcdir) && perl admin/am_edit src/progs/sdcdb/base/Makefile.in + + +#>+ 21 +clean-bcheck: + rm -f *.bchecktest.cc *.bchecktest.cc.class a.out + +bcheck: bcheck-am + +bcheck-am: + @for i in ; do \ + if test $(srcdir)/$$i -nt $$i.bchecktest.cc; then \ + echo "int main() {return 0;}" > $$i.bchecktest.cc ; \ + echo "#include \"$$i\"" >> $$i.bchecktest.cc ; \ + echo "$$i"; \ + if ! $(CXXCOMPILE) --dump-class-hierarchy -c $$i.bchecktest.cc; then \ + rm -f $$i.bchecktest.cc; exit 1; \ + fi ; \ + echo "" >> $$i.bchecktest.cc.class; \ + perl $(top_srcdir)/admin/bcheck.pl $$i.bchecktest.cc.class || { rm -f $$i.bchecktest.cc; exit 1; }; \ + rm -f a.out; \ + fi ; \ + done + + +#>+ 11 +libsdcdb_la.all_cpp.cpp: $(srcdir)/Makefile.in sdcdb.cpp $(srcdir)/sdcdb_debug.cpp sdcdb_debug.moc.cpp + @echo 'creating libsdcdb_la.all_cpp.cpp ...'; \ + rm -f libsdcdb_la.all_cpp.files libsdcdb_la.all_cpp.final; \ + echo "#define KDE_USE_FINAL 1" >> libsdcdb_la.all_cpp.final; \ + for file in sdcdb.cpp sdcdb_debug.cpp sdcdb_debug.moc.cpp ; do \ + echo "#include \"$$file\"" >> libsdcdb_la.all_cpp.files; \ + test ! -f $(srcdir)/$$file || egrep '^#pragma +implementation' $(srcdir)/$$file >> libsdcdb_la.all_cpp.final; \ + done; \ + cat libsdcdb_la.all_cpp.final libsdcdb_la.all_cpp.files > libsdcdb_la.all_cpp.cpp; \ + rm -f libsdcdb_la.all_cpp.final libsdcdb_la.all_cpp.files + +#>+ 3 +clean-final: + -rm -f libsdcdb_la.all_cpp.cpp + +#>+ 3 +final: + $(MAKE) libsdcdb_la_OBJECTS="$(libsdcdb_la_final_OBJECTS)" all-am + +#>+ 3 +final-install: + $(MAKE) libsdcdb_la_OBJECTS="$(libsdcdb_la_final_OBJECTS)" install-am + +#>+ 3 +no-final: + $(MAKE) libsdcdb_la_OBJECTS="$(libsdcdb_la_nofinal_OBJECTS)" all-am + +#>+ 3 +no-final-install: + $(MAKE) libsdcdb_la_OBJECTS="$(libsdcdb_la_nofinal_OBJECTS)" install-am + +#>+ 3 +kde-rpo-clean: + -rm -f *.rpo + +#>+ 3 +nmcheck: +nmcheck-am: nmcheck diff --git a/src/progs/sdcdb/base/Makefile.am b/src/progs/sdcdb/base/Makefile.am new file mode 100644 index 0000000..4ceb14f --- /dev/null +++ b/src/progs/sdcdb/base/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libsdcdb.la +libsdcdb_la_LDFLAGS = $(all_libraries) +libsdcdb_la_SOURCES = sdcdb.cpp sdcdb_debug.cpp diff --git a/src/progs/sdcdb/base/base.pro b/src/progs/sdcdb/base/base.pro new file mode 100644 index 0000000..c01db02 --- /dev/null +++ b/src/progs/sdcdb/base/base.pro @@ -0,0 +1,6 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/lib.pro) + +TARGET = sdcdb +HEADERS += sdcdb.h sdcdb_debug.h +SOURCES += sdcdb.cpp sdcdb_debug.cpp diff --git a/src/progs/sdcdb/base/sdcdb_debug.cpp b/src/progs/sdcdb/base/sdcdb_debug.cpp new file mode 100644 index 0000000..fcccf22 --- /dev/null +++ b/src/progs/sdcdb/base/sdcdb_debug.cpp @@ -0,0 +1,281 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "gpsim_debug.h" + +#include +#include + +#include "devices/list/device_list.h" +#include "devices/pic/pic/pic_debug.h" +#include "devices/pic/base/pic_register.h" +#include "coff/base/coff.h" + +//---------------------------------------------------------------------------- +GPSim::Debugger::Debugger(Programmer &programmer) + : ::Debugger::PicBase(programmer), _nbBreakpoints(0) +{} + +bool GPSim::Debugger::internalInit() +{ + if ( !hardware()->execute("processor pic" + device()->name().lower(), true) ) return false; + if ( _inputType==PURL::Cod ) return hardware()->execute("load s " + _filename, true); + Q_ASSERT( _inputType==PURL::Hex ); + return hardware()->execute("load h " + _filename, true); +} + +bool GPSim::Debugger::internalRun() +{ + return hardware()->execute("run", false); +} + +bool GPSim::Debugger::hardHalt() +{ + log(Log::Warning, i18n("Failed to halt target: kill process.")); + _programmer.disconnectHardware(); + return true; +} + +bool GPSim::Debugger::softHalt(bool &success) +{ + success = hardware()->signal(SIGINT, true); + return true; +} + +bool GPSim::Debugger::internalStep() +{ + return hardware()->execute("step", true); +} + +bool GPSim::Debugger::setBreakpoints(const QValueList
&list) +{ + for (uint i=0; i<_nbBreakpoints; i++) + if ( !hardware()->execute("clear " + QString::number(i), true) ) return false; + for (uint i=0; iexecute("break e 0x" + toHex(list[i], nbChars(list[i].toUInt())), true) ) return false; + _nbBreakpoints = list.count(); + return true; +} + +bool GPSim::Debugger::internalReset() +{ + if ( _programmer.state()==::Programmer::Running && !halt() ) return false; + return hardware()->execute("reset", true); +} + +bool GPSim::Debugger::updateState() +{ + if ( hardware()->isReady() ) _programmer.setState(::Programmer::Halted); + else _programmer.setState(::Programmer::Running); + return true; +} + +bool GPSim::Debugger::findRegExp(const QStringList &lines, const QString &pattern, + const QString &label, QString &value) const +{ + QRegExp rexp(pattern); + uint i = 0; + for (; iversion()<=VersionData(0, 21, 7) || hardware()->version()>=VersionData(0, 22, 0) ) + return getRegister("W", value); + QStringList lines; + if ( !hardware()->execute("dump s", true, &lines) ) return false; + QString s; + if ( !findRegExp(lines, "^\\s*[0-9A-Fa-f]+\\s+(\\w+)\\s*=\\s*([0-9A-Fa-f]+)", "W", s) ) { + log(Log::Error, i18n("Error reading register \"W\"")); + return false; + } + value = fromHex(s, 0); + return true; +} + +bool GPSim::Debugger::getRegister(const QString &name, BitValue &value) +{ + QStringList lines; + QRegExp r; + if ( hardware()->version()execute("x " + name, true, &lines) ) return false; + r.setPattern("\\w+\\s*[][\\w]+\\s*=\\s*(?:0x|)([0-9A-Fa-f]+)(?:\\W.*|)"); + } else { + if ( !hardware()->execute(name, true, &lines) ) return false; + r.setPattern("[^=]*=\\s*(?:0x|\\$)([0-9A-Fa-f]+)(?:\\W.*|)"); + } + uint i = 0; + for (; iregistersData(); + QString name = toHex(address, rdata.nbCharsAddress()); + if ( hardware()->version()registersData().sfrNames[data.address()]; + if ( name=="WREG" ) return readWreg(value); + if ( !name.isEmpty() ) return getRegister(name.lower(), value); + return getRegister(data.address(), value); +} + +bool GPSim::Debugger::setRegister(const QString &name, BitValue value) +{ + if ( hardware()->version()registersData(); + QString s = QString("%1 = %2").arg(name).arg(toHexLabel(value, rdata.nbChars())); + return hardware()->execute(s, true); +} + +bool GPSim::Debugger::setRegister(Address address, BitValue value) +{ + const Pic::RegistersData &rdata = device()->registersData(); + QString s = QString("ramData[$%1]").arg(toHex(address, rdata.nbCharsAddress())); + return setRegister(s, value); +} + +bool GPSim::Debugger::writeRegister(const Register::TypeData &data, BitValue value) +{ + if ( data.type()==Register::Special ) { + if ( data.name()=="WREG" ) return writeWreg(value); + if ( data.name()=="PC" ) { + log(Log::Warning, i18n("Writing PC is not supported by gpsim")); + return true; + } + Q_ASSERT(false); + return false; + } + const Pic::RegistersData &rdata = device()->registersData(); + QString name = rdata.sfrNames[data.address()]; + if ( !name.isEmpty() ) return setRegister(name.lower(), value); + return setRegister(data.address(), value); +} + +bool GPSim::Debugger::writeWreg(BitValue value) +{ + return setRegister("W", value); +} + +bool GPSim::Debugger::updatePortStatus(uint index, QMap &bits) +{ + for (uint i=0; iregistersData().hasPortBit(index, i) ) continue; + QString name = device()->registersData().portName(index).lower() + QString::number(i); + QStringList lines; + if ( !hardware()->execute("symbol " + name, true, &lines) ) return false; + QString pattern = "^(\\w+)=([^\\s])+\\s*", value; + if ( !findRegExp(lines, pattern, "bitState", value) || value.length()!=1 ) { + log(Log::Error, i18n("Error reading state of IO bit: %1").arg(name)); + return false; + } + switch (value[0].latin1()) { + case 'H': + case '1': bits[i].state = Device::High; break; + case 'L': + case '0': bits[i].state = Device::Low; break; + case 'W': bits[i].state = Device::WeakPullUp; break; + case 'w': bits[i].state = Device::WeakPullDown; break; + case 'Z': bits[i].state = Device::HighImpedance; break; + case 'X': bits[i].state = Device::Unknown; break; + default: + bits[i].state = Device::Unknown; + log(Log::Warning, i18n("Unknown state for IO bit: %1 (%2)").arg(name).arg(value)); + break; + } + if ( !findRegExp(lines, pattern, "Driving", value) || value.length()!=1 ) { + log(Log::Error, i18n("Error reading driving state of IO bit: %1").arg(name)); + return false; + } + bits[i].driving = ( value[0]=='1' ); + if (bits[i].driving) { + if ( !findRegExp(lines, pattern, "drivingState", value) || value.length()!=1 ) { + log(Log::Error, i18n("Error reading driving state of IO bit: %1").arg(name)); + return false; + } + bits[i].drivingState = (value[0]=='0' ? Device::IoLow : Device::IoHigh); + bits[i].drivenState = Device::IoUnknown; + } else { + if ( !findRegExp(lines, pattern, "drivenState", value) || value.length()!=1 ) { + log(Log::Error, i18n("Error reading driven state of IO bit: %1").arg(name)); + return false; + } + bits[i].drivenState = (value[0]=='0' ? Device::IoLow : Device::IoHigh); + bits[i].drivingState = Device::IoUnknown; + } + } + return true; +} + +//---------------------------------------------------------------------------- +QString GPSim::Group::statusLabel() const +{ + return i18n("GPSim (4MHz)"); // #### FIXME: add config +} + +void GPSim::Group::initSupported() +{ + ProcessManager manager(0); + if ( !manager.start() ) return; + VersionData version; + if ( !manager.getVersion(version) ) return; + bool oldGpsim = ( version(Device::lister().data(s)); + if (data) { + if ( data->architecture()==Pic::Architecture::P18F && oldGpsim ) continue; + addDevice(data->name(), data, ::Group::Tested); + } + } +} + +Programmer::Hardware *GPSim::Group::createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &) const +{ + return new Hardware(base); +} + +Programmer::DeviceSpecific *GPSim::Group::createDeviceSpecific(::Programmer::Base &base) const +{ + return new DeviceSpecific(base); +} diff --git a/src/progs/sdcdb/base/sdcdb_debug.h b/src/progs/sdcdb/base/sdcdb_debug.h new file mode 100644 index 0000000..55cda75 --- /dev/null +++ b/src/progs/sdcdb/base/sdcdb_debug.h @@ -0,0 +1,95 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef SDCDB_DEBUG_H +#define SDCDB_DEBUG_H + +#include "sdcdb.h" +#include "devices/pic/pic/pic_prog.h" +#include "devices/pic/pic/pic_debug.h" + +namespace SDCDB +{ +//----------------------------------------------------------------------------- +class Programmer : public ::Programmer::PicBase +{ +Q_OBJECT +public: + Programmer(const ::Programmer::Group &group, const Pic::Data *data) + : Programmer::PicBase(group, data, "sdcdb_programmer") {} + +private: + virtual VersionData minVersion() const { return VersionData(0, 8, 0); } + virtual bool verifyDeviceId() { return true; } + virtual bool checkErase() { return false; } + virtual bool internalErase(const Device::MemoryRange &) { return false; } + virtual bool checkRead() { return false; } + virtual bool internalRead(Device::Memory &, const Device::MemoryRange &) { return false; } + virtual bool checkProgram(const Device::Memory &) { return false; } + virtual bool internalProgram(const Device::Memory &, const Device::MemoryRange &) { return false; } + virtual bool checkVerify() { return false; } + virtual bool internalVerify(const Device::Memory &, const Device::MemoryRange &, ::Programmer::VerifyActions) { return false; } +}; + +//----------------------------------------------------------------------------- +class Debugger : public ::Debugger::PicBase +{ +public: + Debugger(Programmer &programmer); + virtual bool setBreakpoints(const QValueList
&list); + virtual bool readRegister(const Register::TypeData &data, BitValue &value); + virtual bool writeRegister(const Register::TypeData &data, BitValue value); + virtual bool updatePortStatus(uint index, QMap &bits); + +private: + uint _nbBreakpoints; + + bool findRegExp(const QStringList &lines, const QString &pattern, + const QString &label, QString &value) const; + bool getRegister(const QString &name, BitValue &value); + bool setRegister(const QString &name, BitValue value); + bool getRegister(Address address, BitValue &value); + bool setRegister(Address address, BitValue value); + Hardware *hardware() { return static_cast(_programmer.hardware()); } + const Pic::Data *device() const { return static_cast(_programmer.device()); } + virtual bool internalInit(); + virtual bool updateState(); + virtual bool internalRun(); + virtual bool internalStep(); + virtual bool softHalt(bool &success); + virtual bool hardHalt(); + virtual bool internalReset(); + bool readWreg(BitValue &value); + bool writeWreg(BitValue value); +}; + +//----------------------------------------------------------------------------- +class Group : public ::Programmer::PicGroup +{ +public: + virtual QString name() const { return "sdcdb"; } + virtual QString label() const { return i18n("SDCDB"); } + virtual QString statusLabel() const; + virtual ::Programmer::Properties properties() const { return ::Programmer::Debugger | ::Programmer::HasConnectedState; } + virtual ::Programmer::TargetPowerMode targetPowerMode() const { return ::Programmer::TargetSelfPowered; } + virtual bool isPortSupported(Port::Type) const { return false; } + virtual uint maxNbBreakpoints(const Device::Data *) const { return 100; } + virtual bool isInputFileTypeSupported(PURL::FileType type) const { return ( type==PURL::Cod || type==PURL::Hex ); } + +protected: + virtual void initSupported(); + virtual ::Programmer::Base *createBase(const Device::Data *data) const { return new Programmer(*this, static_cast(data)); } + virtual ::Programmer::Hardware *createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &hd) const; + virtual ::Programmer::DeviceSpecific *createDeviceSpecific(::Programmer::Base &base) const; + virtual ::Debugger::Base *createDebuggerBase(::Programmer::Base &base) const { return new Debugger(static_cast(base)); } + virtual ::Debugger::Specific *createDebuggerSpecific(::Debugger::Base &) const { return 0; } +}; + +} // namespace + +#endif diff --git a/src/progs/sdcdb/sdcdb.pro b/src/progs/sdcdb/sdcdb.pro new file mode 100644 index 0000000..fe430fe --- /dev/null +++ b/src/progs/sdcdb/sdcdb.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = base diff --git a/src/progs/tbl_bootloader/Makefile.am b/src/progs/tbl_bootloader/Makefile.am new file mode 100644 index 0000000..fccf96d --- /dev/null +++ b/src/progs/tbl_bootloader/Makefile.am @@ -0,0 +1,3 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +SUBDIRS = xml base gui diff --git a/src/progs/tbl_bootloader/base/Makefile.am b/src/progs/tbl_bootloader/base/Makefile.am new file mode 100644 index 0000000..60b11bc --- /dev/null +++ b/src/progs/tbl_bootloader/base/Makefile.am @@ -0,0 +1,11 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libtblbootloader.la +libtblbootloader_la_SOURCES = tbl_bootloader_data.cpp tbl_bootloader.cpp tbl_bootloader_prog.cpp +libtblbootloader_la_DEPENDENCIES = tbl_bootloader_data.cpp + +noinst_DATA = tbl_bootloader.xml +tbl_bootloader_data.cpp: ../xml/xml_tbl_bootloader_parser tbl_bootloader.xml + ../xml/xml_tbl_bootloader_parser +CLEANFILES = tbl_bootloader_data.cpp diff --git a/src/progs/tbl_bootloader/base/base.pro b/src/progs/tbl_bootloader/base/base.pro new file mode 100644 index 0000000..1ccb8e9 --- /dev/null +++ b/src/progs/tbl_bootloader/base/base.pro @@ -0,0 +1,6 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/lib.pro) + +TARGET = tbl_bootloader +HEADERS += tbl_bootloader_data.h tbl_bootloader.h tbl_bootloader_prog.h +SOURCES += tbl_bootloader_data.cpp tbl_bootloader.cpp tbl_bootloader_prog.cpp diff --git a/src/progs/tbl_bootloader/base/tbl_bootloader.cpp b/src/progs/tbl_bootloader/base/tbl_bootloader.cpp new file mode 100644 index 0000000..419ad86 --- /dev/null +++ b/src/progs/tbl_bootloader/base/tbl_bootloader.cpp @@ -0,0 +1,327 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "tbl_bootloader.h" + +#include "tbl_bootloader_data.h" +#include "progs/base/prog_config.h" + +//----------------------------------------------------------------------------- +Port::Serial::Speed TinyBootloader::Config::readSpeed() +{ + uint speed = readUIntEntry("port_speed", 19200); + for (uint i=0; iopen() ) return false; + Config config; + if ( !port()->setMode(Port::Serial::IgnoreBreak | Port::Serial::IgnoreParity, + Port::Serial::ByteSize8 | Port::Serial::IgnoreControlLines, + config.readSpeed(), _timeout) ) + return false; + return true; +} + +bool TinyBootloader::Hardware::internalConnectHardware() +{ + if ( !openPort() ) return false; + // #### possibly do hard (RTS) or soft reset (codes) + uchar uc = 0xC1; + if ( !port()->sendChar(uc, _timeout) ) return false; + if ( !port()->receiveChar((char &)_id, _timeout) ) return false; + if ( !waitReady(0) ) return false; + return true; +} + +bool TinyBootloader::Hardware::verifyDeviceId() +{ + uchar id = data(device().name()).id; + QValueVector list = _base.group().supportedDevices(); + QStringList devices; + for (uint i=0; ireceiveChar(c, _timeout) ) return false; + if ( c=='K' ) { + if (checkCRC) *checkCRC = true; + return true; + } + if (checkCRC) { + *checkCRC = false; + if ( c=='N' ) return true; + log(Log::LineType::Error, i18n("Received unexpected character ('%1' received; 'K' or 'N' expected).").arg(toPrintable(c, PrintAlphaNum))); + return true; + } + log(Log::LineType::Error, i18n("Received unexpected character ('%1' received; 'K' expected).").arg(toPrintable(c, PrintAlphaNum))); + return false; +} + +bool TinyBootloader::Hardware::sendChar(char c, uchar *crc) +{ + if (crc) *crc += c; + return port()->sendChar(c, 10*_timeout); +} + +bool TinyBootloader::Hardware::sendCodeAddress(uint address, uchar &crc) +{ + switch (device().architecture().type()) { + case Pic::Architecture::P16X: + if ( !sendChar(address >> 8, &crc) ) return false; // address high + if ( !sendChar(address & 0xFF, &crc) ) return false; // address low + break; + case Pic::Architecture::P18F: + if ( !sendChar(address >> 16, &crc) ) return false; // address upper + if ( !sendChar((address >> 8) & 0xFF, &crc) ) return false; // address high + if ( !sendChar(address & 0xFF, &crc) ) return false; // address low + break; + case Pic::Architecture::P30F: + if ( !sendChar(address & 0xFF, &crc) ) return false; // address low + if ( !sendChar((address >> 8) & 0xFF, &crc) ) return false; // address high + if ( !sendChar(address >> 16, &crc) ) return false; // address upper + break; + default: Q_ASSERT(false); return false; + } + return true; +} + +bool TinyBootloader::Hardware::endWrite(uchar crc, uint &retries, bool &ok) +{ + if ( !sendChar(-crc & 0xFF, 0) ) return false; + if ( !waitReady(&ok) ) return false; + if ( !ok ) { + if ( retries==0 ) { + log(Log::LineType::Error, i18n("Too many failures: bailing out.")); + return false; + } + retries--; + log(Log::LineType::Warning, i18n("CRC error from bootloader: retrying...")); + } + return true; +} + +bool TinyBootloader::Hardware::writeCode(const Device::Array &data, bool erase) +{ + uint nb = data.count() - 100; + Device::Array wdata(nb+4); + + // check that there is nothing on top of bootloader + for (uint i=nb; i(hardware()).writeCode(memory.arrayForWriting(type), true); + return hardware().write(type, memory.arrayForWriting(type)); +} diff --git a/src/progs/tbl_bootloader/base/tbl_bootloader.h b/src/progs/tbl_bootloader/base/tbl_bootloader.h new file mode 100644 index 0000000..b6e759f --- /dev/null +++ b/src/progs/tbl_bootloader/base/tbl_bootloader.h @@ -0,0 +1,74 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef TBL_BOOTLOADER_H +#define TBL_BOOTLOADER_H + +#include "progs/bootloader/base/bootloader.h" +#include "progs/bootloader/base/bootloader_prog.h" +#include "common/port/serial.h" +#include "common/global/generic_config.h" + +namespace TinyBootloader +{ +//----------------------------------------------------------------------------- +class Config : public GenericConfig +{ +public: + Config() : GenericConfig("tiny_bootloader") {} + Port::Serial::Speed readSpeed(); + void writeSpeed(Port::Serial::Speed speed); + uint readTimeout(); // ms + void writeTimeout(uint timeout); // ms + uint readRetries(); + void writeRetries(uint nb); +}; + +//----------------------------------------------------------------------------- +class Hardware : public ::Bootloader::Hardware +{ +public: + Hardware(::Programmer::Base &base, const QString &portDevice); + Port::Serial *port() { return static_cast(_port); } + bool verifyDeviceId(); + virtual bool write(Pic::MemoryRangeType type, const Device::Array &data); + virtual bool read(Pic::MemoryRangeType, Device::Array &, const ::Programmer::VerifyData *) { return false; } + bool writeCode(const Device::Array &data, bool erase); + bool writeConfig(const Device::Array &data); + bool writeEeprom(const Device::Array &data); + virtual bool internalConnectHardware(); + virtual bool openPort(); + +private: + uchar _id; + uint _timeout; // ms + uint _retries; + + bool waitReady(bool *checkCRC); + bool sendChar(char c, uchar *crc); + bool sendCodeAddress(uint address, uchar &crc); + bool endWrite(uchar crc, uint &retries, bool &ok); +}; + +//----------------------------------------------------------------------------- +class DeviceSpecific : public ::Bootloader::DeviceSpecific +{ +public: + DeviceSpecific(::Programmer::Base &base) : ::Bootloader::DeviceSpecific(base) {} + virtual bool canEraseAll() const { return true; } + virtual bool canEraseRange(Pic::MemoryRangeType type) const { return canWriteRange(type); } + virtual bool emulatedErase() const { return true; } + virtual bool canReadRange(Pic::MemoryRangeType) const { return false; } + virtual bool canWriteRange(Pic::MemoryRangeType type) const; + virtual bool doEraseRange(Pic::MemoryRangeType type); + virtual bool doErase(bool); +}; + +} // namespace + +#endif diff --git a/src/progs/tbl_bootloader/base/tbl_bootloader.xml b/src/progs/tbl_bootloader/base/tbl_bootloader.xml new file mode 100644 index 0000000..bbad6dd --- /dev/null +++ b/src/progs/tbl_bootloader/base/tbl_bootloader.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/progs/tbl_bootloader/base/tbl_bootloader_data.h b/src/progs/tbl_bootloader/base/tbl_bootloader_data.h new file mode 100644 index 0000000..51be528 --- /dev/null +++ b/src/progs/tbl_bootloader/base/tbl_bootloader_data.h @@ -0,0 +1,21 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef TBL_BOOTLOADER_DATA_H +#define TBL_BOOTLOADER_DATA_H + +namespace TinyBootloader +{ + struct Data { + uchar id; + }; + extern bool isSupported(const QString &device); + extern const Data &data(const QString &device); +} // namespace + +#endif diff --git a/src/progs/tbl_bootloader/base/tbl_bootloader_prog.cpp b/src/progs/tbl_bootloader/base/tbl_bootloader_prog.cpp new file mode 100644 index 0000000..22c831e --- /dev/null +++ b/src/progs/tbl_bootloader/base/tbl_bootloader_prog.cpp @@ -0,0 +1,14 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "tbl_bootloader_prog.h" + +//----------------------------------------------------------------------------- +TinyBootloader::ProgrammerBase::ProgrammerBase(const Programmer::Group &group, const Pic::Data *data) + : Bootloader::ProgrammerBase(group, data, "tiny_bootloader_programmer_base") +{} diff --git a/src/progs/tbl_bootloader/base/tbl_bootloader_prog.h b/src/progs/tbl_bootloader/base/tbl_bootloader_prog.h new file mode 100644 index 0000000..75b986d --- /dev/null +++ b/src/progs/tbl_bootloader/base/tbl_bootloader_prog.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef TBL_BOOTLOADER_PROG_H +#define TBL_BOOTLOADER_PROG_H + +#include "tbl_bootloader.h" + +namespace TinyBootloader +{ + +//----------------------------------------------------------------------------- +class ProgrammerBase : public ::Bootloader::ProgrammerBase +{ +Q_OBJECT +public: + ProgrammerBase(const Programmer::Group &group, const Pic::Data *data); + virtual bool verifyDeviceId() { return static_cast(hardware()).verifyDeviceId(); } +}; + +//----------------------------------------------------------------------------- +class Group : public ::Bootloader::Group +{ +public: + virtual QString name() const { return "tbl_bootloader"; } + virtual QString label() const { return i18n("Tiny Bootloader"); } + virtual ::Programmer::Properties properties() const { return ::Programmer::Programmer; } + virtual ::Programmer::TargetPowerMode targetPowerMode() const { return ::Programmer::TargetSelfPowered; } + virtual bool isPortSupported(PortType type) const { return type==PortType::Serial; } + virtual bool canReadVoltage(Pic::VoltageType) const { return false; } + +protected: + virtual void initSupported(); + virtual ::Programmer::Base *createBase(const Device::Data *data) const { return new ProgrammerBase(*this, static_cast(data)); } + virtual ::Programmer::Hardware *createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &hd) const { return new Hardware(base, hd.port.device); } + virtual ::Programmer::DeviceSpecific *createDeviceSpecific(::Programmer::Base &base) const { return new DeviceSpecific(base); } +}; + +} // namespace + +#endif diff --git a/src/progs/tbl_bootloader/gui/Makefile.am b/src/progs/tbl_bootloader/gui/Makefile.am new file mode 100644 index 0000000..d10b944 --- /dev/null +++ b/src/progs/tbl_bootloader/gui/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libtblbootloaderui.la +libtblbootloaderui_la_LDFLAGS = $(all_libraries) +libtblbootloaderui_la_SOURCES = tbl_bootloader_ui.cpp diff --git a/src/progs/tbl_bootloader/gui/tbl_bootloader_ui.cpp b/src/progs/tbl_bootloader/gui/tbl_bootloader_ui.cpp new file mode 100644 index 0000000..5b576b9 --- /dev/null +++ b/src/progs/tbl_bootloader/gui/tbl_bootloader_ui.cpp @@ -0,0 +1,80 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "tbl_bootloader_ui.h" + +#include "progs/tbl_bootloader/base/tbl_bootloader.h" +#include "common/port/serial.h" + +//----------------------------------------------------------------------------- +TinyBootloader::ConfigWidget::ConfigWidget(const::Programmer::Group &group, QWidget *parent) + : ::Programmer::ConfigWidget(group, parent) +{ + uint row = numRows(); + + QLabel *label = new QLabel(i18n("Port Speed:"), this); + addWidget(label, row,row, 0,0); + _speed = new KComboBox(this); + for (uint i=0; iinsertItem(QString::number(Port::Serial::SPEED_VALUES[i])); + } + addWidget(_speed, row,row, 1,1); + row++; + + label = new QLabel(i18n("Timeout (ms):"), this); + addWidget(label, row,row, 0,0); + _timeout = new KIntNumInput(this); + _timeout->setMinValue(0); + addWidget(_timeout, row,row, 1,1); + row++; + + label = new QLabel(i18n("No of Retries:"), this); + addWidget(label, row,row, 0,0); + _retries = new KIntNumInput(this); + _retries->setMinValue(0); + addWidget(_retries, row,row, 1,1); + row++; +} + +void TinyBootloader::ConfigWidget::saveConfig() +{ + Config config; + uint k = 0; + for (uint i=0; icurrentItem())==k ) { + config.writeSpeed(Port::Serial::Speed(i)); + break; + } + k++; + } + config.writeTimeout(_timeout->value()); + config.writeRetries(_retries->value()); +} + +void TinyBootloader::ConfigWidget::loadConfig() +{ + Config config; + Port::Serial::Speed speed = config.readSpeed(); + uint k = 0; + for (uint i=0; isetCurrentItem(k); + _timeout->setValue(config.readTimeout()); + _retries->setValue(config.readRetries()); +} + +//----------------------------------------------------------------------------- +::Programmer::ConfigWidget *TinyBootloader::GroupUI::createConfigWidget(QWidget *parent) const +{ + return new ConfigWidget(static_cast(group()), parent); +} diff --git a/src/progs/tbl_bootloader/gui/tbl_bootloader_ui.h b/src/progs/tbl_bootloader/gui/tbl_bootloader_ui.h new file mode 100644 index 0000000..d0285af --- /dev/null +++ b/src/progs/tbl_bootloader/gui/tbl_bootloader_ui.h @@ -0,0 +1,42 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef TBL_BOOTLOADER_UI_H +#define TBL8BOOTLOADER_UI_H + +#include +#include + +#include "progs/bootloader/gui/bootloader_ui.h" + +//----------------------------------------------------------------------------- +namespace TinyBootloader +{ +class ConfigWidget: public ::Programmer::ConfigWidget +{ +Q_OBJECT +public: + ConfigWidget(const ::Programmer::Group &group, QWidget *parent); + virtual void loadConfig(); + virtual void saveConfig(); + +private: + KIntNumInput *_timeout, *_retries; + KComboBox *_type, *_speed; +}; + +//---------------------------------------------------------------------------- +class GroupUI : public ::Bootloader::GroupUI +{ +public: + virtual ::Programmer::ConfigWidget *createConfigWidget(QWidget *parent) const; +}; + +} // namespace + +#endif diff --git a/src/progs/tbl_bootloader/tbl_bootloader.pro b/src/progs/tbl_bootloader/tbl_bootloader.pro new file mode 100644 index 0000000..60ac0f5 --- /dev/null +++ b/src/progs/tbl_bootloader/tbl_bootloader.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = xml base diff --git a/src/progs/tbl_bootloader/xml/Makefile.am b/src/progs/tbl_bootloader/xml/Makefile.am new file mode 100644 index 0000000..609ca90 --- /dev/null +++ b/src/progs/tbl_bootloader/xml/Makefile.am @@ -0,0 +1,14 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_PROGRAMS = xml_tbl_bootloader_parser +xml_tbl_bootloader_parser_SOURCES = xml_tbl_bootloader_parser.cpp +OBJECTS = $(top_builddir)/src/devices/list/libdevicelistnoui.la \ + $(top_builddir)/src/devices/pic/pic/libpic.la $(top_builddir)/src/devices/pic/base/libpicbase.la \ + $(top_builddir)/src/devices/pic/xml_data/libpicxml.la \ + $(top_builddir)/src/devices/mem24/mem24/libmem24.la $(top_builddir)/src/devices/mem24/base/libmem24base.la \ + $(top_builddir)/src/devices/mem24/xml_data/libmem24xml.la \ + $(top_builddir)/src/xml_to_data/libxmltodata.la $(top_builddir)/src/devices/base/libdevicebase.la \ + $(top_builddir)/src/common/common/libcommon.la +xml_tbl_bootloader_parser_DEPENDENCIES = $(OBJECTS) +xml_tbl_bootloader_parser_LDADD = $(OBJECTS) $(LIB_KDECORE) diff --git a/src/progs/tbl_bootloader/xml/xml.pro b/src/progs/tbl_bootloader/xml/xml.pro new file mode 100644 index 0000000..a7d488a --- /dev/null +++ b/src/progs/tbl_bootloader/xml/xml.pro @@ -0,0 +1,17 @@ +STOPDIR = ../../../.. +include($${STOPDIR}/app.pro) + +TARGET = xml_tbl_bootloader_parser +SOURCES += xml_tbl_bootloader_parser.cpp +LIBS += ../../../devices/list/libdevicelist.a \ + ../../../devices/mem24/mem24/libmem24.a ../../../devices/mem24/xml_data/libmem24xml.a \ + ../../../devices/mem24/base/libmem24base.a \ + ../../../devices/pic/pic/libpic.a ../../../devices/pic/xml_data/libpicxml.a \ + ../../../devices/pic/base/libpicbase.a ../../../xml_to_data/libxmltodata.a \ + ../../../devices/base/libdevicebase.a ../../../common/global/libglobal.a \ + ../../../common/nokde/libnokde.a ../../../common/common/libcommon.a + +unix:QMAKE_POST_LINK = cd ../base && ../xml/xml_tbl_bootloader_parser +unix:QMAKE_CLEAN += ../base/tbl_bootloader_data.cpp +win32:QMAKE_POST_LINK = cd ..\base && ..\xml\xml_tbl_bootloader_parser.exe +win32:QMAKE_CLEAN += ..\base\tbl_bootloader_data.cpp diff --git a/src/progs/tbl_bootloader/xml/xml_tbl_bootloader_parser.cpp b/src/progs/tbl_bootloader/xml/xml_tbl_bootloader_parser.cpp new file mode 100644 index 0000000..62ed806 --- /dev/null +++ b/src/progs/tbl_bootloader/xml/xml_tbl_bootloader_parser.cpp @@ -0,0 +1,48 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "xml_to_data/prog_xml_to_data.h" + +#include "progs/tbl_bootloader/base/tbl_bootloader_data.h" +#include "devices/base/device_group.h" +#include "devices/pic/base/pic.h" + +//----------------------------------------------------------------------------- +namespace TinyBootloader +{ + +class XmlToData : public Programmer::XmlToData +{ +public: + XmlToData() : Programmer::XmlToData("tbl_bootloader", "TinyBootloader") {} + +private: + virtual void parseData(QDomElement element, Data &data); + virtual void outputData(const Data &data, QTextStream &s) const; +}; + +void TinyBootloader::XmlToData::parseData(QDomElement element, Data &data) +{ + const Device::Data *ddata = Device::lister().data(currentDevice()); + if ( ddata->group().name()!="pic" ) qFatal("non-pic device not supported"); + const Pic::Data *pdata = static_cast(ddata); + if ( !pdata->hasFeature(Pic::Feature::USART) ) qFatal("device does not have USART"); + bool ok; + data.id = fromHexLabel(element.attribute("id"), 2, &ok); + if ( !ok ) qFatal("Invalid \"id\" tag"); +} + +void TinyBootloader::XmlToData::outputData(const Data &data, QTextStream &s) const +{ + s << data.id; +} + +} // namespace + +//----------------------------------------------------------------------------- +XML_MAIN(TinyBootloader::XmlToData) diff --git a/src/src.pro b/src/src.pro new file mode 100644 index 0000000..bbb9f17 --- /dev/null +++ b/src/src.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = common xml_to_data devices piklab-hex coff piklab-coff progs piklab-prog diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am new file mode 100644 index 0000000..0b287af --- /dev/null +++ b/src/tools/Makefile.am @@ -0,0 +1,3 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +SUBDIRS = base gui gputils sdcc picc pic30 c18 jal ccsc jalv2 boost mpc cc5x custom list diff --git a/src/tools/base/Makefile.am b/src/tools/base/Makefile.am new file mode 100644 index 0000000..2154bf4 --- /dev/null +++ b/src/tools/base/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libtoolbase.la +libtoolbase_la_LDFLAGS = $(all_libraries) +libtoolbase_la_SOURCES = generic_tool.cpp tool_group.cpp diff --git a/src/tools/base/generic_tool.cpp b/src/tools/base/generic_tool.cpp new file mode 100644 index 0000000..d595362 --- /dev/null +++ b/src/tools/base/generic_tool.cpp @@ -0,0 +1,60 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "generic_tool.h" + +#include "devices/list/device_list.h" +#include "common/global/process.h" +#include "tools/list/compile_config.h" + +//---------------------------------------------------------------------------- +const Tool::Category::Data Tool::Category::DATA[Nb_Types] = { + { "compiler", I18N_NOOP("Compiler:"), I18N_NOOP("Compiler") }, + { "assembler", I18N_NOOP("Assembler:"), I18N_NOOP("Assembler") }, + { "linker", I18N_NOOP("Linker:"), I18N_NOOP("Linker") }, + { "bin_to_hex", I18N_NOOP("Bin to Hex:"), I18N_NOOP("Bin to Hex") }, + { "librarian", I18N_NOOP("Librarian:"), I18N_NOOP("Librarian") } +}; + +const Tool::ExecutableType::Data Tool::ExecutableType::DATA[Nb_Types] = { + { "unix", I18N_NOOP("Unix") }, + { "windows", I18N_NOOP("Windows") } +}; + +const Compile::DirectoryType::Data Compile::DirectoryType::DATA[Nb_Types] = { + { "executable", I18N_NOOP("Executable directory") }, + { "include", I18N_NOOP("Header directory") }, + { "linker_script", I18N_NOOP("Linker Script Directory") }, + { "library", I18N_NOOP("Library Directory") }, + { "source", I18N_NOOP("Source Directory") } +}; + +const Tool::OutputExecutableType::Data Tool::OutputExecutableType::DATA[Nb_Types] = { + { I18N_NOOP("COFF"), "coff", PURL::Coff }, + { I18N_NOOP("ELF"), "elf", PURL::Elf } +}; + +const Tool::OutputType::Data Tool::OutputType::DATA[Nb_Types] = { + { "executable", I18N_NOOP("Executable") }, + { "library", I18N_NOOP("Library") } +}; + +//----------------------------------------------------------------------------- +PURL::Directory Tool::Base::executableDirectory() const +{ + return Compile::Config::directory(*_group, Compile::DirectoryType::Executable); +} + +::Process::LineOutput *Tool::Base::checkExecutableProcess(const PURL::Directory &dir, bool withWine, OutputExecutableType type) const +{ + ::Process::LineOutput *process = new ::Process::LineOutput; + process->setup(dir.path() + baseExecutable(withWine, type), checkExecutableOptions(withWine), withWine); + PURL::Directory wdir = checkExecutableWorkingDirectory(); + if ( !wdir.isEmpty() ) process->setWorkingDirectory(wdir.path()); + return process; +} diff --git a/src/tools/base/generic_tool.h b/src/tools/base/generic_tool.h new file mode 100644 index 0000000..3b3299d --- /dev/null +++ b/src/tools/base/generic_tool.h @@ -0,0 +1,104 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef GENERIC_TOOL_H +#define GENERIC_TOOL_H + +#include "common/global/purl.h" +#include "common/common/key_enum.h" +namespace Device { class Data; class Memory; } +namespace Process { class LineOutput; } +class Project; + +namespace Tool +{ +//---------------------------------------------------------------------------- + struct CategoryData { + const char *key, *label, *title; + }; + BEGIN_DECLARE_ENUM(Category) + Compiler = 0, Assembler, Linker, BinToHex, Librarian + END_DECLARE_ENUM(Category, CategoryData) + + BEGIN_DECLARE_ENUM(ExecutableType) + Unix = 0, Windows + END_DECLARE_ENUM_STD(ExecutableType) +} // namespace + +namespace Compile +{ + enum LinkType { NormalLinking, Icd2Linking }; + class Process; + class Config; + + class TodoItem { + public: + TodoItem() {} + TodoItem(const PURL::Url &_url, bool _generated) : url(_url), generated(_generated) {} + PURL::Url url; + bool generated; + }; + + class Data { + public: + Data() {} + Data(Tool::Category c, const QValueList &i, const QString &d, const Project *p, LinkType lt) + : category(c), items(i), device(d), project(p), linkType(lt) {} + Tool::Category category; + QValueList items; + QString device; + const Project *project; + LinkType linkType; + }; + + BEGIN_DECLARE_ENUM(DirectoryType) + Executable = 0, Header, LinkerScript, Library, Source + END_DECLARE_ENUM_STD(DirectoryType) + +} // namespace + +namespace Tool +{ + class Group; + + struct OutputExecutableTypeData { + const char *label, *key; + PURL::FileType type; + }; + BEGIN_DECLARE_ENUM(OutputExecutableType) + Coff = 0, Elf + END_DECLARE_ENUM(OutputExecutableType, OutputExecutableTypeData) + + BEGIN_DECLARE_ENUM(OutputType) + Executable = 0, Library + END_DECLARE_ENUM_STD(OutputType) + +//----------------------------------------------------------------------------- +class Base +{ +public: + virtual ~Base() {} + const Group &group() const { return *_group; } + virtual QString baseExecutable(bool withWine, OutputExecutableType type) const = 0; + PURL::Directory executableDirectory() const; + virtual bool checkExecutable() const { return true; } + virtual QStringList checkExecutableOptions(bool withWine) const = 0; + virtual PURL::Directory checkExecutableWorkingDirectory() const { return PURL::Directory(); } + virtual ::Process::LineOutput *checkExecutableProcess(const PURL::Directory &dir, bool withWine, OutputExecutableType type) const; + virtual bool checkExecutableResult(bool withWine, QStringList &lines) const = 0; + +protected: + Category _category; + const Group *_group; + + friend class Group; +}; + +} // namespace + +#endif diff --git a/src/tools/base/tool_group.cpp b/src/tools/base/tool_group.cpp new file mode 100644 index 0000000..fb347ce --- /dev/null +++ b/src/tools/base/tool_group.cpp @@ -0,0 +1,140 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "tool_group.h" + +#include "devices/list/device_list.h" +#include "devices/base/device_group.h" +#include "devices/base/generic_memory.h" +#include "common/global/process.h" +#include "tools/list/compile_config.h" +#include "tools/list/compile_process.h" +#include "libgui/project.h" + +//----------------------------------------------------------------------------- +const char *Tool::Group::CUSTOM_NAME = "custom"; + +Tool::Group::Group() + : _sourceGenerator(0), _checkDevicesError(true) +{} + +void Tool::Group::init() +{ + delete _sourceGenerator; + _sourceGenerator = sourceGeneratorFactory(); + FOR_EACH(Category, i) { + delete _bases[i].base; + _bases[i] = baseFactory(i); + if (_bases[i].base) { + _bases[i].base->_category = i; + _bases[i].base->_group = this; + } + } + ::Group::Base::init(); + _version = getToolchainVersion(); +} + +Compile::Process *Tool::Group::createCompileProcess(const Compile::Data &data, Compile::Manager *manager) const +{ + Compile::Process *p = processFactory(data); + if (p) p->init(data, manager); + return p; +} + +Compile::Config *Tool::Group::createConfig(::Project *project) const +{ + Compile::Config *c = configFactory(project); + if (c) c->_group = this; + return c; +} + +PURL::Directory Tool::Group::autodetectDirectory(Compile::DirectoryType, const PURL::Directory &, bool) const +{ + return PURL::Directory(); +} + +QString Tool::Group::defaultLinkerScriptFilename(Compile::LinkType type, const QString &device) const +{ + QString basename = device.lower(); + if ( type==Compile::Icd2Linking ) basename += 'i'; + return basename + '.' + PURL::extension(PURL::Lkr); +} + +bool Tool::Group::hasCustomLinkerScript(const ::Project *project) const +{ + return ( project && !project->customLinkerScript().isEmpty() ); +} + +PURL::Url Tool::Group::linkerScript(const ::Project *project, Compile::LinkType type) const +{ + if ( hasCustomLinkerScript(project) ) return project->customLinkerScript(); + QString filename = defaultLinkerScriptFilename(type, Compile::Config::device(project)); + return PURL::Url(Compile::Config::directory(*this, Compile::DirectoryType::LinkerScript), filename); +} + +::Process::LineOutput *Tool::Group::checkDevicesProcess(uint i, const PURL::Directory &dir, bool withWine) const +{ + ::Process::LineOutput *process = new ::Process::LineOutput; + Tool::Category cat = checkDevicesCategory(); + QString exec = base(cat)->baseExecutable(withWine, Compile::Config::outputExecutableType(*this)); + process->setup(dir.path() + exec, checkDevicesOptions(i), withWine); + return process; +} + +bool Tool::Group::checkExecutable(Tool::Category category, QStringList &lines) +{ + PURL::Directory dir = Compile::Config::directory(*this, Compile::DirectoryType::Executable); + bool withWine = Compile::Config::withWine(*this); + Tool::OutputExecutableType outputType = Compile::Config::outputExecutableType(*this); + ::Process::LineOutput * process = _bases[category].base->checkExecutableProcess(dir, withWine, outputType); + ::Process::State state = ::Process::runSynchronously(*process, ::Process::Start, 10000); + if ( state!=::Process::Exited ) return false; + lines = process->sout() + process->serr(); + return _bases[category].base->checkExecutableResult(withWine, lines); +} + +void Tool::Group::initSupported() +{ + _checkDevicesError = false; + Tool::Category cat = checkDevicesCategory(); + QValueList list; + if ( cat==Tool::Category::Nb_Types ) list = getSupportedDevices(QString::null); + else { + PURL::Directory dir = Compile::Config::directory(*this, Compile::DirectoryType::Executable); + for (uint i=0; isout() + process->serr(); + list += getSupportedDevices(lines.join("\n")); + } else _checkDevicesError = true; + delete process; + } + } + QValueList::const_iterator it; + for (it=list.begin(); it!=list.end(); ++it) addDevice((*it)->name(), *it, ::Group::Support::Tested); +} + +bool Tool::Group::check(const QString &device, Log::Generic *log) const +{ + const_cast(this)->checkInitSupported(); + if ( hasCheckDevicesError() ) + return (log ? log->askContinue(i18n("There were errors detecting supported devices for the selected toolchain (%1). Please check the toolchain configuration. Continue anyway?").arg(label())) : false); + if ( !device.isEmpty() && device!=Device::AUTO_DATA.name && !isSupported(device) ) + return (log ? log->askContinue(i18n("The selected toolchain (%1) does not support device %2. Continue anyway?").arg(label()).arg(device)) : false); + return true; +} + +bool Tool::Group::needs(bool withProject, Tool::Category category) const +{ + if ( _bases[category].base==0 ) return false; + if ( withProject && _bases[category].type==StandaloneOnly ) return false; + if ( !withProject && _bases[category].type==ProjectOnly ) return false; + return true; +} diff --git a/src/tools/base/tool_group.h b/src/tools/base/tool_group.h new file mode 100644 index 0000000..c4adb84 --- /dev/null +++ b/src/tools/base/tool_group.h @@ -0,0 +1,85 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef TOOL_GROUP_H +#define TOOL_GROUP_H + +#include "common/global/purl.h" +#include "common/common/group.h" +#include "common/common/version_data.h" +#include "generic_tool.h" +#include "coff/base/disassembler.h" +namespace Compile { class Manager; } + +namespace Tool +{ +enum CompileType { SeparateFiles, AllFiles, SingleFile }; +class SourceGenerator; + +//----------------------------------------------------------------------------- +class Group : public ::Group::Base +{ +public: + static const char *CUSTOM_NAME; + Group(); + bool isCustom() const { return ( name()==CUSTOM_NAME ); } + virtual QString comment() const { return QString::null; } + virtual void init(); + virtual const ::Tool::Base *base(Category category) const { return _bases[category].base; } + virtual QString informationText() const = 0; + virtual ExecutableType preferedExecutableType() const = 0; + virtual bool hasDirectory(Compile::DirectoryType) const { return false; } + virtual PURL::FileType linkerScriptType() const { return PURL::Nb_FileTypes; } + virtual PURL::Directory autodetectDirectory(Compile::DirectoryType type, const PURL::Directory &execDir, bool withWine) const; + virtual bool hasOutputExecutableType(Tool::OutputExecutableType type) const { return ( type==Tool::OutputExecutableType::Coff ); } + virtual uint nbCheckDevices() const { return 1; } + bool hasCheckDevicesError() const { return _checkDevicesError; } + virtual Tool::Category checkDevicesCategory() const = 0; + virtual QStringList checkDevicesOptions(uint) const { return QStringList(); } + ::Process::LineOutput *checkDevicesProcess(uint i, const PURL::Directory &execDir, bool withWine) const; + virtual QValueList getSupportedDevices(const QString &s) const = 0; + virtual CompileType compileType() const = 0; + virtual bool needs(bool withProject, Category category) const; + Compile::Process *createCompileProcess(const Compile::Data &data, Compile::Manager *manager) const; + Compile::Config *createConfig(::Project *project) const; + bool hasCustomLinkerScript(const ::Project *project) const; + virtual PURL::Url linkerScript(const ::Project *project, Compile::LinkType type) const; + virtual PURL::FileType implementationType(PURL::ToolType type) const = 0; + virtual Compile::Process *processFactory(const Compile::Data &data) const = 0; + const SourceGenerator *sourceGenerator() const { return _sourceGenerator; } + bool check(const QString &device, Log::Generic *log) const; + const VersionData &version() const { return _version; } + virtual bool generateDebugInformation(const QString &device) const { Q_UNUSED(device); return true; } + +protected: + enum NeedType { StandaloneOnly, ProjectOnly, Both }; + class BaseData { + public: + BaseData() : base(0), type(Both) {} + BaseData(::Tool::Base *b, NeedType t) : base(b), type(t) {} + ::Tool::Base *base; + NeedType type; + }; + virtual void initSupported(); + virtual BaseData baseFactory(Category category) const = 0; + virtual QString defaultLinkerScriptFilename(Compile::LinkType type, const QString &device) const; + virtual Compile::Config *configFactory(::Project *project) const = 0; + virtual SourceGenerator *sourceGeneratorFactory() const = 0; + bool checkExecutable(Tool::Category category, QStringList &lines); + virtual VersionData getToolchainVersion() { return VersionData(); } + +private: + SourceGenerator *_sourceGenerator; + QMap _bases; + bool _checkDevicesError; + VersionData _version; +}; + +} // namespace + +#endif diff --git a/src/tools/boost/Makefile.am b/src/tools/boost/Makefile.am new file mode 100644 index 0000000..725e078 --- /dev/null +++ b/src/tools/boost/Makefile.am @@ -0,0 +1,9 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libboost.la +libboost_la_SOURCES = boostc.cpp boostc_compile.cpp boost_config.cpp \ + boost.cpp boostcpp.cpp boostbasic.cpp boost_generator.cpp +libboost_la_LDFLAGS = $(all_libraries) + +SUBDIRS = gui \ No newline at end of file diff --git a/src/tools/boost/boost.cpp b/src/tools/boost/boost.cpp new file mode 100644 index 0000000..86e304c --- /dev/null +++ b/src/tools/boost/boost.cpp @@ -0,0 +1,102 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "boost.h" + +#include "boostc_compile.h" +#include "boost_config.h" +#include "devices/pic/pic/pic_memory.h" +#include "devices/list/device_list.h" +#include "devices/base/device_group.h" + +//---------------------------------------------------------------------------- +bool Boost::Linker::checkExecutableResult(bool, QStringList &lines) const +{ + return ( lines.count()>0 && lines[0].startsWith("BoostLink ") ); +} + +PURL::Directory Boost::Linker::checkExecutableWorkingDirectory() const +{ + return static_cast(_group)->checkExecutableUrl().directory(); +} + +QStringList Boost::Linker16::checkExecutableOptions(bool) const +{ + // #### otherwise may stall... + QStringList args; + args += "-t PIC16F873"; + args += static_cast(_group)->checkExecutableUrl().toExtension("obj").filename(); + return args; +} + +QStringList Boost::Linker18::checkExecutableOptions(bool) const +{ + // #### otherwise may stall... + QStringList args; + args += "-t PIC18F452"; + args += static_cast(_group)->checkExecutableUrl().toExtension("obj").filename(); + return args; +} + +//---------------------------------------------------------------------------- +QStringList Boost::Compiler::checkExecutableOptions(bool) const +{ + // #### otherwise may stall... + return static_cast(_group)->checkExecutableUrl().filename(); +} + +PURL::Directory Boost::Compiler::checkExecutableWorkingDirectory() const +{ + return static_cast(_group)->checkExecutableUrl().directory(); +} + +//---------------------------------------------------------------------------- +Boost::Group::Group(const QString &extension, const QString &text) + : _checkExecTmp(_sview, extension) +{ + if ( _checkExecTmp.openForWrite() ) _checkExecTmp.appendText(text); + _checkExecTmp.close(); +} + +QString Boost::Group::comment() const +{ + return i18n("The Boost toolchain needs to be run by Wine with \"Windows NT 4.0\" compatibility. This can be configured with the Wine configuration utility."); +} + +PURL::Directory Boost::Group::autodetectDirectory(Compile::DirectoryType type, const PURL::Directory &execDir, bool) const +{ + if ( type==Compile::DirectoryType::Library ) return execDir.path() + "Lib"; + return PURL::Directory(); +} + +Compile::Process *Boost::Group::processFactory(const Compile::Data &data) const +{ + switch (data.category.type()) { + case Tool::Category::Compiler: return new Boost::CompileFile; + case Tool::Category::Linker: return new Boost::Link; + default: break; + } + Q_ASSERT(false); + return 0; +} + +Compile::Config *Boost::Group::configFactory(::Project *project) const +{ + return new Boost::Config(project); +} + +QValueList Boost::Group::getSupportedDevices(const QString &) const +{ + QValueList list; + QValueVector devices = Device::lister().group("pic")->supportedDevices(); + for (uint i=0; i(data)->architecture()) ) list.append(data); + } + return list; +} diff --git a/src/tools/boost/boost.h b/src/tools/boost/boost.h new file mode 100644 index 0000000..d6142c9 --- /dev/null +++ b/src/tools/boost/boost.h @@ -0,0 +1,74 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef BOOST_H +#define BOOST_H + +#include "tools/base/tool_group.h" +#include "common/gui/pfile_ext.h" +#include "devices/pic/base/pic.h" + +namespace Boost +{ +//---------------------------------------------------------------------------- +class Linker : public Tool::Base +{ +private: + virtual QString baseExecutable(bool, Tool::OutputExecutableType) const { return "boostlink.pic.exe"; } + virtual bool checkExecutableResult(bool withWine, QStringList &lines) const; + virtual PURL::Directory checkExecutableWorkingDirectory() const; +}; + +class Linker16 : public Linker +{ +private: + virtual QStringList checkExecutableOptions(bool withWine) const; +}; + +class Linker18 : public Linker +{ +private: + virtual QStringList checkExecutableOptions(bool withWine) const; +}; + +//---------------------------------------------------------------------------- +class Compiler : public Tool::Base +{ +private: + virtual QStringList checkExecutableOptions(bool withWine) const; + virtual PURL::Directory checkExecutableWorkingDirectory() const; +}; + +//---------------------------------------------------------------------------- +class Group : public Tool::Group +{ +public: + Group(const QString &extension, const QString &text); + PURL::Url checkExecutableUrl() const { return _checkExecTmp.url(); } + virtual QString comment() const; + virtual Tool::Category checkDevicesCategory() const { return Tool::Category::Nb_Types; } + virtual Tool::ExecutableType preferedExecutableType() const { return Tool::ExecutableType::Windows; } + virtual Tool::CompileType compileType() const { return Tool::SeparateFiles; } + virtual bool hasDirectory(Compile::DirectoryType type) const { return type==Compile::DirectoryType::Library; } + virtual PURL::Directory autodetectDirectory(Compile::DirectoryType type, const PURL::Directory &execDir, bool withWine) const; + +protected: + virtual bool supportedArchitecture(Pic::Architecture architecture) const = 0; + +private: + Log::StringView _sview; + PURL::TempFile _checkExecTmp; + + virtual QValueList getSupportedDevices(const QString &s) const; + virtual Compile::Process *processFactory(const Compile::Data &data) const; + virtual Compile::Config *configFactory(::Project *project) const; +}; + +} // namespace + +#endif diff --git a/src/tools/boost/boost_config.cpp b/src/tools/boost/boost_config.cpp new file mode 100644 index 0000000..b64f0af --- /dev/null +++ b/src/tools/boost/boost_config.cpp @@ -0,0 +1,9 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "boost_config.h" diff --git a/src/tools/boost/boost_config.h b/src/tools/boost/boost_config.h new file mode 100644 index 0000000..c8b540e --- /dev/null +++ b/src/tools/boost/boost_config.h @@ -0,0 +1,24 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef BOOST_CONFIG_H +#define BOOST_CONFIG_H + +#include "tools/list/compile_config.h" + +namespace Boost +{ +class Config : public Compile::Config +{ +public: + Config(Project *project) : Compile::Config(project) {} +}; + +} // namespace + +#endif diff --git a/src/tools/boost/boost_generator.cpp b/src/tools/boost/boost_generator.cpp new file mode 100644 index 0000000..2fa1393 --- /dev/null +++ b/src/tools/boost/boost_generator.cpp @@ -0,0 +1,81 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "boost_generator.h" + +#include "devices/pic/pic/pic_memory.h" + +//--------------------------------------------------------------------------- +SourceLine::List Boost::CSourceGenerator::configLines(PURL::ToolType, const Device::Memory &memory, bool &ok) const +{ + const Pic::Memory &pmemory = static_cast(memory); + const Pic::Data &data = pmemory.device(); + const Pic::Config &config = data.config(); + SourceLine::List lines; + Address address = data.range(Pic::MemoryRangeType::Config).start; + for (uint i=0; i"); + return lines; +} + +SourceLine::List Boost::CSourceGenerator::sourceFileContent(PURL::ToolType, const Device::Data &, bool &) const +{ + SourceLine::List lines; + lines.appendTitle(i18n("interrupt service routine")); + lines.appendNotIndentedCode("void interrupt(void) {"); + lines.appendIndentedCode(QString::null, "<< " + i18n("insert interrupt code") + " >>"); + lines.appendNotIndentedCode("}"); + lines.appendEmpty(); + lines.appendTitle(i18n("main program")); + lines.appendNotIndentedCode("void main() {"); + lines.appendIndentedCode(QString::null, "<< " + i18n("insert code") + " >>"); + lines.appendNotIndentedCode("}"); + return lines; +} + +//--------------------------------------------------------------------------- +SourceLine::List Boost::BasicSourceGenerator::configLines(PURL::ToolType, const Device::Memory &, bool &ok) const +{ + // config bits ? + ok = false; + return SourceLine::List(); +} + +SourceLine::List Boost::BasicSourceGenerator::includeLines(PURL::ToolType, const Device::Data &) const +{ + return SourceLine::List(); +} + +SourceLine::List Boost::BasicSourceGenerator::sourceFileContent(PURL::ToolType, const Device::Data &, bool &ok) const +{ + SourceLine::List lines; + ok = true; + lines.appendTitle(i18n("main program")); + lines.appendNotIndentedCode("Sub main()"); + lines.appendIndentedCode(QString::null, "<< " + i18n("insert code") + " >>"); + lines.appendIndentedCode("Do while 1", i18n("loop forever")); + lines.appendIndentedCode("Loop"); + lines.appendNotIndentedCode("End Sub"); + return lines; +} diff --git a/src/tools/boost/boost_generator.h b/src/tools/boost/boost_generator.h new file mode 100644 index 0000000..0986ee1 --- /dev/null +++ b/src/tools/boost/boost_generator.h @@ -0,0 +1,37 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef BOOST_GENERATOR_H +#define BOOST_GENERATOR_H + +#include "tools/base/tool_group.h" + +namespace Boost +{ + +//--------------------------------------------------------------------------- +class CSourceGenerator : public Tool::SourceGenerator +{ +public: + virtual SourceLine::List configLines(PURL::ToolType type, const Device::Memory &memory, bool &ok) const; + virtual SourceLine::List sourceFileContent(PURL::ToolType type, const Device::Data &data, bool &ok) const; + virtual SourceLine::List includeLines(PURL::ToolType type, const Device::Data &data) const; +}; + +//--------------------------------------------------------------------------- +class BasicSourceGenerator : public Tool::SourceGenerator +{ +public: + virtual SourceLine::List configLines(PURL::ToolType type, const Device::Memory &memory, bool &ok) const; + virtual SourceLine::List sourceFileContent(PURL::ToolType type, const Device::Data &data, bool &ok) const; + virtual SourceLine::List includeLines(PURL::ToolType type, const Device::Data &data) const; +}; + +} // namespace + +#endif diff --git a/src/tools/boost/boostbasic.cpp b/src/tools/boost/boostbasic.cpp new file mode 100644 index 0000000..9983874 --- /dev/null +++ b/src/tools/boost/boostbasic.cpp @@ -0,0 +1,42 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "boostbasic.h" + +#include "boost_generator.h" + +//---------------------------------------------------------------------------- +bool Boost::CompilerBasic::checkExecutableResult(bool, QStringList &lines) const +{ + return ( lines.count()>0 && lines[0].startsWith("BoostBasic ") ); +} + +//---------------------------------------------------------------------------- +QString Boost::GroupBasic::informationText() const +{ + return i18n("BoostBasic Compiler is a Basic compiler distributed by SourceBoost Technologies.").arg("http://www.sourceboost.com/Products/BoostBasic/Overview.html"); +} + +Tool::SourceGenerator *Boost::GroupBasic::sourceGeneratorFactory() const +{ + return new BasicSourceGenerator; +} + +Tool::Group::BaseData Boost::GroupBasic16::baseFactory(Tool::Category category) const +{ + if ( category==Tool::Category::Compiler ) return BaseData(new Boost::CompilerBasic16, Both); + if ( category==Tool::Category::Linker ) return BaseData(new Boost::Linker16, Both); + return BaseData(); +} + +Tool::Group::BaseData Boost::GroupBasic18::baseFactory(Tool::Category category) const +{ + if ( category==Tool::Category::Linker ) return BaseData(new Boost::Linker18, Both); + if ( category==Tool::Category::Compiler ) return BaseData(new Boost::CompilerBasic18, Both); + return BaseData(); +} diff --git a/src/tools/boost/boostbasic.h b/src/tools/boost/boostbasic.h new file mode 100644 index 0000000..5f3b820 --- /dev/null +++ b/src/tools/boost/boostbasic.h @@ -0,0 +1,72 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef BOOSTBASIC_H +#define BOOSTBASIC_H + +#include "boost.h" + +namespace Boost +{ +//---------------------------------------------------------------------------- +class CompilerBasic : public Compiler +{ +private: + virtual bool checkExecutableResult(bool withWine, QStringList &lines) const; +}; + +class CompilerBasic16 : public CompilerBasic +{ +public: + virtual QString baseExecutable(bool, Tool::OutputExecutableType) const { return "boostbasic.pic16.exe"; } +}; + +class CompilerBasic18 : public CompilerBasic +{ +public: + virtual QString baseExecutable(bool, Tool::OutputExecutableType) const { return "boostbasic.pic18.exe"; } +}; + +//---------------------------------------------------------------------------- +class GroupBasic : public Group +{ +public: + GroupBasic() : Group(".bas", "Sub main()\nEnd Sub\n") {} + virtual QString informationText() const; + virtual PURL::FileType implementationType(PURL::ToolType type) const { return (type==PURL::ToolType::Compiler ? PURL::BasicSource : PURL::Nb_FileTypes); } + +private: + virtual Tool::SourceGenerator *sourceGeneratorFactory() const; +}; + +class GroupBasic16 : public GroupBasic +{ +public: + virtual QString name() const { return "boostbasic16"; } + virtual QString label() const { return i18n("BoostBasic Compiler for PIC16"); } + +private: + virtual BaseData baseFactory(Tool::Category) const; + virtual bool supportedArchitecture(Pic::Architecture architecture) const { return ( architecture==Pic::Architecture::P16X ); } +}; + +class GroupBasic18 : public GroupBasic +{ +public: + virtual QString name() const { return "boostbasic18"; } + virtual QString label() const { return i18n("BoostBasic Compiler for PIC18"); } + +private: + virtual BaseData baseFactory(Tool::Category) const; + virtual bool supportedArchitecture(Pic::Architecture architecture) const + { return ( architecture==Pic::Architecture::P18C || architecture==Pic::Architecture::P18F || architecture==Pic::Architecture::P18J ); } +}; + +} // namespace + +#endif diff --git a/src/tools/boost/boostc.cpp b/src/tools/boost/boostc.cpp new file mode 100644 index 0000000..9a6ada9 --- /dev/null +++ b/src/tools/boost/boostc.cpp @@ -0,0 +1,42 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "boostc.h" + +#include "boost_generator.h" + +//---------------------------------------------------------------------------- +bool Boost::CompilerC::checkExecutableResult(bool, QStringList &lines) const +{ + return ( lines.count()>0 && lines[0].startsWith("BoostC ") ); +} + +//---------------------------------------------------------------------------- +QString Boost::GroupC::informationText() const +{ + return i18n("BoostC Compiler is a C compiler distributed by SourceBoost Technologies.").arg("http://www.sourceboost.com/Products/BoostC/Overview.html"); +} + +Tool::SourceGenerator *Boost::GroupC::sourceGeneratorFactory() const +{ + return new CSourceGenerator; +} + +Tool::Group::BaseData Boost::GroupC16::baseFactory(Tool::Category category) const +{ + if ( category==Tool::Category::Compiler ) return BaseData(new Boost::CompilerC16, Both); + if ( category==Tool::Category::Linker ) return BaseData(new Boost::Linker16, Both); + return BaseData(); +} + +Tool::Group::BaseData Boost::GroupC18::baseFactory(Tool::Category category) const +{ + if ( category==Tool::Category::Compiler ) return BaseData(new Boost::CompilerC18, Both); + if ( category==Tool::Category::Linker ) return BaseData(new Boost::Linker18, Both); + return BaseData(); +} diff --git a/src/tools/boost/boostc.h b/src/tools/boost/boostc.h new file mode 100644 index 0000000..5191560 --- /dev/null +++ b/src/tools/boost/boostc.h @@ -0,0 +1,72 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef BOOSTC_H +#define BOOSTC_H + +#include "boost.h" + +namespace Boost +{ +//---------------------------------------------------------------------------- +class CompilerC : public Compiler +{ +private: + virtual bool checkExecutableResult(bool withWine, QStringList &lines) const; +}; + +class CompilerC16 : public CompilerC +{ +public: + virtual QString baseExecutable(bool, Tool::OutputExecutableType) const { return "boostc.pic16.exe"; } +}; + +class CompilerC18 : public CompilerC +{ +public: + virtual QString baseExecutable(bool, Tool::OutputExecutableType) const { return "boostc.pic18.exe"; } +}; + +//---------------------------------------------------------------------------- +class GroupC : public Group +{ +public: + GroupC() : Group(".c", "void main(void) {}\n") {} + virtual QString informationText() const; + virtual PURL::FileType implementationType(PURL::ToolType type) const { return (type==PURL::ToolType::Compiler ? PURL::CSource : PURL::Nb_FileTypes); } + +private: + virtual Tool::SourceGenerator *sourceGeneratorFactory() const; +}; + +class GroupC16 : public GroupC +{ +public: + virtual QString name() const { return "boostc16"; } + virtual QString label() const { return i18n("BoostC Compiler for PIC16"); } + +private: + virtual BaseData baseFactory(Tool::Category) const; + virtual bool supportedArchitecture(Pic::Architecture architecture) const { return ( architecture==Pic::Architecture::P16X ); } +}; + +class GroupC18 : public GroupC +{ +public: + virtual QString name() const { return "boostc18"; } + virtual QString label() const { return i18n("BoostC Compiler for PIC18"); } + +private: + virtual BaseData baseFactory(Tool::Category) const; + virtual bool supportedArchitecture(Pic::Architecture architecture) const + { return ( architecture==Pic::Architecture::P18C || architecture==Pic::Architecture::P18F || architecture==Pic::Architecture::P18J ); } +}; + +} // namespace + +#endif diff --git a/src/tools/boost/boostc_compile.cpp b/src/tools/boost/boostc_compile.cpp new file mode 100644 index 0000000..2298361 --- /dev/null +++ b/src/tools/boost/boostc_compile.cpp @@ -0,0 +1,56 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "boostc_compile.h" + +#include "boost_config.h" + +//---------------------------------------------------------------------------- +void Boost::Process::logStderrLine(const QString &line) +{ + if ( parseErrorLine(line, Compile::ParseErrorData("(.*)\\((\\d+).*\\): (error|warning):(.*)", 1, 2, 4, 3)) ) return; + doLog(Log::LineType::Normal, line, QString::null, 0); +} + +//---------------------------------------------------------------------------- +QStringList Boost::CompileFile::genericArguments(const Compile::Config &config) const +{ + QStringList args; + args += "-t %DEVICE"; + args += "-i"; + args += config.includeDirs(Tool::Category::Compiler, "-I", QString::null, ";"); + args += config.customOptions(Tool::Category::Compiler); + args += "%I"; + return args; +} + +QString Boost::CompileFile::outputFiles() const +{ + return "obj"; +} + +//---------------------------------------------------------------------------- +QStringList Boost::Link::genericArguments(const Compile::Config &config) const +{ + QStringList args; + args += "-t %DEVICE"; + args += "-p"; + args += "%PROJECT"; + args += config.includeDirs(Tool::Category::Linker, "-ld%SEP"); + PURL::Directory dir = Compile::Config::directory(group(), Compile::DirectoryType::Library); + if ( !dir.isEmpty() ) args += "-ld%SEP" + dir.path(); + args += config.customOptions(Tool::Category::Linker); + args += "%OBJS"; + return args; +} + +QString Boost::Link::outputFiles() const +{ + return "PURL::Lst PURL::Hex PURL::Coff PURL::AsmGPAsm stat tree casm"; +} + diff --git a/src/tools/boost/boostc_compile.h b/src/tools/boost/boostc_compile.h new file mode 100644 index 0000000..5c3696a --- /dev/null +++ b/src/tools/boost/boostc_compile.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef BOOSTC_COMPILE_H +#define BOOSTC_COMPILE_H + +#include "tools/list/compile_process.h" + +namespace Boost +{ +//---------------------------------------------------------------------------- +class Process : public Compile::Process +{ +Q_OBJECT +protected: + virtual QString deviceName() const { return "PIC" + _data.device; } + virtual void logStderrLine(const QString &line); +}; + +//---------------------------------------------------------------------------- +class CompileFile : public Process +{ +Q_OBJECT +protected: + virtual QStringList genericArguments(const Compile::Config &config) const; + virtual QString outputFiles() const; +}; + +//---------------------------------------------------------------------------- +class Link : public Process +{ +Q_OBJECT +protected: + virtual QString objectExtension() const { return "obj"; } + virtual QStringList genericArguments(const Compile::Config &config) const; + virtual QString outputFiles() const; +}; + +} // namespace + +#endif diff --git a/src/tools/boost/boostcpp.cpp b/src/tools/boost/boostcpp.cpp new file mode 100644 index 0000000..8991de7 --- /dev/null +++ b/src/tools/boost/boostcpp.cpp @@ -0,0 +1,43 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "boostcpp.h" + +#include "boostc.h" +#include "boost_generator.h" + +//---------------------------------------------------------------------------- +bool Boost::CompilerCpp::checkExecutableResult(bool, QStringList &lines) const +{ + return ( lines.count()>0 && lines[0].startsWith("BoostC++ ") ); +} + +//---------------------------------------------------------------------------- +QString Boost::GroupCpp::informationText() const +{ + return i18n("BoostC++ Compiler is a C compiler distributed by SourceBoost Technologies.").arg("http://www.sourceboost.com/Products/BoostCpp/Overview.html"); +} + +Tool::SourceGenerator *Boost::GroupCpp::sourceGeneratorFactory() const +{ + return new CSourceGenerator; +} + +Tool::Group::BaseData Boost::GroupCpp16::baseFactory(Tool::Category category) const +{ + if ( category==Tool::Category::Compiler ) return BaseData(new Boost::CompilerCpp16, Both); + if ( category==Tool::Category::Linker ) return BaseData(new Boost::Linker16, Both); + return BaseData(); +} + +Tool::Group::BaseData Boost::GroupCpp18::baseFactory(Tool::Category category) const +{ + if ( category==Tool::Category::Compiler ) return BaseData(new Boost::CompilerCpp18, Both); + if ( category==Tool::Category::Linker ) return BaseData(new Boost::Linker18, Both); + return BaseData(); +} diff --git a/src/tools/boost/boostcpp.h b/src/tools/boost/boostcpp.h new file mode 100644 index 0000000..bf5e2ee --- /dev/null +++ b/src/tools/boost/boostcpp.h @@ -0,0 +1,71 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef BOOSTCPP_H +#define BOOSTCPP_H + +#include "boost.h" + +namespace Boost +{ +//---------------------------------------------------------------------------- +class CompilerCpp : public Compiler +{ +private: + virtual bool checkExecutableResult(bool withWine, QStringList &lines) const; +}; + +class CompilerCpp16 : public CompilerCpp +{ +public: + virtual QString baseExecutable(bool, Tool::OutputExecutableType) const { return "boostc++.pic16.exe"; } +}; + +class CompilerCpp18 : public CompilerCpp +{ +public: + virtual QString baseExecutable(bool, Tool::OutputExecutableType) const { return "boostc++.pic18.exe"; } +}; + +//---------------------------------------------------------------------------- +class GroupCpp : public Group +{ +public: + GroupCpp() : Group(".cpp", "void main(void) {}\n") {} + virtual QString informationText() const; + virtual PURL::FileType implementationType(PURL::ToolType type) const { return (type==PURL::ToolType::Compiler ? PURL::CppSource : PURL::Nb_FileTypes); } + +private: + virtual Tool::SourceGenerator *sourceGeneratorFactory() const; +}; + +class GroupCpp16 : public GroupCpp +{ +public: + virtual QString name() const { return "boostc++16"; } + virtual QString label() const { return i18n("BoostC++ Compiler for PIC16"); } + +private: + virtual BaseData baseFactory(Tool::Category) const; + virtual bool supportedArchitecture(Pic::Architecture architecture) const { return ( architecture==Pic::Architecture::P16X ); } +}; + +class GroupCpp18 : public GroupCpp +{ +public: + virtual QString name() const { return "boostc++18"; } + virtual QString label() const { return i18n("BoostC++ Compiler for PIC18"); } + +private: + virtual BaseData baseFactory(Tool::Category) const; + virtual bool supportedArchitecture(Pic::Architecture architecture) const + { return ( architecture==Pic::Architecture::P18C || architecture==Pic::Architecture::P18F || architecture==Pic::Architecture::P18J ); } +}; +} // namespace + +#endif diff --git a/src/tools/boost/gui/Makefile.am b/src/tools/boost/gui/Makefile.am new file mode 100644 index 0000000..94fda00 --- /dev/null +++ b/src/tools/boost/gui/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libboostui.la +libboostui_la_SOURCES = boost_ui.cpp +libboostui_la_LDFLAGS = $(all_libraries) diff --git a/src/tools/boost/gui/boost_ui.cpp b/src/tools/boost/gui/boost_ui.cpp new file mode 100644 index 0000000..2357165 --- /dev/null +++ b/src/tools/boost/gui/boost_ui.cpp @@ -0,0 +1,19 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "boost_ui.h" + +//---------------------------------------------------------------------------- +Boost::ConfigWidget::ConfigWidget(Project *project) + : ToolConfigWidget(project) +{} + +void Boost::ConfigWidget::initEntries() +{ + createIncludeDirectoriesEntry(); +} diff --git a/src/tools/boost/gui/boost_ui.h b/src/tools/boost/gui/boost_ui.h new file mode 100644 index 0000000..6cafcf6 --- /dev/null +++ b/src/tools/boost/gui/boost_ui.h @@ -0,0 +1,35 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef BOOST_UI_H +#define BOOST_UI_H + +#include "tools/gui/tool_config_widget.h" +#include "tools/gui/tool_group_ui.h" + +namespace Boost +{ +//---------------------------------------------------------------------------- +class ConfigWidget : public ToolConfigWidget +{ +Q_OBJECT +public: + ConfigWidget(Project *project); + virtual void initEntries(); +}; + +//---------------------------------------------------------------------------- +class GroupUI : public Tool::GroupUI +{ +public: + virtual ToolConfigWidget *configWidgetFactory(Tool::Category, ::Project *project) const { return new ConfigWidget(project); } +}; + +} // namespace + +#endif diff --git a/src/tools/c18/Makefile.am b/src/tools/c18/Makefile.am new file mode 100644 index 0000000..032e53a --- /dev/null +++ b/src/tools/c18/Makefile.am @@ -0,0 +1,8 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +libc18_la_LDFLAGS = $(all_libraries) +noinst_LTLIBRARIES = libc18.la +libc18_la_SOURCES = c18_compile.cpp c18_config.cpp c18.cpp + +SUBDIRS = gui \ No newline at end of file diff --git a/src/tools/c18/c18.cpp b/src/tools/c18/c18.cpp new file mode 100644 index 0000000..4eb5bfd --- /dev/null +++ b/src/tools/c18/c18.cpp @@ -0,0 +1,86 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "c18.h" + +#include + +#include "c18_compile.h" +#include "c18_config.h" +#include "devices/pic/pic/pic_memory.h" +#include "devices/list/device_list.h" +#include "devices/pic/pic/pic_group.h" +#include "common/global/process.h" + +//---------------------------------------------------------------------------- +bool C18::Compiler::checkExecutableResult(bool, QStringList &lines) const +{ + return ( lines.count()>0 && lines[0].startsWith("MPLAB C18") ); +} + +bool C18::Linker::checkExecutableResult(bool, QStringList &lines) const +{ + return ( lines.count()>0 && lines[0].startsWith("MPLINK") ); +} + +//---------------------------------------------------------------------------- +QValueList C18::Group::getSupportedDevices(const QString &) const +{ + QValueVector devices = Device::lister().group("pic")->supportedDevices(); + QValueList list; + for (uint i=0; i(data)->is18Family() ) list.append(data); + } + return list; +} + +Compile::Process *C18::Group::processFactory(const Compile::Data &data) const +{ + if ( data.category==Tool::Category::Compiler ) return new CompileFile; + Q_ASSERT( data.category==Tool::Category::Linker ); + return new Link; +} + +PURL::Directory C18::Group::autodetectDirectory(Compile::DirectoryType type, const PURL::Directory &execDir, bool) const +{ + QDir dir(execDir.path()); + if ( !dir.cdUp() ) return PURL::Directory(); + switch (type.type()) { + case Compile::DirectoryType::LinkerScript: + if ( dir.cd("lkr") ) return dir.path(); + break; + case Compile::DirectoryType::Header: + if ( dir.cd("h") ) return dir.path(); + break; + case Compile::DirectoryType::Library: + if ( dir.cd("lib") ) return dir.path(); + break; + case Compile::DirectoryType::Executable: + case Compile::DirectoryType::Source: + case Compile::DirectoryType::Nb_Types: Q_ASSERT(false); break; + } + return PURL::Directory(); +} + +Compile::Config *C18::Group::configFactory(::Project *project) const +{ + return new Config(project); +} + +Tool::Group::BaseData C18::Group::baseFactory(Tool::Category category) const +{ + if ( category==Tool::Category::Compiler ) return BaseData(new Compiler, Both); + if ( category==Tool::Category::Linker ) return BaseData(new Linker, Both); + return BaseData(); +} + +QString C18::Group::informationText() const +{ + return i18n("C18 is a C compiler distributed by Microchip.").arg("http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en010014&part=SW006011"); +} diff --git a/src/tools/c18/c18.h b/src/tools/c18/c18.h new file mode 100644 index 0000000..fac739e --- /dev/null +++ b/src/tools/c18/c18.h @@ -0,0 +1,62 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef C18_H +#define C18_H + +#include "tools/base/tool_group.h" + +namespace C18 +{ +//---------------------------------------------------------------------------- +class Compiler : public Tool::Base +{ +public: + virtual QString baseExecutable(bool, Tool::OutputExecutableType) const { return "mcc18"; } + +private: + virtual QStringList checkExecutableOptions(bool) const { return "-v"; } + virtual bool checkExecutableResult(bool withWine, QStringList &lines) const; +}; + +class Linker : public Tool::Base +{ +public: + virtual QString baseExecutable(bool, Tool::OutputExecutableType) const { return "mplink"; } + +private: + virtual QStringList checkExecutableOptions(bool) const { return "/v"; } + virtual bool checkExecutableResult(bool withWine, QStringList &lines) const; +}; + +//---------------------------------------------------------------------------- +class Group : public Tool::Group +{ +public: + virtual QString name() const { return "c18"; } + virtual QString label() const { return i18n("C18 Compiler"); } + virtual QString informationText() const; + virtual Tool::Category checkDevicesCategory() const { return Tool::Category::Nb_Types; } + virtual bool hasDirectory(Compile::DirectoryType type) const { return ( type!=Compile::DirectoryType::Source ); } + virtual PURL::FileType linkerScriptType() const { return PURL::Lkr; } + virtual Tool::ExecutableType preferedExecutableType() const { return Tool::ExecutableType::Windows; } + virtual Tool::CompileType compileType() const { return Tool::SeparateFiles; } + virtual PURL::Directory autodetectDirectory(Compile::DirectoryType type, const PURL::Directory &execDir, bool withWine) const; + virtual PURL::FileType implementationType(PURL::ToolType type) const { return (type==PURL::ToolType::Compiler ? PURL::CSource : PURL::Nb_FileTypes); } + +private: + virtual QValueList getSupportedDevices(const QString &s) const; + virtual Compile::Process *processFactory(const Compile::Data &data) const; + virtual Compile::Config *configFactory(::Project *project) const; + virtual BaseData baseFactory(Tool::Category category) const; + virtual Tool::SourceGenerator *sourceGeneratorFactory() const { /*TODO*/ return 0; } +}; + +} // namespace + +#endif diff --git a/src/tools/c18/c18_compile.cpp b/src/tools/c18/c18_compile.cpp new file mode 100644 index 0000000..181da36 --- /dev/null +++ b/src/tools/c18/c18_compile.cpp @@ -0,0 +1,65 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "c18_compile.h" + +#include "c18_config.h" +#include "c18.h" +#include "devices/list/device_list.h" + +//----------------------------------------------------------------------------- +QStringList C18::CompileFile::genericArguments(const Compile::Config &config) const +{ + QStringList args; + args += config.includeDirs(Tool::Category::Compiler, "-I"); + args += "-I" + Compile::Config::directory(group(), Compile::DirectoryType::Header).path(); + args += "$NO_AUTO_DEVICE(-p)"; + args += "$NO_AUTO_DEVICE(%DEVICE)"; + args += config.customOptions(Tool::Category::Compiler); + args += "-fo=%OBJECT"; + args += "%I"; + return args; +} + +QString C18::CompileFile::outputFiles() const +{ + return "PURL::Object"; +} + +void C18::CompileFile::logStderrLine(const QString &line) +{ + // #### TODO + doLog(Log::LineType::Normal, line, QString::null, 0); +} + +//----------------------------------------------------------------------------- +QStringList C18::Link::genericArguments(const Compile::Config &config) const +{ + QStringList args; + args += "/k%LKR_PATH"; + args += "%LKR_NAME"; + args += "/l" + Compile::Config::directory(group(), Compile::DirectoryType::Library).path(); + args += config.customOptions(Tool::Category::Linker); + args += "/o%COFF"; + args += "/m%MAP"; + args += "%OBJS"; + args += "%LIBS"; + args += config.customLibraries(Tool::Category::Linker); + return args; +} + +QString C18::Link::outputFiles() const +{ + return "PURL::Lkr PURL::Map PURL::Hex PURL::Coff PURL::Lst PURL::Cod"; +} + +void C18::Link::logStderrLine(const QString &line) +{ + // #### TODO + doLog(Log::LineType::Normal, line, QString::null, 0); +} diff --git a/src/tools/c18/c18_compile.h b/src/tools/c18/c18_compile.h new file mode 100644 index 0000000..74f0f06 --- /dev/null +++ b/src/tools/c18/c18_compile.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef C18_COMPILE_H +#define C18_COMPILE_H + +#include "tools/list/compile_process.h" + +namespace C18 +{ +//----------------------------------------------------------------------------- +class Process : public Compile::Process +{ +Q_OBJECT +protected: + virtual QString deviceName() const { return _data.device.lower(); } +}; + +//----------------------------------------------------------------------------- +class CompileFile : public Process +{ +Q_OBJECT +protected: + virtual QStringList genericArguments(const Compile::Config &config) const; + virtual QString outputFiles() const; + virtual void logStderrLine(const QString &line); +}; + +//----------------------------------------------------------------------------- +class Link : public Process +{ +Q_OBJECT +protected: + virtual QStringList genericArguments(const Compile::Config &config) const; + virtual QString outputFiles() const; + virtual void logStderrLine(const QString &line); +}; + +} // namespace + +#endif diff --git a/src/tools/c18/c18_config.cpp b/src/tools/c18/c18_config.cpp new file mode 100644 index 0000000..fdf6164 --- /dev/null +++ b/src/tools/c18/c18_config.cpp @@ -0,0 +1,13 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "c18_config.h" + +const char * const C18::Config::WARNING_LEVEL_LABELS[Nb_WarningLevels] = { + I18N_NOOP("All messages"), I18N_NOOP("Warning and errors"), I18N_NOOP("Errors only") +}; diff --git a/src/tools/c18/c18_config.h b/src/tools/c18/c18_config.h new file mode 100644 index 0000000..dead1a1 --- /dev/null +++ b/src/tools/c18/c18_config.h @@ -0,0 +1,29 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef C18_CONFIG_H +#define C18_CONFIG_H + +#include "tools/list/compile_config.h" + +namespace C18 +{ + +class Config : public Compile::Config +{ +public: + Config(Project *project) : Compile::Config(project) {} + enum { Nb_WarningLevels = 3 }; + static const char * const WARNING_LEVEL_LABELS[Nb_WarningLevels]; + uint warningLevel() const { return QMIN(Compile::Config::warningLevel(Tool::Category::Compiler), uint(Nb_WarningLevels)); } + void setWarningLevel(uint level) { Compile::Config::setWarningLevel(Tool::Category::Compiler, level); } +}; + +} // namespace + +#endif diff --git a/src/tools/c18/gui/Makefile.am b/src/tools/c18/gui/Makefile.am new file mode 100644 index 0000000..3e97599 --- /dev/null +++ b/src/tools/c18/gui/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libc18ui.la +libc18ui_la_LDFLAGS = $(all_libraries) +libc18ui_la_SOURCES = c18_ui.cpp diff --git a/src/tools/c18/gui/c18_ui.cpp b/src/tools/c18/gui/c18_ui.cpp new file mode 100644 index 0000000..c10f328 --- /dev/null +++ b/src/tools/c18/gui/c18_ui.cpp @@ -0,0 +1,50 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "c18_ui.h" + +#include +#include "tools/c18/c18_config.h" + +//---------------------------------------------------------------------------- +C18::ConfigWidget::ConfigWidget(Project *project) + : ToolConfigWidget(project), _warningLevel(0) +{} + +void C18::ConfigWidget::initEntries() +{ + if ( _category==Tool::Category::Compiler ) { + uint row = container()->numRows(); + QLabel *label = new QLabel(i18n("Warning level:"), container()); + container()->addWidget(label, row,row, 0,0); + _warningLevel = new QComboBox(container()); + connect(_warningLevel, SIGNAL(activated(int)), SIGNAL(changed())); + for (uint i=0; iinsertItem(i18n(Config::WARNING_LEVEL_LABELS[i])); + container()->addWidget(_warningLevel, row,row, 1,1); + createIncludeDirectoriesEntry(); + } + if ( _category==Tool::Category::Linker ) { + createCustomLibrariesEntry(); + createHexFormatEntry(); + } +} + +void C18::ConfigWidget::loadConfig(const Compile::Config &config) +{ + ToolConfigWidget::loadConfig(config); + if ( _category==Tool::Category::Compiler ) + _warningLevel->setCurrentItem(static_cast(config).warningLevel()); +} + +void C18::ConfigWidget::saveConfig(Compile::Config &config) const +{ + ToolConfigWidget::saveConfig(config); + if ( _category==Tool::Category::Compiler ) + static_cast(config).setWarningLevel(_warningLevel->currentItem()); +} diff --git a/src/tools/c18/gui/c18_ui.h b/src/tools/c18/gui/c18_ui.h new file mode 100644 index 0000000..d7d45c4 --- /dev/null +++ b/src/tools/c18/gui/c18_ui.h @@ -0,0 +1,40 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef C18_UI_H +#define C18_UI_H + +#include "tools/gui/tool_config_widget.h" +#include "tools/gui/tool_group_ui.h" + +namespace C18 +{ +//---------------------------------------------------------------------------- +class ConfigWidget : public ToolConfigWidget +{ +Q_OBJECT +public: + ConfigWidget(Project *project); + +private: + QComboBox *_warningLevel; + virtual void initEntries(); + virtual void loadConfig(const Compile::Config &config); + virtual void saveConfig(Compile::Config &config) const; +}; + +//---------------------------------------------------------------------------- +class GroupUI : public Tool::GroupUI +{ +public: + virtual ToolConfigWidget *configWidgetFactory(Tool::Category, ::Project *project) const { return new ConfigWidget(project); } +}; + +} // namespace + +#endif diff --git a/src/tools/cc5x/Makefile.am b/src/tools/cc5x/Makefile.am new file mode 100644 index 0000000..b72d8bb --- /dev/null +++ b/src/tools/cc5x/Makefile.am @@ -0,0 +1,8 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libcc5x.la +libcc5x_la_SOURCES = cc5x.cpp cc5x_compile.cpp cc5x_config.cpp +libcc5x_la_LDFLAGS = $(all_libraries) + +SUBDIRS = gui \ No newline at end of file diff --git a/src/tools/cc5x/cc5x.cpp b/src/tools/cc5x/cc5x.cpp new file mode 100644 index 0000000..5b28397 --- /dev/null +++ b/src/tools/cc5x/cc5x.cpp @@ -0,0 +1,62 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "cc5x.h" + +#include + +#include "cc5x_compile.h" +#include "cc5x_config.h" +#include "devices/pic/pic/pic_memory.h" +#include "devices/list/device_list.h" +#include "devices/base/device_group.h" + +//---------------------------------------------------------------------------- +bool CC5X::Base::checkExecutableResult(bool, QStringList &lines) const +{ + return ( lines.count()>0 && lines[0].startsWith("CC5X") ); +} + +//---------------------------------------------------------------------------- +QValueList CC5X::Group::getSupportedDevices(const QString &) const +{ + QValueList list; + QValueVector devices = Device::lister().group("pic")->supportedDevices(); + for (uint i=0; i(Device::lister().data(devices[i])); + if ( data->architecture()!=Pic::Architecture::P10X && data->architecture()!=Pic::Architecture::P16X ) continue; + list.append(data); + } + return list; +} + +Compile::Process *CC5X::Group::processFactory(const Compile::Data &data) const +{ + switch (data.category.type()) { + case Tool::Category::Compiler: return new CC5X::CompileFile; + default: break; + } + Q_ASSERT(false); + return 0; +} + +Compile::Config *CC5X::Group::configFactory(::Project *project) const +{ + return new Config(project); +} + +QString CC5X::Group::informationText() const +{ + return i18n("CC5X is a C compiler distributed by B Knudsen Data.").arg("http://www.bknd.com/cc5x/index.shtml"); +} + +Tool::Group::BaseData CC5X::Group::baseFactory(Tool::Category category) const +{ + if ( category==Tool::Category::Compiler ) return BaseData(new CC5X::Base, Both); + return BaseData(); +} diff --git a/src/tools/cc5x/cc5x.h b/src/tools/cc5x/cc5x.h new file mode 100644 index 0000000..054a9ef --- /dev/null +++ b/src/tools/cc5x/cc5x.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef CC5X_H +#define CC5X_H + +#include "tools/base/tool_group.h" +#include "common/global/pfile.h" + +namespace CC5X +{ +//---------------------------------------------------------------------------- +class Base : public Tool::Base +{ +public: + virtual QString baseExecutable(bool, Tool::OutputExecutableType) const { return "cc5x"; } + +private: + virtual QStringList checkExecutableOptions(bool) const { return QStringList(); } + virtual bool checkExecutableResult(bool withWine, QStringList &lines) const; +}; + +//---------------------------------------------------------------------------- +class Group : public Tool::Group +{ +public: + virtual QString name() const { return "cc5x"; } + virtual QString label() const { return i18n("CC5X Compiler"); } + virtual QString informationText() const; + virtual Tool::Category checkDevicesCategory() const { return Tool::Category::Nb_Types; } + virtual Tool::ExecutableType preferedExecutableType() const { return Tool::ExecutableType::Windows; } + virtual Tool::CompileType compileType() const { return Tool::SingleFile; } + virtual PURL::FileType implementationType(PURL::ToolType type) const { return (type==PURL::ToolType::Compiler ? PURL::CSource : PURL::Nb_FileTypes); } + +private: + virtual QValueList getSupportedDevices(const QString &s) const; + virtual Compile::Process *processFactory(const Compile::Data &data) const; + virtual Compile::Config *configFactory(::Project *project) const; + virtual BaseData baseFactory(Tool::Category) const; + virtual Tool::SourceGenerator *sourceGeneratorFactory() const { /*TODO*/ return 0; } +}; + +} // namespace + +#endif diff --git a/src/tools/cc5x/cc5x_compile.cpp b/src/tools/cc5x/cc5x_compile.cpp new file mode 100644 index 0000000..6956eb8 --- /dev/null +++ b/src/tools/cc5x/cc5x_compile.cpp @@ -0,0 +1,37 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "cc5x_compile.h" + +#include "cc5x_config.h" + +QStringList CC5X::CompileFile::genericArguments(const Compile::Config &config) const +{ + QStringList args; + args += "-a"; // produce asm file + args += "-CC"; // produce cod c file + args += "-L"; // produce list file + args += "-eL"; // error details + //args += "-FM"; // error format for MPLAB + args += "-o%O"; // set output file + args += config.includeDirs(Tool::Category::Compiler, "-I"); + args += config.customOptions(Tool::Category::Compiler); + args += "%I"; + return args; +} + +void CC5X::CompileFile::logStderrLine(const QString &line) +{ + if ( parseErrorLine(line, Compile::ParseErrorData("(.*):([0-9]+):(.+)\\[([0-9]+)\\](.+)", 1, 2, 5, 3)) ) return; + doLog(Log::LineType::Normal, line, QString::null, 0); // unrecognized +} + +QString CC5X::CompileFile::outputFiles() const +{ + return "PURL::Lst PURL::AsmGPAsm PURL::Hex PURL::Cod occ"; +} diff --git a/src/tools/cc5x/cc5x_compile.h b/src/tools/cc5x/cc5x_compile.h new file mode 100644 index 0000000..f400380 --- /dev/null +++ b/src/tools/cc5x/cc5x_compile.h @@ -0,0 +1,29 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef CC5X_COMPILE_H +#define CC5X_COMPILE_H + +#include "tools/list/compile_process.h" + +namespace CC5X +{ + +class CompileFile : public Compile::Process +{ +Q_OBJECT +protected: + virtual QString deviceName() const { return QString::null; } + virtual QStringList genericArguments(const Compile::Config &config) const; + virtual void logStderrLine(const QString &line); + virtual QString outputFiles() const; +}; + +} // namespace + +#endif diff --git a/src/tools/cc5x/cc5x_config.cpp b/src/tools/cc5x/cc5x_config.cpp new file mode 100644 index 0000000..96def5c --- /dev/null +++ b/src/tools/cc5x/cc5x_config.cpp @@ -0,0 +1,9 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "cc5x_config.h" diff --git a/src/tools/cc5x/cc5x_config.h b/src/tools/cc5x/cc5x_config.h new file mode 100644 index 0000000..da1d1f9 --- /dev/null +++ b/src/tools/cc5x/cc5x_config.h @@ -0,0 +1,25 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef CC5X_CONFIG_H +#define CC5X_CONFIG_H + +#include "tools/list/compile_config.h" + +namespace CC5X +{ +//---------------------------------------------------------------------------- +class Config : public Compile::Config +{ +public: + Config(Project *project) : Compile::Config(project) {} +}; + +} // namespace + +#endif diff --git a/src/tools/cc5x/gui/Makefile.am b/src/tools/cc5x/gui/Makefile.am new file mode 100644 index 0000000..760aee9 --- /dev/null +++ b/src/tools/cc5x/gui/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libcc5xui.la +libcc5xui_la_SOURCES = cc5x_ui.cpp +libcc5xui_la_LDFLAGS = $(all_libraries) \ No newline at end of file diff --git a/src/tools/cc5x/gui/cc5x_ui.cpp b/src/tools/cc5x/gui/cc5x_ui.cpp new file mode 100644 index 0000000..b35e6af --- /dev/null +++ b/src/tools/cc5x/gui/cc5x_ui.cpp @@ -0,0 +1,19 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "cc5x_ui.h" + +//---------------------------------------------------------------------------- +CC5X::ConfigWidget::ConfigWidget(Project *project) + : ToolConfigWidget(project) +{} + +void CC5X::ConfigWidget::initEntries() +{ + if ( _category!=Tool::Category::Linker ) createIncludeDirectoriesEntry(); +} diff --git a/src/tools/cc5x/gui/cc5x_ui.h b/src/tools/cc5x/gui/cc5x_ui.h new file mode 100644 index 0000000..7bf0a37 --- /dev/null +++ b/src/tools/cc5x/gui/cc5x_ui.h @@ -0,0 +1,35 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef CC5X_UI_H +#define CC5X_UI_H + +#include "tools/gui/tool_config_widget.h" +#include "tools/gui/tool_group_ui.h" + +namespace CC5X +{ +//---------------------------------------------------------------------------- +class ConfigWidget : public ToolConfigWidget +{ +Q_OBJECT +public: + ConfigWidget(Project *project); + virtual void initEntries(); +}; + +//---------------------------------------------------------------------------- +class GroupUI : public Tool::GroupUI +{ +public: + virtual ToolConfigWidget *configWidgetFactory(Tool::Category, ::Project *project) const { return new ConfigWidget(project); } +}; + +} // namespace + +#endif diff --git a/src/tools/ccsc/Makefile.am b/src/tools/ccsc/Makefile.am new file mode 100644 index 0000000..e0d3844 --- /dev/null +++ b/src/tools/ccsc/Makefile.am @@ -0,0 +1,8 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libccsc.la +libccsc_la_LDFLAGS = $(all_libraries) +libccsc_la_SOURCES = ccsc.cpp ccsc_compile.cpp ccsc_config.cpp + +SUBDIRS = gui \ No newline at end of file diff --git a/src/tools/ccsc/ccsc.cpp b/src/tools/ccsc/ccsc.cpp new file mode 100644 index 0000000..b28f29a --- /dev/null +++ b/src/tools/ccsc/ccsc.cpp @@ -0,0 +1,106 @@ +/*************************************************************************** + * Copyright (C) 2006-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "ccsc.h" + +#include + +#include "ccsc_compile.h" +#include "ccsc_config.h" +#include "devices/pic/pic/pic_memory.h" +#include "devices/list/device_list.h" +#include "devices/base/device_group.h" + +//---------------------------------------------------------------------------- +QStringList CCSC::Base::checkExecutableOptions(bool withWine) const +{ + QStringList args; + if (withWine) { + args += "+STDOUT"; + args += "+FM"; + args += static_cast(_group)->checkExecutableUrl().filename(); + } else args += "+V"; + return args; +} + +PURL::Directory CCSC::Base::checkExecutableWorkingDirectory() const +{ + return static_cast(_group)->checkExecutableUrl().directory(); +} + +bool CCSC::Base::checkExecutableResult(bool withWine, QStringList &lines) const +{ + if (withWine) { + PURL::Url url = static_cast(_group)->checkExecutableUrl().toExtension("err"); + Log::StringView sview; + PURL::File file(url, sview); + if ( !file.openForRead() ) { + url = static_cast(_group)->checkExecutableUrl().appendExtension("err"); + file.setUrl(url); + if ( !file.openForRead() ) return false; + } + lines = file.readLines(); + } + return true; +} + +//---------------------------------------------------------------------------- +CCSC::Group::Group() + : _checkExecTmp(_sview, ".c") +{ + if ( _checkExecTmp.openForWrite() ) _checkExecTmp.appendText("#include <16f877a.h>\nvoid main(void) {}\n"); + _checkExecTmp.close(); +} + +QValueList CCSC::Group::getSupportedDevices(const QString &) const +{ + QValueList list; + QValueVector devices = Device::lister().group("pic")->supportedDevices(); + for (uint i=0; i(data)->architecture(); + if ( arch==Pic::Architecture::P30F || arch==Pic::Architecture::P33F ) continue; + list.append(data); + } + return list; +} + +Compile::Process *CCSC::Group::processFactory(const Compile::Data &data) const +{ + switch (data.category.type()) { + case Tool::Category::Compiler: return new CCSC::CompileFile; + default: break; + } + Q_ASSERT(false); + return 0; +} + +Compile::Config *CCSC::Group::configFactory(::Project *project) const +{ + return new Config(project); +} + +QString CCSC::Group::informationText() const +{ + return i18n("CCS Compiler is a C compiler distributed by CCS.").arg("http://www.ccsinfo.com/content.php?page=compilers"); +} + +Tool::Group::BaseData CCSC::Group::baseFactory(Tool::Category category) const +{ + if ( category==Tool::Category::Compiler ) return BaseData(new CCSC::Base, Both); + return BaseData(); +} + +VersionData CCSC::Group::getToolchainVersion() +{ + if ( !Compile::Config::withWine(*this) ) { + QStringList lines; + if ( checkExecutable(Tool::Category::Compiler, lines) && lines.count()>=1 && lines[0].contains("3.") ) return VersionData(3, 0, 0); + } + return VersionData(4, 0, 0); // default +} diff --git a/src/tools/ccsc/ccsc.h b/src/tools/ccsc/ccsc.h new file mode 100644 index 0000000..aef2005 --- /dev/null +++ b/src/tools/ccsc/ccsc.h @@ -0,0 +1,57 @@ +/*************************************************************************** + * Copyright (C) 2006-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef CCSC_H +#define CCSC_H + +#include "tools/base/tool_group.h" +#include "common/gui/pfile_ext.h" + +namespace CCSC +{ +//---------------------------------------------------------------------------- +class Base : public Tool::Base +{ +public: + virtual QString baseExecutable(bool, Tool::OutputExecutableType) const { return "ccsc"; } + +private: + virtual QStringList checkExecutableOptions(bool withWine) const; + virtual bool checkExecutableResult(bool withWine, QStringList &lines) const; + virtual PURL::Directory checkExecutableWorkingDirectory() const; +}; + +//---------------------------------------------------------------------------- +class Group : public Tool::Group +{ +public: + Group(); + PURL::Url checkExecutableUrl() const { return _checkExecTmp.url(); } + virtual QString name() const { return "ccsc"; } + virtual QString label() const { return i18n("CCS Compiler"); } + virtual QString informationText() const; + virtual Tool::Category checkDevicesCategory() const { return Tool::Category::Nb_Types; } + virtual Tool::ExecutableType preferedExecutableType() const { return Tool::ExecutableType::Unix; } + virtual Tool::CompileType compileType() const { return Tool::SingleFile; } + virtual PURL::FileType implementationType(PURL::ToolType type) const { return (type==PURL::ToolType::Compiler ? PURL::CSource : PURL::Nb_FileTypes); } + +private: + Log::StringView _sview; + PURL::TempFile _checkExecTmp; + + virtual QValueList getSupportedDevices(const QString &s) const; + virtual Compile::Process *processFactory(const Compile::Data &data) const; + virtual Compile::Config *configFactory(::Project *project) const; + virtual BaseData baseFactory(Tool::Category) const; + virtual Tool::SourceGenerator *sourceGeneratorFactory() const { /*TODO*/ return 0; } + virtual VersionData getToolchainVersion(); +}; + +} // namespace + +#endif diff --git a/src/tools/ccsc/ccsc_compile.cpp b/src/tools/ccsc/ccsc_compile.cpp new file mode 100644 index 0000000..56897e8 --- /dev/null +++ b/src/tools/ccsc/ccsc_compile.cpp @@ -0,0 +1,107 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "ccsc_compile.h" + +#include "ccsc.h" +#include "common/global/pfile.h" +#include "ccsc_config.h" +#include "devices/list/device_list.h" +#include "devices/pic/base/pic.h" + +QString CCSC::CompileFile::familyName() const +{ + const Pic::Data *pdata = static_cast(Device::lister().data(_data.device)); + switch (pdata->architecture().type()) { + case Pic::Architecture::P10X: return "B"; + case Pic::Architecture::P16X: return "M"; + case Pic::Architecture::P17C: return "7"; + case Pic::Architecture::P18C: + case Pic::Architecture::P18F: + case Pic::Architecture::P18J: return "H"; + case Pic::Architecture::P24F: + case Pic::Architecture::P24H: + case Pic::Architecture::P30F: + case Pic::Architecture::P33F: break; + case Pic::Architecture::Nb_Types: break; + } + Q_ASSERT(false); + return QString::null; +} + +QStringList CCSC::CompileFile::genericArguments(const Compile::Config &config) const +{ + bool isVersion3 = ( static_cast(Main::toolGroup()).version().majorNum()==3 ); + QStringList args; + args += "+STDOUT"; // output messages on stdout + if ( !isVersion3 ) args += "+EA"; // show all messages and warnings + args += "-P"; // close compile windows after compilation done + if ( !isVersion3 ) args += "+DF"; // output COFF file + args += "+LSlst"; // normal list file + args += "+O8hex"; // produce 8bit Intel file + if ( !isVersion3 ) args += "+M"; // generate symbol file + args += "-J"; // do not create project file + args += "-A"; // do not create stat file + args += "+F%FAMILY"; + if ( isVersion3 ) args += config.includeDirs(Tool::Category::Compiler, "I=\"", "\""); + else args += config.includeDirs(Tool::Category::Compiler, "I+=\"", "\""); + args += config.customOptions(Tool::Category::Compiler); + args += "%I"; + return args; +} + +void CCSC::CompileFile::logStderrLine(const QString &line) +{ + // ignore output for wine + if ( !Compile::Config::withWine(group()) ) parseLine(line); +} + +void CCSC::CompileFile::parseLine(const QString &line) +{ + Log::LineType type; + if ( line.startsWith(">>>") ) type = Log::LineType::Warning; + else if ( line.startsWith("***") ) type = Log::LineType::Error; + else if ( line.startsWith("---") ) type = Log::LineType::Information; + else { + doLog(Log::LineType::Normal, line, QString::null, 0); // unrecognized + return; + } + if ( parseErrorLine(line, Compile::ParseErrorData("[*>-]+\\s\\w+\\s\\d+\\s\"([^\"]*)\"\\sLine\\s(\\d+)\\([^)]*\\):(.*)", 1, 2, 3, type)) ) return; + if ( parseErrorLine(line, Compile::ParseErrorData("[*>-]+\\s\"([^\"]*)\"\\sLine\\s(\\d+):\\s\\w+\\s#\\d+:(.*)", 1, 2, 3, type)) ) return; + doLog(type, line, QString::null, 0); +} + +void CCSC::CompileFile::done(int code) +{ + // with wine, rely on error file + if ( Compile::Config::withWine(group()) ) { + PURL::Url url = PURL::Url(directory(), inputFilepath(0)).toExtension("err"); + Log::StringView sview; + PURL::File file(url, sview); + if ( !file.openForRead() ) doLog(Log::LineType::Error, i18n("Could not find error file (%1).").arg(url.pretty()), QString::null, 0); + else { + QStringList lines = file.readLines(); + for (uint i=0; i * + * * + * 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. * + ***************************************************************************/ +#ifndef CCSC_COMPILE_H +#define CCSC_COMPILE_H + +#include "tools/list/compile_process.h" + +namespace CCSC +{ + +class CompileFile : public Compile::Process +{ +Q_OBJECT +protected: + virtual QString deviceName() const { return QString::null; } + virtual QString familyName() const; + virtual QStringList genericArguments(const Compile::Config &config) const; + virtual void logStderrLine(const QString &line); + virtual QString outputFiles() const; + virtual PURL::Url url(PURL::FileType type = PURL::Nb_FileTypes, uint i = 0) const; + +protected slots: + virtual void done(int code); + +private: + void parseLine(const QString &line); +}; + +} // namespace + +#endif diff --git a/src/tools/ccsc/ccsc_config.cpp b/src/tools/ccsc/ccsc_config.cpp new file mode 100644 index 0000000..333bc14 --- /dev/null +++ b/src/tools/ccsc/ccsc_config.cpp @@ -0,0 +1,9 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "ccsc_config.h" diff --git a/src/tools/ccsc/ccsc_config.h b/src/tools/ccsc/ccsc_config.h new file mode 100644 index 0000000..f4ddef6 --- /dev/null +++ b/src/tools/ccsc/ccsc_config.h @@ -0,0 +1,25 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef CCSC_CONFIG_H +#define CCSC_CONFIG_H + +#include "tools/list/compile_config.h" + +namespace CCSC +{ + +class Config : public Compile::Config +{ +public: + Config(Project *project) : Compile::Config(project) {} +}; + +} // namespace + +#endif diff --git a/src/tools/ccsc/gui/Makefile.am b/src/tools/ccsc/gui/Makefile.am new file mode 100644 index 0000000..e3703bb --- /dev/null +++ b/src/tools/ccsc/gui/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libccscui.la +libccscui_la_LDFLAGS = $(all_libraries) +libccscui_la_SOURCES = ccsc_ui.cpp diff --git a/src/tools/ccsc/gui/ccsc_ui.cpp b/src/tools/ccsc/gui/ccsc_ui.cpp new file mode 100644 index 0000000..eb2a900 --- /dev/null +++ b/src/tools/ccsc/gui/ccsc_ui.cpp @@ -0,0 +1,19 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "ccsc_ui.h" + +//---------------------------------------------------------------------------- +CCSC::ConfigWidget::ConfigWidget(Project *project) + : ToolConfigWidget(project) +{} + +void CCSC::ConfigWidget::initEntries() +{ + if ( _category!=Tool::Category::Linker ) createIncludeDirectoriesEntry(); +} diff --git a/src/tools/ccsc/gui/ccsc_ui.h b/src/tools/ccsc/gui/ccsc_ui.h new file mode 100644 index 0000000..356cf22 --- /dev/null +++ b/src/tools/ccsc/gui/ccsc_ui.h @@ -0,0 +1,35 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef CCSC_UI_H +#define CCSC_UI_H + +#include "tools/gui/tool_config_widget.h" +#include "tools/gui/tool_group_ui.h" + +namespace CCSC +{ +//---------------------------------------------------------------------------- +class ConfigWidget : public ToolConfigWidget +{ +Q_OBJECT +public: + ConfigWidget(Project *project); + virtual void initEntries(); +}; + +//---------------------------------------------------------------------------- +class GroupUI : public Tool::GroupUI +{ +public: + virtual ToolConfigWidget *configWidgetFactory(Tool::Category, ::Project *project) const { return new ConfigWidget(project); } +}; + +} // namespace + +#endif diff --git a/src/tools/custom/Makefile.am b/src/tools/custom/Makefile.am new file mode 100644 index 0000000..2e45534 --- /dev/null +++ b/src/tools/custom/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libcustom.la +libcustom_la_LDFLAGS = $(all_libraries) +libcustom_la_SOURCES = custom.cpp diff --git a/src/tools/custom/custom.cpp b/src/tools/custom/custom.cpp new file mode 100644 index 0000000..3779957 --- /dev/null +++ b/src/tools/custom/custom.cpp @@ -0,0 +1,23 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "custom.h" + +#include "devices/list/device_list.h" +#include "devices/base/device_group.h" + +QValueList CustomTool::Group::getSupportedDevices(const QString &) const +{ + QValueVector devices = Device::lister().supportedDevices(); + QValueList list; + for (uint i=0; i * + * * + * 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. * + ***************************************************************************/ +#ifndef CUSTOM_TOOL_H +#define CUSTOM_TOOL_H + +#include "tools/base/tool_group.h" + +namespace CustomTool +{ + +class Group : public Tool::Group +{ +public: + virtual QString name() const { return CUSTOM_NAME; } + virtual QString label() const { return i18n("Custom"); } + virtual QString informationText() const { return QString::null; } + virtual Tool::Category checkDevicesCategory() const { return Tool::Category::Nb_Types; } + virtual Tool::ExecutableType preferedExecutableType() const { return Tool::ExecutableType::Unix; } + virtual Tool::CompileType compileType() const { return Tool::AllFiles; } + virtual PURL::FileType implementationType(PURL::ToolType) const { return PURL::Nb_FileTypes; } + +protected: + virtual BaseData baseFactory(Tool::Category) const { return BaseData(); } + virtual QValueList getSupportedDevices(const QString &s) const; + virtual Compile::Process *processFactory(const Compile::Data &) const { return 0; } + virtual Compile::Config *configFactory(::Project *) const { return 0; } + virtual Tool::SourceGenerator *sourceGeneratorFactory() const { return 0; } +}; + +} // namespace + +#endif diff --git a/src/tools/gputils/Makefile.am b/src/tools/gputils/Makefile.am new file mode 100644 index 0000000..157784c --- /dev/null +++ b/src/tools/gputils/Makefile.am @@ -0,0 +1,9 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libgputils.la +libgputils_la_LDFLAGS = $(all_libraries) +libgputils_la_SOURCES = gputils_compile.cpp gputils_config.cpp gputils.cpp \ + gputils_generator.cpp + +SUBDIRS = gui \ No newline at end of file diff --git a/src/tools/gputils/gputils.cpp b/src/tools/gputils/gputils.cpp new file mode 100644 index 0000000..3219598 --- /dev/null +++ b/src/tools/gputils/gputils.cpp @@ -0,0 +1,107 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "gputils.h" + +#include + +#include "gputils_compile.h" +#include "gputils_config.h" +#include "devices/pic/pic/pic_memory.h" +#include "common/global/process.h" +#include "gputils_generator.h" + +//---------------------------------------------------------------------------- +QString GPUtils::Base::baseExecutable(bool, Tool::OutputExecutableType) const +{ + switch (_category.type()) { + case Tool::Category::Assembler: return "gpasm"; + case Tool::Category::Linker: return "gplink"; + case Tool::Category::Librarian: return "gplib"; + default: break; + } + return QString::null; +} + +bool GPUtils::Base::checkExecutableResult(bool withWine, QStringList &lines) const +{ + return ( lines.count()>0 && lines[0].startsWith(baseExecutable(withWine, Tool::OutputExecutableType::Coff)) ); +} + +//---------------------------------------------------------------------------- +QString GPUtils::Group::informationText() const +{ + return i18n("GPUtils is an open-source assembler and linker suite.
").arg("http://gputils.sourceforge.net"); +} + +Tool::Group::BaseData GPUtils::Group::baseFactory(Tool::Category category) const +{ + if ( category==Tool::Category::Assembler ) return BaseData(new ::GPUtils::Base, Both); + if ( category==Tool::Category::Linker || category==Tool::Category::Librarian ) return BaseData(new ::GPUtils::Base, ProjectOnly); + return BaseData(); +} + +PURL::Directory GPUtils::Group::autodetectDirectory(Compile::DirectoryType type, const PURL::Directory &execDir, bool withWine) const +{ + switch (type.type()) { + case Compile::DirectoryType::LinkerScript: { + QString exec = execDir.path() + base(Tool::Category::Linker)->baseExecutable(withWine, Tool::OutputExecutableType::Coff); + ::Process::StringOutput process; + process.setup(exec, "-h", withWine); + if ( ::Process::runSynchronously(process, ::Process::Start, 1000)!=::Process::Exited ) return PURL::Directory(); + QString s = process.sout() + process.serr(); + QRegExp re(".*Default linker script path ([^\\n]*)\\n.*"); + if ( !re.exactMatch(s) ) return PURL::Directory(); + return PURL::Directory(re.cap(1)); + } + case Compile::DirectoryType::Header: { + QString exec = execDir.path() + base(Tool::Category::Assembler)->baseExecutable(withWine, Tool::OutputExecutableType::Coff); + ::Process::StringOutput process; + process.setup(exec, "-h", withWine); + if ( ::Process::runSynchronously(process, ::Process::Start, 1000)!=::Process::Exited ) return PURL::Directory(); + QString s = process.sout() + process.serr(); + QRegExp re(".*Default header file path ([^\\n]*)\\n.*"); + if ( !re.exactMatch(s) ) return PURL::Directory(); + return PURL::Directory(re.cap(1)); + } + case Compile::DirectoryType::Executable: + case Compile::DirectoryType::Library: + case Compile::DirectoryType::Source: + case Compile::DirectoryType::Nb_Types: break; + } + return PURL::Directory(); +} + +Compile::Process *GPUtils::Group::processFactory(const Compile::Data &data) const +{ + switch (data.category.type()) { + case Tool::Category::Assembler: + if (data.project) return new GPUtils::AssembleProjectFile; + return new GPUtils::AssembleStandaloneFile; + case Tool::Category::Linker: + Q_ASSERT(data.project); + return new GPUtils::LinkProject; + case Tool::Category::Librarian: + Q_ASSERT(data.project); + return new GPUtils::LibraryProject; + default: break; + } + Q_ASSERT(false); + return 0; +} + +Compile::Config *GPUtils::Group::configFactory(::Project *project) const +{ + return new Config(project); +} + +Tool::SourceGenerator *GPUtils::Group::sourceGeneratorFactory() const +{ + return new SourceGenerator; +} diff --git a/src/tools/gputils/gputils.h b/src/tools/gputils/gputils.h new file mode 100644 index 0000000..b8bcded --- /dev/null +++ b/src/tools/gputils/gputils.h @@ -0,0 +1,54 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef GPUTILS_H +#define GPUTILS_H + +#include "tools/base/tool_group.h" +#include "gputils_generator.h" + +namespace GPUtils +{ +//---------------------------------------------------------------------------- +class Base : public Tool::Base +{ +public: + virtual QString baseExecutable(bool withWine, Tool::OutputExecutableType type) const; + +private: + virtual QStringList checkExecutableOptions(bool) const { return "-v"; } + virtual bool checkExecutableResult(bool withWine, QStringList &lines) const; +}; + +//---------------------------------------------------------------------------- +class Group : public Tool::Group +{ +public: + virtual QString name() const { return "gputils"; } + virtual QString label() const { return i18n("GPUtils"); } + virtual QString informationText() const; + virtual Tool::Category checkDevicesCategory() const { return Tool::Category::Assembler; } + virtual QStringList checkDevicesOptions(uint) const { return "-l"; } + virtual PURL::Directory autodetectDirectory(Compile::DirectoryType type, const PURL::Directory &execDir, bool withWine) const; + virtual bool hasDirectory(Compile::DirectoryType type) const { return type==Compile::DirectoryType::Header || type==Compile::DirectoryType::LinkerScript; } + virtual PURL::FileType linkerScriptType() const { return PURL::Lkr; } + virtual Tool::ExecutableType preferedExecutableType() const { return Tool::ExecutableType::Unix; } + virtual Tool::CompileType compileType() const { return Tool::SeparateFiles; } + virtual PURL::FileType implementationType(PURL::ToolType type) const { return (type==PURL::ToolType::Assembler ? PURL::AsmGPAsm : PURL::Nb_FileTypes); } + +protected: + virtual BaseData baseFactory(Tool::Category c) const; + virtual QValueList getSupportedDevices(const QString &s) const { return GPUtils::getSupportedDevices(s); } + virtual Compile::Process *processFactory(const Compile::Data &data) const; + virtual Compile::Config *configFactory(::Project *project) const; + virtual Tool::SourceGenerator *sourceGeneratorFactory() const; +}; + +} // namespace + +#endif diff --git a/src/tools/gputils/gputils_compile.cpp b/src/tools/gputils/gputils_compile.cpp new file mode 100644 index 0000000..c59828c --- /dev/null +++ b/src/tools/gputils/gputils_compile.cpp @@ -0,0 +1,109 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "gputils_compile.h" + +#include "gputils.h" +#include "gputils_config.h" +#include "devices/list/device_list.h" +#include "coff/base/disassembler.h" + +//----------------------------------------------------------------------------- +QString GPUtils::Process::deviceName() const +{ + return toDeviceName(_data.device); +} + +//----------------------------------------------------------------------------- +void GPUtils::AssembleFile::logStderrLine(const QString &line) +{ + if ( parseErrorLine(line, Compile::ParseErrorData("([^:]*):([0-9]+):(.+)\\[[0-9]+\\](.+)", 1, 2, 4, 3)) ) return; + if ( parseErrorLine(line, Compile::ParseErrorData("([^:]*):([^:]+):([0-9]+):(.+)", 2, 3, 4, Log::LineType::Warning)) ) return; + doLog(Log::LineType::Normal, line, QString::null, 0); // unrecognized +} + +//----------------------------------------------------------------------------- +QStringList GPUtils::AssembleStandaloneFile::genericArguments(const Compile::Config &config) const +{ + QStringList args; + args += "-L"; // force list + args += "-o%O"; + uint wl = static_cast(config).gpasmWarningLevel(); + if ( wl!=Config::Nb_WarningLevels ) args += "-w" + QString::number(wl); + args += config.includeDirs(Tool::Category::Assembler, "-I"); + args += "$NO_AUTO_DEVICE(-p%DEVICE)"; + HexBuffer::Format format = config.hexFormat(); + if( format!=HexBuffer::Nb_Formats ) args += QString("-a") + HexBuffer::FORMATS[format]; + args += config.customOptions(Tool::Category::Assembler); + args += "%I"; + return args; +} + +QString GPUtils::AssembleStandaloneFile::outputFiles() const +{ + return "PURL::Lst PURL::Cod PURL::Hex"; +} + +//----------------------------------------------------------------------------- +QStringList GPUtils::AssembleProjectFile::genericArguments(const Compile::Config &config) const +{ + QStringList args; + args += "-c"; // relocatable code + args += config.includeDirs(Tool::Category::Assembler, "-I"); + if ( !_data.items[0].generated ) args += "-p%DEVICE"; + uint wl = static_cast(config).gpasmWarningLevel() ; + if( wl!=Config::Nb_WarningLevels ) args += "-w" + QString::number(wl); + args += config.customOptions(Tool::Category::Assembler); + args += "%I"; + return args; +} + +QString GPUtils::AssembleProjectFile::outputFiles() const +{ + return "PURL::Object PURL::Lst"; +} + +//----------------------------------------------------------------------------- +QStringList GPUtils::LinkProject::genericArguments(const Compile::Config &config) const +{ + QStringList args; + args += "-o%O"; + args += "-c"; // create coff file + HexBuffer::Format f = config.hexFormat(); + if ( f!=HexBuffer::Nb_Formats ) args += QString("-a") + HexBuffer::FORMATS[f]; + args += "-m"; // with map + args += config.includeDirs(Tool::Category::Linker, "-I"); + args += "$LKR(-s%LKR)"; + args += config.customOptions(Tool::Category::Linker); + args += "%OBJS"; + args += "%LIBS"; + return args; +} + +QString GPUtils::LinkProject::outputFiles() const +{ + return "PURL::Lkr PURL::Map PURL::Lst PURL::Cod PURL::Coff PURL::Hex"; +} + +//----------------------------------------------------------------------------- +QStringList GPUtils::LibraryProject::genericArguments(const Compile::Config &config) const +{ + QStringList args; + args += "-c"; // create archive + args += "%O"; + args += config.customOptions(Tool::Category::Librarian); + args += "%OBJS"; + args += "%LIBS"; + return args; +} + +QString GPUtils::LibraryProject::outputFiles() const +{ + return "PURL::Library"; +} diff --git a/src/tools/gputils/gputils_compile.h b/src/tools/gputils/gputils_compile.h new file mode 100644 index 0000000..a6a09c9 --- /dev/null +++ b/src/tools/gputils/gputils_compile.h @@ -0,0 +1,73 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef GPUTILS_COMPILE_H +#define GPUTILS_COMPILE_H + +#include "tools/list/compile_process.h" + +namespace GPUtils +{ +//----------------------------------------------------------------------------- +class Process : public Compile::Process +{ +Q_OBJECT +private: + virtual QString deviceName() const; + virtual bool hasLinkerScript() const { return ( _data.linkType==Compile::Icd2Linking || Compile::Process::hasLinkerScript() ); } +}; + +//----------------------------------------------------------------------------- +class AssembleFile : public Process +{ +Q_OBJECT +private: + virtual void logStderrLine(const QString &line); +}; + +//----------------------------------------------------------------------------- +class AssembleStandaloneFile : public AssembleFile +{ +Q_OBJECT +private: + virtual QString outputFiles() const; + virtual QStringList genericArguments(const Compile::Config &config) const; +}; + +//----------------------------------------------------------------------------- +class AssembleProjectFile : public AssembleFile +{ +Q_OBJECT +private: + virtual QString outputFiles() const; + virtual QStringList genericArguments(const Compile::Config &config) const; +}; + +//----------------------------------------------------------------------------- +class LinkProject : public Process +{ +Q_OBJECT +private: + virtual QString outputFiles() const; + virtual QStringList genericArguments(const Compile::Config &config) const; + virtual void logStderrLine(const QString &line) { doLog(filterType(line), line, QString::null, 0); } +}; + +//----------------------------------------------------------------------------- +class LibraryProject : public Process +{ +Q_OBJECT +private: + virtual QString outputFiles() const; + virtual QStringList genericArguments(const Compile::Config &config) const; + virtual void logStderrLine(const QString &line) { doLog(filterType(line), line, QString::null, 0); } +}; + +} // namespace + +#endif diff --git a/src/tools/gputils/gputils_config.cpp b/src/tools/gputils/gputils_config.cpp new file mode 100644 index 0000000..8f7bca2 --- /dev/null +++ b/src/tools/gputils/gputils_config.cpp @@ -0,0 +1,19 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "gputils_config.h" + +const char * const GPUtils::Config::WARNING_LEVEL_LABELS[Nb_WarningLevels] = { + I18N_NOOP("All messages"), I18N_NOOP("Warning and errors"), I18N_NOOP("Errors only") +}; + +uint GPUtils::Config::gpasmWarningLevel() const +{ + return QMIN(warningLevel(Tool::Category::Assembler), uint(Nb_WarningLevels)); +} diff --git a/src/tools/gputils/gputils_config.h b/src/tools/gputils/gputils_config.h new file mode 100644 index 0000000..cdaa66e --- /dev/null +++ b/src/tools/gputils/gputils_config.h @@ -0,0 +1,30 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#ifndef GPUTILS_CONFIG_H +#define GPUTILS_CONFIG_H + +#include "tools/list/compile_config.h" + +namespace GPUtils +{ + +class Config : public Compile::Config +{ +public: + Config(Project *project) : Compile::Config(project) {} + enum { Nb_WarningLevels = 3 }; + static const char * const WARNING_LEVEL_LABELS[Nb_WarningLevels]; + uint gpasmWarningLevel() const; + void setGPAsmWarningLevel(uint level) { setWarningLevel(Tool::Category::Assembler, level); } +}; + +} // namespace + +#endif diff --git a/src/tools/gputils/gputils_generator.cpp b/src/tools/gputils/gputils_generator.cpp new file mode 100644 index 0000000..3bcebac --- /dev/null +++ b/src/tools/gputils/gputils_generator.cpp @@ -0,0 +1,256 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "gputils_generator.h" + +#include "devices/pic/pic/pic_memory.h" +#include "devices/pic/base/pic_register.h" +#include "devices/list/device_list.h" + +//---------------------------------------------------------------------------- +QValueList GPUtils::getSupportedDevices(const QString &s) +{ + QStringList devices = QStringList::split(' ', s.simplifyWhiteSpace().upper()); + QValueList list; + for (uint i=0; i(memory), ok); +} + +SourceLine::List GPUtils::SourceGenerator::includeLines(PURL::ToolType, const Device::Data &data) const +{ + return GPUtils::includeLines(data); +} + +SourceLine::List GPUtils::SourceGenerator::sourceFileContent(PURL::ToolType, const Device::Data &data, bool &ok) const +{ + ok = true; + SourceLine::List lines; + lines.appendSeparator(); + const Pic::Data &pdata = static_cast(data); + const Pic::RegistersData &rdata = static_cast(*data.registersData()); + switch (pdata.architecture().type()) { + case Pic::Architecture::P10X: + lines.appendTitle(i18n("relocatable code")); + lines.appendNotIndentedCode("PROG CODE"); + lines.appendNotIndentedCode("start"); + lines.appendIndentedCode(QString::null, "<< " + i18n("insert code") + " >>"); + lines.appendIndentedCode("goto $", i18n("loop forever")); + lines.appendEmpty(); + lines.appendNotIndentedCode("END"); + break; + case Pic::Architecture::P16X: { + lines.appendTitle(i18n("Variables declaration")); + bool needPCLATH = ( pdata.nbWords(Pic::MemoryRangeType::Code)>0x400 ); + uint first; + bool allShared; + bool hasShared = rdata.hasSharedGprs(first, allShared); + if ( hasShared && !allShared ) lines.appendNotIndentedCode("INT_VAR UDATA_SHR"); + else { + first = rdata.firstGprIndex(); + lines.appendNotIndentedCode("INT_VAR UDATA " + toHexLabel(first, rdata.nbCharsAddress())); + } + lines.appendNotIndentedCode("w_saved RES 1", i18n("variable used for context saving")); + lines.appendNotIndentedCode("status_saved RES 1", i18n("variable used for context saving")); + first += 2; + if (needPCLATH) { + lines.appendNotIndentedCode("pclath_saved RES 1", i18n("variable used for context saving")); + first++; + } + lines.appendEmpty(); + lines.appendNotIndentedCode("var1 RES 1", i18n("example variable")); + if ( !hasShared ) { + for (uint i=1; i>"); + if (needPCLATH) { + lines.appendIndentedCode("movf pclath_saved,w", i18n("restore context")); + lines.appendIndentedCode("movwf PCLATH"); + lines.appendIndentedCode("swapf status_saved,w"); + } else lines.appendIndentedCode("swapf status_saved,w", i18n("restore context")); + lines.appendIndentedCode("movwf STATUS"); + lines.appendIndentedCode("swapf w_saved,f"); + lines.appendIndentedCode("swapf w_saved,w"); + lines.appendIndentedCode("retfie"); + lines.appendEmpty(); + lines.appendNotIndentedCode("start"); + lines.appendIndentedCode(QString::null, "<< " + i18n("insert main code") + " >>"); + lines.appendIndentedCode("goto $", i18n("loop forever")); + lines.appendEmpty(); + lines.appendNotIndentedCode("END"); + break; + } + case Pic::Architecture::P17C: + lines.appendTitle(i18n("Variables declaration")); + lines.appendNotIndentedCode("INT_VAR UDATA " + toHexLabel(rdata.accessBankSplit, rdata.nbCharsAddress())); + lines.appendNotIndentedCode("wred_saved RES 1", i18n("variable used for context saving (for low-priority interrupts only)")); + lines.appendNotIndentedCode("alusta_saved RES 1", i18n("variable used for context saving (for low-priority interrupts only)")); + lines.appendNotIndentedCode("bsr_saved RES 1", i18n("variable used for context saving (for low-priority interrupts only)")); + lines.appendNotIndentedCode("pclath_saved RES 1", i18n("variable used for context saving (for low-priority interrupts only)")); + lines.appendEmpty(); + lines.appendNotIndentedCode("var1 RES 1", i18n("example variable")); + lines.appendEmpty(); + lines.appendSeparator(); + lines.appendTitle(i18n("Macros")); + lines.appendNotIndentedCode("PUSH MACRO", i18n("for saving context")); + lines.appendIndentedCode("movpf WREG,wred_saved"); + lines.appendIndentedCode("movpf ALUSTA,alusta_saved"); + lines.appendIndentedCode("movpf BSR,bsr_saved"); + lines.appendIndentedCode("movpf PCLATH,pclath_saved"); + lines.appendIndentedCode("ENDM"); + lines.appendEmpty(); + lines.appendNotIndentedCode("POP MACRO", i18n("for restoringing context")); + lines.appendIndentedCode("movfp pclath_saved,PCLATH"); + lines.appendIndentedCode("movfp bsr_saved,BSR"); + lines.appendIndentedCode("movfp alusta_saved,ALUSTA"); + lines.appendIndentedCode("movfp wred_saved,WREG"); + lines.appendIndentedCode("ENDM"); + lines.appendSeparator(); + lines.appendTitle(i18n("reset vector")); + lines.appendNotIndentedCode("STARTUP CODE 0x0000"); + lines.appendIndentedCode("nop", i18n("needed for ICD2 debugging")); + lines.appendIndentedCode("nop", i18n("needed for ICD2 debugging")); + lines.appendIndentedCode("goto start", i18n("go to start of main code")); + lines.appendEmpty(); + lines.appendNotIndentedCode("INT_PIN_VECTOR CODE 0x0008"); + lines.appendIndentedCode("PUSH"); + lines.appendIndentedCode("goto int_pin_isr", i18n("go to start of int pin interrupt code")); + lines.appendEmpty(); + lines.appendNotIndentedCode("TIMER0_VECTOR CODE 0x0010"); + lines.appendIndentedCode("PUSH"); + lines.appendIndentedCode("goto timer0_isr", i18n("go to start of timer0 interrupt code")); + lines.appendEmpty(); + lines.appendNotIndentedCode("T0CKI_VECTOR CODE 0x00018"); + lines.appendIndentedCode("PUSH"); + lines.appendIndentedCode("goto t0cki_isr", i18n("go to start of t0cki interrupt code")); + lines.appendEmpty(); + lines.appendNotIndentedCode("PERIPHERAL_VECTOR CODE 0x0020"); + lines.appendIndentedCode("PUSH"); + lines.appendIndentedCode("goto peripheral_isr", i18n("go to start of peripheral interrupt code")); + lines.appendEmpty(); + lines.appendNotIndentedCode("start:"); + lines.appendIndentedCode(QString::null, "<< " + i18n("insert main code") + " >>"); + lines.appendIndentedCode("goto $", i18n("loop forever")); + lines.appendEmpty(); + lines.appendTitle(i18n("INT pin interrupt service routine")); + lines.appendNotIndentedCode("int_pin_isr:"); + lines.appendIndentedCode(QString::null, "<< " + i18n("insert INT pin interrupt code") + " >>"); + lines.appendIndentedCode("POP"); + lines.appendIndentedCode("retfie"); + lines.appendEmpty(); + lines.appendTitle(i18n("TIMER0 interrupt service routine")); + lines.appendNotIndentedCode("timer0_isr:"); + lines.appendIndentedCode(QString::null, "<< " + i18n("insert TIMER0 interrupt code") + " >>"); + lines.appendIndentedCode("POP"); + lines.appendIndentedCode("retfie"); + lines.appendEmpty(); + lines.appendTitle(i18n("T0CKI interrupt service routine")); + lines.appendNotIndentedCode("t0cki_isr:"); + lines.appendIndentedCode(QString::null, "<< " + i18n("insert T0CKI interrupt code") + " >>"); + lines.appendIndentedCode("POP"); + lines.appendIndentedCode("retfie"); + lines.appendEmpty(); + lines.appendTitle(i18n("peripheral interrupt service routine")); + lines.appendNotIndentedCode("peripheral_isr:"); + lines.appendIndentedCode(QString::null, "<< " + i18n("insert peripheral interrupt code") + " >>"); + lines.appendIndentedCode("POP"); + lines.appendIndentedCode("retfie"); + lines.appendEmpty(); + lines.appendNotIndentedCode("END"); + break; + case Pic::Architecture::P18C: + case Pic::Architecture::P18F: + case Pic::Architecture::P18J: // ?? + lines.appendTitle(i18n("Variables declaration")); + lines.appendNotIndentedCode("INT_VAR UDATA " + toHexLabel(rdata.accessBankSplit, rdata.nbCharsAddress())); + lines.appendNotIndentedCode("w_saved RES 1", i18n("variable used for context saving (for low-priority interrupts only)")); + lines.appendNotIndentedCode("status_saved RES 1", i18n("variable used for context saving (for low-priority interrupts only)")); + lines.appendNotIndentedCode("bsr_saved RES 1", i18n("variable used for context saving (for low-priority interrupts only)")); + lines.appendEmpty(); + lines.appendNotIndentedCode("var1 RES 1", i18n("example variable")); + lines.appendEmpty(); + lines.appendSeparator(); + lines.appendTitle(i18n("reset vector")); + lines.appendNotIndentedCode("STARTUP CODE 0x0000"); + lines.appendIndentedCode("nop", i18n("needed for ICD2 debugging")); + lines.appendIndentedCode("nop", i18n("needed for ICD2 debugging")); + lines.appendIndentedCode("goto start", i18n("go to start of main code")); + lines.appendEmpty(); + lines.appendTitle(i18n("high priority interrupt vector")); + lines.appendNotIndentedCode("HIGH_INT_VECTOR CODE 0x0008"); + lines.appendIndentedCode("bra high_interrupt", i18n("go to start of high priority interrupt code")); + lines.appendEmpty(); + lines.appendTitle(i18n("low priority interrupt vector")); + lines.appendNotIndentedCode("LOW_INT_VECTOR CODE 0x0018"); + lines.appendIndentedCode("movff STATUS,status_saved", i18n("save context")); + lines.appendIndentedCode("movff WREG,w_saved"); + lines.appendIndentedCode("movff BSR,bsr_saved"); + lines.appendIndentedCode(QString::null, "<< " + i18n("insert low priority interrupt code") + " >>"); + lines.appendIndentedCode("movff bsr_saved,BSR", i18n("restore context")); + lines.appendIndentedCode("movff w_saved,WREG"); + lines.appendIndentedCode("movff status_saved,STATUS"); + lines.appendIndentedCode("retfie"); + lines.appendEmpty(); + lines.appendTitle(i18n("high priority interrupt service routine")); + lines.appendNotIndentedCode("high_interrupt:"); + lines.appendIndentedCode(QString::null, "<< " + i18n("insert high priority interrupt code") + " >>"); + lines.appendIndentedCode("retfie FAST"); + lines.appendEmpty(); + lines.appendNotIndentedCode("start:"); + lines.appendIndentedCode(QString::null, "<< " + i18n("insert main code") + " >>"); + lines.appendIndentedCode("goto $", i18n("loop forever")); + lines.appendEmpty(); + lines.appendNotIndentedCode("END"); + break; + case Pic::Architecture::P24F: + case Pic::Architecture::P24H: + case Pic::Architecture::P30F: + case Pic::Architecture::P33F: ok = false; break; + case Pic::Architecture::Nb_Types: Q_ASSERT(false); break; + } + return lines; +} diff --git a/src/tools/gputils/gputils_generator.h b/src/tools/gputils/gputils_generator.h new file mode 100644 index 0000000..38da66d --- /dev/null +++ b/src/tools/gputils/gputils_generator.h @@ -0,0 +1,29 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef GPUTILS_GENERATOR_H +#define GPUTILS_GENERATOR_H + +#include "coff/base/disassembler.h" + +namespace GPUtils +{ + +extern QValueList getSupportedDevices(const QString &s); + +class SourceGenerator : public Tool::SourceGenerator +{ +public: + virtual SourceLine::List configLines(PURL::ToolType type, const Device::Memory &memory, bool &ok) const; + virtual SourceLine::List sourceFileContent(PURL::ToolType type, const Device::Data &data, bool &ok) const; + virtual SourceLine::List includeLines(PURL::ToolType type, const Device::Data &data) const; +}; + +} // namespace + +#endif diff --git a/src/tools/gputils/gui/Makefile.am b/src/tools/gputils/gui/Makefile.am new file mode 100644 index 0000000..0ac81c9 --- /dev/null +++ b/src/tools/gputils/gui/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libgputilsui.la +libgputilsui_la_LDFLAGS = $(all_libraries) +libgputilsui_la_SOURCES = gputils_ui.cpp diff --git a/src/tools/gputils/gui/gputils_ui.cpp b/src/tools/gputils/gui/gputils_ui.cpp new file mode 100644 index 0000000..35cdce8 --- /dev/null +++ b/src/tools/gputils/gui/gputils_ui.cpp @@ -0,0 +1,53 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "gputils_ui.h" + +#include +#include "tools/gputils/gputils_config.h" + +//---------------------------------------------------------------------------- +GPUtils::ConfigWidget::ConfigWidget(Project *project) + : ToolConfigWidget(project), _gpasmWarning(0) +{} + +void GPUtils::ConfigWidget::initEntries() +{ + if ( _category==Tool::Category::Assembler ) { + uint row = container()->numRows(); + QLabel *label = new QLabel(i18n("Warning level:"), container()); + container()->addWidget(label, row,row, 0,0); + _gpasmWarning = new QComboBox(container()); + connect(_gpasmWarning, SIGNAL(activated(int)), SIGNAL(changed())); + for (uint i=0; iinsertItem(i18n(GPUtils::Config::WARNING_LEVEL_LABELS[i])); + _gpasmWarning->insertItem(i18n("as in LIST directive")); + container()->addWidget(_gpasmWarning, row,row, 1,1); + createIncludeDirectoriesEntry(); + if ( _project==0 ) createHexFormatEntry(); + } + if ( _category==Tool::Category::Linker ) { + createHexFormatEntry(); + createIncludeDirectoriesEntry(); + } +} + +void GPUtils::ConfigWidget::loadConfig(const Compile::Config &config) +{ + ToolConfigWidget::loadConfig(config); + if ( _category==Tool::Category::Assembler ) + _gpasmWarning->setCurrentItem(static_cast(config).gpasmWarningLevel()); +} + +void GPUtils::ConfigWidget::saveConfig(Compile::Config &config) const +{ + ToolConfigWidget::saveConfig(config); + if ( _category==Tool::Category::Assembler ) + static_cast(config).setGPAsmWarningLevel(_gpasmWarning->currentItem()); +} diff --git a/src/tools/gputils/gui/gputils_ui.h b/src/tools/gputils/gui/gputils_ui.h new file mode 100644 index 0000000..8d6daea --- /dev/null +++ b/src/tools/gputils/gui/gputils_ui.h @@ -0,0 +1,41 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#ifndef GPUTILS_UI_H +#define GPUTILS_UI_H + +#include "tools/gui/tool_config_widget.h" +#include "tools/gui/tool_group_ui.h" + +namespace GPUtils +{ +//---------------------------------------------------------------------------- +class ConfigWidget : public ToolConfigWidget +{ +Q_OBJECT +public: + ConfigWidget(Project *project); + virtual void initEntries(); + +protected: + QComboBox *_gpasmWarning; + virtual void loadConfig(const Compile::Config &config); + virtual void saveConfig(Compile::Config &config) const; +}; + +//---------------------------------------------------------------------------- +class GroupUI : public Tool::GroupUI +{ +public: + virtual ToolConfigWidget *configWidgetFactory(Tool::Category, ::Project *project) const { return new ConfigWidget(project); } +}; + +} // namespace + +#endif diff --git a/src/tools/gui/Makefile.am b/src/tools/gui/Makefile.am new file mode 100644 index 0000000..0d582eb --- /dev/null +++ b/src/tools/gui/Makefile.am @@ -0,0 +1,7 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libtoolui.la +libtoolui_la_LDFLAGS = $(all_libraries) +libtoolui_la_SOURCES = tool_group_ui.cpp toolchain_config_widget.cpp \ + tool_config_widget.cpp toolchain_config_center.cpp diff --git a/src/tools/gui/tool_config_widget.cpp b/src/tools/gui/tool_config_widget.cpp new file mode 100644 index 0000000..308e61b --- /dev/null +++ b/src/tools/gui/tool_config_widget.cpp @@ -0,0 +1,181 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * Copyright (C) 2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "tool_config_widget.h" + +#include +#include +#include +#include + +#include "devices/base/hex_buffer.h" +#include "tools/list/compile_config.h" +#include "libgui/project.h" +#include "common/gui/purl_gui.h" +#include "tools/list/compile_process.h" + +const char * const ToolConfigWidget::ARGUMENTS_TYPE_LABELS[Nb_ArgumentsTypes] = { + I18N_NOOP("Automatic"), I18N_NOOP("Custom") +}; + +ToolConfigWidget::ToolConfigWidget(Project *project) + : ::ConfigWidget(0), _group(0), _project(project), + _customOptions(0), _customLibraries(0), _includeDirs(0), _hexFormat(0), + _config(0), _tmpConfig(0), _process(0), _tmpProject(0) +{ + + Container *container = new Container(this); + container->setColStretch(2, 1); + addWidget(container, 0,0, 0,0); + QLabel *label = new QLabel(i18n("Configuration:"), container); + container->addWidget(label, 0,0, 0,0); + _argumentsType = new KComboBox(container); + for (uint i=0; iinsertItem(i18n(ARGUMENTS_TYPE_LABELS[i]), i); + connect(_argumentsType, SIGNAL(activated(int)), SLOT(updateArguments())); + container->addWidget(_argumentsType, 0,0, 1,1); + label = new QLabel(i18n("Arguments:"), container); + container->addWidget(label, 1,1, 0,0); + _arguments = new KLineEdit(container); + _arguments->setReadOnly(true); + container->addWidget(_arguments, 1,1, 1,2); + KPushButton *button = new KPushButton(KGuiItem(QString::null, "help"), container); + connect(button, SIGNAL(clicked()), SIGNAL(displayHelp())); + container->addWidget(button, 1,1, 3,3); + _argumentsEditor = new EditListBox(1, container, "arguments_editor", EditListBox::DuplicatesAllowed, + EditListBox::Add | EditListBox::Remove | EditListBox::UpDown | EditListBox::RemoveAll | EditListBox::Reset); + connect(_argumentsEditor, SIGNAL(changed()), SLOT(updateArguments())); + connect(_argumentsEditor, SIGNAL(reset()), SLOT(resetCustomArguments())); + container->addWidget(_argumentsEditor, 2,2, 0,3); + + _container = new Container(container); + _container->setColStretch(2, 1); + container->addWidget(_container, 3,3, 0,3); + + connect(this, SIGNAL(changed()), SLOT(updateArguments())); +} + +void ToolConfigWidget::init(Tool::Category category, const Tool::Group &group) +{ + _category = category; + _group = &group; + _config = _group->createConfig(_project); + _tmpProject = new Project(PURL::Url()); + _tmpConfig = _group->createConfig(_tmpProject); + Compile::Data data(_category, QValueList(), QString::null, _project, Compile::NormalLinking); + _process = _group->createCompileProcess(data, 0); + + initEntries(); + createCustomOptionsEntry(); +} + +ToolConfigWidget::~ToolConfigWidget() +{ + delete _process; + delete _tmpConfig; + delete _tmpProject; + delete _config; +} + +PURL::DirectoriesWidget *ToolConfigWidget::createDirectoriesEntry(const QString &text) +{ + uint row = container()->numRows(); + PURL::DirectoriesWidget *sdw = new PURL::DirectoriesWidget(text, _project ? _project->directory().path() : QString::null, container()); + connect(sdw, SIGNAL(changed()), SIGNAL(changed())); + container()->addWidget(sdw, row,row, 0,2); + return sdw; +} + +void ToolConfigWidget::createCustomOptionsEntry() +{ + uint row = container()->numRows(); + QLabel *label = new QLabel(i18n("Custom options:"), container()); + container()->addWidget(label, row,row, 0,0); + _customOptions = new QLineEdit(container()); + connect(_customOptions, SIGNAL(textChanged(const QString &)), SIGNAL(changed())); + container()->addWidget(_customOptions, row,row, 1,2); +} + +void ToolConfigWidget::createCustomLibrariesEntry() +{ + uint row = container()->numRows(); + QLabel *label = new QLabel(i18n("Custom libraries:"), container()); + container()->addWidget(label, row,row, 0,0); + _customLibraries = new QLineEdit(container()); + connect(_customLibraries, SIGNAL(textChanged(const QString &)), SIGNAL(changed())); + QToolTip::add(_customLibraries, i18n("This values will be placed after the linked objects.")) ; + container()->addWidget(_customLibraries, row,row, 1,2); +} + +void ToolConfigWidget::createHexFormatEntry() +{ + uint row = container()->numRows(); + QLabel *label = new QLabel(i18n("Hex file format:"), container()); + container()->addWidget(label, row,row, 0,0); + _hexFormat = new QComboBox(container()); + connect(_hexFormat, SIGNAL(activated(int)), SIGNAL(changed())); + for (uint i=0; iinsertItem(HexBuffer::FORMATS[i]); + _hexFormat->insertItem(i18n("as in LIST directive")); + container()->addWidget(_hexFormat, row,row, 1,1); +} + +void ToolConfigWidget::loadConfig() +{ + loadConfig(*_config); + if ( _config->customArguments(_category).isEmpty() ) resetCustomArguments(); + else updateArguments(); +} + +void ToolConfigWidget::resetCustomArguments() +{ + _argumentsEditor->setTexts(arguments(AutomaticArguments)); + updateArguments(); +} + +void ToolConfigWidget::loadConfig(const Compile::Config &config) +{ + _argumentsType->setCurrentItem(config.hasCustomArguments(_category) ? CustomArguments : AutomaticArguments); + _argumentsEditor->setTexts(config.customArguments(_category)); + if (_includeDirs) _includeDirs->setDirectories(config.rawIncludeDirs(_category)) ; + if (_customOptions) _customOptions->setText(config.rawCustomOptions(_category)); + if (_customLibraries) _customLibraries->setText(config.rawCustomLibraries(_category)); + if (_hexFormat) _hexFormat->setCurrentItem(config.hexFormat()); +} + +void ToolConfigWidget::saveConfig(Compile::Config &config) const +{ + config.setHasCustomArguments(_category, _argumentsType->currentItem()==CustomArguments); + config.setCustomArguments(_category, _argumentsEditor->texts()); + if (_includeDirs) config.setRawIncludeDirs(_category, _includeDirs->directories()); + if (_customOptions) config.setRawCustomOptions(_category, _customOptions->text()); + if (_customLibraries) config.setRawCustomLibraries(_category, _customLibraries->text()); + if (_hexFormat) config.setHexFormat(HexBuffer::Format(_hexFormat->currentItem())); +} + +QStringList ToolConfigWidget::arguments(ArgumentsType type) const +{ + if ( _tmpConfig==0 ) return QStringList(); + saveConfig(*_tmpConfig); + if ( type==AutomaticArguments ) return _process->genericArguments(*_tmpConfig); + return _argumentsEditor->texts(); +} + +void ToolConfigWidget::updateArguments() +{ + ArgumentsType type = ArgumentsType(_argumentsType->currentItem()); + if ( type==AutomaticArguments ) { + _argumentsEditor->hide(); + _container->show(); + } else { + _argumentsEditor->show(); + _container->hide(); + } + _arguments->setText(arguments(type).join(" ")); +} diff --git a/src/tools/gui/tool_config_widget.h b/src/tools/gui/tool_config_widget.h new file mode 100644 index 0000000..5b38753 --- /dev/null +++ b/src/tools/gui/tool_config_widget.h @@ -0,0 +1,79 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * Copyright (C) 2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#ifndef TOOL_CONFIG_WIDGET_H +#define TOOL_CONFIG_WIDGET_H + +#include +#include +#include +#include +#include +#include + +#include "common/gui/container.h" +#include "tools/base/generic_tool.h" +#include "tools/base/tool_group.h" +#include "common/gui/config_widget.h" +#include "common/gui/editlistbox.h" +namespace PURL { class DirectoriesWidget; } + +class ToolConfigWidget : public ::ConfigWidget +{ +Q_OBJECT +public: + ToolConfigWidget(Project *project); + void init(Tool::Category category, const Tool::Group &group); + virtual ~ToolConfigWidget(); + +signals: + void changed(); + void displayHelp(); + +public slots: + virtual void loadConfig(); + virtual void saveConfig() { saveConfig(*_config); } + +private slots: + void updateArguments(); + void resetCustomArguments(); + +protected: + const Tool::Group *_group; + Tool::Category _category; + Project *_project; + QLineEdit *_customOptions, *_customLibraries; + PURL::DirectoriesWidget *_includeDirs; + QComboBox *_hexFormat; + + Container *container() { return _container; } + PURL::DirectoriesWidget * createDirectoriesEntry(const QString &label); + void createIncludeDirectoriesEntry() { _includeDirs = createDirectoriesEntry(i18n("Include directories:")); } + void createCustomOptionsEntry(); + void createCustomLibrariesEntry(); + void createHexFormatEntry(); + virtual void initEntries() = 0; + virtual void loadConfig(const Compile::Config &config); + virtual void saveConfig(Compile::Config &config) const; + +private: + enum ArgumentsType { AutomaticArguments = 0, CustomArguments, Nb_ArgumentsTypes }; + static const char * const ARGUMENTS_TYPE_LABELS[Nb_ArgumentsTypes]; + Compile::Config *_config, *_tmpConfig; + Compile::Process *_process; + Project *_tmpProject; + KComboBox *_argumentsType; + KLineEdit *_arguments; + EditListBox *_argumentsEditor; + Container *_container; + + QStringList arguments(ArgumentsType type) const; +}; + +#endif diff --git a/src/tools/gui/tool_group_ui.cpp b/src/tools/gui/tool_group_ui.cpp new file mode 100644 index 0000000..9bb02dd --- /dev/null +++ b/src/tools/gui/tool_group_ui.cpp @@ -0,0 +1,25 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "tool_group_ui.h" + +#include "tool_config_widget.h" +#include "toolchain_config_widget.h" + +ToolchainConfigWidget *Tool::GroupUI::toolchainConfigWidgetFactory(QWidget *parent) const +{ + return new ToolchainConfigWidget(static_cast(group()), parent); +} + +ToolConfigWidget *Tool::GroupUI::createConfigWidget(Category category, ::Project *project) const +{ + ToolConfigWidget *cw = configWidgetFactory(category, project); + Q_ASSERT(cw); + cw->init(category, static_cast(group())); + return cw; +} diff --git a/src/tools/gui/tool_group_ui.h b/src/tools/gui/tool_group_ui.h new file mode 100644 index 0000000..4d1f42c --- /dev/null +++ b/src/tools/gui/tool_group_ui.h @@ -0,0 +1,32 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef TOOL_GROUP_UI_H +#define TOOL_GROUP_UI_H + +#include "tools/base/tool_group.h" +#include "tools/base/generic_tool.h" +class ToolConfigWidget; +class ToolchainConfigWidget; + +namespace Tool +{ + +class GroupUI : public ::Group::BaseGui +{ +public: + ToolConfigWidget *createConfigWidget(Category category, ::Project *project) const; + virtual ToolConfigWidget *configWidgetFactory(Category category, ::Project *project) const = 0; + virtual ToolchainConfigWidget *toolchainConfigWidgetFactory(QWidget *parent) const; +}; + +inline const GroupUI &groupui(const Base &base) { return static_cast(*base.group().gui()); } + +} // namespace + +#endif diff --git a/src/tools/gui/toolchain_config_center.cpp b/src/tools/gui/toolchain_config_center.cpp new file mode 100644 index 0000000..c8b889d --- /dev/null +++ b/src/tools/gui/toolchain_config_center.cpp @@ -0,0 +1,111 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * Copyright (C) 2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "toolchain_config_center.h" + +#include +#include +#include + +#include "tools/list/tools_config_widget.h" +#include "tools/list/compile_config.h" +#include "tools/list/tool_list.h" +#include "toolchain_config_widget.h" +#include "tool_group_ui.h" + +ToolchainsConfigCenter::ToolchainsConfigCenter(const Tool::Group &sgroup, QWidget *parent) + : TreeListDialog(parent, "configure_toolchains_dialog", true, + i18n("Configure Toolchains"), Ok|User1|User2|Cancel, Cancel, false) +{ + setButtonGuiItem(User1, KStdGuiItem::reset()); + setButtonGuiItem(User2, KGuiItem(i18n("Update"), "reload")); + + _titleBox->addStretch(1); + _infoButton = new KPushButton(KGuiItem(QString::null, "viewmag"), _frame); + connect(_infoButton, SIGNAL(clicked()), SLOT(showInformationDialog())); + _titleBox->addWidget(_infoButton); + + QWidget *current = 0; + FOR_EACH(PURL::SourceFamily, family) { + Tool::Lister::ConstIterator it; + for (it=Tool::lister().begin(); it!=Tool::lister().end(); ++it) { + PURL::FileType type = it.data()->implementationType(family.data().toolType); + if ( type==PURL::Nb_FileTypes || type.data().sourceFamily!=family ) continue; + if ( family==PURL::SourceFamily::Asm && it.data()->implementationType(PURL::ToolType::Compiler)!=PURL::Nb_FileTypes ) continue; + QStringList names = family.label(); + names += it.data()->label(); + QWidget *page = addPage(names); + QVBoxLayout *vbox = new QVBoxLayout(page); + ToolchainConfigWidget *tcw = static_cast(it.data()->gui())->toolchainConfigWidgetFactory(page); + tcw->init(); + tcw->loadConfig(); + vbox->addWidget(tcw); + _pages[page] = tcw; + if ( it.key()==sgroup.name() ) current = page; + } + } + showPage(current); + aboutToShowPageSlot(current); + connect(this, SIGNAL(aboutToShowPage(QWidget *)), SLOT(aboutToShowPageSlot(QWidget *))); +} + +void ToolchainsConfigCenter::aboutToShowPageSlot(QWidget *page) +{ + if ( !_pages.contains(page) ) _infoButton->hide(); + else { + _infoButton->show(); + QTimer::singleShot(0, _pages[page], SLOT(detect())); + } +} + +void ToolchainsConfigCenter::slotApply() +{ + QMap::iterator it; + for (it=_pages.begin(); it!=_pages.end(); ++it) it.data()->saveConfig(); +} + +void ToolchainsConfigCenter::slotOk() +{ + slotApply(); + accept(); +} + +ToolchainConfigWidget *ToolchainsConfigCenter::current() const +{ + int i = activePageIndex(); + if ( i==-1 ) return 0; + QMap::const_iterator it; + for (it=_pages.begin(); it!=_pages.end(); ++it) + if ( pageIndex(it.key())==i ) return it.data(); + Q_ASSERT(false); + return 0; +} + +void ToolchainsConfigCenter::slotUser1() +{ + ToolchainConfigWidget *tcw = current(); + if (tcw) { + tcw->loadConfig(); + tcw->forceDetect(); + } +} + +void ToolchainsConfigCenter::slotUser2() +{ + ToolchainConfigWidget *tcw = current(); + if (tcw) tcw->forceDetect(); +} + +void ToolchainsConfigCenter::showInformationDialog() +{ + ToolchainConfigWidget *tcw = current(); + Q_ASSERT(tcw); + TextEditorDialog dialog(tcw->group().informationText(), tcw->group().label(), true, this); + dialog.exec(); +} diff --git a/src/tools/gui/toolchain_config_center.h b/src/tools/gui/toolchain_config_center.h new file mode 100644 index 0000000..4b2110b --- /dev/null +++ b/src/tools/gui/toolchain_config_center.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * Copyright (C) 2005 Nicolas Hadacek * + * Copyright (C) 2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#ifndef TOOLCHAIN_CONFIG_CENTER_H +#define TOOLCHAIN_CONFIG_CENTER_H + +#include +#include +#include +#include + +#include "tools/gui/tool_config_widget.h" +#include "common/gui/dialog.h" +class ToolchainConfigWidget; + +class ToolchainsConfigCenter : public TreeListDialog +{ +Q_OBJECT +public: + ToolchainsConfigCenter(const Tool::Group &group, QWidget *parent); + +public slots: + virtual void slotOk(); + virtual void slotApply(); + virtual void slotUser1(); + virtual void slotUser2(); + +private slots: + void aboutToShowPageSlot(QWidget *page); + void showInformationDialog(); + +private: + KPushButton *_infoButton; + QMap _pages; + + ToolchainConfigWidget *current() const; +}; + +#endif diff --git a/src/tools/gui/toolchain_config_widget.cpp b/src/tools/gui/toolchain_config_widget.cpp new file mode 100644 index 0000000..aede699 --- /dev/null +++ b/src/tools/gui/toolchain_config_widget.cpp @@ -0,0 +1,301 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "toolchain_config_widget.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "tools/list/compile_config.h" +#include "common/gui/purl_gui.h" +#include "common/global/process.h" +#include "common/gui/container.h" + +//---------------------------------------------------------------------------- +ToolchainConfigWidget::ToolchainConfigWidget(const Tool::Group &group, QWidget *parent) + : ::ConfigWidget(parent), + _group(group), _dirty(false), _outputType(0), _devicesData(group.nbCheckDevices()) +{ + _config = group.createConfig(0); +} + +ToolchainConfigWidget::~ToolchainConfigWidget() +{ + delete _config; +} + +void ToolchainConfigWidget::init() +{ + Container *container = new Container(this, Container::Sunken); + addWidget(container, 0,0, 0,3); + container->setColStretch(3, 1); + + uint row = 0; + QLabel *label = new QLabel(Compile::DirectoryType(Compile::DirectoryType::Executable).label() + ":", container); + container->addWidget(label, row,row, 0,0); + _dirs[Compile::DirectoryType::Executable] = new PURL::DirectoryWidget(container); + connect(_dirs[Compile::DirectoryType::Executable], SIGNAL(changed()), SLOT(forceDetect())); + container->addWidget(_dirs[Compile::DirectoryType::Executable], row,row, 1,3); + row++; + + label = new QLabel(i18n("Executable Type:"), container); + container->addWidget(label, row,row, 0,0); + _execType = new QComboBox(container); + FOR_EACH(Tool::ExecutableType, type) _execType->insertItem(type.label()); + connect(_execType, SIGNAL(activated(int)), SLOT(forceDetect())); + container->addWidget(_execType, row,row, 1,2); + row++; + + uint nbOutputTypes = 0; + FOR_EACH(Tool::OutputExecutableType, type) + if ( _group.hasOutputExecutableType(type) ) nbOutputTypes++; + if ( nbOutputTypes>1 ) { + label = new QLabel(i18n("Output Executable Type:"), container); + container->addWidget(label, row,row, 0,0); + _outputType = new KeyComboBox(container); + FOR_EACH(Tool::OutputExecutableType, type) + if ( _group.hasOutputExecutableType(type) ) _outputType->appendItem(type, type.label()); + connect(_outputType->widget(), SIGNAL(activated(int)), SLOT(forceDetect())); + container->addWidget(_outputType->widget(), row,row, 1,1); + row++; + } + + addCustomExecutableOptions(container); + + FOR_EACH(Tool::Category, k) { + const Tool::Base *base = _group.base(k); + if ( base==0 ) continue; + label = new QLabel(k.label(), container); + container->addWidget(label, row,row, 0,0); + _data[k].label = new QLabel(container); + container->addWidget(_data[k].label, row,row, 1,1); + _data[k].button = new KPushButton(KGuiItem(QString::null, "viewmag"), container); + connect(_data[k].button, SIGNAL(clicked()), SLOT(showDetails())); + container->addWidget(_data[k].button, row,row, 2,2); + row++; + } + + label = new QLabel(i18n("Device detection:"), container); + container->addWidget(label, row,row, 0,0); + _devicesLabel = new QLabel(container); + container->addWidget(_devicesLabel, row,row, 1,1); + KPushButton *button = new KPushButton(KGuiItem(QString::null, "viewmag"), container); + connect(button, SIGNAL(clicked()), SLOT(showDeviceDetails())); + container->addWidget(button, row,row, 2,2); + row++; + + row = numRows(); + FOR_EACH(Compile::DirectoryType, type) { + if ( type==Compile::DirectoryType::Executable ) continue; + if ( !_group.hasDirectory(type) ) _dirs[type] = 0; + else { + label = new QLabel(type.label() + ":", this); + addWidget(label, row,row, 0,0); + _dirs[type] = new PURL::DirectoryWidget(this); + addWidget(_dirs[type], row,row, 1,3); + row++; + } + } + + if ( !_group.comment().isEmpty() ) { + KTextEdit *w = new KTextEdit(_group.comment(), QString::null, this); + w->setReadOnly(true); + w->setWordWrap(QTextEdit::WidgetWidth); + addWidget(w, row,row, 0,3); + row++; + } + + setColStretch(3, 1); +} + +void ToolchainConfigWidget::loadConfig() +{ + _execType->blockSignals(true); + _execType->setCurrentItem(Compile::Config::withWine(_group) ? Tool::ExecutableType::Windows : Tool::ExecutableType::Unix); + _execType->blockSignals(false); + if (_outputType) { + _outputType->widget()->blockSignals(true); + _outputType->setCurrentItem(Compile::Config::outputExecutableType(_group)); + _outputType->widget()->blockSignals(false); + } + FOR_EACH(Compile::DirectoryType, type) { + if ( _dirs[type]==0 ) continue; + _dirs[type]->blockSignals(true); + _dirs[type]->setDirectory(Compile::Config::directory(_group, type)); + _dirs[type]->blockSignals(false); + } + _dirty = true; +} + +void ToolchainConfigWidget::saveConfig() +{ + Compile::Config::setWithWine(_group, withWine()); + if (_outputType) Compile::Config::setOutputExecutableType(_group, outputType()); + FOR_EACH(Compile::DirectoryType, type) + if ( _dirs[type] ) Compile::Config::setDirectory(_group, type, _dirs[type]->directory()); +} + +void ToolchainConfigWidget::forceDetect() +{ + _dirty = true; + detect(); +} + +void ToolchainConfigWidget::checkExecutableDone() +{ + FOR_EACH(Tool::Category, i) { + if ( _data[i].process!=sender() ) continue; + if ( _data[i].process->state()==::Process::Timedout ) { + _data[i].label->setText(i18n("Timeout")); + return; + } + _data[i].checkLines = _data[i].process->sout() + _data[i].process->serr(); + const Tool::Base *base = _group.base(i); + QString exec = base->baseExecutable(withWine(), outputType()); + if ( base->checkExecutableResult(withWine(), _data[i].checkLines) ) _data[i].label->setText(i18n("\"%1\" found").arg(exec)); + else _data[i].label->setText(i18n("\"%1\" not recognized").arg(exec)); + break; + } +} + +void ToolchainConfigWidget::checkDevicesDone() +{ + for(uint i=0; i<_devicesData.count(); i++) { + if ( _devicesData[i].process!=sender() ) continue; + if ( _devicesData[i].process->state()==::Process::Timedout ) { + _devicesLabel->setText(i18n("Timeout")); + return; + } + _devicesData[i].checkLines = _devicesData[i].process->sout() + _devicesData[i].process->serr(); + _devicesData[i].done = true; + break; + } + QValueList list; + for(uint i=0; i<_devicesData.count(); i++) { + if ( !_devicesData[i].done ) return; + list += _group.getSupportedDevices(_devicesData[i].checkLines.join("\n")); + } + _devicesLabel->setText(i18n("Detected (%1)").arg(list.count())); +} + +bool ToolchainConfigWidget::withWine() const +{ + return ( _execType->currentItem()==Tool::ExecutableType::Windows ); +} + +Tool::OutputExecutableType ToolchainConfigWidget::outputType() const +{ + return (_outputType==0 ? Compile::Config::outputExecutableType(_group) : _outputType->currentItem()); +} + +QString ToolchainConfigWidget::baseExecutable(Tool::Category category) const +{ + return _group.base(category)->baseExecutable(withWine(), outputType()); +} + +::Process::LineOutput *ToolchainConfigWidget::checkExecutableProcess(Tool::Category category) const +{ + PURL::Directory execDir = _dirs[Compile::DirectoryType::Executable]->directory(); + return _group.base(category)->checkExecutableProcess(execDir, withWine(), outputType()); +} + +::Process::LineOutput *ToolchainConfigWidget::checkDevicesProcess(uint i) const +{ + PURL::Directory execDir = _dirs[Compile::DirectoryType::Executable]->directory(); + return _group.checkDevicesProcess(i, execDir, withWine()); +} + +void ToolchainConfigWidget::detect() +{ + if ( !_dirty ) return; + FOR_EACH(Tool::Category, k) { + if ( _data[k].label==0 ) continue; + if ( !_group.base(k)->checkExecutable() ) _data[k].label->setText(i18n("Unknown")); + else { + delete _data[k].process; + _data[k].checkLines.clear(); + _data[k].process = checkExecutableProcess(k); + _data[k].command = _data[k].process->prettyCommand(); + connect(_data[k].process, SIGNAL(done(int)), SLOT(checkExecutableDone())); + connect(_data[k].process, SIGNAL(timeout()), SLOT(checkExecutableDone())); + QString exec = baseExecutable(k); + if ( !_data[k].process->start(10000) ) _data[k].label->setText(i18n("\"%1\" not found").arg(exec)); + else _data[k].label->setText(i18n("Detecting \"%1\"...").arg(exec)); + } + } + if ( _group.checkDevicesCategory()==Tool::Category::Nb_Types ) { + QValueVector supported = _group.supportedDevices(); + _devicesLabel->setText(i18n("Hardcoded (%1)").arg(supported.count())); + } else { + for (uint i=0; i<_devicesData.count(); i++) { + delete _devicesData[i].process; + _devicesData[i].process = checkDevicesProcess(i); + _devicesData[i].command = _devicesData[i].process->prettyCommand(); + connect(_devicesData[i].process, SIGNAL(done(int)), SLOT(checkDevicesDone())); + connect(_devicesData[i].process, SIGNAL(timeout()), SLOT(checkDevicesDone())); + _devicesData[i].done = false; + _devicesData[i].checkLines.clear(); + if ( !_devicesData[i].process->start(10000) ) _devicesLabel->setText(i18n("Failed")); + else _devicesLabel->setText(i18n("Detecting ...")); + } + } + FOR_EACH(Compile::DirectoryType, type) { + if ( _dirs[type]==0 || type==Compile::DirectoryType::Executable ) continue; + PURL::Directory execDir = _dirs[Compile::DirectoryType::Executable]->directory(); + PURL::Directory dir = _group.autodetectDirectory(type, execDir, withWine()); + if ( !dir.isEmpty() ) _dirs[type]->setDirectory(dir); + } + _dirty = false; +} + +void ToolchainConfigWidget::showDetails() +{ + FOR_EACH(Tool::Category, k) { + if ( sender()!=_data[k].button ) continue; + QString s; + const Tool::Base *base = _group.base(k); + if ( base->checkExecutable() ) { + s += i18n("Command for executable detection:
%1
").arg(_data[k].command); + s += i18n("Version string:
%1
").arg(_data[k].checkLines.join("
")); + } else s += i18n("This tool cannot be automatically detected."); + MessageBox::text(s, Log::Show); + break; + } +} + +void ToolchainConfigWidget::showDeviceDetails() +{ + QString s; + if ( _group.checkDevicesCategory()==Tool::Category::Nb_Types ) { + s += ""; + QValueVector supported = _group.supportedDevices(); + for (uint i=0; iCommand for devices detection:
%1
").arg(_devicesData[i].command); + else s += i18n("Command #%1 for devices detection:
%2
").arg(i+1).arg(_devicesData[i].command); + QString ss = _devicesData[i].checkLines.join("
"); + if ( nb==1 ) s += i18n("Device string:
%1
").arg(ss); + else s += i18n("Device string #%1:
%2
").arg(i+1).arg(ss); + } + } + MessageBox::text(s, Log::Show); +} diff --git a/src/tools/gui/toolchain_config_widget.h b/src/tools/gui/toolchain_config_widget.h new file mode 100644 index 0000000..ad7978a --- /dev/null +++ b/src/tools/gui/toolchain_config_widget.h @@ -0,0 +1,85 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef TOOLCHAIN_CONFIG_WIDGET_H +#define TOOLCHAIN_CONFIG_WIDGET_H + +#include +#include +#include +#include + +#include "common/gui/key_gui.h" +#include "common/global/process.h" +#include "common/gui/config_widget.h" +#include "tools/list/compile_process.h" +class Container; +namespace PURL { class DirectoryWidget; } +namespace Tool { class Group; } + +//---------------------------------------------------------------------------- +class ToolchainConfigWidget : public ::ConfigWidget +{ + Q_OBJECT +public: + ToolchainConfigWidget(const Tool::Group &group, QWidget *parent); + virtual ~ToolchainConfigWidget(); + const Tool::Group &group() const { return _group; } + void init(); + +public slots: + void detect(); + void forceDetect(); + virtual void loadConfig(); + virtual void saveConfig(); + +protected: + bool withWine() const; + Tool::OutputExecutableType outputType() const; + virtual void addCustomExecutableOptions(Container *) {} + virtual QString baseExecutable(Tool::Category category) const; + virtual ::Process::LineOutput *checkExecutableProcess(Tool::Category category) const; + virtual ::Process::LineOutput *checkDevicesProcess(uint i) const; + +protected slots: + void showDetails(); + void showDeviceDetails(); + void checkExecutableDone(); + void checkDevicesDone(); + +protected: + const Tool::Group &_group; + Compile::Config *_config; + bool _dirty; + QComboBox *_execType; + KeyComboBox *_outputType; + QLabel *_devicesLabel; + QMap _dirs; + class ExecData { + public: + ExecData() : label(0), button(0), process(0) {} + ~ExecData() { delete process; } + QLabel *label; + QString command; + QStringList checkLines; + KPushButton *button; + ::Process::LineOutput *process; + }; + QMap _data; + class DevicesData { + public: + DevicesData() : process(0) {} + bool done; + QString command; + QStringList checkLines; + ::Process::LineOutput *process; + }; + QValueVector _devicesData; +}; + +#endif diff --git a/src/tools/jal/Makefile.am b/src/tools/jal/Makefile.am new file mode 100644 index 0000000..b0d8b43 --- /dev/null +++ b/src/tools/jal/Makefile.am @@ -0,0 +1,8 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libjal.la +libjal_la_LDFLAGS = $(all_libraries) +libjal_la_SOURCES = jal_compile.cpp jal_config.cpp jal.cpp jal_generator.cpp + +SUBDIRS = gui \ No newline at end of file diff --git a/src/tools/jal/gui/Makefile.am b/src/tools/jal/gui/Makefile.am new file mode 100644 index 0000000..60341d3 --- /dev/null +++ b/src/tools/jal/gui/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libjalui.la +libjalui_la_LDFLAGS = $(all_libraries) +libjalui_la_SOURCES = jal_ui.cpp diff --git a/src/tools/jal/gui/jal_ui.cpp b/src/tools/jal/gui/jal_ui.cpp new file mode 100644 index 0000000..4300de0 --- /dev/null +++ b/src/tools/jal/gui/jal_ui.cpp @@ -0,0 +1,14 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "jal_ui.h" + +//---------------------------------------------------------------------------- +JAL::ConfigWidget::ConfigWidget(Project *project) + : ToolConfigWidget(project) +{} diff --git a/src/tools/jal/gui/jal_ui.h b/src/tools/jal/gui/jal_ui.h new file mode 100644 index 0000000..aa6957e --- /dev/null +++ b/src/tools/jal/gui/jal_ui.h @@ -0,0 +1,35 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef JAL_UI_H +#define JAL_UI_H + +#include "tools/gui/tool_config_widget.h" +#include "tools/gui/tool_group_ui.h" + +namespace JAL +{ +//---------------------------------------------------------------------------- +class ConfigWidget : public ToolConfigWidget +{ +Q_OBJECT +public: + ConfigWidget(Project *project); + virtual void initEntries() {} +}; + +//---------------------------------------------------------------------------- +class GroupUI : public Tool::GroupUI +{ +public: + virtual ToolConfigWidget *configWidgetFactory(Tool::Category, ::Project *project) const { return new ConfigWidget(project); } +}; + +} // namespace + +#endif diff --git a/src/tools/jal/jal.cpp b/src/tools/jal/jal.cpp new file mode 100644 index 0000000..009ea21 --- /dev/null +++ b/src/tools/jal/jal.cpp @@ -0,0 +1,72 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "jal.h" + +#include "jal_compile.h" +#include "jal_config.h" +#include "devices/pic/pic/pic_memory.h" +#include "devices/list/device_list.h" +#include "common/global/process.h" +#include "jal_generator.h" + +//---------------------------------------------------------------------------- +bool JAL::Base::checkExecutableResult(bool, QStringList &lines) const +{ + QStringList tmp; + for (uint i=0; i0 && lines[0].startsWith("jal") ); +} + +//---------------------------------------------------------------------------- +QString JAL::Group::informationText() const +{ + return i18n("JAL is a high-level language for PIC microcontrollers.").arg("http://jal.sourceforge.net"); +} + +Tool::Group::BaseData JAL::Group::baseFactory(Tool::Category category) const +{ + if ( category==Tool::Category::Compiler ) return BaseData(new ::JAL::Base, Both); + return BaseData(); +} + +const char * const SUPPORTED_DEVICES[] = { + "12C508", "12C509A", "12CE674", "12F629", "12F675", + "16C84", "16F84", "16F88", "16F873", "16F876", "16F877", "16F628", + "18F242", "18F252", "18F442", "18F452", + 0 +}; + +QValueList JAL::Group::getSupportedDevices(const QString &) const +{ + QValueList list; + for (uint i=0; SUPPORTED_DEVICES[i]; i++) { + const Device::Data *data = Device::lister().data(SUPPORTED_DEVICES[i]); + Q_ASSERT(data); + list.append(data); + } + return list; +} + +Compile::Process *JAL::Group::processFactory(const Compile::Data &data) const +{ + Q_ASSERT( data.category==Tool::Category::Compiler ); + return new CompileFile; +} + +Compile::Config *JAL::Group::configFactory(::Project *project) const +{ + return new Config(project); +} + +Tool::SourceGenerator *JAL::Group::sourceGeneratorFactory() const +{ + return new SourceGenerator; +} diff --git a/src/tools/jal/jal.h b/src/tools/jal/jal.h new file mode 100644 index 0000000..0c0d790 --- /dev/null +++ b/src/tools/jal/jal.h @@ -0,0 +1,49 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef JAL_H +#define JAL_H + +#include "tools/base/tool_group.h" + +namespace JAL +{ +//---------------------------------------------------------------------------- +class Base : public Tool::Base +{ +public: + virtual QString baseExecutable(bool, Tool::OutputExecutableType) const { return "jal"; } + +private: + virtual QStringList checkExecutableOptions(bool) const { return QStringList(); } + virtual bool checkExecutableResult(bool withWine, QStringList &lines) const; +}; + +//---------------------------------------------------------------------------- +class Group : public Tool::Group +{ +public: + virtual QString name() const { return "jal"; } + virtual QString label() const { return i18n("JAL"); } + virtual QString informationText() const; + virtual Tool::Category checkDevicesCategory() const { return Tool::Category::Nb_Types; } + virtual Tool::ExecutableType preferedExecutableType() const { return Tool::ExecutableType::Unix; } + virtual Tool::CompileType compileType() const { return Tool::AllFiles; } + virtual PURL::FileType implementationType(PURL::ToolType type) const { return (type==PURL::ToolType::Compiler ? PURL::JalSource : PURL::Nb_FileTypes); } + +private: + virtual BaseData baseFactory(Tool::Category c) const; + virtual QValueList getSupportedDevices(const QString &s) const; + virtual Compile::Process *processFactory(const Compile::Data &data) const; + virtual Compile::Config *configFactory(::Project *project) const; + virtual Tool::SourceGenerator *sourceGeneratorFactory() const; +}; + +} // namespace + +#endif diff --git a/src/tools/jal/jal_compile.cpp b/src/tools/jal/jal_compile.cpp new file mode 100644 index 0000000..4d62e68 --- /dev/null +++ b/src/tools/jal/jal_compile.cpp @@ -0,0 +1,26 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "jal_compile.h" + +void JAL::CompileFile::logStderrLine(const QString &line) +{ + if ( line.contains('\r') ) return; // what are those lines ? + // #### TODO + doLog(Log::LineType::Normal, line, QString::null, 0); // unrecognized +} + +QStringList JAL::CompileFile::genericArguments(const Compile::Config &) const +{ + return "%I"; +} + +QString JAL::CompileFile::outputFiles() const +{ + return "PURL::AsmGPAsm PURL::Hex"; +} diff --git a/src/tools/jal/jal_compile.h b/src/tools/jal/jal_compile.h new file mode 100644 index 0000000..e63f603 --- /dev/null +++ b/src/tools/jal/jal_compile.h @@ -0,0 +1,29 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef JAL_COMPILE_H +#define JAL_COMPILE_H + +#include "tools/list/compile_process.h" + +namespace JAL +{ +//----------------------------------------------------------------------------- +class CompileFile : public Compile::Process +{ +Q_OBJECT +protected: + virtual QString deviceName() const { return _data.device; } + virtual void logStderrLine(const QString &line); + virtual QStringList genericArguments(const Compile::Config &config) const; + virtual QString outputFiles() const; +}; + +} // namespace + +#endif diff --git a/src/tools/jal/jal_config.cpp b/src/tools/jal/jal_config.cpp new file mode 100644 index 0000000..c51ddf6 --- /dev/null +++ b/src/tools/jal/jal_config.cpp @@ -0,0 +1,9 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "jal_config.h" diff --git a/src/tools/jal/jal_config.h b/src/tools/jal/jal_config.h new file mode 100644 index 0000000..0d0a513 --- /dev/null +++ b/src/tools/jal/jal_config.h @@ -0,0 +1,25 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef JAL_CONFIG_H +#define JAL_CONFIG_H + +#include "tools/list/compile_config.h" + +namespace JAL +{ + +class Config : public Compile::Config +{ +public: + Config(Project *project) : Compile::Config(project) {} +}; + +} // namespace + +#endif diff --git a/src/tools/jal/jal_generator.cpp b/src/tools/jal/jal_generator.cpp new file mode 100644 index 0000000..6aa9b08 --- /dev/null +++ b/src/tools/jal/jal_generator.cpp @@ -0,0 +1,35 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "jal_generator.h" + +#include "devices/pic/base/pic.h" + +SourceLine::List JAL::SourceGenerator::configLines(PURL::ToolType, const Device::Memory &, bool &) const +{ + // no config lines (?) + return SourceLine::List(); +} + +SourceLine::List JAL::SourceGenerator::includeLines(PURL::ToolType, const Device::Data &data) const +{ + SourceLine::List lines; + lines.appendNotIndentedCode("include " + data.name().lower() + "_10", i18n("10MHz crystal")); + lines.appendNotIndentedCode("include jlib", i18n("jal standard library")); + return lines; +} + +SourceLine::List JAL::SourceGenerator::sourceFileContent(PURL::ToolType, const Device::Data &, bool &) const +{ + SourceLine::List lines; + lines.appendTitle(i18n("main code")); + lines.appendNotIndentedCode(QString::null, "<< " + i18n("insert code") + " >>"); + lines.appendNotIndentedCode("forever loop", i18n("loop forever")); + lines.appendNotIndentedCode("end loop"); + return lines; +} diff --git a/src/tools/jal/jal_generator.h b/src/tools/jal/jal_generator.h new file mode 100644 index 0000000..b6beddb --- /dev/null +++ b/src/tools/jal/jal_generator.h @@ -0,0 +1,27 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef JAL_GENERATOR_H +#define JAL_GENERATOR_H + +#include "tools/base/tool_group.h" + +namespace JAL +{ + +class SourceGenerator : public Tool::SourceGenerator +{ +public: + virtual SourceLine::List configLines(PURL::ToolType type, const Device::Memory &memory, bool &ok) const; + virtual SourceLine::List sourceFileContent(PURL::ToolType type, const Device::Data &data, bool &ok) const; + virtual SourceLine::List includeLines(PURL::ToolType type, const Device::Data &data) const; +}; + +} // namespace + +#endif diff --git a/src/tools/jalv2/Makefile.am b/src/tools/jalv2/Makefile.am new file mode 100644 index 0000000..3b59ea9 --- /dev/null +++ b/src/tools/jalv2/Makefile.am @@ -0,0 +1,8 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libjalv2.la +libjalv2_la_SOURCES = jalv2_compile.cpp jalv2_config.cpp jalv2.cpp +libjalv2_la_LDFLAGS = $(all_libraries) + +SUBDIRS = gui \ No newline at end of file diff --git a/src/tools/jalv2/gui/Makefile.am b/src/tools/jalv2/gui/Makefile.am new file mode 100644 index 0000000..92e338c --- /dev/null +++ b/src/tools/jalv2/gui/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libjalv2ui.la +libjalv2ui_la_SOURCES = jalv2_ui.cpp +libjalv2ui_la_LDFLAGS = $(all_libraries) diff --git a/src/tools/jalv2/gui/jalv2_ui.cpp b/src/tools/jalv2/gui/jalv2_ui.cpp new file mode 100644 index 0000000..0990c6d --- /dev/null +++ b/src/tools/jalv2/gui/jalv2_ui.cpp @@ -0,0 +1,19 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "jalv2_ui.h" + +//---------------------------------------------------------------------------- +JALV2::ConfigWidget::ConfigWidget(Project *project) + : ToolConfigWidget(project) +{} + +void JALV2::ConfigWidget::initEntries() +{ + createIncludeDirectoriesEntry(); +} diff --git a/src/tools/jalv2/gui/jalv2_ui.h b/src/tools/jalv2/gui/jalv2_ui.h new file mode 100644 index 0000000..93085c1 --- /dev/null +++ b/src/tools/jalv2/gui/jalv2_ui.h @@ -0,0 +1,35 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef JALV2_UI_H +#define JALV2_UI_H + +#include "tools/gui/tool_config_widget.h" +#include "tools/gui/tool_group_ui.h" + +namespace JALV2 +{ +//---------------------------------------------------------------------------- +class ConfigWidget : public ToolConfigWidget +{ +Q_OBJECT +public: + ConfigWidget(Project *project); + virtual void initEntries(); +}; + +//---------------------------------------------------------------------------- +class GroupUI : public Tool::GroupUI +{ +public: + virtual ToolConfigWidget *configWidgetFactory(Tool::Category, ::Project *project) const { return new ConfigWidget(project); } +}; + +} // namespace + +#endif diff --git a/src/tools/jalv2/jalv2.cpp b/src/tools/jalv2/jalv2.cpp new file mode 100644 index 0000000..1d910b8 --- /dev/null +++ b/src/tools/jalv2/jalv2.cpp @@ -0,0 +1,77 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "jalv2.h" + +#include "jalv2_compile.h" +#include "jalv2_config.h" +#include "devices/pic/pic/pic_memory.h" +#include "devices/list/device_list.h" +#include "common/global/process.h" +#include "tools/jal/jal_generator.h" + +//---------------------------------------------------------------------------- +bool JALV2::Base::checkExecutableResult(bool, QStringList &lines) const +{ + QStringList tmp; + for (uint i=0; i0 && lines[0].startsWith("jal") ); +} + +//---------------------------------------------------------------------------- +QString JALV2::Group::informationText() const +{ + return i18n("JAL V2 is a new compiler for the high-level language JAL.").arg("http://www.casadeyork.com/jalv2"); +} + +Tool::Group::BaseData JALV2::Group::baseFactory(Tool::Category category) const +{ + if ( category==Tool::Category::Compiler ) return BaseData(new ::JALV2::Base, Both); + return BaseData(); +} + +const char * const SUPPORTED_DEVICES[] = { + "12C509A", "12F675", + "16F628", + "16F818", "16F819", + "16C84", "16F84", + "16F87", "16F88", + "16F873", "16F874", "16F876", "16F877", + "16F873A", "16F874A", "16F876A", "16F877A", + "18F242", "18F252", "18F452", + 0 +}; + +QValueList JALV2::Group::getSupportedDevices(const QString &) const +{ + QValueList list; + for (uint i=0; SUPPORTED_DEVICES[i]; i++) { + const Device::Data *data = Device::lister().data(SUPPORTED_DEVICES[i]); + Q_ASSERT(data); + list.append(data); + } + return list; +} + +Compile::Process *JALV2::Group::processFactory(const Compile::Data &data) const +{ + Q_ASSERT( data.category==Tool::Category::Compiler ); + return new CompileFile; +} + +Compile::Config *JALV2::Group::configFactory(::Project *project) const +{ + return new Config(project); +} + +Tool::SourceGenerator *JALV2::Group::sourceGeneratorFactory() const +{ + return new JAL::SourceGenerator; +} diff --git a/src/tools/jalv2/jalv2.h b/src/tools/jalv2/jalv2.h new file mode 100644 index 0000000..80c3d02 --- /dev/null +++ b/src/tools/jalv2/jalv2.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef JALV2_H +#define JALV2_H + +#include "tools/base/tool_group.h" + +namespace JALV2 +{ +//---------------------------------------------------------------------------- +class Base : public Tool::Base +{ +public: + virtual QString baseExecutable(bool, Tool::OutputExecutableType) const { return "jalv2"; } + +private: + virtual QStringList checkExecutableOptions(bool) const { return QStringList(); } + virtual bool checkExecutableResult(bool withWine, QStringList &lines) const; +}; + +//---------------------------------------------------------------------------- +class Group : public Tool::Group +{ +public: + virtual QString name() const { return "jalv2"; } + virtual QString label() const { return i18n("JAL V2"); } + virtual QString informationText() const; + virtual bool hasDirectory(Compile::DirectoryType type) const { return type==Compile::DirectoryType::Header; } + virtual Tool::Category checkDevicesCategory() const { return Tool::Category::Nb_Types; } + virtual Tool::ExecutableType preferedExecutableType() const { return Tool::ExecutableType::Unix; } + virtual Tool::CompileType compileType() const { return Tool::AllFiles; } + virtual PURL::FileType implementationType(PURL::ToolType type) const { return (type==PURL::ToolType::Compiler ? PURL::JalSource : PURL::Nb_FileTypes); } + +private: + virtual BaseData baseFactory(Tool::Category c) const; + virtual QValueList getSupportedDevices(const QString &s) const; + virtual Compile::Process *processFactory(const Compile::Data &data) const; + virtual Compile::Config *configFactory(::Project *project) const; + virtual Tool::SourceGenerator *sourceGeneratorFactory() const; +}; + +} // namespace + +#endif diff --git a/src/tools/jalv2/jalv2_compile.cpp b/src/tools/jalv2/jalv2_compile.cpp new file mode 100644 index 0000000..0b1e7f5 --- /dev/null +++ b/src/tools/jalv2/jalv2_compile.cpp @@ -0,0 +1,43 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "jalv2_compile.h" + +#include "jalv2.h" +#include "common/common/misc.h" +#include "tools/list/compile_config.h" + +QStringList JALV2::CompileFile::genericArguments(const Compile::Config &config) const +{ + QStringList args; + QStringList includes = config.includeDirs(Tool::Category::Compiler, QString::null, QString::null, ";"); + QString s = (includes.isEmpty() ? QString::null : includes[0]); + PURL::Directory dir = Compile::Config::directory(group(), Compile::DirectoryType::Header).path(); + if ( !dir.isEmpty() ) { + if ( !s.isEmpty() ) s += ";"; + s += dir.path(); + } + if ( !s.isEmpty() ) { + args += "-s"; + args += s; + } + args += "%I"; + return args; +} + +void JALV2::CompileFile::logStderrLine(const QString &line) +{ + if ( parseErrorLine(line, Compile::ParseErrorData("([^:]*):([0-9]+):\\s*(warning)(.+)", 1, 2, 4, 3)) ) return; + if ( parseErrorLine(line, Compile::ParseErrorData("([^:]*):([0-9]+):\\s*(.+)", 1, 2, 3, Log::LineType::Error)) ) return; + doLog(Log::LineType::Normal, line, QString::null, 0); // unrecognized +} + +QString JALV2::CompileFile::outputFiles() const +{ + return "PURL::AsmGPAsm PURL::Hex"; +} diff --git a/src/tools/jalv2/jalv2_compile.h b/src/tools/jalv2/jalv2_compile.h new file mode 100644 index 0000000..de0257d --- /dev/null +++ b/src/tools/jalv2/jalv2_compile.h @@ -0,0 +1,28 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef JALV2_COMPILE_H +#define JALV2_COMPILE_H + +#include "tools/list/compile_process.h" + +namespace JALV2 +{ +class CompileFile : public Compile::Process +{ +Q_OBJECT +protected: + virtual QString deviceName() const { return _data.device; } + virtual void logStderrLine(const QString &line); + virtual QStringList genericArguments(const Compile::Config &config) const; + virtual QString outputFiles() const; +}; + +} // namespace + +#endif diff --git a/src/tools/jalv2/jalv2_config.cpp b/src/tools/jalv2/jalv2_config.cpp new file mode 100644 index 0000000..c172c5e --- /dev/null +++ b/src/tools/jalv2/jalv2_config.cpp @@ -0,0 +1,9 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "jalv2_config.h" diff --git a/src/tools/jalv2/jalv2_config.h b/src/tools/jalv2/jalv2_config.h new file mode 100644 index 0000000..e2811d3 --- /dev/null +++ b/src/tools/jalv2/jalv2_config.h @@ -0,0 +1,25 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef JALV2_CONFIG_H +#define JALV2_CONFIG_H + +#include "tools/list/compile_config.h" + +namespace JALV2 +{ + +class Config : public Compile::Config +{ +public: + Config(Project *project) : Compile::Config(project) {} +}; + +} // namespace + +#endif diff --git a/src/tools/list/Makefile.am b/src/tools/list/Makefile.am new file mode 100644 index 0000000..9d62533 --- /dev/null +++ b/src/tools/list/Makefile.am @@ -0,0 +1,7 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libtoollist.la +libtoollist_la_LDFLAGS = $(all_libraries) +libtoollist_la_SOURCES = tool_list.cpp tools_config_widget.cpp \ + compile_config.cpp device_info.cpp compile_manager.cpp compile_process.cpp diff --git a/src/tools/list/compile_config.cpp b/src/tools/list/compile_config.cpp new file mode 100644 index 0000000..5ec8dfc --- /dev/null +++ b/src/tools/list/compile_config.cpp @@ -0,0 +1,189 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "compile_config.h" + +#include "common/global/generic_config.h" +#include "devices/list/device_list.h" +#include "libgui/project.h" +#include "tool_list.h" + +//---------------------------------------------------------------------------- +PURL::Directory Compile::Config::directory(const Tool::Group &group, DirectoryType type) +{ + QString def; + if ( type!=DirectoryType::Executable ) + def = group.autodetectDirectory(type, directory(group, DirectoryType::Executable), withWine(group)).path(); + return PURL::Directory(value(group.name(), QString::null, type.key() + QString("_path"), def)); +} +void Compile::Config::setDirectory(const Tool::Group &group, DirectoryType type, const PURL::Directory &dir) +{ + setValue(group.name(), QString::null, type.key() + QString("_path"), dir.path()); + if ( type==DirectoryType::Executable ) const_cast(group).init(); +} + +bool Compile::Config::withWine(const Tool::Group &group) +{ + QString def = (group.preferedExecutableType()==Tool::ExecutableType::Unix ? "false" : "true"); + return ( value(group.name(), QString::null, "with_wine", def)=="true" ); +} +void Compile::Config::setWithWine(const Tool::Group &group, bool withWine) +{ + setValue(group.name(), QString::null, "with_wine", withWine ? "true" : "false"); + const_cast(group).init(); +} + +Tool::OutputExecutableType Compile::Config::outputExecutableType(const Tool::Group &group) +{ + QString s = value(group.name(), QString::null, "output_type", Tool::OutputExecutableType(Tool::OutputExecutableType::Coff).key()); + return Tool::OutputExecutableType::fromKey(s); +} +void Compile::Config::setOutputExecutableType(const Tool::Group &group, Tool::OutputExecutableType type) +{ + setValue(group.name(), QString::null, "output_type", type.key()); + const_cast(group).init(); +} + +QString Compile::Config::value(const QString &group, const QString &subGroup, const QString &key, const QString &defaultValue) +{ + QString grp = (subGroup.isEmpty() ? group : group + '-' + subGroup); + GenericConfig gc(grp); + return gc.readEntry(key, defaultValue); +} +void Compile::Config::setValue(const QString &group, const QString &subGroup, const QString &key, const QString &value) +{ + QString grp = (subGroup.isEmpty() ? group : group + '-' + subGroup); + GenericConfig gc(grp); + gc.writeEntry(key, value); +} +QStringList Compile::Config::listValues(const QString &group, const QString &subGroup, const QString &key, const QStringList &defaultValues) +{ + QString grp = (subGroup.isEmpty() ? group : group + '-' + subGroup); + GenericConfig gc(grp); + return gc.readListEntry(key, defaultValues); +} +void Compile::Config::setListValues(const QString &group, const QString &subGroup, const QString &key, const QStringList &values) +{ + QString grp = (subGroup.isEmpty() ? group : group + '-' + subGroup); + GenericConfig gc(grp); + gc.writeEntry(key, values); +} + +QStringList Compile::Config::includeDirs(Tool::Category category, const QString &prefix, const QString &suffix, const QString &separator) const +{ + QStringList list; + QStringList raw = rawIncludeDirs(category); + for (uint i=0; isetValue(category.key(), key, value); + else Config::setValue(_group->name(), category.key(), key, value); +} +QString Compile::Config::value(Tool::Category category, const QString &key, const QString &defaultValue) const +{ + Q_ASSERT( category!=Tool::Category::Nb_Types ); + Q_ASSERT( _project || _group ); + if (_project) return _project->value(category.key(), key, defaultValue); + return Config::value(_group->name(), category.key(), key, defaultValue); +} +void Compile::Config::setListValues(Tool::Category category, const QString &key, const QStringList &values) +{ + Q_ASSERT( category!=Tool::Category::Nb_Types ); + Q_ASSERT( _project || _group ); + if (_project) _project->setListValues(category.key(), key, values); + else Config::setListValues(_group->name(), category.key(), key, values); +} +QStringList Compile::Config::listValues(Tool::Category category, const QString &key, const QStringList &defaultValues) const +{ + Q_ASSERT( category!=Tool::Category::Nb_Types ); + Q_ASSERT( _project || _group ); + if (_project) return _project->listValues(category.key(), key, defaultValues); + return Config::listValues(_group->name(), category.key(), key, defaultValues); +} +bool Compile::Config::boolValue(Tool::Category category, const QString &key, bool defaultValue) const +{ + QString s = value(category, key, QString::null); + if ( s.isNull() ) return defaultValue; + return !( s=="false" || s=="0" ); +} +uint Compile::Config::uintValue(Tool::Category category, const QString &key, uint defaultValue) const +{ + bool ok; + uint i = value(category, key, QString::null).toUInt(&ok); + if ( !ok ) return defaultValue; + return i; +} + +QString Compile::Config::globalValue(const Project *project, const QString &key, const QString &defaultValue) +{ + if (project) return project->value("general", key, defaultValue); + return Config::value("general", QString::null, key, defaultValue); +} +void Compile::Config::setGlobalValue(Project *project, const QString &key, const QString &value) +{ + if (project) project->setValue("general", key, value); + else Config::setValue("general", QString::null, key, value); +} + +QStringList Compile::Config::globalListValues(const Project *project, const QString &key, const QStringList &defaultValues) +{ + if (project) return project->listValues("general", key, defaultValues); + return Config::listValues("general", QString::null, key, defaultValues); +} +void Compile::Config::setGlobalListValues(Project *project, const QString &key, const QStringList &values) +{ + if (project) project->setListValues("general", key, values); + else Config::setListValues("general", QString::null, key, values); +} diff --git a/src/tools/list/compile_config.h b/src/tools/list/compile_config.h new file mode 100644 index 0000000..13beff4 --- /dev/null +++ b/src/tools/list/compile_config.h @@ -0,0 +1,84 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef COMPILE_CONFIG_H +#define COMPILE_CONFIG_H + +#include "common/global/purl.h" +#include "devices/base/hex_buffer.h" +#include "tools/base/tool_group.h" +class Project; + +//---------------------------------------------------------------------------- +namespace Compile +{ +class Config +{ +public: + Config(Project *project) : _group(0), _project(project) {} + + bool hasCustomArguments(Tool::Category category) const { return boolValue(category, "has_custom_arguments", false); } + void setHasCustomArguments(Tool::Category category, bool custom) { setValue(category, "has_custom_arguments", custom); } + QStringList customArguments(Tool::Category category) const { return listValues(category, "custom_arguments", QStringList()); } + void setCustomArguments(Tool::Category category, const QStringList &args) { return setListValues(category, "custom_arguments", args); } + QStringList rawIncludeDirs(Tool::Category category) const { return listValues(category, "includes", "$(SRCPATH)"); } + QStringList includeDirs(Tool::Category category, const QString &prefix, const QString &suffix = QString::null, const QString &separator = QString::null) const; + void setRawIncludeDirs(Tool::Category category, const QStringList &dirs) { setListValues(category, "includes", dirs); } + QString rawCustomOptions(Tool::Category category) const { return value(category, "custom_options", QString::null); } + QStringList customOptions(Tool::Category category) const; + void setRawCustomOptions(Tool::Category category, const QString &value) { setValue(category, "custom_options", value); } + QString rawCustomLibraries(Tool::Category category) const { return value(category, "custom_libraries", QString::null); } + QStringList customLibraries(Tool::Category category) const; + void setRawCustomLibraries(Tool::Category category, const QString &value) { setValue(category, "custom_libraries", value); } + uint warningLevel(Tool::Category category) const { return uintValue(category, "warning_level", 0); } + void setWarningLevel(Tool::Category category, uint level) { setValue(category, "warning_level", QString::number(level)); } + HexBuffer::Format hexFormat() const; + void setHexFormat(HexBuffer::Format format); + + static const Tool::Group &toolGroup(const Project *project); + static void setToolGroup(Project *project, const Tool::Group &group) { setGlobalValue(project, "tool", group.name()); } + static QString device(const Project *project); + static void setDevice(Project *project, const QString &device) { setGlobalValue(project, "device", device); } + static QStringList customCommands(Project *project) { return globalListValues(project, "custom_shell_commands", QStringList()); } + static void setCustomCommands(Project *project, const QStringList &commands) { setGlobalListValues(project, "custom_shell_commands", commands); } + static QString globalValue(const Project *project, const QString &key, const QString &defaultValue); + static void setGlobalValue(Project *project, const QString &key, const QString &value); + static QStringList globalListValues(const Project *project, const QString &key, const QStringList &defaultValues); + static void setGlobalListValues(Project *project, const QString &key, const QStringList &value); + + static PURL::Directory directory(const Tool::Group &group, DirectoryType type); + static void setDirectory(const Tool::Group &group, DirectoryType type, const PURL::Directory &dir); + static bool withWine(const Tool::Group &group); + static void setWithWine(const Tool::Group &group, bool withWine); + static Tool::OutputExecutableType outputExecutableType(const Tool::Group &group); + static void setOutputExecutableType(const Tool::Group &group, Tool::OutputExecutableType type); + +protected: + const Tool::Group *_group; + Project *_project; + + void setValue(Tool::Category category, const QString &key, const QString &value); + QString value(Tool::Category category, const QString &key, const QString &defaultValue) const; + void setListValues(Tool::Category category, const QString &key, const QStringList &values); + QStringList listValues(Tool::Category category, const QString &key, const QStringList &defaultValues) const; + void setValue(Tool::Category category, const QString &key, bool value) { setValue(category, key, QString(value ? "true" : "false")); } + bool boolValue(Tool::Category category, const QString &key, bool defaultValue) const; + void setValue(Tool::Category category, const QString &key, uint value) { setValue(category, key, QString::number(value)); } + uint uintValue(Tool::Category category, const QString &key, uint defaultValue) const; + + static QString value(const QString &group, const QString &subGroup, const QString &key, const QString &defaultValue); + static void setValue(const QString &group, const QString &subGroup, const QString &key, const QString &value); + static QStringList listValues(const QString &group, const QString &subGroup, const QString &key, const QStringList &defaultValues); + static void setListValues(const QString &group, const QString &subGroup, const QString &key, const QStringList &values); + + friend class Tool::Group; +}; + +} // namespace + +#endif diff --git a/src/tools/list/compile_manager.cpp b/src/tools/list/compile_manager.cpp new file mode 100644 index 0000000..00a4182 --- /dev/null +++ b/src/tools/list/compile_manager.cpp @@ -0,0 +1,292 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "compile_manager.h" + +#include + +#include "libgui/project.h" +#include "common/gui/misc_gui.h" +#include "compile_config.h" + +Compile::Manager::Manager(QObject *parent) + : QObject(parent, "compile_manager"), _base(0) +{} + +void Compile::Manager::cleanFile(const PURL::Url &url) +{ + setupFile(Clean, TodoItem(url, false)); +} + +bool Compile::Manager::compileFile(const TodoItem &item) +{ + _label = i18n("Compiling file..."); + return setupFile(Clean | (Main::project() ? CompileOnly : Build), item); +} + +bool Compile::Manager::setupFile(Operations op, const TodoItem &item) +{ + Log::Base::clear(); + clearAll(); + _operations = op; + _type = NormalLinking; + _todo.append(item); + _action = Compiling; + _wholeProject = false; + QTimer::singleShot(0, this, SLOT(start())); + return true; +} + +void Compile::Manager::cleanProject(LinkType type) +{ + setupProject(Clean, type); +} + +bool Compile::Manager::buildProject(LinkType type) +{ + _label = i18n("Building project..."); + return setupProject(Clean | Build, type); +} + +bool Compile::Manager::setupProject(Operations op, LinkType type) +{ + Log::Base::clear(); + clearAll(); + _operations = op; + _type = type; + PURL::UrlList files = Main::project()->absoluteFiles(); + if ( files.count()==0 ) { + MessageBox::sorry(i18n("Cannot build empty project."), Log::Show); + return false; + } + PURL::UrlList::const_iterator it; + for (it=files.begin(); it!=files.end(); ++it) + if ( (*it).data().group==PURL::Source ) _todo.append(TodoItem(*it, false)); + if ( _todo.count()>1 && Main::toolGroup().compileType()==Tool::SingleFile ) { + MessageBox::sorry(i18n("The selected toolchain only supports single-file project."), Log::Show); + return false; + } + _action = Compiling; + _wholeProject = true; + QTimer::singleShot(0, this, SLOT(start())); + return true; +} + +void Compile::Manager::kill() +{ + if ( clearAll() ) Log::Base::log(Log::LineType::Error, i18n("*** Aborted ***"), Log::Delayed); + emit failure(); +} + +bool Compile::Manager::clearAll() +{ + bool running = ( _base!=0 ); + delete _base; + _base = 0; + _todo.clear(); + return running; +} + +void Compile::Manager::setup(Tool::Category category) +{ + delete _base; + Compile::Data data(category, _items, Main::device(), Main::project(), _type); + _base = Main::toolGroup().createCompileProcess(data, this); +} + +bool Compile::Manager::setupCompile() +{ + PURL::FileType type = Main::toolGroup().implementationType(PURL::ToolType::Compiler); + for (uint i=0; i<_items.count(); i++) { + if ( _items[i].url.fileType()!=type ) { + if ( _operations!=Clean ) { + QString e = PURL::extensions(type); + MessageBox::detailedSorry(i18n("The selected toolchain (%1) cannot compile file. It only supports files with extensions: %2") + .arg(Main::toolGroup().label()).arg(e), i18n("File: %1").arg(_items[i].url.pretty()), Log::Show); + Log::Base::log(Log::LineType::Error, i18n("*** Aborted ***"), Log::Delayed); + processFailed(); + } + return false; + } + } + if ( !compileOnly() && Main::toolGroup().needs(Main::project(), Tool::Category::Assembler) ) { + PURL::FileType type = Main::toolGroup().implementationType(PURL::ToolType::Assembler); + for (uint i=0; i<_items.count(); i++) + _todo.append(TodoItem(_items[i].url.toFileType(type), true)); + } + setup(Tool::Category::Compiler); + return true; +} + +bool Compile::Manager::setupAssemble() +{ + PURL::FileType type = Main::toolGroup().implementationType(PURL::ToolType::Assembler); + for (uint i=0; i<_items.count(); i++) { + if ( _items[i].url.fileType()!=type ) { + if ( _operations!=Clean ) { + if ( type==PURL::Nb_FileTypes ) type = Main::toolGroup().implementationType(PURL::ToolType::Compiler); + QString e = PURL::extensions(type); + MessageBox::detailedSorry(i18n("The selected toolchain (%1) cannot assemble file. It only supports files with extensions: %2") + .arg(Main::toolGroup().label()).arg(e), i18n("File: %1").arg(_items[i].url.pretty()), Log::Show); + Log::Base::log(Log::LineType::Error, i18n("*** Aborted ***"), Log::Delayed); + processFailed(); + } + return false; + } + } + setup(Tool::Category::Assembler); + return true; +} + +bool Compile::Manager::setupLink() +{ + _action = Linking; + Tool::Category category = (Main::project() && Main::project()->outputType()==Tool::OutputType::Library ? Tool::Category::Librarian : Tool::Category::Linker); + if ( !Main::toolGroup().needs(Main::project(), category) ) { + start(); + return false; + } + setup(category); + return true; +} + +bool Compile::Manager::setupBinToHex() +{ + _action = BinToHex; + if ( !Main::toolGroup().needs(Main::project(), Tool::Category::BinToHex) ) { + start(); + return false; + } + setup(Tool::Category::BinToHex); + return true; +} + +bool Compile::Manager::prepareAction() +{ + switch (_action) { + case Compiling: + if ( _todo.count()!=0 ) { + _items.clear(); + if ( Main::toolGroup().compileType()==Tool::AllFiles ) { + _items = _todo; + _todo.clear(); + } else { + _items.append(_todo[0]); + _todo.remove(_todo.begin()); + } + PURL::SourceFamily family = _items[0].url.data().sourceFamily; + if ( family.data().toolType==PURL::ToolType::Compiler && Main::toolGroup().base(Tool::Category::Compiler) ) + return setupCompile(); + return setupAssemble(); + } + if ( !compileOnly() ) return setupLink(); + break; + case Linking: return setupBinToHex(); + case BinToHex: break; + } + if ( !(_operations & Clean) ) { + Log::Base::log(Log::LineType::Information, i18n("*** Success ***"), Log::Delayed); + emit success(); + } else if ( _operations!=Clean ) { + _operations &= ~Clean; + if (_wholeProject) setupProject(_operations, _type); + else setupFile(_operations, _items[0]); + } + return false; +} + +void Compile::Manager::start() +{ + if ( Main::toolGroup().isCustom() ) { + executeCustomCommands(); + return; + } + delete _base; + _base = 0; + if ( !prepareAction() ) return; + if ( !_base->check() ) { + processFailed(); + return; + } + if ( _operations & Clean ) { + _base->files(0).onlyExistingFiles().cleanGenerated(); + QTimer::singleShot(0, this, SLOT(start())); + return; + } + if ( !_base->start() ) { + Log::Base::log(Log::LineType::Error, i18n("Failed to execute command: check toolchain configuration."), Log::Delayed); + processFailed(); + } +} + +void Compile::Manager::log(Log::LineType type, const QString &message, const QString &filepath, uint line) +{ + if ( type==Log::LineType::Error ) setError(message); + static_cast(view())->appendLine(type, message, filepath, line); +} + +void Compile::Manager::log(Log::DebugLevel level, const QString &message, const QString &filepath, uint line) +{ + static_cast(view())->appendLine(level, message, filepath, line); +} + +void Compile::Manager::processDone() +{ + if ( hasError() ) { + processFailed(); + return; + } + if ( Main::toolGroup().isCustom() ) { + _customCommandIndex++; + startCustomCommand(); + } else { + FileData::List list = _base->files(0).onlyExistingFiles(); + FileData::List::iterator it; + for (it=list.begin(); it!=list.end(); ++it) emit updateFile(*it); + QTimer::singleShot(0, this, SLOT(start())); + } +} + +void Compile::Manager::processFailed() +{ + clearAll(); + emit failure(); +} + +void Compile::Manager::startCustomCommand() +{ + delete _base; + _base = 0; + QStringList commands = Compile::Config::customCommands(Main::project()); + if ( _customCommandIndex==commands.count() ) { + Log::Base::log(Log::LineType::Information, i18n("*** Success ***"), Log::Delayed); + emit success(); + return; + } + QString command = commands[_customCommandIndex]; + _base = new CustomProcess(command); + Compile::Data data(Tool::Category::Nb_Types, _todo, Main::device(), Main::project(), _type); + _base->init(data, this); + if ( !_base->start() ) { + Log::Base::log(Log::LineType::Error, i18n("Failed to execute custom command #%1.").arg(_customCommandIndex+1), Log::Delayed); + processFailed(); + } +} + +void Compile::Manager::executeCustomCommands() +{ + _customCommandIndex = 0; + if ( Compile::Config::customCommands(Main::project()).isEmpty() ) { + MessageBox::sorry(i18n("No custom commands specified."), Log::Show); + emit failure(); + return; + } + log(Log::LineType::Information, i18n("Executing custom commands...")); + startCustomCommand(); +} diff --git a/src/tools/list/compile_manager.h b/src/tools/list/compile_manager.h new file mode 100644 index 0000000..6f617b4 --- /dev/null +++ b/src/tools/list/compile_manager.h @@ -0,0 +1,74 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef COMPILE_MANAGER_H +#define COMPILE_MANAGER_H + +#include "compile_process.h" + +namespace Compile +{ + +class Manager : public QObject, public Log::Base +{ +Q_OBJECT +public: + enum Operation { NoOperation = 0, Clean = 1, CompileOnly = 2, Build = 4 }; + Q_DECLARE_FLAGS(Operations, Operation) + +public: + Manager(QObject *parent); + QString label() const { return _label; } + bool compileFile(const TodoItem &item); + void cleanFile(const PURL::Url &url); + bool buildProject(LinkType type); + void cleanProject(LinkType type); + void kill(); + bool compileOnly() const { return (_operations & CompileOnly); } + void processDone(); + void processFailed(); + void log(Log::LineType type, const QString &message, const QString &filepath = QString::null, uint line = 0); + void log(Log::DebugLevel debug, const QString &message, const QString &filepath = QString::null, uint line = 0); + +signals: + void success(); + void failure(); + void updateFile(const Compile::FileData &fdata); + +private slots: + void start(); + +private: + Operations _operations; + enum Action { Compiling, Linking, BinToHex }; + Action _action; + QValueList _todo, _items; + BaseProcess *_base; + QString _label; + LinkType _type; + bool _wholeProject; + uint _customCommandIndex; + + bool startProject(); + bool clearAll(); + bool setupFile(Operations operations, const TodoItem &item); + bool setupProject(Operations operations, LinkType type); + void setup(Tool::Category category); + bool setupCompile(); + bool setupAssemble(); + bool setupLink(); + bool setupBinToHex(); + bool prepareAction(); + void startCustomCommand(); + void executeCustomCommands(); +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(Manager::Operations) + +} // namespace + +#endif diff --git a/src/tools/list/compile_process.cpp b/src/tools/list/compile_process.cpp new file mode 100644 index 0000000..4f251bc --- /dev/null +++ b/src/tools/list/compile_process.cpp @@ -0,0 +1,376 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * Copyright (C) 2003-2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "compile_process.h" + +#include +#include + +#include "devices/list/device_list.h" +#include "common/global/process.h" +#include "common/gui/misc_gui.h" +#include "libgui/text_editor.h" +#include "libgui/editor_manager.h" +#include "libgui/project.h" +#include "compile_config.h" +#include "compile_manager.h" + +//----------------------------------------------------------------------------- +const Compile::ArgumentData Compile::ARGUMENT_DATA[] = { + { "$(SRCPATH)", I18N_NOOP("Replaced by the source directory.") }, + { "$LKR(xxx)", I18N_NOOP("Replaced by \"xxx\" when there is a custom linker script.") }, + { "$WINE(xxx)", I18N_NOOP("Replaced by \"xxx\" when \"wine\" is used.") }, + { "$NO_AUTO_DEVICE(xxx)", I18N_NOOP("Replaced by \"xxx\" when the device name is specified.") }, + { "%OBJS", I18N_NOOP("Replaced by the list of additionnal objects.") }, + { "%LIBS", I18N_NOOP("Replaced by the list of additionnal libraries.") }, + { "%O", I18N_NOOP("Replaced by the output filename.") }, + { "%PROJECT", I18N_NOOP("Replaced by the project name.") }, + { "%COFF", I18N_NOOP("Replaced by the COFF filename.") }, + { "%MAP", I18N_NOOP("Replaced by the map filename.") }, + { "%SYM", I18N_NOOP("Replaced by the symbol filename.") }, + { "%LIST", I18N_NOOP("Replaced by the list filename.") }, + { "%DEVICE", I18N_NOOP("Replaced by the device name.") }, + { "%FAMILY", I18N_NOOP("Replaced by the device family name (when needed).") }, + { "%I", I18N_NOOP("Replaced by the relative input filepath(s).") }, + { "%OBJECT", I18N_NOOP("Replaced by the object file name.") }, + { "%LKR_PATH", I18N_NOOP("Replaced by the linker script path.") }, + { "%LKR_NAME", I18N_NOOP("Replaced by the linker script basename.") }, + { "%LKR", I18N_NOOP("Replaced by the linker script filename.") }, + { "%SEP", I18N_NOOP("Replaced by a separation into two arguments.") }, + { 0, 0 } +}; + +//----------------------------------------------------------------------------- +Compile::FileData::List Compile::FileData::List::onlyExistingFiles() const +{ + List list; + List::const_iterator it; + for (it=begin(); it!=end(); ++it) { + FileData data = *it; + if ( PURL::findExistingUrl(data.url) ) list.append(data); + } + return list; +} + +void Compile::FileData::List::cleanGenerated() const +{ + Log::StringView sview; + List::const_iterator it; + for (it=begin(); it!=end(); ++it) + if ( (*it).actions & Generated ) (*it).url.del(sview); +} + +//----------------------------------------------------------------------------- +Compile::LogWidget::LogWidget(QWidget *parent) + : Log::Widget(parent, "compile_log") +{ + connect(this, SIGNAL(clicked(int, int)), SLOT(lineClicked(int))); +} + +void Compile::LogWidget::clear() +{ + Log::Widget::clear(); + _map.clear(); +} + +void Compile::LogWidget::appendLine(Log::LineType type, const QString &message, const QString &filepath, uint line) +{ + log(type, message, Log::Delayed); + if ( !filepath.isEmpty() ) _map[paragraphs()-1] = Data(filepath, line); +} + +void Compile::LogWidget::appendLine(Log::DebugLevel level, const QString &message, const QString &filepath, uint line) +{ + log(level, message, Log::Delayed); + if ( !filepath.isEmpty() ) _map[paragraphs()-1] = Data(filepath, line); +} + +void Compile::LogWidget::lineClicked(int line) +{ + if ( !_map.contains(line) ) return; + PURL::Url url = PURL::Url::fromPathOrUrl(_map[line].filepath); + TextEditor *e = ::qt_cast(Main::editorManager().openEditor(url)); + if ( e==0 ) return; + e->setCursor(_map[line].line, 0); +} + +//----------------------------------------------------------------------------- +Compile::BaseProcess::BaseProcess() + : QObject(0, "compile_process"), _manager(0), _process(0) +{} + +void Compile::BaseProcess::init(const Data &data, Manager *manager) +{ + _data = data; + _manager = manager; +} + +PURL::Directory Compile::BaseProcess::directory(uint i) const +{ + if (_data.project) return _data.project->directory(); + Q_ASSERT( i<_data.items.count() ); + return _data.items[i].url.directory(); +} + +bool Compile::BaseProcess::start() +{ + _stdout = QString::null; + _stderr = QString::null; + delete _process; + _process = new ::Process::LineSignal; + connect(_process, SIGNAL(done(int)), SLOT(done(int))); + connect(_process, SIGNAL(timeout()), SLOT(timeout())); + connect(_process, SIGNAL(logStdoutLine(const QString &)), SLOT(logStdoutLine(const QString &))); + connect(_process, SIGNAL(logStderrLine(const QString &)), SLOT(logStderrLine(const QString &))); + _process->setWorkingDirectory(directory().path()); + setupProcess(); + _manager->log(Log::LineType::Command, _process->arguments().join(" ")); + return _process->start(0); // no timeout +} + +void Compile::BaseProcess::done(int code) +{ + if ( code!=0 ) { + _manager->log(Log::LineType::Error, i18n("*** Exited with status: %1 ***").arg(code)); + _manager->processFailed(); + } else if ( _manager->hasError() ) { + _manager->log(Log::LineType::Error, i18n("*** Error ***")); + _manager->processFailed(); + } else _manager->processDone(); +} + +void Compile::BaseProcess::timeout() +{ + _manager->log(Log::LineType::Error, i18n("*** Timeout ***")); + _manager->processFailed(); +} + +//----------------------------------------------------------------------------- +void Compile::Process::init(const Data &data, Manager *manager) +{ + BaseProcess::init(data, manager); + _config = group().createConfig(const_cast(data.project)); +} + +Compile::Process::~Process() +{ + delete _config; +} + +bool Compile::Process::check() const +{ + return group().check(_data.device, _manager); +} + +PURL::Url Compile::Process::url(PURL::FileType type, uint i) const +{ + PURL::Url url; + if ( _data.project && (type==PURL::Hex || _data.category==Tool::Category::Linker || _data.category==Tool::Category::BinToHex) ) + url = _data.project->url(); + else if ( _data.project && (type==PURL::Library || _data.category==Tool::Category::Librarian) ) + return _data.project->url().toExtension(libraryExtension()); + else { + Q_ASSERT( i<_data.items.count() ); + url = _data.items[i].url; + } + if ( type==PURL::Nb_FileTypes ) return url; + return url.toFileType(type); +} + +QString Compile::Process::filepath(PURL::FileType type, uint i) const +{ + return url(type, i).relativeTo(directory(), Compile::Config::withWine(group()) ? PURL::WindowsSeparator : PURL::UnixSeparator); +} + +QString Compile::Process::outputFilepath() const +{ + if ( _data.category==Tool::Category::Librarian ) return filepath(PURL::Library); + return filepath(PURL::Hex); +} + +Compile::FileData Compile::Process::fileData(PURL::FileType type, FileActions actions) const +{ + return FileData(url(type, nbFiles()-1), actions); +} + +Compile::FileData::List Compile::Process::files(bool *ok) const +{ + if (ok) *ok = true; + FileData::List list; + QRegExp rexp("PURL::(.*)"); + QStringList files = QStringList::split(" ", outputFiles()); + for (uint i=0; ilabel().latin1()); + continue; + } + if ( type.data().group==PURL::LinkerScript ) { + PURL::Url lkr = Main::toolGroup().linkerScript(_data.project, _data.linkType); + list += FileData(lkr, Included | InProject); + } else { + FileActions actions = Generated; + if ( type.data().group==PURL::Source || type==PURL::Hex + || type==PURL::Map || type==PURL::Coff || type==PURL::Library ) actions |= InProject; + if ( type==PURL::Hex && _data.project==0 ) actions |= Show; + list += fileData(type, actions); + } + } else list += FileData(url().toExtension(files[i]), Compile::Generated); + } + return list; +} + +bool Compile::Process::checkIs(const QString &s, const QString &key) +{ + if ( !s.contains(key) ) return false; + if ( s!=key ) qWarning("Argument should be only %s, the rest will be ignored...", key.latin1()); + return true; +} + +QString Compile::Process::replaceIf(const QString &s, const QString &key, bool condition) +{ + QRegExp rexp("(.*)\\$" + key + "\\(([^)]*)\\)(.*)"); + if ( !rexp.exactMatch(s) ) return s; + return rexp.cap(1) + (condition ? rexp.cap(2) : QString::null) + rexp.cap(3); +} + +QStringList Compile::Process::arguments() const +{ + bool custom = _config->hasCustomArguments(_data.category); + bool withWine = Compile::Config::withWine(group()); + QStringList args = (custom ? _config->customArguments(_data.category) : genericArguments(*_config)); + PURL::Url lkr = Main::toolGroup().linkerScript(_data.project, _data.linkType); + QStringList nargs; + for (uint i=0; iobjectsForLinker(objectExtension(), withWine); + else { + PURL::Url tmp = url(PURL::Object); + if ( !objectExtension().isEmpty() ) tmp = tmp.toExtension(objectExtension()); + nargs += tmp.relativeTo(directory(), withWine ? PURL::WindowsSeparator : PURL::UnixSeparator); + } + continue; + } + if ( checkIs(args[i], "%LIBS") ) { + if (_data.project) nargs += _data.project->librariesForLinker(QString::null, withWine); + continue; + } + args[i].replace("%OBJECT", filepath(PURL::Object)); // before %O + args[i].replace("%O", outputFilepath()); + args[i].replace("%COFF", filepath(PURL::Coff)); + if (_data.project) args[i].replace("%PROJECT", _data.project->name()); + else args[i].replace("%PROJECT", url().basename()); + args[i].replace("%MAP", filepath(PURL::Map)); + args[i].replace("%SYM", url().toExtension("sym").relativeTo(directory(), withWine ? PURL::WindowsSeparator : PURL::UnixSeparator)); + args[i].replace("%LIST", filepath(PURL::Lst)); + args[i].replace("%DEVICE", deviceName()); + args[i].replace("%FAMILY", familyName()); + args[i].replace("%LKR_PATH", lkr.path()); // before %LKR + args[i].replace("%LKR_NAME", lkr.filename()); // before LKR + args[i].replace("%LKR", lkr.filepath()); + if ( checkIs(args[i], "%I") ) { + for (uint k=0; kbaseExecutable(withWine, Compile::Config::outputExecutableType(group())); + QString path = tool()->executableDirectory().path(); + _process->setup(path + exec, arguments(), withWine); +} + +Log::LineType Compile::Process::filterType(const QString &type) const +{ + QString s = type.lower(); + if ( s.startsWith("warning") ) return Log::LineType::Warning; + if ( s.startsWith("error") ) return Log::LineType::Error; + if ( s.startsWith("message") ) return Log::LineType::Information; + return Log::LineType::Normal; +} + +bool Compile::Process::parseErrorLine(const QString &s, const ParseErrorData &data) +{ + QRegExp re(data.pattern); + if ( !re.exactMatch(s) ) return false; + QString file; + if ( data.indexFile>=0 ) { + file = re.cap(data.indexFile).stripWhiteSpace(); + if ( file.endsWith(".") ) file = file.mid(0, file.length()-1); + if ( file=="-" ) file = QString::null; + } + bool ok; + int line = -1; + if ( data.indexLine>=0 ) line = re.cap(data.indexLine).stripWhiteSpace().toUInt(&ok) - 1; + if ( !ok ) line = -1; + QString message; + if ( data.indexMessage>=0 ) message= re.cap(data.indexMessage).stripWhiteSpace(); + Log::LineType type = data.defaultLineType; + if ( data.indexLogType>=0 ) { + QString s = re.cap(data.indexLogType).stripWhiteSpace(); + if ( s.isEmpty() ) type = data.defaultLineType; + else type = filterType(s); + } + doLog(type, message, file, line); + return true; +} + +void Compile::Process::doLog(const QString &type, const QString &message, const QString &surl, uint line) +{ + doLog(filterType(type), message, surl, line); +} + +void Compile::Process::doLog(Log::LineType type, const QString &message, const QString &surl, uint line) +{ + if ( surl.isEmpty() ) { + _manager->log(type, message); + return; + } + PURL::Url url = PURL::Url::fromPathOrUrl(surl); + QString s; + if ( !url.isEmpty() ) { + if ( !url.exists() && !url.isInto(directory()) ) url = PURL::Url(directory(), surl); + s += url.filename() + ":" + QString::number(line+1) + ": "; + } + switch (type.type()) { + case Log::LineType::Warning: s += i18n("warning: "); break; + case Log::LineType::Error: s += i18n("error: "); break; + case Log::LineType::Information: s += i18n("message: "); break; + default: break; + } + _manager->log(type, s + message.stripWhiteSpace(), url.filepath(), line); +} + +//----------------------------------------------------------------------------- +void Compile::CustomProcess::setupProcess() +{ + _process->setUseShell(true); + _process->setup(_command, QStringList(), false); +} + +void Compile::CustomProcess::logStderrLine(const QString &line) +{ + _manager->log(Log::LineType::Normal, line); +} diff --git a/src/tools/list/compile_process.h b/src/tools/list/compile_process.h new file mode 100644 index 0000000..4fe396e --- /dev/null +++ b/src/tools/list/compile_process.h @@ -0,0 +1,179 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef COMPILE_PROCESS_H +#define COMPILE_PROCESS_H + +#include "common/common/qflags.h" +#include "common/global/purl.h" +#include "libgui/log_view.h" +#include "devices/base/hex_buffer.h" +#include "tools/base/tool_group.h" +#include "tools/base/generic_tool.h" +#include "libgui/main_global.h" +namespace Process { class LineSignal; } + +namespace Compile +{ + class Manager; + enum FileAction { NoAction = 0, Show = 1, InProject = 2, Generated = 8, Included = 16 }; + Q_DECLARE_FLAGS(FileActions, FileAction) + Q_DECLARE_OPERATORS_FOR_FLAGS(FileActions) + + class FileData { + public: + FileData() {} + FileData(const PURL::Url &u, FileActions a) : url(u), actions(a) {} + PURL::Url url; + FileActions actions; + class List : public QValueList { + public: + List() {} + List(const FileData &data) { append(data); } + List onlyExistingFiles() const; + void cleanGenerated() const; + }; + }; + + struct ArgumentData { + const char *key, *description; + }; + extern const ArgumentData ARGUMENT_DATA[]; + + class ParseErrorData { + public: + ParseErrorData(const QString &p, int iFile, int iLine, int iMessage, Log::LineType dLineType) + : pattern(p), indexFile(iFile), indexLine(iLine), indexMessage(iMessage), indexLogType(-1), + defaultLineType(dLineType) {} + ParseErrorData(const QString &p, int iFile, int iLine, int iMessage, uint iLogType, + Log::LineType dLineType = Log::LineType::Error) + : pattern(p), indexFile(iFile), indexLine(iLine), indexMessage(iMessage), indexLogType(iLogType), + defaultLineType(dLineType) {} + QString pattern; + int indexFile, indexLine, indexMessage, indexLogType; + Log::LineType defaultLineType; + }; + +//----------------------------------------------------------------------------- +class LogWidget : public Log::Widget +{ + Q_OBJECT +public: + LogWidget(QWidget *parent); + void appendLine(Log::LineType type, const QString &message, const QString &filepath, uint line); + void appendLine(Log::DebugLevel debug, const QString &message, const QString &filepath, uint line); + virtual void clear(); + +private slots: + void lineClicked(int line); + +private: + class Data { + public: + Data() {} + Data(const QString &fp, uint l) : filepath(fp), line(l) {} + QString filepath; + uint line; + }; + QMap _map; +}; + +//----------------------------------------------------------------------------- +class BaseProcess : public QObject +{ +Q_OBJECT +public: + BaseProcess(); + virtual void init(const Data &data, Manager *manager); + virtual bool check() const = 0; + virtual FileData::List files(bool *ok) const = 0; + bool start(); + +signals: + void success(); + void failure(); + +protected: + Manager *_manager; + Data _data; + ::Process::LineSignal *_process; + QString _stdout, _stderr; + + const Tool::Group &group() const { return Main::toolGroup(); } + PURL::Directory directory(uint i = 0) const; + virtual void setupProcess() = 0; + +protected slots: + virtual void logStdoutLine(const QString &line) { logStderrLine(line); } + virtual void logStderrLine(const QString &line) = 0; + virtual void done(int code); + void timeout(); +}; + +//----------------------------------------------------------------------------- +class Process : public BaseProcess +{ +Q_OBJECT +public: + virtual ~Process(); + virtual void init(const Data &data, Manager *manager); + virtual bool check() const; + virtual FileData::List files(bool *ok) const; + virtual QStringList genericArguments(const Compile::Config &config) const = 0; + void checkArguments() const; + +protected: + Config *_config; + + virtual PURL::Url url(PURL::FileType type = PURL::Nb_FileTypes, uint i = 0) const; + QString filepath(PURL::FileType type, uint i=0) const; + virtual QString outputFilepath() const; + virtual QString outputFiles() const = 0; + uint nbFiles() const { return _data.items.count(); } + virtual QString inputFilepath(uint i) const { return filepath(PURL::Nb_FileTypes, i); } + virtual QString deviceName() const = 0; + virtual QString familyName() const { return QString::null; } + virtual QString objectExtension() const { return QString::null; } + virtual QString libraryExtension() const { return "lib"; } + virtual bool hasLinkerScript() const { return group().hasCustomLinkerScript(_data.project); } + FileData fileData(PURL::FileType type, FileActions actions) const; + bool parseErrorLine(const QString &s, const ParseErrorData &data); + virtual Log::LineType filterType(const QString &type) const; + void doLog(const QString &type, const QString &message, const QString &surl, uint line); + void doLog(Log::LineType type, const QString &message, const QString &surl, uint line); + virtual void setupProcess(); + QStringList arguments() const; + const Tool::Base *tool() const { return group().base(_data.category); } + +private: + static bool checkIs(const QString &s, const QString &key); + static QString replaceIf(const QString &s, const QString &key, bool condition); +}; + +//----------------------------------------------------------------------------- +class CustomProcess : public BaseProcess +{ +Q_OBJECT +public: + CustomProcess(const QString &command) : _command(command) {} + virtual bool check() const { return true; } + virtual FileData::List files(bool *ok) const { if (ok) *ok = true; return FileData::List(); } + +protected: + virtual void setupProcess(); + +protected slots: + virtual void logStderrLine(const QString &line); + +private: + QString _command; +}; + +} // namespace + +#endif diff --git a/src/tools/list/device_info.cpp b/src/tools/list/device_info.cpp new file mode 100644 index 0000000..78ca7a7 --- /dev/null +++ b/src/tools/list/device_info.cpp @@ -0,0 +1,63 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "device_info.h" + +#include "devices/base/generic_device.h" +#include "progs/list/prog_list.h" +#include "tool_list.h" + +QString Device::webpageHtml(const Device::Data &data) +{ + const Device::Documents &documents = data.documents(); + QString url = "http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId="; + if ( documents.webpage.isEmpty() ) url += "2044&AllWords=" + data.name(); + else url += "1335&dDocName=en" + documents.webpage; + return "" + i18n("Device Page") + " "; +} + +QString documentHtml(const QString &document, const QString &label) +{ + if ( document.isEmpty() ) return QString::null; + return ", " + label + ""; +} + +QString Device::documentHtml(const Device::Data &data) +{ + QString s = webpageHtml(data); + s += documentHtml(data.documents().datasheet, i18n("Datasheet")); + s += documentHtml(data.documents().progsheet, i18n("Programming Specifications")); + return htmlTableRow(i18n("Documents"), s); +} + +QString Device::supportedHtmlInfo(const Device::Data &data) +{ + QString doc; + doc += "
\n"; + doc += "\n"; + QString tools; + Tool::Lister::ConstIterator tit; + for (tit=Tool::lister().begin(); tit!=Tool::lister().end(); ++tit) { + if ( !tit.data()->isSupported(data.name()) ) continue; + if ( tit.data()->isCustom() ) continue; + if ( !tools.isEmpty() ) tools += ", "; + tools += tit.data()->label(); + } + doc += htmlTableRow(i18n("Tools"), tools) + "\n"; + QString progs; + Programmer::Lister::ConstIterator pit; + for (pit=Programmer::lister().begin(); pit!=Programmer::lister().end(); ++pit) { + if ( !pit.data()->isSupported(data.name()) ) continue; + if ( !progs.isEmpty() ) progs += ", "; + progs += pit.data()->label(); + } + doc += htmlTableRow(i18n("Programmers"), progs) + "\n"; + doc += "
\n"; + + return doc; +} diff --git a/src/tools/list/device_info.h b/src/tools/list/device_info.h new file mode 100644 index 0000000..ad69c59 --- /dev/null +++ b/src/tools/list/device_info.h @@ -0,0 +1,22 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef DEVICE_INFO_H +#define DEVICE_INFO_H + +#include +namespace Device { class Data; } + +namespace Device +{ + extern QString webpageHtml(const Device::Data &data); + extern QString documentHtml(const Device::Data &data); + extern QString supportedHtmlInfo(const Device::Data &data); +} // namespace + +#endif diff --git a/src/tools/list/tool_list.cpp b/src/tools/list/tool_list.cpp new file mode 100644 index 0000000..da21cd7 --- /dev/null +++ b/src/tools/list/tool_list.cpp @@ -0,0 +1,69 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "tool_list.h" + +#include "tools/gputils/gputils.h" +#include "tools/gputils/gui/gputils_ui.h" +#include "tools/sdcc/sdcc.h" +#include "tools/sdcc/gui/sdcc_ui.h" +#include "tools/pic30/pic30.h" +#include "tools/pic30/gui/pic30_ui.h" +#include "tools/picc/picc.h" +#include "tools/picc/gui/picc_ui.h" +#include "tools/jal/jal.h" +#include "tools/jal/gui/jal_ui.h" +#include "tools/c18/c18.h" +#include "tools/c18/gui/c18_ui.h" +#include "tools/ccsc/ccsc.h" +#include "tools/ccsc/gui/ccsc_ui.h" +#include "tools/jalv2/jalv2.h" +#include "tools/jalv2/gui/jalv2_ui.h" +#include "tools/boost/boostc.h" +#include "tools/boost/boostcpp.h" +#include "tools/boost/boostbasic.h" +#include "tools/boost/gui/boost_ui.h" +#include "tools/mpc/mpc.h" +#include "tools/mpc/gui/mpc_ui.h" +#include "tools/cc5x/cc5x.h" +#include "tools/cc5x/gui/cc5x_ui.h" +#include "tools/custom/custom.h" + +Tool::Lister::Lister() +{ + addGroup(new GPUtils::Group, new GPUtils::GroupUI); + addGroup(new SDCC::Group, new SDCC::GroupUI); + addGroup(new PIC30::Group, new PIC30::GroupUI); + addGroup(new PICC::PICCLiteGroup, new PICC::GroupUI); + addGroup(new PICC::PICCGroup, new PICC::GroupUI); + addGroup(new PICC::PICC18Group, new PICC::GroupUI); + addGroup(new JAL::Group, new JAL::GroupUI); + addGroup(new C18::Group, new C18::GroupUI); + addGroup(new CCSC::Group, new CCSC::GroupUI); + addGroup(new JALV2::Group, new JALV2::GroupUI); + addGroup(new Boost::GroupC16, new Boost::GroupUI); + addGroup(new Boost::GroupC18, new Boost::GroupUI); + addGroup(new Boost::GroupCpp16, new Boost::GroupUI); + addGroup(new Boost::GroupCpp18, new Boost::GroupUI); + addGroup(new Boost::GroupBasic16, new Boost::GroupUI); + addGroup(new Boost::GroupBasic18, new Boost::GroupUI); + addGroup(new MPC::Group, new MPC::GroupUI); + addGroup(new CC5X::Group, new CC5X::GroupUI); + addGroup(new CustomTool::Group, 0); +} + +namespace Tool +{ + Lister *_lister = 0; +} + +const Tool::Lister &Tool::lister() +{ + if ( _lister==0 ) _lister = new Lister; + return *_lister; +} diff --git a/src/tools/list/tool_list.h b/src/tools/list/tool_list.h new file mode 100644 index 0000000..b63aee0 --- /dev/null +++ b/src/tools/list/tool_list.h @@ -0,0 +1,28 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef TOOL_LIST_H +#define TOOL_LIST_H + +#include "common/common/lister.h" +#include "tools/base/tool_group.h" + +namespace Tool +{ + +class Lister : public ::Group::Lister +{ +public: + Lister(); +}; + +extern const Lister &lister(); + +} // namespace + +#endif diff --git a/src/tools/list/tools_config_widget.cpp b/src/tools/list/tools_config_widget.cpp new file mode 100644 index 0000000..449183d --- /dev/null +++ b/src/tools/list/tools_config_widget.cpp @@ -0,0 +1,144 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * Copyright (C) 2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#include "tools_config_widget.h" + +#include +#include + +#include "tool_list.h" +#include "tools/gui/tool_config_widget.h" +#include "tools/gui/tool_group_ui.h" +#include "compile_config.h" +#include "compile_process.h" +#include "libgui/project.h" + +//---------------------------------------------------------------------------- +HelpDialog::HelpDialog(QWidget *parent) + : Dialog(parent, "help_dialog", false, i18n("Help Dialog"), Close, Close, false) +{ + QGridLayout *top = new QGridLayout(mainWidget(), 1, 1, 10, 10); + uint k = 0; + for (; Compile::ARGUMENT_DATA[k].key; k++) { + QLabel *label = new QLabel(Compile::ARGUMENT_DATA[k].key, mainWidget()); + top->addWidget(label, k, 0); + label = new QLabel(i18n(Compile::ARGUMENT_DATA[k].description), mainWidget()); + top->addWidget(label, k, 1); + } + top->setColStretch(2, 1); + top->setRowStretch(k, 1); +} + +//---------------------------------------------------------------------------- +ToolsConfigWidget::ToolsConfigWidget(Project *project, QWidget *parent) + : ::ConfigWidget(parent), _project(project), _helpDialog(0) +{ + uint row = 0; + + QLabel *label = new QLabel(i18n("Toolchain:"), this); + addWidget(label, row,row, 0,0); + _tool = new KeyComboBox(this); + Tool::Lister::ConstIterator it; + for (it=Tool::lister().begin(); it!=Tool::lister().end(); ++it) + _tool->appendItem(it.key(), it.data()->label()); + connect(_tool->widget(), SIGNAL(activated(int)), SLOT(toolChanged())); + addWidget(_tool->widget(), row,row, 1,1); + label = new QLabel(i18n("Output type:"), this); + addWidget(label, row,row, 2,2); + _output = new KeyComboBox(this); + FOR_EACH(Tool::OutputType, type) _output->appendItem(type, type.label()); + addWidget(_output->widget(), row,row, 3,3); + row++; + + _mainStack = new QWidgetStack(this); + addWidget(_mainStack, row,row, 0,4); + row++; + _tabWidget = new QTabWidget(_mainStack); + _mainStack->addWidget(_tabWidget); + FOR_EACH(Tool::Category, category) { + _stacks[category] = new KeyWidgetStack(_tabWidget); + _stacks[category]->widget()->setMargin(10); + Tool::Lister::ConstIterator it; + for (it=Tool::lister().begin(); it!=Tool::lister().end(); ++it) { + if ( it.data()->isCustom() ) continue; + if ( !it.data()->needs(_project, category) ) continue; + ToolConfigWidget *cw = static_cast(it.data()->gui())->createConfigWidget(category, project); + Q_ASSERT(cw); + _stacks[category]->appendItem(it.key(), cw); + connect(cw, SIGNAL(displayHelp()), SLOT(displayHelp())); + } + } + _customWidget = new QWidget(_mainStack); + _mainStack->addWidget(_customWidget); + QVBoxLayout *vbox = new QVBoxLayout(_customWidget); + label = new QLabel(i18n("Custom shell commands:"), _customWidget); + vbox->addWidget(label); + _commandsEditor = new EditListBox(1, _customWidget, "command_editor", EditListBox::DuplicatesAllowed); + vbox->addWidget(_commandsEditor); + + setColStretch(4, 1); +} + +void ToolsConfigWidget::toolChanged() +{ + QString name = _tool->currentItem(); + bool canMakeLibrary = Tool::lister().group(name)->needs(_project, Tool::Category::Librarian); + _output->widget()->setEnabled(canMakeLibrary); + if ( !canMakeLibrary ) _output->setCurrentItem(Tool::OutputType::Executable); + if ( name==Tool::Group::CUSTOM_NAME ) _mainStack->raiseWidget(_customWidget); + else { + _mainStack->raiseWidget(_tabWidget); + FOR_EACH(Tool::Category, k) { + _tabWidget->removePage(_stacks[k]->widget()); + _stacks[k]->widget()->hide(); + if ( _stacks[k]->contains(name) ) { + _stacks[k]->setCurrentItem(name); + _stacks[k]->widget()->show(); + _tabWidget->addTab(_stacks[k]->widget(), i18n(k.data().title)); + } + } + _tabWidget->setCurrentPage(0); + } +} + +void ToolsConfigWidget::loadConfig() +{ + const Tool::Group &group = Compile::Config::toolGroup(_project); + _tool->setCurrentItem(group.name()); + _output->setCurrentItem(_project->outputType()); + QStringList commands = Compile::Config::customCommands(_project); + _commandsEditor->setTexts(commands); + toolChanged(); + FOR_EACH(Tool::Category, k) { + KeyWidgetStack::ConstIterator it; + for (it=_stacks[k]->begin(); it!=_stacks[k]->end(); ++it) { + if ( it.key()==Tool::Group::CUSTOM_NAME ) continue; + static_cast(_stacks[k]->item(it.key()))->loadConfig(); + } + } +} + +void ToolsConfigWidget::saveConfig() +{ + QString name = _tool->currentItem(); + Compile::Config::setToolGroup(_project, *Tool::lister().group(name)); + _project->setOutputType(_output->currentItem()); + Compile::Config::setCustomCommands(_project, _commandsEditor->texts()); + FOR_EACH(Tool::Category, k) { + if ( !_stacks[k]->contains(name) ) continue; + QWidget *w = _stacks[k]->item(name); + static_cast(w)->saveConfig(); + } +} + +void ToolsConfigWidget::displayHelp() +{ + if ( _helpDialog.isNull() ) _helpDialog = new HelpDialog(this); + _helpDialog->show(); +} diff --git a/src/tools/list/tools_config_widget.h b/src/tools/list/tools_config_widget.h new file mode 100644 index 0000000..0f41b6a --- /dev/null +++ b/src/tools/list/tools_config_widget.h @@ -0,0 +1,60 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * Copyright (C) 2004 Alain Gibaud * + * * + * 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. * + ***************************************************************************/ +#ifndef TOOLS_CONFIG_WIDGET_H +#define TOOLS_CONFIG_WIDGET_H + +#include +#include +#include + +#include "common/gui/config_widget.h" +#include "common/gui/dialog.h" +#include "common/gui/key_gui.h" +#include "common/gui/editlistbox.h" +#include "tools/base/generic_tool.h" +class Project; +class ToolConfigWidget; + +//---------------------------------------------------------------------------- +class HelpDialog : public Dialog +{ +Q_OBJECT +public: + HelpDialog(QWidget *parent); +}; + +//---------------------------------------------------------------------------- +class ToolsConfigWidget : public ConfigWidget +{ +Q_OBJECT +public: + ToolsConfigWidget(Project *project, QWidget *parent); + virtual void loadConfig(); + +public slots: + virtual void saveConfig(); + virtual void displayHelp(); + +private slots: + void toolChanged(); + +private: + Project *_project; + KeyComboBox *_tool; + KeyComboBox *_output; + QWidgetStack *_mainStack; + QWidget *_customWidget; + EditListBox *_commandsEditor; + QTabWidget *_tabWidget; + QMap *> _stacks; + QGuardedPtr _helpDialog; +}; + +#endif diff --git a/src/tools/mpc/Makefile.am b/src/tools/mpc/Makefile.am new file mode 100644 index 0000000..debc478 --- /dev/null +++ b/src/tools/mpc/Makefile.am @@ -0,0 +1,8 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libmpc.la +libmpc_la_SOURCES = mpc.cpp mpc_compile.cpp mpc_config.cpp +libmpc_la_LDFLAGS = $(all_libraries) + +SUBDIRS = gui \ No newline at end of file diff --git a/src/tools/mpc/gui/Makefile.am b/src/tools/mpc/gui/Makefile.am new file mode 100644 index 0000000..5d590c6 --- /dev/null +++ b/src/tools/mpc/gui/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libmpcui.la +libmpcui_la_SOURCES = mpc_ui.cpp +libmpcui_la_LDFLAGS = $(all_libraries) \ No newline at end of file diff --git a/src/tools/mpc/gui/mpc_ui.cpp b/src/tools/mpc/gui/mpc_ui.cpp new file mode 100644 index 0000000..b3ad4e7 --- /dev/null +++ b/src/tools/mpc/gui/mpc_ui.cpp @@ -0,0 +1,14 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "mpc_ui.h" + +//---------------------------------------------------------------------------- +MPC::ConfigWidget::ConfigWidget(Project *project) + : ToolConfigWidget(project) +{} diff --git a/src/tools/mpc/gui/mpc_ui.h b/src/tools/mpc/gui/mpc_ui.h new file mode 100644 index 0000000..2fc51f9 --- /dev/null +++ b/src/tools/mpc/gui/mpc_ui.h @@ -0,0 +1,35 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef MPC_UI_H +#define MPC_UI_H + +#include "tools/gui/tool_config_widget.h" +#include "tools/gui/tool_group_ui.h" + +namespace MPC +{ +//---------------------------------------------------------------------------- +class ConfigWidget : public ToolConfigWidget +{ +Q_OBJECT +public: + ConfigWidget(Project *project); + virtual void initEntries() {} +}; + +//---------------------------------------------------------------------------- +class GroupUI : public Tool::GroupUI +{ +public: + virtual ToolConfigWidget *configWidgetFactory(Tool::Category, ::Project *project) const { return new ConfigWidget(project); } +}; + +} // namespace + +#endif diff --git a/src/tools/mpc/mpc.cpp b/src/tools/mpc/mpc.cpp new file mode 100644 index 0000000..88f9ec2 --- /dev/null +++ b/src/tools/mpc/mpc.cpp @@ -0,0 +1,57 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "mpc.h" + +#include + +#include "mpc_compile.h" +#include "mpc_config.h" +#include "devices/pic/pic/pic_memory.h" +#include "devices/list/device_list.h" +#include "devices/base/device_group.h" + +//---------------------------------------------------------------------------- +QValueList MPC::Group::getSupportedDevices(const QString &) const +{ + QValueList list; + QValueVector devices = Device::lister().group("pic")->supportedDevices(); + for (uint i=0; i(data)->architecture(); + if ( arch!=Pic::Architecture::P16X && arch!=Pic::Architecture::P17C ) continue; + list.append(data); + } + return list; +} + +Compile::Process *MPC::Group::processFactory(const Compile::Data &data) const +{ + switch (data.category.type()) { + case Tool::Category::Compiler: return new MPC::CompileFile; + default: break; + } + Q_ASSERT(false); + return 0; +} + +Compile::Config *MPC::Group::configFactory(::Project *project) const +{ + return new Config(project); +} + +QString MPC::Group::informationText() const +{ + return i18n("MPC Compiler is a C compiler distributed by Byte Craft.").arg("http://www.bytecraft.com/mpccaps.html"); +} + +Tool::Group::BaseData MPC::Group::baseFactory(Tool::Category category) const +{ + if ( category==Tool::Category::Compiler ) return BaseData(new MPC::Base, Both); + return BaseData(); +} diff --git a/src/tools/mpc/mpc.h b/src/tools/mpc/mpc.h new file mode 100644 index 0000000..a378307 --- /dev/null +++ b/src/tools/mpc/mpc.h @@ -0,0 +1,49 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef MPC_H +#define MPC_H + +#include "tools/base/tool_group.h" +#include "common/global/pfile.h" + +namespace MPC +{ +//---------------------------------------------------------------------------- +class Base : public Tool::Base +{ +public: + virtual QString baseExecutable(bool, Tool::OutputExecutableType) const { return "mpcw"; } + virtual bool checkExecutable() const { return false; } + virtual QStringList checkExecutableOptions(bool) const { return QStringList(); } + virtual bool checkExecutableResult(bool, QStringList &) const { return true; } +}; + +//---------------------------------------------------------------------------- +class Group : public Tool::Group +{ +public: + virtual QString name() const { return "mpcw"; } + virtual QString label() const { return i18n("MPC Compiler"); } + virtual QString informationText() const; + virtual Tool::Category checkDevicesCategory() const { return Tool::Category::Nb_Types; } + virtual Tool::ExecutableType preferedExecutableType() const { return Tool::ExecutableType::Windows; } + virtual Tool::CompileType compileType() const { return Tool::SingleFile; } + virtual PURL::FileType implementationType(PURL::ToolType type) const { return (type==PURL::ToolType::Compiler ? PURL::CSource : PURL::Nb_FileTypes); } + +private: + virtual QValueList getSupportedDevices(const QString &s) const; + virtual Compile::Process *processFactory(const Compile::Data &data) const; + virtual Compile::Config *configFactory(::Project *project) const; + virtual BaseData baseFactory(Tool::Category) const; + virtual Tool::SourceGenerator *sourceGeneratorFactory() const { /*TODO*/ return 0; } +}; + +} // namespace + +#endif diff --git a/src/tools/mpc/mpc_compile.cpp b/src/tools/mpc/mpc_compile.cpp new file mode 100644 index 0000000..69ee994 --- /dev/null +++ b/src/tools/mpc/mpc_compile.cpp @@ -0,0 +1,51 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "mpc_compile.h" + +#include "common/global/pfile.h" +#include "mpc_config.h" +#include "devices/list/device_list.h" +#include "devices/pic/base/pic.h" + +QStringList MPC::CompileFile::genericArguments(const Compile::Config &) const +{ + QStringList args; + args += "%I"; + return args; +} + +void MPC::CompileFile::logStderrLine(const QString &) +{ + // ignore output +} + +void MPC::CompileFile::parseLine(const QString &line) +{ + if ( parseErrorLine(line, Compile::ParseErrorData("(\\w+)\\s+(.*)\\s+(\\d+):\\d+:(.*)", 2, 3, 4, 1)) ) return; + doLog(Log::LineType::Normal, line, QString::null, 0); // unrecognized +} + +void MPC::CompileFile::done(int code) +{ + // rely on error file + PURL::Url url = PURL::Url(directory(), inputFilepath(0)).toExtension("err"); + Log::StringView sview; + PURL::File file(url, sview); + if ( !file.openForRead() ) doLog(Log::LineType::Error, i18n("Could not find error file (%1).").arg(url.pretty()), QString::null, 0); + else { + QStringList lines = file.readLines(); + for (uint i=0; i * + * * + * 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. * + ***************************************************************************/ +#ifndef MPC_COMPILE_H +#define MPC_COMPILE_H + +#include "tools/list/compile_process.h" + +namespace MPC +{ + +class CompileFile : public Compile::Process +{ +Q_OBJECT +protected: + virtual QString deviceName() const { return QString::null; } + virtual QStringList genericArguments(const Compile::Config &config) const; + virtual void logStderrLine(const QString &line); + virtual QString outputFiles() const; + +protected slots: + virtual void done(int code); + +private: + void parseLine(const QString &line); +}; + +} // namespace + +#endif diff --git a/src/tools/mpc/mpc_config.cpp b/src/tools/mpc/mpc_config.cpp new file mode 100644 index 0000000..d477e1e --- /dev/null +++ b/src/tools/mpc/mpc_config.cpp @@ -0,0 +1,9 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "mpc_config.h" diff --git a/src/tools/mpc/mpc_config.h b/src/tools/mpc/mpc_config.h new file mode 100644 index 0000000..45ae64c --- /dev/null +++ b/src/tools/mpc/mpc_config.h @@ -0,0 +1,25 @@ +/*************************************************************************** + * Copyright (C) 2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef MPC_CONFIG_H +#define MPC_CONFIG_H + +#include "tools/list/compile_config.h" + +namespace MPC +{ +//---------------------------------------------------------------------------- +class Config : public Compile::Config +{ +public: + Config(Project *project) : Compile::Config(project) {} +}; + +} // namespace + +#endif diff --git a/src/tools/pic30/Makefile.am b/src/tools/pic30/Makefile.am new file mode 100644 index 0000000..edf11c8 --- /dev/null +++ b/src/tools/pic30/Makefile.am @@ -0,0 +1,9 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libpic30.la +libpic30_la_LDFLAGS = $(all_libraries) +libpic30_la_SOURCES = pic30_compile.cpp pic30_config.cpp pic30.cpp \ + pic30_generator.cpp + +SUBDIRS = gui \ No newline at end of file diff --git a/src/tools/pic30/gui/Makefile.am b/src/tools/pic30/gui/Makefile.am new file mode 100644 index 0000000..4ee894e --- /dev/null +++ b/src/tools/pic30/gui/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libpic30ui.la +libpic30ui_la_LDFLAGS = $(all_libraries) +libpic30ui_la_SOURCES = pic30_ui.cpp diff --git a/src/tools/pic30/gui/pic30_ui.cpp b/src/tools/pic30/gui/pic30_ui.cpp new file mode 100644 index 0000000..9d1b2c4 --- /dev/null +++ b/src/tools/pic30/gui/pic30_ui.cpp @@ -0,0 +1,26 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "pic30_ui.h" + +#include + +#include "common/gui/purl_gui.h" +#include "tools/pic30/pic30_config.h" + +//---------------------------------------------------------------------------- +PIC30::ConfigWidget::ConfigWidget(Project *project) + : ToolConfigWidget(project) +{} + +void PIC30::ConfigWidget::initEntries() +{ + if ( _category==Tool::Category::Compiler || _category==Tool::Category::Assembler || _category==Tool::Category::Linker ) + createIncludeDirectoriesEntry(); + if ( _category==Tool::Category::Linker ) createCustomLibrariesEntry(); +} diff --git a/src/tools/pic30/gui/pic30_ui.h b/src/tools/pic30/gui/pic30_ui.h new file mode 100644 index 0000000..d9890e7 --- /dev/null +++ b/src/tools/pic30/gui/pic30_ui.h @@ -0,0 +1,36 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PIC30_UI_H +#define PIC30_UI_H + +#include "tools/gui/tool_config_widget.h" +#include "tools/gui/tool_group_ui.h" + +namespace PIC30 +{ + +//---------------------------------------------------------------------------- +class ConfigWidget : public ToolConfigWidget +{ +Q_OBJECT +public: + ConfigWidget(Project *project); + virtual void initEntries(); +}; + +//---------------------------------------------------------------------------- +class GroupUI : public Tool::GroupUI +{ +public: + virtual ::ToolConfigWidget *configWidgetFactory(Tool::Category, ::Project *project) const { return new ConfigWidget(project); } +}; + +} // namespace + +#endif diff --git a/src/tools/pic30/pic30.cpp b/src/tools/pic30/pic30.cpp new file mode 100644 index 0000000..45b9270 --- /dev/null +++ b/src/tools/pic30/pic30.cpp @@ -0,0 +1,137 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "pic30.h" + +#include "devices/list/device_list.h" +#include "devices/base/device_group.h" +#include "pic30_compile.h" +#include "pic30_config.h" +#include "devices/pic/pic/pic_memory.h" +#include "common/global/process.h" +#include "pic30_generator.h" + +//---------------------------------------------------------------------------- +QString PIC30::Base::baseExecutable(bool, Tool::OutputExecutableType type) const +{ + QString s = "pic30-"; + if ( type==Tool::OutputExecutableType::Coff ) s += "coff"; + else s += "elf"; + s += "-"; + switch (_category.type()) { + case Tool::Category::Compiler: return s + "gcc"; + case Tool::Category::Assembler: return s + "as"; + case Tool::Category::Linker: return s + "ld"; + case Tool::Category::Librarian: return s + "ar"; + case Tool::Category::BinToHex: return s + "bin2hex"; + case Tool::Category::Nb_Types: break; + } + Q_ASSERT(false); + return QString::null; +} + +QStringList PIC30::Base::checkExecutableOptions(bool) const +{ + if ( _category!=Tool::Category::BinToHex ) return "--version"; + return QStringList(); +} + +bool PIC30::Base::checkExecutableResult(bool, QStringList &lines) const +{ + if ( lines.count()==0 ) return false; + lines[0] = lines[0].stripWhiteSpace(); + switch (_category.type()) { + case Tool::Category::Compiler: return lines[0].startsWith("pic30"); + case Tool::Category::Assembler: return lines[0].startsWith("GNU assembler"); + case Tool::Category::Linker: return lines[0].startsWith("GNU ld"); + case Tool::Category::BinToHex: return lines.join(" ").contains("Microchip "); + case Tool::Category::Librarian: return lines[0].startsWith("GNU ar"); + case Tool::Category::Nb_Types: break; + } + Q_ASSERT(false); + return false; +} + +//---------------------------------------------------------------------------- +QString PIC30::Group::informationText() const +{ + return i18n("The PIC30 ToolChain is a toolsuite for 16-bit PICs available from Microchip. Most of it is available under the GNU Public License.").arg("http://microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en010065&part=SW006012"); +} + +Tool::Group::BaseData PIC30::Group::baseFactory(Tool::Category category) const +{ + if ( category==Tool::Category::Compiler || category==Tool::Category::Assembler + || category==Tool::Category::Linker || category==Tool::Category::BinToHex ) return BaseData(new ::PIC30::Base, Both); + if ( category==Tool::Category::Librarian ) return BaseData(new ::PIC30::Base, ProjectOnly); + return BaseData(); +} + +QValueList PIC30::Group::getSupportedDevices(const QString &) const +{ + QValueList list; + QValueVector devices = Device::lister().group("pic")->supportedDevices(); + for (uint i=0; i(data)->is16bitFamily() ) list.append(data); + } + return list; +} + +Compile::Process *PIC30::Group::processFactory(const Compile::Data &data) const +{ + switch (data.category.type()) { + case Tool::Category::Compiler: + if (data.project) return new PIC30::CompileProjectFile; + return new PIC30::CompileStandaloneFile; + case Tool::Category::Assembler: + if (data.project) return new PIC30::AssembleProjectFile; + return new PIC30::AssembleStandaloneFile; + case Tool::Category::Linker: + if (data.project) return new PIC30::LinkProject; + return new PIC30::LinkStandalone; + case Tool::Category::Librarian: + Q_ASSERT(data.project); + return new PIC30::LibraryProject; + case Tool::Category::BinToHex: return new PIC30::BinToHex; + case Tool::Category::Nb_Types: break; + } + Q_ASSERT(false); + return 0; +} + +Compile::Config *PIC30::Group::configFactory(::Project *project) const +{ + return new Config(project); +} + +PURL::FileType PIC30::Group::implementationType(PURL::ToolType type) const +{ + if ( type==PURL::ToolType::Assembler ) return PURL::AsmPIC30; + if ( type==PURL::ToolType::Compiler ) return PURL::CSource; + return PURL::Nb_FileTypes; +} + +Tool::SourceGenerator *PIC30::Group::sourceGeneratorFactory() const +{ + return new SourceGenerator; +} + +PURL::Directory PIC30::Group::autodetectDirectory(Compile::DirectoryType type, const PURL::Directory &execDir, bool withWine) const +{ + if ( !withWine ) return PURL::Directory(); + PURL::Directory baseDir = execDir.up(); + switch (type.type()) { + case Compile::DirectoryType::LinkerScript: return baseDir.down("support/gld"); + case Compile::DirectoryType::Header: return baseDir.down("support/h"); + case Compile::DirectoryType::Library: return baseDir.down("lib"); + case Compile::DirectoryType::Executable: + case Compile::DirectoryType::Source: + case Compile::DirectoryType::Nb_Types: Q_ASSERT(false); break; + } + return PURL::Directory(); +} diff --git a/src/tools/pic30/pic30.h b/src/tools/pic30/pic30.h new file mode 100644 index 0000000..a490ed0 --- /dev/null +++ b/src/tools/pic30/pic30.h @@ -0,0 +1,54 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PIC30_H +#define PIC30_H + +#include "tools/base/tool_group.h" + +namespace PIC30 +{ + +//---------------------------------------------------------------------------- +class Base : public Tool::Base +{ +public: + virtual QString baseExecutable(bool withWine, Tool::OutputExecutableType type) const; + +private: + virtual QStringList checkExecutableOptions(bool withWine) const; + virtual bool checkExecutableResult(bool withWine, QStringList &lines) const; +}; + +//---------------------------------------------------------------------------- +class Group : public Tool::Group +{ +public: + virtual QString name() const { return "pic30"; } + virtual QString label() const { return i18n("PIC30 Toolchain"); } + virtual QString informationText() const; + virtual bool hasDirectory(Compile::DirectoryType type) const { return type==Compile::DirectoryType::Header || type==Compile::DirectoryType::LinkerScript || type==Compile::DirectoryType::Library; } + virtual PURL::Directory autodetectDirectory(Compile::DirectoryType type, const PURL::Directory &execDir, bool withWine) const; + virtual bool hasOutputExecutableType(Tool::OutputExecutableType type) const { return ( type==Tool::OutputExecutableType::Coff || type==Tool::OutputExecutableType::Elf ); } + virtual Tool::Category checkDevicesCategory() const { return Tool::Category::Nb_Types; } + virtual Tool::ExecutableType preferedExecutableType() const { return Tool::ExecutableType::Unix; } + virtual Tool::CompileType compileType() const { return Tool::SeparateFiles; } + virtual PURL::FileType linkerScriptType() const { return PURL::Gld; } + virtual PURL::FileType implementationType(PURL::ToolType type) const; + +private: + virtual BaseData baseFactory(Tool::Category category) const; + virtual QValueList getSupportedDevices(const QString &s) const; + virtual Compile::Process *processFactory(const Compile::Data &data) const; + virtual Compile::Config *configFactory(::Project *project) const; + virtual Tool::SourceGenerator *sourceGeneratorFactory() const; +}; + +} // namespace + +#endif diff --git a/src/tools/pic30/pic30_compile.cpp b/src/tools/pic30/pic30_compile.cpp new file mode 100644 index 0000000..02cbb35 --- /dev/null +++ b/src/tools/pic30/pic30_compile.cpp @@ -0,0 +1,196 @@ +/*************************************************************************** + * Copyright (C) 2006-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "pic30_compile.h" + +#include "config.h" +#include "pic30_config.h" +#include "devices/list/device_list.h" + +//----------------------------------------------------------------------------- +QStringList PIC30::CompileFile::genericArguments(const Compile::Config &config) const +{ + QStringList args; + args += "-S"; // compile only + args += "$NO_AUTO_DEVICE(-mcpu=%DEVICE)"; + args += config.includeDirs(Tool::Category::Compiler, "-I"); + PURL::Directory purl = Compile::Config::directory(group(), Compile::DirectoryType::Header); + if ( !purl.isEmpty() ) args += "-I" + purl.path(); + args += config.customOptions(Tool::Category::Compiler); + return args; +} + +QString PIC30::CompileFile::outputFiles() const +{ + return "PURL::AsmPIC30"; +} + +void PIC30::CompileFile::logStderrLine(const QString &line) +{ + // #### TODO + doLog(Log::LineType::Normal, line, QString::null, 0); // unrecognized +} + +//----------------------------------------------------------------------------- +QStringList PIC30::CompileStandaloneFile::genericArguments(const Compile::Config &config) const +{ + QStringList args = CompileFile::genericArguments(config); + args += "%I"; + return args; +} + +QString PIC30::CompileStandaloneFile::outputFiles() const +{ + return CompileFile::outputFiles() + " PURL::Object PURL::Elf"; +} + +//----------------------------------------------------------------------------- +QStringList PIC30::CompileProjectFile::genericArguments(const Compile::Config &config) const +{ + QStringList args = CompileFile::genericArguments(config); + args += "-g"; + args += "%I"; + return args; +} + +//----------------------------------------------------------------------------- +QStringList PIC30::AssembleFile::genericArguments(const Compile::Config &config) const +{ + QStringList args; + args += "-g"; + args += "-a=%LIST"; // listing + args += "-o%O"; + args += config.includeDirs(Tool::Category::Assembler, "-I"); + args += config.customOptions(Tool::Category::Assembler); + return args; +} + +QString PIC30::AssembleFile::outputFiles() const +{ + return "PURL::Object PURL::Lst"; +} + +void PIC30::AssembleFile::logStderrLine(const QString &line) +{ + // #### TODO + doLog(Log::LineType::Normal, line, QString::null, 0); // unrecognized +} + +//----------------------------------------------------------------------------- +QStringList PIC30::AssembleStandaloneFile::genericArguments(const Compile::Config &config) const +{ + QStringList args = AssembleFile::genericArguments(config); + args += "$NO_AUTO_DEVICE(-p%DEVICE)"; + args += "%I"; + return args; +} + +//----------------------------------------------------------------------------- +QStringList PIC30::AssembleProjectFile::genericArguments(const Compile::Config &config) const +{ + QStringList args = AssembleFile::genericArguments(config); + if ( !_data.items[0].generated ) args += "-p%DEVICE"; + args += "%I"; + return args; +} + +//----------------------------------------------------------------------------- +QString PIC30::Link::outputFilepath() const +{ + PURL::FileType type = Compile::Config::outputExecutableType(group()).data().type; + return filepath(type); +} + +QStringList PIC30::Link::genericArguments(const Compile::Config &config) const +{ + QStringList args; + args += "-Map"; + args += "%MAP"; + args += "-o%O"; + args += config.includeDirs(Tool::Category::Linker, "-L"); + PURL::Directory purl = Compile::Config::directory(group(), Compile::DirectoryType::Library); + if ( !purl.isEmpty() ) args += "-L" + purl.path(); + args += "$LKR(-T%LKR)"; + args += config.customOptions(Tool::Category::Linker); + args += "%OBJS"; + return args; +} + +QString PIC30::Link::outputFiles() const +{ + PURL::FileType type = Compile::Config::outputExecutableType(group()).data().type; + return QString("PURL::Map PURL::") + type.key(); +} + +void PIC30::Link::logStderrLine(const QString &line) +{ + // #### TODO + doLog(Log::LineType::Normal, line, QString::null, 0); // unrecognized +} + +//----------------------------------------------------------------------------- +QStringList PIC30::LinkStandalone::genericArguments(const Compile::Config &config) const +{ + QStringList args = Link::genericArguments(config); + args += config.customLibraries(Tool::Category::Linker); + return args; +} + +//----------------------------------------------------------------------------- +QStringList PIC30::LinkProject::genericArguments(const Compile::Config &config) const +{ + QStringList args = Link::genericArguments(config); + args += "%LIBS"; + args += config.customLibraries(Tool::Category::Linker); + return args; +} + +//----------------------------------------------------------------------------- +QStringList PIC30::LibraryProject::genericArguments(const Compile::Config &) const +{ + QStringList args; + args += "-rc"; // insert new + do not warn if creating library + args += "%O"; + args += "%LIBS"; + args += "%OBJS"; + return args; +} + +void PIC30::LibraryProject::logStderrLine(const QString &line) +{ + // #### TODO + doLog(Log::LineType::Normal, line, QString::null, 0); // unrecognized +} + +QString PIC30::LibraryProject::outputFiles() const +{ + return "PURL::Library"; +} + +//----------------------------------------------------------------------------- +QString PIC30::BinToHex::inputFilepath(uint) const +{ + PURL::FileType type = Compile::Config::outputExecutableType(group()).data().type; + return filepath(type); +} + +QStringList PIC30::BinToHex::genericArguments(const Compile::Config &) const +{ + return "%I"; +} + +QString PIC30::BinToHex::outputFiles() const +{ + return "PURL::Hex"; +} + +void PIC30::BinToHex::logStderrLine(const QString &line) +{ + // #### TODO + doLog(Log::LineType::Normal, line, QString::null, 0); // unrecognized +} diff --git a/src/tools/pic30/pic30_compile.h b/src/tools/pic30/pic30_compile.h new file mode 100644 index 0000000..c298eac --- /dev/null +++ b/src/tools/pic30/pic30_compile.h @@ -0,0 +1,128 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PIC30_COMPILE_H +#define PIC30_COMPILE_H + +#include "tools/list/compile_process.h" + +namespace PIC30 +{ +//----------------------------------------------------------------------------- +class Process : public Compile::Process +{ +Q_OBJECT +protected: + virtual QString deviceName() const { return _data.device; } +}; + +//----------------------------------------------------------------------------- +class CompileFile : public Process +{ +Q_OBJECT +protected: + virtual QStringList genericArguments(const Compile::Config &config) const; + virtual QString outputFiles() const; + virtual void logStderrLine(const QString &line); +}; + +//----------------------------------------------------------------------------- +class CompileStandaloneFile : public CompileFile +{ +Q_OBJECT +protected: + virtual QStringList genericArguments(const Compile::Config &config) const; + virtual QString outputFiles() const; +}; + +//----------------------------------------------------------------------------- +class CompileProjectFile : public CompileFile +{ +Q_OBJECT +protected: + virtual QStringList genericArguments(const Compile::Config &config) const; +}; + +//----------------------------------------------------------------------------- +class AssembleFile : public Process +{ +Q_OBJECT +protected: + virtual QString outputFilepath() const { return filepath(PURL::Object); } + virtual QStringList genericArguments(const Compile::Config &config) const; + virtual QString outputFiles() const; + virtual void logStderrLine(const QString &line); +}; + +//----------------------------------------------------------------------------- +class AssembleStandaloneFile : public AssembleFile +{ +Q_OBJECT +protected: + virtual QStringList genericArguments(const Compile::Config &config) const; +}; + +//----------------------------------------------------------------------------- +class AssembleProjectFile : public AssembleFile +{ +Q_OBJECT +protected: + virtual QStringList genericArguments(const Compile::Config &config) const; +}; + +//----------------------------------------------------------------------------- +class Link : public Process +{ +Q_OBJECT +protected: + virtual QString outputFilepath() const; + virtual QStringList genericArguments(const Compile::Config &config) const; + virtual QString outputFiles() const; + virtual void logStderrLine(const QString &line); +}; + +//----------------------------------------------------------------------------- +class LinkStandalone : public Link +{ +Q_OBJECT +protected: + virtual QStringList genericArguments(const Compile::Config &config) const; +}; + +//----------------------------------------------------------------------------- +class LinkProject : public Link +{ +Q_OBJECT +protected: + virtual QStringList genericArguments(const Compile::Config &config) const; +}; + +//----------------------------------------------------------------------------- +class LibraryProject : public Process +{ +Q_OBJECT +protected: + virtual QStringList genericArguments(const Compile::Config &config) const; + virtual QString outputFiles() const; + virtual void logStderrLine(const QString &line); +}; + +//----------------------------------------------------------------------------- +class BinToHex : public Process +{ +Q_OBJECT +protected: + virtual QString inputFilepath(uint i) const; + virtual QStringList genericArguments(const Compile::Config &config) const; + virtual QString outputFiles() const; + virtual void logStderrLine(const QString &line); +}; + +} // namespace + +#endif diff --git a/src/tools/pic30/pic30_config.cpp b/src/tools/pic30/pic30_config.cpp new file mode 100644 index 0000000..32ef7e0 --- /dev/null +++ b/src/tools/pic30/pic30_config.cpp @@ -0,0 +1,9 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "pic30_config.h" diff --git a/src/tools/pic30/pic30_config.h b/src/tools/pic30/pic30_config.h new file mode 100644 index 0000000..f0b1520 --- /dev/null +++ b/src/tools/pic30/pic30_config.h @@ -0,0 +1,25 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PIC30_CONFIG_H +#define PIC30_CONFIG_H + +#include "tools/list/compile_config.h" + +namespace PIC30 +{ +//---------------------------------------------------------------------------- +class Config : public Compile::Config +{ +public: + Config(Project *project) : Compile::Config(project) {} +}; + +} // namespace + +#endif diff --git a/src/tools/pic30/pic30_generator.cpp b/src/tools/pic30/pic30_generator.cpp new file mode 100644 index 0000000..fe874e3 --- /dev/null +++ b/src/tools/pic30/pic30_generator.cpp @@ -0,0 +1,111 @@ +/*************************************************************************** + * Copyright (C) 2006-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "pic30_generator.h" + +#include "devices/pic/pic/pic_memory.h" + +SourceLine::List PIC30::SourceGenerator::configLines(PURL::ToolType type, const Device::Memory &memory, bool &ok) const +{ + const Pic::Memory &pmemory = static_cast(memory); + const Pic::Data &data = pmemory.device(); + const Pic::Config &config = data.config(); + SourceLine::List lines; + for (uint i=0; i"); + return lines; +} + +SourceLine::List PIC30::SourceGenerator::sourceFileContent(PURL::ToolType type, const Device::Data &, bool &ok) const +{ + SourceLine::List lines; + if ( type==PURL::ToolType::Assembler ) { + lines.appendTitle(i18n("Global declarations")); + lines.appendIndentedCode(".global _wreg_init"); + lines.appendIndentedCode(".global __reset", i18n("label for code start")); + lines.appendIndentedCode(".global __T1Interrrupt", i18n("declare Timer1 ISR")); + lines.appendEmpty(); + lines.appendSeparator(); + lines.appendTitle(i18n("Constants in program space")); + lines.appendIndentedCode(".section .constbuffer, code"); + lines.appendIndentedCode(".palign 2"); + lines.appendNotIndentedCode("const1:"); + lines.appendIndentedCode(".hword 0x0001, 0x0002, 0X0003"); + lines.appendEmpty(); + lines.appendTitle(i18n("Unitialized variables in X-space")); + lines.appendIndentedCode(".section .xbss, bss, xmemory"); + lines.appendNotIndentedCode("x_var1: .space 4", i18n("allocating 4 bytes")); + lines.appendEmpty(); + lines.appendTitle(i18n("Unitialized variables in Y-space")); + lines.appendIndentedCode(".section .ybss, bss, ymemory"); + lines.appendNotIndentedCode("y_var1: .space 2", i18n("allocating 2 bytes")); + lines.appendEmpty(); + lines.appendTitle(i18n("Unitialized variables in near data memory")); + lines.appendIndentedCode(".section .nbss, bss, near"); + lines.appendNotIndentedCode("var1: .space 4", i18n("allocating 4 bytes")); + lines.appendEmpty(); + lines.appendSeparator(); + lines.appendTitle("Code section"); + lines.appendNotIndentedCode(".text"); + lines.appendNotIndentedCode("__reset:"); + lines.appendIndentedCode("MOV #__SP_init, W15", i18n("initialize stack pointer")); + lines.appendIndentedCode("MOV #__SPLIM_init, W0", i18n("initialize stack pointer limit register")); + lines.appendIndentedCode("MOV W0, SPLIM"); + lines.appendIndentedCode("NOP", i18n("nop after SPLIM initialization")); + lines.appendIndentedCode("CALL _wreg_init", i18n("call _wreg_init subroutine")); + lines.appendEmpty(); + lines.appendIndentedCode(QString::null, "<<" + i18n("insert code") + ">>"); + lines.appendEmpty(); + lines.appendNotIndentedCode("done:"); + lines.appendIndentedCode("BRA done", i18n("loop forever")); + lines.appendEmpty(); + lines.appendSeparator(); + lines.appendTitle(i18n("Subroutine to initialize W registers to 0x0000")); + lines.appendNotIndentedCode("_wreg_init:"); + lines.appendIndentedCode("CLR W0"); + lines.appendIndentedCode("MOV W0, W14"); + lines.appendIndentedCode("REPEAT #12"); + lines.appendIndentedCode("MOV W0, [++W14]"); + lines.appendIndentedCode("CLR W14"); + lines.appendIndentedCode("RETURN"); + lines.appendEmpty(); + lines.appendSeparator(); + lines.appendTitle(i18n("Timer1 interrupt service routine")); + lines.appendNotIndentedCode("__T1Interrupt:"); + lines.appendIndentedCode("PUSH.D W4", i18n("example of context saving (push W4 and W5)")); + lines.appendIndentedCode(QString::null, "<<" + i18n("insert interrupt code") + ">>"); + lines.appendIndentedCode("BCLR IFS0, #T1IF", i18n("clear Timer1 interrupt flag status bit")); + lines.appendIndentedCode("POP.D W4", i18n("restore context from stack")); + lines.appendIndentedCode("RETFIE"); + lines.appendEmpty(); + lines.appendSeparator(); + lines.appendTitle(i18n("End of all code sections")); + lines.appendNotIndentedCode(".end"); + } else { + // #### TODO + ok = false; + } + return lines; +} diff --git a/src/tools/pic30/pic30_generator.h b/src/tools/pic30/pic30_generator.h new file mode 100644 index 0000000..510a483 --- /dev/null +++ b/src/tools/pic30/pic30_generator.h @@ -0,0 +1,27 @@ +/*************************************************************************** + * Copyright (C) 2006-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PIC30_GENERATOR_H +#define PIC30_GENERATOR_H + +#include "tools/base/tool_group.h" + +namespace PIC30 +{ + +class SourceGenerator : public Tool::SourceGenerator +{ +public: + virtual SourceLine::List configLines(PURL::ToolType type, const Device::Memory &memory, bool &ok) const; + virtual SourceLine::List sourceFileContent(PURL::ToolType type, const Device::Data &data, bool &ok) const; + virtual SourceLine::List includeLines(PURL::ToolType type, const Device::Data &data) const; +}; + +} // namespace + +#endif diff --git a/src/tools/picc/Makefile.am b/src/tools/picc/Makefile.am new file mode 100644 index 0000000..9a6d0c2 --- /dev/null +++ b/src/tools/picc/Makefile.am @@ -0,0 +1,8 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libpicc.la +libpicc_la_LDFLAGS = $(all_libraries) +libpicc_la_SOURCES = picc_compile.cpp picc_config.cpp picc.cpp + +SUBDIRS = gui \ No newline at end of file diff --git a/src/tools/picc/gui/Makefile.am b/src/tools/picc/gui/Makefile.am new file mode 100644 index 0000000..ddc928d --- /dev/null +++ b/src/tools/picc/gui/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libpiccui.la +libpiccui_la_LDFLAGS = $(all_libraries) +libpiccui_la_SOURCES = picc_ui.cpp diff --git a/src/tools/picc/gui/picc_ui.cpp b/src/tools/picc/gui/picc_ui.cpp new file mode 100644 index 0000000..207a7cb --- /dev/null +++ b/src/tools/picc/gui/picc_ui.cpp @@ -0,0 +1,20 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "picc_ui.h" + +//---------------------------------------------------------------------------- +PICC::ConfigWidget::ConfigWidget(Project *project) + : ToolConfigWidget(project) +{} + +void PICC::ConfigWidget::initEntries() +{ + if ( _category==Tool::Category::Compiler || _category==Tool::Category::Assembler ) + createIncludeDirectoriesEntry(); +} diff --git a/src/tools/picc/gui/picc_ui.h b/src/tools/picc/gui/picc_ui.h new file mode 100644 index 0000000..ec096c2 --- /dev/null +++ b/src/tools/picc/gui/picc_ui.h @@ -0,0 +1,35 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PICC_UI_H +#define PICC_UI_H + +#include "tools/gui/tool_config_widget.h" +#include "tools/gui/tool_group_ui.h" + +namespace PICC +{ +//---------------------------------------------------------------------------- +class ConfigWidget : public ToolConfigWidget +{ +Q_OBJECT +public: + ConfigWidget(Project *project); + virtual void initEntries(); +}; + +//---------------------------------------------------------------------------- +class GroupUI : public Tool::GroupUI +{ +public: + virtual ToolConfigWidget *configWidgetFactory(Tool::Category, ::Project *project) const { return new ConfigWidget(project); } +}; + +} // namespace + +#endif diff --git a/src/tools/picc/picc.cpp b/src/tools/picc/picc.cpp new file mode 100644 index 0000000..f0d6e83 --- /dev/null +++ b/src/tools/picc/picc.cpp @@ -0,0 +1,127 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "picc.h" + +#include + +#include "picc_compile.h" +#include "picc_config.h" +#include "devices/pic/pic/pic_memory.h" +#include "devices/list/device_list.h" +#include "common/global/process.h" + +//---------------------------------------------------------------------------- +bool PICC::Base::checkExecutableResult(bool, QStringList &lines) const +{ + return lines.join(" ").contains("HI-TECH"); +} + +QString PICC::BaseLite::baseExecutable(bool, Tool::OutputExecutableType) const +{ + if ( _category.type()==Tool::Category::Librarian ) return "libr"; + return "picl"; +} + +QString PICC::BaseNormal::baseExecutable(bool, Tool::OutputExecutableType) const +{ + if ( _category.type()==Tool::Category::Librarian ) return "libr"; + return "picc"; +} + +QString PICC::Base18::baseExecutable(bool, Tool::OutputExecutableType) const +{ + if ( _category.type()==Tool::Category::Librarian ) return "libr"; + return "picc18"; +} + +//---------------------------------------------------------------------------- +QValueList PICC::Group::getSupportedDevices(const QString &s) const +{ + QValueList list; + QStringList lines = QStringList::split('\n', s); + for (uint i=0; iPICC-Lite is a freeware C compiler distributed by HTSoft.").arg("http://www.htsoft.com"); +} + +Tool::Group::BaseData PICC::PICCLiteGroup::baseFactory(Tool::Category category) const +{ + if ( category==Tool::Category::Compiler || category==Tool::Category::Assembler ) return BaseData(new BaseLite, Both); + if ( category==Tool::Category::Linker || category==Tool::Category::Librarian ) return BaseData(new BaseLite, ProjectOnly); + return BaseData(); +} + +//---------------------------------------------------------------------------- +QString PICC::PICCGroup::informationText() const +{ + return i18n("PICC is a C compiler distributed by HTSoft.").arg("http://www.htsoft.com"); +} + +Tool::Group::BaseData PICC::PICCGroup::baseFactory(Tool::Category category) const +{ + if ( category==Tool::Category::Compiler || category==Tool::Category::Assembler ) return BaseData(new BaseNormal, Both); + if ( category==Tool::Category::Linker || category==Tool::Category::Librarian ) return BaseData(new BaseNormal, ProjectOnly); + return BaseData(); +} + +//---------------------------------------------------------------------------- +QString PICC::PICC18Group::informationText() const +{ + return i18n("PICC 18 is a C compiler distributed by HTSoft.").arg("http://www.htsoft.com"); +} + +Tool::Group::BaseData PICC::PICC18Group::baseFactory(Tool::Category category) const +{ + if ( category==Tool::Category::Compiler || category==Tool::Category::Assembler ) return BaseData(new Base18, Both); + if ( category==Tool::Category::Linker || category==Tool::Category::Librarian ) return BaseData(new Base18, ProjectOnly); + return BaseData(); +} diff --git a/src/tools/picc/picc.h b/src/tools/picc/picc.h new file mode 100644 index 0000000..af44d02 --- /dev/null +++ b/src/tools/picc/picc.h @@ -0,0 +1,97 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PICC_H +#define PICC_H + +#include "tools/base/tool_group.h" + +namespace PICC +{ +//---------------------------------------------------------------------------- +class Base : public Tool::Base +{ +private: + virtual QStringList checkExecutableOptions(bool) const { return "--ver"; } + virtual bool checkExecutableResult(bool withWine, QStringList &lines) const; +}; + +class BaseLite : public Base +{ +public: + virtual QString baseExecutable(bool, Tool::OutputExecutableType) const; +}; + +class BaseNormal : public Base +{ +public: + virtual QString baseExecutable(bool, Tool::OutputExecutableType) const; +}; + +class Base18 : public Base +{ +public: + virtual QString baseExecutable(bool, Tool::OutputExecutableType) const; +}; + +//---------------------------------------------------------------------------- +class Group : public Tool::Group +{ +public: + virtual Tool::Category checkDevicesCategory() const { return Tool::Category::Compiler; } + virtual QStringList checkDevicesOptions(uint) const { return "--CHIPINFO"; } + virtual Tool::ExecutableType preferedExecutableType() const { return Tool::ExecutableType::Unix; } + virtual Tool::CompileType compileType() const { return Tool::SeparateFiles; } + virtual PURL::FileType implementationType(PURL::ToolType type) const; + +private: + virtual QValueList getSupportedDevices(const QString &s) const; + virtual Compile::Process *processFactory(const Compile::Data &data) const; + virtual Compile::Config *configFactory(::Project *project) const; + virtual Tool::SourceGenerator *sourceGeneratorFactory() const { /*TODO*/ return 0; } +}; + +//---------------------------------------------------------------------------- +class PICCLiteGroup : public Group +{ +public: + virtual QString name() const { return "picclite"; } + virtual QString label() const { return i18n("PICC Lite Compiler"); } + virtual QString informationText() const; + +private: + virtual BaseData baseFactory(Tool::Category) const; +}; + +//---------------------------------------------------------------------------- +class PICCGroup : public Group +{ +public: + virtual QString name() const { return "picc"; } + virtual QString label() const { return i18n("PICC Compiler"); } + virtual QString informationText() const; + +private: + virtual BaseData baseFactory(Tool::Category) const; +}; + +//---------------------------------------------------------------------------- +class PICC18Group : public Group +{ +public: + virtual QString name() const { return "picc18"; } + virtual QString label() const { return i18n("PICC-18 Compiler"); } + virtual QString informationText() const; + +private: + virtual BaseData baseFactory(Tool::Category) const; +}; + +} // namespace + +#endif diff --git a/src/tools/picc/picc_compile.cpp b/src/tools/picc/picc_compile.cpp new file mode 100644 index 0000000..63fd127 --- /dev/null +++ b/src/tools/picc/picc_compile.cpp @@ -0,0 +1,136 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "picc_compile.h" + +#include "picc_config.h" + +//----------------------------------------------------------------------------- +QStringList PICC::Process::genericArguments(const Compile::Config &) const +{ + QStringList args; + args += "--ERRFORMAT"; + args += "--WARNFORMAT"; + args += "--MSGFORMAT"; + args += "--CHIP=%DEVICE"; + args += "--IDE=mplab"; + args += "-Q"; // suppress copyright message + return args; +} + +void PICC::Process::logStderrLine(const QString &line) +{ + // #### TODO + doLog(Log::LineType::Normal, line, QString::null, 0); +} + +//----------------------------------------------------------------------------- +QStringList PICC::CompileStandaloneFile::genericArguments(const Compile::Config &config) const +{ + QStringList args = Process::genericArguments(config); + args += "-M%MAP"; + args += "-G%SYM"; + args += "--ASMLIST"; + args += config.includeDirs(Tool::Category::Compiler, "-I"); + args += config.customOptions(Tool::Category::Compiler); + args += "%I"; + return args; +} + +QString PICC::CompileStandaloneFile::outputFiles() const +{ + return "PURL::Lst PURL::Map obj PURL::Hex PURL::Coff sym sdb hxl rlf"; +} + +//----------------------------------------------------------------------------- +QStringList PICC::CompileProjectFile::genericArguments(const Compile::Config &config) const +{ + QStringList args = Process::genericArguments(config); + args += "-S"; + args += config.includeDirs(Tool::Category::Compiler, "-I"); + args += config.customOptions(Tool::Category::Compiler); + args += "%I"; + return args; +} + +QString PICC::CompileProjectFile::outputFiles() const +{ + return "PURL::AsmPICC"; +} + +//----------------------------------------------------------------------------- +QStringList PICC::AssembleStandaloneFile::genericArguments(const Compile::Config &config) const +{ + QStringList args = Process::genericArguments(config); + args += "-M%MAP"; + args += "-G%SYM"; + args += "--ASMLIST"; + args += config.includeDirs(Tool::Category::Assembler, "-I"); + args += config.customOptions(Tool::Category::Assembler); + args += "%I"; + return args; +} + +QString PICC::AssembleStandaloneFile::outputFiles() const +{ + return "PURL::Lst PURL::Map obj PURL::Hex sym sdb hxl rlf"; +} + +//----------------------------------------------------------------------------- +QStringList PICC::AssembleProjectFile::genericArguments(const Compile::Config &config) const +{ + QStringList args = Process::genericArguments(config); + args += "-C"; + args += "--ASMLIST"; + args += config.includeDirs(Tool::Category::Assembler, "-I"); + args += config.customOptions(Tool::Category::Assembler); + args += "%I"; + return args; +} + +QString PICC::AssembleProjectFile::outputFiles() const +{ + return "obj PURL::Lst rlf"; +} + +//----------------------------------------------------------------------------- +QStringList PICC::LinkProject::genericArguments(const Compile::Config &config) const +{ + QStringList args = Process::genericArguments(config); + args += "-O%O"; + args += "-M%MAP"; + args += "-G%SYM"; + if ( _data.linkType==Compile::Icd2Linking ) args += "--DEBUGGER=icd2"; + args += config.customOptions(Tool::Category::Linker); + args += "%OBJS"; + args += "%LIBS"; + args += config.customLibraries(Tool::Category::Linker); + return args; +} + +QString PICC::LinkProject::outputFiles() const +{ + return "PURL::Map PURL::Hex PURL::Coff sym sdb hxl"; +} + +//----------------------------------------------------------------------------- +QStringList PICC::LibraryProject::genericArguments(const Compile::Config &config) const +{ + QStringList args; + args += config.customOptions(Tool::Category::Librarian); + args += "r"; + args += "%O"; + args += "%OBJS"; + args += "%LIBS"; + return args; +} + +QString PICC::LibraryProject::outputFiles() const +{ + return "PURL::Library"; +} diff --git a/src/tools/picc/picc_compile.h b/src/tools/picc/picc_compile.h new file mode 100644 index 0000000..6db92ca --- /dev/null +++ b/src/tools/picc/picc_compile.h @@ -0,0 +1,83 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PICC_COMPILE_H +#define PICC_COMPILE_H + +#include "tools/list/compile_process.h" + +namespace PICC +{ +//----------------------------------------------------------------------------- +class Process : public Compile::Process +{ +Q_OBJECT +protected: + virtual QString deviceName() const { return _data.device; } + virtual QStringList genericArguments(const Compile::Config &config) const; + virtual void logStderrLine(const QString &line); + virtual QString objectExtension() const { return "obj"; } +}; + +//----------------------------------------------------------------------------- +class CompileStandaloneFile : public Process +{ +Q_OBJECT +protected: + virtual QString outputFiles() const; + virtual QStringList genericArguments(const Compile::Config &config) const; +}; + +//----------------------------------------------------------------------------- +class CompileProjectFile : public Process +{ +Q_OBJECT +protected: + virtual QString outputFiles() const; + virtual QStringList genericArguments(const Compile::Config &config) const; +}; + +//----------------------------------------------------------------------------- +class AssembleStandaloneFile : public Process +{ +Q_OBJECT +protected: + virtual QString outputFiles() const; + virtual QStringList genericArguments(const Compile::Config &config) const; +}; + +//----------------------------------------------------------------------------- +class AssembleProjectFile : public Process +{ +Q_OBJECT +protected: + virtual QString outputFiles() const; + virtual QStringList genericArguments(const Compile::Config &config) const; +}; + +//----------------------------------------------------------------------------- +class LinkProject : public Process +{ +Q_OBJECT +protected: + virtual QString outputFiles() const; + virtual QStringList genericArguments(const Compile::Config &config) const; +}; + +//----------------------------------------------------------------------------- +class LibraryProject : public Process +{ +Q_OBJECT +protected: + virtual QString outputFiles() const; + virtual QStringList genericArguments(const Compile::Config &config) const; +}; + +} // namespace + +#endif diff --git a/src/tools/picc/picc_config.cpp b/src/tools/picc/picc_config.cpp new file mode 100644 index 0000000..3404bb5 --- /dev/null +++ b/src/tools/picc/picc_config.cpp @@ -0,0 +1,9 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "picc_config.h" diff --git a/src/tools/picc/picc_config.h b/src/tools/picc/picc_config.h new file mode 100644 index 0000000..c78f186 --- /dev/null +++ b/src/tools/picc/picc_config.h @@ -0,0 +1,25 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PICC_CONFIG_H +#define PICC_CONFIG_H + +#include "tools/list/compile_config.h" + +namespace PICC +{ +//---------------------------------------------------------------------------- +class Config : public Compile::Config +{ +public: + Config(Project *project) : Compile::Config(project) {} +}; + +} // namespace + +#endif diff --git a/src/tools/sdcc/Makefile.am b/src/tools/sdcc/Makefile.am new file mode 100644 index 0000000..d5fa9da --- /dev/null +++ b/src/tools/sdcc/Makefile.am @@ -0,0 +1,9 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libsdcc.la +libsdcc_la_LDFLAGS = $(all_libraries) +libsdcc_la_SOURCES = sdcc_compile.cpp sdcc_config.cpp sdcc.cpp \ + sdcc_generator.cpp + +SUBDIRS = gui diff --git a/src/tools/sdcc/gui/Makefile.am b/src/tools/sdcc/gui/Makefile.am new file mode 100644 index 0000000..35ee59a --- /dev/null +++ b/src/tools/sdcc/gui/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libsdccui.la +libsdccui_la_LDFLAGS = $(all_libraries) +libsdccui_la_SOURCES = sdcc_ui.cpp \ No newline at end of file diff --git a/src/tools/sdcc/gui/sdcc_ui.cpp b/src/tools/sdcc/gui/sdcc_ui.cpp new file mode 100644 index 0000000..bc14f78 --- /dev/null +++ b/src/tools/sdcc/gui/sdcc_ui.cpp @@ -0,0 +1,29 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "sdcc_ui.h" + +#include "tools/gputils/gui/gputils_ui.h" + +//---------------------------------------------------------------------------- +SDCC::ConfigWidget::ConfigWidget(Project *project) + : ToolConfigWidget(project) +{} + +void SDCC::ConfigWidget::initEntries() +{ + if ( _category==Tool::Category::Linker ) createHexFormatEntry(); + createIncludeDirectoriesEntry(); +} + +//---------------------------------------------------------------------------- +ToolConfigWidget *SDCC::GroupUI::configWidgetFactory(Tool::Category category, Project *project) const +{ + if ( category==Tool::Category::Librarian ) return new GPUtils::ConfigWidget(project); + return new ConfigWidget(project); +} diff --git a/src/tools/sdcc/gui/sdcc_ui.h b/src/tools/sdcc/gui/sdcc_ui.h new file mode 100644 index 0000000..a0f0ffc --- /dev/null +++ b/src/tools/sdcc/gui/sdcc_ui.h @@ -0,0 +1,35 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef SDCC_UI_H +#define SDCC_UI_H + +#include "tools/gui/tool_config_widget.h" +#include "tools/gui/tool_group_ui.h" + +namespace SDCC +{ +//---------------------------------------------------------------------------- +class ConfigWidget : public ToolConfigWidget +{ +Q_OBJECT +public: + ConfigWidget(Project *project); + virtual void initEntries(); +}; + +//---------------------------------------------------------------------------- +class GroupUI : public Tool::GroupUI +{ +public: + virtual ToolConfigWidget *configWidgetFactory(Tool::Category category, ::Project *project) const; +}; + +} // namespace + +#endif diff --git a/src/tools/sdcc/sdcc.cpp b/src/tools/sdcc/sdcc.cpp new file mode 100644 index 0000000..ba86273 --- /dev/null +++ b/src/tools/sdcc/sdcc.cpp @@ -0,0 +1,115 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "sdcc.h" + +#include "devices/list/device_list.h" +#include "sdcc_compile.h" +#include "sdcc_config.h" +#include "devices/pic/pic/pic_memory.h" +#include "common/global/pfile.h" +#include "common/global/process.h" +#include "sdcc_generator.h" + +//---------------------------------------------------------------------------- +bool SDCC::Base::checkExecutableResult(bool, QStringList &lines) const +{ + return ( lines.count()>0 && lines[0].startsWith("SDCC") ); +} + +//---------------------------------------------------------------------------- +QString SDCC::Group::informationText() const +{ + return i18n("The Small Devices C Compiler is an open-source C compiler for several families of microcontrollers.").arg("http://sdcc.sourceforge.net"); +} + +const ::Tool::Base *SDCC::Group::base(Tool::Category category) const +{ + if ( category==Tool::Category::Assembler || category==Tool::Category::Librarian ) + return Tool::lister().group("gputils")->base(category); + return Tool::Group::base(category); +} + +Tool::Group::BaseData SDCC::Group::baseFactory(Tool::Category category) const +{ + if ( category==Tool::Category::Compiler ) return BaseData(new ::SDCC::Base, Both); + if ( category==Tool::Category::Linker) return BaseData(new ::SDCC::Base, ProjectOnly); + return BaseData(); +} + +SDCC::Group::Group() + : _checkDevicesTmp(_sview, ".c") +{ + // used to obtain device list + if ( _checkDevicesTmp.openForWrite() ) _checkDevicesTmp.appendText("void main(void) {}\n"); + _checkDevicesTmp.close(); +} + +QStringList SDCC::Group::checkDevicesOptions(uint i) const +{ + QStringList options; + options += QString("-m") + SDCC::FAMILY_DATA[i].name; + options += "-phelp"; + options += _checkDevicesTmp.url().filepath(); + return options; +} + +PURL::Directory SDCC::Group::autodetectDirectory(Compile::DirectoryType type, const PURL::Directory &dir, bool withWine) const +{ + return Tool::lister().group("gputils")->autodetectDirectory(type, dir, withWine); +} + +bool SDCC::Group::needs(bool withProject, Tool::Category category) const +{ + if ( category==Tool::Category::Assembler || category==Tool::Category::Librarian ) return Tool::lister().group("gputils")->needs(withProject, category); + return Tool::Group::needs(withProject, category); +} + +Compile::Process *SDCC::Group::processFactory(const Compile::Data &data) const +{ + switch (data.category.type()) { + case Tool::Category::Assembler: + case Tool::Category::Librarian: + return Tool::lister().group("gputils")->processFactory(data); + case Tool::Category::Compiler: + if (data.project) return new SDCC::CompileProjectFile; + return new SDCC::CompileStandaloneFile; + case Tool::Category::Linker: + return new SDCC::LinkProjectFile; + default: break; + } + return 0; +} + +Compile::Config *SDCC::Group::configFactory(::Project *project) const +{ + return new Config(project); +} + +PURL::FileType SDCC::Group::implementationType(PURL::ToolType type) const +{ + if ( type==PURL::ToolType::Assembler ) return PURL::AsmGPAsm; + if ( type==PURL::ToolType::Compiler ) return PURL::CSource; + return PURL::Nb_FileTypes; +} + +Tool::SourceGenerator *SDCC::Group::sourceGeneratorFactory() const +{ + return new SourceGenerator; +} + +bool SDCC::Group::generateDebugInformation(const QString &device) const +{ + switch (family(device)) { + case P14: return false; + case P16: return true; + case Nb_Families: break; + } + Q_ASSERT(false); + return false; +} diff --git a/src/tools/sdcc/sdcc.h b/src/tools/sdcc/sdcc.h new file mode 100644 index 0000000..3155273 --- /dev/null +++ b/src/tools/sdcc/sdcc.h @@ -0,0 +1,63 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef SDCC_H +#define SDCC_H + +#include "tools/list/tool_list.h" +#include "common/gui/pfile_ext.h" +#include "sdcc_generator.h" + +namespace SDCC +{ +//---------------------------------------------------------------------------- +class Base : public Tool::Base +{ +public: + virtual QString baseExecutable(bool, Tool::OutputExecutableType) const { return "sdcc"; } + +private: + virtual QStringList checkExecutableOptions(bool) const { return "-v"; } + virtual bool checkExecutableResult(bool withWine, QStringList &lines) const; +}; + +//---------------------------------------------------------------------------- +class Group : public Tool::Group +{ +public: + Group(); + virtual QString name() const { return "sdcc"; } + virtual QString label() const { return i18n("Small Device C Compiler"); } + virtual QString informationText() const; + virtual const ::Tool::Base *base(Tool::Category category) const; + virtual uint nbCheckDevices() const { return SDCC::Nb_Families; } + virtual bool hasDirectory(Compile::DirectoryType type) const { return type==Compile::DirectoryType::Header || type==Compile::DirectoryType::LinkerScript; } + virtual PURL::FileType linkerScriptType() const { return PURL::Lkr; } + virtual PURL::Url linkerScript(const ::Project *project, Compile::LinkType type) const { return Tool::lister().group("gputils")->linkerScript(project, type); } + virtual PURL::Directory autodetectDirectory(Compile::DirectoryType type, const PURL::Directory &execDir, bool withWine) const; + virtual Tool::ExecutableType preferedExecutableType() const { return Tool::ExecutableType::Unix; } + virtual Tool::CompileType compileType() const { return Tool::SeparateFiles; } + virtual Tool::Category checkDevicesCategory() const { return Tool::Category::Compiler; } + virtual QStringList checkDevicesOptions(uint i) const; + virtual bool needs(bool withProject, Tool::Category category) const; + virtual PURL::FileType implementationType(PURL::ToolType type) const; + virtual bool generateDebugInformation(const QString &device) const; + +private: + Log::StringView _sview; + PURL::TempFile _checkDevicesTmp; + virtual BaseData baseFactory(Tool::Category category) const; + virtual QValueList getSupportedDevices(const QString &s) const { return SDCC::getSupportedDevices(s); } + virtual Compile::Process *processFactory(const Compile::Data &data) const; + virtual Compile::Config *configFactory(::Project *project) const; + virtual Tool::SourceGenerator *sourceGeneratorFactory() const; +}; + +} // namespace + +#endif diff --git a/src/tools/sdcc/sdcc_compile.cpp b/src/tools/sdcc/sdcc_compile.cpp new file mode 100644 index 0000000..a3c072f --- /dev/null +++ b/src/tools/sdcc/sdcc_compile.cpp @@ -0,0 +1,103 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "sdcc_compile.h" + +#include "sdcc.h" +#include "sdcc_config.h" +#include "tools/list/tool_list.h" +#include "sdcc_generator.h" + +//----------------------------------------------------------------------------- +QString SDCC::Process::familyName() const +{ + return FAMILY_DATA[family(_data.device)].name; +} + +QString SDCC::Process::deviceName() const +{ + return toDeviceName(_data.device); +} + +QStringList SDCC::Process::genericArguments(const Compile::Config &) const +{ + QStringList args; + args += "-m%FAMILY"; + args += "-%DEVICE"; + args += "-V"; // verbose + args += "--debug"; + return args; +} + +QString SDCC::Process::outputFiles() const +{ + return "PURL::Object PURL::AsmGPAsm adb p d PURL::Lst"; +} + +void SDCC::Process::logStderrLine(const QString &line) +{ + if ( parseErrorLine(line, Compile::ParseErrorData("([^:]*):([0-9]+):(error|warning|message):(.+)", 1, 2, 4, 3)) ) return; + if ( parseErrorLine(line, Compile::ParseErrorData("([^:]*):([0-9]+):(\\w+)\\s*\\[[0-9]+\\](.+)", 1, 2, 4, 3)) ) return; + if ( parseErrorLine(line, Compile::ParseErrorData("([^:]*)\\s*[0-9]+:(.+)", -1, -1, 2, 1, Log::LineType::Warning)) ) return; + if ( parseErrorLine(line, Compile::ParseErrorData("([^:]*):([0-9]+):(.+)", 1, 2, 3, Log::LineType::Warning)) ) return; + if ( parseErrorLine(line, Compile::ParseErrorData("([^:]*):([^:]+):([0-9]+):(.+)", 2, 3, 4, Log::LineType::Warning)) ) return; + if ( parseErrorLine(line, Compile::ParseErrorData("([^:]+):(.+)", -1, -1, 2, 1, Log::LineType::Warning)) ) return; + doLog(filterType(line), line, QString::null, 0); +} + +//----------------------------------------------------------------------------- +QStringList SDCC::CompileStandaloneFile::genericArguments(const Compile::Config &config) const +{ + QStringList args = Process::genericArguments(config); + args += config.includeDirs(Tool::Category::Compiler, "-I"); + args += config.customOptions(Tool::Category::Compiler); + args += "-Wl-o%O"; + args += "-Wl-m"; // output map file + HexBuffer::Format format = config.hexFormat(); + if( format!=HexBuffer::Nb_Formats ) + args += QString("-Wl-a") + HexBuffer::FORMATS[format]; + args += "%I"; + return args; +} + +QString SDCC::CompileStandaloneFile::outputFiles() const +{ + return Process::outputFiles() + " PURL::Map PURL::Hex PURL::Cod rst sym mem lnk"; +} + +//----------------------------------------------------------------------------- +QStringList SDCC::CompileProjectFile::genericArguments(const Compile::Config &config) const +{ + QStringList args = Process::genericArguments(config); + args += config.includeDirs(Tool::Category::Compiler, "-I"); + args += config.customOptions(Tool::Category::Compiler); + args += "-c"; // compile only + args += "%I"; + return args; +} + +//----------------------------------------------------------------------------- +QStringList SDCC::LinkProjectFile::genericArguments(const Compile::Config &config) const +{ + QStringList args = Process::genericArguments(config); + args += "-Wl-c"; // create coff file + args += "-Wl-m"; // output map file + args += "$LKR(-Wl-s%LKR)"; + args += config.includeDirs(Tool::Category::Linker, "-I"); + args += config.customOptions(Tool::Category::Linker); + args += "-o%O"; + args += "%OBJS"; + args += "%LIBS"; + args += config.customLibraries(Tool::Category::Linker); + return args; +} + +QString SDCC::LinkProjectFile::outputFiles() const +{ + return Process::outputFiles() + " PURL::Lkr PURL::Hex PURL::Cod PURL::Coff PURL::Map"; +} diff --git a/src/tools/sdcc/sdcc_compile.h b/src/tools/sdcc/sdcc_compile.h new file mode 100644 index 0000000..8ba4c30 --- /dev/null +++ b/src/tools/sdcc/sdcc_compile.h @@ -0,0 +1,58 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef SDCC_COMPILE_H +#define SDCC_COMPILE_H + +#include "tools/list/compile_process.h" + +namespace SDCC +{ +//----------------------------------------------------------------------------- +class Process : public Compile::Process +{ +Q_OBJECT +protected: + virtual QString deviceName() const; + virtual QString familyName() const; + virtual QStringList genericArguments(const Compile::Config &config) const; + virtual QString outputFiles() const; + virtual void logStderrLine(const QString &line); + virtual bool hasLinkerScript() const { return ( _data.linkType==Compile::Icd2Linking || Main::toolGroup().hasCustomLinkerScript(_data.project) ); } +}; + +//----------------------------------------------------------------------------- +class CompileStandaloneFile : public Process +{ +Q_OBJECT +private: + virtual QStringList genericArguments(const Compile::Config &config) const; + virtual QString outputFiles() const; +}; + +//----------------------------------------------------------------------------- +class CompileProjectFile : public Process +{ +Q_OBJECT +private: + virtual QStringList genericArguments(const Compile::Config &config) const; +}; + +//----------------------------------------------------------------------------- +class LinkProjectFile : public Process +{ +Q_OBJECT +private: + virtual QStringList genericArguments(const Compile::Config &config) const; + virtual QString outputFiles() const; + virtual QString objectExtension() const { return "o"; } +}; + +} // namespace + +#endif diff --git a/src/tools/sdcc/sdcc_config.cpp b/src/tools/sdcc/sdcc_config.cpp new file mode 100644 index 0000000..5b44673 --- /dev/null +++ b/src/tools/sdcc/sdcc_config.cpp @@ -0,0 +1,9 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "sdcc_config.h" diff --git a/src/tools/sdcc/sdcc_config.h b/src/tools/sdcc/sdcc_config.h new file mode 100644 index 0000000..c4bafdd --- /dev/null +++ b/src/tools/sdcc/sdcc_config.h @@ -0,0 +1,25 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef SDCC_CONFIG_H +#define SDCC_CONFIG_H + +#include "tools/gputils/gputils_config.h" + +namespace SDCC +{ +//---------------------------------------------------------------------------- +class Config : public GPUtils::Config +{ +public: + Config(Project *project) : GPUtils::Config(project) {} +}; + +} // namespace + +#endif diff --git a/src/tools/sdcc/sdcc_generator.cpp b/src/tools/sdcc/sdcc_generator.cpp new file mode 100644 index 0000000..fb57ab6 --- /dev/null +++ b/src/tools/sdcc/sdcc_generator.cpp @@ -0,0 +1,117 @@ +/*************************************************************************** + * Copyright (C) 2006-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "sdcc_generator.h" + +#include "devices/pic/pic/pic_memory.h" +#include "devices/list/device_list.h" +#include "tools/gputils/gputils.h" + +//---------------------------------------------------------------------------- +const SDCC::FamilyData SDCC::FAMILY_DATA[Nb_Families] = { + { "pic14" }, + { "pic16" } +}; + +SDCC::Family SDCC::family(const QString &device) +{ + const Device::Data *data = Device::lister().data(device); + switch (static_cast(data)->architecture().type()) { + case Pic::Architecture::P10X: + case Pic::Architecture::P16X: return P14; + case Pic::Architecture::P17C: + case Pic::Architecture::P18C: + case Pic::Architecture::P18F: + case Pic::Architecture::P18J: return P16; + case Pic::Architecture::P24F: + case Pic::Architecture::P24H: + case Pic::Architecture::P30F: + case Pic::Architecture::P33F: + case Pic::Architecture::Nb_Types: break; + } + Q_ASSERT(false); + return Nb_Families; +} + +QString SDCC::toDeviceName(const QString &device) +{ + return GPUtils::toDeviceName(device); +} + +QValueList SDCC::getSupportedDevices(const QString &s) +{ + return GPUtils::getSupportedDevices(s); +} + +SourceLine::List SDCC::SourceGenerator::configLines(PURL::ToolType type, const Device::Memory &memory, bool &ok) const +{ + if ( type==PURL::ToolType::Assembler ) { + GPUtils::SourceGenerator generator; + return generator.configLines(type, memory, ok); + } + const Pic::Memory &pmemory = static_cast(memory); + const Pic::Data &data = pmemory.device(); + const Pic::Config &config = data.config(); + SourceLine::List lines; + if ( !data.is18Family() ) lines.appendNotIndentedCode("typedef unsigned int word;"); + Address address = data.range(Pic::MemoryRangeType::Config).start; + QString prefix = (data.nbWords(Pic::MemoryRangeType::Config)==2 || data.name().startsWith("16F9") ? "_" : "__"); + for (uint i=0; i"); + return lines; +} + +SourceLine::List SDCC::SourceGenerator::sourceFileContent(PURL::ToolType type, const Device::Data &data, bool &ok) const +{ + if ( type==PURL::ToolType::Assembler ) { + GPUtils::SourceGenerator generator; + return generator.sourceFileContent(type, data, ok); + } + SourceLine::List lines; + switch (static_cast(data).architecture().type()) { + case Pic::Architecture::P16X: + lines.appendNotIndentedCode("void isr() interrupt 0 {", i18n("interrupt service routine")); + lines.appendIndentedCode(QString::null, "<< " + i18n("insert interrupt code") + " >>"); + lines.appendNotIndentedCode("}"); + lines.appendEmpty(); + break; + case Pic::Architecture::P18C: + case Pic::Architecture::P18F: + case Pic::Architecture::P18J: + // #### TODO: template interrupt code + break; + default: Q_ASSERT(false); break; + } + lines.appendNotIndentedCode("void main() {"); + lines.appendIndentedCode(QString::null, "<< " + i18n("insert code") + " >>"); + lines.appendNotIndentedCode("}"); + return lines; +} diff --git a/src/tools/sdcc/sdcc_generator.h b/src/tools/sdcc/sdcc_generator.h new file mode 100644 index 0000000..e5f0101 --- /dev/null +++ b/src/tools/sdcc/sdcc_generator.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * Copyright (C) 2006-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef SDCC_GENERATOR_H +#define SDCC_GENERATOR_H + +#include "coff/base/disassembler.h" + +namespace SDCC +{ +//---------------------------------------------------------------------------- +enum Family { P14 = 0, P16, Nb_Families }; +struct FamilyData { + const char *name; +}; +extern const FamilyData FAMILY_DATA[Nb_Families]; +extern Family family(const QString &device); +extern QString toDeviceName(const QString &device); +extern QValueList getSupportedDevices(const QString &s); + +//---------------------------------------------------------------------------- +class SourceGenerator : public Tool::SourceGenerator +{ +public: + virtual SourceLine::List configLines(PURL::ToolType type, const Device::Memory &memory, bool &ok) const; + virtual SourceLine::List sourceFileContent(PURL::ToolType type, const Device::Data &data, bool &ok) const; + virtual SourceLine::List includeLines(PURL::ToolType type, const Device::Data &data) const; + +private: + struct P16CNameData { + const char *cname, *sdccName; + }; + static const P16CNameData P16_CNAME_DATA[]; + static void transformCName(QString &cname, const Pic::Data &data); + +}; + +} // namespace + +#endif diff --git a/src/xml_to_data/Makefile.am b/src/xml_to_data/Makefile.am new file mode 100644 index 0000000..66985ca --- /dev/null +++ b/src/xml_to_data/Makefile.am @@ -0,0 +1,7 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO + +libxmltodata_la_LDFLAGS = $(all_libraries) +noinst_LTLIBRARIES = libxmltodata.la +libxmltodata_la_SOURCES = xml_to_data.cpp xml_to_data.cpp device_xml_to_data.cpp +libxmltodata_la_LIBADD = $(LIB_QT) diff --git a/src/xml_to_data/device_xml_to_data.cpp b/src/xml_to_data/device_xml_to_data.cpp new file mode 100644 index 0000000..9ad1940 --- /dev/null +++ b/src/xml_to_data/device_xml_to_data.cpp @@ -0,0 +1,260 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "device_xml_to_data.h" + +#include +#include +#include +#include + +bool Device::XmlToDataBase::getFrequencyRange(OperatingCondition oc, Special special, QDomElement element) +{ + QDomElement range; + for (QDomNode child=element.firstChild(); !child.isNull(); child=child.nextSibling()) { + if ( child.nodeName()!="frequency_range" ) continue; + if ( !child.isElement() ) qFatal("\"frequency_range\" should be an element"); + if ( child.toElement().attribute("name")!=oc.key() ) continue; + Special s = Special::fromKey(child.toElement().attribute("special")); + if ( s==Special::Nb_Types ) qFatal("Unrecognized special"); + if ( special!=s ) continue; + if ( !range.isNull() ) qFatal("Duplicated \"frequency_range\""); + range = child.toElement(); + } + if ( range.isNull() ) return false; + FrequencyRange frange; + frange.operatingCondition = oc; + frange.special = special; + for (QDomNode child=range.firstChild(); !child.isNull(); child=child.nextSibling()) { + if ( child.nodeName()=="frequency" ) { + if ( !child.isElement() ) qFatal("Frequency is not an element"); + QDomElement frequency = child.toElement(); + bool ok1, ok2, ok3, ok4; + RangeBox box; + box.start.x = frequency.attribute("start").toDouble(&ok1); + box.end.x = frequency.attribute("end").toDouble(&ok2); + box.start.yMin = frequency.attribute("vdd_min").toDouble(&ok3); + box.start.yMax = frequency.attribute("vdd_max").toDouble(&ok4); + box.end.yMax = box.start.yMax; + if ( !ok1 || !ok2 || !ok3 || !ok4 + || box.start.x<0.0 || box.start.x>box.end.x + || box.start.yMin<0.0 || box.start.yMin>box.start.yMax ) + qFatal("Malformed frequency element"); + if ( frequency.attribute("vdd_min_end").isEmpty() ) box.end.yMin = box.start.yMin; + else { + box.end.yMin = frequency.attribute("vdd_min_end").toDouble(&ok1); + if ( !ok1 || box.end.yMin>box.end.yMax ) qFatal("Malformed frequency element"); + } + box.mode = frequency.attribute("mode"); + box.osc = frequency.attribute("osc"); + box.special = frequency.attribute("special"); + for (uint i=0; ifrange.vdds[i].start.x ) { + if ( box.mode.isEmpty() && box.osc.isEmpty() && box.special.isEmpty() ) + qFatal("Overlapping frequency ranges"); + continue; // #### FIXME: ignore additionnal mode + } +// qDebug("add Freq Range: %s %s %f=[%f %f] %f=[%f %f]", +// Device::FrequencyRange::TYPE_LABELS[type], Device::FrequencyRange::SPECIAL_LABELS[type], +// box.start.x, box.start.yMin, box.start.yMax, +// box.end.x, box.end.yMin, box.end.yMax); + frange.vdds.append(box); + } + } + if ( frange.vdds.count()==0 ) qFatal("Empty frequency range"); + _data->_frequencyRanges.append(frange); + return true; +} + +bool Device::XmlToDataBase::getMemoryTechnology(QDomElement element) +{ + QString s = element.attribute("memory_technology"); + _data->_memoryTechnology = MemoryTechnology::fromKey(s); + if ( _data->_memoryTechnology!=MemoryTechnology::Nb_Types ) return true; + if ( !s.isNull() ) qFatal("Unrecognized memory technology"); + return false; +} + +void Device::XmlToDataBase::processDevice(QDomElement device) +{ + QString name = device.attribute("name").upper(); + if ( name.isEmpty() ) qFatal("Device has no name"); + if ( _map.contains(name) ) qFatal(QString("Device \"%1\" already defined").arg(name)); + _data = createData(); + _map[name] = _data; + _data->_name = name; + _data->_alternatives = QStringList::split(' ', device.attribute("alternative")); + if ( _data->_alternatives.count() ) _alternatives[name] = _data->_alternatives; + _data->_status = Status::fromKey(device.attribute("status")); + switch (_data->_status.type()) { + case Status::Nb_Types: + qFatal("Unrecognized or absent device status"); + break; + case Status::Future: + if ( _data->_alternatives.count() ) qFatal("Future device has alternative"); + break; + case Status::NotRecommended: + case Status::Mature: + if ( _data->_alternatives.count()==0 ) warning("Not-recommended/mature device has no alternative"); + break; + case Status::InProduction: + case Status::EOL: + case Status::Unknown: break; + } + + // document + _data->_documents.webpage = device.attribute("document"); // ### REMOVE ME + QDomElement documents = findUniqueElement(device, "documents", QString::null, QString::null); + if ( documents.isNull() ) { + if ( _data->_documents.webpage.isEmpty() ) qFatal("Missing \"documents\" element"); + } else { + if ( !_data->_documents.webpage.isEmpty() ) qFatal("document should be removed from root element"); + _data->_documents.webpage = documents.attribute("webpage"); + if ( _data->_documents.webpage.isEmpty() ) qFatal("Missing webpage"); + _data->_documents.datasheet = documents.attribute("datasheet"); + QRegExp rexp("\\d{5}"); + if ( _data->_documents.datasheet=="?" ) warning("No datasheet specified"); + if ( !rexp.exactMatch(_data->_documents.datasheet) ) qFatal(QString("Malformed datasheet \"%1\" (5 digits)").arg(_data->_documents.datasheet)); + _data->_documents.progsheet = documents.attribute("progsheet"); + if ( _data->_documents.progsheet=="?" ) warning("No progsheet specified"); + if ( !rexp.exactMatch(_data->_documents.datasheet) ) qFatal(QString("Malformed progsheet \"%1\" (5 digits)").arg(_data->_documents.progsheet)); + _data->_documents.erratas = QStringList::split(" ", documents.attribute("erratas")); + for (uint i=0; i_documents.erratas.count()); i++) { + QString errata = _data->_documents.erratas[i]; + if ( !rexp.exactMatch(errata) ) { + QRegExp rexp2("\\d{5}e\\d"); + if ( !rexp2.exactMatch(errata) && !errata.startsWith("er") && errata.mid(2)!=_data->_name.lower() ) + qFatal(QString("Malformed erratas \"%1\" (5 digits or 5 digits + e + 1 digit or \"er\" + name)").arg(errata)); + } + } + } + if ( _data->_documents.webpage=="?" ) warning("No webpage specified"); + else { + QRegExp rexp("\\d{6}"); + if ( !rexp.exactMatch(_data->_documents.webpage) ) qFatal(QString("Malformed webpage \"%1\" (6 digits)").arg(_data->_documents.webpage)); + if ( _documents.contains(_data->_documents.webpage) ) + qFatal(QString("webpage duplicated (already used for %1)").arg(_documents[_data->_documents.webpage])); + _documents[_data->_documents.webpage] = name; + } + + // frequency ranges + QStringList names; + bool ok = false; + FOR_EACH(OperatingCondition, oc) { + names += oc.key(); + FOR_EACH(Special, special) + if ( getFrequencyRange(oc, special, device) && special==Special::Normal ) ok = true; + } + if ( !ok ) qWarning("No normal frequency range defined"); + checkTagNames(device, "frequency_range", names); + + // memory technology + if ( !getMemoryTechnology(device) ) qFatal("Memory technology not defined"); + + // packages + for (QDomNode child=device.firstChild(); !child.isNull(); child=child.nextSibling()) { + if ( !child.isElement() || child.nodeName()!="package" ) continue; + Package p = processPackage(child.toElement()); + QMap pinLabels; + for (uint i=0; i_packages.count()); k++) + for (uint l=0; l_packages[k].types.count()); j++) + if ( _data->_packages[k].types[j]==p.types[l] && _data->_packages[k].pins.count()==p.pins.count() ) qFatal("Duplicated package type"); + if ( !pinLabels.isEmpty() ) checkPins(pinLabels); + _data->_packages.append(p); + } +} + +Device::Package Device::XmlToDataBase::processPackage(QDomElement element) +{ + Package package; + // nb pins + bool ok; + uint nb = element.attribute("nb_pins").toUInt(&ok); + if ( !ok || nb==0 ) qFatal("Malformed \"nb_pins\""); + package.pins.resize(nb); + // types + QStringList types = QStringList::split(" ", element.attribute("types")); + if ( types.isEmpty() ) qFatal("No package types specified"); + for (uint k=0; k found(nb); + found.fill(false); + QDomNode child = element.firstChild(); + while ( !child.isNull() ) { + if ( child.nodeName()=="pin" ) { + if ( !child.isElement() ) qFatal("\"pin\" is not an element"); + QDomElement pin = child.toElement(); + bool ok; + uint i = pin.attribute("index").toUInt(&ok); + if ( !ok || i==0 || i>nb ) qFatal("Malformed pin index"); + if (found[i-1]) qFatal("Duplicated pin index"); + found[i-1] = true; + QString name = pin.attribute("name"); + if ( !name.isEmpty() && name!="N/C" ) { + QStringList labels = QStringList::split("/", name); + if ( name.contains(" ") || labels.count()==0 ) qFatal("Malformed pin name"); + if ( name!=name.upper() ) qFatal("Pin name should be uppercase"); + } + package.pins[i-1] = name; + have_pins = true; + } + child = child.nextSibling(); + } + if ( !have_pins ) ;//warning("Pins not specified"); // #### REMOVE ME !! + else for (uint i=0; i::const_iterator ait = _alternatives.begin(); + for (; ait!=_alternatives.end(); ++ait) { + QStringList::const_iterator lit = ait.data().begin(); + for (; lit!=ait.data().end(); ++lit) + if ( !_map.contains(*lit) ) qFatal(QString("Unknown alternative %1 for device %2").arg((*lit)).arg(ait.key())); + } +} diff --git a/src/xml_to_data/device_xml_to_data.h b/src/xml_to_data/device_xml_to_data.h new file mode 100644 index 0000000..a1d0529 --- /dev/null +++ b/src/xml_to_data/device_xml_to_data.h @@ -0,0 +1,88 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef DEVICE_XML_TO_DATA_H +#define DEVICE_XML_TO_DATA_H + +#include +#include +#include + +#include "common/common/misc.h" +#include "common/common/streamer.h" +#include "devices/base/generic_device.h" +#include "xml_to_data.h" + +namespace Device +{ +class XmlToDataBase : public ::XmlToData +{ +public: + XmlToDataBase() : _data(0) {} + +protected: + mutable Data *_data; + QMap _map; // device -> data + + virtual void parse(); + virtual QString currentDevice() const { return (_data ? _data->name() : QString::null); } + virtual QString namespaceName() const = 0; + virtual Data *createData() const = 0; + virtual void processDevice(QDomElement device); + virtual void checkPins(const QMap &pinLabels) const = 0; + +private: + QMap _documents; // document -> device + QMap _alternatives; // device -> alternatives + + bool getFrequencyRange(OperatingCondition oc, Special special, QDomElement element); + bool getMemoryTechnology(QDomElement element); + Device::Package processPackage(QDomElement element); +}; + +template +class XmlToData : public XmlToDataBase, public DataStreamer +{ +public: + virtual Device::Data *createData() const { return new DataType; } + DataType *data() { return static_cast(_data); } + const DataType *data() const { return static_cast(_data); } + virtual void output() { + QFile dfile("deps.mak"); + if ( !dfile.open(IO_WriteOnly) ) return; + QTextStream dts(&dfile); + dts << "noinst_DATA = "; + uint i = 0; + QMap::const_iterator it; + for (it=_map.begin(); it!=_map.end(); ++it) { + if ( (i%10)==0 ) dts << "\\" << endl << " "; + dts << " " << it.key() << ".xml"; + i++; + } + dts << endl; + dfile.close(); + + QFile file(namespaceName().lower() + "_data.cpp"); + if ( !file.open(IO_WriteOnly) ) return; + QTextStream ts(&file); + ts << "#include \"devices/" << namespaceName().lower() << "/" + << namespaceName().lower() << "/" << namespaceName().lower() << "_group.h\"" << endl << endl; + ts << "const char *" << namespaceName() << "::DATA_STREAM =" << endl; + QValueList list; + for (it=_map.begin(); it!=_map.end(); ++it) + list.append(static_cast(it.data())); + uint size = toCppString(list, ts); + ts << ";" << endl; + ts << "const uint " << namespaceName() << "::DATA_SIZE = " << size << ";" << endl; + file.close(); + } +}; + +} // namespace + +#endif diff --git a/src/xml_to_data/prog_xml_to_data.h b/src/xml_to_data/prog_xml_to_data.h new file mode 100644 index 0000000..f4e820b --- /dev/null +++ b/src/xml_to_data/prog_xml_to_data.h @@ -0,0 +1,218 @@ +/*************************************************************************** + * Copyright (C) 2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#ifndef PROG_XML_TO_DATA_H +#define PROG_XML_TO_DATA_H + +#include +#include +#include + +#include "xml_to_data.h" +#include "devices/list/device_list.h" + +//---------------------------------------------------------------------------- +template +class ExtXmlToData : public ::XmlToData +{ +public: + ExtXmlToData(const QString &basename, const QString &namespac) + : _basename(basename), _namespace(namespac) {} + +protected: + QString _basename, _namespace; + virtual bool hasFamilies() const { return true; } + const QStringList &families() const { return _families; } + virtual uint familyIndex(const QString &family) const { return _families.findIndex(family); } + virtual void parseData(QDomElement, Data &) = 0; + virtual void includes(QTextStream &) const {} + virtual void outputData(const Data &, QTextStream &) const {} + virtual void outputFunctions(QTextStream &) const {} + virtual QString currentDevice() const { return _current; } + virtual void parseDevice(QDomElement element); + ::Group::Support extractSupport(const QString &s) const; + bool hasDevice(const QString &device) const { return _map.contains(device); } + virtual void parse(); + +protected: + QString _current; + class PData { + public: + uint family; + ::Group::Support support; + Data data; + }; + QMap _map; + QStringList _families; + + virtual void output(); +}; + +template +Group::Support ExtXmlToData::extractSupport(const QString &s) const +{ + if ( s.isEmpty() ) return Group::Support::Untested; + Group::Support support = Group::Support::fromKey(s); + if ( support==Group::Support::None ) qFatal("Cannot be \"not supported\""); + if ( support==Group::Support::Nb_Types ) qFatal("Unknown support type"); + return support; +} + +template +void ExtXmlToData::parseDevice(QDomElement element) +{ + if ( element.nodeName()!="device" ) qFatal("Root node child should be named \"device\""); + _current = element.attribute("name").upper(); + if ( Device::lister().data(_current)==0 ) qFatal(QString("Device name \"%1\" unknown").arg(_current)); + if ( _map.contains(_current) ) qFatal(QString("Device \"%1\" already parsed").arg(_current)); + PData data; + if ( hasFamilies() ) { + QString family = element.attribute("family"); + if ( family.isEmpty() ) qFatal(QString("Family is empty").arg(family)); + if ( _families.find(family)==_families.end() ) _families.append(family); + data.family = familyIndex(family); + } + data.support = extractSupport(element.attribute("support_type")); + parseData(element, data.data); + _map[_current] = data; +} + +template +void ExtXmlToData::parse() +{ + QDomDocument doc = parseFile(_basename + ".xml"); + QDomElement root = doc.documentElement(); + if ( root.nodeName()!="type" ) qFatal("Root node should be \"type\""); + if ( root.attribute("name")!=_basename ) qFatal(QString("Root node name is not \"%1\"").arg(_basename)); + QDomNode child = root.firstChild(); + while ( !child.isNull() ) { + if ( child.isComment() ) qDebug("comment: %s", child.toComment().data().latin1()); + else { + if ( !child.isElement() ) qFatal("Root node child should be an element"); + parseDevice(child.toElement()); + } + child = child.nextSibling(); + } +} + +template +void ExtXmlToData::output() +{ + // write .cpp file + QFile file(_basename + "_data.cpp"); + if ( !file.open(IO_WriteOnly) ) qFatal(QString("Cannot open output file \"%1\"").arg(file.name())); + QTextStream s(&file); + s << "// #### Do not edit: this file is autogenerated !!!" << endl << endl; + s << "#include \"devices/list/device_list.h\"" << endl; + s << "#include \"" + _basename + ".h\"" << endl; + s << "#include \"" + _basename + "_data.h\"" << endl; + includes(s); + s << endl; + s << "namespace " << _namespace << endl; + s << "{" << endl; + s << "struct CData {" << endl; + s << " const char *name;" << endl; + if ( hasFamilies() ) s << " uint family;" << endl; + s << " uint support;" << endl; + s << " Data data;" << endl; + s << "};" << endl; + s << endl; + + // data list + typename QMap::const_iterator it = _map.begin(); + for (; it!=_map.end(); ++it) { + s << "const CData PIC" << it.key() << "_DATA = {"; + s << " \"" << it.key() << "\", "; + if ( hasFamilies() ) s << it.data().family << ", "; + s << it.data().support.type() << ", "; + s << "{ "; + outputData(it.data().data, s); + s << " }"; + s << " };" << endl; + } + s << endl; + s << "const CData *DATA_LIST[] = {" << endl; + uint i = 0; + it = _map.begin(); + for (; it!=_map.end(); ++it) { + s << "&PIC" << it.key() << "_DATA,"; + i++; + if ( (i%10)==0 ) s << endl; + } + s << "0 " << endl; + s << "};" << endl; + + // functions + s << endl; + s << "const CData *cdata(const QString &device)" << endl; + s << "{" << endl; + s << " for(uint i=0; DATA_LIST[i]; i++)" << endl; + s << " if ( device==DATA_LIST[i]->name ) return DATA_LIST[i];" << endl; + s << " return 0;" << endl; + s << "}" << endl; + s << "bool isSupported(const QString &device)" << endl; + s << "{" << endl; + s << " return cdata(device);" << endl; + s << "}" << endl; + if ( hasFamilies() ) { + s << "uint family(const QString &device)" << endl; + s << "{" << endl; + s << " return cdata(device)->family;" << endl; + s << "}" << endl; + } + s << "::Group::Support support(const QString &device)" << endl; + s << "{" << endl; + s << " return ::Group::Support::Type(cdata(device)->support);" << endl; + s << "}" << endl; + s << "const Data &data(const QString &device)" << endl; + s << "{" << endl; + s << " return cdata(device)->data;" << endl; + s << "}" << endl; + s << endl; + outputFunctions(s); + s << endl; + s << "}" << endl; +} + +//---------------------------------------------------------------------------- +namespace Programmer +{ +template +class XmlToData : public ExtXmlToData +{ +public: + XmlToData(const QString &basename, const QString &namespac) + : ExtXmlToData(basename, namespac) {} + +protected: + virtual void outputFunctions(QTextStream &s) const; + virtual void includes(QTextStream &) const; +}; + +template +void Programmer::XmlToData::outputFunctions(QTextStream &s) const +{ + s << "void Group::initSupported()" << endl; + s << "{" << endl; + s << " for (uint i=0; DATA_LIST[i]; i++) {" << endl; + s << " const Device::Data *data = Device::lister().data(DATA_LIST[i]->name);" << endl; + s << " addDevice(data->name(), data, ::Group::Support::Type(DATA_LIST[i]->support));" << endl; + s << " }" << endl; + s << "}" << endl; + s << endl; +} + +template +void Programmer::XmlToData::includes(QTextStream &s) const +{ + s << "#include \"" << ExtXmlToData::_basename << "_prog.h\"" << endl; +} + +} // namespace + +#endif diff --git a/src/xml_to_data/xml_to_data.cpp b/src/xml_to_data/xml_to_data.cpp new file mode 100644 index 0000000..d31ded0 --- /dev/null +++ b/src/xml_to_data/xml_to_data.cpp @@ -0,0 +1,71 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 Nicolas Hadacek * + * * + * 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. * + ***************************************************************************/ +#include "xml_to_data.h" + +#include +#include + +QDomElement XmlToData::findUniqueElement(QDomElement parent, const QString &tag, + const QString &attribute, const QString &value) const +{ + QDomElement element; + QDomNode child = parent.firstChild(); + while ( !child.isNull() ) { + if ( child.nodeName()==tag && child.isElement() + && (attribute.isEmpty() || child.toElement().attribute(attribute)==value) ) { + if ( !element.isNull() ) qFatal(QString("Duplicated element \"%1/%2\"").arg(tag).arg(value)); + element = child.toElement(); + } + child = child.nextSibling(); + } + return element; +} + +void XmlToData::checkTagNames(QDomElement element, const QString &tag, + const QStringList &names) const +{ + QDomNodeList list = element.elementsByTagName(tag); + for (uint i=0; i * + * * + * 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. * + ***************************************************************************/ +#ifndef XML_TO_DATA_H +#define XML_TO_DATA_H + +#include "common/global/global.h" +#if QT_VERSION<0x040000 +# include +#else +# include +#endif +#include + +class XmlToData +{ +public: + XmlToData() {} + virtual ~XmlToData() {} + void process(); + +protected: + virtual void parse() = 0; + virtual void output() = 0; + virtual QString currentDevice() const = 0; + virtual void warning(const QString &message) const; + virtual void qFatal(const QString &message) const; + QDomElement findUniqueElement(QDomElement parent, const QString &nodeName, + const QString &attribute, const QString &value) const; + void checkTagNames(QDomElement element, const QString &tag, const QStringList &names) const; + QDomDocument parseFile(const QString &filename) const; +}; + +#define XML_MAIN(_type) \ + int main(int, char **) \ + { \ + _type dx; \ + dx.process(); \ + return 0; \ + } + +#endif diff --git a/src/xml_to_data/xml_to_data.pro b/src/xml_to_data/xml_to_data.pro new file mode 100644 index 0000000..0f6e151 --- /dev/null +++ b/src/xml_to_data/xml_to_data.pro @@ -0,0 +1,6 @@ +STOPDIR = ../.. +include($${STOPDIR}/lib.pro) + +TARGET = xmltodata +HEADERS += xml_to_data.h device_xml_to_data.h prog_xml_to_data.h +SOURCES += xml_to_data.cpp device_xml_to_data.cpp -- cgit v1.2.1