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 USBCdc(object):
Pawel Zarembski 0:01f31e923fe2 23 """Wrapper class for a CDC usb device"""
Pawel Zarembski 0:01f31e923fe2 24
Pawel Zarembski 0:01f31e923fe2 25 # Communication commands documented in
Pawel Zarembski 0:01f31e923fe2 26 # PSTN120 inside CDC1.2_WMC1.1_012011
Pawel Zarembski 0:01f31e923fe2 27
Pawel Zarembski 0:01f31e923fe2 28 CLASS_CDC_DATA = 0xa
Pawel Zarembski 0:01f31e923fe2 29 CLASS_CDC_COMM = 0x2
Pawel Zarembski 0:01f31e923fe2 30
Pawel Zarembski 0:01f31e923fe2 31 FORMAT_STOP_BITS_1_0 = 0
Pawel Zarembski 0:01f31e923fe2 32 FORMAT_STOP_BITS_1_5 = 1
Pawel Zarembski 0:01f31e923fe2 33 FORMAT_STOP_BITS_2_0 = 2
Pawel Zarembski 0:01f31e923fe2 34
Pawel Zarembski 0:01f31e923fe2 35 PARITY_NONE = 0
Pawel Zarembski 0:01f31e923fe2 36 PARITY_ODD = 1
Pawel Zarembski 0:01f31e923fe2 37 PARITY_EVEN = 2
Pawel Zarembski 0:01f31e923fe2 38 PARITY_MARK = 3
Pawel Zarembski 0:01f31e923fe2 39 PARITY_SPACE = 4
Pawel Zarembski 0:01f31e923fe2 40
Pawel Zarembski 0:01f31e923fe2 41 DATA_BITS_5 = 5
Pawel Zarembski 0:01f31e923fe2 42 DATA_BITS_6 = 6
Pawel Zarembski 0:01f31e923fe2 43 DATA_BITS_7 = 7
Pawel Zarembski 0:01f31e923fe2 44 DATA_BITS_8 = 8
Pawel Zarembski 0:01f31e923fe2 45 DATA_BITS_16 = 16
Pawel Zarembski 0:01f31e923fe2 46
Pawel Zarembski 0:01f31e923fe2 47 SEND_BREAK_ON = 0xFFFF
Pawel Zarembski 0:01f31e923fe2 48 SEND_BREAK_OFF = 0x0000
Pawel Zarembski 0:01f31e923fe2 49
Pawel Zarembski 0:01f31e923fe2 50 def __init__(self, device):
Pawel Zarembski 0:01f31e923fe2 51 self._dev = device
Pawel Zarembski 0:01f31e923fe2 52 self._if_data = None
Pawel Zarembski 0:01f31e923fe2 53 self._if_comm = None
Pawel Zarembski 0:01f31e923fe2 54 self.ep_data_out = None
Pawel Zarembski 0:01f31e923fe2 55 self.ep_data_in = None
Pawel Zarembski 0:01f31e923fe2 56 self._locked = False
Pawel Zarembski 0:01f31e923fe2 57 self.timeout = 10000
Pawel Zarembski 0:01f31e923fe2 58
Pawel Zarembski 0:01f31e923fe2 59 # Find interfaces
Pawel Zarembski 0:01f31e923fe2 60 for interface in device.get_active_configuration():
Pawel Zarembski 0:01f31e923fe2 61 if interface.bInterfaceClass == USBCdc.CLASS_CDC_DATA:
Pawel Zarembski 0:01f31e923fe2 62 assert self._if_data is None
Pawel Zarembski 0:01f31e923fe2 63 self._if_data = interface
Pawel Zarembski 0:01f31e923fe2 64 if interface.bInterfaceClass == USBCdc.CLASS_CDC_COMM:
Pawel Zarembski 0:01f31e923fe2 65 assert self._if_comm is None
Pawel Zarembski 0:01f31e923fe2 66 self._if_comm = interface
Pawel Zarembski 0:01f31e923fe2 67 assert self._if_data is not None
Pawel Zarembski 0:01f31e923fe2 68 assert self._if_comm is not None
Pawel Zarembski 0:01f31e923fe2 69
Pawel Zarembski 0:01f31e923fe2 70 # Find endpoints
Pawel Zarembski 0:01f31e923fe2 71 for endpoint in self._if_data:
Pawel Zarembski 0:01f31e923fe2 72 if endpoint.bEndpointAddress & 0x80:
Pawel Zarembski 0:01f31e923fe2 73 assert self.ep_data_in is None
Pawel Zarembski 0:01f31e923fe2 74 self.ep_data_in = endpoint
Pawel Zarembski 0:01f31e923fe2 75 else:
Pawel Zarembski 0:01f31e923fe2 76 assert self.ep_data_out is None
Pawel Zarembski 0:01f31e923fe2 77 self.ep_data_out = endpoint
Pawel Zarembski 0:01f31e923fe2 78 assert self.ep_data_in is not None
Pawel Zarembski 0:01f31e923fe2 79 assert self.ep_data_out is not None
Pawel Zarembski 0:01f31e923fe2 80
Pawel Zarembski 0:01f31e923fe2 81 def lock(self):
Pawel Zarembski 0:01f31e923fe2 82 """Acquire exclisive access to CDC"""
Pawel Zarembski 0:01f31e923fe2 83 assert not self._locked
Pawel Zarembski 0:01f31e923fe2 84
Pawel Zarembski 0:01f31e923fe2 85 for interface in (self._if_data, self._if_comm):
Pawel Zarembski 0:01f31e923fe2 86 num = interface.bInterfaceNumber
Pawel Zarembski 0:01f31e923fe2 87 try:
Pawel Zarembski 0:01f31e923fe2 88 if self._dev.is_kernel_driver_active(num):
Pawel Zarembski 0:01f31e923fe2 89 self._dev.detach_kernel_driver(num)
Pawel Zarembski 0:01f31e923fe2 90 except NotImplementedError:
Pawel Zarembski 0:01f31e923fe2 91 pass
Pawel Zarembski 0:01f31e923fe2 92 except usb.core.USBError:
Pawel Zarembski 0:01f31e923fe2 93 pass
Pawel Zarembski 0:01f31e923fe2 94 usb.util.claim_interface(self._dev, num)
Pawel Zarembski 0:01f31e923fe2 95 self._locked = True
Pawel Zarembski 0:01f31e923fe2 96
Pawel Zarembski 0:01f31e923fe2 97 def unlock(self):
Pawel Zarembski 0:01f31e923fe2 98 """Release exclusive access to CDC"""
Pawel Zarembski 0:01f31e923fe2 99 assert self._locked
Pawel Zarembski 0:01f31e923fe2 100
Pawel Zarembski 0:01f31e923fe2 101 for interface in (self._if_data, self._if_comm):
Pawel Zarembski 0:01f31e923fe2 102 num = interface.bInterfaceNumber
Pawel Zarembski 0:01f31e923fe2 103 usb.util.release_interface(self._dev, num)
Pawel Zarembski 0:01f31e923fe2 104 try:
Pawel Zarembski 0:01f31e923fe2 105 self._dev.attach_kernel_driver(num)
Pawel Zarembski 0:01f31e923fe2 106 except NotImplementedError:
Pawel Zarembski 0:01f31e923fe2 107 pass
Pawel Zarembski 0:01f31e923fe2 108 except usb.core.USBError:
Pawel Zarembski 0:01f31e923fe2 109 pass
Pawel Zarembski 0:01f31e923fe2 110 self._locked = False
Pawel Zarembski 0:01f31e923fe2 111
Pawel Zarembski 0:01f31e923fe2 112 def set_line_coding(self, baud, fmt=FORMAT_STOP_BITS_1_0,
Pawel Zarembski 0:01f31e923fe2 113 parity=PARITY_NONE, databits=DATA_BITS_8):
Pawel Zarembski 0:01f31e923fe2 114 """Send the SetLineCoding CDC command"""
Pawel Zarembski 0:01f31e923fe2 115 assert self._locked
Pawel Zarembski 0:01f31e923fe2 116
Pawel Zarembski 0:01f31e923fe2 117 data = bytearray(7)
Pawel Zarembski 0:01f31e923fe2 118 data[0] = (baud >> (8 * 0)) & 0xFF
Pawel Zarembski 0:01f31e923fe2 119 data[1] = (baud >> (8 * 1)) & 0xFF
Pawel Zarembski 0:01f31e923fe2 120 data[2] = (baud >> (8 * 2)) & 0xFF
Pawel Zarembski 0:01f31e923fe2 121 data[3] = (baud >> (8 * 3)) & 0xFF
Pawel Zarembski 0:01f31e923fe2 122 data[4] = fmt
Pawel Zarembski 0:01f31e923fe2 123 data[5] = parity
Pawel Zarembski 0:01f31e923fe2 124 data[6] = databits
Pawel Zarembski 0:01f31e923fe2 125
Pawel Zarembski 0:01f31e923fe2 126 request_type = 0x21
Pawel Zarembski 0:01f31e923fe2 127 request = 0x20 # SET_LINE_CODING
Pawel Zarembski 0:01f31e923fe2 128 value = 0 # Always 0 for this request
Pawel Zarembski 0:01f31e923fe2 129 index = self._if_comm.bInterfaceNumber # Communication interface
Pawel Zarembski 0:01f31e923fe2 130 self._dev.ctrl_transfer(request_type, request, value, index, data,
Pawel Zarembski 0:01f31e923fe2 131 self.timeout)
Pawel Zarembski 0:01f31e923fe2 132
Pawel Zarembski 0:01f31e923fe2 133 def get_line_coding(self):
Pawel Zarembski 0:01f31e923fe2 134 """Send the GetLineCoding CDC command
Pawel Zarembski 0:01f31e923fe2 135
Pawel Zarembski 0:01f31e923fe2 136 Returns a tuple containing
Pawel Zarembski 0:01f31e923fe2 137 baud, fmt, parity, databits
Pawel Zarembski 0:01f31e923fe2 138 """
Pawel Zarembski 0:01f31e923fe2 139 assert self._locked
Pawel Zarembski 0:01f31e923fe2 140
Pawel Zarembski 0:01f31e923fe2 141 request_type = 0xA1
Pawel Zarembski 0:01f31e923fe2 142 request = 0x21 # GET_LINE_CODING
Pawel Zarembski 0:01f31e923fe2 143 value = 0 # Always 0 for this request
Pawel Zarembski 0:01f31e923fe2 144 index = self._if_comm.bInterfaceNumber # Communication interface
Pawel Zarembski 0:01f31e923fe2 145 resp = self._dev.ctrl_transfer(request_type, request, value, index, 7,
Pawel Zarembski 0:01f31e923fe2 146 self.timeout)
Pawel Zarembski 0:01f31e923fe2 147 baud = (((resp[0] & 0xFF) << (8 * 0)) |
Pawel Zarembski 0:01f31e923fe2 148 ((resp[1] & 0xFF) << (8 * 1)) |
Pawel Zarembski 0:01f31e923fe2 149 ((resp[2] & 0xFF) << (8 * 2)) |
Pawel Zarembski 0:01f31e923fe2 150 ((resp[3] & 0xFF) << (8 * 3)))
Pawel Zarembski 0:01f31e923fe2 151 fmt = resp[4]
Pawel Zarembski 0:01f31e923fe2 152 parity = resp[5]
Pawel Zarembski 0:01f31e923fe2 153 databits = resp[6]
Pawel Zarembski 0:01f31e923fe2 154 return (baud, fmt, parity, databits)
Pawel Zarembski 0:01f31e923fe2 155
Pawel Zarembski 0:01f31e923fe2 156 def send_break(self, break_time):
Pawel Zarembski 0:01f31e923fe2 157 """Send the SendBreak CDC command"""
Pawel Zarembski 0:01f31e923fe2 158 assert self._locked
Pawel Zarembski 0:01f31e923fe2 159 assert break_time & ~0xFFFF == 0, "Value outside of supported range"
Pawel Zarembski 0:01f31e923fe2 160
Pawel Zarembski 0:01f31e923fe2 161 request_type = 0x21
Pawel Zarembski 0:01f31e923fe2 162 request = 0x23 # SEND_BREAK
Pawel Zarembski 0:01f31e923fe2 163 value = break_time # Duration of break in ms
Pawel Zarembski 0:01f31e923fe2 164 index = self._if_comm.bInterfaceNumber # Communication interface
Pawel Zarembski 0:01f31e923fe2 165 self._dev.ctrl_transfer(request_type, request, value, index, None,
Pawel Zarembski 0:01f31e923fe2 166 self.timeout)
Pawel Zarembski 0:01f31e923fe2 167
Pawel Zarembski 0:01f31e923fe2 168 def read(self, size, timeout=None):
Pawel Zarembski 0:01f31e923fe2 169 """Read from the CDC data endpoint"""
Pawel Zarembski 0:01f31e923fe2 170 assert self._locked
Pawel Zarembski 0:01f31e923fe2 171
Pawel Zarembski 0:01f31e923fe2 172 if timeout is None:
Pawel Zarembski 0:01f31e923fe2 173 timeout = self.timeout
Pawel Zarembski 0:01f31e923fe2 174 return self.ep_data_in.read(size, timeout)
Pawel Zarembski 0:01f31e923fe2 175
Pawel Zarembski 0:01f31e923fe2 176 def write(self, data, timeout=None):
Pawel Zarembski 0:01f31e923fe2 177 """Write to the CDC data endpoint"""
Pawel Zarembski 0:01f31e923fe2 178 assert self._locked
Pawel Zarembski 0:01f31e923fe2 179
Pawel Zarembski 0:01f31e923fe2 180 if timeout is None:
Pawel Zarembski 0:01f31e923fe2 181 timeout = self.timeout
Pawel Zarembski 0:01f31e923fe2 182 self.ep_data_out.write(data, self.timeout)