From 2e1cc913f6e1964b5b422c6750b8310da7ff2512 Mon Sep 17 00:00:00 2001 From: Nathaniel Wesley Filardo Date: Sat, 10 Oct 2020 14:07:48 +0100 Subject: [PATCH] An initial version of a minimal ht16k33 driver --- ht16k33/ht16k33.lua | 92 +++++++++++++++++++++++++++++++++++++++++++++ ht16k33/pinouts.txt | 32 ++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 ht16k33/ht16k33.lua create mode 100644 ht16k33/pinouts.txt diff --git a/ht16k33/ht16k33.lua b/ht16k33/ht16k33.lua new file mode 100644 index 0000000..3f5239f --- /dev/null +++ b/ht16k33/ht16k33.lua @@ -0,0 +1,92 @@ +-- A very minimal HT16K33 driver, fitting for such a minimal chip! + +local M = {} + +local function tx(self, ...) + local i2c, bus, addr = i2c, self.bus, self.addr + i2c.start(bus) + i2c.address(bus, addr, i2c.TRANSMITTER) + i2c.write(bus, ...) + i2c.stop(bus) +end + +local function txrx(self, w, rn) + local i2c, bus, addr = i2c, self.bus, self.addr + i2c.start(bus) + i2c.address(bus, addr, i2c.TRANSMITTER) + i2c.write(bus, w) + i2c.start(bus) + i2c.address(bus, addr, i2c.TRANSMITTER) + local ret = i2c.read(rn) + i2c.stop(bus) + return ret +end + +-- control the primary oscillator +local function osc(self,on) + return tx(self, on and 0x21 or 0x20) +end +M.osc = osc + +M.BLINK_NONE = 0 +M.BLINK_2HZ = 1 +M.BLINK_1HZ = 2 +M.BLINK_05HZ = 3 +local function conf(self, blink, on) + return tx(self, 0x80 + (blink*2) + (on and 1 or 0)) +end +M.conf = conf + +M.KEYROW_ROW = 0 +M.KEYROW_INT_LO = 1 +M.KEYROW_INT_HI = 3 +function M:rowint(how) -- configure last row as row or interrupt + return tx(self, 0xA0 + how) +end + +-- Set brightness between 0 (which is not off, just dim) and 15 +function M:dim(bright) + return tx(self, 0xE0 + bright) +end + +-- write what (str int or string with #str <= 16) where (default to 0, 0 to 15) +-- +-- Recall that device display memory is organized by COM then ROW: the first +-- byte here is COM0 ROW0 (LSB) through COM0 ROW7 (MSB), then COM0 ROW8 (LSB) +-- through COM0 ROW15 (MSB), then COM1 ROW0 (LSB) through COM1 ROW7 (MSB), etc. +function M:write(what, where) + where = where or 0x00 + if type(what) == "table" + then return tx(self, where, table.unpack(what)) + else return tx(self, where, what) + end +end + +function M:readint() + return txrx(self, "\096", 1) +end + +function M:readkey() + return txrx(self, "\064", 5) +end + +local function blank(self) + self:write("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0") +end +M.blank = blank + +-- a convenience method for default initialization +function M:init() + osc(self, true) + blank(self) + conf(self, 0, true) +end + +M.__index = M + +return function(bus, addr) + local self = setmetatable({}, M) + self.bus, self.addr = bus, addr + + return self +end diff --git a/ht16k33/pinouts.txt b/ht16k33/pinouts.txt new file mode 100644 index 0000000..5c9cdb5 --- /dev/null +++ b/ht16k33/pinouts.txt @@ -0,0 +1,32 @@ +Adafruit 8x16 Feather +===================== + +:: + + [ 12 pin header ] + ROW0 ROW2 ... ROW14 || ROW1 ROW3 ... ROW15 + COM7 + ... + COM0 + [ 16 pin header ] + +SparkFun Qwiic Alphanumeric +=========================== + +The COLON is at ROW8 COM0 and the DOT is at ROW8 COM1. There is nothing else +on ROW8. + +Each individual digit, rendered in ASCII ART and with letters stolen from the +manufacturer's datasheet, looks like this:: + + * Digits each occupy two ROWs, always 4 apart. + AAAAAAA + FH J KB * Digits left to right are on ROW0(4) through ROW3(7). + F H J K B + F H J K B * Within each digit, segments are assigned to their COMs + G1 G2 as follows: + E N M L C + E N M L C A B C D E F G1 G2 H J K L M N + EN M LC COM 0 1 2 3 4 5 6 0 1 2 3 4 5 6 + DDDDDDD ROW 0 0 0 0 0 0 0 4 4 4 4 4 4 4 + -- 2.50.1