generic_algorithms.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. """
  2. # TOP2049 Open Source programming suite
  3. #
  4. # Generic programming algorithms
  5. #
  6. # Copyright (c) 2012 Michael Buesch <m@bues.ch>
  7. #
  8. # This program is free software; you can redistribute it and/or modify
  9. # it under the terms of the GNU General Public License as published by
  10. # the Free Software Foundation; either version 2 of the License, or
  11. # (at your option) any later version.
  12. #
  13. # This program is distributed in the hope that it will be useful,
  14. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. # GNU General Public License for more details.
  17. #
  18. # You should have received a copy of the GNU General Public License along
  19. # with this program; if not, write to the Free Software Foundation, Inc.,
  20. # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  21. """
  22. from util import *
  23. class AddrSetter(object):
  24. """Generic address setter"""
  25. def __init__(self, chip,
  26. fpgaCmdByte0,
  27. fpgaCmdByte1 = -1,
  28. fpgaCmdByte2 = -1,
  29. fpgaCmdByte3 = -1,
  30. addrSetupFunc = lambda byteNr, data: None,
  31. addrFinishFunc = lambda byteNr, data: None):
  32. """
  33. chip => The Chip.
  34. fpgaCmdByte0 => FPGA command number for setting addr byte 0.
  35. fpgaCmdByte1 => FPGA command number for setting addr byte 1.
  36. fpgaCmdByte2 => FPGA command number for setting addr byte 2.
  37. fpgaCmdByte3 => FPGA command number for setting addr byte 3.
  38. addrSetupFunc => Optional function called before addr write.
  39. addrFinishFunc => Optional function called after addr write.
  40. """
  41. self.chip = chip
  42. self.fpgaCmds = [
  43. fpgaCmdByte0,
  44. fpgaCmdByte1,
  45. fpgaCmdByte2,
  46. fpgaCmdByte3,
  47. ]
  48. self.addrSetupFunc = addrSetupFunc
  49. self.addrFinishFunc = addrFinishFunc
  50. self.reset()
  51. def reset(self):
  52. self.prevAddr = None
  53. def load(self, addr):
  54. """Load an address into the FPGA.
  55. This loads only the bytes that changed."""
  56. shifts = (0, 8, 16, 24)
  57. for byteNr, shift in enumerate(shifts):
  58. fpgaCmd = self.fpgaCmds[byteNr]
  59. if fpgaCmd < 0:
  60. continue
  61. addrByte = (addr >> shift) & 0xFF
  62. if self.prevAddr is None or\
  63. ((self.prevAddr >> shift) & 0xFF) != addrByte:
  64. self.addrSetupFunc(byteNr, addrByte)
  65. self.chip.top.cmdFPGAWrite(fpgaCmd, addrByte)
  66. self.addrFinishFunc(byteNr, addrByte)
  67. self.prevAddr = addr
  68. class GenericAlgorithms(object):
  69. """Generic programming algorithms."""
  70. def __init__(self, chip):
  71. self.chip = chip
  72. def simpleVoltageSetup(self, vcc=5.0, vpp=5.0, vppEnable=False):
  73. """Simple voltage setup."""
  74. self.chip.top.cmdSetVCCVoltage(vcc)
  75. self.chip.top.cmdSetVPPVoltage(vpp)
  76. self.chip.applyVCC(True)
  77. self.chip.applyGND(True)
  78. self.chip.applyVPP(vppEnable)
  79. def simpleVoltageShutdown(self):
  80. """Turn off voltages."""
  81. self.chip.applyVCC(False)
  82. self.chip.applyVPP(False)
  83. self.chip.applyGND(False)
  84. self.chip.top.cmdSetVCCVoltage(self.chip.top.vcc.minVoltage())
  85. self.chip.top.cmdSetVPPVoltage(self.chip.top.vpp.minVoltage())
  86. def simpleRead(self, name, sizeBytes,
  87. readData8Func,
  88. addrSetter,
  89. initFunc = lambda: None,
  90. exitFunc = lambda: None):
  91. """Simple 8-bit data read algorithm."""
  92. self.chip.progressMeterInit("Reading %s" % name, sizeBytes)
  93. image, count = [], 0
  94. initFunc()
  95. addrSetter.reset()
  96. for addr in range(0, sizeBytes):
  97. self.chip.progressMeter(addr)
  98. addrSetter.load(addr)
  99. readData8Func()
  100. count += 1
  101. if count == self.chip.top.getBufferRegSize():
  102. image.append(self.chip.top.cmdReadBufferReg())
  103. count = 0
  104. if count:
  105. image.append(self.chip.top.cmdReadBufferReg()[:count])
  106. exitFunc()
  107. self.chip.progressMeterFinish()
  108. return b"".join(image)
  109. def simpleReadEPROM(self, sizeBytes,
  110. readData8Func,
  111. addrSetter,
  112. initFunc = lambda: None,
  113. exitFunc = lambda: None):
  114. return self.simpleRead("EPROM", sizeBytes, readData8Func,
  115. addrSetter, initFunc, exitFunc)
  116. def simpleReadEEPROM(self, sizeBytes,
  117. readData8Func,
  118. addrSetter,
  119. initFunc = lambda: None,
  120. exitFunc = lambda: None):
  121. return self.simpleRead("EEPROM", sizeBytes, readData8Func,
  122. addrSetter, initFunc, exitFunc)
  123. def simpleTest(self, readFunc, writeFunc, size):
  124. """Simple Unit-test."""
  125. image = genRandomBlob(size)
  126. writeFunc(image)
  127. if readFunc() != image:
  128. self.chip.throwError("Unit-test failed. "
  129. "The chip may be physically broken.")