package main
import (
"embedded/rtos"
"time"
"github.com/embeddedgo/stm32/hal/exti"
"github.com/embeddedgo/stm32/hal/gpio"
"github.com/embeddedgo/stm32/hal/irq"
"github.com/embeddedgo/stm32/hal/spi"
"github.com/embeddedgo/stm32/hal/spi/spi1"
_ "github.com/embeddedgo/stm32/devboard/f4-discovery/board/init"
)
const (
CTRL_REG4 = 0x20
CTRL_REG3 = 0x23
OUT_X_L = 0x28
)
var accel *LIS3DSH
type LIS3DSH struct {
d *spi.Driver
cs gpio.Pin
dri exti.Lines
drn rtos.Note
}
func NewLIS3DSH(d *spi.Driver, cs gpio.Pin, dri exti.Lines) *LIS3DSH {
return &LIS3DSH{d: d, cs: cs, dri: dri}
}
func (a *LIS3DSH) Init() {
time.Sleep(10*time.Millisecond - rtos.Nanotime())
a.cs.Clear()
a.d.WriteRead([]byte{CTRL_REG4, 0x67}, nil)
a.cs.Set()
a.cs.Clear()
a.d.WriteRead([]byte{CTRL_REG3, 0xC8}, nil)
a.cs.Set()
}
func (a *LIS3DSH) ReadXYZ() (x, y, z int) {
a.drn.Clear()
a.dri.EnableIRQ()
a.drn.Sleep(-1)
buf := [1 + 6]byte{1<<7 | OUT_X_L}
a.cs.Clear()
a.d.WriteRead(buf[:1], buf[:])
a.cs.Set()
x = int(int16(buf[1])|int16(buf[2])<<8) * 2000 / 32768
y = int(int16(buf[3])|int16(buf[4])<<8) * 2000 / 32768
z = int(int16(buf[5])|int16(buf[6])<<8) * 2000 / 32768
return
}
func (a *LIS3DSH) ISR() {
a.dri.DisableIRQ()
a.dri.ClearPending()
a.drn.Wakeup()
}
func main() {
// Allocate GPIO pins
pa := gpio.A()
pa.EnableClock(true)
sck := pa.Pin(5)
miso := pa.Pin(6)
mosi := pa.Pin(7)
pe := gpio.E()
pe.EnableClock(true)
dr := pe.Pin(0)
cs := pe.Pin(3)
// Configure SPI pins
spi1.UsePinMaster(spi.SCK, sck)
spi1.UsePinMaster(spi.MOSI, mosi)
spi1.UsePinMaster(spi.MISO, miso)
cs.Set() // CS active state is low
cs.Setup(&gpio.Config{Mode: gpio.Out, Speed: gpio.High})
// Configure EXTI
dr.Setup(&gpio.Config{Mode: gpio.In})
dri := exti.Lines(1 << dr.Index())
dri.Connect(dr.Port())
dri.EnableRiseTrig()
irq.EXTI0.Enable(rtos.IntPrioLow, 0)
// Configure and enable SPI
d := spi1.Driver()
d.Setup(spi.Master|spi.CPOL1|spi.CPHA1|spi.SoftSS|spi.ISSHigh, 10e6)
d.SetWordSize(8)
d.Enable()
// Reading acceleration data using DRDY interrupt
accel = NewLIS3DSH(d, cs, dri)
accel.Init()
for {
show(accel.ReadXYZ())
}
}
func show(x, y, z int) {
gauge("x", x)
gauge("y", y)
gauge("z", z)
print("+-----------------------------------------+\n")
rtos.Nanosleep(100e6)
}
func gauge(name string, v int) {
const bar = "--------------------"
const spc = " "
v /= 100
print("|")
switch {
case v > 0:
if v > 20 {
v = 20
}
print(spc, name, bar[:v], spc[v:])
case v < 0:
if v < -20 {
v = -20
}
print(spc[:20+v], bar[20+v:], name, spc)
default: // v == 0:
print(spc, name, spc)
}
print("|\n")
}
//go:interrupthandler
func EXTI0_Handler() { accel.ISR() }