mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-08-16 12:53:23 +00:00
Shiftregister implementation (#135)
* Basic support of SIPO shift register * typo * add example of shiftregister for arduino and nucleo * Fix build flag for nucleof103rb * Fix wrong data pin configuration * Change README.md for Shift registers * Add API for individual register's output pin * Rewrite shift register example to show ShiftPin usage * Fix target for shiftregister example smoke test * Fix type in makefile * Add shiftregister compatble IC * Edit comment and readme
This commit is contained in:
committed by
GitHub
parent
12ac4c2c06
commit
c7cbd7c6cd
@@ -121,5 +121,7 @@ smoke-test:
|
|||||||
@md5sum ./build/test.hex
|
@md5sum ./build/test.hex
|
||||||
tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/l9110x/speed/main.go
|
tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/l9110x/speed/main.go
|
||||||
@md5sum ./build/test.hex
|
@md5sum ./build/test.hex
|
||||||
|
tinygo build -size short -o ./build/test.hex -target=nucleo-f103rb ./examples/shiftregister/main.go
|
||||||
|
@md5sum ./build/test.hex
|
||||||
|
|
||||||
test: clean fmt-check smoke-test
|
test: clean fmt-check smoke-test
|
||||||
|
|||||||
@@ -87,7 +87,8 @@ The following 44 devices are supported.
|
|||||||
| [PCD8544 display](http://eia.udg.edu/~forest/PCD8544_1.pdf) | SPI |
|
| [PCD8544 display](http://eia.udg.edu/~forest/PCD8544_1.pdf) | SPI |
|
||||||
| [Resistive Touchscreen (4-wire)](http://ww1.microchip.com/downloads/en/Appnotes/doc8091.pdf) | GPIO |
|
| [Resistive Touchscreen (4-wire)](http://ww1.microchip.com/downloads/en/Appnotes/doc8091.pdf) | GPIO |
|
||||||
| [Semihosting](https://wiki.segger.com/Semihosting) | Debug |
|
| [Semihosting](https://wiki.segger.com/Semihosting) | Debug |
|
||||||
| [Shift register](https://en.wikipedia.org/wiki/Shift_register#Parallel-in_serial-out_\(PISO\)) | GPIO |
|
| [Shift register (PISO)](https://en.wikipedia.org/wiki/Shift_register#Parallel-in_serial-out_\(PISO\)) | GPIO |
|
||||||
|
| [Shift registers (SIPO)](https://en.wikipedia.org/wiki/Shift_register#Serial-in_parallel-out_(SIPO)) | GPIO |
|
||||||
| [SHT3x Digital Humidity Sensor](https://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/0_Datasheets/Humidity/Sensirion_Humidity_Sensors_SHT3x_Datasheet_digital.pdf) | I2C |
|
| [SHT3x Digital Humidity Sensor](https://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/0_Datasheets/Humidity/Sensirion_Humidity_Sensors_SHT3x_Datasheet_digital.pdf) | I2C |
|
||||||
| [SSD1306 OLED display](https://cdn-shop.adafruit.com/datasheets/SSD1306.pdf) | I2C / SPI |
|
| [SSD1306 OLED display](https://cdn-shop.adafruit.com/datasheets/SSD1306.pdf) | I2C / SPI |
|
||||||
| [SSD1331 TFT color display](https://www.crystalfontz.com/controllers/SolomonSystech/SSD1331/381/) | SPI |
|
| [SSD1331 TFT color display](https://www.crystalfontz.com/controllers/SolomonSystech/SSD1331/381/) | SPI |
|
||||||
|
|||||||
@@ -0,0 +1,124 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"machine"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/shiftregister"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
d := shiftregister.New(
|
||||||
|
shiftregister.EIGHT_BITS,
|
||||||
|
machine.PA6, // D12 Pin latch connected to ST_CP of 74HC595 (12)
|
||||||
|
machine.PA7, // D11 Pin clock connected to SH_CP of 74HC595 (11)
|
||||||
|
machine.PB6, // D10 Pin data connected to DS of 74HC595 (14)
|
||||||
|
)
|
||||||
|
d.Configure()
|
||||||
|
|
||||||
|
for {
|
||||||
|
|
||||||
|
// Examples using masks. This method writes all pins state at once.
|
||||||
|
|
||||||
|
// All pins High
|
||||||
|
d.WriteMask(0xFF)
|
||||||
|
delay()
|
||||||
|
|
||||||
|
// All pins Low
|
||||||
|
d.WriteMask(0x00)
|
||||||
|
delay()
|
||||||
|
|
||||||
|
// Some fun with masks
|
||||||
|
for _, pattern := range patterns {
|
||||||
|
d.WriteMask(pattern)
|
||||||
|
shortDelay()
|
||||||
|
}
|
||||||
|
delay()
|
||||||
|
d.WriteMask(0x00)
|
||||||
|
|
||||||
|
// Examples using individually addressable pin API. This method is slower than using mask
|
||||||
|
// because all register's pins state are send for is p.Set() call.
|
||||||
|
|
||||||
|
// Set register's pin #4
|
||||||
|
d.GetShiftPin(4).High()
|
||||||
|
delay()
|
||||||
|
d.GetShiftPin(4).Low()
|
||||||
|
delay()
|
||||||
|
|
||||||
|
// Get an individual pin and use it
|
||||||
|
pin := d.GetShiftPin(7)
|
||||||
|
pin.High()
|
||||||
|
delay()
|
||||||
|
pin.Low()
|
||||||
|
delay()
|
||||||
|
|
||||||
|
// Prepare an array of pin attached to the register
|
||||||
|
pins := [8]*shiftregister.ShiftPin{}
|
||||||
|
for p := 0; p < 8; p++ {
|
||||||
|
pins[p] = d.GetShiftPin(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
for p := 7; p >= 0; p-- {
|
||||||
|
pins[p].Low()
|
||||||
|
shortDelay()
|
||||||
|
pins[p].High()
|
||||||
|
}
|
||||||
|
|
||||||
|
for p := 7; p >= 0; p-- {
|
||||||
|
pins[p].High()
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
pins[p].Low()
|
||||||
|
}
|
||||||
|
delay()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func delay() {
|
||||||
|
time.Sleep(500 * time.Millisecond)
|
||||||
|
}
|
||||||
|
func shortDelay() {
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
}
|
||||||
|
|
||||||
|
var patterns = []uint32{
|
||||||
|
0b00000001,
|
||||||
|
0b00000010,
|
||||||
|
0b00000100,
|
||||||
|
0b00001000,
|
||||||
|
0b00010000,
|
||||||
|
0b00100000,
|
||||||
|
0b01000000,
|
||||||
|
0b10000000,
|
||||||
|
0b10000001,
|
||||||
|
0b10000010,
|
||||||
|
0b10000100,
|
||||||
|
0b10001000,
|
||||||
|
0b10010000,
|
||||||
|
0b10100000,
|
||||||
|
0b11000000,
|
||||||
|
0b11000001,
|
||||||
|
0b11000010,
|
||||||
|
0b11000100,
|
||||||
|
0b11001000,
|
||||||
|
0b11010000,
|
||||||
|
0b11100000,
|
||||||
|
0b11100001,
|
||||||
|
0b11100010,
|
||||||
|
0b11100100,
|
||||||
|
0b11101000,
|
||||||
|
0b11110000,
|
||||||
|
0b11110001,
|
||||||
|
0b11110010,
|
||||||
|
0b11110100,
|
||||||
|
0b11111000,
|
||||||
|
0b11111001,
|
||||||
|
0b11111010,
|
||||||
|
0b11111100,
|
||||||
|
0b11111101,
|
||||||
|
0b11111110,
|
||||||
|
0b11111111,
|
||||||
|
0b00000000,
|
||||||
|
0b11111111,
|
||||||
|
0b00000000,
|
||||||
|
0b11111111,
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
// Package shiftregister is for 8bit shift output register using 3 GPIO pins like SN74ALS164A, SN74AHC594, SN74AHC595, ...
|
||||||
|
package shiftregister
|
||||||
|
|
||||||
|
import (
|
||||||
|
"machine"
|
||||||
|
)
|
||||||
|
|
||||||
|
type NumberBit int8
|
||||||
|
|
||||||
|
// Bit number of the register
|
||||||
|
const (
|
||||||
|
EIGHT_BITS NumberBit = 8
|
||||||
|
SIXTEEN_BITS NumberBit = 16
|
||||||
|
THIRTYTWO_BITS NumberBit = 32
|
||||||
|
)
|
||||||
|
|
||||||
|
// Device holds pin number
|
||||||
|
type Device struct {
|
||||||
|
latch, clock, out machine.Pin // IC wiring
|
||||||
|
bits NumberBit // Pin number
|
||||||
|
mask uint32 // keep all pins state
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShiftPin is the implementation of the ShiftPin interface.
|
||||||
|
// ShiftPin provide an interface like regular machine.Pin
|
||||||
|
type ShiftPin struct {
|
||||||
|
mask uint32 // Bit representing the pin
|
||||||
|
d *Device // Reference to the register
|
||||||
|
}
|
||||||
|
|
||||||
|
// New returns a new shift output register device
|
||||||
|
func New(Bits NumberBit, Latch, Clock, Out machine.Pin) *Device {
|
||||||
|
return &Device{
|
||||||
|
latch: Latch,
|
||||||
|
clock: Clock,
|
||||||
|
out: Out,
|
||||||
|
bits: Bits,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure set hardware configuration
|
||||||
|
func (d *Device) Configure() {
|
||||||
|
d.latch.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||||
|
d.clock.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||||
|
d.out.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||||
|
d.latch.High()
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteMask applies mask's bits to register's outputs pin
|
||||||
|
// mask's MSB set Q1, LSB set Q8 (for 8 bits mask)
|
||||||
|
func (d *Device) WriteMask(mask uint32) {
|
||||||
|
d.mask = mask // Keep the mask for individual addressing
|
||||||
|
d.latch.Low()
|
||||||
|
for i := 0; i < int(d.bits); i++ {
|
||||||
|
d.clock.Low()
|
||||||
|
d.out.Set(mask&1 != 0)
|
||||||
|
mask = mask >> 1
|
||||||
|
d.clock.High()
|
||||||
|
}
|
||||||
|
d.latch.High()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetShiftPin return an individually addressable pin
|
||||||
|
func (d *Device) GetShiftPin(pin int) *ShiftPin {
|
||||||
|
if pin < 0 || pin > int(d.bits) {
|
||||||
|
panic("invalid pin number")
|
||||||
|
}
|
||||||
|
return &ShiftPin{
|
||||||
|
mask: 1 << pin,
|
||||||
|
d: d,
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set changes the value of this register pin.
|
||||||
|
func (p ShiftPin) Set(value bool) {
|
||||||
|
d := p.d
|
||||||
|
if value {
|
||||||
|
d.WriteMask(d.mask | p.mask)
|
||||||
|
} else {
|
||||||
|
d.WriteMask(d.mask & ^p.mask)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// High sets this shift register pin to high.
|
||||||
|
func (p ShiftPin) High() {
|
||||||
|
p.Set(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Low sets this shift register pin to low.
|
||||||
|
func (p ShiftPin) Low() {
|
||||||
|
p.Set(false)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user