From a771641339831cbdb8b893c55bb69750a5b32681 Mon Sep 17 00:00:00 2001 From: Tobias Theel Date: Sat, 30 Jan 2021 16:43:09 +0100 Subject: [PATCH] max7219: add driver support --- .vscode/settings.json | 6 ++ Makefile | 6 +- README.md | 3 +- examples/max72xx/main.go | 135 +++++++++++++++++++++++++++++++++++++++ max72xx/max72xx.go | 85 ++++++++++++++++++++++++ max72xx/registers.go | 18 ++++++ 6 files changed, 251 insertions(+), 2 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 examples/max72xx/main.go create mode 100644 max72xx/max72xx.go create mode 100644 max72xx/registers.go diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..a8e65e5 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "go.toolsEnvVars": { + "GOROOT": "/home/tobias/.cache/tinygo/goroot-go1.16-65176e9981f9146086a1cca207bd1d47f4da8a15455d548a5d84fac12d1814d2-syscall", + "GOFLAGS": "-tags=arduino_nano33,atsamd21g18a,atsamd21g18,atsamd21,sam,cortexm,baremetal,linux,arm,tinygo,gc.conservative,scheduler.tasks" + } +} \ No newline at end of file diff --git a/Makefile b/Makefile index 50efd99..70f876a 100644 --- a/Makefile +++ b/Makefile @@ -165,11 +165,15 @@ endif @md5sum ./build/test.hex tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/lis2mdl/main.go @md5sum ./build/test.hex + tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/max72xx/main.go + @md5sum ./build/test.hex + tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/dht/main.go + @md5sum ./build/test.hex DRIVERS = $(wildcard */) NOTESTS = build examples flash semihosting pcd8544 shiftregister st7789 microphone mcp3008 gps microbitmatrix \ hcsr04 ssd1331 ws2812 thermistor apa102 easystepper ssd1351 ili9341 wifinina shifter hub75 \ - hd44780 buzzer ssd1306 espat l9110x st7735 bmi160 l293x + hd44780 buzzer ssd1306 espat l9110x st7735 bmi160 l293x max72xx TESTS = $(filter-out $(addsuffix /%,$(NOTESTS)),$(DRIVERS)) unit-test: diff --git a/README.md b/README.md index 0bd1625..5054b7a 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ func main() { ## Currently supported devices -The following 53 devices are supported. +The following 54 devices are supported. | Device Name | Interface Type | |----------|-------------| @@ -84,6 +84,7 @@ The following 53 devices are supported. | [LIS3DH accelerometer](https://www.st.com/resource/en/datasheet/lis3dh.pdf) | I2C | | [LSM6DS3 accelerometer](https://www.st.com/resource/en/datasheet/lsm6ds3.pdf) | I2C | | [MAG3110 magnetometer](https://www.nxp.com/docs/en/data-sheet/MAG3110.pdf) | I2C | +| [MAX7219 & MAX7221 display driver](https://datasheets.maximintegrated.com/en/ds/MAX7219-MAX7221.pdf) | SPI | | [MCP3008 analog to digital converter (ADC)](http://ww1.microchip.com/downloads/en/DeviceDoc/21295d.pdf) | SPI | | [Microphone - PDM](https://cdn-learn.adafruit.com/assets/assets/000/049/977/original/MP34DT01-M.pdf) | I2S/PDM | | [MMA8653 accelerometer](https://www.nxp.com/docs/en/data-sheet/MMA8653FC.pdf) | I2C | diff --git a/examples/max72xx/main.go b/examples/max72xx/main.go new file mode 100644 index 0000000..9569ef7 --- /dev/null +++ b/examples/max72xx/main.go @@ -0,0 +1,135 @@ +package main + +import ( + "machine" + "time" + + "tinygo.org/x/drivers/max72xx" +) + +// example for a 4 digit 7 segment display +func main() { + // Pins for Arduino Nano 33 IOT + err := machine.SPI0.Configure(machine.SPIConfig{ + SDO: machine.D11, // default SDO pin + SCK: machine.D13, // default sck pin + LSBFirst: false, + Frequency: 10000000, + }) + + if err != nil { + println(err.Error()) + } + + driver := max72xx.NewDevice(machine.SPI0, machine.D6) + driver.Configure() + + digitNumber := 4 + + driver.StopDisplayTest() + driver.SetDecodeMode(4) + driver.SetScanLimit(4) + driver.StopShutdownMode() + + for i := 1; i < int(digitNumber); i++ { + driver.WriteCommand(byte(i), byte(Blank)) + } + + for { + for _, character := range characters { + println("writing", "characterValue:", character.String()) + driver.WriteCommand(byte(4), byte(character)) + driver.WriteCommand(byte(3), byte(character)) + driver.WriteCommand(byte(2), byte(character)) + driver.WriteCommand(byte(1), byte(character)) + time.Sleep(500 * time.Millisecond) + + } + time.Sleep(time.Second) + } + +} + +var characters = []Character{ + Zero, + One, + Two, + Three, + Four, + Five, + Six, + Seven, + Eight, + Nine, + Dash, + E, + H, + L, + P, + Blank, + Dot, +} + +// Each bit translates to a pin, which is driven high or low +type Character byte + +func (char Character) String() string { + switch char { + case Zero: + return "0" + case One: + return "1" + case Two: + return "2" + case Three: + return "3" + case Four: + return "4" + case Five: + return "5" + case Six: + return "6" + case Seven: + return "7" + case Eight: + return "8" + case Nine: + return "9" + case Dash: + return "-" + case E: + return "E" + case H: + return "H" + case L: + return "L" + case P: + return "P" + case Blank: + return "" + case Dot: + return "." + } + + return "" +} + +const ( + Zero Character = 0 //126 + One Character = 1 //48 + Two Character = 2 // 109 + Three Character = 3 // 121 + Four Character = 4 + Five Character = 5 + Six Character = 6 + Seven Character = 7 + Eight Character = 8 + Nine Character = 9 + Dash Character = 10 + E Character = 11 + H Character = 12 + L Character = 13 + P Character = 14 + Blank Character = 15 + Dot Character = 128 +) diff --git a/max72xx/max72xx.go b/max72xx/max72xx.go new file mode 100644 index 0000000..7890d41 --- /dev/null +++ b/max72xx/max72xx.go @@ -0,0 +1,85 @@ +// Driver works for max7219 and 7221 +// Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX7219-MAX7221.pdf +package max72xx + +import ( + "machine" +) + +type Device struct { + bus machine.SPI + cs machine.Pin +} + +// NewDriver creates a new max7219 connection. The SPI wire must already be configured +// The SPI frequency must not be higher than 10MHz. +// parameter cs: the datasheet also refers to this pin as "load" pin. +func NewDevice(bus machine.SPI, cs machine.Pin) *Device { + return &Device{ + bus: bus, + cs: cs, + } +} + +// Configure setups the pins. +func (driver *Device) Configure() { + outPutConfig := machine.PinConfig{Mode: machine.PinOutput} + + driver.cs.Configure(outPutConfig) +} + +// SetScanLimit sets the scan limit. Maximum is 8. +// Example: a 4 digit 7SegmentDisplay has a scan limit of 4 +func (driver *Device) SetScanLimit(digitNumber uint8) { + driver.WriteCommand(byte(REG_SCANLIMIT), byte(digitNumber-1)) +} + +// SetDecodeMode sets the decode mode for 7 segment displays. +// digitNumber = 1 -> 1 digit gets decoded +// digitNumber = 2 or 3, or 4 -> 4 digit are being decoded +// digitNumber = 8 -> 8 digits are being decoded +// digitNumber 0 || digitNumber > 8 -> no decoding is being used +func (driver *Device) SetDecodeMode(digitNumber uint8) { + switch digitNumber { + case 1: // only decode first digit + driver.WriteCommand(REG_DECODE_MODE, 0x01) + case 2, 3, 4: // decode digits 3-0 + driver.WriteCommand(REG_DECODE_MODE, 0x0F) + case 8: // decode 8 digits + driver.WriteCommand(REG_DECODE_MODE, 0xFF) + default: + driver.WriteCommand(REG_DECODE_MODE, 0x00) + } +} + +// StartShutdownMode sets the IC into a low power shutdown mode. +func (driver *Device) StartShutdownMode() { + driver.WriteCommand(REG_SHUTDOWN, 0x00) +} + +// StartShutdownMode sets the IC into normal operation mode. +func (driver *Device) StopShutdownMode() { + driver.WriteCommand(REG_SHUTDOWN, 0x01) +} + +// StartDisplayTest starts a display test. +func (driver *Device) StartDisplayTest() { + driver.WriteCommand(REG_DISPLAY_TEST, 0x01) +} + +// StopDisplayTest stops the display test and gets into normal operation mode. +func (driver *Device) StopDisplayTest() { + driver.WriteCommand(REG_DISPLAY_TEST, 0x00) +} + +func (driver *Device) writeByte(data byte) { + driver.bus.Transfer(data) +} + +// WriteCommand write data to a given register. +func (driver *Device) WriteCommand(register, data byte) { + driver.cs.Low() + driver.writeByte(register) + driver.writeByte(data) + driver.cs.High() +} diff --git a/max72xx/registers.go b/max72xx/registers.go new file mode 100644 index 0000000..ce3511d --- /dev/null +++ b/max72xx/registers.go @@ -0,0 +1,18 @@ +package max72xx + +const ( + REG_NOOP byte = 0x00 + REG_DIGIT0 byte = 0x01 + REG_DIGIT1 byte = 0x02 + REG_DIGIT2 byte = 0x03 + REG_DIGIT3 byte = 0x04 + REG_DIGIT4 byte = 0x05 + REG_DIGIT5 byte = 0x06 + REG_DIGIT6 byte = 0x07 + REG_DIGIT7 byte = 0x08 + REG_DECODE_MODE byte = 0x09 // turn of for led matrix, turn on for digits + REG_INTENSITY byte = 0x0A + REG_SCANLIMIT byte = 0x0B + REG_SHUTDOWN byte = 0x0C // turn on for no shutdown mode + REG_DISPLAY_TEST byte = 0x0F // turn off for no display test +)