_27cxxx.py 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. """
  2. # TOP2049 Open Source programming suite
  3. #
  4. # 27c16dip28 UV/OTP EPROM
  5. # 27c32dip28 UV/OTP EPROM
  6. # 27c64dip28 UV/OTP EPROM
  7. # 27c128dip28 UV/OTP EPROM
  8. # 27c256dip28 UV/OTP EPROM
  9. # 27c512dip28 UV/OTP EPROM
  10. # Various manufacturers
  11. #
  12. # Copyright (c) 2012 Michael Buesch <m@bues.ch>
  13. #
  14. # This program is free software; you can redistribute it and/or modify
  15. # it under the terms of the GNU General Public License as published by
  16. # the Free Software Foundation; either version 2 of the License, or
  17. # (at your option) any later version.
  18. #
  19. # This program is distributed in the hope that it will be useful,
  20. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. # GNU General Public License for more details.
  23. #
  24. # You should have received a copy of the GNU General Public License along
  25. # with this program; if not, write to the Free Software Foundation, Inc.,
  26. # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  27. """
  28. from libtoprammer.chip import *
  29. from libtoprammer.util import *
  30. class Chip_27cXXX(Chip):
  31. "Generic 27cXXX EPROM"
  32. CTYPE_16 = 0
  33. CTYPE_32 = 1
  34. CTYPE_64 = 2
  35. CTYPE_128 = 3
  36. CTYPE_256 = 4
  37. CTYPE_512 = 5
  38. # Chip sizes (in bytes)
  39. ctype2size = {
  40. CTYPE_16 : 16 * 1024 // 8,
  41. CTYPE_32 : 32 * 1024 // 8,
  42. CTYPE_64 : 64 * 1024 // 8,
  43. CTYPE_128 : 128 * 1024 // 8,
  44. CTYPE_256 : 256 * 1024 // 8,
  45. CTYPE_512 : 512 * 1024 // 8,
  46. }
  47. # Programming voltages
  48. vppTable = {
  49. CTYPE_16 : 12.75,
  50. CTYPE_32 : 12.75,
  51. CTYPE_64 : 12.75,
  52. CTYPE_128 : 12.75,
  53. CTYPE_256 : 12.75,
  54. CTYPE_512 : 12.75,
  55. }
  56. # Programming pulse lengths (in microseconds)
  57. ppulseLengths = {
  58. CTYPE_16 : 1000,
  59. CTYPE_32 : 1000,
  60. CTYPE_64 : 1000,
  61. CTYPE_128 : 1000,
  62. CTYPE_256 : 500,
  63. CTYPE_512 : 500,
  64. }
  65. # Can we read the chip with VPP enabled?
  66. readWithVPP = {
  67. CTYPE_16 : True,
  68. CTYPE_32 : False, # VPP is shared with OE
  69. CTYPE_64 : True,
  70. CTYPE_128 : True,
  71. CTYPE_256 : True,
  72. CTYPE_512 : False, # VPP is shared with OE
  73. }
  74. # Chips that need overprogramming pulse.
  75. # This may not be true for all manufacturers.
  76. # Let the user set the chip option 'overprogram_pulse' in that case.
  77. needOverprogram = {
  78. CTYPE_16 : True,
  79. CTYPE_32 : True,
  80. CTYPE_64 : True,
  81. CTYPE_128 : True,
  82. CTYPE_256 : True,
  83. CTYPE_512 : False,
  84. }
  85. def __init__(self, chipType,
  86. chipPinVCC, chipPinVPP, chipPinGND):
  87. Chip.__init__(self, chipPackage = "DIP28",
  88. chipPinVCC = chipPinVCC,
  89. chipPinsVPP = chipPinVPP,
  90. chipPinGND = chipPinGND)
  91. self.chipType = chipType
  92. self.generic = GenericAlgorithms(self)
  93. self.addrSetter = AddrSetter(self, 0, 1)
  94. def readEEPROM(self):
  95. self.__turnOn()
  96. return self.generic.simpleReadEPROM(
  97. sizeBytes = self.ctype2size[self.chipType],
  98. readData8Func = self.__dataRead,
  99. addrSetter = self.addrSetter,
  100. initFunc = lambda: self.__setFlags(oe=0, ce=0),
  101. exitFunc = lambda: self.__setFlags(oe=1, ce=1)
  102. )
  103. def writeEEPROM(self, image):
  104. sizeBytes = self.ctype2size[self.chipType]
  105. if len(image) > sizeBytes:
  106. self.throwError("Invalid image size. "
  107. "Got %d bytes, but EPROM is only %d bytes." %\
  108. (len(image), sizeBytes))
  109. # Get the options
  110. immediateVerify = self.getChipOptionValue(
  111. "immediate_verify",
  112. self.readWithVPP[self.chipType])
  113. overprogram = self.getChipOptionValue(
  114. "overprogram_pulse",
  115. self.needOverprogram[self.chipType])
  116. vppVolt = self.getChipOptionValue(
  117. "vpp_voltage",
  118. self.vppTable[self.chipType])
  119. progpulseUsec = self.getChipOptionValue(
  120. "ppulse_length",
  121. self.ppulseLengths[self.chipType])
  122. # Run the write algorithm
  123. self.__writeAlgo(image, vppVolt, immediateVerify, overprogram,
  124. progpulseUsec)
  125. def __writeAlgo(self, image, vppVolt, immediateVerify, overprogramPulse,
  126. progpulseUsec):
  127. self.printInfo("Using %.2f VPP" % vppVolt)
  128. self.printInfo("Using %s verify." %\
  129. ("immediate" if immediateVerify else "detached"))
  130. if immediateVerify and not self.readWithVPP[self.chipType]:
  131. self.printWarning("Immediate verify will be slow "
  132. "on this chip!")
  133. self.printInfo("%s overprogramming pulse." %\
  134. ("Using" if overprogramPulse else "Not using"))
  135. if not immediateVerify and overprogramPulse:
  136. self.printWarning("Using overprogramming, but no "
  137. "immediate verify. This probably is NOT what "
  138. "you intended.")
  139. self.printInfo("Using ppulse length: %d microseconds" %\
  140. progpulseUsec)
  141. self.__turnOn()
  142. self.addrSetter.reset()
  143. self.applyVPP(False)
  144. self.top.cmdSetVPPVoltage(vppVolt)
  145. okMask = [ False ] * len(image)
  146. nrRetries = 25
  147. for retry in range(0, nrRetries):
  148. # Program
  149. self.progressMeterInit("Writing EPROM", len(image))
  150. self.__setFlags(data_en=1, prog_en=1, ce=0, oe=1)
  151. self.applyVPP(True)
  152. for addr in range(0, len(image)):
  153. self.progressMeter(addr)
  154. if okMask[addr]:
  155. continue
  156. data = byte2int(image[addr])
  157. if data == 0xFF:
  158. okMask[addr] = True
  159. else:
  160. self.__writeByte(addr, data,
  161. immediateVerify, overprogramPulse,
  162. progpulseUsec)
  163. self.applyVPP(False)
  164. self.__setFlags(data_en=0, prog_en=0, ce=0, oe=0)
  165. self.progressMeterFinish()
  166. if immediateVerify:
  167. break
  168. if all(okMask):
  169. break
  170. # Detached verify
  171. readImage = self.generic.simpleReadEPROM(
  172. sizeBytes = len(image),
  173. readData8Func = self.__dataRead,
  174. addrSetter = self.addrSetter,
  175. initFunc = lambda: self.__setFlags(oe=0, ce=0),
  176. exitFunc = lambda: self.__setFlags(oe=1, ce=1)
  177. )
  178. for addr in range(0, len(image)):
  179. if okMask[addr]:
  180. continue
  181. if image[addr] == readImage[addr]:
  182. okMask[addr] = True
  183. if all(okMask):
  184. break
  185. self.printInfo("%d of %d bytes failed verification. "
  186. "Retrying those bytes..." %\
  187. (len([ ok for ok in okMask if ok]),
  188. len(okMask)))
  189. else:
  190. self.throwError("Failed to write EPROM. "
  191. "Tried %d times." % nrRetries)
  192. self.__setFlags()
  193. self.top.cmdSetVPPVoltage(5)
  194. def __writeByte(self, addr, data,
  195. doVerify, doOverprogram, progpulseUsec):
  196. self.addrSetter.load(addr)
  197. self.__setDataPins(data)
  198. for retry in range(0, 25):
  199. self.__progPulse(progpulseUsec)
  200. if not doVerify:
  201. break
  202. # Immediate verify
  203. if not self.readWithVPP[self.chipType]:
  204. self.applyVPP(False)
  205. self.__setFlags(data_en=0, prog_en=0, ce=0, oe=0)
  206. readData = self.__readByte(addr)
  207. self.__setFlags(data_en=1, prog_en=1, ce=0, oe=1)
  208. if not self.readWithVPP[self.chipType]:
  209. self.applyVPP(True)
  210. if readData == data:
  211. break
  212. else:
  213. self.throwError("Failed to write EPROM address %d" % addr)
  214. if doOverprogram:
  215. self.addrSetter.load(addr)
  216. self.__progPulse(progpulseUsec * 3 * (retry + 1))
  217. def __readByte(self, addr):
  218. self.addrSetter.load(addr)
  219. self.__dataRead()
  220. return self.top.cmdReadBufferReg8()
  221. def __turnOn(self):
  222. self.__setType(self.chipType)
  223. self.__setFlags()
  224. self.generic.simpleVoltageSetup()
  225. def __setDataPins(self, value):
  226. self.top.cmdFPGAWrite(2, value)
  227. def __setFlags(self, data_en=0, prog_en=0, ce=1, oe=1):
  228. value = 0
  229. if data_en:
  230. value |= (1 << 0)
  231. if prog_en:
  232. value |= (1 << 1)
  233. if ce:
  234. value |= (1 << 2)
  235. if oe:
  236. value |= (1 << 3)
  237. self.top.cmdFPGAWrite(3, value)
  238. def __progPulse(self, usec):
  239. value = roundup(usec, 100) // 100
  240. if value > 0x7F:
  241. value = roundup(value, 8) // 8
  242. if value > 0x7F:
  243. self.throwError("__progPulse time too big")
  244. value |= 0x80 # Set "times 8" multiplier
  245. self.top.cmdFPGAWrite(4, value)
  246. seconds = float(value & 0x7F) / 10000
  247. if value & 0x80:
  248. seconds *= 8
  249. self.top.cmdDelay(seconds)
  250. self.top.flushCommands()
  251. def __setType(self, typeNumber):
  252. self.top.cmdFPGAWrite(5, typeNumber)
  253. def __dataRead(self):
  254. self.top.cmdFPGARead(0)
  255. class ChipDescription_27cXXX(ChipDescription):
  256. "Generic 27cXXX ChipDescription"
  257. def __init__(self, chipImplClass, name):
  258. ChipDescription.__init__(self,
  259. chipImplClass = chipImplClass,
  260. bitfile = "_27cxxxdip28",
  261. chipID = name,
  262. runtimeID = (12, 1),
  263. chipType = ChipDescription.TYPE_EPROM,
  264. chipVendors = "Various",
  265. description = name + " EPROM",
  266. packages = ( ("DIP28", ""), ),
  267. chipOptions = (
  268. ChipOptionBool("immediate_verify",
  269. "Immediately verify each written byte"),
  270. ChipOptionBool("overprogram_pulse",
  271. "Perform an 'overprogramming' pulse"),
  272. ChipOptionFloat("vpp_voltage",
  273. "Override the default VPP voltage",
  274. minVal=10.0, maxVal=14.0),
  275. ChipOptionInt("ppulse_length",
  276. "Force 'Programming pulse' length, in microseconds.",
  277. minVal=100, maxVal=10000),
  278. )
  279. )
  280. class Chip_27c16(Chip_27cXXX):
  281. def __init__(self):
  282. Chip_27cXXX.__init__(self,
  283. chipType = Chip_27cXXX.CTYPE_16,
  284. chipPinVCC = 26,
  285. chipPinVPP = 23,
  286. chipPinGND = 14)
  287. ChipDescription_27cXXX(Chip_27c16, "27c16")
  288. class Chip_27c32(Chip_27cXXX):
  289. def __init__(self):
  290. Chip_27cXXX.__init__(self,
  291. chipType = Chip_27cXXX.CTYPE_32,
  292. chipPinVCC = 26,
  293. chipPinVPP = 22,
  294. chipPinGND = 14)
  295. ChipDescription_27cXXX(Chip_27c32, "27c32")
  296. class Chip_27c64(Chip_27cXXX):
  297. def __init__(self):
  298. Chip_27cXXX.__init__(self,
  299. chipType = Chip_27cXXX.CTYPE_64,
  300. chipPinVCC = 28,
  301. chipPinVPP = 1,
  302. chipPinGND = 14)
  303. ChipDescription_27cXXX(Chip_27c64, "27c64")
  304. class Chip_27c128(Chip_27cXXX):
  305. def __init__(self):
  306. Chip_27cXXX.__init__(self,
  307. chipType = Chip_27cXXX.CTYPE_128,
  308. chipPinVCC = 28,
  309. chipPinVPP = 1,
  310. chipPinGND = 14)
  311. ChipDescription_27cXXX(Chip_27c128, "27c128")
  312. class Chip_27c256(Chip_27cXXX):
  313. def __init__(self):
  314. Chip_27cXXX.__init__(self,
  315. chipType = Chip_27cXXX.CTYPE_256,
  316. chipPinVCC = 28,
  317. chipPinVPP = 1,
  318. chipPinGND = 14)
  319. ChipDescription_27cXXX(Chip_27c256, "27c256")
  320. class Chip_27c512(Chip_27cXXX):
  321. def __init__(self):
  322. Chip_27cXXX.__init__(self,
  323. chipType = Chip_27cXXX.CTYPE_512,
  324. chipPinVCC = 28,
  325. chipPinVPP = 22,
  326. chipPinGND = 14)
  327. ChipDescription_27cXXX(Chip_27c512, "27c512")