mirror of
https://github.com/OpenVoiceOS/OpenVoiceOS
synced 2025-03-02 18:48:04 +01:00
Get the sj201 in line / Sound system architecture changes
This commit is contained in:
parent
4bd41cf6a8
commit
812e92cbde
@ -612,7 +612,6 @@ BR2_PACKAGE_USERLAND_TOOLS=y
|
||||
BR2_PACKAGE_VOCALFUSION=y
|
||||
BR2_PACKAGE_WIFI_CONNECT=y
|
||||
BR2_PACKAGE_WIRINGPI2=y
|
||||
BR2_PACKAGE_XVF3510=y
|
||||
BR2_PACKAGE_PYTHON_ADAPT_PARSER=y
|
||||
BR2_PACKAGE_PYTHON_ASTRAL=y
|
||||
BR2_PACKAGE_PYTHON_CLICK_DEFAULT_GROUP=y
|
||||
@ -701,7 +700,6 @@ BR2_PACKAGE_MYCROFT_SKILL_IP=y
|
||||
BR2_PACKAGE_MYCROFT_SKILL_JOKE=y
|
||||
BR2_PACKAGE_MYCROFT_SKILL_NAPTIME=y
|
||||
BR2_PACKAGE_MYCROFT_SKILL_NEWS=y
|
||||
BR2_PACKAGE_MYCROFT_SKILL_OSM=y
|
||||
BR2_PACKAGE_MYCROFT_SKILL_OVOS_COMMON_PLAY=y
|
||||
BR2_PACKAGE_MYCROFT_SKILL_OVOS_ENCLOSURE=y
|
||||
BR2_PACKAGE_MYCROFT_SKILL_OVOS_HOMESCREEN=y
|
||||
|
Binary file not shown.
@ -12,6 +12,13 @@ $(eval $(kernel-module))
|
||||
|
||||
define VOCALFUSION_INSTALL_TARGET_CMDS
|
||||
$(INSTALL) -D -m 0644 $(@D)/xvf3510.dtbo $(BINARIES_DIR)/overlays/
|
||||
|
||||
$(INSTALL) -D -m 755 $(BR2_EXTERNAL_OPENVOICEOS_PATH)/package/vocalfusion/xvf3510-flash \
|
||||
$(TARGET_DIR)/usr/sbin/xvf3510-flash
|
||||
|
||||
mkdir -p $(TARGET_DIR)/usr/lib/firmware/xvf3510
|
||||
$(INSTALL) -D -m 0644 $(BR2_EXTERNAL_OPENVOICEOS_PATH)/package/vocalfusion/app_xvf3510_int_spi_boot_v4_1_0.bin \
|
||||
$(TARGET_DIR)/usr/lib/firmware/xvf3510/app_xvf3510_int_spi_boot_v4_1_0.bin
|
||||
endef
|
||||
|
||||
$(eval $(generic-package))
|
||||
|
209
buildroot-external/package/vocalfusion/xvf3510-flash
Normal file
209
buildroot-external/package/vocalfusion/xvf3510-flash
Normal file
@ -0,0 +1,209 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2019-2020, XMOS Ltd, All rights reserved
|
||||
# requires dtparam=spi=on in /boot/config.txt
|
||||
|
||||
"""
|
||||
This script configures the XVF3510 board in boot from SPI slave and load a
|
||||
binary file. It requires a bin file as input parameter.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
import argparse
|
||||
import spidev
|
||||
import RPi.GPIO as GPIO
|
||||
from smbus import SMBus
|
||||
from pathlib import Path
|
||||
|
||||
if sys.version[0] != '3':
|
||||
print("Run this script with Python 3")
|
||||
sys.exit(1)
|
||||
|
||||
def bit_reversed_byte(byte_to_reverse):
|
||||
"""
|
||||
Function to reverse the bit-order of a byte
|
||||
|
||||
Args:
|
||||
byte_to_reverse: byte to process
|
||||
|
||||
Retruns:
|
||||
byte in reversed order
|
||||
"""
|
||||
return int('{:08b}'.format(byte_to_reverse)[::-1], 2)
|
||||
|
||||
def set_boot_sel():
|
||||
"""
|
||||
Function to set XVF3510 board in SPI slave boot mode
|
||||
|
||||
Args:
|
||||
None
|
||||
|
||||
Returns:
|
||||
None
|
||||
"""
|
||||
|
||||
bus = SMBus(1)
|
||||
|
||||
# reset BOOT_SEL
|
||||
bus.write_byte_data(0x20, 3, 0xFE)
|
||||
bus.write_byte_data(0x20, 7, 0xFF)
|
||||
|
||||
state = {}
|
||||
for i in [2, 6]:
|
||||
state[i] = bus.read_byte_data(0x20, i)
|
||||
|
||||
# start reset
|
||||
data_to_write = 0x00 | (state[2] & 0xDF)
|
||||
bus.write_byte_data(0x20, 2, data_to_write)
|
||||
data_to_write = 0x00 | (state[6] & 0xDF)
|
||||
bus.write_byte_data(0x20, 6, data_to_write)
|
||||
# set BOOT_SEL high
|
||||
data_to_write = 0x01
|
||||
bus.write_byte_data(0x20, 3, data_to_write)
|
||||
data_to_write = 0xFE
|
||||
bus.write_byte_data(0x20, 7, data_to_write)
|
||||
# stop reset
|
||||
data_to_write = 0x20 | (state[2] & 0xDF)
|
||||
bus.write_byte_data(0x20, 2, data_to_write)
|
||||
data_to_write = 0x20 | (state[6] & 0xDF)
|
||||
bus.write_byte_data(0x20, 6, data_to_write)
|
||||
|
||||
|
||||
|
||||
def send_image(bin_filename, verbose=False, max_spi_speed_mhz = 5, block_transfer_pause_ms = 1, direct = False, delay = False):
|
||||
"""
|
||||
Function to send the given image to the device via SPI slave
|
||||
|
||||
Args:
|
||||
bin_filename: binary file containing the image to boot
|
||||
verbose: flag to print debug printouts
|
||||
direct: Use Pi GPIO outputs rather than the XVF3510 Pi HAT
|
||||
delay: Release BootSel early to delay startup on version 4.0.0 onwards
|
||||
|
||||
Returns:
|
||||
None
|
||||
"""
|
||||
|
||||
if direct:
|
||||
#setup GPIO
|
||||
GPIO.setmode(GPIO.BOARD)
|
||||
GPIO.setwarnings(False)
|
||||
|
||||
#boot_sel = 8
|
||||
#rst_n = 10
|
||||
'''
|
||||
Mycroft board update
|
||||
'''
|
||||
#GPIO.setmode(GPIO.BCM)
|
||||
|
||||
boot_sel = 37 #26 #= 25 # fix these numbers to be Wiring Pi
|
||||
rst_n = 13 #27 #= 2
|
||||
GPIO.setup(boot_sel, GPIO.IN) # Normally, the Pi should not drive this
|
||||
GPIO.setup(rst_n, GPIO.OUT, initial=GPIO.HIGH)
|
||||
|
||||
#setup SPI
|
||||
spi = spidev.SpiDev()
|
||||
bus_spi = 0
|
||||
device = 0
|
||||
spi.open(bus_spi, device)
|
||||
|
||||
#SPI Settings
|
||||
spi.max_speed_hz = int(max_spi_speed_mhz * 1000000)
|
||||
spi.mode = 0b00 #XMOS supports 00 or 11
|
||||
|
||||
spi_block_size = 4096 #Limitation in spidev and xfer2 doesn't work!
|
||||
|
||||
if direct:
|
||||
GPIO.output(rst_n, 0)
|
||||
GPIO.setup(boot_sel, GPIO.OUT, initial=GPIO.HIGH)
|
||||
GPIO.output(rst_n, 1)
|
||||
else:
|
||||
set_boot_sel()
|
||||
|
||||
# Create a table to map byte values to their bit-reversed values
|
||||
reverse_table = [bit_reversed_byte(byte) for byte in range(256)]
|
||||
|
||||
data = []
|
||||
with open(bin_filename, "rb") as f:
|
||||
bytes_read = f.read()
|
||||
data = list(bytes_read)
|
||||
binary_size = len(data)
|
||||
block_count = 0
|
||||
print('Read file "{0}" size: {1} Bytes'.format(args.bin_filename, binary_size))
|
||||
if binary_size % spi_block_size != 0:
|
||||
print("Warning - binary file not a multiple of {} - {} remainder".format( \
|
||||
spi_block_size, binary_size % spi_block_size))
|
||||
while binary_size > 0:
|
||||
block = [reverse_table[byte] for byte in data[:spi_block_size]]
|
||||
del data[:spi_block_size]
|
||||
binary_size = len(data)
|
||||
if verbose:
|
||||
print("Sending {} Bytes in block {} checksum 0x{:X}".format( \
|
||||
len(block), block_count, sum(block)))
|
||||
spi.xfer(block)
|
||||
|
||||
if block_count == 0:
|
||||
#Long delay for PLL reboot
|
||||
time.sleep(0.1)
|
||||
|
||||
if delay:
|
||||
# release boot_sel early to prevent startup
|
||||
if direct:
|
||||
GPIO.setup(boot_sel, GPIO.IN)
|
||||
else:
|
||||
#bus = smbus.SMBus(1)
|
||||
bus = SMBus(1)
|
||||
data_to_write = 0xFE
|
||||
bus.write_byte_data(0x20, 3, data_to_write)
|
||||
data_to_write = 0xFF
|
||||
bus.write_byte_data(0x20, 7, data_to_write)
|
||||
|
||||
elif binary_size > 0:
|
||||
time.sleep(block_transfer_pause_ms / 1000)
|
||||
block_count += 1
|
||||
print("Sending complete")
|
||||
|
||||
if direct:
|
||||
GPIO.setup(boot_sel, GPIO.IN) # Once booted, the Pi should not need to drive boot_sel
|
||||
GPIO.setup(rst_n, GPIO.OUT, initial=GPIO.HIGH) # Once booted, the Pi should not need to drive reset
|
||||
#GPIO.cleanup()
|
||||
else:
|
||||
#bus = smbus.SMBus(1)
|
||||
bus = SMBus(1)
|
||||
|
||||
# reset BOOT_SEL
|
||||
data_to_write = 0xFE
|
||||
bus.write_byte_data(0x20, 3, data_to_write)
|
||||
data_to_write = 0xFF
|
||||
bus.write_byte_data(0x20, 7, data_to_write)
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
start_time = time.time()
|
||||
parser = argparse.ArgumentParser(description='Load an image via SPI slave from an RPi')
|
||||
parser.add_argument('bin_filename', help='binary file name')
|
||||
parser.add_argument('--direct', action='store_true', \
|
||||
help='Use just direct GPIO outputs rather than using the XVF3510 Development Kit Pi HAT')
|
||||
parser.add_argument('--delay', action='store_true', \
|
||||
help='Delay xvf3510 device start. Release the BootSel pin early to prevent the XVF3510 (V4.0.0 onwards) from starting with the default I2S configuration. This gives AP a chance to configure and start the XVF3510 device.')
|
||||
parser.add_argument('--max-spi-speed-mhz', type=float, default=5, \
|
||||
help='Max SPI speed in MHz')
|
||||
parser.add_argument('--block-transfer-pause-ms', type=float, default=1, \
|
||||
help='pause between SPI transfers in milliseconds, default 1ms')
|
||||
parser.add_argument('--verbose', action='store_true', \
|
||||
help='print debug information')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if not Path(args.bin_filename).is_file():
|
||||
print("Error: input file {} not found".format(args.bin_filename))
|
||||
exit(1)
|
||||
|
||||
send_image(args.bin_filename, args.verbose, args.max_spi_speed_mhz, args.block_transfer_pause_ms, args.direct, args.delay)
|
||||
|
||||
end_time = time.time()
|
||||
if args.verbose:
|
||||
print("Sending image took {:.3} seconds".format(end_time - start_time))
|
@ -1,14 +0,0 @@
|
||||
# Use PulseAudio by default
|
||||
pcm.!default {
|
||||
type pulse
|
||||
fallback "sysdefault"
|
||||
hint {
|
||||
show on
|
||||
description "Default ALSA Output (currently PulseAudio Sound Server)"
|
||||
}
|
||||
}
|
||||
|
||||
ctl.!default {
|
||||
type pulse
|
||||
fallback "sysdefault"
|
||||
}
|
@ -92,8 +92,4 @@
|
||||
resample-method = ffmpeg
|
||||
default-sample-format = s32le
|
||||
default-sample-rate = 48000
|
||||
alternate-sample-rate = 44100
|
||||
default-sample-channels = 2
|
||||
default-channel-map = front-left,front-right
|
||||
avoid-resampling = true
|
||||
flat-volumes = no
|
||||
|
@ -1,77 +0,0 @@
|
||||
#!/usr/bin/pulseaudio -nF
|
||||
#
|
||||
# This file is part of PulseAudio.
|
||||
#
|
||||
# PulseAudio is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# PulseAudio is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# This startup script is used only if PulseAudio is started in system
|
||||
# mode.
|
||||
|
||||
### Automatically restore the volume of streams and devices
|
||||
load-module module-device-restore
|
||||
load-module module-stream-restore
|
||||
load-module module-card-restore
|
||||
|
||||
### Automatically load driver modules depending on the hardware available
|
||||
.ifexists module-udev-detect.so
|
||||
load-module module-udev-detect tsched=0
|
||||
.else
|
||||
### Use the static hardware detection module (for systems that lack udev/hal support)
|
||||
load-module module-detect
|
||||
.endif
|
||||
|
||||
### Load several protocols
|
||||
.ifexists module-esound-protocol-unix.so
|
||||
load-module module-esound-protocol-unix
|
||||
.endif
|
||||
load-module module-native-protocol-unix auth-anonymous=1
|
||||
|
||||
### Network access (may be configured with paprefs, so leave this commented
|
||||
### here if you plan to use paprefs)
|
||||
#load-module module-esound-protocol-tcp
|
||||
load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1;192.168.0.0/16;172.16.0.0/12;10.0.0.0/8 auth-anonymous=1
|
||||
load-module module-zeroconf-publish
|
||||
|
||||
### Automatically restore the default sink/source when changed by the user
|
||||
### during runtime
|
||||
### NOTE: This should be loaded as early as possible so that subsequent modules
|
||||
### that look up the default sink/source get the right value
|
||||
load-module module-default-device-restore
|
||||
|
||||
### Automatically move streams to the default sink if the sink they are
|
||||
### connected to dies, similar for sources
|
||||
load-module module-rescue-streams
|
||||
|
||||
### Make sure we always have a sink around, even if it is a null sink.
|
||||
load-module module-always-sink
|
||||
|
||||
### Automatically suspend sinks/sources that become idle for too long
|
||||
load-module module-suspend-on-idle
|
||||
|
||||
### Enable positioned event sounds
|
||||
load-module module-position-event-sounds
|
||||
|
||||
### OpenVoiceOS Audio Settings
|
||||
unload-module module-suspend-on-idle
|
||||
load-module module-role-ducking
|
||||
load-module module-combine-sink sink_name=OpenVoiceOS
|
||||
load-module module-remap-source source_name=VF_ASR_L source_properties="device.description='VocalFusion ASR recording'" master=alsa_input.platform-asoc-simple-card.0.stereo-fallback remix=no master_channel_map=front-left channel_map=mono
|
||||
load-module module-remap-source source_name=VF_Comms_R source_properties="device.description='VocalFusion Comms recording'" master=alsa_input.platform-asoc-simple-card.0.stereo-fallback remix=no master_channel_map=front-right channel_map=mono
|
||||
set-default-source VF_ASR_L
|
||||
set-default-sink OpenVoiceOS
|
||||
|
||||
### Enable Echo/Noise-Cancellation
|
||||
#load-module module-echo-cancel aec_method=webrtc source_name=echoCancel_source sink_name=echoCancel_sink
|
||||
#set-default-source echoCancel_source
|
||||
#set-default-sink echoCancel_sink
|
@ -93,5 +93,4 @@ resample-method = ffmpeg
|
||||
default-sample-format = s16le
|
||||
default-sample-rate = 44100
|
||||
alternate-sample-rate = 48000
|
||||
; avoid-resampling = true
|
||||
flat-volumes = no
|
||||
|
@ -181,7 +181,7 @@ class tasTest:
|
||||
|
||||
return x * p1 + x0
|
||||
|
||||
def setVolume(self, vol=1.0):
|
||||
def setVolume(self, vol=0.5):
|
||||
# vol takes a float from 0.0 - 1.0
|
||||
# default vol 0.5 = 50%
|
||||
hw_vol = self.calc_log_y(vol * 100.0)
|
||||
|
@ -16,13 +16,9 @@
|
||||
##########################################################################
|
||||
|
||||
# Set default configurations
|
||||
ASOUND_STATE=/var/lib/alsa/default-asound.state
|
||||
PULSE_SYSTEM=/etc/pulse/pulseaudio-system.pa
|
||||
PULSE_DAEMON=/etc/pulse/pulseaudio-daemon.conf
|
||||
|
||||
# Set known hat overlay variables
|
||||
RPI_HATS="seeed-2mic-voicecard seeed-4mic-voicecard seeed-8mic-voicecard"
|
||||
|
||||
# Scanning the I2C bus for know addresses
|
||||
is_1a=$(i2cdetect -y 1 0x1a 0x1a | egrep "(1a|UU)" | awk '{print $2}') # ReSpeaker 2-mic / WM8960
|
||||
if [ "${is_1a}" == "1a" ] || [ "${is_1a}" == "UU" ] ; then
|
||||
@ -62,12 +58,6 @@ fi
|
||||
|
||||
|
||||
# Remove old configurations
|
||||
if [ -f /var/lib/alsa/asound.state ] ; then
|
||||
rm /var/lib/alsa/asound.state
|
||||
fi
|
||||
if [ -f /etc/ovos_asound.state ] ; then
|
||||
rm /etc/ovos_asound.state
|
||||
fi
|
||||
if [ -f /etc/pulse/system.pa ] ; then
|
||||
rm /etc/pulse/system.pa
|
||||
fi
|
||||
@ -77,27 +67,19 @@ fi
|
||||
|
||||
if [ "$RESPEAKER2" == "found" ] && [ "$RESPEAKER4" != "found" ] ; then
|
||||
echo "Installing and configuring ReSpeaker 2-mic"
|
||||
modprobe snd-soc-wm8960
|
||||
OVERLAY=seeed-2mic-voicecard
|
||||
ASOUND_STATE=/etc/voicecard/wm8960_asound.state
|
||||
dtoverlay seeed-2mic-voicecard
|
||||
fi
|
||||
|
||||
if [ "${RESPEAKER6}" == "found" ] && [ "${RESPEAKER4}" != "found" ] ; then
|
||||
echo "Installing and configuring ReSpeaker 4-mic"
|
||||
modprobe snd-soc-seeed-voicecard
|
||||
modprobe snd-soc-ac108
|
||||
OVERLAY=seeed-4mic-voicecard
|
||||
ASOUND_STATE=/etc/voicecard/ac108_asound.state
|
||||
dtoverlay seeed-4mic-voicecard
|
||||
PULSE_SYSTEM=/etc/pulse/seeed-voicecard-4mic-default.pa
|
||||
PULSE_DAEMON=/etc/pulse/seeed-voicecard-4mic-daemon.conf
|
||||
fi
|
||||
|
||||
if [ "{$RESPEAKER6}" == "found" ] && [ "${RESPEAKER4}" == "found" ] ; then
|
||||
echo "Installing and configuring ReSpeaker 6mic"
|
||||
modprobe snd-soc-seeed-voicecard
|
||||
modprobe snd-soc-ac108
|
||||
OVERLAY=seeed-8mic-voicecard
|
||||
ASOUND_STATE=/etc/voicecard/ac108_6mic.state
|
||||
dtoverlay seeed-8mic-voicecard
|
||||
PULSE_SYSTEM=/etc/pulse/seeed-voicecard-8mic-default.pa
|
||||
PULSE_DAEMON=/etc/pulse/seeed-voicecard-8mic-daemon.conf
|
||||
fi
|
||||
@ -110,7 +92,8 @@ fi
|
||||
if [ "$TAS5806" ] && [ "$SJ201LED" ]; then
|
||||
echo "Installing and configuring SJ201"
|
||||
# Initializing XMOS xvf3510
|
||||
/usr/sbin/xvf3510-start
|
||||
dtoverlay xvf3510
|
||||
xvf3510-flash --direct "/usr/lib/firmware/xvf3510/app_xvf3510_int_spi_boot_v4_1_0.bin"
|
||||
# Initializing Texas Instruments 5806 Amplifier
|
||||
/usr/bin/tas5806-init
|
||||
# Initializing and resetting LED ring
|
||||
@ -118,27 +101,11 @@ if [ "$TAS5806" ] && [ "$SJ201LED" ]; then
|
||||
# Reset FAN to low speed
|
||||
/usr/sbin/i2cset -a -y 1 0x04 101 30 i
|
||||
|
||||
#PULSE_SYSTEM=/etc/pulse/mycroft-sj201-default.pa
|
||||
#PULSE_DAEMON=/etc/pulse/mycroft-sj201-daemon.conf
|
||||
PULSE_DAEMON=/etc/pulse/mycroft-sj201-daemon.conf
|
||||
fi
|
||||
|
||||
# Load overlay
|
||||
if [ "$OVERLAY" ]; then
|
||||
echo Loading $OVERLAY ...
|
||||
|
||||
# Make sure the driver loads correctly
|
||||
dtoverlay $OVERLAY || true
|
||||
fi
|
||||
|
||||
# Install soundstate
|
||||
echo "create asound status file"
|
||||
ln -s $ASOUND_STATE /etc/ovos_asound.state
|
||||
|
||||
# Install pulseaudio files
|
||||
echo "create pulse system file"
|
||||
ln -s $PULSE_SYSTEM /etc/pulse/system.pa
|
||||
echo "create pulse daemon file"
|
||||
ln -s $PULSE_DAEMON /etc/pulse/daemon.conf
|
||||
|
||||
# Restore sound levels
|
||||
alsactl -E HOME=/run/alsa -f /etc/ovos_asound.state restore
|
||||
|
Loading…
x
Reference in New Issue
Block a user