Add PDM support for circuitplay-bluefruit (#3359)

machine/nrf52840: add PDM support

Signed-off-by: Marcus Sorensen <marcus@turboio.com>
Этот коммит содержится в:
Marcus Sorensen 2023-01-17 04:32:01 -07:00 коммит произвёл GitHub
родитель 0d646d8e95
коммит e7ba07dd5a
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 110 добавлений и 0 удалений

27
src/examples/pdm/pdm.go Обычный файл
Просмотреть файл

@ -0,0 +1,27 @@
package main
import (
"fmt"
"machine"
)
var (
audio = make([]int16, 16)
pdm = machine.PDM{}
)
func main() {
machine.BUTTONA.Configure(machine.PinConfig{Mode: machine.PinInputPulldown})
err := pdm.Configure(machine.PDMConfig{CLK: machine.PDM_CLK_PIN, DIN: machine.PDM_DIN_PIN})
if err != nil {
panic(fmt.Sprintf("Failed to configure PDM:%v", err))
}
for {
if machine.BUTTONA.Get() {
println("Recording new audio clip into memory")
pdm.Read(audio)
println(fmt.Sprintf("Recorded new audio clip into memory: %v", audio))
}
}
}

Просмотреть файл

@ -73,6 +73,12 @@ const (
SPI0_SDI_PIN = P0_23 // SDI SPI0_SDI_PIN = P0_23 // SDI
) )
// PDM pins
const (
PDM_CLK_PIN = P0_17 // CLK
PDM_DIN_PIN = P0_16 // DIN
)
// USB CDC identifiers // USB CDC identifiers
const ( const (
usb_STRING_PRODUCT = "Adafruit Circuit Playground Bluefruit" usb_STRING_PRODUCT = "Adafruit Circuit Playground Bluefruit"

Просмотреть файл

@ -4,6 +4,8 @@ package machine
import ( import (
"device/nrf" "device/nrf"
"errors"
"unsafe"
) )
// Get peripheral and pin number for this GPIO pin. // Get peripheral and pin number for this GPIO pin.
@ -32,3 +34,71 @@ var (
PWM2 = &PWM{PWM: nrf.PWM2} PWM2 = &PWM{PWM: nrf.PWM2}
PWM3 = &PWM{PWM: nrf.PWM3} 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
}

7
src/machine/pdm.go Обычный файл
Просмотреть файл

@ -0,0 +1,7 @@
package machine
type PDMConfig struct {
Stereo bool
DIN Pin
CLK Pin
}