Moshiboard
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.
- 0A 0E 1A 1E 4A 4E 51 53 59 5A 5B 5E 71 74 79 7B
- 00 01 03 04 09 0C 10 14 21 23 29 2B 40 44 50 54
- 55 57 5D 5F 75 77 7D 7F 8A 8E 9A 9E CA CE DA DE
- 05 07 0D 0F 25 27 2D 2F 80 84 90 94 C0 C4 D0 D4
- AA AE BA BE D5 D7 DD DF EA EE F5 F7 FA FD FE FF
- 15 17 1D 1F 35 37 3D 3F 88 8C 98 9C C8 CC D8 DC
- 45 47 4D 4F 65 67 6D 6F 82 86 92 96 C2 C6 D2 D6
- 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)
- ['50', '51', '52', '53', '54', '55', '56', '58', '59', '5a', '5b', '5c', '5d', '5e', '5f', '8e']
- ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '0a', '0c', '0d', '0e', '0f', '18']
- ['70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '7a', '7b', '7c', '7d', '7e', '7f']
- ['20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '2a', '2b', '2c', '2d', '2e', '2f']
- ['f0', 'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'fa', 'fb', 'fc', 'fd', 'fe', 'ff']
- ['30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '3a', '3b', '3c', '3d', '3e', '3f']
- ['60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '6a', '6b', '6c', '6d', '6e', '6f']
- ['e0', 'e1', 'e2', 'e3', 'e4', 'e5', 'e6', 'e7', 'e8', 'e9', 'ea', 'eb', 'ec', 'ed', 'ee', 'ef']
Inverted Swizzling
- ['00', '01', '40', '03', '10', '21', '50', '23', '04', '09', '44', '0b', '14', '29', '54', '2b']
- ['08', '11', '48', '13', '18', '31', '58', '33', '0c', '19', '4c', '1b', '1c', '39', '5c', '3b']
- ['80', '05', 'c0', '07', '90', '25', 'd0', '27', '84', '0d', 'c4', '0f', '94', '2d', 'd4', '2f']
- ['88', '15', 'c8', '17', '98', '35', 'd8', '37', '8c', '1d', 'cc', '1f', '9c', '3d', 'dc', '3f']
- ['02', '41', '42', '43', '12', '61', '52', '63', '06', '49', '46', '4b', '16', '69', '56', '6b']
- ['0a', '51', '4a', '53', '1a', '71', '5a', '73', '0e', '59', '4e', '5b', '1e', '79', '5e', '7b']
- ['82', '45', 'c2', '47', '92', '65', 'd2', '67', '86', '4d', 'c6', '4f', '96', '6d', 'd6', '6f']
- ['8a', '55', 'ca', '57', '9a', '75', 'da', '77', '8e', '5d', 'ce', '5f', '9e', '7d', 'de', '7f']
- ['20', '81', '60', '83', '30', 'a1', '70', 'a3', '24', '89', '64', '8b', '34', 'a9', '74', 'ab']
- ['28', '91', '68', '93', '38', 'b1', '78', 'b3', '2c', '99', '6c', '9b', '3c', 'b9', '7c', 'bb']
- ['a0', '85', 'e0', '87', 'b0', 'a5', 'f0', 'a7', 'a4', '8d', 'e4', '8f', 'b4', 'ad', 'f4', 'af']
- ['a8', '95', 'e8', '97', 'b8', 'b5', 'f8', 'b7', 'ac', '9d', 'ec', '9f', 'bc', 'bd', 'fc', 'bf']
- ['22', 'c1', '62', 'c3', '32', 'e1', '72', 'e3', '26', 'c9', '66', 'cb', '36', 'e9', '76', 'eb']
- ['2a', 'd1', '6a', 'd3', '3a', 'f1', '7a', 'f3', '2e', 'd9', '6e', 'db', '3e', 'f9', '7e', 'fb']
- ['a2', 'c5', 'e2', 'c7', 'b2', 'e5', 'f2', 'e7', 'a6', 'cd', 'e6', 'cf', 'b6', 'ed', 'f6', 'ef']
- ['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.
- The MeerK40t project has done some initial work reverse engineering the Moshiboard. https://github.com/meerk40t/moshi
Links
Official
Other Sources
- MeerK40t moshi project MeerK40t Moshi Project
- MeerK40t moshi wiki MeerK40t Moshi Wiki