{"action":"created","comment":{"url":"https://api.github.com/repos/mbedmicro/pyOCD/pulls/comments/47970181","id":47970181,"diff_hunk":"@@ -0,0 +1,347 @@\n+\"\"\"\n+ mbed CMSIS-DAP debugger\n+ Copyright (c) 2015 ARM Limited\n+\n+ Licensed under the Apache License, Version 2.0 (the \"License\");\n+ you may not use this file except in compliance with the License.\n+ You may obtain a copy of the License at\n+\n+     http://www.apache.org/licenses/LICENSE-2.0\n+\n+ Unless required by applicable law or agreed to in writing, software\n+ distributed under the License is distributed on an \"AS IS\" BASIS,\n+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+ See the License for the specific language governing permissions and\n+ limitations under the License.\n+\"\"\"\n+\n+from ..pyDAPAccess import DAPAccess\n+from .rom_table import ROMTable\n+from .dap import (AP_REG, _ap_addr_to_reg, READ, WRITE, AP_ACC, APSEL_SHIFT, LOG_DAP)\n+from ..utility import conversion\n+import logging\n+\n+AP_ROM_TABLE_ADDR_REG = 0xf8\n+AP_ROM_TABLE_FORMAT_MASK = 0x2\n+AP_ROM_TABLE_ENTRY_PRESENT_MASK = 0x1\n+\n+AHB_IDR_TO_WRAP_SIZE = {\n+    0x24770011 : 0x1000,    # Used on m4 & m3 - Documented in arm_cortexm4_processor_trm_100166_0001_00_en.pdf\n+                            #                   and arm_cortexm3_processor_trm_100165_0201_00_en.pdf\n+    0x44770001 : 0x400,     # Used on m1 - Documented in DDI0413D_cortexm1_r1p0_trm.pdf\n+    0x04770031 : 0x400,     # Used on m0+? at least on KL25Z, KL46, LPC812\n+    0x04770021 : 0x400,     # Used on m0? used on nrf51, lpc11u24\n+    0x64770001 : 0x400,     # Used on m7\n+    0x74770001 : 0x400,     # Used on m0+ on KL28Z\n+    }\n+\n+# AP Control and Status Word definitions\n+CSW_SIZE     =  0x00000007\n+CSW_SIZE8    =  0x00000000\n+CSW_SIZE16   =  0x00000001\n+CSW_SIZE32   =  0x00000002\n+CSW_ADDRINC  =  0x00000030\n+CSW_NADDRINC =  0x00000000\n+CSW_SADDRINC =  0x00000010\n+CSW_PADDRINC =  0x00000020\n+CSW_DBGSTAT  =  0x00000040\n+CSW_TINPROG  =  0x00000080\n+CSW_HPROT    =  0x02000000\n+CSW_MSTRTYPE =  0x20000000\n+CSW_MSTRCORE =  0x00000000\n+CSW_MSTRDBG  =  0x20000000\n+CSW_RESERVED =  0x01000000\n+\n+CSW_VALUE = (CSW_RESERVED | CSW_MSTRDBG | CSW_HPROT | CSW_DBGSTAT | CSW_SADDRINC)\n+\n+TRANSFER_SIZE = {8: CSW_SIZE8,\n+                 16: CSW_SIZE16,\n+                 32: CSW_SIZE32\n+                 }\n+\n+class AccessPort(object):\n+    def __init__(self, dp, ap_num):\n+        self.dp = dp\n+        self.ap_num = ap_num\n+        self.link = dp.link\n+        self.idr = 0\n+        self.rom_addr = 0\n+        self.has_rom_table = False\n+        self.rom_table = None\n+        if LOG_DAP:\n+            self.logger = self.dp.logger.getChild('ap%d' % ap_num)\n+\n+    def init(self, bus_accessible=True):\n+        self.idr = self.read_reg(AP_REG['IDR'])\n+\n+        # Init ROM table\n+        self.rom_addr = self.read_reg(AP_ROM_TABLE_ADDR_REG)\n+        self.has_rom_table = (self.rom_addr != 0xffffffff) and ((self.rom_addr & AP_ROM_TABLE_ENTRY_PRESENT_MASK) != 0)\n+        self.rom_addr &= 0xfffffffc # clear format and present bits\n+        if self.has_rom_table and bus_accessible:\n+            self.init_rom_table()\n+\n+    def init_rom_table(self):\n+        self.rom_table = ROMTable(self)\n+        self.rom_table.init()\n+\n+    def read_reg(self, addr, now=True):\n+        return self.dp.readAP((self.ap_num << APSEL_SHIFT) | addr, now)\n+\n+    def write_reg(self, addr, data):\n+        self.dp.writeAP((self.ap_num << APSEL_SHIFT) | addr, data)\n+\n+class MEM_AP(AccessPort):\n+    def __init__(self, dp, ap_num):\n+        super(MEM_AP, self).__init__(dp, ap_num)\n+        self.auto_increment_page_size = 4\n+\n+    ## @brief Write a single memory location.\n+    #\n+    # By default the transfer size is a word\n+    def writeMemory(self, addr, data, transfer_size=32):\n+        num = self.dp.next_access_number\n+        if LOG_DAP:\n+            self.logger.info(\"writeMem:%06d (addr=0x%08x, size=%d) = 0x%08x {\", num, addr, transfer_size, data)\n+        self.write_reg(AP_REG['CSW'], CSW_VALUE | TRANSFER_SIZE[transfer_size])\n+        if transfer_size == 8:\n+            data = data << ((addr & 0x03) << 3)\n+        elif transfer_size == 16:\n+            data = data << ((addr & 0x02) << 3)\n+\n+        try:\n+            self.write_reg(AP_REG['TAR'], addr)\n+            self.write_reg(AP_REG['DRW'], data)\n+        except DAPAccess.Error as error:\n+            self._handle_error(error, num)\n+            raise\n+        if LOG_DAP:\n+            self.logger.info(\"writeMem:%06d }\", num)\n+\n+    ## @brief Read a memory location.\n+    #\n+    # By default, a word will be read.\n+    def readMemory(self, addr, transfer_size=32, now=True):\n+        num = self.dp.next_access_number\n+        if LOG_DAP:\n+            self.logger.info(\"readMem:%06d (addr=0x%08x, size=%d) {\", num, addr, transfer_size)\n+        res = None\n+        try:\n+            self.write_reg(AP_REG['CSW'], CSW_VALUE |\n+                         TRANSFER_SIZE[transfer_size])\n+            self.write_reg(AP_REG['TAR'], addr)\n+            result_cb = self.read_reg(AP_REG['DRW'], now=False)\n+        except DAPAccess.Error as error:\n+            self._handle_error(error, num)\n+            raise\n+\n+        def readMemCb():\n+            try:\n+                res = result_cb()\n+                if transfer_size == 8:\n+                    res = (res >> ((addr & 0x03) << 3) & 0xff)\n+                elif transfer_size == 16:\n+                    res = (res >> ((addr & 0x02) << 3) & 0xffff)\n+                if LOG_DAP:\n+                    self.logger.info(\"readMem:%06d %s(addr=0x%08x, size=%d) -> 0x%08x }\", num, \"\" if now else \"...\", addr, transfer_size, res)\n+            except DAPAccess.Error as error:\n+                self._handle_error(error, num)\n+                raise\n+            return res\n+\n+        if now:\n+            result = readMemCb()\n+            return result\n+        else:\n+            return readMemCb\n+\n+    # write aligned word (\"data\" are words)\n+    def writeBlock32(self, addr, data):\n+        num = self.dp.next_access_number\n+        if LOG_DAP:\n+            self.logger.info(\"writeBlock32:%06d (addr=0x%08x, size=%d) {\", num, addr, len(data))\n+        # put address in TAR\n+        self.write_reg(AP_REG['CSW'], CSW_VALUE | CSW_SIZE32)\n+        self.write_reg(AP_REG['TAR'], addr)\n+        try:\n+            reg = _ap_addr_to_reg((self.ap_num << APSEL_SHIFT) | WRITE | AP_ACC | AP_REG['DRW'])\n+            self.link.reg_write_repeat(len(data), reg, data)\n+        except DAPAccess.Error as error:\n+            self._handle_error(error, num)\n+            raise\n+        if LOG_DAP:\n+            self.logger.info(\"writeBlock32:%06d }\", num)\n+\n+    # read aligned word (the size is in words)\n+    def readBlock32(self, addr, size):\n+        num = self.dp.next_access_number\n+        if LOG_DAP:\n+            self.logger.info(\"readBlock32:%06d (addr=0x%08x, size=%d) {\", num, addr, size)\n+        # put address in TAR\n+        self.write_reg(AP_REG['CSW'], CSW_VALUE | CSW_SIZE32)\n+        self.write_reg(AP_REG['TAR'], addr)\n+        try:\n+            reg = _ap_addr_to_reg((self.ap_num << APSEL_SHIFT) | READ | AP_ACC | AP_REG['DRW'])\n+            resp = self.link.reg_read_repeat(size, reg)\n+        except DAPAccess.Error as error:\n+            self._handle_error(error, num)\n+            raise\n+        if LOG_DAP:\n+            self.logger.info(\"readBlock32:%06d }\", num)\n+        return resp\n+\n+    ## @brief Shorthand to write a 32-bit word.\n+    def write32(self, addr, value):\n+        self.writeMemory(addr, value, 32)\n+\n+    ## @brief Shorthand to write a 16-bit halfword.\n+    def write16(self, addr, value):\n+        self.writeMemory(addr, value, 16)\n+\n+    ## @brief Shorthand to write a byte.\n+    def write8(self, addr, value):\n+        self.writeMemory(addr, value, 8)\n+\n+    ## @brief Shorthand to read a 32-bit word.\n+    def read32(self, addr, now=True):\n+        return self.readMemory(addr, 32, now)\n+\n+    ## @brief Shorthand to read a 16-bit halfword.\n+    def read16(self, addr, now=True):\n+        return self.readMemory(addr, 16, now)\n+\n+    ## @brief Shorthand to read a byte.\n+    def read8(self, addr, now=True):\n+        return self.readMemory(addr, 8, now)\n+\n+    ## @brief Read a block of unaligned bytes in memory.\n+    # @return an array of byte values\n+    def readBlockMemoryUnaligned8(self, addr, size):\n+        res = []\n+\n+        # try to read 8bits data\n+        if (size > 0) and (addr & 0x01):\n+            mem = self.readMemory(addr, 8)\n+            res.append(mem)\n+            size -= 1\n+            addr += 1\n+\n+        # try to read 16bits data\n+        if (size > 1) and (addr & 0x02):\n+            mem = self.readMemory(addr, 16)\n+            res.append(mem & 0xff)\n+            res.append((mem >> 8) & 0xff)\n+            size -= 2\n+            addr += 2\n+\n+        # try to read aligned block of 32bits\n+        if (size >= 4):\n+            mem = self.readBlockMemoryAligned32(addr, size/4)\n+            res += conversion.u32leListToByteList(mem)\n+            size -= 4*len(mem)\n+            addr += 4*len(mem)\n+\n+        if (size > 1):\n+            mem = self.readMemory(addr, 16)\n+            res.append(mem & 0xff)\n+            res.append((mem >> 8) & 0xff)\n+            size -= 2\n+            addr += 2\n+\n+        if (size > 0):\n+            mem = self.readMemory(addr, 8)\n+            res.append(mem)\n+            size -= 1\n+            addr += 1\n+\n+        return res\n+\n+    ## @brief Write a block of unaligned bytes in memory.\n+    def writeBlockMemoryUnaligned8(self, addr, data):\n+        size = len(data)\n+        idx = 0\n+\n+        #try to write 8 bits data\n+        if (size > 0) and (addr & 0x01):\n+            self.writeMemory(addr, data[idx], 8)\n+            size -= 1\n+            addr += 1\n+            idx += 1\n+\n+        # try to write 16 bits data\n+        if (size > 1) and (addr & 0x02):\n+            self.writeMemory(addr, data[idx] | (data[idx+1] << 8), 16)\n+            size -= 2\n+            addr += 2\n+            idx += 2\n+\n+        # write aligned block of 32 bits\n+        if (size >= 4):\n+            data32 = conversion.byteListToU32leList(data[idx:idx + (size & ~0x03)])\n+            self.writeBlockMemoryAligned32(addr, data32)\n+            addr += size & ~0x03\n+            idx += size & ~0x03\n+            size -= size & ~0x03\n+\n+        # try to write 16 bits data\n+        if (size > 1):\n+            self.writeMemory(addr, data[idx] | (data[idx+1] << 8), 16)\n+            size -= 2\n+            addr += 2\n+            idx += 2\n+\n+        #try to write 8 bits data\n+        if (size > 0):\n+            self.writeMemory(addr, data[idx], 8)\n+            size -= 1\n+            addr += 1\n+            idx += 1\n+\n+        return\n+\n+    ## @brief Write a block of aligned words in memory.\n+    def writeBlockMemoryAligned32(self, addr, data):","path":"pyOCD/coresight/ap.py","position":303,"original_position":303,"commit_id":"d2abcce416d50b8c2fbf1de4627d8d9502a27060","original_commit_id":"d2abcce416d50b8c2fbf1de4627d8d9502a27060","user":{"login":"c1728p9","id":2916772,"avatar_url":"https://avatars.githubusercontent.com/u/2916772?v=3","gravatar_id":"","url":"https://api.github.com/users/c1728p9","html_url":"https://github.com/c1728p9","followers_url":"https://api.github.com/users/c1728p9/followers","following_url":"https://api.github.com/users/c1728p9/following{/other_user}","gists_url":"https://api.github.com/users/c1728p9/gists{/gist_id}","starred_url":"https://api.github.com/users/c1728p9/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/c1728p9/subscriptions","organizations_url":"https://api.github.com/users/c1728p9/orgs","repos_url":"https://api.github.com/users/c1728p9/repos","events_url":"https://api.github.com/users/c1728p9/events{/privacy}","received_events_url":"https://api.github.com/users/c1728p9/received_events","type":"User","site_admin":false},"body":"I'm not sure if there is much of a need to write blocks of 32 bytes values.  It might be good to make this private/remove it from the public API.  What do you think?","created_at":"2015-12-17T22:25:29Z","updated_at":"2015-12-17T22:25:29Z","html_url":"https://github.com/mbedmicro/pyOCD/pull/216#discussion_r47970181","pull_request_url":"https://api.github.com/repos/mbedmicro/pyOCD/pulls/216","_links":{"self":{"href":"https://api.github.com/repos/mbedmicro/pyOCD/pulls/comments/47970181"},"html":{"href":"https://github.com/mbedmicro/pyOCD/pull/216#discussion_r47970181"},"pull_request":{"href":"https://api.github.com/repos/mbedmicro/pyOCD/pulls/216"}}},"pull_request":{"url":"https://api.github.com/repos/mbedmicro/pyOCD/pulls/216","id":52879614,"html_url":"https://github.com/mbedmicro/pyOCD/pull/216","diff_url":"https://github.com/mbedmicro/pyOCD/pull/216.diff","patch_url":"https://github.com/mbedmicro/pyOCD/pull/216.patch","issue_url":"https://api.github.com/repos/mbedmicro/pyOCD/issues/216","number":216,"state":"open","locked":false,"title":"Architectural refactoring","user":{"login":"flit","id":3116536,"avatar_url":"https://avatars.githubusercontent.com/u/3116536?v=3","gravatar_id":"","url":"https://api.github.com/users/flit","html_url":"https://github.com/flit","followers_url":"https://api.github.com/users/flit/followers","following_url":"https://api.github.com/users/flit/following{/other_user}","gists_url":"https://api.github.com/users/flit/gists{/gist_id}","starred_url":"https://api.github.com/users/flit/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/flit/subscriptions","organizations_url":"https://api.github.com/users/flit/orgs","repos_url":"https://api.github.com/users/flit/repos","events_url":"https://api.github.com/users/flit/events{/privacy}","received_events_url":"https://api.github.com/users/flit/received_events","type":"User","site_admin":false},"body":"Fairly significant changes to re-architect pyOCD's target and Cortex-M related code.\r\n\r\n- Created new pyOCD.coresight submodule. It has DebugPort and AccessPort classes, as well as classes for CortexM, FPB, DWT, breakpoints, and ROM table parsing.\r\n- CortexM class moved to pyOCD.coresight and simplified by using other coresight component classes such as AHB_AP and the breakpoints classes.\r\n- New CoreSightTarget subclass of Target that owns the DebugPort, AccessPort, and CortexM classes. It supports multiple cores. The existing target classes are now subclasses of CoreSightTarget rather than CortexM.\r\n- Factored breakpoints code that was in CortexM into a BreakpointsManager class and related classes.\r\n- CoreSight ROM tables are parsed during init, although they are not yet used to construct objects.\r\n- Additional CPU states are supported: reset, lockup, and sleep.\r\n- Debug resources are disabled and debug is powered down upon disconnect.\r\n- Memory reads are filtered to hide software breakpoints.\r\n\r\nThis changeset also includes some miscellaneous changes, as well:\r\n- pyocd-tool can execute arbitrary Python expressions via a \"$<python code>\" syntax.\r\n- Added \"core\" command to pyocd-tool to select the current core.\r\n- SVD files are associated with targets and the registers can be accessed via pyocd-tool.\r\n- hidapi USB backend was improved to fix issues with multiple connected boards and when another process already has a board open.","created_at":"2015-12-07T18:07:58Z","updated_at":"2015-12-17T22:25:29Z","closed_at":null,"merged_at":null,"merge_commit_sha":"1135941969915204f79ac9718c438cde82d17fcc","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/mbedmicro/pyOCD/pulls/216/commits","review_comments_url":"https://api.github.com/repos/mbedmicro/pyOCD/pulls/216/comments","review_comment_url":"https://api.github.com/repos/mbedmicro/pyOCD/pulls/comments{/number}","comments_url":"https://api.github.com/repos/mbedmicro/pyOCD/issues/216/comments","statuses_url":"https://api.github.com/repos/mbedmicro/pyOCD/statuses/d2abcce416d50b8c2fbf1de4627d8d9502a27060","head":{"label":"flit:dev_architecture","ref":"dev_architecture","sha":"d2abcce416d50b8c2fbf1de4627d8d9502a27060","user":{"login":"flit","id":3116536,"avatar_url":"https://avatars.githubusercontent.com/u/3116536?v=3","gravatar_id":"","url":"https://api.github.com/users/flit","html_url":"https://github.com/flit","followers_url":"https://api.github.com/users/flit/followers","following_url":"https://api.github.com/users/flit/following{/other_user}","gists_url":"https://api.github.com/users/flit/gists{/gist_id}","starred_url":"https://api.github.com/users/flit/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/flit/subscriptions","organizations_url":"https://api.github.com/users/flit/orgs","repos_url":"https://api.github.com/users/flit/repos","events_url":"https://api.github.com/users/flit/events{/privacy}","received_events_url":"https://api.github.com/users/flit/received_events","type":"User","site_admin":false},"repo":{"id":14731481,"name":"pyOCD","full_name":"flit/pyOCD","owner":{"login":"flit","id":3116536,"avatar_url":"https://avatars.githubusercontent.com/u/3116536?v=3","gravatar_id":"","url":"https://api.github.com/users/flit","html_url":"https://github.com/flit","followers_url":"https://api.github.com/users/flit/followers","following_url":"https://api.github.com/users/flit/following{/other_user}","gists_url":"https://api.github.com/users/flit/gists{/gist_id}","starred_url":"https://api.github.com/users/flit/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/flit/subscriptions","organizations_url":"https://api.github.com/users/flit/orgs","repos_url":"https://api.github.com/users/flit/repos","events_url":"https://api.github.com/users/flit/events{/privacy}","received_events_url":"https://api.github.com/users/flit/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/flit/pyOCD","description":"Open source python library for programming and debugging ARM Cortex-M microcontrollers using CMSIS-DAP","fork":true,"url":"https://api.github.com/repos/flit/pyOCD","forks_url":"https://api.github.com/repos/flit/pyOCD/forks","keys_url":"https://api.github.com/repos/flit/pyOCD/keys{/key_id}","collaborators_url":"https://api.github.com/repos/flit/pyOCD/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/flit/pyOCD/teams","hooks_url":"https://api.github.com/repos/flit/pyOCD/hooks","issue_events_url":"https://api.github.com/repos/flit/pyOCD/issues/events{/number}","events_url":"https://api.github.com/repos/flit/pyOCD/events","assignees_url":"https://api.github.com/repos/flit/pyOCD/assignees{/user}","branches_url":"https://api.github.com/repos/flit/pyOCD/branches{/branch}","tags_url":"https://api.github.com/repos/flit/pyOCD/tags","blobs_url":"https://api.github.com/repos/flit/pyOCD/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/flit/pyOCD/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/flit/pyOCD/git/refs{/sha}","trees_url":"https://api.github.com/repos/flit/pyOCD/git/trees{/sha}","statuses_url":"https://api.github.com/repos/flit/pyOCD/statuses/{sha}","languages_url":"https://api.github.com/repos/flit/pyOCD/languages","stargazers_url":"https://api.github.com/repos/flit/pyOCD/stargazers","contributors_url":"https://api.github.com/repos/flit/pyOCD/contributors","subscribers_url":"https://api.github.com/repos/flit/pyOCD/subscribers","subscription_url":"https://api.github.com/repos/flit/pyOCD/subscription","commits_url":"https://api.github.com/repos/flit/pyOCD/commits{/sha}","git_commits_url":"https://api.github.com/repos/flit/pyOCD/git/commits{/sha}","comments_url":"https://api.github.com/repos/flit/pyOCD/comments{/number}","issue_comment_url":"https://api.github.com/repos/flit/pyOCD/issues/comments{/number}","contents_url":"https://api.github.com/repos/flit/pyOCD/contents/{+path}","compare_url":"https://api.github.com/repos/flit/pyOCD/compare/{base}...{head}","merges_url":"https://api.github.com/repos/flit/pyOCD/merges","archive_url":"https://api.github.com/repos/flit/pyOCD/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/flit/pyOCD/downloads","issues_url":"https://api.github.com/repos/flit/pyOCD/issues{/number}","pulls_url":"https://api.github.com/repos/flit/pyOCD/pulls{/number}","milestones_url":"https://api.github.com/repos/flit/pyOCD/milestones{/number}","notifications_url":"https://api.github.com/repos/flit/pyOCD/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/flit/pyOCD/labels{/name}","releases_url":"https://api.github.com/repos/flit/pyOCD/releases{/id}","created_at":"2013-11-26T22:48:46Z","updated_at":"2014-07-23T15:16:30Z","pushed_at":"2015-12-14T21:16:16Z","git_url":"git://github.com/flit/pyOCD.git","ssh_url":"git@github.com:flit/pyOCD.git","clone_url":"https://github.com/flit/pyOCD.git","svn_url":"https://github.com/flit/pyOCD","homepage":null,"size":1379,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"mbedmicro:master","ref":"master","sha":"9ac954655a1ca2fe748c594b5fa104f9f1455792","user":{"login":"mbedmicro","id":3626466,"avatar_url":"https://avatars.githubusercontent.com/u/3626466?v=3","gravatar_id":"","url":"https://api.github.com/users/mbedmicro","html_url":"https://github.com/mbedmicro","followers_url":"https://api.github.com/users/mbedmicro/followers","following_url":"https://api.github.com/users/mbedmicro/following{/other_user}","gists_url":"https://api.github.com/users/mbedmicro/gists{/gist_id}","starred_url":"https://api.github.com/users/mbedmicro/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mbedmicro/subscriptions","organizations_url":"https://api.github.com/users/mbedmicro/orgs","repos_url":"https://api.github.com/users/mbedmicro/repos","events_url":"https://api.github.com/users/mbedmicro/events{/privacy}","received_events_url":"https://api.github.com/users/mbedmicro/received_events","type":"Organization","site_admin":false},"repo":{"id":13862423,"name":"pyOCD","full_name":"mbedmicro/pyOCD","owner":{"login":"mbedmicro","id":3626466,"avatar_url":"https://avatars.githubusercontent.com/u/3626466?v=3","gravatar_id":"","url":"https://api.github.com/users/mbedmicro","html_url":"https://github.com/mbedmicro","followers_url":"https://api.github.com/users/mbedmicro/followers","following_url":"https://api.github.com/users/mbedmicro/following{/other_user}","gists_url":"https://api.github.com/users/mbedmicro/gists{/gist_id}","starred_url":"https://api.github.com/users/mbedmicro/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mbedmicro/subscriptions","organizations_url":"https://api.github.com/users/mbedmicro/orgs","repos_url":"https://api.github.com/users/mbedmicro/repos","events_url":"https://api.github.com/users/mbedmicro/events{/privacy}","received_events_url":"https://api.github.com/users/mbedmicro/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/mbedmicro/pyOCD","description":"Open source python library for programming and debugging ARM Cortex-M microcontrollers using CMSIS-DAP","fork":false,"url":"https://api.github.com/repos/mbedmicro/pyOCD","forks_url":"https://api.github.com/repos/mbedmicro/pyOCD/forks","keys_url":"https://api.github.com/repos/mbedmicro/pyOCD/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mbedmicro/pyOCD/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mbedmicro/pyOCD/teams","hooks_url":"https://api.github.com/repos/mbedmicro/pyOCD/hooks","issue_events_url":"https://api.github.com/repos/mbedmicro/pyOCD/issues/events{/number}","events_url":"https://api.github.com/repos/mbedmicro/pyOCD/events","assignees_url":"https://api.github.com/repos/mbedmicro/pyOCD/assignees{/user}","branches_url":"https://api.github.com/repos/mbedmicro/pyOCD/branches{/branch}","tags_url":"https://api.github.com/repos/mbedmicro/pyOCD/tags","blobs_url":"https://api.github.com/repos/mbedmicro/pyOCD/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mbedmicro/pyOCD/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mbedmicro/pyOCD/git/refs{/sha}","trees_url":"https://api.github.com/repos/mbedmicro/pyOCD/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mbedmicro/pyOCD/statuses/{sha}","languages_url":"https://api.github.com/repos/mbedmicro/pyOCD/languages","stargazers_url":"https://api.github.com/repos/mbedmicro/pyOCD/stargazers","contributors_url":"https://api.github.com/repos/mbedmicro/pyOCD/contributors","subscribers_url":"https://api.github.com/repos/mbedmicro/pyOCD/subscribers","subscription_url":"https://api.github.com/repos/mbedmicro/pyOCD/subscription","commits_url":"https://api.github.com/repos/mbedmicro/pyOCD/commits{/sha}","git_commits_url":"https://api.github.com/repos/mbedmicro/pyOCD/git/commits{/sha}","comments_url":"https://api.github.com/repos/mbedmicro/pyOCD/comments{/number}","issue_comment_url":"https://api.github.com/repos/mbedmicro/pyOCD/issues/comments{/number}","contents_url":"https://api.github.com/repos/mbedmicro/pyOCD/contents/{+path}","compare_url":"https://api.github.com/repos/mbedmicro/pyOCD/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mbedmicro/pyOCD/merges","archive_url":"https://api.github.com/repos/mbedmicro/pyOCD/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mbedmicro/pyOCD/downloads","issues_url":"https://api.github.com/repos/mbedmicro/pyOCD/issues{/number}","pulls_url":"https://api.github.com/repos/mbedmicro/pyOCD/pulls{/number}","milestones_url":"https://api.github.com/repos/mbedmicro/pyOCD/milestones{/number}","notifications_url":"https://api.github.com/repos/mbedmicro/pyOCD/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mbedmicro/pyOCD/labels{/name}","releases_url":"https://api.github.com/repos/mbedmicro/pyOCD/releases{/id}","created_at":"2013-10-25T14:10:05Z","updated_at":"2015-12-17T06:54:45Z","pushed_at":"2015-12-16T19:40:40Z","git_url":"git://github.com/mbedmicro/pyOCD.git","ssh_url":"git@github.com:mbedmicro/pyOCD.git","clone_url":"https://github.com/mbedmicro/pyOCD.git","svn_url":"https://github.com/mbedmicro/pyOCD","homepage":null,"size":1677,"stargazers_count":92,"watchers_count":92,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":71,"mirror_url":null,"open_issues_count":19,"forks":71,"open_issues":19,"watchers":92,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/mbedmicro/pyOCD/pulls/216"},"html":{"href":"https://github.com/mbedmicro/pyOCD/pull/216"},"issue":{"href":"https://api.github.com/repos/mbedmicro/pyOCD/issues/216"},"comments":{"href":"https://api.github.com/repos/mbedmicro/pyOCD/issues/216/comments"},"review_comments":{"href":"https://api.github.com/repos/mbedmicro/pyOCD/pulls/216/comments"},"review_comment":{"href":"https://api.github.com/repos/mbedmicro/pyOCD/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/mbedmicro/pyOCD/pulls/216/commits"},"statuses":{"href":"https://api.github.com/repos/mbedmicro/pyOCD/statuses/d2abcce416d50b8c2fbf1de4627d8d9502a27060"}}}}