mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-07 12:33:42 +00:00
6e1b8a54aa
machine/stm32, nrf: implement machine.Flash Implements the machine.Flash interface using the same definition as the tinyfs BlockDevice. This implementation covers the stm32f4, stm32l4, stm32wlx, nrf51, nrf52, and nrf528xx processors.
111 lines
3.0 KiB
Go
111 lines
3.0 KiB
Go
//go:build nrf52840
|
|
|
|
package machine
|
|
|
|
import (
|
|
"device/nrf"
|
|
"errors"
|
|
"unsafe"
|
|
)
|
|
|
|
// Get peripheral and pin number for this GPIO pin.
|
|
func (p Pin) getPortPin() (*nrf.GPIO_Type, uint32) {
|
|
if p >= 32 {
|
|
return nrf.P1, uint32(p - 32)
|
|
} else {
|
|
return nrf.P0, uint32(p)
|
|
}
|
|
}
|
|
|
|
func (uart *UART) setPins(tx, rx Pin) {
|
|
nrf.UART0.PSEL.TXD.Set(uint32(tx))
|
|
nrf.UART0.PSEL.RXD.Set(uint32(rx))
|
|
}
|
|
|
|
func (i2c *I2C) setPins(scl, sda Pin) {
|
|
i2c.Bus.PSEL.SCL.Set(uint32(scl))
|
|
i2c.Bus.PSEL.SDA.Set(uint32(sda))
|
|
}
|
|
|
|
// PWM
|
|
var (
|
|
PWM0 = &PWM{PWM: nrf.PWM0}
|
|
PWM1 = &PWM{PWM: nrf.PWM1}
|
|
PWM2 = &PWM{PWM: nrf.PWM2}
|
|
PWM3 = &PWM{PWM: nrf.PWM3}
|
|
)
|
|
|
|
// PDM represents a PDM device
|
|
type PDM struct {
|
|
device *nrf.PDM_Type
|
|
defaultBuffer int16
|
|
}
|
|
|
|
// Configure is intended to set up the PDM interface prior to use.
|
|
func (pdm *PDM) Configure(config PDMConfig) error {
|
|
if config.DIN == 0 {
|
|
return errors.New("No DIN pin provided in configuration")
|
|
}
|
|
|
|
if config.CLK == 0 {
|
|
return errors.New("No CLK pin provided in configuration")
|
|
}
|
|
|
|
config.DIN.Configure(PinConfig{Mode: PinInput})
|
|
config.CLK.Configure(PinConfig{Mode: PinOutput})
|
|
pdm.device = nrf.PDM
|
|
pdm.device.PSEL.DIN.Set(uint32(config.DIN))
|
|
pdm.device.PSEL.CLK.Set(uint32(config.CLK))
|
|
pdm.device.PDMCLKCTRL.Set(nrf.PDM_PDMCLKCTRL_FREQ_Default)
|
|
pdm.device.RATIO.Set(nrf.PDM_RATIO_RATIO_Ratio64)
|
|
pdm.device.GAINL.Set(nrf.PDM_GAINL_GAINL_DefaultGain)
|
|
pdm.device.GAINR.Set(nrf.PDM_GAINR_GAINR_DefaultGain)
|
|
pdm.device.ENABLE.Set(nrf.PDM_ENABLE_ENABLE_Enabled)
|
|
|
|
if config.Stereo {
|
|
pdm.device.MODE.Set(nrf.PDM_MODE_OPERATION_Stereo | nrf.PDM_MODE_EDGE_LeftRising)
|
|
} else {
|
|
pdm.device.MODE.Set(nrf.PDM_MODE_OPERATION_Mono | nrf.PDM_MODE_EDGE_LeftRising)
|
|
}
|
|
|
|
pdm.device.SAMPLE.SetPTR(uint32(uintptr(unsafe.Pointer(&pdm.defaultBuffer))))
|
|
pdm.device.SAMPLE.SetMAXCNT_BUFFSIZE(1)
|
|
pdm.device.SetTASKS_START(1)
|
|
return nil
|
|
}
|
|
|
|
// Read stores a set of samples in the given target buffer.
|
|
func (pdm *PDM) Read(buf []int16) (uint32, error) {
|
|
pdm.device.SAMPLE.SetPTR(uint32(uintptr(unsafe.Pointer(&buf[0]))))
|
|
pdm.device.SAMPLE.MAXCNT.Set(uint32(len(buf)))
|
|
pdm.device.EVENTS_STARTED.Set(0)
|
|
|
|
// Step 1: wait for new sampling to start for target buffer
|
|
for !pdm.device.EVENTS_STARTED.HasBits(nrf.PDM_EVENTS_STARTED_EVENTS_STARTED) {
|
|
}
|
|
pdm.device.EVENTS_END.Set(0)
|
|
|
|
// Step 2: swap out buffers for next recording so we don't continue to
|
|
// write to the target buffer
|
|
pdm.device.EVENTS_STARTED.Set(0)
|
|
pdm.device.SAMPLE.SetPTR(uint32(uintptr(unsafe.Pointer(&pdm.defaultBuffer))))
|
|
pdm.device.SAMPLE.MAXCNT.Set(1)
|
|
|
|
// Step 3: wait for original event to end
|
|
for pdm.device.EVENTS_END.HasBits(nrf.PDM_EVENTS_STOPPED_EVENTS_STOPPED) {
|
|
}
|
|
|
|
// Step 4: wait for default buffer to start recording before proceeding
|
|
// otherwise we see the contents of target buffer change later
|
|
for !pdm.device.EVENTS_STARTED.HasBits(nrf.PDM_EVENTS_STARTED_EVENTS_STARTED) {
|
|
}
|
|
|
|
return uint32(len(buf)), nil
|
|
}
|
|
|
|
const eraseBlockSizeValue = 4096
|
|
|
|
func eraseBlockSize() int64 {
|
|
return eraseBlockSizeValue
|
|
}
|