From b930b20a2d5505db6ce14e364163e696d8367354 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Ruel Date: Tue, 20 Nov 2018 21:15:13 -0500 Subject: [PATCH] nrzled: clean up NRZ encoded as 3 or 4 bits - Fix package documentation. - Switch the main code to use a lookup array (and not slices!). - Add unit test to test the lookup table against the algorithm. --- experimental/devices/nrzled/doc.go | 1 - experimental/devices/nrzled/nrz.go | 570 ++++++++++++++++++ experimental/devices/nrzled/nrz_spi.go | 267 +------- experimental/devices/nrzled/nrz_test.go | 32 + experimental/devices/nrzled/nrzled.go | 76 +-- .../devices/nrzled/nrzled_go1_7_test.go | 39 -- experimental/devices/nrzled/nrzled_test.go | 9 - 7 files changed, 628 insertions(+), 366 deletions(-) create mode 100644 experimental/devices/nrzled/nrz.go create mode 100644 experimental/devices/nrzled/nrz_test.go delete mode 100644 experimental/devices/nrzled/nrzled_go1_7_test.go diff --git a/experimental/devices/nrzled/doc.go b/experimental/devices/nrzled/doc.go index f88efc9..53d3f1f 100644 --- a/experimental/devices/nrzled/doc.go +++ b/experimental/devices/nrzled/doc.go @@ -32,5 +32,4 @@ // ws2812b A.K.A. Neopixel datasheet // // https://cdn-shop.adafruit.com/datasheets/WS2812B.pdf - package nrzled diff --git a/experimental/devices/nrzled/nrz.go b/experimental/devices/nrzled/nrz.go new file mode 100644 index 0000000..1fab2eb --- /dev/null +++ b/experimental/devices/nrzled/nrz.go @@ -0,0 +1,570 @@ +// Copyright 2018 The Periph Authors. All rights reserved. +// Use of this source code is governed under the Apache License, Version 2.0 +// that can be found in the LICENSE file. + +package nrzled + +// nrzMSB3 converts a byte into the MSB-first Non-Return-to-Zero encoded 24 +// bits. +// +// zero becomes 100. one becomes 110. +// +// The upper 8 bits are zeros and shall be ignored. +// +// The Non-return-to-zero protocol is a self-clocking signal that enables +// one-way communication without the need of a dedicated clock signal, unlike +// SPI driven LEDs like the apa102. +// +// See https://en.wikipedia.org/wiki/Non-return-to-zero for more technical +// details. +func nrzMSB3Algo(b byte) uint32 { + // The stream is 1x01x01x01x01x01x01x01x0 with the x bits being the bits from + // `b` in reverse order. + out := uint32(0x924924) + out |= uint32(b&0x80) << (3*7 + 1 - 7) + out |= uint32(b&0x40) << (3*6 + 1 - 6) + out |= uint32(b&0x20) << (3*5 + 1 - 5) + out |= uint32(b&0x10) << (3*4 + 1 - 4) + out |= uint32(b&0x08) << (3*3 + 1 - 3) + out |= uint32(b&0x04) << (3*2 + 1 - 2) + out |= uint32(b&0x02) << (3*1 + 1 - 1) + out |= uint32(b&0x01) << (3*0 + 1 - 0) + return out +} + +var nrzMSB3 = [...][3]byte{ + {0x92, 0x49, 0x24}, // 0x00 | 100100100100100100100100 + {0x92, 0x49, 0x26}, // 0x01 | 100100100100100100100110 + {0x92, 0x49, 0x34}, // 0x02 | 100100100100100100110100 + {0x92, 0x49, 0x36}, // 0x03 | 100100100100100100110110 + {0x92, 0x49, 0xA4}, // 0x04 | 100100100100100110100100 + {0x92, 0x49, 0xA6}, // 0x05 | 100100100100100110100110 + {0x92, 0x49, 0xB4}, // 0x06 | 100100100100100110110100 + {0x92, 0x49, 0xB6}, // 0x07 | 100100100100100110110110 + {0x92, 0x4D, 0x24}, // 0x08 | 100100100100110100100100 + {0x92, 0x4D, 0x26}, // 0x09 | 100100100100110100100110 + {0x92, 0x4D, 0x34}, // 0x0A | 100100100100110100110100 + {0x92, 0x4D, 0x36}, // 0x0B | 100100100100110100110110 + {0x92, 0x4D, 0xA4}, // 0x0C | 100100100100110110100100 + {0x92, 0x4D, 0xA6}, // 0x0D | 100100100100110110100110 + {0x92, 0x4D, 0xB4}, // 0x0E | 100100100100110110110100 + {0x92, 0x4D, 0xB6}, // 0x0F | 100100100100110110110110 + {0x92, 0x69, 0x24}, // 0x10 | 100100100110100100100100 + {0x92, 0x69, 0x26}, // 0x11 | 100100100110100100100110 + {0x92, 0x69, 0x34}, // 0x12 | 100100100110100100110100 + {0x92, 0x69, 0x36}, // 0x13 | 100100100110100100110110 + {0x92, 0x69, 0xA4}, // 0x14 | 100100100110100110100100 + {0x92, 0x69, 0xA6}, // 0x15 | 100100100110100110100110 + {0x92, 0x69, 0xB4}, // 0x16 | 100100100110100110110100 + {0x92, 0x69, 0xB6}, // 0x17 | 100100100110100110110110 + {0x92, 0x6D, 0x24}, // 0x18 | 100100100110110100100100 + {0x92, 0x6D, 0x26}, // 0x19 | 100100100110110100100110 + {0x92, 0x6D, 0x34}, // 0x1A | 100100100110110100110100 + {0x92, 0x6D, 0x36}, // 0x1B | 100100100110110100110110 + {0x92, 0x6D, 0xA4}, // 0x1C | 100100100110110110100100 + {0x92, 0x6D, 0xA6}, // 0x1D | 100100100110110110100110 + {0x92, 0x6D, 0xB4}, // 0x1E | 100100100110110110110100 + {0x92, 0x6D, 0xB6}, // 0x1F | 100100100110110110110110 + {0x93, 0x49, 0x24}, // 0x20 | 100100110100100100100100 + {0x93, 0x49, 0x26}, // 0x21 | 100100110100100100100110 + {0x93, 0x49, 0x34}, // 0x22 | 100100110100100100110100 + {0x93, 0x49, 0x36}, // 0x23 | 100100110100100100110110 + {0x93, 0x49, 0xA4}, // 0x24 | 100100110100100110100100 + {0x93, 0x49, 0xA6}, // 0x25 | 100100110100100110100110 + {0x93, 0x49, 0xB4}, // 0x26 | 100100110100100110110100 + {0x93, 0x49, 0xB6}, // 0x27 | 100100110100100110110110 + {0x93, 0x4D, 0x24}, // 0x28 | 100100110100110100100100 + {0x93, 0x4D, 0x26}, // 0x29 | 100100110100110100100110 + {0x93, 0x4D, 0x34}, // 0x2A | 100100110100110100110100 + {0x93, 0x4D, 0x36}, // 0x2B | 100100110100110100110110 + {0x93, 0x4D, 0xA4}, // 0x2C | 100100110100110110100100 + {0x93, 0x4D, 0xA6}, // 0x2D | 100100110100110110100110 + {0x93, 0x4D, 0xB4}, // 0x2E | 100100110100110110110100 + {0x93, 0x4D, 0xB6}, // 0x2F | 100100110100110110110110 + {0x93, 0x69, 0x24}, // 0x30 | 100100110110100100100100 + {0x93, 0x69, 0x26}, // 0x31 | 100100110110100100100110 + {0x93, 0x69, 0x34}, // 0x32 | 100100110110100100110100 + {0x93, 0x69, 0x36}, // 0x33 | 100100110110100100110110 + {0x93, 0x69, 0xA4}, // 0x34 | 100100110110100110100100 + {0x93, 0x69, 0xA6}, // 0x35 | 100100110110100110100110 + {0x93, 0x69, 0xB4}, // 0x36 | 100100110110100110110100 + {0x93, 0x69, 0xB6}, // 0x37 | 100100110110100110110110 + {0x93, 0x6D, 0x24}, // 0x38 | 100100110110110100100100 + {0x93, 0x6D, 0x26}, // 0x39 | 100100110110110100100110 + {0x93, 0x6D, 0x34}, // 0x3A | 100100110110110100110100 + {0x93, 0x6D, 0x36}, // 0x3B | 100100110110110100110110 + {0x93, 0x6D, 0xA4}, // 0x3C | 100100110110110110100100 + {0x93, 0x6D, 0xA6}, // 0x3D | 100100110110110110100110 + {0x93, 0x6D, 0xB4}, // 0x3E | 100100110110110110110100 + {0x93, 0x6D, 0xB6}, // 0x3F | 100100110110110110110110 + {0x9A, 0x49, 0x24}, // 0x40 | 100110100100100100100100 + {0x9A, 0x49, 0x26}, // 0x41 | 100110100100100100100110 + {0x9A, 0x49, 0x34}, // 0x42 | 100110100100100100110100 + {0x9A, 0x49, 0x36}, // 0x43 | 100110100100100100110110 + {0x9A, 0x49, 0xA4}, // 0x44 | 100110100100100110100100 + {0x9A, 0x49, 0xA6}, // 0x45 | 100110100100100110100110 + {0x9A, 0x49, 0xB4}, // 0x46 | 100110100100100110110100 + {0x9A, 0x49, 0xB6}, // 0x47 | 100110100100100110110110 + {0x9A, 0x4D, 0x24}, // 0x48 | 100110100100110100100100 + {0x9A, 0x4D, 0x26}, // 0x49 | 100110100100110100100110 + {0x9A, 0x4D, 0x34}, // 0x4A | 100110100100110100110100 + {0x9A, 0x4D, 0x36}, // 0x4B | 100110100100110100110110 + {0x9A, 0x4D, 0xA4}, // 0x4C | 100110100100110110100100 + {0x9A, 0x4D, 0xA6}, // 0x4D | 100110100100110110100110 + {0x9A, 0x4D, 0xB4}, // 0x4E | 100110100100110110110100 + {0x9A, 0x4D, 0xB6}, // 0x4F | 100110100100110110110110 + {0x9A, 0x69, 0x24}, // 0x50 | 100110100110100100100100 + {0x9A, 0x69, 0x26}, // 0x51 | 100110100110100100100110 + {0x9A, 0x69, 0x34}, // 0x52 | 100110100110100100110100 + {0x9A, 0x69, 0x36}, // 0x53 | 100110100110100100110110 + {0x9A, 0x69, 0xA4}, // 0x54 | 100110100110100110100100 + {0x9A, 0x69, 0xA6}, // 0x55 | 100110100110100110100110 + {0x9A, 0x69, 0xB4}, // 0x56 | 100110100110100110110100 + {0x9A, 0x69, 0xB6}, // 0x57 | 100110100110100110110110 + {0x9A, 0x6D, 0x24}, // 0x58 | 100110100110110100100100 + {0x9A, 0x6D, 0x26}, // 0x59 | 100110100110110100100110 + {0x9A, 0x6D, 0x34}, // 0x5A | 100110100110110100110100 + {0x9A, 0x6D, 0x36}, // 0x5B | 100110100110110100110110 + {0x9A, 0x6D, 0xA4}, // 0x5C | 100110100110110110100100 + {0x9A, 0x6D, 0xA6}, // 0x5D | 100110100110110110100110 + {0x9A, 0x6D, 0xB4}, // 0x5E | 100110100110110110110100 + {0x9A, 0x6D, 0xB6}, // 0x5F | 100110100110110110110110 + {0x9B, 0x49, 0x24}, // 0x60 | 100110110100100100100100 + {0x9B, 0x49, 0x26}, // 0x61 | 100110110100100100100110 + {0x9B, 0x49, 0x34}, // 0x62 | 100110110100100100110100 + {0x9B, 0x49, 0x36}, // 0x63 | 100110110100100100110110 + {0x9B, 0x49, 0xA4}, // 0x64 | 100110110100100110100100 + {0x9B, 0x49, 0xA6}, // 0x65 | 100110110100100110100110 + {0x9B, 0x49, 0xB4}, // 0x66 | 100110110100100110110100 + {0x9B, 0x49, 0xB6}, // 0x67 | 100110110100100110110110 + {0x9B, 0x4D, 0x24}, // 0x68 | 100110110100110100100100 + {0x9B, 0x4D, 0x26}, // 0x69 | 100110110100110100100110 + {0x9B, 0x4D, 0x34}, // 0x6A | 100110110100110100110100 + {0x9B, 0x4D, 0x36}, // 0x6B | 100110110100110100110110 + {0x9B, 0x4D, 0xA4}, // 0x6C | 100110110100110110100100 + {0x9B, 0x4D, 0xA6}, // 0x6D | 100110110100110110100110 + {0x9B, 0x4D, 0xB4}, // 0x6E | 100110110100110110110100 + {0x9B, 0x4D, 0xB6}, // 0x6F | 100110110100110110110110 + {0x9B, 0x69, 0x24}, // 0x70 | 100110110110100100100100 + {0x9B, 0x69, 0x26}, // 0x71 | 100110110110100100100110 + {0x9B, 0x69, 0x34}, // 0x72 | 100110110110100100110100 + {0x9B, 0x69, 0x36}, // 0x73 | 100110110110100100110110 + {0x9B, 0x69, 0xA4}, // 0x74 | 100110110110100110100100 + {0x9B, 0x69, 0xA6}, // 0x75 | 100110110110100110100110 + {0x9B, 0x69, 0xB4}, // 0x76 | 100110110110100110110100 + {0x9B, 0x69, 0xB6}, // 0x77 | 100110110110100110110110 + {0x9B, 0x6D, 0x24}, // 0x78 | 100110110110110100100100 + {0x9B, 0x6D, 0x26}, // 0x79 | 100110110110110100100110 + {0x9B, 0x6D, 0x34}, // 0x7A | 100110110110110100110100 + {0x9B, 0x6D, 0x36}, // 0x7B | 100110110110110100110110 + {0x9B, 0x6D, 0xA4}, // 0x7C | 100110110110110110100100 + {0x9B, 0x6D, 0xA6}, // 0x7D | 100110110110110110100110 + {0x9B, 0x6D, 0xB4}, // 0x7E | 100110110110110110110100 + {0x9B, 0x6D, 0xB6}, // 0x7F | 100110110110110110110110 + {0xD2, 0x49, 0x24}, // 0x80 | 110100100100100100100100 + {0xD2, 0x49, 0x26}, // 0x81 | 110100100100100100100110 + {0xD2, 0x49, 0x34}, // 0x82 | 110100100100100100110100 + {0xD2, 0x49, 0x36}, // 0x83 | 110100100100100100110110 + {0xD2, 0x49, 0xA4}, // 0x84 | 110100100100100110100100 + {0xD2, 0x49, 0xA6}, // 0x85 | 110100100100100110100110 + {0xD2, 0x49, 0xB4}, // 0x86 | 110100100100100110110100 + {0xD2, 0x49, 0xB6}, // 0x87 | 110100100100100110110110 + {0xD2, 0x4D, 0x24}, // 0x88 | 110100100100110100100100 + {0xD2, 0x4D, 0x26}, // 0x89 | 110100100100110100100110 + {0xD2, 0x4D, 0x34}, // 0x8A | 110100100100110100110100 + {0xD2, 0x4D, 0x36}, // 0x8B | 110100100100110100110110 + {0xD2, 0x4D, 0xA4}, // 0x8C | 110100100100110110100100 + {0xD2, 0x4D, 0xA6}, // 0x8D | 110100100100110110100110 + {0xD2, 0x4D, 0xB4}, // 0x8E | 110100100100110110110100 + {0xD2, 0x4D, 0xB6}, // 0x8F | 110100100100110110110110 + {0xD2, 0x69, 0x24}, // 0x90 | 110100100110100100100100 + {0xD2, 0x69, 0x26}, // 0x91 | 110100100110100100100110 + {0xD2, 0x69, 0x34}, // 0x92 | 110100100110100100110100 + {0xD2, 0x69, 0x36}, // 0x93 | 110100100110100100110110 + {0xD2, 0x69, 0xA4}, // 0x94 | 110100100110100110100100 + {0xD2, 0x69, 0xA6}, // 0x95 | 110100100110100110100110 + {0xD2, 0x69, 0xB4}, // 0x96 | 110100100110100110110100 + {0xD2, 0x69, 0xB6}, // 0x97 | 110100100110100110110110 + {0xD2, 0x6D, 0x24}, // 0x98 | 110100100110110100100100 + {0xD2, 0x6D, 0x26}, // 0x99 | 110100100110110100100110 + {0xD2, 0x6D, 0x34}, // 0x9A | 110100100110110100110100 + {0xD2, 0x6D, 0x36}, // 0x9B | 110100100110110100110110 + {0xD2, 0x6D, 0xA4}, // 0x9C | 110100100110110110100100 + {0xD2, 0x6D, 0xA6}, // 0x9D | 110100100110110110100110 + {0xD2, 0x6D, 0xB4}, // 0x9E | 110100100110110110110100 + {0xD2, 0x6D, 0xB6}, // 0x9F | 110100100110110110110110 + {0xD3, 0x49, 0x24}, // 0xA0 | 110100110100100100100100 + {0xD3, 0x49, 0x26}, // 0xA1 | 110100110100100100100110 + {0xD3, 0x49, 0x34}, // 0xA2 | 110100110100100100110100 + {0xD3, 0x49, 0x36}, // 0xA3 | 110100110100100100110110 + {0xD3, 0x49, 0xA4}, // 0xA4 | 110100110100100110100100 + {0xD3, 0x49, 0xA6}, // 0xA5 | 110100110100100110100110 + {0xD3, 0x49, 0xB4}, // 0xA6 | 110100110100100110110100 + {0xD3, 0x49, 0xB6}, // 0xA7 | 110100110100100110110110 + {0xD3, 0x4D, 0x24}, // 0xA8 | 110100110100110100100100 + {0xD3, 0x4D, 0x26}, // 0xA9 | 110100110100110100100110 + {0xD3, 0x4D, 0x34}, // 0xAA | 110100110100110100110100 + {0xD3, 0x4D, 0x36}, // 0xAB | 110100110100110100110110 + {0xD3, 0x4D, 0xA4}, // 0xAC | 110100110100110110100100 + {0xD3, 0x4D, 0xA6}, // 0xAD | 110100110100110110100110 + {0xD3, 0x4D, 0xB4}, // 0xAE | 110100110100110110110100 + {0xD3, 0x4D, 0xB6}, // 0xAF | 110100110100110110110110 + {0xD3, 0x69, 0x24}, // 0xB0 | 110100110110100100100100 + {0xD3, 0x69, 0x26}, // 0xB1 | 110100110110100100100110 + {0xD3, 0x69, 0x34}, // 0xB2 | 110100110110100100110100 + {0xD3, 0x69, 0x36}, // 0xB3 | 110100110110100100110110 + {0xD3, 0x69, 0xA4}, // 0xB4 | 110100110110100110100100 + {0xD3, 0x69, 0xA6}, // 0xB5 | 110100110110100110100110 + {0xD3, 0x69, 0xB4}, // 0xB6 | 110100110110100110110100 + {0xD3, 0x69, 0xB6}, // 0xB7 | 110100110110100110110110 + {0xD3, 0x6D, 0x24}, // 0xB8 | 110100110110110100100100 + {0xD3, 0x6D, 0x26}, // 0xB9 | 110100110110110100100110 + {0xD3, 0x6D, 0x34}, // 0xBA | 110100110110110100110100 + {0xD3, 0x6D, 0x36}, // 0xBB | 110100110110110100110110 + {0xD3, 0x6D, 0xA4}, // 0xBC | 110100110110110110100100 + {0xD3, 0x6D, 0xA6}, // 0xBD | 110100110110110110100110 + {0xD3, 0x6D, 0xB4}, // 0xBE | 110100110110110110110100 + {0xD3, 0x6D, 0xB6}, // 0xBF | 110100110110110110110110 + {0xDA, 0x49, 0x24}, // 0xC0 | 110110100100100100100100 + {0xDA, 0x49, 0x26}, // 0xC1 | 110110100100100100100110 + {0xDA, 0x49, 0x34}, // 0xC2 | 110110100100100100110100 + {0xDA, 0x49, 0x36}, // 0xC3 | 110110100100100100110110 + {0xDA, 0x49, 0xA4}, // 0xC4 | 110110100100100110100100 + {0xDA, 0x49, 0xA6}, // 0xC5 | 110110100100100110100110 + {0xDA, 0x49, 0xB4}, // 0xC6 | 110110100100100110110100 + {0xDA, 0x49, 0xB6}, // 0xC7 | 110110100100100110110110 + {0xDA, 0x4D, 0x24}, // 0xC8 | 110110100100110100100100 + {0xDA, 0x4D, 0x26}, // 0xC9 | 110110100100110100100110 + {0xDA, 0x4D, 0x34}, // 0xCA | 110110100100110100110100 + {0xDA, 0x4D, 0x36}, // 0xCB | 110110100100110100110110 + {0xDA, 0x4D, 0xA4}, // 0xCC | 110110100100110110100100 + {0xDA, 0x4D, 0xA6}, // 0xCD | 110110100100110110100110 + {0xDA, 0x4D, 0xB4}, // 0xCE | 110110100100110110110100 + {0xDA, 0x4D, 0xB6}, // 0xCF | 110110100100110110110110 + {0xDA, 0x69, 0x24}, // 0xD0 | 110110100110100100100100 + {0xDA, 0x69, 0x26}, // 0xD1 | 110110100110100100100110 + {0xDA, 0x69, 0x34}, // 0xD2 | 110110100110100100110100 + {0xDA, 0x69, 0x36}, // 0xD3 | 110110100110100100110110 + {0xDA, 0x69, 0xA4}, // 0xD4 | 110110100110100110100100 + {0xDA, 0x69, 0xA6}, // 0xD5 | 110110100110100110100110 + {0xDA, 0x69, 0xB4}, // 0xD6 | 110110100110100110110100 + {0xDA, 0x69, 0xB6}, // 0xD7 | 110110100110100110110110 + {0xDA, 0x6D, 0x24}, // 0xD8 | 110110100110110100100100 + {0xDA, 0x6D, 0x26}, // 0xD9 | 110110100110110100100110 + {0xDA, 0x6D, 0x34}, // 0xDA | 110110100110110100110100 + {0xDA, 0x6D, 0x36}, // 0xDB | 110110100110110100110110 + {0xDA, 0x6D, 0xA4}, // 0xDC | 110110100110110110100100 + {0xDA, 0x6D, 0xA6}, // 0xDD | 110110100110110110100110 + {0xDA, 0x6D, 0xB4}, // 0xDE | 110110100110110110110100 + {0xDA, 0x6D, 0xB6}, // 0xDF | 110110100110110110110110 + {0xDB, 0x49, 0x24}, // 0xE0 | 110110110100100100100100 + {0xDB, 0x49, 0x26}, // 0xE1 | 110110110100100100100110 + {0xDB, 0x49, 0x34}, // 0xE2 | 110110110100100100110100 + {0xDB, 0x49, 0x36}, // 0xE3 | 110110110100100100110110 + {0xDB, 0x49, 0xA4}, // 0xE4 | 110110110100100110100100 + {0xDB, 0x49, 0xA6}, // 0xE5 | 110110110100100110100110 + {0xDB, 0x49, 0xB4}, // 0xE6 | 110110110100100110110100 + {0xDB, 0x49, 0xB6}, // 0xE7 | 110110110100100110110110 + {0xDB, 0x4D, 0x24}, // 0xE8 | 110110110100110100100100 + {0xDB, 0x4D, 0x26}, // 0xE9 | 110110110100110100100110 + {0xDB, 0x4D, 0x34}, // 0xEA | 110110110100110100110100 + {0xDB, 0x4D, 0x36}, // 0xEB | 110110110100110100110110 + {0xDB, 0x4D, 0xA4}, // 0xEC | 110110110100110110100100 + {0xDB, 0x4D, 0xA6}, // 0xED | 110110110100110110100110 + {0xDB, 0x4D, 0xB4}, // 0xEE | 110110110100110110110100 + {0xDB, 0x4D, 0xB6}, // 0xEF | 110110110100110110110110 + {0xDB, 0x69, 0x24}, // 0xF0 | 110110110110100100100100 + {0xDB, 0x69, 0x26}, // 0xF1 | 110110110110100100100110 + {0xDB, 0x69, 0x34}, // 0xF2 | 110110110110100100110100 + {0xDB, 0x69, 0x36}, // 0xF3 | 110110110110100100110110 + {0xDB, 0x69, 0xA4}, // 0xF4 | 110110110110100110100100 + {0xDB, 0x69, 0xA6}, // 0xF5 | 110110110110100110100110 + {0xDB, 0x69, 0xB4}, // 0xF6 | 110110110110100110110100 + {0xDB, 0x69, 0xB6}, // 0xF7 | 110110110110100110110110 + {0xDB, 0x6D, 0x24}, // 0xF8 | 110110110110110100100100 + {0xDB, 0x6D, 0x26}, // 0xF9 | 110110110110110100100110 + {0xDB, 0x6D, 0x34}, // 0xFA | 110110110110110100110100 + {0xDB, 0x6D, 0x36}, // 0xFB | 110110110110110100110110 + {0xDB, 0x6D, 0xA4}, // 0xFC | 110110110110110110100100 + {0xDB, 0x6D, 0xA6}, // 0xFD | 110110110110110110100110 + {0xDB, 0x6D, 0xB4}, // 0xFE | 110110110110110110110100 + {0xDB, 0x6D, 0xB6}, // 0xFF | 110110110110110110110110 +} + +// nrzMSB4 converts a byte into the MSB-first Non-Return-to-Zero encoded 32 +// bits. +// +// zero becomes 1000. one becomes 1110. +// +// Note that this is out of spec but is close enough. +func nrzMSB4Algo(b byte) uint32 { + out := uint32(0x88888888) + out |= (uint32(b&0x80) * 3) << (4*7 + 1 - 7) + out |= (uint32(b&0x40) * 3) << (4*6 + 1 - 6) + out |= (uint32(b&0x20) * 3) << (4*5 + 1 - 5) + out |= (uint32(b&0x10) * 3) << (4*4 + 1 - 4) + out |= (uint32(b&0x08) * 3) << (4*3 + 1 - 3) + out |= (uint32(b&0x04) * 3) << (4*2 + 1 - 2) + out |= (uint32(b&0x02) * 3) << (4*1 + 1 - 1) + out |= (uint32(b&0x01) * 3) << (4*0 + 1 - 0) + return out +} + +var nrzMSB4 = [...][4]byte{ + {0x88, 0x88, 0x88, 0x88}, // 0x00 | 10001000100010001000100010001000 + {0x88, 0x88, 0x88, 0x8E}, // 0x01 | 10001000100010001000100010001110 + {0x88, 0x88, 0x88, 0xE8}, // 0x02 | 10001000100010001000100011101000 + {0x88, 0x88, 0x88, 0xEE}, // 0x03 | 10001000100010001000100011101110 + {0x88, 0x88, 0x8E, 0x88}, // 0x04 | 10001000100010001000111010001000 + {0x88, 0x88, 0x8E, 0x8E}, // 0x05 | 10001000100010001000111010001110 + {0x88, 0x88, 0x8E, 0xE8}, // 0x06 | 10001000100010001000111011101000 + {0x88, 0x88, 0x8E, 0xEE}, // 0x07 | 10001000100010001000111011101110 + {0x88, 0x88, 0xE8, 0x88}, // 0x08 | 10001000100010001110100010001000 + {0x88, 0x88, 0xE8, 0x8E}, // 0x09 | 10001000100010001110100010001110 + {0x88, 0x88, 0xE8, 0xE8}, // 0x0A | 10001000100010001110100011101000 + {0x88, 0x88, 0xE8, 0xEE}, // 0x0B | 10001000100010001110100011101110 + {0x88, 0x88, 0xEE, 0x88}, // 0x0C | 10001000100010001110111010001000 + {0x88, 0x88, 0xEE, 0x8E}, // 0x0D | 10001000100010001110111010001110 + {0x88, 0x88, 0xEE, 0xE8}, // 0x0E | 10001000100010001110111011101000 + {0x88, 0x88, 0xEE, 0xEE}, // 0x0F | 10001000100010001110111011101110 + {0x88, 0x8E, 0x88, 0x88}, // 0x10 | 10001000100011101000100010001000 + {0x88, 0x8E, 0x88, 0x8E}, // 0x11 | 10001000100011101000100010001110 + {0x88, 0x8E, 0x88, 0xE8}, // 0x12 | 10001000100011101000100011101000 + {0x88, 0x8E, 0x88, 0xEE}, // 0x13 | 10001000100011101000100011101110 + {0x88, 0x8E, 0x8E, 0x88}, // 0x14 | 10001000100011101000111010001000 + {0x88, 0x8E, 0x8E, 0x8E}, // 0x15 | 10001000100011101000111010001110 + {0x88, 0x8E, 0x8E, 0xE8}, // 0x16 | 10001000100011101000111011101000 + {0x88, 0x8E, 0x8E, 0xEE}, // 0x17 | 10001000100011101000111011101110 + {0x88, 0x8E, 0xE8, 0x88}, // 0x18 | 10001000100011101110100010001000 + {0x88, 0x8E, 0xE8, 0x8E}, // 0x19 | 10001000100011101110100010001110 + {0x88, 0x8E, 0xE8, 0xE8}, // 0x1A | 10001000100011101110100011101000 + {0x88, 0x8E, 0xE8, 0xEE}, // 0x1B | 10001000100011101110100011101110 + {0x88, 0x8E, 0xEE, 0x88}, // 0x1C | 10001000100011101110111010001000 + {0x88, 0x8E, 0xEE, 0x8E}, // 0x1D | 10001000100011101110111010001110 + {0x88, 0x8E, 0xEE, 0xE8}, // 0x1E | 10001000100011101110111011101000 + {0x88, 0x8E, 0xEE, 0xEE}, // 0x1F | 10001000100011101110111011101110 + {0x88, 0xE8, 0x88, 0x88}, // 0x20 | 10001000111010001000100010001000 + {0x88, 0xE8, 0x88, 0x8E}, // 0x21 | 10001000111010001000100010001110 + {0x88, 0xE8, 0x88, 0xE8}, // 0x22 | 10001000111010001000100011101000 + {0x88, 0xE8, 0x88, 0xEE}, // 0x23 | 10001000111010001000100011101110 + {0x88, 0xE8, 0x8E, 0x88}, // 0x24 | 10001000111010001000111010001000 + {0x88, 0xE8, 0x8E, 0x8E}, // 0x25 | 10001000111010001000111010001110 + {0x88, 0xE8, 0x8E, 0xE8}, // 0x26 | 10001000111010001000111011101000 + {0x88, 0xE8, 0x8E, 0xEE}, // 0x27 | 10001000111010001000111011101110 + {0x88, 0xE8, 0xE8, 0x88}, // 0x28 | 10001000111010001110100010001000 + {0x88, 0xE8, 0xE8, 0x8E}, // 0x29 | 10001000111010001110100010001110 + {0x88, 0xE8, 0xE8, 0xE8}, // 0x2A | 10001000111010001110100011101000 + {0x88, 0xE8, 0xE8, 0xEE}, // 0x2B | 10001000111010001110100011101110 + {0x88, 0xE8, 0xEE, 0x88}, // 0x2C | 10001000111010001110111010001000 + {0x88, 0xE8, 0xEE, 0x8E}, // 0x2D | 10001000111010001110111010001110 + {0x88, 0xE8, 0xEE, 0xE8}, // 0x2E | 10001000111010001110111011101000 + {0x88, 0xE8, 0xEE, 0xEE}, // 0x2F | 10001000111010001110111011101110 + {0x88, 0xEE, 0x88, 0x88}, // 0x30 | 10001000111011101000100010001000 + {0x88, 0xEE, 0x88, 0x8E}, // 0x31 | 10001000111011101000100010001110 + {0x88, 0xEE, 0x88, 0xE8}, // 0x32 | 10001000111011101000100011101000 + {0x88, 0xEE, 0x88, 0xEE}, // 0x33 | 10001000111011101000100011101110 + {0x88, 0xEE, 0x8E, 0x88}, // 0x34 | 10001000111011101000111010001000 + {0x88, 0xEE, 0x8E, 0x8E}, // 0x35 | 10001000111011101000111010001110 + {0x88, 0xEE, 0x8E, 0xE8}, // 0x36 | 10001000111011101000111011101000 + {0x88, 0xEE, 0x8E, 0xEE}, // 0x37 | 10001000111011101000111011101110 + {0x88, 0xEE, 0xE8, 0x88}, // 0x38 | 10001000111011101110100010001000 + {0x88, 0xEE, 0xE8, 0x8E}, // 0x39 | 10001000111011101110100010001110 + {0x88, 0xEE, 0xE8, 0xE8}, // 0x3A | 10001000111011101110100011101000 + {0x88, 0xEE, 0xE8, 0xEE}, // 0x3B | 10001000111011101110100011101110 + {0x88, 0xEE, 0xEE, 0x88}, // 0x3C | 10001000111011101110111010001000 + {0x88, 0xEE, 0xEE, 0x8E}, // 0x3D | 10001000111011101110111010001110 + {0x88, 0xEE, 0xEE, 0xE8}, // 0x3E | 10001000111011101110111011101000 + {0x88, 0xEE, 0xEE, 0xEE}, // 0x3F | 10001000111011101110111011101110 + {0x8E, 0x88, 0x88, 0x88}, // 0x40 | 10001110100010001000100010001000 + {0x8E, 0x88, 0x88, 0x8E}, // 0x41 | 10001110100010001000100010001110 + {0x8E, 0x88, 0x88, 0xE8}, // 0x42 | 10001110100010001000100011101000 + {0x8E, 0x88, 0x88, 0xEE}, // 0x43 | 10001110100010001000100011101110 + {0x8E, 0x88, 0x8E, 0x88}, // 0x44 | 10001110100010001000111010001000 + {0x8E, 0x88, 0x8E, 0x8E}, // 0x45 | 10001110100010001000111010001110 + {0x8E, 0x88, 0x8E, 0xE8}, // 0x46 | 10001110100010001000111011101000 + {0x8E, 0x88, 0x8E, 0xEE}, // 0x47 | 10001110100010001000111011101110 + {0x8E, 0x88, 0xE8, 0x88}, // 0x48 | 10001110100010001110100010001000 + {0x8E, 0x88, 0xE8, 0x8E}, // 0x49 | 10001110100010001110100010001110 + {0x8E, 0x88, 0xE8, 0xE8}, // 0x4A | 10001110100010001110100011101000 + {0x8E, 0x88, 0xE8, 0xEE}, // 0x4B | 10001110100010001110100011101110 + {0x8E, 0x88, 0xEE, 0x88}, // 0x4C | 10001110100010001110111010001000 + {0x8E, 0x88, 0xEE, 0x8E}, // 0x4D | 10001110100010001110111010001110 + {0x8E, 0x88, 0xEE, 0xE8}, // 0x4E | 10001110100010001110111011101000 + {0x8E, 0x88, 0xEE, 0xEE}, // 0x4F | 10001110100010001110111011101110 + {0x8E, 0x8E, 0x88, 0x88}, // 0x50 | 10001110100011101000100010001000 + {0x8E, 0x8E, 0x88, 0x8E}, // 0x51 | 10001110100011101000100010001110 + {0x8E, 0x8E, 0x88, 0xE8}, // 0x52 | 10001110100011101000100011101000 + {0x8E, 0x8E, 0x88, 0xEE}, // 0x53 | 10001110100011101000100011101110 + {0x8E, 0x8E, 0x8E, 0x88}, // 0x54 | 10001110100011101000111010001000 + {0x8E, 0x8E, 0x8E, 0x8E}, // 0x55 | 10001110100011101000111010001110 + {0x8E, 0x8E, 0x8E, 0xE8}, // 0x56 | 10001110100011101000111011101000 + {0x8E, 0x8E, 0x8E, 0xEE}, // 0x57 | 10001110100011101000111011101110 + {0x8E, 0x8E, 0xE8, 0x88}, // 0x58 | 10001110100011101110100010001000 + {0x8E, 0x8E, 0xE8, 0x8E}, // 0x59 | 10001110100011101110100010001110 + {0x8E, 0x8E, 0xE8, 0xE8}, // 0x5A | 10001110100011101110100011101000 + {0x8E, 0x8E, 0xE8, 0xEE}, // 0x5B | 10001110100011101110100011101110 + {0x8E, 0x8E, 0xEE, 0x88}, // 0x5C | 10001110100011101110111010001000 + {0x8E, 0x8E, 0xEE, 0x8E}, // 0x5D | 10001110100011101110111010001110 + {0x8E, 0x8E, 0xEE, 0xE8}, // 0x5E | 10001110100011101110111011101000 + {0x8E, 0x8E, 0xEE, 0xEE}, // 0x5F | 10001110100011101110111011101110 + {0x8E, 0xE8, 0x88, 0x88}, // 0x60 | 10001110111010001000100010001000 + {0x8E, 0xE8, 0x88, 0x8E}, // 0x61 | 10001110111010001000100010001110 + {0x8E, 0xE8, 0x88, 0xE8}, // 0x62 | 10001110111010001000100011101000 + {0x8E, 0xE8, 0x88, 0xEE}, // 0x63 | 10001110111010001000100011101110 + {0x8E, 0xE8, 0x8E, 0x88}, // 0x64 | 10001110111010001000111010001000 + {0x8E, 0xE8, 0x8E, 0x8E}, // 0x65 | 10001110111010001000111010001110 + {0x8E, 0xE8, 0x8E, 0xE8}, // 0x66 | 10001110111010001000111011101000 + {0x8E, 0xE8, 0x8E, 0xEE}, // 0x67 | 10001110111010001000111011101110 + {0x8E, 0xE8, 0xE8, 0x88}, // 0x68 | 10001110111010001110100010001000 + {0x8E, 0xE8, 0xE8, 0x8E}, // 0x69 | 10001110111010001110100010001110 + {0x8E, 0xE8, 0xE8, 0xE8}, // 0x6A | 10001110111010001110100011101000 + {0x8E, 0xE8, 0xE8, 0xEE}, // 0x6B | 10001110111010001110100011101110 + {0x8E, 0xE8, 0xEE, 0x88}, // 0x6C | 10001110111010001110111010001000 + {0x8E, 0xE8, 0xEE, 0x8E}, // 0x6D | 10001110111010001110111010001110 + {0x8E, 0xE8, 0xEE, 0xE8}, // 0x6E | 10001110111010001110111011101000 + {0x8E, 0xE8, 0xEE, 0xEE}, // 0x6F | 10001110111010001110111011101110 + {0x8E, 0xEE, 0x88, 0x88}, // 0x70 | 10001110111011101000100010001000 + {0x8E, 0xEE, 0x88, 0x8E}, // 0x71 | 10001110111011101000100010001110 + {0x8E, 0xEE, 0x88, 0xE8}, // 0x72 | 10001110111011101000100011101000 + {0x8E, 0xEE, 0x88, 0xEE}, // 0x73 | 10001110111011101000100011101110 + {0x8E, 0xEE, 0x8E, 0x88}, // 0x74 | 10001110111011101000111010001000 + {0x8E, 0xEE, 0x8E, 0x8E}, // 0x75 | 10001110111011101000111010001110 + {0x8E, 0xEE, 0x8E, 0xE8}, // 0x76 | 10001110111011101000111011101000 + {0x8E, 0xEE, 0x8E, 0xEE}, // 0x77 | 10001110111011101000111011101110 + {0x8E, 0xEE, 0xE8, 0x88}, // 0x78 | 10001110111011101110100010001000 + {0x8E, 0xEE, 0xE8, 0x8E}, // 0x79 | 10001110111011101110100010001110 + {0x8E, 0xEE, 0xE8, 0xE8}, // 0x7A | 10001110111011101110100011101000 + {0x8E, 0xEE, 0xE8, 0xEE}, // 0x7B | 10001110111011101110100011101110 + {0x8E, 0xEE, 0xEE, 0x88}, // 0x7C | 10001110111011101110111010001000 + {0x8E, 0xEE, 0xEE, 0x8E}, // 0x7D | 10001110111011101110111010001110 + {0x8E, 0xEE, 0xEE, 0xE8}, // 0x7E | 10001110111011101110111011101000 + {0x8E, 0xEE, 0xEE, 0xEE}, // 0x7F | 10001110111011101110111011101110 + {0xE8, 0x88, 0x88, 0x88}, // 0x80 | 11101000100010001000100010001000 + {0xE8, 0x88, 0x88, 0x8E}, // 0x81 | 11101000100010001000100010001110 + {0xE8, 0x88, 0x88, 0xE8}, // 0x82 | 11101000100010001000100011101000 + {0xE8, 0x88, 0x88, 0xEE}, // 0x83 | 11101000100010001000100011101110 + {0xE8, 0x88, 0x8E, 0x88}, // 0x84 | 11101000100010001000111010001000 + {0xE8, 0x88, 0x8E, 0x8E}, // 0x85 | 11101000100010001000111010001110 + {0xE8, 0x88, 0x8E, 0xE8}, // 0x86 | 11101000100010001000111011101000 + {0xE8, 0x88, 0x8E, 0xEE}, // 0x87 | 11101000100010001000111011101110 + {0xE8, 0x88, 0xE8, 0x88}, // 0x88 | 11101000100010001110100010001000 + {0xE8, 0x88, 0xE8, 0x8E}, // 0x89 | 11101000100010001110100010001110 + {0xE8, 0x88, 0xE8, 0xE8}, // 0x8A | 11101000100010001110100011101000 + {0xE8, 0x88, 0xE8, 0xEE}, // 0x8B | 11101000100010001110100011101110 + {0xE8, 0x88, 0xEE, 0x88}, // 0x8C | 11101000100010001110111010001000 + {0xE8, 0x88, 0xEE, 0x8E}, // 0x8D | 11101000100010001110111010001110 + {0xE8, 0x88, 0xEE, 0xE8}, // 0x8E | 11101000100010001110111011101000 + {0xE8, 0x88, 0xEE, 0xEE}, // 0x8F | 11101000100010001110111011101110 + {0xE8, 0x8E, 0x88, 0x88}, // 0x90 | 11101000100011101000100010001000 + {0xE8, 0x8E, 0x88, 0x8E}, // 0x91 | 11101000100011101000100010001110 + {0xE8, 0x8E, 0x88, 0xE8}, // 0x92 | 11101000100011101000100011101000 + {0xE8, 0x8E, 0x88, 0xEE}, // 0x93 | 11101000100011101000100011101110 + {0xE8, 0x8E, 0x8E, 0x88}, // 0x94 | 11101000100011101000111010001000 + {0xE8, 0x8E, 0x8E, 0x8E}, // 0x95 | 11101000100011101000111010001110 + {0xE8, 0x8E, 0x8E, 0xE8}, // 0x96 | 11101000100011101000111011101000 + {0xE8, 0x8E, 0x8E, 0xEE}, // 0x97 | 11101000100011101000111011101110 + {0xE8, 0x8E, 0xE8, 0x88}, // 0x98 | 11101000100011101110100010001000 + {0xE8, 0x8E, 0xE8, 0x8E}, // 0x99 | 11101000100011101110100010001110 + {0xE8, 0x8E, 0xE8, 0xE8}, // 0x9A | 11101000100011101110100011101000 + {0xE8, 0x8E, 0xE8, 0xEE}, // 0x9B | 11101000100011101110100011101110 + {0xE8, 0x8E, 0xEE, 0x88}, // 0x9C | 11101000100011101110111010001000 + {0xE8, 0x8E, 0xEE, 0x8E}, // 0x9D | 11101000100011101110111010001110 + {0xE8, 0x8E, 0xEE, 0xE8}, // 0x9E | 11101000100011101110111011101000 + {0xE8, 0x8E, 0xEE, 0xEE}, // 0x9F | 11101000100011101110111011101110 + {0xE8, 0xE8, 0x88, 0x88}, // 0xA0 | 11101000111010001000100010001000 + {0xE8, 0xE8, 0x88, 0x8E}, // 0xA1 | 11101000111010001000100010001110 + {0xE8, 0xE8, 0x88, 0xE8}, // 0xA2 | 11101000111010001000100011101000 + {0xE8, 0xE8, 0x88, 0xEE}, // 0xA3 | 11101000111010001000100011101110 + {0xE8, 0xE8, 0x8E, 0x88}, // 0xA4 | 11101000111010001000111010001000 + {0xE8, 0xE8, 0x8E, 0x8E}, // 0xA5 | 11101000111010001000111010001110 + {0xE8, 0xE8, 0x8E, 0xE8}, // 0xA6 | 11101000111010001000111011101000 + {0xE8, 0xE8, 0x8E, 0xEE}, // 0xA7 | 11101000111010001000111011101110 + {0xE8, 0xE8, 0xE8, 0x88}, // 0xA8 | 11101000111010001110100010001000 + {0xE8, 0xE8, 0xE8, 0x8E}, // 0xA9 | 11101000111010001110100010001110 + {0xE8, 0xE8, 0xE8, 0xE8}, // 0xAA | 11101000111010001110100011101000 + {0xE8, 0xE8, 0xE8, 0xEE}, // 0xAB | 11101000111010001110100011101110 + {0xE8, 0xE8, 0xEE, 0x88}, // 0xAC | 11101000111010001110111010001000 + {0xE8, 0xE8, 0xEE, 0x8E}, // 0xAD | 11101000111010001110111010001110 + {0xE8, 0xE8, 0xEE, 0xE8}, // 0xAE | 11101000111010001110111011101000 + {0xE8, 0xE8, 0xEE, 0xEE}, // 0xAF | 11101000111010001110111011101110 + {0xE8, 0xEE, 0x88, 0x88}, // 0xB0 | 11101000111011101000100010001000 + {0xE8, 0xEE, 0x88, 0x8E}, // 0xB1 | 11101000111011101000100010001110 + {0xE8, 0xEE, 0x88, 0xE8}, // 0xB2 | 11101000111011101000100011101000 + {0xE8, 0xEE, 0x88, 0xEE}, // 0xB3 | 11101000111011101000100011101110 + {0xE8, 0xEE, 0x8E, 0x88}, // 0xB4 | 11101000111011101000111010001000 + {0xE8, 0xEE, 0x8E, 0x8E}, // 0xB5 | 11101000111011101000111010001110 + {0xE8, 0xEE, 0x8E, 0xE8}, // 0xB6 | 11101000111011101000111011101000 + {0xE8, 0xEE, 0x8E, 0xEE}, // 0xB7 | 11101000111011101000111011101110 + {0xE8, 0xEE, 0xE8, 0x88}, // 0xB8 | 11101000111011101110100010001000 + {0xE8, 0xEE, 0xE8, 0x8E}, // 0xB9 | 11101000111011101110100010001110 + {0xE8, 0xEE, 0xE8, 0xE8}, // 0xBA | 11101000111011101110100011101000 + {0xE8, 0xEE, 0xE8, 0xEE}, // 0xBB | 11101000111011101110100011101110 + {0xE8, 0xEE, 0xEE, 0x88}, // 0xBC | 11101000111011101110111010001000 + {0xE8, 0xEE, 0xEE, 0x8E}, // 0xBD | 11101000111011101110111010001110 + {0xE8, 0xEE, 0xEE, 0xE8}, // 0xBE | 11101000111011101110111011101000 + {0xE8, 0xEE, 0xEE, 0xEE}, // 0xBF | 11101000111011101110111011101110 + {0xEE, 0x88, 0x88, 0x88}, // 0xC0 | 11101110100010001000100010001000 + {0xEE, 0x88, 0x88, 0x8E}, // 0xC1 | 11101110100010001000100010001110 + {0xEE, 0x88, 0x88, 0xE8}, // 0xC2 | 11101110100010001000100011101000 + {0xEE, 0x88, 0x88, 0xEE}, // 0xC3 | 11101110100010001000100011101110 + {0xEE, 0x88, 0x8E, 0x88}, // 0xC4 | 11101110100010001000111010001000 + {0xEE, 0x88, 0x8E, 0x8E}, // 0xC5 | 11101110100010001000111010001110 + {0xEE, 0x88, 0x8E, 0xE8}, // 0xC6 | 11101110100010001000111011101000 + {0xEE, 0x88, 0x8E, 0xEE}, // 0xC7 | 11101110100010001000111011101110 + {0xEE, 0x88, 0xE8, 0x88}, // 0xC8 | 11101110100010001110100010001000 + {0xEE, 0x88, 0xE8, 0x8E}, // 0xC9 | 11101110100010001110100010001110 + {0xEE, 0x88, 0xE8, 0xE8}, // 0xCA | 11101110100010001110100011101000 + {0xEE, 0x88, 0xE8, 0xEE}, // 0xCB | 11101110100010001110100011101110 + {0xEE, 0x88, 0xEE, 0x88}, // 0xCC | 11101110100010001110111010001000 + {0xEE, 0x88, 0xEE, 0x8E}, // 0xCD | 11101110100010001110111010001110 + {0xEE, 0x88, 0xEE, 0xE8}, // 0xCE | 11101110100010001110111011101000 + {0xEE, 0x88, 0xEE, 0xEE}, // 0xCF | 11101110100010001110111011101110 + {0xEE, 0x8E, 0x88, 0x88}, // 0xD0 | 11101110100011101000100010001000 + {0xEE, 0x8E, 0x88, 0x8E}, // 0xD1 | 11101110100011101000100010001110 + {0xEE, 0x8E, 0x88, 0xE8}, // 0xD2 | 11101110100011101000100011101000 + {0xEE, 0x8E, 0x88, 0xEE}, // 0xD3 | 11101110100011101000100011101110 + {0xEE, 0x8E, 0x8E, 0x88}, // 0xD4 | 11101110100011101000111010001000 + {0xEE, 0x8E, 0x8E, 0x8E}, // 0xD5 | 11101110100011101000111010001110 + {0xEE, 0x8E, 0x8E, 0xE8}, // 0xD6 | 11101110100011101000111011101000 + {0xEE, 0x8E, 0x8E, 0xEE}, // 0xD7 | 11101110100011101000111011101110 + {0xEE, 0x8E, 0xE8, 0x88}, // 0xD8 | 11101110100011101110100010001000 + {0xEE, 0x8E, 0xE8, 0x8E}, // 0xD9 | 11101110100011101110100010001110 + {0xEE, 0x8E, 0xE8, 0xE8}, // 0xDA | 11101110100011101110100011101000 + {0xEE, 0x8E, 0xE8, 0xEE}, // 0xDB | 11101110100011101110100011101110 + {0xEE, 0x8E, 0xEE, 0x88}, // 0xDC | 11101110100011101110111010001000 + {0xEE, 0x8E, 0xEE, 0x8E}, // 0xDD | 11101110100011101110111010001110 + {0xEE, 0x8E, 0xEE, 0xE8}, // 0xDE | 11101110100011101110111011101000 + {0xEE, 0x8E, 0xEE, 0xEE}, // 0xDF | 11101110100011101110111011101110 + {0xEE, 0xE8, 0x88, 0x88}, // 0xE0 | 11101110111010001000100010001000 + {0xEE, 0xE8, 0x88, 0x8E}, // 0xE1 | 11101110111010001000100010001110 + {0xEE, 0xE8, 0x88, 0xE8}, // 0xE2 | 11101110111010001000100011101000 + {0xEE, 0xE8, 0x88, 0xEE}, // 0xE3 | 11101110111010001000100011101110 + {0xEE, 0xE8, 0x8E, 0x88}, // 0xE4 | 11101110111010001000111010001000 + {0xEE, 0xE8, 0x8E, 0x8E}, // 0xE5 | 11101110111010001000111010001110 + {0xEE, 0xE8, 0x8E, 0xE8}, // 0xE6 | 11101110111010001000111011101000 + {0xEE, 0xE8, 0x8E, 0xEE}, // 0xE7 | 11101110111010001000111011101110 + {0xEE, 0xE8, 0xE8, 0x88}, // 0xE8 | 11101110111010001110100010001000 + {0xEE, 0xE8, 0xE8, 0x8E}, // 0xE9 | 11101110111010001110100010001110 + {0xEE, 0xE8, 0xE8, 0xE8}, // 0xEA | 11101110111010001110100011101000 + {0xEE, 0xE8, 0xE8, 0xEE}, // 0xEB | 11101110111010001110100011101110 + {0xEE, 0xE8, 0xEE, 0x88}, // 0xEC | 11101110111010001110111010001000 + {0xEE, 0xE8, 0xEE, 0x8E}, // 0xED | 11101110111010001110111010001110 + {0xEE, 0xE8, 0xEE, 0xE8}, // 0xEE | 11101110111010001110111011101000 + {0xEE, 0xE8, 0xEE, 0xEE}, // 0xEF | 11101110111010001110111011101110 + {0xEE, 0xEE, 0x88, 0x88}, // 0xF0 | 11101110111011101000100010001000 + {0xEE, 0xEE, 0x88, 0x8E}, // 0xF1 | 11101110111011101000100010001110 + {0xEE, 0xEE, 0x88, 0xE8}, // 0xF2 | 11101110111011101000100011101000 + {0xEE, 0xEE, 0x88, 0xEE}, // 0xF3 | 11101110111011101000100011101110 + {0xEE, 0xEE, 0x8E, 0x88}, // 0xF4 | 11101110111011101000111010001000 + {0xEE, 0xEE, 0x8E, 0x8E}, // 0xF5 | 11101110111011101000111010001110 + {0xEE, 0xEE, 0x8E, 0xE8}, // 0xF6 | 11101110111011101000111011101000 + {0xEE, 0xEE, 0x8E, 0xEE}, // 0xF7 | 11101110111011101000111011101110 + {0xEE, 0xEE, 0xE8, 0x88}, // 0xF8 | 11101110111011101110100010001000 + {0xEE, 0xEE, 0xE8, 0x8E}, // 0xF9 | 11101110111011101110100010001110 + {0xEE, 0xEE, 0xE8, 0xE8}, // 0xFA | 11101110111011101110100011101000 + {0xEE, 0xEE, 0xE8, 0xEE}, // 0xFB | 11101110111011101110100011101110 + {0xEE, 0xEE, 0xEE, 0x88}, // 0xFC | 11101110111011101110111010001000 + {0xEE, 0xEE, 0xEE, 0x8E}, // 0xFD | 11101110111011101110111010001110 + {0xEE, 0xEE, 0xEE, 0xE8}, // 0xFE | 11101110111011101110111011101000 + {0xEE, 0xEE, 0xEE, 0xEE}, // 0xFF | 11101110111011101110111011101110 +} diff --git a/experimental/devices/nrzled/nrz_spi.go b/experimental/devices/nrzled/nrz_spi.go index ee483fe..0b98170 100644 --- a/experimental/devices/nrzled/nrz_spi.go +++ b/experimental/devices/nrzled/nrz_spi.go @@ -144,9 +144,9 @@ func (d *SPIDev) raster(dst []byte, src []byte, srcHasAlpha bool) { dOff := 3 * stride * i //3 channels * stride r, g, b := src[sOff], src[sOff+1], src[sOff+2] //grb color order, msb first - copy(dst[dOff+stride*0:dOff+stride*1], bitlut[r]) - copy(dst[dOff+stride*1:dOff+stride*2], bitlut[g]) - copy(dst[dOff+stride*2:dOff+stride*3], bitlut[b]) + copy(dst[dOff+stride*0:dOff+stride*1], nrzMSB4[r][:]) + copy(dst[dOff+stride*1:dOff+stride*2], nrzMSB4[g][:]) + copy(dst[dOff+stride*2:dOff+stride*3], nrzMSB4[b][:]) } } @@ -190,264 +190,3 @@ func (d *SPIDev) rasterImg(dst []byte, rect image.Rectangle, src image.Image, sr } var _ display.Drawer = &Dev{} - -// The bit lookup table converts a single byte into its 4 byte SPI symbol -// 0 => 1000 and 1 => 1110 -var bitlut = [][]byte{ - {0x88, 0x88, 0x88, 0x88}, // 0 | 0x00 | 10001000100010001000100010001000 - {0x88, 0x88, 0x88, 0x8E}, // 1 | 0x01 | 10001000100010001000100010001110 - {0x88, 0x88, 0x88, 0xE8}, // 2 | 0x02 | 10001000100010001000100011101000 - {0x88, 0x88, 0x88, 0xEE}, // 3 | 0x03 | 10001000100010001000100011101110 - {0x88, 0x88, 0x8E, 0x88}, // 4 | 0x04 | 10001000100010001000111010001000 - {0x88, 0x88, 0x8E, 0x8E}, // 5 | 0x05 | 10001000100010001000111010001110 - {0x88, 0x88, 0x8E, 0xE8}, // 6 | 0x06 | 10001000100010001000111011101000 - {0x88, 0x88, 0x8E, 0xEE}, // 7 | 0x07 | 10001000100010001000111011101110 - {0x88, 0x88, 0xE8, 0x88}, // 8 | 0x08 | 10001000100010001110100010001000 - {0x88, 0x88, 0xE8, 0x8E}, // 9 | 0x09 | 10001000100010001110100010001110 - {0x88, 0x88, 0xE8, 0xE8}, // 10 | 0x0A | 10001000100010001110100011101000 - {0x88, 0x88, 0xE8, 0xEE}, // 11 | 0x0B | 10001000100010001110100011101110 - {0x88, 0x88, 0xEE, 0x88}, // 12 | 0x0C | 10001000100010001110111010001000 - {0x88, 0x88, 0xEE, 0x8E}, // 13 | 0x0D | 10001000100010001110111010001110 - {0x88, 0x88, 0xEE, 0xE8}, // 14 | 0x0E | 10001000100010001110111011101000 - {0x88, 0x88, 0xEE, 0xEE}, // 15 | 0x0F | 10001000100010001110111011101110 - {0x88, 0x8E, 0x88, 0x88}, // 16 | 0x10 | 10001000100011101000100010001000 - {0x88, 0x8E, 0x88, 0x8E}, // 17 | 0x11 | 10001000100011101000100010001110 - {0x88, 0x8E, 0x88, 0xE8}, // 18 | 0x12 | 10001000100011101000100011101000 - {0x88, 0x8E, 0x88, 0xEE}, // 19 | 0x13 | 10001000100011101000100011101110 - {0x88, 0x8E, 0x8E, 0x88}, // 20 | 0x14 | 10001000100011101000111010001000 - {0x88, 0x8E, 0x8E, 0x8E}, // 21 | 0x15 | 10001000100011101000111010001110 - {0x88, 0x8E, 0x8E, 0xE8}, // 22 | 0x16 | 10001000100011101000111011101000 - {0x88, 0x8E, 0x8E, 0xEE}, // 23 | 0x17 | 10001000100011101000111011101110 - {0x88, 0x8E, 0xE8, 0x88}, // 24 | 0x18 | 10001000100011101110100010001000 - {0x88, 0x8E, 0xE8, 0x8E}, // 25 | 0x19 | 10001000100011101110100010001110 - {0x88, 0x8E, 0xE8, 0xE8}, // 26 | 0x1A | 10001000100011101110100011101000 - {0x88, 0x8E, 0xE8, 0xEE}, // 27 | 0x1B | 10001000100011101110100011101110 - {0x88, 0x8E, 0xEE, 0x88}, // 28 | 0x1C | 10001000100011101110111010001000 - {0x88, 0x8E, 0xEE, 0x8E}, // 29 | 0x1D | 10001000100011101110111010001110 - {0x88, 0x8E, 0xEE, 0xE8}, // 30 | 0x1E | 10001000100011101110111011101000 - {0x88, 0x8E, 0xEE, 0xEE}, // 31 | 0x1F | 10001000100011101110111011101110 - {0x88, 0xE8, 0x88, 0x88}, // 32 | 0x20 | 10001000111010001000100010001000 - {0x88, 0xE8, 0x88, 0x8E}, // 33 | 0x21 | 10001000111010001000100010001110 - {0x88, 0xE8, 0x88, 0xE8}, // 34 | 0x22 | 10001000111010001000100011101000 - {0x88, 0xE8, 0x88, 0xEE}, // 35 | 0x23 | 10001000111010001000100011101110 - {0x88, 0xE8, 0x8E, 0x88}, // 36 | 0x24 | 10001000111010001000111010001000 - {0x88, 0xE8, 0x8E, 0x8E}, // 37 | 0x25 | 10001000111010001000111010001110 - {0x88, 0xE8, 0x8E, 0xE8}, // 38 | 0x26 | 10001000111010001000111011101000 - {0x88, 0xE8, 0x8E, 0xEE}, // 39 | 0x27 | 10001000111010001000111011101110 - {0x88, 0xE8, 0xE8, 0x88}, // 40 | 0x28 | 10001000111010001110100010001000 - {0x88, 0xE8, 0xE8, 0x8E}, // 41 | 0x29 | 10001000111010001110100010001110 - {0x88, 0xE8, 0xE8, 0xE8}, // 42 | 0x2A | 10001000111010001110100011101000 - {0x88, 0xE8, 0xE8, 0xEE}, // 43 | 0x2B | 10001000111010001110100011101110 - {0x88, 0xE8, 0xEE, 0x88}, // 44 | 0x2C | 10001000111010001110111010001000 - {0x88, 0xE8, 0xEE, 0x8E}, // 45 | 0x2D | 10001000111010001110111010001110 - {0x88, 0xE8, 0xEE, 0xE8}, // 46 | 0x2E | 10001000111010001110111011101000 - {0x88, 0xE8, 0xEE, 0xEE}, // 47 | 0x2F | 10001000111010001110111011101110 - {0x88, 0xEE, 0x88, 0x88}, // 48 | 0x30 | 10001000111011101000100010001000 - {0x88, 0xEE, 0x88, 0x8E}, // 49 | 0x31 | 10001000111011101000100010001110 - {0x88, 0xEE, 0x88, 0xE8}, // 50 | 0x32 | 10001000111011101000100011101000 - {0x88, 0xEE, 0x88, 0xEE}, // 51 | 0x33 | 10001000111011101000100011101110 - {0x88, 0xEE, 0x8E, 0x88}, // 52 | 0x34 | 10001000111011101000111010001000 - {0x88, 0xEE, 0x8E, 0x8E}, // 53 | 0x35 | 10001000111011101000111010001110 - {0x88, 0xEE, 0x8E, 0xE8}, // 54 | 0x36 | 10001000111011101000111011101000 - {0x88, 0xEE, 0x8E, 0xEE}, // 55 | 0x37 | 10001000111011101000111011101110 - {0x88, 0xEE, 0xE8, 0x88}, // 56 | 0x38 | 10001000111011101110100010001000 - {0x88, 0xEE, 0xE8, 0x8E}, // 57 | 0x39 | 10001000111011101110100010001110 - {0x88, 0xEE, 0xE8, 0xE8}, // 58 | 0x3A | 10001000111011101110100011101000 - {0x88, 0xEE, 0xE8, 0xEE}, // 59 | 0x3B | 10001000111011101110100011101110 - {0x88, 0xEE, 0xEE, 0x88}, // 60 | 0x3C | 10001000111011101110111010001000 - {0x88, 0xEE, 0xEE, 0x8E}, // 61 | 0x3D | 10001000111011101110111010001110 - {0x88, 0xEE, 0xEE, 0xE8}, // 62 | 0x3E | 10001000111011101110111011101000 - {0x88, 0xEE, 0xEE, 0xEE}, // 63 | 0x3F | 10001000111011101110111011101110 - {0x8E, 0x88, 0x88, 0x88}, // 64 | 0x40 | 10001110100010001000100010001000 - {0x8E, 0x88, 0x88, 0x8E}, // 65 | 0x41 | 10001110100010001000100010001110 - {0x8E, 0x88, 0x88, 0xE8}, // 66 | 0x42 | 10001110100010001000100011101000 - {0x8E, 0x88, 0x88, 0xEE}, // 67 | 0x43 | 10001110100010001000100011101110 - {0x8E, 0x88, 0x8E, 0x88}, // 68 | 0x44 | 10001110100010001000111010001000 - {0x8E, 0x88, 0x8E, 0x8E}, // 69 | 0x45 | 10001110100010001000111010001110 - {0x8E, 0x88, 0x8E, 0xE8}, // 70 | 0x46 | 10001110100010001000111011101000 - {0x8E, 0x88, 0x8E, 0xEE}, // 71 | 0x47 | 10001110100010001000111011101110 - {0x8E, 0x88, 0xE8, 0x88}, // 72 | 0x48 | 10001110100010001110100010001000 - {0x8E, 0x88, 0xE8, 0x8E}, // 73 | 0x49 | 10001110100010001110100010001110 - {0x8E, 0x88, 0xE8, 0xE8}, // 74 | 0x4A | 10001110100010001110100011101000 - {0x8E, 0x88, 0xE8, 0xEE}, // 75 | 0x4B | 10001110100010001110100011101110 - {0x8E, 0x88, 0xEE, 0x88}, // 76 | 0x4C | 10001110100010001110111010001000 - {0x8E, 0x88, 0xEE, 0x8E}, // 77 | 0x4D | 10001110100010001110111010001110 - {0x8E, 0x88, 0xEE, 0xE8}, // 78 | 0x4E | 10001110100010001110111011101000 - {0x8E, 0x88, 0xEE, 0xEE}, // 79 | 0x4F | 10001110100010001110111011101110 - {0x8E, 0x8E, 0x88, 0x88}, // 80 | 0x50 | 10001110100011101000100010001000 - {0x8E, 0x8E, 0x88, 0x8E}, // 81 | 0x51 | 10001110100011101000100010001110 - {0x8E, 0x8E, 0x88, 0xE8}, // 82 | 0x52 | 10001110100011101000100011101000 - {0x8E, 0x8E, 0x88, 0xEE}, // 83 | 0x53 | 10001110100011101000100011101110 - {0x8E, 0x8E, 0x8E, 0x88}, // 84 | 0x54 | 10001110100011101000111010001000 - {0x8E, 0x8E, 0x8E, 0x8E}, // 85 | 0x55 | 10001110100011101000111010001110 - {0x8E, 0x8E, 0x8E, 0xE8}, // 86 | 0x56 | 10001110100011101000111011101000 - {0x8E, 0x8E, 0x8E, 0xEE}, // 87 | 0x57 | 10001110100011101000111011101110 - {0x8E, 0x8E, 0xE8, 0x88}, // 88 | 0x58 | 10001110100011101110100010001000 - {0x8E, 0x8E, 0xE8, 0x8E}, // 89 | 0x59 | 10001110100011101110100010001110 - {0x8E, 0x8E, 0xE8, 0xE8}, // 90 | 0x5A | 10001110100011101110100011101000 - {0x8E, 0x8E, 0xE8, 0xEE}, // 91 | 0x5B | 10001110100011101110100011101110 - {0x8E, 0x8E, 0xEE, 0x88}, // 92 | 0x5C | 10001110100011101110111010001000 - {0x8E, 0x8E, 0xEE, 0x8E}, // 93 | 0x5D | 10001110100011101110111010001110 - {0x8E, 0x8E, 0xEE, 0xE8}, // 94 | 0x5E | 10001110100011101110111011101000 - {0x8E, 0x8E, 0xEE, 0xEE}, // 95 | 0x5F | 10001110100011101110111011101110 - {0x8E, 0xE8, 0x88, 0x88}, // 96 | 0x60 | 10001110111010001000100010001000 - {0x8E, 0xE8, 0x88, 0x8E}, // 97 | 0x61 | 10001110111010001000100010001110 - {0x8E, 0xE8, 0x88, 0xE8}, // 98 | 0x62 | 10001110111010001000100011101000 - {0x8E, 0xE8, 0x88, 0xEE}, // 99 | 0x63 | 10001110111010001000100011101110 - {0x8E, 0xE8, 0x8E, 0x88}, //100 | 0x64 | 10001110111010001000111010001000 - {0x8E, 0xE8, 0x8E, 0x8E}, //101 | 0x65 | 10001110111010001000111010001110 - {0x8E, 0xE8, 0x8E, 0xE8}, //102 | 0x66 | 10001110111010001000111011101000 - {0x8E, 0xE8, 0x8E, 0xEE}, //103 | 0x67 | 10001110111010001000111011101110 - {0x8E, 0xE8, 0xE8, 0x88}, //104 | 0x68 | 10001110111010001110100010001000 - {0x8E, 0xE8, 0xE8, 0x8E}, //105 | 0x69 | 10001110111010001110100010001110 - {0x8E, 0xE8, 0xE8, 0xE8}, //106 | 0x6A | 10001110111010001110100011101000 - {0x8E, 0xE8, 0xE8, 0xEE}, //107 | 0x6B | 10001110111010001110100011101110 - {0x8E, 0xE8, 0xEE, 0x88}, //108 | 0x6C | 10001110111010001110111010001000 - {0x8E, 0xE8, 0xEE, 0x8E}, //109 | 0x6D | 10001110111010001110111010001110 - {0x8E, 0xE8, 0xEE, 0xE8}, //110 | 0x6E | 10001110111010001110111011101000 - {0x8E, 0xE8, 0xEE, 0xEE}, //111 | 0x6F | 10001110111010001110111011101110 - {0x8E, 0xEE, 0x88, 0x88}, //112 | 0x70 | 10001110111011101000100010001000 - {0x8E, 0xEE, 0x88, 0x8E}, //113 | 0x71 | 10001110111011101000100010001110 - {0x8E, 0xEE, 0x88, 0xE8}, //114 | 0x72 | 10001110111011101000100011101000 - {0x8E, 0xEE, 0x88, 0xEE}, //115 | 0x73 | 10001110111011101000100011101110 - {0x8E, 0xEE, 0x8E, 0x88}, //116 | 0x74 | 10001110111011101000111010001000 - {0x8E, 0xEE, 0x8E, 0x8E}, //117 | 0x75 | 10001110111011101000111010001110 - {0x8E, 0xEE, 0x8E, 0xE8}, //118 | 0x76 | 10001110111011101000111011101000 - {0x8E, 0xEE, 0x8E, 0xEE}, //119 | 0x77 | 10001110111011101000111011101110 - {0x8E, 0xEE, 0xE8, 0x88}, //120 | 0x78 | 10001110111011101110100010001000 - {0x8E, 0xEE, 0xE8, 0x8E}, //121 | 0x79 | 10001110111011101110100010001110 - {0x8E, 0xEE, 0xE8, 0xE8}, //122 | 0x7A | 10001110111011101110100011101000 - {0x8E, 0xEE, 0xE8, 0xEE}, //123 | 0x7B | 10001110111011101110100011101110 - {0x8E, 0xEE, 0xEE, 0x88}, //124 | 0x7C | 10001110111011101110111010001000 - {0x8E, 0xEE, 0xEE, 0x8E}, //125 | 0x7D | 10001110111011101110111010001110 - {0x8E, 0xEE, 0xEE, 0xE8}, //126 | 0x7E | 10001110111011101110111011101000 - {0x8E, 0xEE, 0xEE, 0xEE}, //127 | 0x7F | 10001110111011101110111011101110 - {0xE8, 0x88, 0x88, 0x88}, //128 | 0x80 | 11101000100010001000100010001000 - {0xE8, 0x88, 0x88, 0x8E}, //129 | 0x81 | 11101000100010001000100010001110 - {0xE8, 0x88, 0x88, 0xE8}, //130 | 0x82 | 11101000100010001000100011101000 - {0xE8, 0x88, 0x88, 0xEE}, //131 | 0x83 | 11101000100010001000100011101110 - {0xE8, 0x88, 0x8E, 0x88}, //132 | 0x84 | 11101000100010001000111010001000 - {0xE8, 0x88, 0x8E, 0x8E}, //133 | 0x85 | 11101000100010001000111010001110 - {0xE8, 0x88, 0x8E, 0xE8}, //134 | 0x86 | 11101000100010001000111011101000 - {0xE8, 0x88, 0x8E, 0xEE}, //135 | 0x87 | 11101000100010001000111011101110 - {0xE8, 0x88, 0xE8, 0x88}, //136 | 0x88 | 11101000100010001110100010001000 - {0xE8, 0x88, 0xE8, 0x8E}, //137 | 0x89 | 11101000100010001110100010001110 - {0xE8, 0x88, 0xE8, 0xE8}, //138 | 0x8A | 11101000100010001110100011101000 - {0xE8, 0x88, 0xE8, 0xEE}, //139 | 0x8B | 11101000100010001110100011101110 - {0xE8, 0x88, 0xEE, 0x88}, //140 | 0x8C | 11101000100010001110111010001000 - {0xE8, 0x88, 0xEE, 0x8E}, //141 | 0x8D | 11101000100010001110111010001110 - {0xE8, 0x88, 0xEE, 0xE8}, //142 | 0x8E | 11101000100010001110111011101000 - {0xE8, 0x88, 0xEE, 0xEE}, //143 | 0x8F | 11101000100010001110111011101110 - {0xE8, 0x8E, 0x88, 0x88}, //144 | 0x90 | 11101000100011101000100010001000 - {0xE8, 0x8E, 0x88, 0x8E}, //145 | 0x91 | 11101000100011101000100010001110 - {0xE8, 0x8E, 0x88, 0xE8}, //146 | 0x92 | 11101000100011101000100011101000 - {0xE8, 0x8E, 0x88, 0xEE}, //147 | 0x93 | 11101000100011101000100011101110 - {0xE8, 0x8E, 0x8E, 0x88}, //148 | 0x94 | 11101000100011101000111010001000 - {0xE8, 0x8E, 0x8E, 0x8E}, //149 | 0x95 | 11101000100011101000111010001110 - {0xE8, 0x8E, 0x8E, 0xE8}, //150 | 0x96 | 11101000100011101000111011101000 - {0xE8, 0x8E, 0x8E, 0xEE}, //151 | 0x97 | 11101000100011101000111011101110 - {0xE8, 0x8E, 0xE8, 0x88}, //152 | 0x98 | 11101000100011101110100010001000 - {0xE8, 0x8E, 0xE8, 0x8E}, //153 | 0x99 | 11101000100011101110100010001110 - {0xE8, 0x8E, 0xE8, 0xE8}, //154 | 0x9A | 11101000100011101110100011101000 - {0xE8, 0x8E, 0xE8, 0xEE}, //155 | 0x9B | 11101000100011101110100011101110 - {0xE8, 0x8E, 0xEE, 0x88}, //156 | 0x9C | 11101000100011101110111010001000 - {0xE8, 0x8E, 0xEE, 0x8E}, //157 | 0x9D | 11101000100011101110111010001110 - {0xE8, 0x8E, 0xEE, 0xE8}, //158 | 0x9E | 11101000100011101110111011101000 - {0xE8, 0x8E, 0xEE, 0xEE}, //159 | 0x9F | 11101000100011101110111011101110 - {0xE8, 0xE8, 0x88, 0x88}, //160 | 0xA0 | 11101000111010001000100010001000 - {0xE8, 0xE8, 0x88, 0x8E}, //161 | 0xA1 | 11101000111010001000100010001110 - {0xE8, 0xE8, 0x88, 0xE8}, //162 | 0xA2 | 11101000111010001000100011101000 - {0xE8, 0xE8, 0x88, 0xEE}, //163 | 0xA3 | 11101000111010001000100011101110 - {0xE8, 0xE8, 0x8E, 0x88}, //164 | 0xA4 | 11101000111010001000111010001000 - {0xE8, 0xE8, 0x8E, 0x8E}, //165 | 0xA5 | 11101000111010001000111010001110 - {0xE8, 0xE8, 0x8E, 0xE8}, //166 | 0xA6 | 11101000111010001000111011101000 - {0xE8, 0xE8, 0x8E, 0xEE}, //167 | 0xA7 | 11101000111010001000111011101110 - {0xE8, 0xE8, 0xE8, 0x88}, //168 | 0xA8 | 11101000111010001110100010001000 - {0xE8, 0xE8, 0xE8, 0x8E}, //169 | 0xA9 | 11101000111010001110100010001110 - {0xE8, 0xE8, 0xE8, 0xE8}, //170 | 0xAA | 11101000111010001110100011101000 - {0xE8, 0xE8, 0xE8, 0xEE}, //171 | 0xAB | 11101000111010001110100011101110 - {0xE8, 0xE8, 0xEE, 0x88}, //172 | 0xAC | 11101000111010001110111010001000 - {0xE8, 0xE8, 0xEE, 0x8E}, //173 | 0xAD | 11101000111010001110111010001110 - {0xE8, 0xE8, 0xEE, 0xE8}, //174 | 0xAE | 11101000111010001110111011101000 - {0xE8, 0xE8, 0xEE, 0xEE}, //175 | 0xAF | 11101000111010001110111011101110 - {0xE8, 0xEE, 0x88, 0x88}, //176 | 0xB0 | 11101000111011101000100010001000 - {0xE8, 0xEE, 0x88, 0x8E}, //177 | 0xB1 | 11101000111011101000100010001110 - {0xE8, 0xEE, 0x88, 0xE8}, //178 | 0xB2 | 11101000111011101000100011101000 - {0xE8, 0xEE, 0x88, 0xEE}, //179 | 0xB3 | 11101000111011101000100011101110 - {0xE8, 0xEE, 0x8E, 0x88}, //180 | 0xB4 | 11101000111011101000111010001000 - {0xE8, 0xEE, 0x8E, 0x8E}, //181 | 0xB5 | 11101000111011101000111010001110 - {0xE8, 0xEE, 0x8E, 0xE8}, //182 | 0xB6 | 11101000111011101000111011101000 - {0xE8, 0xEE, 0x8E, 0xEE}, //183 | 0xB7 | 11101000111011101000111011101110 - {0xE8, 0xEE, 0xE8, 0x88}, //184 | 0xB8 | 11101000111011101110100010001000 - {0xE8, 0xEE, 0xE8, 0x8E}, //185 | 0xB9 | 11101000111011101110100010001110 - {0xE8, 0xEE, 0xE8, 0xE8}, //186 | 0xBA | 11101000111011101110100011101000 - {0xE8, 0xEE, 0xE8, 0xEE}, //187 | 0xBB | 11101000111011101110100011101110 - {0xE8, 0xEE, 0xEE, 0x88}, //188 | 0xBC | 11101000111011101110111010001000 - {0xE8, 0xEE, 0xEE, 0x8E}, //189 | 0xBD | 11101000111011101110111010001110 - {0xE8, 0xEE, 0xEE, 0xE8}, //190 | 0xBE | 11101000111011101110111011101000 - {0xE8, 0xEE, 0xEE, 0xEE}, //191 | 0xBF | 11101000111011101110111011101110 - {0xEE, 0x88, 0x88, 0x88}, //192 | 0xC0 | 11101110100010001000100010001000 - {0xEE, 0x88, 0x88, 0x8E}, //193 | 0xC1 | 11101110100010001000100010001110 - {0xEE, 0x88, 0x88, 0xE8}, //194 | 0xC2 | 11101110100010001000100011101000 - {0xEE, 0x88, 0x88, 0xEE}, //195 | 0xC3 | 11101110100010001000100011101110 - {0xEE, 0x88, 0x8E, 0x88}, //196 | 0xC4 | 11101110100010001000111010001000 - {0xEE, 0x88, 0x8E, 0x8E}, //197 | 0xC5 | 11101110100010001000111010001110 - {0xEE, 0x88, 0x8E, 0xE8}, //198 | 0xC6 | 11101110100010001000111011101000 - {0xEE, 0x88, 0x8E, 0xEE}, //199 | 0xC7 | 11101110100010001000111011101110 - {0xEE, 0x88, 0xE8, 0x88}, //200 | 0xC8 | 11101110100010001110100010001000 - {0xEE, 0x88, 0xE8, 0x8E}, //201 | 0xC9 | 11101110100010001110100010001110 - {0xEE, 0x88, 0xE8, 0xE8}, //202 | 0xCA | 11101110100010001110100011101000 - {0xEE, 0x88, 0xE8, 0xEE}, //203 | 0xCB | 11101110100010001110100011101110 - {0xEE, 0x88, 0xEE, 0x88}, //204 | 0xCC | 11101110100010001110111010001000 - {0xEE, 0x88, 0xEE, 0x8E}, //205 | 0xCD | 11101110100010001110111010001110 - {0xEE, 0x88, 0xEE, 0xE8}, //206 | 0xCE | 11101110100010001110111011101000 - {0xEE, 0x88, 0xEE, 0xEE}, //207 | 0xCF | 11101110100010001110111011101110 - {0xEE, 0x8E, 0x88, 0x88}, //208 | 0xD0 | 11101110100011101000100010001000 - {0xEE, 0x8E, 0x88, 0x8E}, //209 | 0xD1 | 11101110100011101000100010001110 - {0xEE, 0x8E, 0x88, 0xE8}, //210 | 0xD2 | 11101110100011101000100011101000 - {0xEE, 0x8E, 0x88, 0xEE}, //211 | 0xD3 | 11101110100011101000100011101110 - {0xEE, 0x8E, 0x8E, 0x88}, //212 | 0xD4 | 11101110100011101000111010001000 - {0xEE, 0x8E, 0x8E, 0x8E}, //213 | 0xD5 | 11101110100011101000111010001110 - {0xEE, 0x8E, 0x8E, 0xE8}, //214 | 0xD6 | 11101110100011101000111011101000 - {0xEE, 0x8E, 0x8E, 0xEE}, //215 | 0xD7 | 11101110100011101000111011101110 - {0xEE, 0x8E, 0xE8, 0x88}, //216 | 0xD8 | 11101110100011101110100010001000 - {0xEE, 0x8E, 0xE8, 0x8E}, //217 | 0xD9 | 11101110100011101110100010001110 - {0xEE, 0x8E, 0xE8, 0xE8}, //218 | 0xDA | 11101110100011101110100011101000 - {0xEE, 0x8E, 0xE8, 0xEE}, //219 | 0xDB | 11101110100011101110100011101110 - {0xEE, 0x8E, 0xEE, 0x88}, //220 | 0xDC | 11101110100011101110111010001000 - {0xEE, 0x8E, 0xEE, 0x8E}, //221 | 0xDD | 11101110100011101110111010001110 - {0xEE, 0x8E, 0xEE, 0xE8}, //222 | 0xDE | 11101110100011101110111011101000 - {0xEE, 0x8E, 0xEE, 0xEE}, //223 | 0xDF | 11101110100011101110111011101110 - {0xEE, 0xE8, 0x88, 0x88}, //224 | 0xE0 | 11101110111010001000100010001000 - {0xEE, 0xE8, 0x88, 0x8E}, //225 | 0xE1 | 11101110111010001000100010001110 - {0xEE, 0xE8, 0x88, 0xE8}, //226 | 0xE2 | 11101110111010001000100011101000 - {0xEE, 0xE8, 0x88, 0xEE}, //227 | 0xE3 | 11101110111010001000100011101110 - {0xEE, 0xE8, 0x8E, 0x88}, //228 | 0xE4 | 11101110111010001000111010001000 - {0xEE, 0xE8, 0x8E, 0x8E}, //229 | 0xE5 | 11101110111010001000111010001110 - {0xEE, 0xE8, 0x8E, 0xE8}, //230 | 0xE6 | 11101110111010001000111011101000 - {0xEE, 0xE8, 0x8E, 0xEE}, //231 | 0xE7 | 11101110111010001000111011101110 - {0xEE, 0xE8, 0xE8, 0x88}, //232 | 0xE8 | 11101110111010001110100010001000 - {0xEE, 0xE8, 0xE8, 0x8E}, //233 | 0xE9 | 11101110111010001110100010001110 - {0xEE, 0xE8, 0xE8, 0xE8}, //234 | 0xEA | 11101110111010001110100011101000 - {0xEE, 0xE8, 0xE8, 0xEE}, //235 | 0xEB | 11101110111010001110100011101110 - {0xEE, 0xE8, 0xEE, 0x88}, //236 | 0xEC | 11101110111010001110111010001000 - {0xEE, 0xE8, 0xEE, 0x8E}, //237 | 0xED | 11101110111010001110111010001110 - {0xEE, 0xE8, 0xEE, 0xE8}, //238 | 0xEE | 11101110111010001110111011101000 - {0xEE, 0xE8, 0xEE, 0xEE}, //239 | 0xEF | 11101110111010001110111011101110 - {0xEE, 0xEE, 0x88, 0x88}, //240 | 0xF0 | 11101110111011101000100010001000 - {0xEE, 0xEE, 0x88, 0x8E}, //241 | 0xF1 | 11101110111011101000100010001110 - {0xEE, 0xEE, 0x88, 0xE8}, //242 | 0xF2 | 11101110111011101000100011101000 - {0xEE, 0xEE, 0x88, 0xEE}, //243 | 0xF3 | 11101110111011101000100011101110 - {0xEE, 0xEE, 0x8E, 0x88}, //244 | 0xF4 | 11101110111011101000111010001000 - {0xEE, 0xEE, 0x8E, 0x8E}, //245 | 0xF5 | 11101110111011101000111010001110 - {0xEE, 0xEE, 0x8E, 0xE8}, //246 | 0xF6 | 11101110111011101000111011101000 - {0xEE, 0xEE, 0x8E, 0xEE}, //247 | 0xF7 | 11101110111011101000111011101110 - {0xEE, 0xEE, 0xE8, 0x88}, //248 | 0xF8 | 11101110111011101110100010001000 - {0xEE, 0xEE, 0xE8, 0x8E}, //249 | 0xF9 | 11101110111011101110100010001110 - {0xEE, 0xEE, 0xE8, 0xE8}, //250 | 0xFA | 11101110111011101110100011101000 - {0xEE, 0xEE, 0xE8, 0xEE}, //251 | 0xFB | 11101110111011101110100011101110 - {0xEE, 0xEE, 0xEE, 0x88}, //252 | 0xFC | 11101110111011101110111010001000 - {0xEE, 0xEE, 0xEE, 0x8E}, //253 | 0xFD | 11101110111011101110111010001110 - {0xEE, 0xEE, 0xEE, 0xE8}, //254 | 0xFE | 11101110111011101110111011101000 - {0xEE, 0xEE, 0xEE, 0xEE}, //255 | 0xFF | 11101110111011101110111011101110 -} diff --git a/experimental/devices/nrzled/nrz_test.go b/experimental/devices/nrzled/nrz_test.go new file mode 100644 index 0000000..3608e90 --- /dev/null +++ b/experimental/devices/nrzled/nrz_test.go @@ -0,0 +1,32 @@ +// Copyright 2018 The Periph Authors. All rights reserved. +// Use of this source code is governed under the Apache License, Version 2.0 +// that can be found in the LICENSE file. + +package nrzled + +import "testing" + +func TestNRZMSB3(t *testing.T) { + for i := 0; i < 256; i++ { + x := nrzMSB3Algo(byte(i)) + a := byte(x >> 16) + b := byte((x >> 8)) + c := byte(x) + if v := nrzMSB3[i]; a != v[0] || b != v[1] || c != v[2] { + t.Fatalf("#%d: 0x%X != 0x%X || 0x%X != 0x%X || 0x%X != 0x%X", i, a, v[0], b, v[1], c, v[2]) + } + } +} + +func TestNRZMSB4(t *testing.T) { + for i := 0; i < 256; i++ { + x := nrzMSB4Algo(byte(i)) + a := byte(x >> 24) + b := byte((x >> 16)) + c := byte((x >> 8)) + d := byte(x) + if v := nrzMSB4[i]; a != v[0] || b != v[1] || c != v[2] || d != v[3] { + t.Fatalf("#%d: 0x%X != 0x%X || 0x%X != 0x%X || 0x%X != 0x%X || 0x%X != 0x%X", i, a, v[0], b, v[1], c, v[2], d, v[3]) + } + } +} diff --git a/experimental/devices/nrzled/nrzled.go b/experimental/devices/nrzled/nrzled.go index 40a7ec8..b215240 100644 --- a/experimental/devices/nrzled/nrzled.go +++ b/experimental/devices/nrzled/nrzled.go @@ -15,32 +15,7 @@ import ( "periph.io/x/periph/conn/physic" ) -// NRZ converts a byte into the MSB-first Non-Return-to-Zero encoded 24 bits. -// -// The upper 8 bits are zeros and shall be ignored. -// -// The Non-return-to-zero protocol is a self-clocking signal that enables -// one-way communication without the need of a dedicated clock signal, unlike -// SPI driven LEDs like the apa102. -// -// See https://en.wikipedia.org/wiki/Non-return-to-zero for more technical -// details. -func NRZ(b byte) uint32 { - // The stream is 1x01x01x01x01x01x01x01x0 with the x bits being the bits from - // `b` in reverse order. - out := uint32(0x924924) - out |= uint32(b&0x80) << (3*7 + 1 - 7) - out |= uint32(b&0x40) << (3*6 + 1 - 6) - out |= uint32(b&0x20) << (3*5 + 1 - 5) - out |= uint32(b&0x10) << (3*4 + 1 - 4) - out |= uint32(b&0x08) << (3*3 + 1 - 3) - out |= uint32(b&0x04) << (3*2 + 1 - 2) - out |= uint32(b&0x02) << (3*1 + 1 - 1) - out |= uint32(b&0x01) << (3*0 + 1 - 0) - return out -} - -//A Strip is the high level interface all hardware implementations conform to +// Strip is deprecated and will soon be removed. type Strip interface { display.Drawer Write(pixels []byte) (int, error) @@ -109,14 +84,11 @@ func (d *Dev) String() string { // // It doesn't affect the back buffer. func (d *Dev) Halt() error { - zero := NRZ(0) - a := byte(zero >> 16) - b := byte(zero >> 8) - c := byte(zero) + zero := nrzMSB3[0] for i := 0; i < d.channels*d.numPixels; i++ { - d.b.Bits[3*i+0] = a - d.b.Bits[3*i+1] = b - d.b.Bits[3*i+2] = c + d.b.Bits[3*i+0] = zero[0] + d.b.Bits[3*i+1] = zero[1] + d.b.Bits[3*i+2] = zero[2] } if err := d.p.StreamOut(&d.b); err != nil { return fmt.Errorf("nrzled: %v", err) @@ -172,18 +144,18 @@ func (d *Dev) Draw(r image.Rectangle, src image.Image, sp image.Point) error { for i := 0; i < m; i++ { c := color.NRGBAModel.Convert(src.At(srcR.Min.X+i, srcR.Min.Y)).(color.NRGBA) j := 3 * i - put(d.b.Bits[3*(j+0):], c.G) - put(d.b.Bits[3*(j+1):], c.R) - put(d.b.Bits[3*(j+2):], c.B) + putNRZMSB3(d.b.Bits[3*(j+0):], c.G) + putNRZMSB3(d.b.Bits[3*(j+1):], c.R) + putNRZMSB3(d.b.Bits[3*(j+2):], c.B) } } else { for i := 0; i < m; i++ { c := color.NRGBAModel.Convert(src.At(srcR.Min.X+i, srcR.Min.Y)).(color.NRGBA) j := 4 * i - put(d.b.Bits[3*(j+0):], c.G) - put(d.b.Bits[3*(j+1):], c.R) - put(d.b.Bits[3*(j+2):], c.B) - put(d.b.Bits[3*(j+3):], c.A) + putNRZMSB3(d.b.Bits[3*(j+0):], c.G) + putNRZMSB3(d.b.Bits[3*(j+1):], c.R) + putNRZMSB3(d.b.Bits[3*(j+2):], c.B) + putNRZMSB3(d.b.Bits[3*(j+3):], c.A) } } } @@ -220,28 +192,26 @@ func raster(out, in []byte, outChannels, inChannels int) { for i := 0; i < pixels; i++ { j := i * inChannels k := 3 * i - put(out[3*(k+0):], in[j+1]) - put(out[3*(k+1):], in[j+0]) - put(out[3*(k+2):], in[j+2]) + putNRZMSB3(out[3*(k+0):], in[j+1]) + putNRZMSB3(out[3*(k+1):], in[j+0]) + putNRZMSB3(out[3*(k+2):], in[j+2]) } } else { for i := 0; i < pixels; i++ { j := i * inChannels k := 4 * i - put(out[3*(k+0):], in[j+1]) - put(out[3*(k+1):], in[j+0]) - put(out[3*(k+2):], in[j+2]) - put(out[3*(k+3):], in[j+3]) + putNRZMSB3(out[3*(k+0):], in[j+1]) + putNRZMSB3(out[3*(k+1):], in[j+0]) + putNRZMSB3(out[3*(k+2):], in[j+2]) + putNRZMSB3(out[3*(k+3):], in[j+3]) } } } -// put writes the byte v as an MSB-first NRZ encoded triplet byte into out. -func put(out []byte, v byte) { - w := NRZ(v) - out[0] = byte(w >> 16) - out[1] = byte(w >> 8) - out[2] = byte(w) +// putNRZMSB3 writes the byte v as an MSB-first NRZ encoded triplet byte into +// out. +func putNRZMSB3(out []byte, v byte) { + copy(out, nrzMSB3[v][:]) } var _ display.Drawer = &Dev{} diff --git a/experimental/devices/nrzled/nrzled_go1_7_test.go b/experimental/devices/nrzled/nrzled_go1_7_test.go deleted file mode 100644 index c5108f3..0000000 --- a/experimental/devices/nrzled/nrzled_go1_7_test.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2017 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -// +build go1.7 - -package nrzled - -import ( - "strconv" - "testing" -) - -func TestNRZ(t *testing.T) { - data := []struct { - in byte - expected uint32 - }{ - {0x00, 0x924924}, - {0x01, 0x924926}, - {0x02, 0x924934}, - {0x04, 0x9249A4}, - {0x08, 0x924D24}, - {0x10, 0x926924}, - {0x20, 0x934924}, - {0x40, 0x9A4924}, - {0x80, 0xD24924}, - {0xFD, 0xDB6DA6}, - {0xFE, 0xDB6DB4}, - {0xFF, 0xDB6DB6}, - } - for i, line := range data { - t.Run(strconv.Itoa(i), func(t *testing.T) { - if actual := NRZ(line.in); line.expected != actual { - t.Fatalf("NRZ(%X): 0x%X != 0x%X", line.in, line.expected, actual) - } - }) - } -} diff --git a/experimental/devices/nrzled/nrzled_test.go b/experimental/devices/nrzled/nrzled_test.go index cda9218..b312da6 100644 --- a/experimental/devices/nrzled/nrzled_test.go +++ b/experimental/devices/nrzled/nrzled_test.go @@ -288,15 +288,6 @@ func TestRaster_4_4(t *testing.T) { // -func BenchmarkNRZ(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - NRZ(23) - } -} - -// - // getRGB returns a buffer of 10 RGB pixels. func getRGB() []byte { return []byte{