From 5a75c9c40301463f418429eba46988fd9722032b Mon Sep 17 00:00:00 2001 From: sago35 Date: Mon, 3 Aug 2020 19:42:17 +0900 Subject: [PATCH] Add ILI9341 TFT driver (SPI) for ATSAMD2x (#174) * ILI9341: Add ILI9341 SPI support for for ATSAMD2x --- Makefile | 4 + examples/ili9341/basic/atsamd21.go | 29 +++++++ examples/ili9341/scroll/atsamd21.go | 29 +++++++ ili9341/spi_atsamd21.go | 116 ++++++++++++++++++++++++++++ 4 files changed, 178 insertions(+) create mode 100644 examples/ili9341/basic/atsamd21.go create mode 100644 examples/ili9341/scroll/atsamd21.go create mode 100644 ili9341/spi_atsamd21.go diff --git a/Makefile b/Makefile index f8f8ada..0678544 100644 --- a/Makefile +++ b/Makefile @@ -65,10 +65,14 @@ smoke-test: @md5sum ./build/test.hex 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=xiao ./examples/ili9341/basic + @md5sum ./build/test.hex 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=xiao ./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 tinygo build -size short -o ./build/test.hex -target=microbit ./examples/lsm303agr/main.go diff --git a/examples/ili9341/basic/atsamd21.go b/examples/ili9341/basic/atsamd21.go new file mode 100644 index 0000000..2b98594 --- /dev/null +++ b/examples/ili9341/basic/atsamd21.go @@ -0,0 +1,29 @@ +// +build atsamd21 + +package main + +import ( + "machine" + + "tinygo.org/x/drivers/ili9341" +) + +var ( + display = ili9341.NewSpi( + machine.SPI0, + machine.D0, + machine.D1, + machine.D2, + ) + + backlight = machine.D3 +) + +func init() { + machine.SPI0.Configure(machine.SPIConfig{ + SCK: machine.SPI0_SCK_PIN, + SDO: machine.SPI0_SDO_PIN, + SDI: machine.SPI0_SDI_PIN, + Frequency: 24000000, + }) +} diff --git a/examples/ili9341/scroll/atsamd21.go b/examples/ili9341/scroll/atsamd21.go new file mode 100644 index 0000000..2b98594 --- /dev/null +++ b/examples/ili9341/scroll/atsamd21.go @@ -0,0 +1,29 @@ +// +build atsamd21 + +package main + +import ( + "machine" + + "tinygo.org/x/drivers/ili9341" +) + +var ( + display = ili9341.NewSpi( + machine.SPI0, + machine.D0, + machine.D1, + machine.D2, + ) + + backlight = machine.D3 +) + +func init() { + machine.SPI0.Configure(machine.SPIConfig{ + SCK: machine.SPI0_SCK_PIN, + SDO: machine.SPI0_SDO_PIN, + SDI: machine.SPI0_SDI_PIN, + Frequency: 24000000, + }) +} diff --git a/ili9341/spi_atsamd21.go b/ili9341/spi_atsamd21.go new file mode 100644 index 0000000..bc630a1 --- /dev/null +++ b/ili9341/spi_atsamd21.go @@ -0,0 +1,116 @@ +// +build atsamd21 + +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_SPI_CTRLB_RXEN) + + for !pd.bus.Bus.INTFLAG.HasBits(sam.SERCOM_SPI_INTFLAG_DRE) { + } + pd.bus.Bus.DATA.Set(uint32(b)) + + pd.bus.Bus.CTRLB.SetBits(sam.SERCOM_SPI_CTRLB_RXEN) + for pd.bus.Bus.SYNCBUSY.HasBits(sam.SERCOM_SPI_SYNCBUSY_CTRLB) { + } +} + +func (pd *spiDriver) write8n(b byte, n int) { + pd.bus.Bus.CTRLB.ClearBits(sam.SERCOM_SPI_CTRLB_RXEN) + + for i, c := 0, n; i < c; i++ { + for !pd.bus.Bus.INTFLAG.HasBits(sam.SERCOM_SPI_INTFLAG_DRE) { + } + pd.bus.Bus.DATA.Set(uint32(b)) + } + + pd.bus.Bus.CTRLB.SetBits(sam.SERCOM_SPI_CTRLB_RXEN) + for pd.bus.Bus.SYNCBUSY.HasBits(sam.SERCOM_SPI_SYNCBUSY_CTRLB) { + } +} + +func (pd *spiDriver) write8sl(b []byte) { + pd.bus.Bus.CTRLB.ClearBits(sam.SERCOM_SPI_CTRLB_RXEN) + + for i, c := 0, len(b); i < c; i++ { + for !pd.bus.Bus.INTFLAG.HasBits(sam.SERCOM_SPI_INTFLAG_DRE) { + } + pd.bus.Bus.DATA.Set(uint32(b[i])) + } + + pd.bus.Bus.CTRLB.SetBits(sam.SERCOM_SPI_CTRLB_RXEN) + for pd.bus.Bus.SYNCBUSY.HasBits(sam.SERCOM_SPI_SYNCBUSY_CTRLB) { + } +} + +func (pd *spiDriver) write16(data uint16) { + pd.bus.Bus.CTRLB.ClearBits(sam.SERCOM_SPI_CTRLB_RXEN) + + for !pd.bus.Bus.INTFLAG.HasBits(sam.SERCOM_SPI_INTFLAG_DRE) { + } + pd.bus.Bus.DATA.Set(uint32(uint8(data >> 8))) + for !pd.bus.Bus.INTFLAG.HasBits(sam.SERCOM_SPI_INTFLAG_DRE) { + } + pd.bus.Bus.DATA.Set(uint32(uint8(data))) + + pd.bus.Bus.CTRLB.SetBits(sam.SERCOM_SPI_CTRLB_RXEN) + for pd.bus.Bus.SYNCBUSY.HasBits(sam.SERCOM_SPI_SYNCBUSY_CTRLB) { + } +} + +func (pd *spiDriver) write16n(data uint16, n int) { + pd.bus.Bus.CTRLB.ClearBits(sam.SERCOM_SPI_CTRLB_RXEN) + + for i := 0; i < n; i++ { + for !pd.bus.Bus.INTFLAG.HasBits(sam.SERCOM_SPI_INTFLAG_DRE) { + } + pd.bus.Bus.DATA.Set(uint32(uint8(data >> 8))) + for !pd.bus.Bus.INTFLAG.HasBits(sam.SERCOM_SPI_INTFLAG_DRE) { + } + pd.bus.Bus.DATA.Set(uint32(uint8(data))) + } + + pd.bus.Bus.CTRLB.SetBits(sam.SERCOM_SPI_CTRLB_RXEN) + for pd.bus.Bus.SYNCBUSY.HasBits(sam.SERCOM_SPI_SYNCBUSY_CTRLB) { + } +} + +func (pd *spiDriver) write16sl(data []uint16) { + pd.bus.Bus.CTRLB.ClearBits(sam.SERCOM_SPI_CTRLB_RXEN) + + for i, c := 0, len(data); i < c; i++ { + for !pd.bus.Bus.INTFLAG.HasBits(sam.SERCOM_SPI_INTFLAG_DRE) { + } + pd.bus.Bus.DATA.Set(uint32(uint8(data[i] >> 8))) + for !pd.bus.Bus.INTFLAG.HasBits(sam.SERCOM_SPI_INTFLAG_DRE) { + } + pd.bus.Bus.DATA.Set(uint32(uint8(data[i]))) + } + + pd.bus.Bus.CTRLB.SetBits(sam.SERCOM_SPI_CTRLB_RXEN) + for pd.bus.Bus.SYNCBUSY.HasBits(sam.SERCOM_SPI_SYNCBUSY_CTRLB) { + } +}