Skip to content

Commit ab01269

Browse files
committed
add STM32F4 SPI driver for ILI9341, pyportal_boing demo for feather-stm32f405
1 parent 4c98d0b commit ab01269

File tree

2 files changed

+173
-0
lines changed

2 files changed

+173
-0
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// +build feather_stm32f405
2+
3+
package main
4+
5+
import (
6+
"machine"
7+
8+
"tinygo.org/x/drivers/ili9341"
9+
)
10+
11+
var (
12+
csPin = machine.D12
13+
dcPin = machine.D11
14+
display = ili9341.NewSpi(
15+
machine.SPI0,
16+
dcPin,
17+
csPin,
18+
machine.D8,
19+
)
20+
21+
backlight = machine.D9
22+
)
23+
24+
func init() {
25+
machine.SPI0.Configure(machine.SPIConfig{
26+
SCK: machine.SPI0_SCK_PIN,
27+
SDO: machine.SPI0_SDO_PIN,
28+
SDI: machine.SPI0_SDI_PIN,
29+
Frequency: 40000000,
30+
})
31+
}

ili9341/spi_stm32f4.go

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
// +build stm32f4
2+
3+
package ili9341
4+
5+
import (
6+
"device/stm32"
7+
"machine"
8+
)
9+
10+
type spiDriver struct {
11+
bus machine.SPI
12+
}
13+
14+
func NewSpi(bus machine.SPI, dc, cs, rst machine.Pin) *Device {
15+
return &Device{
16+
dc: dc,
17+
cs: cs,
18+
rst: rst,
19+
rd: machine.NoPin,
20+
driver: &spiDriver{
21+
bus: bus,
22+
},
23+
}
24+
}
25+
26+
func (pd *spiDriver) configure(config *Config) {
27+
}
28+
29+
func (pd *spiDriver) write8(b byte) {
30+
if !pd.bus.Bus.CR1.HasBits(stm32.SPI_CR1_SPE) {
31+
pd.bus.Bus.CR1.SetBits(stm32.SPI_CR1_SPE)
32+
}
33+
34+
pd.setWord(b, true, true)
35+
36+
pd.bus.Bus.CR1.ClearBits(stm32.SPI_CR1_SPE)
37+
}
38+
39+
func (pd *spiDriver) write8n(b byte, n int) {
40+
if !pd.bus.Bus.CR1.HasBits(stm32.SPI_CR1_SPE) {
41+
pd.bus.Bus.CR1.SetBits(stm32.SPI_CR1_SPE)
42+
}
43+
44+
for i := 0; i < n-1; i++ {
45+
pd.setWord(b, i == 0, i+1 == n)
46+
}
47+
48+
pd.bus.Bus.CR1.ClearBits(stm32.SPI_CR1_SPE)
49+
}
50+
51+
func (pd *spiDriver) write8sl(b []byte) {
52+
if !pd.bus.Bus.CR1.HasBits(stm32.SPI_CR1_SPE) {
53+
pd.bus.Bus.CR1.SetBits(stm32.SPI_CR1_SPE)
54+
}
55+
56+
for i, w := range b {
57+
pd.setWord(w, i == 0, i+1 == len(b))
58+
}
59+
60+
pd.bus.Bus.CR1.ClearBits(stm32.SPI_CR1_SPE)
61+
}
62+
63+
func (pd *spiDriver) write16(data uint16) {
64+
if !pd.bus.Bus.CR1.HasBits(stm32.SPI_CR1_SPE) {
65+
pd.bus.Bus.CR1.SetBits(stm32.SPI_CR1_SPE)
66+
}
67+
68+
pd.setWord(uint8(data>>8), true, false)
69+
pd.setWord(uint8(data), false, true)
70+
71+
pd.bus.Bus.CR1.ClearBits(stm32.SPI_CR1_SPE)
72+
}
73+
74+
func (pd *spiDriver) write16n(data uint16, n int) {
75+
if !pd.bus.Bus.CR1.HasBits(stm32.SPI_CR1_SPE) {
76+
pd.bus.Bus.CR1.SetBits(stm32.SPI_CR1_SPE)
77+
}
78+
79+
for i := 0; i < n; i++ {
80+
pd.setWord(uint8(data>>8), i == 0, false)
81+
pd.setWord(uint8(data), false, i+1 == n)
82+
}
83+
84+
pd.bus.Bus.CR1.ClearBits(stm32.SPI_CR1_SPE)
85+
}
86+
87+
func (pd *spiDriver) write16sl(data []uint16) {
88+
if !pd.bus.Bus.CR1.HasBits(stm32.SPI_CR1_SPE) {
89+
pd.bus.Bus.CR1.SetBits(stm32.SPI_CR1_SPE)
90+
}
91+
92+
for i, w := range data {
93+
pd.setWord(uint8(w>>8), i == 0, false)
94+
pd.setWord(uint8(w), false, i+1 == len(data))
95+
}
96+
97+
pd.bus.Bus.CR1.ClearBits(stm32.SPI_CR1_SPE)
98+
}
99+
100+
// puts a single 8-bit word in the SPI data register (DR).
101+
// if first (first word being transmitted) is false, waits for the SPI transmit
102+
// buffer empty bit (TXE) is set before putting the word in DR.
103+
// if last (last word being transmitted) is true, waits for the SPI transmit
104+
// buffer empty bit (TXE) is set and SPI bus busy bit (BSY) is clear before
105+
// returning.
106+
// for all wait operations, a fixed number of wait iterations (const tryMax) are
107+
// performed before a timeout is assumed.
108+
// if timeout occurs, returns false. otherwise, returns true.
109+
func (pd *spiDriver) setWord(word uint8, first bool, last bool) bool {
110+
111+
const tryMax = 10000
112+
113+
canWrite := first
114+
for i := 0; (!canWrite) && (i < tryMax); i++ {
115+
canWrite = pd.bus.Bus.SR.HasBits(stm32.SPI_SR_TXE)
116+
}
117+
if !canWrite {
118+
return false // timeout
119+
}
120+
121+
pd.bus.Bus.DR.Set(uint32(word))
122+
123+
if last {
124+
canReturn := false
125+
for i := 0; (!canReturn) && (i < tryMax); i++ {
126+
canReturn = pd.bus.Bus.SR.HasBits(stm32.SPI_SR_TXE)
127+
}
128+
if !canReturn {
129+
return false // timeout
130+
}
131+
132+
canReturn = false
133+
for i := 0; (!canReturn) && (i < tryMax); i++ {
134+
canReturn = !pd.bus.Bus.SR.HasBits(stm32.SPI_SR_BSY)
135+
}
136+
if !canReturn {
137+
return false // timeout
138+
}
139+
}
140+
141+
return true
142+
}

0 commit comments

Comments
 (0)