Permalink
Browse files

initial checkin including test setup for becky's knitting machine and

code for converting qr codes
  • Loading branch information...
0 parents commit febe4fcb72f2a65d346615df2148a06303a17d41 @brianredbeard brianredbeard committed Oct 16, 2010
Showing with 1,718 additions and 0 deletions.
  1. +633 −0 PDDemu-debug.py
  2. +633 −0 PDDemulate-1.0.py
  3. +352 −0 brother.py
  4. BIN brother.pyc
  5. +59 −0 dumppattern.py
  6. BIN img/00.dat
  7. BIN img/00.id
  8. BIN img/01.dat
  9. BIN img/01.id
  10. BIN img/02.dat
  11. BIN img/02.id
  12. BIN img/03.dat
  13. BIN img/03.id
  14. BIN img/04.dat
  15. BIN img/04.id
  16. BIN img/05.dat
  17. BIN img/05.id
  18. BIN img/06.dat
  19. BIN img/06.id
  20. BIN img/07.dat
  21. BIN img/07.id
  22. BIN img/08.dat
  23. BIN img/08.id
  24. BIN img/09.dat
  25. BIN img/09.id
  26. BIN img/10.dat
  27. BIN img/10.id
  28. BIN img/11.dat
  29. BIN img/11.id
  30. BIN img/12.dat
  31. BIN img/12.id
  32. BIN img/13.dat
  33. BIN img/13.id
  34. BIN img/14.dat
  35. BIN img/14.id
  36. BIN img/15.dat
  37. BIN img/15.id
  38. BIN img/16.dat
  39. BIN img/16.id
  40. BIN img/17.dat
  41. BIN img/17.id
  42. BIN img/18.dat
  43. BIN img/18.id
  44. BIN img/19.dat
  45. BIN img/19.id
  46. BIN img/20.dat
  47. BIN img/20.id
  48. BIN img/21.dat
  49. BIN img/21.id
  50. BIN img/22.dat
  51. BIN img/22.id
  52. BIN img/23.dat
  53. BIN img/23.id
  54. BIN img/24.dat
  55. BIN img/24.id
  56. BIN img/25.dat
  57. BIN img/25.id
  58. BIN img/26.dat
  59. BIN img/26.id
  60. BIN img/27.dat
  61. BIN img/27.id
  62. BIN img/28.dat
  63. BIN img/28.id
  64. BIN img/29.dat
  65. BIN img/29.id
  66. BIN img/30.dat
  67. BIN img/30.id
  68. BIN img/31.dat
  69. BIN img/31.id
  70. BIN img/32.dat
  71. BIN img/32.id
  72. BIN img/33.dat
  73. BIN img/33.id
  74. BIN img/34.dat
  75. BIN img/34.id
  76. BIN img/35.dat
  77. BIN img/35.id
  78. BIN img/36.dat
  79. BIN img/36.id
  80. BIN img/37.dat
  81. BIN img/37.id
  82. BIN img/38.dat
  83. BIN img/38.id
  84. BIN img/39.dat
  85. BIN img/39.id
  86. BIN img/40.dat
  87. BIN img/40.id
  88. BIN img/41.dat
  89. BIN img/41.id
  90. BIN img/42.dat
  91. BIN img/42.id
  92. BIN img/43.dat
  93. BIN img/43.id
  94. BIN img/44.dat
  95. BIN img/44.id
  96. BIN img/45.dat
  97. BIN img/45.id
  98. BIN img/46.dat
  99. BIN img/46.id
  100. BIN img/47.dat
  101. BIN img/47.id
  102. BIN img/48.dat
  103. BIN img/48.id
  104. BIN img/49.dat
  105. BIN img/49.id
  106. BIN img/50.dat
  107. BIN img/50.id
  108. BIN img/51.dat
  109. BIN img/51.id
  110. BIN img/52.dat
  111. BIN img/52.id
  112. BIN img/53.dat
  113. BIN img/53.id
  114. BIN img/54.dat
  115. BIN img/54.id
  116. BIN img/55.dat
  117. BIN img/55.id
  118. BIN img/56.dat
  119. BIN img/56.id
  120. BIN img/57.dat
  121. BIN img/57.id
  122. BIN img/58.dat
  123. BIN img/58.id
  124. BIN img/59.dat
  125. BIN img/59.id
  126. BIN img/60.dat
  127. BIN img/60.id
  128. BIN img/61.dat
  129. BIN img/61.id
  130. BIN img/62.dat
  131. BIN img/62.id
  132. BIN img/63.dat
  133. BIN img/63.id
  134. BIN img/64.dat
  135. BIN img/64.id
  136. BIN img/65.dat
  137. BIN img/65.id
  138. BIN img/66.dat
  139. BIN img/66.id
  140. BIN img/67.dat
  141. BIN img/67.id
  142. BIN img/68.dat
  143. BIN img/68.id
  144. BIN img/69.dat
  145. BIN img/69.id
  146. BIN img/70.dat
  147. BIN img/70.id
  148. BIN img/71.dat
  149. BIN img/71.id
  150. BIN img/72.dat
  151. BIN img/72.id
  152. BIN img/73.dat
  153. BIN img/73.id
  154. BIN img/74.dat
  155. BIN img/74.id
  156. BIN img/75.dat
  157. BIN img/75.id
  158. BIN img/76.dat
  159. BIN img/76.id
  160. BIN img/77.dat
  161. BIN img/77.id
  162. BIN img/78.dat
  163. BIN img/78.id
  164. BIN img/79.dat
  165. BIN img/79.id
  166. BIN img/file-01.dat
  167. BIN pdd_1.img
  168. BIN pdd_2.img
  169. BIN pdd_3.img
  170. +40 −0 process_image.py
  171. BIN qr_test.bmp
  172. BIN qr_test.png
  173. BIN qr_test.xcf
  174. +1 −0 test.html

Large diffs are not rendered by default.

Oops, something went wrong.

Large diffs are not rendered by default.

Oops, something went wrong.
@@ -0,0 +1,352 @@
+#!/usr/bin/env python
+
+# Copyright 2009 Steve Conklin
+# steve at conklinhouse dot com
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+import sys
+import array
+#import os
+#import os.path
+#import string
+#from array import *
+
+__version__ = '1.0'
+
+# Some file location constants
+initPatternOffset = 0x06DF # programmed patterns start here, grow down
+currentPatternAddr = 0x07EA # stored in MSN and following byte
+currentRowAddr = 0x06FF
+nextRowAddr = 0x072F
+currentRowNumberAddr = 0x0702
+carriageStatusAddr = 0x070F
+selectAddr = 0x07EA
+
+
+
+# various unknowns which are probably something we care about
+unknownList = {'0700':0x0700, '0701':0x0701,
+ '0704':0x0704, '0705':0x0705, '0706':0x0706, '0707':0x0707,
+ '0708':0x0708, '0709':0x0709, '070A':0x070A, '070B':0x070B,
+ '070C':0x070C, '070D':0x070D, '070E':0x070E, '0710':0x0710,
+ '0711':0x0711, '0712':0x0712, '0713':0x0713, '0714':0x0714,
+ '0715':0x0715}
+
+def nibbles(achar):
+ #print '0x%02X' % ord(achar)
+ msn = (ord(achar) & 0xF0) >> 4
+ lsn = ord(achar) & 0x0F
+ return msn, lsn
+
+def hto(hundreds, tens, ones):
+ return (100 * hundreds) + (10 * tens) + ones
+
+def roundeven(val):
+ return (val+(val%2))
+
+def roundeight(val):
+ if val % 8:
+ return val + (8-(val%8))
+ else:
+ return val
+
+def roundfour(val):
+ if val % 4:
+ return val + (4-(val%4))
+ else:
+ return val
+
+def nibblesPerRow(stitches):
+ # there are four stitches per nibble
+ # each row is nibble aligned
+ return(roundfour(stitches)/4)
+
+def bytesPerPattern(stitches, rows):
+ nibbs = rows * nibblesPerRow(stitches)
+ bytes = roundeven(nibbs)/2
+ return bytes
+
+def bytesForMemo(rows):
+ bytes = roundeven(rows)/2
+ return bytes
+
+def bytesPerPatternAndMemo(stitches, rows):
+ patbytes = bytesPerPattern(stitches, rows)
+ memobytes = bytesForMemo(rows)
+ return patbytes + memobytes
+
+class brotherFile(object):
+
+ def __init__(self, fn):
+ self.dfn = None
+ self.verbose = False
+ try:
+ try:
+ self.df = open(fn, 'r+')
+ except IOError:
+ # for now, read only
+ raise
+ #self.df = open(fn, 'w')
+ except:
+ print 'Unable to open brother file <%s>' % fn
+ raise
+ try:
+ self.data = self.df.read(2048)
+ self.df.close()
+ except:
+ print 'Unable to read 2048 bytes from file <%s>' % fn
+ raise
+ self.dfn = fn
+ return
+
+ def __del__(self):
+ return
+
+ def getIndexedByte(self, index):
+ return ord(self.data[index])
+
+ def getIndexedNibble(self, offset, nibble):
+ # nibbles is zero based
+ bytes = nibble/2
+ m, l = nibbles(self.data[offset-bytes])
+ if nibble % 2:
+ return m
+ else:
+ return l
+
+ def getRowData(self, pattOffset, stitches, rownumber):
+ row=array.array('B')
+ nibspr = nibblesPerRow(stitches)
+ startnib = nibspr * rownumber
+ endnib = startnib + nibspr
+
+ for i in range(startnib, endnib, 1):
+ nib = self.getIndexedNibble(pattOffset, i)
+ row.append(nib & 0x01)
+ stitches = stitches - 1
+ if stitches:
+ row.append((nib & 0x02) >> 1)
+ stitches = stitches - 1
+ if stitches:
+ row.append((nib & 0x04) >> 2)
+ stitches = stitches - 1
+ if stitches:
+ row.append((nib & 0x08) >> 3)
+ stitches = stitches - 1
+
+ return row
+
+ def getPatterns(self, patternNumber = None):
+ """
+ Get a list of custom patterns stored in the file, or
+ information for a single pattern.
+ Pattern information is stored at the beginning
+ of the file, with seven bytes per pattern and
+ 99 possible patterns, numbered 901-999.
+ Returns: A list of tuples:
+ patternNumber
+ stitches
+ rows
+ patternOffset
+ memoOffset
+ """
+ patlist = []
+ idx = 0
+ pptr = initPatternOffset
+ for pi in range(1, 100):
+ flag = ord(self.data[idx])
+ if self.verbose:
+ print 'Entry %d, flag is 0x%02X' % (pi, flag)
+ idx = idx + 1
+ unknown = ord(self.data[idx])
+ idx = idx + 1
+ rh, rt = nibbles(self.data[idx])
+ idx = idx + 1
+ ro, sh = nibbles(self.data[idx])
+ idx = idx + 1
+ st, so = nibbles(self.data[idx])
+ idx = idx + 1
+ unk, ph = nibbles(self.data[idx])
+ idx = idx + 1
+ pt, po = nibbles(self.data[idx])
+ idx = idx + 1
+ rows = hto(rh,rt,ro)
+ stitches = hto(sh,st,so)
+ patno = hto(ph,pt,po)
+ # we have this entry
+ if self.verbose:
+ print ' Pattern %3d: %3d Rows, %3d Stitches - ' % (patno, rows, stitches)
+ print 'Unk = %d, Unknown = 0x%02X (%d)' % (unk, unknown, unknown)
+ if flag == 1:
+ # valid entry
+ memoff = pptr
+ patoff = pptr - bytesForMemo(rows)
+ pptr = pptr - bytesPerPatternAndMemo(stitches, rows)
+ # TODO figure out how to calculate pattern length
+ #pptr = pptr - something
+ if patternNumber:
+ if patternNumber == patno:
+ patlist.append({'number':patno, 'stitches':stitches, 'rows':rows, 'memo':memoff, 'pattern':patoff})
+ else:
+ patlist.append({'number':patno, 'stitches':stitches, 'rows':rows, 'memo':memoff, 'pattern':patoff})
+ else:
+ break
+ return patlist
+
+ def getMemo(self):
+ """
+ Return an array containing the memo
+ information for the pattern currently in memory
+ """
+ patt = self.patternNumber()
+ if patt > 900:
+ return self.getPatternMemo(patt)
+ else:
+ rows = 0 # TODO XXXXXXXXX
+ return [0]
+
+ def patternNumber(self):
+ sn, pnh = nibbles(self.data[currentPatternAddr])
+ pnt, pno = nibbles(self.data[currentPatternAddr+1])
+ pattern = hto(pnh,pnt,pno)
+ return(pattern)
+
+ def getPatternMemo(self, patternNumber):
+ """
+ Return an array containing the memo
+ information for a custom pattern. The array
+ is the same length as the number of rows
+ in the pattern.
+ """
+ list = self.getPatterns(patternNumber)
+ if len(list) == 0:
+ return None
+ memos = array.array('B')
+ memoOff = list[0]['memo']
+ rows = list[0]['rows']
+ memlen = roundeven(rows)/2
+ # memo is padded to en even byte
+ for i in range(memoOff, memoOff-memlen, -1):
+ msn, lsn = nibbles(self.data[i])
+ memos.append(lsn)
+ rows = rows - 1
+ if (rows):
+ memos.append(msn)
+ rows = rows - 1
+ return memos
+
+ def getPattern(self, patternNumber):
+ """
+ Return an array containing the pattern
+ information for a pattern.
+ """
+ list = self.getPatterns(patternNumber)
+ if len(list) == 0:
+ return None
+ pattern = []
+
+ patoff = list[0]['pattern']
+ rows = list[0]['rows']
+ stitches = list[0]['stitches']
+
+ #print 'patoff = 0x%04X' % patoff
+ #print 'rows = ', rows
+ #print 'stitches = ', stitches
+ for i in range(0, rows):
+ arow = self.getRowData(patoff, stitches, i)
+ #print arow
+ pattern.append(arow)
+ return pattern
+
+ def displayPattern(self, patternNumber):
+ """
+ Display a user pattern stored in file saved
+ from the brother knitting machine. Patterns
+ in memory are stored with the beginning of the
+ pattern at the highest memory address.
+ """
+
+ return
+
+ def rowNumber(self):
+ sn, rnh = nibbles(self.data[currentRowNumberAddr])
+ rnt, rno = nibbles(self.data[currentRowNumberAddr+1])
+ rowno = hto(rnh,rnt,rno)
+ return(rowno)
+
+ def nextRow(self):
+ return self.getRowData(nextRowAddr, 200, 0)
+
+ def selectorValue(self):
+ return ord(self.data[selectAddr])
+
+ def carriageStatus(self):
+ return ord(self.data[carriageStatusAddr])
+
+ def motifData(self):
+ motiflist = []
+ addr = 0x07FB
+ for i in range(6):
+ mph, mpt = nibbles(self.data[addr])
+ if mph & 8:
+ mph = mph - 8
+ side = 'right'
+ else:
+ side = 'left'
+ mpo, foo = nibbles(self.data[addr+1])
+ mch, mct = nibbles(self.data[addr+2])
+ mco, bar = nibbles(self.data[addr+3])
+ pos = hto(mph,mpt,mpo)
+ cnt = hto(mch,mct,mco)
+ motiflist.append({'position':pos, 'copies':cnt, 'side':side})
+ addr = addr - 3
+ return motiflist
+
+ def patternPosition(self):
+ addr = 0x07FE
+ foo, ph = nibbles(self.data[addr])
+ if ph & 8:
+ ph = ph - 8
+ side = 'right'
+ else:
+ side = 'left'
+ pt, po = nibbles(self.data[addr+1])
+ pos = hto(ph,pt,po)
+
+ return {'position':pos, 'side':side}
+
+ # these are hardcoded for now
+ def unknownOne(self):
+ info = array.array('B')
+ for i in range(0x06E0, 0x06E5):
+ info.append(ord(self.data[i]))
+ return info
+
+ def unknownMemoRange(self):
+ info = array.array('B')
+ for i in range(0x0731, 0x0787):
+ info.append(ord(self.data[i]))
+ return info
+
+ def unknownEndRange(self):
+ info = array.array('B')
+ for i in range(0x07D0, 0x07E9):
+ info.append(ord(self.data[i]))
+ return info
+
+ def unknownAddrs(self):
+ return unknownList.items()
+
Binary file not shown.
Oops, something went wrong.

0 comments on commit febe4fc

Please sign in to comment.