Repostiory containing DAPLink source code with Reset Pin workaround for HANI_IOT board.

Upstream: https://github.com/ARMmbed/DAPLink

Committer:
Pawel Zarembski
Date:
Tue Apr 07 12:55:42 2020 +0200
Revision:
0:01f31e923fe2
hani: DAPLink with reset workaround

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Pawel Zarembski 0:01f31e923fe2 1 #
Pawel Zarembski 0:01f31e923fe2 2 # DAPLink Interface Firmware
Pawel Zarembski 0:01f31e923fe2 3 # Copyright (c) 2016-2016, ARM Limited, All Rights Reserved
Pawel Zarembski 0:01f31e923fe2 4 # SPDX-License-Identifier: Apache-2.0
Pawel Zarembski 0:01f31e923fe2 5 #
Pawel Zarembski 0:01f31e923fe2 6 # Licensed under the Apache License, Version 2.0 (the "License"); you may
Pawel Zarembski 0:01f31e923fe2 7 # not use this file except in compliance with the License.
Pawel Zarembski 0:01f31e923fe2 8 # You may obtain a copy of the License at
Pawel Zarembski 0:01f31e923fe2 9 #
Pawel Zarembski 0:01f31e923fe2 10 # http://www.apache.org/licenses/LICENSE-2.0
Pawel Zarembski 0:01f31e923fe2 11 #
Pawel Zarembski 0:01f31e923fe2 12 # Unless required by applicable law or agreed to in writing, software
Pawel Zarembski 0:01f31e923fe2 13 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
Pawel Zarembski 0:01f31e923fe2 14 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Pawel Zarembski 0:01f31e923fe2 15 # See the License for the specific language governing permissions and
Pawel Zarembski 0:01f31e923fe2 16 # limitations under the License.
Pawel Zarembski 0:01f31e923fe2 17 #
Pawel Zarembski 0:01f31e923fe2 18
Pawel Zarembski 0:01f31e923fe2 19 import usb.util
Pawel Zarembski 0:01f31e923fe2 20
Pawel Zarembski 0:01f31e923fe2 21
Pawel Zarembski 0:01f31e923fe2 22 class USBHid(object):
Pawel Zarembski 0:01f31e923fe2 23 """Wrapper class for a HID usb device"""
Pawel Zarembski 0:01f31e923fe2 24
Pawel Zarembski 0:01f31e923fe2 25 # HID commands documented in
Pawel Zarembski 0:01f31e923fe2 26 # Device Class Definition for Human Interface Devices (HID)
Pawel Zarembski 0:01f31e923fe2 27
Pawel Zarembski 0:01f31e923fe2 28 CLASS_HID = 0x3
Pawel Zarembski 0:01f31e923fe2 29
Pawel Zarembski 0:01f31e923fe2 30 DESC_TYPE_HID = 0x21
Pawel Zarembski 0:01f31e923fe2 31 DESC_TYPE_REPORT = 0x22
Pawel Zarembski 0:01f31e923fe2 32 DESC_TYPE_PHYSICAL = 0x23
Pawel Zarembski 0:01f31e923fe2 33
Pawel Zarembski 0:01f31e923fe2 34 REPORT_TYPE_INPUT = 1
Pawel Zarembski 0:01f31e923fe2 35 REPORT_TYPE_OUTPUT = 2
Pawel Zarembski 0:01f31e923fe2 36 REPORT_TYPE_FEATURE = 3
Pawel Zarembski 0:01f31e923fe2 37
Pawel Zarembski 0:01f31e923fe2 38 def __init__(self, device):
Pawel Zarembski 0:01f31e923fe2 39 self._dev = device
Pawel Zarembski 0:01f31e923fe2 40 self._if = None
Pawel Zarembski 0:01f31e923fe2 41 self.ep_in = None
Pawel Zarembski 0:01f31e923fe2 42 self.ep_out = None
Pawel Zarembski 0:01f31e923fe2 43 self._locked = False
Pawel Zarembski 0:01f31e923fe2 44 self.timeout = 10 * 1000
Pawel Zarembski 0:01f31e923fe2 45
Pawel Zarembski 0:01f31e923fe2 46 # Find interface
Pawel Zarembski 0:01f31e923fe2 47 for interface in device.get_active_configuration():
Pawel Zarembski 0:01f31e923fe2 48 if interface.bInterfaceClass == USBHid.CLASS_HID:
Pawel Zarembski 0:01f31e923fe2 49 assert self._if is None
Pawel Zarembski 0:01f31e923fe2 50 self._if = interface
Pawel Zarembski 0:01f31e923fe2 51 assert self._if is not None
Pawel Zarembski 0:01f31e923fe2 52
Pawel Zarembski 0:01f31e923fe2 53 # Find endpoints
Pawel Zarembski 0:01f31e923fe2 54 for endpoint in self._if:
Pawel Zarembski 0:01f31e923fe2 55 if endpoint.bEndpointAddress & 0x80:
Pawel Zarembski 0:01f31e923fe2 56 assert self.ep_in is None
Pawel Zarembski 0:01f31e923fe2 57 self.ep_in = endpoint
Pawel Zarembski 0:01f31e923fe2 58 else:
Pawel Zarembski 0:01f31e923fe2 59 assert self.ep_out is None
Pawel Zarembski 0:01f31e923fe2 60 self.ep_out = endpoint
Pawel Zarembski 0:01f31e923fe2 61 assert self.ep_in is not None
Pawel Zarembski 0:01f31e923fe2 62 # Endpoint out can be None
Pawel Zarembski 0:01f31e923fe2 63
Pawel Zarembski 0:01f31e923fe2 64 def lock(self):
Pawel Zarembski 0:01f31e923fe2 65 """Acquire exclisive access to HID"""
Pawel Zarembski 0:01f31e923fe2 66 assert not self._locked
Pawel Zarembski 0:01f31e923fe2 67
Pawel Zarembski 0:01f31e923fe2 68 num = self._if.bInterfaceNumber
Pawel Zarembski 0:01f31e923fe2 69 try:
Pawel Zarembski 0:01f31e923fe2 70 if self._dev.is_kernel_driver_active(num):
Pawel Zarembski 0:01f31e923fe2 71 self._dev.detach_kernel_driver(num)
Pawel Zarembski 0:01f31e923fe2 72 except NotImplementedError:
Pawel Zarembski 0:01f31e923fe2 73 pass
Pawel Zarembski 0:01f31e923fe2 74 except usb.core.USBError:
Pawel Zarembski 0:01f31e923fe2 75 pass
Pawel Zarembski 0:01f31e923fe2 76 usb.util.claim_interface(self._dev, num)
Pawel Zarembski 0:01f31e923fe2 77 self._locked = True
Pawel Zarembski 0:01f31e923fe2 78
Pawel Zarembski 0:01f31e923fe2 79 def unlock(self):
Pawel Zarembski 0:01f31e923fe2 80 """Release exclusive access to HID"""
Pawel Zarembski 0:01f31e923fe2 81 assert self._locked
Pawel Zarembski 0:01f31e923fe2 82
Pawel Zarembski 0:01f31e923fe2 83 num = self._if.bInterfaceNumber
Pawel Zarembski 0:01f31e923fe2 84 usb.util.release_interface(self._dev, num)
Pawel Zarembski 0:01f31e923fe2 85 try:
Pawel Zarembski 0:01f31e923fe2 86 self._dev.attach_kernel_driver(num)
Pawel Zarembski 0:01f31e923fe2 87 except NotImplementedError:
Pawel Zarembski 0:01f31e923fe2 88 pass
Pawel Zarembski 0:01f31e923fe2 89 except usb.core.USBError:
Pawel Zarembski 0:01f31e923fe2 90 pass
Pawel Zarembski 0:01f31e923fe2 91 self._locked = False
Pawel Zarembski 0:01f31e923fe2 92
Pawel Zarembski 0:01f31e923fe2 93 def set_idle(self, report_id=0, duration=0):
Pawel Zarembski 0:01f31e923fe2 94 """Send a HID Set_Idle request"""
Pawel Zarembski 0:01f31e923fe2 95 assert self._locked
Pawel Zarembski 0:01f31e923fe2 96 assert report_id & ~0xFF == 0
Pawel Zarembski 0:01f31e923fe2 97 assert duration & ~0xFF == 0
Pawel Zarembski 0:01f31e923fe2 98
Pawel Zarembski 0:01f31e923fe2 99 request_type = 0x21
Pawel Zarembski 0:01f31e923fe2 100 request = 0x0A # SET_IDLE
Pawel Zarembski 0:01f31e923fe2 101 value = ((duration << 8) | (report_id << 0)) # Report and duration
Pawel Zarembski 0:01f31e923fe2 102 index = self._if.bInterfaceNumber # HID interface
Pawel Zarembski 0:01f31e923fe2 103 self._dev.ctrl_transfer(request_type, request, value, index, None)
Pawel Zarembski 0:01f31e923fe2 104
Pawel Zarembski 0:01f31e923fe2 105 def get_descriptor(self, desc_type, index):
Pawel Zarembski 0:01f31e923fe2 106 """Get the given descriptor"""
Pawel Zarembski 0:01f31e923fe2 107 assert self._locked
Pawel Zarembski 0:01f31e923fe2 108 assert desc_type & ~0xFF == 0
Pawel Zarembski 0:01f31e923fe2 109 assert index & ~0xFF == 0
Pawel Zarembski 0:01f31e923fe2 110
Pawel Zarembski 0:01f31e923fe2 111 request_type = 0x81
Pawel Zarembski 0:01f31e923fe2 112 request = 0x6 # GET_DESCRIPTOR
Pawel Zarembski 0:01f31e923fe2 113 value = (((index & 0xFF) << (0 * 8)) |
Pawel Zarembski 0:01f31e923fe2 114 ((desc_type & 0xFF) << (1 * 8))) # Descriptor type and index
Pawel Zarembski 0:01f31e923fe2 115 index = self._if.bInterfaceNumber # HID interface
Pawel Zarembski 0:01f31e923fe2 116 return self._dev.ctrl_transfer(request_type, request,
Pawel Zarembski 0:01f31e923fe2 117 value, index, 256)
Pawel Zarembski 0:01f31e923fe2 118
Pawel Zarembski 0:01f31e923fe2 119 def set_report_req(self, data, report_type=REPORT_TYPE_OUTPUT,
Pawel Zarembski 0:01f31e923fe2 120 report_id=0):
Pawel Zarembski 0:01f31e923fe2 121 """Set a report of the given type"""
Pawel Zarembski 0:01f31e923fe2 122 assert self._locked
Pawel Zarembski 0:01f31e923fe2 123 assert report_type & ~0xFF == 0
Pawel Zarembski 0:01f31e923fe2 124 assert report_id & ~0xFF == 0
Pawel Zarembski 0:01f31e923fe2 125
Pawel Zarembski 0:01f31e923fe2 126 request_type = 0x21
Pawel Zarembski 0:01f31e923fe2 127 request = 0x09 # SET_REPORT
Pawel Zarembski 0:01f31e923fe2 128 value = ((report_type << 8) |
Pawel Zarembski 0:01f31e923fe2 129 (report_id << 0)) # Report and duration
Pawel Zarembski 0:01f31e923fe2 130 index = self._if.bInterfaceNumber # HID interface
Pawel Zarembski 0:01f31e923fe2 131 self._dev.ctrl_transfer(request_type, request, value, index, data,
Pawel Zarembski 0:01f31e923fe2 132 self.timeout)
Pawel Zarembski 0:01f31e923fe2 133
Pawel Zarembski 0:01f31e923fe2 134 def get_report_req(self, data_size, report_type=REPORT_TYPE_INPUT,
Pawel Zarembski 0:01f31e923fe2 135 report_id=0):
Pawel Zarembski 0:01f31e923fe2 136 """Set a report of the given type"""
Pawel Zarembski 0:01f31e923fe2 137 assert self._locked
Pawel Zarembski 0:01f31e923fe2 138 assert report_type & ~0xFF == 0
Pawel Zarembski 0:01f31e923fe2 139 assert report_id & ~0xFF == 0
Pawel Zarembski 0:01f31e923fe2 140
Pawel Zarembski 0:01f31e923fe2 141 request_type = 0xA1
Pawel Zarembski 0:01f31e923fe2 142 request = 0x01 # SET_REPORT
Pawel Zarembski 0:01f31e923fe2 143 value = ((report_type << 8) |
Pawel Zarembski 0:01f31e923fe2 144 (report_id << 0)) # Report and duration
Pawel Zarembski 0:01f31e923fe2 145 index = self._if.bInterfaceNumber # HID interface
Pawel Zarembski 0:01f31e923fe2 146 return self._dev.ctrl_transfer(request_type, request, value, index,
Pawel Zarembski 0:01f31e923fe2 147 data_size, self.timeout)
Pawel Zarembski 0:01f31e923fe2 148
Pawel Zarembski 0:01f31e923fe2 149 def set_report(self, data):
Pawel Zarembski 0:01f31e923fe2 150 """Send report to the device"""
Pawel Zarembski 0:01f31e923fe2 151 assert self._locked
Pawel Zarembski 0:01f31e923fe2 152
Pawel Zarembski 0:01f31e923fe2 153 if self.ep_out is None:
Pawel Zarembski 0:01f31e923fe2 154 self.set_report_req(data)
Pawel Zarembski 0:01f31e923fe2 155 else:
Pawel Zarembski 0:01f31e923fe2 156 self.ep_out.write(data, 10 * 1000)
Pawel Zarembski 0:01f31e923fe2 157
Pawel Zarembski 0:01f31e923fe2 158 def get_report(self, size):
Pawel Zarembski 0:01f31e923fe2 159 """Read report from the device"""
Pawel Zarembski 0:01f31e923fe2 160 assert self._locked
Pawel Zarembski 0:01f31e923fe2 161
Pawel Zarembski 0:01f31e923fe2 162 return self.ep_in.read(size, 10 * 1000)