xusbcom.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. # NOTE: This script is test under Python 3.x
  2. __copyright__ = "Copyright (C) 2020~2021 Nuvoton Technology Corp. All rights reserved"
  3. import sys
  4. import usb.core
  5. import usb.util
  6. import json
  7. import typing
  8. XFER_LEN_CMD = 0x0012
  9. GET_INFO_CMD = 0x0005
  10. class XUsbCom:
  11. def __init__(self, _dev):
  12. self.dev = _dev
  13. self.write_addr = 0x1
  14. self.read_addr = 0x81
  15. self.attach = False
  16. self.id = 0
  17. self.info = b''
  18. def write(self, data) -> None:
  19. try:
  20. # Vendor command set transfer length
  21. self.dev.ctrl_transfer(0x40, 0xA0, wValue=XFER_LEN_CMD, wIndex=len(data), data_or_wLength='')
  22. # Actual data
  23. self.dev.write(self.write_addr, data, timeout=1000)
  24. except usb.core.USBError as err:
  25. sys.exit(err)
  26. def read(self, size) -> bytes:
  27. try:
  28. buf = self.dev.read(self.read_addr, size, timeout=1000)
  29. except usb.core.USBError as err:
  30. sys.exit(err)
  31. return buf
  32. def set_media(self, media) -> None:
  33. try:
  34. # Vendor command set type
  35. self.dev.ctrl_transfer(0x40, 0xB0, wValue=media, wIndex=0, data_or_wLength='')
  36. except usb.core.USBError as err:
  37. sys.exit(err)
  38. return
  39. def get_info(self, data) -> bytes:
  40. try:
  41. self.dev.ctrl_transfer(0x40, 0xB0, wValue=GET_INFO_CMD, wIndex=0, data_or_wLength='')
  42. self.dev.ctrl_transfer(0x40, 0xA0, wValue=XFER_LEN_CMD, wIndex=76, data_or_wLength='')
  43. self.dev.write(0x01, data, timeout=1000)
  44. self.info = self.dev.read(0x81, 76, timeout=1000)
  45. # not used
  46. self.dev.read(0x81, 4, timeout=5000)
  47. except usb.core.USBError as err:
  48. sys.exit(err)
  49. return self.info
  50. def set_id(self, i) -> None:
  51. self.id = i
  52. def get_id(self) -> int:
  53. return self.id
  54. @staticmethod
  55. def set_align(nand, spinand) -> None:
  56. # See if we need to overwrite existing json file.
  57. overwrite = False
  58. try:
  59. with open(".config", "r") as json_file:
  60. cfg = json.load(json_file)
  61. for key in cfg.keys():
  62. if key == 'nand_align':
  63. if nand != int(cfg['nand_align']):
  64. overwrite = True
  65. elif key == 'spinand_align':
  66. if spinand != int(cfg['spinand_align']):
  67. overwrite = True
  68. except (IOError, OSError, json.decoder.JSONDecodeError) as err:
  69. overwrite = True
  70. if overwrite is True:
  71. try:
  72. with open(".config", "w+") as json_file:
  73. new_key = {'nand_align': nand, 'spinand_align': spinand}
  74. json.dump(new_key, json_file)
  75. except (IOError, OSError) as err:
  76. print("Write .config failed. Please re-attach")
  77. sys.exit(err)
  78. @staticmethod
  79. def get_align() -> typing.Tuple[int, int]:
  80. try:
  81. with open(".config", "r") as json_file:
  82. cfg = json.load(json_file)
  83. except (IOError, OSError, json.decoder.JSONDecodeError) as err:
  84. print("Open/parsing .config failed. Please re-attach")
  85. sys.exit(err)
  86. nand_align = spinand_align = 0
  87. for key in cfg.keys():
  88. if key == 'nand_align':
  89. nand_align = int(cfg['nand_align'])
  90. elif key == 'spinand_align':
  91. spinand_align = int(cfg['spinand_align'])
  92. return nand_align, spinand_align
  93. class XUsbComList:
  94. def __init__(self, attach_all=False):
  95. vid = 0x0416
  96. pid = 0x5963
  97. try:
  98. self.devices = list(usb.core.find(idVendor=vid, idProduct=pid,
  99. find_all=True if attach_all is True else False))
  100. except TypeError:
  101. # list will raise exception if there's no device
  102. self.devices = []
  103. return
  104. except usb.core.NoBackendError as err:
  105. sys.exit(err)
  106. if len(self.devices) != 0 and attach_all is False:
  107. # Object type return on attach_all == False is different
  108. self.devices[0] = self.devices[0].device
  109. for dev in self.devices:
  110. try:
  111. dev.set_configuration()
  112. except (usb.core.USBError, NotImplementedError) as err:
  113. sys.exit(err)
  114. for i in range(0, len(self.devices)):
  115. self.devices[i] = XUsbCom(self.devices[i])
  116. self.devices[i].set_id(i)
  117. def __del__(self):
  118. if len(self.devices) != 0:
  119. for dev in self.devices:
  120. try:
  121. usb.util.dispose_resources(dev.dev)
  122. # dev.dev.reset()
  123. dev = None
  124. #except (usb.core.USBError, NotImplementedError) as err:
  125. except usb.core.USBError as err:
  126. sys.exit(err)
  127. self.devices = None
  128. def get_dev(self):
  129. return self.devices