Initial commit: ESP32-S3-RLCD-4.2 hardware utility classes and demo
This commit is contained in:
+128
@@ -0,0 +1,128 @@
|
||||
import time
|
||||
import machine
|
||||
from machine import Pin, I2C, I2S
|
||||
|
||||
class ES7210:
|
||||
"""MicroPython driver for the ES7210 4-Channel Audio ADC (Microphone Array).
|
||||
|
||||
Controls the ES7210 chip over I2C to configure clocks, channels, gain, and format.
|
||||
"""
|
||||
ADDR = 0x40
|
||||
|
||||
def __init__(self, i2c):
|
||||
self.i2c = i2c
|
||||
|
||||
def init(self, sample_rate=16000, bit_width=16):
|
||||
"""Initializes the ES7210 registers for dual-microphone recording.
|
||||
|
||||
Args:
|
||||
sample_rate (int): Audio sample rate (e.g. 16000, 44100, 48000).
|
||||
bit_width (int): Data bit depth (16 or 24).
|
||||
|
||||
Returns:
|
||||
bool: True if initialization was successful, False otherwise.
|
||||
"""
|
||||
print("Initializing ES7210 Microphone ADC...")
|
||||
try:
|
||||
# 1. Reset the chip
|
||||
self._write(0x00, 0xFF) # Write all 1s to reset register
|
||||
time.sleep_ms(10)
|
||||
self._write(0x00, 0x00) # Release reset
|
||||
|
||||
# 2. Power management and system configuration
|
||||
self._write(0x01, 0x00) # Enable analog power, reference voltage
|
||||
self._write(0x11, 0x60) # Enable master clock PLL
|
||||
|
||||
# 3. Configure Clock Dividers
|
||||
if sample_rate == 16000:
|
||||
self._write(0x02, 0x0C) # BCLK divider
|
||||
self._write(0x03, 0x10) # LRCK divider
|
||||
else: # 44100 / 48000 defaults
|
||||
self._write(0x02, 0x04)
|
||||
self._write(0x03, 0x08)
|
||||
|
||||
# 4. Input Configuration (Enable Mics 1 and 2, power down Mics 3 and 4)
|
||||
self._write(0x47, 0x00) # Enable MIC1 / MIC2 analog front-ends
|
||||
self._write(0x48, 0xFF) # Power down MIC3 / MIC4 path
|
||||
self._write(0x49, 0x0A) # Power up PGA (Programmable Gain Amplifier) 1 and 2
|
||||
self._write(0x4A, 0x00) # Power down PGA 3 and 4
|
||||
|
||||
# 5. Microphone Gain Settings (+24dB standard)
|
||||
# Gain range: 0x00 (0dB) to 0x0F (+45dB) in 3dB steps. 0x08 = +24dB.
|
||||
self._write(0x43, 0x08) # Set MIC1 Gain (+24dB)
|
||||
self._write(0x44, 0x08) # Set MIC2 Gain (+24dB)
|
||||
|
||||
# 6. Set Digital Interface Format (I2S standard format)
|
||||
# Bit width: 0x00 = 24-bit, 0x01 = 16-bit, 0x02 = 8-bit, 0x03 = 32-bit
|
||||
fmt = 0x01 if bit_width == 16 else 0x00
|
||||
self._write(0x13, fmt) # Set serial output interface format
|
||||
self._write(0x14, 0x18) # Enable frame clock / bit clock output
|
||||
|
||||
# 7. Unmute ADCs and enable output
|
||||
self._write(0x12, 0x00) # Enable ADC digital filters (unmute)
|
||||
self._write(0x15, 0x30) # Enable output data pin (SDOUT) active
|
||||
|
||||
print("ES7210 initialization complete.")
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"Failed to initialize ES7210: {e}")
|
||||
return False
|
||||
|
||||
def _write(self, reg, val):
|
||||
self.i2c.writeto_mem(self.ADDR, reg, bytes([val]))
|
||||
|
||||
|
||||
def record_audio(duration_seconds=5, filename='recording.pcm'):
|
||||
"""Records raw stereo PCM data from the dual microphones to a file.
|
||||
|
||||
Args:
|
||||
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=13, SCL=14)
|
||||
i2c = I2C(0, sda=Pin(13), scl=Pin(14))
|
||||
|
||||
# 2. Configure I2S Receiver
|
||||
# Pins: sck=BCLK (GPIO 9), ws=WS/LRCK (GPIO 45), sd=DIN (GPIO 10)
|
||||
i2s = I2S(1,
|
||||
sck=Pin(9),
|
||||
ws=Pin(45),
|
||||
sd=Pin(10),
|
||||
mode=I2S.RX,
|
||||
ibuf=16000,
|
||||
rate=16000,
|
||||
bits=16,
|
||||
format=I2S.STEREO)
|
||||
|
||||
# 3. Wake up and configure the ES7210 microphone chip
|
||||
mic_adc = ES7210(i2c)
|
||||
if not mic_adc.init(sample_rate=16000, bit_width=16):
|
||||
i2s.deinit()
|
||||
return False
|
||||
|
||||
print(f"Recording {duration_seconds} seconds of audio...")
|
||||
|
||||
# Create reading buffer (reads 100ms chunks: 16000 samples/sec * 2 channels * 2 bytes/sample * 0.1s = 6400 bytes)
|
||||
buffer = bytearray(6400)
|
||||
|
||||
start_time = time.time()
|
||||
total_bytes = 0
|
||||
|
||||
try:
|
||||
with open(filename, 'wb') as f:
|
||||
while (time.time() - start_time) < duration_seconds:
|
||||
# Read raw stereo PCM data from I2S
|
||||
bytes_read = i2s.readinto(buffer)
|
||||
if bytes_read > 0:
|
||||
f.write(buffer[:bytes_read])
|
||||
total_bytes += bytes_read
|
||||
|
||||
print(f"Recording saved successfully to '{filename}' ({total_bytes} bytes).")
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"Error during recording: {e}")
|
||||
return False
|
||||
finally:
|
||||
# Always release the I2S peripheral resources
|
||||
i2s.deinit()
|
||||
print("I2S receiver deinitialized.")
|
||||
Reference in New Issue
Block a user