def transfer(self, count, request, data=[0], dap_index=0): cmd = [] cmd.append(COMMAND_ID['DAP_TRANSFER']) cmd.append(dap_index) cmd.append(count) count_write = count for i in range(count): cmd.append(request[i]) if not (request[i] & ((1 << 1) | (1 << 4))): cmd.append(data[i] & 0xff) cmd.append((data[i] >> 8) & 0xff) cmd.append((data[i] >> 16) & 0xff) cmd.append((data[i] >> 24) & 0xff) count_write -= 1 self.interface.write(cmd) resp = self.interface.read() if resp[0] != COMMAND_ID['DAP_TRANSFER']: raise ValueError('DAP_TRANSFER response error') if resp[2] != DAP_TRANSFER_OK: if resp[2] == DAP_TRANSFER_FAULT: raise Transport.TransferError() raise ValueError('SWD Fault') # Check for count mismatch after checking for DAP_TRANSFER_FAULT # This allows TransferError to get thrown instead of ValueError if resp[1] != count: raise ValueError('Transfer not completed') return resp[3:3 + count_write * 4]
def transferBlock(self, count, request, data=[0], dap_index=0): packet_count = count max_pending_reads = self.interface.getPacketCount() reads_pending = 0 nb = 0 resp = [] error_transfer = False error_response = False # we send successfully several packets if the size is bigger than MAX_PACKET_COUNT while packet_count > 0 or reads_pending > 0: # Make sure the transmit buffer stays saturated while packet_count > 0 and reads_pending < max_pending_reads: cmd = [] cmd.append(COMMAND_ID['DAP_TRANSFER_BLOCK']) cmd.append(dap_index) packet_written = min(packet_count, MAX_PACKET_SIZE) cmd.append(packet_written & 0xff) cmd.append((packet_written >> 8) & 0xff) cmd.append(request) if not (request & ((1 << 1))): for i in range(packet_written): cmd.append(data[i + nb * MAX_PACKET_SIZE] & 0xff) cmd.append((data[i + nb * MAX_PACKET_SIZE] >> 8) & 0xff) cmd.append((data[i + nb * MAX_PACKET_SIZE] >> 16) & 0xff) cmd.append((data[i + nb * MAX_PACKET_SIZE] >> 24) & 0xff) self.interface.write(cmd) packet_count = packet_count - MAX_PACKET_SIZE nb = nb + 1 reads_pending = reads_pending + 1 # Read data if reads_pending > 0: # we then read tmp = self.interface.read() if tmp[0] != COMMAND_ID['DAP_TRANSFER_BLOCK']: # Error occurred - abort further writes # but make sure to finish reading remaining packets packet_count = 0 error_response = True if tmp[3] != DAP_TRANSFER_OK: # Error occurred - abort further writes # but make sure to finish reading remaining packets packet_count = 0 if tmp[3] == DAP_TRANSFER_FAULT: error_transfer = True else: error_response = True size_transfer = tmp[1] | (tmp[2] << 8) resp.extend(tmp[4:4 + size_transfer * 4]) reads_pending = reads_pending - 1 # Raise pending errors if error_response: raise ValueError('DAP_TRANSFER_BLOCK response error') elif error_transfer: raise Transport.TransferError() return resp