1
1
mirror of https://github.com/OpenVoiceOS/OpenVoiceOS synced 2024-12-15 02:16:36 +01:00
OpenVoiceOS/buildroot-external/rootfs-overlay/usr/bin/tas5806-init

197 lines
5.9 KiB
Python
Executable File

#!/usr/bin/env python
##########################################################################
# tas5806-init
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
##########################################################################
'''
install:
pip3 install smbus2
run:
python3 tas5806Test.py
'''
from smbus2 import SMBus
# Open i2c bus 1 and read one byte from address 80, offset 0
import os
import time
import subprocess
from math import log, exp
MAX_VOL = 84
class tasTest:
devAddr = 0x2f
bus = ""
commandReturn = ""
def __init__(self):
self.bus = SMBus(1)
def dumpData(self):
#for i in range(0x10):
# b = self.bus.read_byte_data(self.devAddr, i)
# print("%s: %s" % (hex(i), hex(b)) )
#print("------------------")
commandSend = 'i2cdump -y 1 ' +str( self.devAddr) +' W'
#os.system(commandSend)
self.commandReturn = os.popen(commandSend).read()
#print(self.commandReturn)
self.checkErrors()
'''
Check through error codes in i2cDump
'''
def checkErrors(self):
# register 0x37
fsMon = self.commandReturn.splitlines()[4][25:27]
fsMonBin = "{0:08b}".format(int(fsMon, 16))
fsMonStr = ["FS Error","","","","","","32KHz","","Reserved","48KHz","","96KHz"]
#print("FS_MON: %s (0x37)" % (fsMon))
print("FS_MON: %s (reg: 0x37)" % fsMonStr[int(fsMon)] )
# (reg: 0x70)
errorString = self.commandReturn.splitlines()[8][4:6]
errorStringBin = "{0:08b}".format(int(errorString, 16))
if(errorStringBin[-4] == "1" ):
print("Left channel DC fault" )
if(errorStringBin[-3] == "1" ):
print("Right channel DC fault" )
if(errorStringBin[-2] == "1" ):
print("Left channel over current fault" )
if(errorStringBin[-1] == "1" ):
print("Right channel over current fault" )
# (reg: 0x71)
errorString = self.commandReturn.splitlines()[8][7:9]
errorStringBin = "{0:08b}".format(int(errorString, 16))
if(errorStringBin[-3] == "1" ):
print("Clock fault (reg: 0x71)" )
# register 0x68
runStatus = self.commandReturn.splitlines()[7][29:31]
runStatusBin = "{0:08b}".format(int(runStatus, 16))
#print(runStatus)
runStatusStr = ["Deep sleep","Sleep","HIZ","Play"]
print("Run Status: %s (reg: 0x68)" % runStatusStr[int(runStatus)] )
def writeData(self, addr, val, comment = "" ):
self.bus.write_byte_data(self.devAddr, addr , val)
#print("write: %s: %s - %s" %(hex(addr),hex(val), comment ) )
time.sleep(0.1)
def close(self):
self.bus.close()
'''
Start Sequence for the TAS5806
'''
def startSequence(self):
self.writeData(0x01,0x11, "Reset Chip") #reset chip
self.writeData(0x78,0x80, "Clear Faults") #clear fault - works
self.dumpData()
self.writeData(0x01,0x00 , "Remove Reset") #remove reset
self.writeData(0x78,0x00 , "Remove Clear Fault") #remove clear fault
self.dumpData()
#self.writeData(51,3) # 0x33 h set bit rate
#self.writeData(118,64) # 0x76
##self.writeData(0x6A,3 , "")
##self.dumpData()
#self.writeData(0x33,0x00, "16-bit")
#self.writeData(0x33,0x01, "20-bit")
#self.writeData(0x33,0x02, "24-bit")
self.writeData(0x33,0x03, "32-bit")
self.dumpData()
self.setVolume(0x60)
self.writeData(0x30,0x01, "SDOUT is the DSP input (pre-processing)")
self.writeData(0x03,0x00, "Deep Sleep") #Deep Sleep
self.dumpData()
#self.writeData(0x03,0x01) #Sleep
#self.dumpData()
self.writeData(0x03,0x02, "HiZ") #HiZ
self.dumpData()
self.writeData(0x5C,0x01, "coefficient") #Indicate the first coefficient of a BQ is starting to write
self.dumpData()
self.writeData(0x03,0x03 , "Play") #Play
self.dumpData()
def calc_log_y(self, x):
""" given x produce y. takes in an int
0-100 returns a log oriented hardware
value with larger steps for low volumes
and smaller steps for loud volumes """
if x < 0:
x = 0
if x > 100:
x = 100
x0 = 0 # input range low
x1 = 100 # input range hi
y0 = MAX_VOL # max hw vol
y1 = 210 # min hw val
p1 = (x - x0) / (x1 - x0)
p2 = log(y0) - log(y1)
pval = p1 * p2 + log(y1)
return round(exp(pval))
def calc_log_x(self, y):
""" given y produce x. takes in an int
30-210 returns a value from 0-100 """
if y < 0:
y = MAX_VOL
if y > 210:
y = 210
x0 = 0 # input range low
x1 = 100 # input range hi
y0 = MAX_VOL # max hw vol
y1 = 210 # min hw val
x = x1 - x0
p1 = (log(y) - log(y0)) / (log(y1) - log(y0))
return x * p1 + x0
def setVolume(self, vol=1.0):
# vol takes a float from 0.0 - 1.0
# default vol 0.5 = 50%
hw_vol = self.calc_log_y(vol * 100.0)
setVolStr = "Set Volume %s" %( str (hw_vol) )
self.writeData(0x4c, hw_vol, setVolStr) #Set volume
if __name__ == '__main__':
tt = tasTest()
tt.startSequence()
tt.setVolume()
tt.close()