MCPcopy Create free account
hub / github.com/LeoDJ/P2Pro-Viewer / _standard_cmd_write

Method _standard_cmd_write

P2Pro/P2Pro_cmd.py:140–200  ·  view source on GitHub ↗

Sends a "standard CMD write" packet :param cmd: 2 byte CMD code :param cmd_param: 4 byte parameter that gets sent together with CMD (for spi_* commands, the address needs to be passed in as big-endian) :param data: payload :param dataLen: payload length

(self, cmd: int, cmd_param: int = 0, data: bytes = b'\x00', dataLen: int = -1)

Source from the content-addressed store, hash-verified

138 return bytes(res)
139
140 def _standard_cmd_write(self, cmd: int, cmd_param: int = 0, data: bytes = b'\x00', dataLen: int = -1):
141 """
142 Sends a "standard CMD write" packet
143
144 :param cmd: 2 byte CMD code
145 :param cmd_param: 4 byte parameter that gets sent together with CMD (for spi_* commands, the address needs to be passed in as big-endian)
146 :param data: payload
147 :param dataLen: payload length
148 """
149 if dataLen == -1:
150 dataLen = len(data)
151
152 cmd_param = struct.unpack('<I', struct.pack('>I', cmd_param))[0] # switch endinanness
153
154 # If there is no payload, send the 8 byte command immediately
155 if (dataLen == 0 or data == b'\x00'):
156 # send 1d00 with cmd
157 d = struct.pack("<H", cmd)
158 d += struct.pack(">I2x", cmd_param)
159 log.debug(f's_cmd_w {0x1d00:#x} ({len(d):2}) {d.hex()}')
160 self._dev.ctrl_transfer(0x41, 0x45, 0x78, 0x1d00, d)
161 self._block_until_camera_ready()
162 return
163
164 outer_chunk_size = 0x100
165 inner_chunk_size = 0x40
166
167 # A "camera command" can be 256 bytes long max, but we can split the data and
168 # send more with an incremented address parameter (only spi_read/write actually uses that afaik)
169 # (adress parameter is big endian, but others are either little endian or only one byte in initial_data[2])
170 for i in range(0, dataLen, outer_chunk_size):
171 outer_chunk = data[i:i+outer_chunk_size]
172
173 # Send initial "camera command"
174 initial_data = struct.pack("<H", cmd)
175 initial_data += struct.pack(">IH", cmd_param + i, len(outer_chunk))
176 log.debug(f's_cmd_w {0x9d00:#x} ({len(initial_data):2}) {initial_data.hex()}')
177 self._dev.ctrl_transfer(0x41, 0x45, 0x78, 0x9d00, initial_data)
178 self._block_until_camera_ready()
179
180 # Each vendor control transfer can be 64 bytes max. Split up and send with incrementing wIndex value
181 for j in range(0, len(outer_chunk), inner_chunk_size):
182 inner_chunk = outer_chunk[j:j+inner_chunk_size]
183 to_send = len(outer_chunk) - j
184
185 # The logic for splitting up long vendor requests is a bit weird
186 # I just reimplemented it like Infiray did according to the USB trace. Don't want to cause unnecessary problems
187 if (to_send <= 8):
188 log.debug(f's_cmd_w {(0x1d08 + j):#x} ({len(inner_chunk):2}) {inner_chunk.hex()}')
189 self._dev.ctrl_transfer(0x41, 0x45, 0x78, 0x1d08 + j, inner_chunk)
190 self._block_until_camera_ready()
191 elif (to_send <= 64):
192 log.debug(f's_cmd_w {(0x9d08 + j):#x} ({len(inner_chunk[:-8]):2}) {inner_chunk[:-8].hex()}')
193 log.debug(
194 f's_cmd_w {(0x1d08 + j + to_send - 8):#x} ({len(inner_chunk[-8:]):2}) {inner_chunk[-8:].hex()}')
195 self._dev.ctrl_transfer(0x41, 0x45, 0x78, 0x9d08 + j, inner_chunk[:-8])
196 self._dev.ctrl_transfer(0x41, 0x45, 0x78, 0x1d08 + j + to_send - 8, inner_chunk[-8:])
197 self._block_until_camera_ready()

Callers 1

pseudo_color_setMethod · 0.95

Calls 1

Tested by

no test coverage detected