Moshiboard

The educational technology and digital learning wiki
Revision as of 06:59, 4 August 2020 by Tatarize (talk | contribs) (Created page with "= Moshiboard = The Moshiboard laser cutter board is a proprietary controller with proprietary software. In the case of Moshiboard this software is called `MoshiDraw`. Like mo...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Moshiboard

The Moshiboard laser cutter board is a proprietary controller with proprietary software. In the case of Moshiboard this software is called `MoshiDraw`. Like most proprietary laser cutting software intended for a specific board it has significant disadvantages and the only open source solutions are attempts at reverse engineering.

USB Protocol

The usb device is located at vendor 0548 with a PID of 1005

These are sent to endpoint 0x04 and read from 0x88.

Swizzling

Like many different boards there is some light swizzling for some bytes in this case the command bytes are swizzled. Half of the command byte has random data (random distribution) and the other half is control code. This gives us 4 bits of command code, 4 random bytes. The swizzling can actually thus be interpreted in many ways, but we'll put the first four bits as command and the last 4 bits as random.

  1. 0A 0E 1A 1E 4A 4E 51 53 59 5A 5B 5E 71 74 79 7B
  2. 00 01 03 04 09 0C 10 14 21 23 29 2B 40 44 50 54
  3. 55 57 5D 5F 75 77 7D 7F 8A 8E 9A 9E CA CE DA DE
  4. 05 07 0D 0F 25 27 2D 2F 80 84 90 94 C0 C4 D0 D4
  5. AA AE BA BE D5 D7 DD DF EA EE F5 F7 FA FD FE FF
  6. 15 17 1D 1F 35 37 3D 3F 88 8C 98 9C C8 CC D8 DC
  7. 45 47 4D 4F 65 67 6D 6F 82 86 92 96 C2 C6 D2 D6
  8. A2 A6 B2 B6 C5 C7 CD CF E2 E5 E6 E7 ED EF F2 F6

These are the 8 different code seen, in their 16 different forms. If we apply a swizzle to these:

def swizzle(b, b0, b1, b2, b3, b4, b5, b6, b7):

   return ((b >> 0) & 1) << b7 | ((b >> 1) & 1) << b6 | \
          ((b >> 2) & 1) << b5 | ((b >> 3) & 1) << b4 | \
          ((b >> 4) & 1) << b3 | ((b >> 5) & 1) << b2 | \
          ((b >> 6) & 1) << b1 | ((b >> 7) & 1) << b0

def convert(q):

   if q & 1:
       return swizzle(q, 7, 6, 2, 4, 3, 5, 1, 0)
   else:
       return swizzle(q, 5, 1, 7, 2, 4, 3, 6, 0)
  1. ['50', '51', '52', '53', '54', '55', '56', '58', '59', '5a', '5b', '5c', '5d', '5e', '5f', '8e']
  2. ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '0a', '0c', '0d', '0e', '0f', '18']
  3. ['70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '7a', '7b', '7c', '7d', '7e', '7f']
  4. ['20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '2a', '2b', '2c', '2d', '2e', '2f']
  5. ['f0', 'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'fa', 'fb', 'fc', 'fd', 'fe', 'ff']
  6. ['30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '3a', '3b', '3c', '3d', '3e', '3f']
  7. ['60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '6a', '6b', '6c', '6d', '6e', '6f']
  8. ['e0', 'e1', 'e2', 'e3', 'e4', 'e5', 'e6', 'e7', 'e8', 'e9', 'ea', 'eb', 'ec', 'ed', 'ee', 'ef']

Inverted Swizzling

  1. ['00', '01', '40', '03', '10', '21', '50', '23', '04', '09', '44', '0b', '14', '29', '54', '2b']
  2. ['08', '11', '48', '13', '18', '31', '58', '33', '0c', '19', '4c', '1b', '1c', '39', '5c', '3b']
  3. ['80', '05', 'c0', '07', '90', '25', 'd0', '27', '84', '0d', 'c4', '0f', '94', '2d', 'd4', '2f']
  4. ['88', '15', 'c8', '17', '98', '35', 'd8', '37', '8c', '1d', 'cc', '1f', '9c', '3d', 'dc', '3f']
  5. ['02', '41', '42', '43', '12', '61', '52', '63', '06', '49', '46', '4b', '16', '69', '56', '6b']
  6. ['0a', '51', '4a', '53', '1a', '71', '5a', '73', '0e', '59', '4e', '5b', '1e', '79', '5e', '7b']
  7. ['82', '45', 'c2', '47', '92', '65', 'd2', '67', '86', '4d', 'c6', '4f', '96', '6d', 'd6', '6f']
  8. ['8a', '55', 'ca', '57', '9a', '75', 'da', '77', '8e', '5d', 'ce', '5f', '9e', '7d', 'de', '7f']
  9. ['20', '81', '60', '83', '30', 'a1', '70', 'a3', '24', '89', '64', '8b', '34', 'a9', '74', 'ab']
  10. ['28', '91', '68', '93', '38', 'b1', '78', 'b3', '2c', '99', '6c', '9b', '3c', 'b9', '7c', 'bb']
  11. ['a0', '85', 'e0', '87', 'b0', 'a5', 'f0', 'a7', 'a4', '8d', 'e4', '8f', 'b4', 'ad', 'f4', 'af']
  12. ['a8', '95', 'e8', '97', 'b8', 'b5', 'f8', 'b7', 'ac', '9d', 'ec', '9f', 'bc', 'bd', 'fc', 'bf']
  13. ['22', 'c1', '62', 'c3', '32', 'e1', '72', 'e3', '26', 'c9', '66', 'cb', '36', 'e9', '76', 'eb']
  14. ['2a', 'd1', '6a', 'd3', '3a', 'f1', '7a', 'f3', '2e', 'd9', '6e', 'db', '3e', 'f9', '7e', 'fb']
  15. ['a2', 'c5', 'e2', 'c7', 'b2', 'e5', 'f2', 'e7', 'a6', 'cd', 'e6', 'cf', 'b6', 'ed', 'f6', 'ef']
  16. ['aa', 'd5', 'ea', 'd7', 'ba', 'f5', 'fa', 'f7', 'ae', 'dd', 'ee', 'df', 'be', 'fd', 'fe', 'ff']

Moshiboard Commands

Since command bytes have 4 bits there can only be 16 of them.

Command Length Code Parameters
Cut_XY_ABS 1 0xF? (2 byte ABS X) (2 byte ABS Y)
Cut_X_ABS 1 0xE? (2 byte ABS X)
UNKNOWN 1 0xD? unknown
UNKNOWN 1 0xC? unknown
Cut_Y_ABS 1 0xB? (2 byte ABS Y)
UNKNOWN 1 0xA? unknown
UNKNOWN 1 0x9? unknown
UNKNOWN 1 0x8? unknown
Move_XY_ABS 1 0x7? (2 byte ABS X) (2 byte ABS Y)
Move_X_ABS 1 0x6? (2 byte ABS X)
Header Start 1 0x5? (2 bytes unknown)
UNKNOWN 1 0x4? unknown
Move_Y_ABS 1 0x3? (2 byte ABS Y)
Terminal Commands 1 0x2? nothing. (occurs in 6 bytes increments)
UNKNOWN 1 0x1? unknown
2nd Command For Jump 0 0x0? (2 bytes) (2 bytes) (2 bytes)


Bitwise this implies our flags for our 4 data bytes are: Laser, X-Value, Unknown, Y-Value

Reverse engineering resources.

Links

Official

Other Sources