pyopenmv.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. #!/usr/bin/env python2
  2. # This file is part of the OpenMV project.
  3. #
  4. # Copyright (c) 2013-2019 Ibrahim Abdelkader <iabdalkader@openmv.io>
  5. # Copyright (c) 2013-2019 Kwabena W. Agyeman <kwagyeman@openmv.io>
  6. #
  7. # This work is licensed under the MIT license, see the file LICENSE for details.
  8. #
  9. # Openmv module.
  10. import struct
  11. import sys,time
  12. import serial
  13. import platform
  14. import numpy as np
  15. from PIL import Image
  16. __serial = None
  17. __FB_HDR_SIZE =12
  18. # USB Debug commands
  19. __USBDBG_CMD = 48
  20. __USBDBG_FW_VERSION = 0x80
  21. __USBDBG_FRAME_SIZE = 0x81
  22. __USBDBG_FRAME_DUMP = 0x82
  23. __USBDBG_ARCH_STR = 0x83
  24. __USBDBG_SCRIPT_EXEC = 0x05
  25. __USBDBG_SCRIPT_STOP = 0x06
  26. __USBDBG_SCRIPT_SAVE = 0x07
  27. __USBDBG_SCRIPT_RUNNING = 0x87
  28. __USBDBG_TEMPLATE_SAVE = 0x08
  29. __USBDBG_DESCRIPTOR_SAVE= 0x09
  30. __USBDBG_ATTR_READ = 0x8A
  31. __USBDBG_ATTR_WRITE = 0x0B
  32. __USBDBG_SYS_RESET = 0x0C
  33. __USBDBG_FB_ENABLE = 0x0D
  34. __USBDBG_TX_BUF_LEN = 0x8E
  35. __USBDBG_TX_BUF = 0x8F
  36. ATTR_CONTRAST =0
  37. ATTR_BRIGHTNESS =1
  38. ATTR_SATURATION =2
  39. ATTR_GAINCEILING=3
  40. __BOOTLDR_START = 0xABCD0001
  41. __BOOTLDR_RESET = 0xABCD0002
  42. __BOOTLDR_ERASE = 0xABCD0004
  43. __BOOTLDR_WRITE = 0xABCD0008
  44. def init(port, baudrate=921600, timeout=0.3):
  45. global __serial
  46. # open CDC port
  47. __serial = serial.Serial(port, baudrate=baudrate, timeout=timeout)
  48. def disconnect():
  49. global __serial
  50. try:
  51. if (__serial):
  52. __serial.close()
  53. __serial = None
  54. except:
  55. pass
  56. def set_timeout(timeout):
  57. __serial.timeout = timeout
  58. def fb_size():
  59. # read fb header
  60. __serial.write(struct.pack("<BBI", __USBDBG_CMD, __USBDBG_FRAME_SIZE, __FB_HDR_SIZE))
  61. return struct.unpack("III", __serial.read(12))
  62. def fb_dump():
  63. size = fb_size()
  64. if (not size[0]):
  65. # frame not ready
  66. return None
  67. if (size[2] > 2): #JPEG
  68. num_bytes = size[2]
  69. else:
  70. num_bytes = size[0]*size[1]*size[2]
  71. # read fb data
  72. __serial.write(struct.pack("<BBI", __USBDBG_CMD, __USBDBG_FRAME_DUMP, num_bytes))
  73. buff = __serial.read(num_bytes)
  74. if size[2] == 1: # Grayscale
  75. y = np.fromstring(buff, dtype=np.uint8)
  76. buff = np.column_stack((y, y, y))
  77. elif size[2] == 2: # RGB565
  78. arr = np.fromstring(buff, dtype=np.uint16).newbyteorder('S')
  79. r = (((arr & 0xF800) >>11)*255.0/31.0).astype(np.uint8)
  80. g = (((arr & 0x07E0) >>5) *255.0/63.0).astype(np.uint8)
  81. b = (((arr & 0x001F) >>0) *255.0/31.0).astype(np.uint8)
  82. buff = np.column_stack((r,g,b))
  83. else: # JPEG
  84. try:
  85. buff = np.asarray(Image.frombuffer("RGB", size[0:2], buff, "jpeg", "RGB", ""))
  86. except Exception as e:
  87. print ("JPEG decode error (%s)"%(e))
  88. return None
  89. if (buff.size != (size[0]*size[1]*3)):
  90. return None
  91. return (size[0], size[1], buff.reshape((size[1], size[0], 3)))
  92. def exec_script(buf):
  93. __serial.write(struct.pack("<BBI", __USBDBG_CMD, __USBDBG_SCRIPT_EXEC, len(buf)))
  94. __serial.write(buf.encode())
  95. def stop_script():
  96. __serial.write(struct.pack("<BBI", __USBDBG_CMD, __USBDBG_SCRIPT_STOP, 0))
  97. def script_running():
  98. __serial.write(struct.pack("<BBI", __USBDBG_CMD, __USBDBG_SCRIPT_RUNNING, 4))
  99. return struct.unpack("I", __serial.read(4))[0]
  100. def save_template(x, y, w, h, path):
  101. buf = struct.pack("IIII", x, y, w, h) + path
  102. __serial.write(struct.pack("<BBI", __USBDBG_CMD, __USBDBG_TEMPLATE_SAVE, len(buf)))
  103. __serial.write(buf)
  104. def save_descriptor(x, y, w, h, path):
  105. buf = struct.pack("HHHH", x, y, w, h) + path
  106. __serial.write(struct.pack("<BBI", __USBDBG_CMD, __USBDBG_DESCRIPTOR_SAVE, len(buf)))
  107. __serial.write(buf)
  108. def set_attr(attr, value):
  109. __serial.write(struct.pack("<BBI", __USBDBG_CMD, __USBDBG_ATTR_WRITE, 8))
  110. __serial.write(struct.pack("<II", attr, value))
  111. def get_attr(attr):
  112. __serial.write(struct.pack("<BBIh", __USBDBG_CMD, __USBDBG_ATTR_READ, 1, attr))
  113. return __serial.read(1)
  114. def reset():
  115. __serial.write(struct.pack("<BBI", __USBDBG_CMD, __USBDBG_SYS_RESET, 0))
  116. def bootloader_start():
  117. __serial.write(struct.pack("<I", __BOOTLDR_START))
  118. return struct.unpack("I", __serial.read(4))[0] == __BOOTLDR_START
  119. def bootloader_reset():
  120. __serial.write(struct.pack("<I", __BOOTLDR_RESET))
  121. def flash_erase(sector):
  122. __serial.write(struct.pack("<II", __BOOTLDR_ERASE, sector))
  123. def flash_write(buf):
  124. __serial.write(struct.pack("<I", __BOOTLDR_WRITE) + buf)
  125. def tx_buf_len():
  126. __serial.write(struct.pack("<BBI", __USBDBG_CMD, __USBDBG_TX_BUF_LEN, 4))
  127. return struct.unpack("I", __serial.read(4))[0]
  128. def tx_buf(bytes):
  129. __serial.write(struct.pack("<BBI", __USBDBG_CMD, __USBDBG_TX_BUF, bytes))
  130. return __serial.read(bytes)
  131. def fw_version():
  132. __serial.write(struct.pack("<BBI", __USBDBG_CMD, __USBDBG_FW_VERSION, 12))
  133. return struct.unpack("III", __serial.read(12))
  134. def enable_fb(enable):
  135. __serial.write(struct.pack("<BBI", __USBDBG_CMD, __USBDBG_FB_ENABLE, 4))
  136. __serial.write(struct.pack("<I", enable))
  137. def arch_str():
  138. __serial.write(struct.pack("<BBI", __USBDBG_CMD, __USBDBG_ARCH_STR, 64))
  139. return __serial.read(64).split('\0', 1)[0]
  140. if __name__ == '__main__':
  141. if len(sys.argv)!= 3:
  142. print ('usage: pyopenmv.py <port> <script>')
  143. sys.exit(1)
  144. with open(sys.argv[2], 'r') as fin:
  145. buf = fin.read()
  146. disconnect()
  147. init(sys.argv[1])
  148. stop_script()
  149. exec_script(buf)
  150. tx_len = tx_buf_len()
  151. time.sleep(0.250)
  152. if (tx_len):
  153. print(tx_buf(tx_len).decode())
  154. disconnect()