Implement dynamic hardware auto-detection in board_config.py to support both Hosyond and Waveshare RLCD boards out-of-the-box
This commit is contained in:
+73
-50
@@ -1,6 +1,7 @@
|
||||
import time
|
||||
import machine
|
||||
from machine import Pin, I2C, I2S
|
||||
import board_config
|
||||
|
||||
class ES7210:
|
||||
"""MicroPython driver for the ES7210 4-Channel Audio ADC (Microphone Array).
|
||||
@@ -79,32 +80,41 @@ def record_audio(duration_seconds=5, filename='recording.pcm'):
|
||||
duration_seconds (int): How long to record in seconds.
|
||||
filename (str): Name of output raw PCM file on the device.
|
||||
"""
|
||||
# 1. Start I2C Control Bus (SDA=16, SCL=15)
|
||||
i2c = I2C(0, sda=Pin(16), scl=Pin(15))
|
||||
# 1. Use I2C Control Bus from board_config
|
||||
i2c = board_config.i2c_bus
|
||||
|
||||
# 1a. Setup Master Clock (MCLK) on GPIO 4 using PWM (needed for ES8311 ADC)
|
||||
mclk_pin = Pin(4, Pin.OUT)
|
||||
mclk_pwm = machine.PWM(mclk_pin)
|
||||
mclk_pwm.freq(6144000)
|
||||
mclk_pwm.duty_u16(32768)
|
||||
# 1a. Setup Master Clock (MCLK) using PWM if configured
|
||||
mclk_pwm = None
|
||||
if board_config.audio_mclk_pin is not None:
|
||||
mclk_pin = Pin(board_config.audio_mclk_pin, Pin.OUT)
|
||||
mclk_pwm = machine.PWM(mclk_pin)
|
||||
mclk_pwm.freq(board_config.audio_mclk_freq)
|
||||
mclk_pwm.duty_u16(32768)
|
||||
|
||||
# 2. Configure I2S Receiver
|
||||
# Pins: sck=BCLK (GPIO 5), ws=WS/LRCK (GPIO 7), sd=DIN (GPIO 6)
|
||||
i2s = I2S(1,
|
||||
sck=Pin(5),
|
||||
ws=Pin(7),
|
||||
sd=Pin(6),
|
||||
sck=Pin(board_config.audio_i2s_sck),
|
||||
ws=Pin(board_config.audio_i2s_ws),
|
||||
sd=Pin(board_config.audio_i2s_rx_sd),
|
||||
mode=I2S.RX,
|
||||
ibuf=16000,
|
||||
rate=16000,
|
||||
bits=16,
|
||||
format=I2S.STEREO)
|
||||
|
||||
# 3. Wake up and configure the ES8311 codec chip
|
||||
mic_adc = ES8311(i2c)
|
||||
if not mic_adc.init(sample_rate=16000):
|
||||
i2s.deinit()
|
||||
return False
|
||||
# 3. Wake up and configure the microphone chip (ES7210 vs ES8311)
|
||||
if board_config.audio_mic_codec == "ES7210":
|
||||
mic_adc = ES7210(i2c)
|
||||
if not mic_adc.init(sample_rate=16000, bit_width=16):
|
||||
i2s.deinit()
|
||||
if mclk_pwm: mclk_pwm.deinit()
|
||||
return False
|
||||
else:
|
||||
mic_adc = ES8311(i2c)
|
||||
if not mic_adc.init(sample_rate=16000):
|
||||
i2s.deinit()
|
||||
if mclk_pwm: mclk_pwm.deinit()
|
||||
return False
|
||||
|
||||
print(f"Recording {duration_seconds} seconds of audio...")
|
||||
|
||||
@@ -130,8 +140,15 @@ def record_audio(duration_seconds=5, filename='recording.pcm'):
|
||||
return False
|
||||
finally:
|
||||
# Always release the I2S peripheral resources
|
||||
i2s.deinit()
|
||||
mclk_pwm.deinit()
|
||||
try:
|
||||
i2s.deinit()
|
||||
except:
|
||||
pass
|
||||
if mclk_pwm:
|
||||
try:
|
||||
mclk_pwm.deinit()
|
||||
except:
|
||||
pass
|
||||
print("I2S receiver and MCLK deinitialized.")
|
||||
|
||||
|
||||
@@ -226,37 +243,40 @@ def play_tone(frequency=440, duration_ms=1000, volume=50):
|
||||
|
||||
print(f"Playing tone: {frequency}Hz for {duration_ms}ms (vol={volume})...")
|
||||
|
||||
# 1. Setup Master Clock (MCLK) on GPIO 4 using PWM
|
||||
mclk_pin = Pin(4, Pin.OUT)
|
||||
mclk_pwm = machine.PWM(mclk_pin)
|
||||
mclk_pwm.freq(6144000)
|
||||
mclk_pwm.duty_u16(32768)
|
||||
# 1. Setup Master Clock (MCLK) using PWM if configured
|
||||
mclk_pwm = None
|
||||
if board_config.audio_mclk_pin is not None:
|
||||
mclk_pin = Pin(board_config.audio_mclk_pin, Pin.OUT)
|
||||
mclk_pwm = machine.PWM(mclk_pin)
|
||||
mclk_pwm.freq(board_config.audio_mclk_freq)
|
||||
mclk_pwm.duty_u16(32768)
|
||||
|
||||
# 2. Start I2C Control Bus (SDA=16, SCL=15)
|
||||
i2c = I2C(0, sda=Pin(16), scl=Pin(15))
|
||||
# 2. Use dynamic I2C Control Bus from board_config
|
||||
i2c = board_config.i2c_bus
|
||||
|
||||
# 3. Initialize the ES8311 DAC
|
||||
dac = ES8311(i2c)
|
||||
if not dac.init(sample_rate=16000):
|
||||
mclk_pwm.deinit()
|
||||
if mclk_pwm: mclk_pwm.deinit()
|
||||
return False
|
||||
|
||||
dac.set_volume(volume)
|
||||
|
||||
# 4. Configure I2S TX
|
||||
# Pins: sck=BCLK (GPIO 5), ws=WS/LRCK (GPIO 7), sd=DOUT (GPIO 8)
|
||||
i2s = I2S(1,
|
||||
sck=Pin(5),
|
||||
ws=Pin(7),
|
||||
sd=Pin(8),
|
||||
sck=Pin(board_config.audio_i2s_sck),
|
||||
ws=Pin(board_config.audio_i2s_ws),
|
||||
sd=Pin(board_config.audio_i2s_tx_sd),
|
||||
mode=I2S.TX,
|
||||
ibuf=8000,
|
||||
rate=16000,
|
||||
bits=16,
|
||||
format=I2S.STEREO)
|
||||
|
||||
# 5. Enable Speaker Amplifier (GPIO 1, Active Low)
|
||||
amp_pin = Pin(1, Pin.OUT, value=0)
|
||||
# 5. Enable Speaker Amplifier
|
||||
on_val = 0 if board_config.audio_amp_active_level == 0 else 1
|
||||
off_val = 1 if board_config.audio_amp_active_level == 0 else 0
|
||||
amp_pin = Pin(board_config.audio_amp_pin, Pin.OUT, value=on_val)
|
||||
|
||||
# 6. Generate sine wave cycle
|
||||
# Approximate frequency to make integer number of samples per cycle
|
||||
@@ -284,9 +304,9 @@ def play_tone(frequency=440, duration_ms=1000, volume=50):
|
||||
|
||||
# 7. Clean up
|
||||
time.sleep_ms(100) # Let the remaining buffer play out
|
||||
amp_pin.value(1) # Disable amp
|
||||
amp_pin.value(off_val) # Disable amp
|
||||
i2s.deinit()
|
||||
mclk_pwm.deinit()
|
||||
if mclk_pwm: mclk_pwm.deinit()
|
||||
print("Tone playback complete.")
|
||||
return True
|
||||
|
||||
@@ -344,39 +364,42 @@ def play_wav(filename, volume=50):
|
||||
|
||||
print(f"WAV Info: {sample_rate}Hz, {bits} bits, {'Mono' if channels == 1 else 'Stereo'}")
|
||||
|
||||
# 2. Setup Master Clock (MCLK) on GPIO 4 using PWM
|
||||
mclk_pin = Pin(4, Pin.OUT)
|
||||
mclk_pwm = machine.PWM(mclk_pin)
|
||||
mclk_pwm.freq(6144000)
|
||||
mclk_pwm.duty_u16(32768)
|
||||
# 2. Setup Master Clock (MCLK) using PWM if configured
|
||||
mclk_pwm = None
|
||||
if board_config.audio_mclk_pin is not None:
|
||||
mclk_pin = Pin(board_config.audio_mclk_pin, Pin.OUT)
|
||||
mclk_pwm = machine.PWM(mclk_pin)
|
||||
mclk_pwm.freq(board_config.audio_mclk_freq)
|
||||
mclk_pwm.duty_u16(32768)
|
||||
|
||||
# 3. Start I2C Control Bus (SDA=16, SCL=15)
|
||||
i2c = I2C(0, sda=Pin(16), scl=Pin(15))
|
||||
# 3. Use dynamic I2C Control Bus from board_config
|
||||
i2c = board_config.i2c_bus
|
||||
|
||||
# 4. Initialize the ES8311 DAC
|
||||
dac = ES8311(i2c)
|
||||
if not dac.init(sample_rate=16000):
|
||||
mclk_pwm.deinit()
|
||||
if mclk_pwm: mclk_pwm.deinit()
|
||||
f.close()
|
||||
return False
|
||||
|
||||
dac.set_volume(volume)
|
||||
|
||||
# 5. Configure I2S TX
|
||||
# Pins: sck=BCLK (GPIO 5), ws=WS/LRCK (GPIO 7), sd=DOUT (GPIO 8)
|
||||
i2s_format = I2S.MONO if channels == 1 else I2S.STEREO
|
||||
i2s = I2S(1,
|
||||
sck=Pin(5),
|
||||
ws=Pin(7),
|
||||
sd=Pin(8),
|
||||
sck=Pin(board_config.audio_i2s_sck),
|
||||
ws=Pin(board_config.audio_i2s_ws),
|
||||
sd=Pin(board_config.audio_i2s_tx_sd),
|
||||
mode=I2S.TX,
|
||||
ibuf=4096,
|
||||
rate=sample_rate,
|
||||
bits=bits,
|
||||
format=i2s_format)
|
||||
|
||||
# 6. Enable Speaker Amplifier (GPIO 1, Active Low)
|
||||
amp_pin = Pin(1, Pin.OUT, value=0)
|
||||
# 6. Enable Speaker Amplifier
|
||||
on_val = 0 if board_config.audio_amp_active_level == 0 else 1
|
||||
off_val = 1 if board_config.audio_amp_active_level == 0 else 0
|
||||
amp_pin = Pin(board_config.audio_amp_pin, Pin.OUT, value=on_val)
|
||||
|
||||
# 7. Read and stream chunks to I2S
|
||||
buf = bytearray(2048)
|
||||
@@ -388,9 +411,9 @@ def play_wav(filename, volume=50):
|
||||
|
||||
# 8. Clean up
|
||||
time.sleep_ms(100) # Let the remaining buffer play out
|
||||
amp_pin.value(1) # Disable amp
|
||||
amp_pin.value(off_val) # Disable amp
|
||||
i2s.deinit()
|
||||
mclk_pwm.deinit()
|
||||
if mclk_pwm: mclk_pwm.deinit()
|
||||
f.close()
|
||||
print("WAV playback complete.")
|
||||
return True
|
||||
|
||||
Reference in New Issue
Block a user