diff --git a/Makefile b/Makefile index 9fc48c8e7..f9bae8b1e 100644 --- a/Makefile +++ b/Makefile @@ -57,9 +57,11 @@ smoke-test: @md5sum ./build/test.hex tinygo build -size short -o ./build/test.hex -target=microbit ./examples/hub75/main.go @md5sum ./build/test.hex - tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/ili9341/basic/main.go + tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/ili9341/basic @md5sum ./build/test.hex - tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/ili9341/scroll/main.go + tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/ili9341/pyportal_boing + @md5sum ./build/test.hex + tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/ili9341/scroll @md5sum ./build/test.hex tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/lis3dh/main.go @md5sum ./build/test.hex diff --git a/examples/ili9341/basic/main.go b/examples/ili9341/basic/main.go index e49130b63..51e2be79d 100644 --- a/examples/ili9341/basic/main.go +++ b/examples/ili9341/basic/main.go @@ -9,15 +9,6 @@ import ( ) var ( - display = ili9341.NewParallel( - machine.LCD_DATA0, - machine.TFT_WR, - machine.TFT_DC, - machine.TFT_CS, - machine.TFT_RESET, - machine.TFT_RD, - ) - black = color.RGBA{0, 0, 0, 255} white = color.RGBA{255, 255, 255, 255} red = color.RGBA{255, 0, 0, 255} @@ -27,13 +18,13 @@ var ( func main() { - machine.TFT_BACKLIGHT.Configure(machine.PinConfig{machine.PinOutput}) + backlight.Configure(machine.PinConfig{machine.PinOutput}) display.Configure(ili9341.Config{}) width, height := display.Size() display.FillScreen(black) - machine.TFT_BACKLIGHT.High() + backlight.High() display.FillRectangle(0, 0, width/2, height/2, white) display.FillRectangle(width/2, 0, width/2, height/2, red) diff --git a/examples/ili9341/basic/pyportal.go b/examples/ili9341/basic/pyportal.go new file mode 100644 index 000000000..d6973cf01 --- /dev/null +++ b/examples/ili9341/basic/pyportal.go @@ -0,0 +1,22 @@ +// +build pyportal + +package main + +import ( + "machine" + + "tinygo.org/x/drivers/ili9341" +) + +var ( + display = ili9341.NewParallel( + machine.LCD_DATA0, + machine.TFT_WR, + machine.TFT_DC, + machine.TFT_CS, + machine.TFT_RESET, + machine.TFT_RD, + ) + + backlight = machine.TFT_BACKLIGHT +) diff --git a/examples/ili9341/basic/wioterminal.go b/examples/ili9341/basic/wioterminal.go new file mode 100644 index 000000000..a7cd96b64 --- /dev/null +++ b/examples/ili9341/basic/wioterminal.go @@ -0,0 +1,29 @@ +// +build wioterminal + +package main + +import ( + "machine" + + "tinygo.org/x/drivers/ili9341" +) + +var ( + display = ili9341.NewSpi( + machine.SPI3, + machine.LCD_DC, + machine.LCD_SS_PIN, + machine.LCD_RESET, + ) + + backlight = machine.LCD_BACKLIGHT +) + +func init() { + machine.SPI3.Configure(machine.SPIConfig{ + SCK: machine.LCD_SCK_PIN, + MOSI: machine.LCD_MOSI_PIN, + MISO: machine.LCD_MISO_PIN, + Frequency: 40000000, + }) +} diff --git a/examples/ili9341/pyportal_boing/main.go b/examples/ili9341/pyportal_boing/main.go index 43e4105ea..6b3cfe120 100644 --- a/examples/ili9341/pyportal_boing/main.go +++ b/examples/ili9341/pyportal_boing/main.go @@ -25,15 +25,6 @@ const ( ) var ( - display = ili9341.NewParallel( - machine.LCD_DATA0, - machine.TFT_WR, - machine.TFT_DC, - machine.TFT_CS, - machine.TFT_RESET, - machine.TFT_RD, - ) - frameBuffer = [(graphics.BALLHEIGHT + 8) * (graphics.BALLWIDTH + 8)]uint16{} startTime int64 @@ -56,7 +47,7 @@ var ( func main() { // configure backlight - machine.TFT_BACKLIGHT.Configure(machine.PinConfig{machine.PinOutput}) + backlight.Configure(machine.PinConfig{machine.PinOutput}) // configure display display.Configure(ili9341.Config{}) @@ -64,7 +55,7 @@ func main() { width, height := display.Size() println(width, height) - machine.TFT_BACKLIGHT.High() + backlight.High() display.SetRotation(ili9341.Rotation270) DrawBackground() diff --git a/examples/ili9341/pyportal_boing/pyportal.go b/examples/ili9341/pyportal_boing/pyportal.go new file mode 100644 index 000000000..d6973cf01 --- /dev/null +++ b/examples/ili9341/pyportal_boing/pyportal.go @@ -0,0 +1,22 @@ +// +build pyportal + +package main + +import ( + "machine" + + "tinygo.org/x/drivers/ili9341" +) + +var ( + display = ili9341.NewParallel( + machine.LCD_DATA0, + machine.TFT_WR, + machine.TFT_DC, + machine.TFT_CS, + machine.TFT_RESET, + machine.TFT_RD, + ) + + backlight = machine.TFT_BACKLIGHT +) diff --git a/examples/ili9341/pyportal_boing/wioterminal.go b/examples/ili9341/pyportal_boing/wioterminal.go new file mode 100644 index 000000000..a7cd96b64 --- /dev/null +++ b/examples/ili9341/pyportal_boing/wioterminal.go @@ -0,0 +1,29 @@ +// +build wioterminal + +package main + +import ( + "machine" + + "tinygo.org/x/drivers/ili9341" +) + +var ( + display = ili9341.NewSpi( + machine.SPI3, + machine.LCD_DC, + machine.LCD_SS_PIN, + machine.LCD_RESET, + ) + + backlight = machine.LCD_BACKLIGHT +) + +func init() { + machine.SPI3.Configure(machine.SPIConfig{ + SCK: machine.LCD_SCK_PIN, + MOSI: machine.LCD_MOSI_PIN, + MISO: machine.LCD_MISO_PIN, + Frequency: 40000000, + }) +} diff --git a/examples/ili9341/scroll/main.go b/examples/ili9341/scroll/main.go index e302fdc3e..3d74fc578 100644 --- a/examples/ili9341/scroll/main.go +++ b/examples/ili9341/scroll/main.go @@ -9,15 +9,6 @@ import ( ) var ( - display = ili9341.NewParallel( - machine.LCD_DATA0, - machine.TFT_WR, - machine.TFT_DC, - machine.TFT_CS, - machine.TFT_RESET, - machine.TFT_RD, - ) - red = color.RGBA{255, 0, 0, 255} blue = color.RGBA{0, 0, 255, 255} green = color.RGBA{0, 255, 0, 255} @@ -27,13 +18,13 @@ var ( func main() { - machine.TFT_BACKLIGHT.Configure(machine.PinConfig{machine.PinOutput}) + backlight.Configure(machine.PinConfig{machine.PinOutput}) display.Configure(ili9341.Config{}) width, height := display.Size() display.FillScreen(black) - machine.TFT_BACKLIGHT.High() + backlight.High() display.FillRectangle(0, 0, width/2, height/2, white) display.FillRectangle(width/2, 0, width/2, height/2, red) diff --git a/examples/ili9341/scroll/pyportal.go b/examples/ili9341/scroll/pyportal.go new file mode 100644 index 000000000..d6973cf01 --- /dev/null +++ b/examples/ili9341/scroll/pyportal.go @@ -0,0 +1,22 @@ +// +build pyportal + +package main + +import ( + "machine" + + "tinygo.org/x/drivers/ili9341" +) + +var ( + display = ili9341.NewParallel( + machine.LCD_DATA0, + machine.TFT_WR, + machine.TFT_DC, + machine.TFT_CS, + machine.TFT_RESET, + machine.TFT_RD, + ) + + backlight = machine.TFT_BACKLIGHT +) diff --git a/examples/ili9341/scroll/wioterminal.go b/examples/ili9341/scroll/wioterminal.go new file mode 100644 index 000000000..a7cd96b64 --- /dev/null +++ b/examples/ili9341/scroll/wioterminal.go @@ -0,0 +1,29 @@ +// +build wioterminal + +package main + +import ( + "machine" + + "tinygo.org/x/drivers/ili9341" +) + +var ( + display = ili9341.NewSpi( + machine.SPI3, + machine.LCD_DC, + machine.LCD_SS_PIN, + machine.LCD_RESET, + ) + + backlight = machine.LCD_BACKLIGHT +) + +func init() { + machine.SPI3.Configure(machine.SPIConfig{ + SCK: machine.LCD_SCK_PIN, + MOSI: machine.LCD_MOSI_PIN, + MISO: machine.LCD_MISO_PIN, + Frequency: 40000000, + }) +} diff --git a/ili9341/ili9341.go b/ili9341/ili9341.go index 2ff82c64b..6bc22492e 100644 --- a/ili9341/ili9341.go +++ b/ili9341/ili9341.go @@ -281,15 +281,15 @@ func (d *Device) sendCommand(cmd byte, data []byte) { d.dc.Low() d.driver.write8(cmd) d.dc.High() - for _, b := range data { - d.driver.write8(b) - } + d.driver.write8sl(data) d.endWrite() } type driver interface { configure(config *Config) write8(b byte) + write8n(b byte, n int) + write8sl(b []byte) write16(data uint16) write16n(data uint16, n int) write16sl(data []uint16) diff --git a/ili9341/parallel_atsamd51.go b/ili9341/parallel_atsamd51.go index 0530c8c8f..4b566829a 100644 --- a/ili9341/parallel_atsamd51.go +++ b/ili9341/parallel_atsamd51.go @@ -72,6 +72,20 @@ func (pd *parallelDriver) wrx() { volatile.StoreUint32(pd.wrPortSet, pd.wrMaskSet) } +//go:inline +func (pd *parallelDriver) write8n(b byte, n int) { + for i := 0; i < n; i++ { + pd.write8(b) + } +} + +//go:inline +func (pd *parallelDriver) write8sl(b []byte) { + for i := 0; i < len(b); i++ { + pd.write8(b[i]) + } +} + //go:inline func (pd *parallelDriver) write16(data uint16) { pd.write8(byte(data >> 8)) diff --git a/ili9341/spi_atsamd51.go b/ili9341/spi_atsamd51.go new file mode 100644 index 000000000..a7ea9ff06 --- /dev/null +++ b/ili9341/spi_atsamd51.go @@ -0,0 +1,116 @@ +// +build atsamd51 + +package ili9341 + +import ( + "device/sam" + "machine" +) + +type spiDriver struct { + bus machine.SPI +} + +func NewSpi(bus machine.SPI, dc, cs, rst machine.Pin) *Device { + return &Device{ + dc: dc, + cs: cs, + rst: rst, + rd: machine.NoPin, + driver: &spiDriver{ + bus: bus, + }, + } +} + +func (pd *spiDriver) configure(config *Config) { +} + +func (pd *spiDriver) write8(b byte) { + pd.bus.Bus.CTRLB.ClearBits(sam.SERCOM_SPIM_CTRLB_RXEN) + + for !pd.bus.Bus.INTFLAG.HasBits(sam.SERCOM_SPIM_INTFLAG_DRE) { + } + pd.bus.Bus.DATA.Set(uint32(b)) + + pd.bus.Bus.CTRLB.SetBits(sam.SERCOM_SPIM_CTRLB_RXEN) + for pd.bus.Bus.SYNCBUSY.HasBits(sam.SERCOM_SPIM_SYNCBUSY_CTRLB) { + } +} + +func (pd *spiDriver) write8n(b byte, n int) { + pd.bus.Bus.CTRLB.ClearBits(sam.SERCOM_SPIM_CTRLB_RXEN) + + for i, c := 0, n; i < c; i++ { + for !pd.bus.Bus.INTFLAG.HasBits(sam.SERCOM_SPIM_INTFLAG_DRE) { + } + pd.bus.Bus.DATA.Set(uint32(b)) + } + + pd.bus.Bus.CTRLB.SetBits(sam.SERCOM_SPIM_CTRLB_RXEN) + for pd.bus.Bus.SYNCBUSY.HasBits(sam.SERCOM_SPIM_SYNCBUSY_CTRLB) { + } +} + +func (pd *spiDriver) write8sl(b []byte) { + pd.bus.Bus.CTRLB.ClearBits(sam.SERCOM_SPIM_CTRLB_RXEN) + + for i, c := 0, len(b); i < c; i++ { + for !pd.bus.Bus.INTFLAG.HasBits(sam.SERCOM_SPIM_INTFLAG_DRE) { + } + pd.bus.Bus.DATA.Set(uint32(b[i])) + } + + pd.bus.Bus.CTRLB.SetBits(sam.SERCOM_SPIM_CTRLB_RXEN) + for pd.bus.Bus.SYNCBUSY.HasBits(sam.SERCOM_SPIM_SYNCBUSY_CTRLB) { + } +} + +func (pd *spiDriver) write16(data uint16) { + pd.bus.Bus.CTRLB.ClearBits(sam.SERCOM_SPIM_CTRLB_RXEN) + + for !pd.bus.Bus.INTFLAG.HasBits(sam.SERCOM_SPIM_INTFLAG_DRE) { + } + pd.bus.Bus.DATA.Set(uint32(uint8(data >> 8))) + for !pd.bus.Bus.INTFLAG.HasBits(sam.SERCOM_SPIM_INTFLAG_DRE) { + } + pd.bus.Bus.DATA.Set(uint32(uint8(data))) + + pd.bus.Bus.CTRLB.SetBits(sam.SERCOM_SPIM_CTRLB_RXEN) + for pd.bus.Bus.SYNCBUSY.HasBits(sam.SERCOM_SPIM_SYNCBUSY_CTRLB) { + } +} + +func (pd *spiDriver) write16n(data uint16, n int) { + pd.bus.Bus.CTRLB.ClearBits(sam.SERCOM_SPIM_CTRLB_RXEN) + + for i := 0; i < n; i++ { + for !pd.bus.Bus.INTFLAG.HasBits(sam.SERCOM_SPIM_INTFLAG_DRE) { + } + pd.bus.Bus.DATA.Set(uint32(uint8(data >> 8))) + for !pd.bus.Bus.INTFLAG.HasBits(sam.SERCOM_SPIM_INTFLAG_DRE) { + } + pd.bus.Bus.DATA.Set(uint32(uint8(data))) + } + + pd.bus.Bus.CTRLB.SetBits(sam.SERCOM_SPIM_CTRLB_RXEN) + for pd.bus.Bus.SYNCBUSY.HasBits(sam.SERCOM_SPIM_SYNCBUSY_CTRLB) { + } +} + +func (pd *spiDriver) write16sl(data []uint16) { + pd.bus.Bus.CTRLB.ClearBits(sam.SERCOM_SPIM_CTRLB_RXEN) + + for i, c := 0, len(data); i < c; i++ { + for !pd.bus.Bus.INTFLAG.HasBits(sam.SERCOM_SPIM_INTFLAG_DRE) { + } + pd.bus.Bus.DATA.Set(uint32(uint8(data[i] >> 8))) + for !pd.bus.Bus.INTFLAG.HasBits(sam.SERCOM_SPIM_INTFLAG_DRE) { + } + pd.bus.Bus.DATA.Set(uint32(uint8(data[i]))) + } + + pd.bus.Bus.CTRLB.SetBits(sam.SERCOM_SPIM_CTRLB_RXEN) + for pd.bus.Bus.SYNCBUSY.HasBits(sam.SERCOM_SPIM_SYNCBUSY_CTRLB) { + } +}