mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-07-26 10:38:41 +00:00
Driver for BBC micro:bit on-board LED matrix (#48)
This commit is contained in:
committed by
Ron Evans
parent
a9e5c8f710
commit
d22cf7a3e1
@@ -28,6 +28,7 @@ jobs:
|
||||
- run: tinygo build -size short -o test.elf -target=microbit ./examples/hub75/main.go
|
||||
- run: tinygo build -size short -o test.elf -target=circuitplay-express ./examples/lis3dh/main.go
|
||||
- run: tinygo build -size short -o test.elf -target=itsybitsy-m0 ./examples/mag3110/main.go
|
||||
- run: tinygo build -size short -o test.elf -target=microbit ./examples/microbitmatrix/main.go
|
||||
- run: tinygo build -size short -o test.elf -target=itsybitsy-m0 ./examples/mma8653/main.go
|
||||
- run: tinygo build -size short -o test.elf -target=itsybitsy-m0 ./examples/mpu6050/main.go
|
||||
- run: tinygo build -size short -o test.elf -target=microbit ./examples/pcd8544/setbuffer/main.go
|
||||
|
||||
@@ -65,6 +65,7 @@ func main() {
|
||||
| [HUB75 RGB led matrix](https://cdn-learn.adafruit.com/downloads/pdf/32x16-32x32-rgb-led-matrix.pdf) | SPI |
|
||||
| [LIS3DH accelerometer](https://www.st.com/resource/en/datasheet/lis3dh.pdf) | I2C |
|
||||
| [MAG3110 magnetometer](https://www.nxp.com/docs/en/data-sheet/MAG3110.pdf) | I2C |
|
||||
| [BBC micro:bit LED matrix](https://github.com/bbcmicrobit/hardware/blob/master/SCH_BBC-Microbit_V1.3B.pdf) | GPIO |
|
||||
| [MMA8653 accelerometer](https://www.nxp.com/docs/en/data-sheet/MMA8653FC.pdf) | I2C |
|
||||
| [MPU6050 accelerometer/gyroscope](https://store.invensense.com/datasheets/invensense/MPU-6050_DataSheet_V3%204.pdf) | I2C |
|
||||
| [PCD8544 display](http://eia.udg.edu/~forest/PCD8544_1.pdf) | SPI |
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"image/color"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/tinygo-org/drivers/microbitmatrix"
|
||||
)
|
||||
|
||||
var display microbitmatrix.Device
|
||||
|
||||
func main() {
|
||||
display = microbitmatrix.New()
|
||||
display.Configure(microbitmatrix.Config{})
|
||||
|
||||
display.ClearDisplay()
|
||||
|
||||
x := int16(1)
|
||||
y := int16(2)
|
||||
deltaX := int16(1)
|
||||
deltaY := int16(1)
|
||||
then := time.Now()
|
||||
c := color.RGBA{255, 255, 255, 255}
|
||||
|
||||
for {
|
||||
if time.Since(then).Nanoseconds() > 80000000 {
|
||||
then = time.Now()
|
||||
|
||||
pixel := display.GetPixel(x, y)
|
||||
if pixel {
|
||||
display.ClearDisplay()
|
||||
x = 1 + int16(rand.Int31n(3))
|
||||
y = 1 + int16(rand.Int31n(3))
|
||||
deltaX = 1
|
||||
deltaY = 1
|
||||
if rand.Int31n(2) == 0 {
|
||||
deltaX = -1
|
||||
}
|
||||
if rand.Int31n(2) == 0 {
|
||||
deltaY = -1
|
||||
}
|
||||
}
|
||||
display.SetPixel(x, y, c)
|
||||
|
||||
x += deltaX
|
||||
y += deltaY
|
||||
|
||||
if x == 0 || x == 4 {
|
||||
deltaX = -deltaX
|
||||
}
|
||||
|
||||
if y == 0 || y == 4 {
|
||||
deltaY = -deltaY
|
||||
}
|
||||
}
|
||||
display.Display()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
// Package microbitmatrix implements a driver for the BBC micro:bit's LED matrix.
|
||||
//
|
||||
// Schematic: https://github.com/bbcmicrobit/hardware/blob/master/SCH_BBC-Microbit_V1.3B.pdf
|
||||
package microbitmatrix
|
||||
|
||||
import (
|
||||
"device/nrf"
|
||||
"image/color"
|
||||
"machine"
|
||||
"time"
|
||||
)
|
||||
|
||||
var matrixRotations = [4][5][5][2]uint8{
|
||||
{ // 0
|
||||
{{0, 0}, {1, 3}, {0, 1}, {1, 4}, {0, 2}},
|
||||
{{2, 3}, {2, 4}, {2, 5}, {2, 6}, {2, 7}},
|
||||
{{1, 1}, {0, 8}, {1, 2}, {2, 8}, {1, 0}},
|
||||
{{0, 7}, {0, 6}, {0, 5}, {0, 4}, {0, 3}},
|
||||
{{2, 2}, {1, 6}, {2, 0}, {1, 5}, {2, 1}},
|
||||
},
|
||||
{ // 90 CCW
|
||||
{{0, 2}, {2, 7}, {1, 0}, {0, 3}, {2, 1}},
|
||||
{{1, 4}, {2, 6}, {2, 8}, {0, 4}, {1, 5}},
|
||||
{{0, 1}, {2, 5}, {1, 2}, {0, 5}, {2, 0}},
|
||||
{{1, 3}, {2, 4}, {0, 8}, {0, 6}, {1, 6}},
|
||||
{{0, 0}, {2, 3}, {1, 1}, {0, 7}, {2, 2}},
|
||||
},
|
||||
{ // 180
|
||||
{{2, 1}, {1, 5}, {2, 0}, {1, 6}, {2, 2}},
|
||||
{{0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}},
|
||||
{{1, 0}, {2, 8}, {1, 2}, {0, 8}, {1, 1}},
|
||||
{{2, 7}, {2, 6}, {2, 5}, {2, 4}, {2, 3}},
|
||||
{{0, 2}, {1, 4}, {0, 1}, {1, 3}, {0, 0}},
|
||||
},
|
||||
{ // 270
|
||||
{{2, 2}, {0, 7}, {1, 1}, {2, 3}, {0, 0}},
|
||||
{{1, 6}, {0, 6}, {0, 8}, {2, 4}, {1, 3}},
|
||||
{{2, 0}, {0, 5}, {1, 2}, {2, 5}, {0, 1}},
|
||||
{{1, 5}, {0, 4}, {2, 8}, {2, 6}, {1, 4}},
|
||||
{{2, 1}, {0, 3}, {1, 0}, {2, 7}, {0, 2}},
|
||||
},
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Rotation uint8
|
||||
}
|
||||
|
||||
type Device struct {
|
||||
buffer [3][9]bool
|
||||
rotation uint8
|
||||
}
|
||||
|
||||
// New returns a new microbitmatrix driver.
|
||||
func New() Device {
|
||||
return Device{}
|
||||
}
|
||||
|
||||
// Configure sets up the device.
|
||||
func (d *Device) Configure(cfg Config) {
|
||||
d.SetRotation(cfg.Rotation)
|
||||
|
||||
set := 0
|
||||
for i := machine.LED_COL_1; i <= machine.LED_ROW_3; i++ {
|
||||
set |= 1 << uint8(i)
|
||||
}
|
||||
nrf.GPIO.DIRSET = nrf.RegValue(set)
|
||||
d.ClearDisplay()
|
||||
d.DisableAll()
|
||||
}
|
||||
|
||||
// SetRotation changes the rotation of the LED matrix
|
||||
func (d *Device) SetRotation(rotation uint8) {
|
||||
d.rotation = rotation % 4
|
||||
}
|
||||
|
||||
// SetPixel modifies the internal buffer in a single pixel.
|
||||
func (d *Device) SetPixel(x int16, y int16, c color.RGBA) {
|
||||
if x < 0 || x >= 5 || y < 0 || y >= 5 {
|
||||
return
|
||||
}
|
||||
if c.R != 0 || c.G != 0 || c.B != 0 {
|
||||
d.buffer[matrixRotations[d.rotation][x][y][0]][matrixRotations[d.rotation][x][y][1]] = true
|
||||
} else {
|
||||
d.buffer[matrixRotations[d.rotation][x][y][0]][matrixRotations[d.rotation][x][y][1]] = false
|
||||
}
|
||||
}
|
||||
|
||||
// GetPixel returns if the specific pixels is enabled
|
||||
func (d *Device) GetPixel(x int16, y int16) bool {
|
||||
if x < 0 || x >= 5 || y < 0 || y >= 5 {
|
||||
return false
|
||||
}
|
||||
return d.buffer[matrixRotations[d.rotation][x][y][0]][matrixRotations[d.rotation][x][y][1]]
|
||||
}
|
||||
|
||||
// Display sends the buffer (if any) to the screen.
|
||||
func (d *Device) Display() error {
|
||||
for row := 0; row < 3; row++ {
|
||||
d.DisableAll()
|
||||
set := 0
|
||||
set |= 1 << uint8(machine.LED_ROW_1+row)
|
||||
nrf.GPIO.OUTSET = nrf.RegValue(set)
|
||||
|
||||
set = 0
|
||||
for col := 0; col < 9; col++ {
|
||||
|
||||
if d.buffer[row][col] {
|
||||
set |= 1 << uint8(machine.LED_COL_1+col)
|
||||
}
|
||||
|
||||
}
|
||||
nrf.GPIO.OUTCLR = nrf.RegValue(set)
|
||||
time.Sleep(time.Millisecond * 2)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ClearDisplay erases the internal buffer
|
||||
func (d *Device) ClearDisplay() {
|
||||
for row := 0; row < 3; row++ {
|
||||
for col := 0; col < 9; col++ {
|
||||
d.buffer[row][col] = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DisableAll disables all the LEDs without modifying the buffer
|
||||
func (d *Device) DisableAll() {
|
||||
set := 0
|
||||
for i := machine.LED_COL_1; i <= machine.LED_COL_9; i++ {
|
||||
set |= 1 << uint8(i)
|
||||
}
|
||||
nrf.GPIO.OUTSET = nrf.RegValue(set)
|
||||
nrf.GPIO.OUTCLR = (1 << machine.LED_ROW_1) | (1 << machine.LED_ROW_2) | (1 << machine.LED_ROW_3)
|
||||
}
|
||||
|
||||
// EnableAll enables all the LEDs without modifying the buffer
|
||||
func EnableAll() error {
|
||||
set := 0
|
||||
for i := machine.LED_ROW_1; i <= machine.LED_ROW_3; i++ {
|
||||
set |= 1 << uint8(i)
|
||||
}
|
||||
nrf.GPIO.OUTSET = nrf.RegValue(set)
|
||||
|
||||
set = 0
|
||||
for i := machine.LED_COL_1; i <= machine.LED_COL_9; i++ {
|
||||
set |= 1 << uint8(i)
|
||||
}
|
||||
nrf.GPIO.OUTCLR = nrf.RegValue(set)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Size returns the current size of the display.
|
||||
func (d *Device) Size() (w, h int16) {
|
||||
return 5, 5
|
||||
}
|
||||
Reference in New Issue
Block a user