rp2040: add machine.ReadTemperature
Replace ADCChannel.ReadTemperature() with a simple ReadTemperature function. Not all chips will have a temperature sensor that is read by sampling an ADC channel. The replacement ReadTemperature is simpler and more generic to other chip families. This breaks chips that were relying on the previous ReadTemperature method. I hope it won't break a lot of existing code. If it does, a fallback can be added.
Этот коммит содержится в:
родитель
86ea216e7d
коммит
70b3ece6ec
4 изменённых файлов: 39 добавлений и 64 удалений
2
Makefile
2
Makefile
|
@ -611,7 +611,7 @@ endif
|
|||
@$(MD5SUM) test.hex
|
||||
$(TINYGO) build -size short -o test.hex -target=challenger-rp2040 examples/blinky1
|
||||
@$(MD5SUM) test.hex
|
||||
$(TINYGO) build -size short -o test.hex -target=trinkey-qt2040 examples/adc_rp2040
|
||||
$(TINYGO) build -size short -o test.hex -target=trinkey-qt2040 examples/temp
|
||||
@$(MD5SUM) test.hex
|
||||
# test pwm
|
||||
$(TINYGO) build -size short -o test.hex -target=itsybitsy-m0 examples/pwm
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
// Reads multiple rp2040 ADC channels concurrently. Including the internal temperature sensor
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"machine"
|
||||
"time"
|
||||
)
|
||||
|
||||
type celsius float32
|
||||
|
||||
func (c celsius) String() string {
|
||||
return fmt.Sprintf("%4.1f℃", c)
|
||||
}
|
||||
|
||||
// rp2040 ADC is 12 bits. Reading are shifted <<4 to fill the 16-bit range.
|
||||
var adcReading [3]uint16
|
||||
|
||||
func readADC(a machine.ADC, w time.Duration, i int) {
|
||||
for {
|
||||
adcReading[i] = a.Get()
|
||||
time.Sleep(w)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
machine.InitADC()
|
||||
a0 := machine.ADC{machine.ADC0} // GPIO26 input
|
||||
a1 := machine.ADC{machine.ADC1} // GPIO27 input
|
||||
a2 := machine.ADC{machine.ADC2} // GPIO28 input
|
||||
t := machine.ADC_TEMP_SENSOR // Internal Temperature sensor
|
||||
// Configure sets the GPIOs to PinAnalog mode
|
||||
a0.Configure(machine.ADCConfig{})
|
||||
a1.Configure(machine.ADCConfig{})
|
||||
a2.Configure(machine.ADCConfig{})
|
||||
// Configure powers on the temperature sensor
|
||||
t.Configure(machine.ADCConfig{})
|
||||
|
||||
// Safe to read concurrently
|
||||
go readADC(a0, 10*time.Millisecond, 0)
|
||||
go readADC(a1, 17*time.Millisecond, 1)
|
||||
go readADC(a2, 29*time.Millisecond, 2)
|
||||
|
||||
for {
|
||||
fmt.Printf("ADC0: %5d ADC1: %5d ADC2: %5d Temp: %v\n\r", adcReading[0], adcReading[1], adcReading[2], celsius(float32(t.ReadTemperature())/1000))
|
||||
time.Sleep(1000 * time.Millisecond)
|
||||
}
|
||||
}
|
23
src/examples/temp/temp.go
Обычный файл
23
src/examples/temp/temp.go
Обычный файл
|
@ -0,0 +1,23 @@
|
|||
// Read the internal temperature sensor of the chip.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"machine"
|
||||
"time"
|
||||
)
|
||||
|
||||
type celsius float32
|
||||
|
||||
func (c celsius) String() string {
|
||||
return fmt.Sprintf("%4.1f℃", c)
|
||||
}
|
||||
|
||||
func main() {
|
||||
for {
|
||||
temp := celsius(float32(machine.ReadTemperature()) / 1000)
|
||||
println("temperature:", temp.String())
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
}
|
|
@ -17,8 +17,8 @@ const (
|
|||
adc0_CH ADCChannel = iota
|
||||
adc1_CH
|
||||
adc2_CH
|
||||
adc3_CH // Note: GPIO29 not broken out on pico board
|
||||
ADC_TEMP_SENSOR // Internal temperature sensor channel
|
||||
adc3_CH // Note: GPIO29 not broken out on pico board
|
||||
adcTempSensor // Internal temperature sensor channel
|
||||
)
|
||||
|
||||
// Used to serialise ADC sampling
|
||||
|
@ -75,19 +75,17 @@ func (a ADC) GetADCChannel() (c ADCChannel, err error) {
|
|||
return c, err
|
||||
}
|
||||
|
||||
// Configure sets the channel's associated pin to analog input mode or powers on the temperature sensor for ADC_TEMP_SENSOR.
|
||||
// Configure sets the channel's associated pin to analog input mode.
|
||||
// The powered on temperature sensor increases ADC_AVDD current by approximately 40 μA.
|
||||
func (c ADCChannel) Configure(config ADCConfig) error {
|
||||
if config.Reference != 0 {
|
||||
adcAref = config.Reference
|
||||
}
|
||||
if p, err := c.Pin(); err == nil {
|
||||
p.Configure(PinConfig{Mode: PinAnalog})
|
||||
}
|
||||
if c == ADC_TEMP_SENSOR {
|
||||
// Enable temperature sensor bias source
|
||||
rp.ADC.CS.SetBits(rp.ADC_CS_TS_EN)
|
||||
p, err := c.Pin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.Configure(PinConfig{Mode: PinAnalog})
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -112,13 +110,16 @@ func (c ADCChannel) getVoltage() uint32 {
|
|||
}
|
||||
|
||||
// ReadTemperature does a one-shot sample of the internal temperature sensor and returns a milli-celsius reading.
|
||||
// Only works on the ADC_TEMP_SENSOR channel. aka AINSEL=4. Other channels will return 0
|
||||
func (c ADCChannel) ReadTemperature() (millicelsius uint32) {
|
||||
if c != ADC_TEMP_SENSOR {
|
||||
return
|
||||
func ReadTemperature() (millicelsius int32) {
|
||||
if rp.ADC.CS.Get()&rp.ADC_CS_EN == 0 {
|
||||
InitADC()
|
||||
}
|
||||
|
||||
// Enable temperature sensor bias source
|
||||
rp.ADC.CS.SetBits(rp.ADC_CS_TS_EN)
|
||||
|
||||
// T = 27 - (ADC_voltage - 0.706)/0.001721
|
||||
return (27000<<16 - (c.getVoltage()-706<<16)*581) >> 16
|
||||
return (27000<<16 - (int32(adcTempSensor.getVoltage())-706<<16)*581) >> 16
|
||||
}
|
||||
|
||||
// waitForReady spins waiting for the ADC peripheral to become ready.
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче