You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

control_sgtl5000.cpp 37KB

10 vuotta sitten
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074
  1. /* Audio Library for Teensy 3.X
  2. * Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com
  3. *
  4. * Development of this audio library was funded by PJRC.COM, LLC by sales of
  5. * Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
  6. * open source software by purchasing Teensy or other PJRC products.
  7. *
  8. * Permission is hereby granted, free of charge, to any person obtaining a copy
  9. * of this software and associated documentation files (the "Software"), to deal
  10. * in the Software without restriction, including without limitation the rights
  11. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12. * copies of the Software, and to permit persons to whom the Software is
  13. * furnished to do so, subject to the following conditions:
  14. *
  15. * The above copyright notice, development funding notice, and this permission
  16. * notice shall be included in all copies or substantial portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24. * THE SOFTWARE.
  25. */
  26. #include <Arduino.h>
  27. #include "control_sgtl5000.h"
  28. #include "Wire.h"
  29. #define CHIP_ID 0x0000
  30. // 15:8 PARTID 0xA0 - 8 bit identifier for SGTL5000
  31. // 7:0 REVID 0x00 - revision number for SGTL5000.
  32. #define CHIP_DIG_POWER 0x0002
  33. // 6 ADC_POWERUP 1=Enable, 0=disable the ADC block, both digital & analog,
  34. // 5 DAC_POWERUP 1=Enable, 0=disable the DAC block, both analog and digital
  35. // 4 DAP_POWERUP 1=Enable, 0=disable the DAP block
  36. // 1 I2S_OUT_POWERUP 1=Enable, 0=disable the I2S data output
  37. // 0 I2S_IN_POWERUP 1=Enable, 0=disable the I2S data input
  38. #define CHIP_CLK_CTRL 0x0004
  39. // 5:4 RATE_MODE Sets the sample rate mode. MCLK_FREQ is still specified
  40. // relative to the rate in SYS_FS
  41. // 0x0 = SYS_FS specifies the rate
  42. // 0x1 = Rate is 1/2 of the SYS_FS rate
  43. // 0x2 = Rate is 1/4 of the SYS_FS rate
  44. // 0x3 = Rate is 1/6 of the SYS_FS rate
  45. // 3:2 SYS_FS Sets the internal system sample rate (default=2)
  46. // 0x0 = 32 kHz
  47. // 0x1 = 44.1 kHz
  48. // 0x2 = 48 kHz
  49. // 0x3 = 96 kHz
  50. // 1:0 MCLK_FREQ Identifies incoming SYS_MCLK frequency and if the PLL should be used
  51. // 0x0 = 256*Fs
  52. // 0x1 = 384*Fs
  53. // 0x2 = 512*Fs
  54. // 0x3 = Use PLL
  55. // The 0x3 (Use PLL) setting must be used if the SYS_MCLK is not
  56. // a standard multiple of Fs (256, 384, or 512). This setting can
  57. // also be used if SYS_MCLK is a standard multiple of Fs.
  58. // Before this field is set to 0x3 (Use PLL), the PLL must be
  59. // powered up by setting CHIP_ANA_POWER->PLL_POWERUP and
  60. // CHIP_ANA_POWER->VCOAMP_POWERUP. Also, the PLL dividers must
  61. // be calculated based on the external MCLK rate and
  62. // CHIP_PLL_CTRL register must be set (see CHIP_PLL_CTRL register
  63. // description details on how to calculate the divisors).
  64. #define CHIP_I2S_CTRL 0x0006
  65. // 8 SCLKFREQ Sets frequency of I2S_SCLK when in master mode (MS=1). When in slave
  66. // mode (MS=0), this field must be set appropriately to match SCLK input
  67. // rate.
  68. // 0x0 = 64Fs
  69. // 0x1 = 32Fs - Not supported for RJ mode (I2S_MODE = 1)
  70. // 7 MS Configures master or slave of I2S_LRCLK and I2S_SCLK.
  71. // 0x0 = Slave: I2S_LRCLK an I2S_SCLK are inputs
  72. // 0x1 = Master: I2S_LRCLK and I2S_SCLK are outputs
  73. // NOTE: If the PLL is used (CHIP_CLK_CTRL->MCLK_FREQ==0x3),
  74. // the SGTL5000 must be a master of the I2S port (MS==1)
  75. // 6 SCLK_INV Sets the edge that data (input and output) is clocked in on for I2S_SCLK
  76. // 0x0 = data is valid on rising edge of I2S_SCLK
  77. // 0x1 = data is valid on falling edge of I2S_SCLK
  78. // 5:4 DLEN I2S data length (default=1)
  79. // 0x0 = 32 bits (only valid when SCLKFREQ=0),
  80. // not valid for Right Justified Mode
  81. // 0x1 = 24 bits (only valid when SCLKFREQ=0)
  82. // 0x2 = 20 bits
  83. // 0x3 = 16 bits
  84. // 3:2 I2S_MODE Sets the mode for the I2S port
  85. // 0x0 = I2S mode or Left Justified (Use LRALIGN to select)
  86. // 0x1 = Right Justified Mode
  87. // 0x2 = PCM Format A/B
  88. // 0x3 = RESERVED
  89. // 1 LRALIGN I2S_LRCLK Alignment to data word. Not used for Right Justified mode
  90. // 0x0 = Data word starts 1 I2S_SCLK delay after I2S_LRCLK
  91. // transition (I2S format, PCM format A)
  92. // 0x1 = Data word starts after I2S_LRCLK transition (left
  93. // justified format, PCM format B)
  94. // 0 LRPOL I2S_LRCLK Polarity when data is presented.
  95. // 0x0 = I2S_LRCLK = 0 - Left, 1 - Right
  96. // 1x0 = I2S_LRCLK = 0 - Right, 1 - Left
  97. // The left subframe should be presented first regardless of
  98. // the setting of LRPOL.
  99. #define CHIP_SSS_CTRL 0x000A
  100. // 14 DAP_MIX_LRSWAP DAP Mixer Input Swap
  101. // 0x0 = Normal Operation
  102. // 0x1 = Left and Right channels for the DAP MIXER Input are swapped.
  103. // 13 DAP_LRSWAP DAP Mixer Input Swap
  104. // 0x0 = Normal Operation
  105. // 0x1 = Left and Right channels for the DAP Input are swapped
  106. // 12 DAC_LRSWAP DAC Input Swap
  107. // 0x0 = Normal Operation
  108. // 0x1 = Left and Right channels for the DAC are swapped
  109. // 10 I2S_LRSWAP I2S_DOUT Swap
  110. // 0x0 = Normal Operation
  111. // 0x1 = Left and Right channels for the I2S_DOUT are swapped
  112. // 9:8 DAP_MIX_SELECT Select data source for DAP mixer
  113. // 0x0 = ADC
  114. // 0x1 = I2S_IN
  115. // 0x2 = Reserved
  116. // 0x3 = Reserved
  117. // 7:6 DAP_SELECT Select data source for DAP
  118. // 0x0 = ADC
  119. // 0x1 = I2S_IN
  120. // 0x2 = Reserved
  121. // 0x3 = Reserved
  122. // 5:4 DAC_SELECT Select data source for DAC (default=1)
  123. // 0x0 = ADC
  124. // 0x1 = I2S_IN
  125. // 0x2 = Reserved
  126. // 0x3 = DAP
  127. // 1:0 I2S_SELECT Select data source for I2S_DOUT
  128. // 0x0 = ADC
  129. // 0x1 = I2S_IN
  130. // 0x2 = Reserved
  131. // 0x3 = DAP
  132. #define CHIP_ADCDAC_CTRL 0x000E
  133. // 13 VOL_BUSY_DAC_RIGHT Volume Busy DAC Right
  134. // 0x0 = Ready
  135. // 0x1 = Busy - This indicates the channel has not reached its
  136. // programmed volume/mute level
  137. // 12 VOL_BUSY_DAC_LEFT Volume Busy DAC Left
  138. // 0x0 = Ready
  139. // 0x1 = Busy - This indicates the channel has not reached its
  140. // programmed volume/mute level
  141. // 9 VOL_RAMP_EN Volume Ramp Enable (default=1)
  142. // 0x0 = Disables volume ramp. New volume settings take immediate
  143. // effect without a ramp
  144. // 0x1 = Enables volume ramp
  145. // This field affects DAC_VOL. The volume ramp effects both
  146. // volume settings and mute When set to 1 a soft mute is enabled.
  147. // 8 VOL_EXPO_RAMP Exponential Volume Ramp Enable
  148. // 0x0 = Linear ramp over top 4 volume octaves
  149. // 0x1 = Exponential ramp over full volume range
  150. // This bit only takes effect if VOL_RAMP_EN is 1.
  151. // 3 DAC_MUTE_RIGHT DAC Right Mute (default=1)
  152. // 0x0 = Unmute
  153. // 0x1 = Muted
  154. // If VOL_RAMP_EN = 1, this is a soft mute.
  155. // 2 DAC_MUTE_LEFT DAC Left Mute (default=1)
  156. // 0x0 = Unmute
  157. // 0x1 = Muted
  158. // If VOL_RAMP_EN = 1, this is a soft mute.
  159. // 1 ADC_HPF_FREEZE ADC High Pass Filter Freeze
  160. // 0x0 = Normal operation
  161. // 0x1 = Freeze the ADC high-pass filter offset register. The
  162. // offset continues to be subtracted from the ADC data stream.
  163. // 0 ADC_HPF_BYPASS ADC High Pass Filter Bypass
  164. // 0x0 = Normal operation
  165. // 0x1 = Bypassed and offset not updated
  166. #define CHIP_DAC_VOL 0x0010
  167. // 15:8 DAC_VOL_RIGHT DAC Right Channel Volume. Set the Right channel DAC volume
  168. // with 0.5017 dB steps from 0 to -90 dB
  169. // 0x3B and less = Reserved
  170. // 0x3C = 0 dB
  171. // 0x3D = -0.5 dB
  172. // 0xF0 = -90 dB
  173. // 0xFC and greater = Muted
  174. // If VOL_RAMP_EN = 1, there is an automatic ramp to the
  175. // new volume setting.
  176. // 7:0 DAC_VOL_LEFT DAC Left Channel Volume. Set the Left channel DAC volume
  177. // with 0.5017 dB steps from 0 to -90 dB
  178. // 0x3B and less = Reserved
  179. // 0x3C = 0 dB
  180. // 0x3D = -0.5 dB
  181. // 0xF0 = -90 dB
  182. // 0xFC and greater = Muted
  183. // If VOL_RAMP_EN = 1, there is an automatic ramp to the
  184. // new volume setting.
  185. #define CHIP_PAD_STRENGTH 0x0014
  186. // 9:8 I2S_LRCLK I2S LRCLK Pad Drive Strength (default=1)
  187. // Sets drive strength for output pads per the table below.
  188. // VDDIO 1.8 V 2.5 V 3.3 V
  189. // 0x0 = Disable
  190. // 0x1 = 1.66 mA 2.87 mA 4.02 mA
  191. // 0x2 = 3.33 mA 5.74 mA 8.03 mA
  192. // 0x3 = 4.99 mA 8.61 mA 12.05 mA
  193. // 7:6 I2S_SCLK I2S SCLK Pad Drive Strength (default=1)
  194. // 5:4 I2S_DOUT I2S DOUT Pad Drive Strength (default=1)
  195. // 3:2 CTRL_DATA I2C DATA Pad Drive Strength (default=3)
  196. // 1:0 CTRL_CLK I2C CLK Pad Drive Strength (default=3)
  197. // (all use same table as I2S_LRCLK)
  198. #define CHIP_ANA_ADC_CTRL 0x0020
  199. // 8 ADC_VOL_M6DB ADC Volume Range Reduction
  200. // This bit shifts both right and left analog ADC volume
  201. // range down by 6.0 dB.
  202. // 0x0 = No change in ADC range
  203. // 0x1 = ADC range reduced by 6.0 dB
  204. // 7:4 ADC_VOL_RIGHT ADC Right Channel Volume
  205. // Right channel analog ADC volume control in 1.5 dB steps.
  206. // 0x0 = 0 dB
  207. // 0x1 = +1.5 dB
  208. // ...
  209. // 0xF = +22.5 dB
  210. // This range is -6.0 dB to +16.5 dB if ADC_VOL_M6DB is set to 1.
  211. // 3:0 ADC_VOL_LEFT ADC Left Channel Volume
  212. // (same scale as ADC_VOL_RIGHT)
  213. #define CHIP_ANA_HP_CTRL 0x0022
  214. // 14:8 HP_VOL_RIGHT Headphone Right Channel Volume (default 0x18)
  215. // Right channel headphone volume control with 0.5 dB steps.
  216. // 0x00 = +12 dB
  217. // 0x01 = +11.5 dB
  218. // 0x18 = 0 dB
  219. // ...
  220. // 0x7F = -51.5 dB
  221. // 6:0 HP_VOL_LEFT Headphone Left Channel Volume (default 0x18)
  222. // (same scale as HP_VOL_RIGHT)
  223. #define CHIP_ANA_CTRL 0x0024
  224. // 8 MUTE_LO LINEOUT Mute, 0 = Unmute, 1 = Mute (default 1)
  225. // 6 SELECT_HP Select the headphone input, 0 = DAC, 1 = LINEIN
  226. // 5 EN_ZCD_HP Enable the headphone zero cross detector (ZCD)
  227. // 0x0 = HP ZCD disabled
  228. // 0x1 = HP ZCD enabled
  229. // 4 MUTE_HP Mute the headphone outputs, 0 = Unmute, 1 = Mute (default)
  230. // 2 SELECT_ADC Select the ADC input, 0 = Microphone, 1 = LINEIN
  231. // 1 EN_ZCD_ADC Enable the ADC analog zero cross detector (ZCD)
  232. // 0x0 = ADC ZCD disabled
  233. // 0x1 = ADC ZCD enabled
  234. // 0 MUTE_ADC Mute the ADC analog volume, 0 = Unmute, 1 = Mute (default)
  235. #define CHIP_LINREG_CTRL 0x0026
  236. // 6 VDDC_MAN_ASSN Determines chargepump source when VDDC_ASSN_OVRD is set.
  237. // 0x0 = VDDA
  238. // 0x1 = VDDIO
  239. // 5 VDDC_ASSN_OVRD Charge pump Source Assignment Override
  240. // 0x0 = Charge pump source is automatically assigned based
  241. // on higher of VDDA and VDDIO
  242. // 0x1 = the source of charge pump is manually assigned by
  243. // VDDC_MAN_ASSN If VDDIO and VDDA are both the same
  244. // and greater than 3.1 V, VDDC_ASSN_OVRD and
  245. // VDDC_MAN_ASSN should be used to manually assign
  246. // VDDIO as the source for charge pump.
  247. // 3:0 D_PROGRAMMING Sets the VDDD linear regulator output voltage in 50 mV steps.
  248. // Must clear the LINREG_SIMPLE_POWERUP and STARTUP_POWERUP bits
  249. // in the 0x0030 (CHIP_ANA_POWER) register after power-up, for
  250. // this setting to produce the proper VDDD voltage.
  251. // 0x0 = 1.60
  252. // 0xF = 0.85
  253. #define CHIP_REF_CTRL 0x0028 // bandgap reference bias voltage and currents
  254. // 8:4 VAG_VAL Analog Ground Voltage Control
  255. // These bits control the analog ground voltage in 25 mV steps.
  256. // This should usually be set to VDDA/2 or lower for best
  257. // performance (maximum output swing at minimum THD). This VAG
  258. // reference is also used for the DAC and ADC voltage reference.
  259. // So changing this voltage scales the output swing of the DAC
  260. // and the output signal of the ADC.
  261. // 0x00 = 0.800 V
  262. // 0x1F = 1.575 V
  263. // 3:1 BIAS_CTRL Bias control
  264. // These bits adjust the bias currents for all of the analog
  265. // blocks. By lowering the bias current a lower quiescent power
  266. // is achieved. It should be noted that this mode can affect
  267. // performance by 3-4 dB.
  268. // 0x0 = Nominal
  269. // 0x1-0x3=+12.5%
  270. // 0x4=-12.5%
  271. // 0x5=-25%
  272. // 0x6=-37.5%
  273. // 0x7=-50%
  274. // 0 SMALL_POP VAG Ramp Control
  275. // Setting this bit slows down the VAG ramp from ~200 to ~400 ms
  276. // to reduce the startup pop, but increases the turn on/off time.
  277. // 0x0 = Normal VAG ramp
  278. // 0x1 = Slow down VAG ramp
  279. #define CHIP_MIC_CTRL 0x002A // microphone gain & internal microphone bias
  280. // 9:8 BIAS_RESISTOR MIC Bias Output Impedance Adjustment
  281. // Controls an adjustable output impedance for the microphone bias.
  282. // If this is set to zero the micbias block is powered off and
  283. // the output is highZ.
  284. // 0x0 = Powered off
  285. // 0x1 = 2.0 kohm
  286. // 0x2 = 4.0 kohm
  287. // 0x3 = 8.0 kohm
  288. // 6:4 BIAS_VOLT MIC Bias Voltage Adjustment
  289. // Controls an adjustable bias voltage for the microphone bias
  290. // amp in 250 mV steps. This bias voltage setting should be no
  291. // more than VDDA-200 mV for adequate power supply rejection.
  292. // 0x0 = 1.25 V
  293. // ...
  294. // 0x7 = 3.00 V
  295. // 1:0 GAIN MIC Amplifier Gain
  296. // Sets the microphone amplifier gain. At 0 dB setting the THD
  297. // can be slightly higher than other paths- typically around
  298. // ~65 dB. At other gain settings the THD are better.
  299. // 0x0 = 0 dB
  300. // 0x1 = +20 dB
  301. // 0x2 = +30 dB
  302. // 0x3 = +40 dB
  303. #define CHIP_LINE_OUT_CTRL 0x002C
  304. // 11:8 OUT_CURRENT Controls the output bias current for the LINEOUT amplifiers. The
  305. // nominal recommended setting for a 10 kohm load with 1.0 nF load cap
  306. // is 0x3. There are only 5 valid settings.
  307. // 0x0=0.18 mA
  308. // 0x1=0.27 mA
  309. // 0x3=0.36 mA
  310. // 0x7=0.45 mA
  311. // 0xF=0.54 mA
  312. // 5:0 LO_VAGCNTRL LINEOUT Amplifier Analog Ground Voltage
  313. // Controls the analog ground voltage for the LINEOUT amplifiers
  314. // in 25 mV steps. This should usually be set to VDDIO/2.
  315. // 0x00 = 0.800 V
  316. // ...
  317. // 0x1F = 1.575 V
  318. // ...
  319. // 0x23 = 1.675 V
  320. // 0x24-0x3F are invalid
  321. #define CHIP_LINE_OUT_VOL 0x002E
  322. // 12:8 LO_VOL_RIGHT LINEOUT Right Channel Volume (default=4)
  323. // Controls the right channel LINEOUT volume in 0.5 dB steps.
  324. // Higher codes have more attenuation.
  325. // 4:0 LO_VOL_LEFT LINEOUT Left Channel Output Level (default=4)
  326. // Used to normalize the output level of the left line output
  327. // to full scale based on the values used to set
  328. // LINE_OUT_CTRL->LO_VAGCNTRL and CHIP_REF_CTRL->VAG_VAL.
  329. // In general this field should be set to:
  330. // 40*log((VAG_VAL)/(LO_VAGCNTRL)) + 15
  331. // Suggested values based on typical VDDIO and VDDA voltages.
  332. // VDDA VAG_VAL VDDIO LO_VAGCNTRL LO_VOL_*
  333. // 1.8 V 0.9 3.3 V 1.55 0x06
  334. // 1.8 V 0.9 1.8 V 0.9 0x0F
  335. // 3.3 V 1.55 1.8 V 0.9 0x19
  336. // 3.3 V 1.55 3.3 V 1.55 0x0F
  337. // After setting to the nominal voltage, this field can be used
  338. // to adjust the output level in +/-0.5 dB increments by using
  339. // values higher or lower than the nominal setting.
  340. #define CHIP_ANA_POWER 0x0030 // power down controls for the analog blocks.
  341. // The only other power-down controls are BIAS_RESISTOR in the MIC_CTRL register
  342. // and the EN_ZCD control bits in ANA_CTRL.
  343. // 14 DAC_MONO While DAC_POWERUP is set, this allows the DAC to be put into left only
  344. // mono operation for power savings. 0=mono, 1=stereo (default)
  345. // 13 LINREG_SIMPLE_POWERUP Power up the simple (low power) digital supply regulator.
  346. // After reset, this bit can be cleared IF VDDD is driven
  347. // externally OR the primary digital linreg is enabled with
  348. // LINREG_D_POWERUP
  349. // 12 STARTUP_POWERUP Power up the circuitry needed during the power up ramp and reset.
  350. // After reset this bit can be cleared if VDDD is coming from
  351. // an external source.
  352. // 11 VDDC_CHRGPMP_POWERUP Power up the VDDC charge pump block. If neither VDDA or VDDIO
  353. // is 3.0 V or larger this bit should be cleared before analog
  354. // blocks are powered up.
  355. // 10 PLL_POWERUP PLL Power Up, 0 = Power down, 1 = Power up
  356. // When cleared, the PLL is turned off. This must be set before
  357. // CHIP_CLK_CTRL->MCLK_FREQ is programmed to 0x3. The
  358. // CHIP_PLL_CTRL register must be configured correctly before
  359. // setting this bit.
  360. // 9 LINREG_D_POWERUP Power up the primary VDDD linear regulator, 0 = Power down, 1 = Power up
  361. // 8 VCOAMP_POWERUP Power up the PLL VCO amplifier, 0 = Power down, 1 = Power up
  362. // 7 VAG_POWERUP Power up the VAG reference buffer.
  363. // Setting this bit starts the power up ramp for the headphone
  364. // and LINEOUT. The headphone (and/or LINEOUT) powerup should
  365. // be set BEFORE clearing this bit. When this bit is cleared
  366. // the power-down ramp is started. The headphone (and/or LINEOUT)
  367. // powerup should stay set until the VAG is fully ramped down
  368. // (200 to 400 ms after clearing this bit).
  369. // 0x0 = Power down, 0x1 = Power up
  370. // 6 ADC_MONO While ADC_POWERUP is set, this allows the ADC to be put into left only
  371. // mono operation for power savings. This mode is useful when
  372. // only using the microphone input.
  373. // 0x0 = Mono (left only), 0x1 = Stereo
  374. // 5 REFTOP_POWERUP Power up the reference bias currents
  375. // 0x0 = Power down, 0x1 = Power up
  376. // This bit can be cleared when the part is a sleep state
  377. // to minimize analog power.
  378. // 4 HEADPHONE_POWERUP Power up the headphone amplifiers
  379. // 0x0 = Power down, 0x1 = Power up
  380. // 3 DAC_POWERUP Power up the DACs
  381. // 0x0 = Power down, 0x1 = Power up
  382. // 2 CAPLESS_HEADPHONE_POWERUP Power up the capless headphone mode
  383. // 0x0 = Power down, 0x1 = Power up
  384. // 1 ADC_POWERUP Power up the ADCs
  385. // 0x0 = Power down, 0x1 = Power up
  386. // 0 LINEOUT_POWERUP Power up the LINEOUT amplifiers
  387. // 0x0 = Power down, 0x1 = Power up
  388. #define CHIP_PLL_CTRL 0x0032
  389. // 15:11 INT_DIVISOR
  390. // 10:0 FRAC_DIVISOR
  391. #define CHIP_CLK_TOP_CTRL 0x0034
  392. // 11 ENABLE_INT_OSC Setting this bit enables an internal oscillator to be used for the
  393. // zero cross detectors, the short detect recovery, and the
  394. // charge pump. This allows the I2S clock to be shut off while
  395. // still operating an analog signal path. This bit can be kept
  396. // on when the I2S clock is enabled, but the I2S clock is more
  397. // accurate so it is preferred to clear this bit when I2S is present.
  398. // 3 INPUT_FREQ_DIV2 SYS_MCLK divider before PLL input
  399. // 0x0 = pass through
  400. // 0x1 = SYS_MCLK is divided by 2 before entering PLL
  401. // This must be set when the input clock is above 17 Mhz. This
  402. // has no effect when the PLL is powered down.
  403. #define CHIP_ANA_STATUS 0x0036
  404. // 9 LRSHORT_STS This bit is high whenever a short is detected on the left or right
  405. // channel headphone drivers.
  406. // 8 CSHORT_STS This bit is high whenever a short is detected on the capless headphone
  407. // common/center channel driver.
  408. // 4 PLL_IS_LOCKED This bit goes high after the PLL is locked.
  409. #define CHIP_ANA_TEST1 0x0038 // intended only for debug.
  410. #define CHIP_ANA_TEST2 0x003A // intended only for debug.
  411. #define CHIP_SHORT_CTRL 0x003C
  412. // 14:12 LVLADJR Right channel headphone short detector in 25 mA steps.
  413. // 0x3=25 mA
  414. // 0x2=50 mA
  415. // 0x1=75 mA
  416. // 0x0=100 mA
  417. // 0x4=125 mA
  418. // 0x5=150 mA
  419. // 0x6=175 mA
  420. // 0x7=200 mA
  421. // This trip point can vary by ~30% over process so leave plenty
  422. // of guard band to avoid false trips. This short detect trip
  423. // point is also effected by the bias current adjustments made
  424. // by CHIP_REF_CTRL->BIAS_CTRL and by CHIP_ANA_TEST1->HP_IALL_ADJ.
  425. // 10:8 LVLADJL Left channel headphone short detector in 25 mA steps.
  426. // (same scale as LVLADJR)
  427. // 6:4 LVLADJC Capless headphone center channel short detector in 50 mA steps.
  428. // 0x3=50 mA
  429. // 0x2=100 mA
  430. // 0x1=150 mA
  431. // 0x0=200 mA
  432. // 0x4=250 mA
  433. // 0x5=300 mA
  434. // 0x6=350 mA
  435. // 0x7=400 mA
  436. // 3:2 MODE_LR Behavior of left/right short detection
  437. // 0x0 = Disable short detector, reset short detect latch,
  438. // software view non-latched short signal
  439. // 0x1 = Enable short detector and reset the latch at timeout
  440. // (every ~50 ms)
  441. // 0x2 = This mode is not used/invalid
  442. // 0x3 = Enable short detector with only manual reset (have
  443. // to return to 0x0 to reset the latch)
  444. // 1:0 MODE_CM Behavior of capless headphone central short detection
  445. // (same settings as MODE_LR)
  446. #define DAP_CONTROL 0x0100
  447. #define DAP_PEQ 0x0102
  448. #define DAP_BASS_ENHANCE 0x0104
  449. #define DAP_BASS_ENHANCE_CTRL 0x0106
  450. #define DAP_AUDIO_EQ 0x0108
  451. #define DAP_SGTL_SURROUND 0x010A
  452. #define DAP_FILTER_COEF_ACCESS 0x010C
  453. #define DAP_COEF_WR_B0_MSB 0x010E
  454. #define DAP_COEF_WR_B0_LSB 0x0110
  455. #define DAP_AUDIO_EQ_BASS_BAND0 0x0116 // 115 Hz
  456. #define DAP_AUDIO_EQ_BAND1 0x0118 // 330 Hz
  457. #define DAP_AUDIO_EQ_BAND2 0x011A // 990 Hz
  458. #define DAP_AUDIO_EQ_BAND3 0x011C // 3000 Hz
  459. #define DAP_AUDIO_EQ_TREBLE_BAND4 0x011E // 9900 Hz
  460. #define DAP_MAIN_CHAN 0x0120
  461. #define DAP_MIX_CHAN 0x0122
  462. #define DAP_AVC_CTRL 0x0124
  463. #define DAP_AVC_THRESHOLD 0x0126
  464. #define DAP_AVC_ATTACK 0x0128
  465. #define DAP_AVC_DECAY 0x012A
  466. #define DAP_COEF_WR_B1_MSB 0x012C
  467. #define DAP_COEF_WR_B1_LSB 0x012E
  468. #define DAP_COEF_WR_B2_MSB 0x0130
  469. #define DAP_COEF_WR_B2_LSB 0x0132
  470. #define DAP_COEF_WR_A1_MSB 0x0134
  471. #define DAP_COEF_WR_A1_LSB 0x0136
  472. #define DAP_COEF_WR_A2_MSB 0x0138
  473. #define DAP_COEF_WR_A2_LSB 0x013A
  474. #define SGTL5000_I2C_ADDR_CS_LOW 0x0A // CTRL_ADR0_CS pin low (normal configuration)
  475. #define SGTL5000_I2C_ADDR_CS_HIGH 0x2A // CTRL_ADR0_CS pin high
  476. void AudioControlSGTL5000::setAddress(uint8_t level)
  477. {
  478. if (level == LOW) {
  479. i2c_addr = SGTL5000_I2C_ADDR_CS_LOW;
  480. } else {
  481. i2c_addr = SGTL5000_I2C_ADDR_CS_HIGH;
  482. }
  483. }
  484. bool AudioControlSGTL5000::enable(void) {
  485. #if defined(KINETISL)
  486. return enable(16000000); // SGTL as Master with 16MHz MCLK from Teensy LC
  487. #else
  488. return enable(0);
  489. #endif
  490. }
  491. bool AudioControlSGTL5000::enable(const unsigned extMCLK, const uint32_t pllFreq)
  492. {
  493. Wire.begin();
  494. delay(5);
  495. //Check if we are in Master Mode and if the Teensy had a reset:
  496. unsigned int n = read(CHIP_I2S_CTRL);
  497. if ( (extMCLK > 0) && (n == (0x0030 | (1<<7))) ) {
  498. //Yes. Do not initialize.
  499. muted = false;
  500. semi_automated = true;
  501. return true;
  502. }
  503. //Serial.print("chip ID = ");
  504. //delay(5);
  505. //unsigned int n = read(CHIP_ID);
  506. //Serial.println(n, HEX);
  507. muted = true;
  508. int r = write(CHIP_ANA_POWER, 0x4060); // VDDD is externally driven with 1.8V
  509. if (!r) return false;
  510. write(CHIP_LINREG_CTRL, 0x006C); // VDDA & VDDIO both over 3.1V
  511. write(CHIP_REF_CTRL, 0x01F2); // VAG=1.575, normal ramp, +12.5% bias current
  512. write(CHIP_LINE_OUT_CTRL, 0x0F22); // LO_VAGCNTRL=1.65V, OUT_CURRENT=0.54mA
  513. write(CHIP_SHORT_CTRL, 0x4446); // allow up to 125mA
  514. write(CHIP_ANA_CTRL, 0x0137); // enable zero cross detectors
  515. if (extMCLK > 0) {
  516. //SGTL is I2S Master
  517. //Datasheet Pg. 14: Using the PLL - Asynchronous SYS_MCLK input
  518. if (extMCLK > 17000000) {
  519. write(CHIP_CLK_TOP_CTRL, 1);
  520. } else {
  521. write(CHIP_CLK_TOP_CTRL, 0);
  522. }
  523. uint32_t int_divisor = (pllFreq / extMCLK) & 0x1f;
  524. uint32_t frac_divisor = (uint32_t)((((float)pllFreq / extMCLK) - int_divisor) * 2048.0f) & 0x7ff;
  525. write(CHIP_PLL_CTRL, (int_divisor << 11) | frac_divisor);
  526. write(CHIP_ANA_POWER, 0x40FF | (1<<10) | (1<<8) ); // power up: lineout, hp, adc, dac, PLL_POWERUP, VCOAMP_POWERUP
  527. } else {
  528. //SGTL is I2S Slave
  529. write(CHIP_ANA_POWER, 0x40FF); // power up: lineout, hp, adc, dac
  530. }
  531. write(CHIP_DIG_POWER, 0x0073); // power up all digital stuff
  532. delay(400);
  533. write(CHIP_LINE_OUT_VOL, 0x1D1D); // default approx 1.3 volts peak-to-peak
  534. if (extMCLK > 0) {
  535. //SGTL is I2S Master
  536. write(CHIP_CLK_CTRL, 0x0004 | 0x03); // 44.1 kHz, 256*Fs, use PLL
  537. write(CHIP_I2S_CTRL, 0x0030 | (1<<7)); // SCLK=64*Fs, 16bit, I2S format
  538. } else {
  539. //SGTL is I2S Slave
  540. write(CHIP_CLK_CTRL, 0x0004); // 44.1 kHz, 256*Fs
  541. write(CHIP_I2S_CTRL, 0x0030); // SCLK=64*Fs, 16bit, I2S format
  542. }
  543. // default signal routing is ok?
  544. write(CHIP_SSS_CTRL, 0x0010); // ADC->I2S, I2S->DAC
  545. write(CHIP_ADCDAC_CTRL, 0x0000); // disable dac mute
  546. write(CHIP_DAC_VOL, 0x3C3C); // digital gain, 0dB
  547. write(CHIP_ANA_HP_CTRL, 0x7F7F); // set volume (lowest level)
  548. write(CHIP_ANA_CTRL, 0x0036); // enable zero cross detectors
  549. semi_automated = true;
  550. return true;
  551. }
  552. unsigned int AudioControlSGTL5000::read(unsigned int reg)
  553. {
  554. unsigned int val;
  555. Wire.beginTransmission(i2c_addr);
  556. Wire.write(reg >> 8);
  557. Wire.write(reg);
  558. if (Wire.endTransmission(false) != 0) return 0;
  559. if (Wire.requestFrom((int)i2c_addr, 2) < 2) return 0;
  560. val = Wire.read() << 8;
  561. val |= Wire.read();
  562. return val;
  563. }
  564. bool AudioControlSGTL5000::write(unsigned int reg, unsigned int val)
  565. {
  566. if (reg == CHIP_ANA_CTRL) ana_ctrl = val;
  567. Wire.beginTransmission(i2c_addr);
  568. Wire.write(reg >> 8);
  569. Wire.write(reg);
  570. Wire.write(val >> 8);
  571. Wire.write(val);
  572. if (Wire.endTransmission() == 0) return true;
  573. return false;
  574. }
  575. unsigned int AudioControlSGTL5000::modify(unsigned int reg, unsigned int val, unsigned int iMask)
  576. {
  577. unsigned int val1 = (read(reg)&(~iMask))|val;
  578. if(!write(reg,val1)) return 0;
  579. return val1;
  580. }
  581. bool AudioControlSGTL5000::volumeInteger(unsigned int n)
  582. {
  583. if (n == 0) {
  584. muted = true;
  585. write(CHIP_ANA_HP_CTRL, 0x7F7F);
  586. return muteHeadphone();
  587. } else if (n > 0x80) {
  588. n = 0;
  589. } else {
  590. n = 0x80 - n;
  591. }
  592. if (muted) {
  593. muted = false;
  594. unmuteHeadphone();
  595. }
  596. n = n | (n << 8);
  597. return write(CHIP_ANA_HP_CTRL, n); // set volume
  598. }
  599. bool AudioControlSGTL5000::volume(float left, float right)
  600. {
  601. unsigned short m=((0x7F-calcVol(right,0x7F))<<8)|(0x7F-calcVol(left,0x7F));
  602. return write(CHIP_ANA_HP_CTRL, m);
  603. }
  604. bool AudioControlSGTL5000::micGain(unsigned int dB)
  605. {
  606. unsigned int preamp_gain, input_gain;
  607. if (dB >= 40) {
  608. preamp_gain = 3;
  609. dB -= 40;
  610. } else if (dB >= 30) {
  611. preamp_gain = 2;
  612. dB -= 30;
  613. } else if (dB >= 20) {
  614. preamp_gain = 1;
  615. dB -= 20;
  616. } else {
  617. preamp_gain = 0;
  618. }
  619. input_gain = (dB * 2) / 3;
  620. if (input_gain > 15) input_gain = 15;
  621. return write(CHIP_MIC_CTRL, 0x0170 | preamp_gain)
  622. && write(CHIP_ANA_ADC_CTRL, (input_gain << 4) | input_gain);
  623. }
  624. // CHIP_ANA_ADC_CTRL
  625. // Actual measured full-scale peak-to-peak sine wave input for max signal
  626. // 0: 3.12 Volts p-p
  627. // 1: 2.63 Volts p-p
  628. // 2: 2.22 Volts p-p
  629. // 3: 1.87 Volts p-p
  630. // 4: 1.58 Volts p-p
  631. // 5: 1.33 Volts p-p
  632. // 6: 1.11 Volts p-p
  633. // 7: 0.94 Volts p-p
  634. // 8: 0.79 Volts p-p
  635. // 9: 0.67 Volts p-p
  636. // 10: 0.56 Volts p-p
  637. // 11: 0.48 Volts p-p
  638. // 12: 0.40 Volts p-p
  639. // 13: 0.34 Volts p-p
  640. // 14: 0.29 Volts p-p
  641. // 15: 0.24 Volts p-p
  642. bool AudioControlSGTL5000::lineInLevel(uint8_t left, uint8_t right)
  643. {
  644. if (left > 15) left = 15;
  645. if (right > 15) right = 15;
  646. return write(CHIP_ANA_ADC_CTRL, (left << 4) | right);
  647. }
  648. // CHIP_LINE_OUT_VOL
  649. // Actual measured full-scale peak-to-peak sine wave output voltage:
  650. // 0-12: output has clipping
  651. // 13: 3.16 Volts p-p
  652. // 14: 2.98 Volts p-p
  653. // 15: 2.83 Volts p-p
  654. // 16: 2.67 Volts p-p
  655. // 17: 2.53 Volts p-p
  656. // 18: 2.39 Volts p-p
  657. // 19: 2.26 Volts p-p
  658. // 20: 2.14 Volts p-p
  659. // 21: 2.02 Volts p-p
  660. // 22: 1.91 Volts p-p
  661. // 23: 1.80 Volts p-p
  662. // 24: 1.71 Volts p-p
  663. // 25: 1.62 Volts p-p
  664. // 26: 1.53 Volts p-p
  665. // 27: 1.44 Volts p-p
  666. // 28: 1.37 Volts p-p
  667. // 29: 1.29 Volts p-p
  668. // 30: 1.22 Volts p-p
  669. // 31: 1.16 Volts p-p
  670. unsigned short AudioControlSGTL5000::lineOutLevel(uint8_t n)
  671. {
  672. if (n > 31) n = 31;
  673. else if (n < 13) n = 13;
  674. return modify(CHIP_LINE_OUT_VOL,(n<<8)|n,(31<<8)|31);
  675. }
  676. unsigned short AudioControlSGTL5000::lineOutLevel(uint8_t left, uint8_t right)
  677. {
  678. if (left > 31) left = 31;
  679. else if (left < 13) left = 13;
  680. if (right > 31) right = 31;
  681. else if (right < 13) right = 13;
  682. return modify(CHIP_LINE_OUT_VOL,(right<<8)|left,(31<<8)|31);
  683. }
  684. unsigned short AudioControlSGTL5000::dacVolume(float n) // set both directly
  685. {
  686. if ((read(CHIP_ADCDAC_CTRL)&(3<<2)) != ((n>0 ? 0:3)<<2)) {
  687. modify(CHIP_ADCDAC_CTRL,(n>0 ? 0:3)<<2,3<<2);
  688. }
  689. unsigned char m=calcVol(n,0xC0);
  690. return modify(CHIP_DAC_VOL,((0xFC-m)<<8)|(0xFC-m),65535);
  691. }
  692. unsigned short AudioControlSGTL5000::dacVolume(float left, float right)
  693. {
  694. unsigned short adcdac=((right>0 ? 0:2)|(left>0 ? 0:1))<<2;
  695. if ((read(CHIP_ADCDAC_CTRL)&(3<<2)) != adcdac) {
  696. modify(CHIP_ADCDAC_CTRL,adcdac,1<<2);
  697. }
  698. unsigned short m=(0xFC-calcVol(right,0xC0))<<8|(0xFC-calcVol(left,0xC0));
  699. return modify(CHIP_DAC_VOL,m,65535);
  700. }
  701. bool AudioControlSGTL5000::dacVolumeRamp()
  702. {
  703. return modify(CHIP_ADCDAC_CTRL, 0x300, 0x300);
  704. }
  705. bool AudioControlSGTL5000::dacVolumeRampLinear()
  706. {
  707. return modify(CHIP_ADCDAC_CTRL, 0x200, 0x300);
  708. }
  709. bool AudioControlSGTL5000::dacVolumeRampDisable()
  710. {
  711. return modify(CHIP_ADCDAC_CTRL, 0, 0x300);
  712. }
  713. unsigned short AudioControlSGTL5000::adcHighPassFilterEnable(void)
  714. {
  715. return modify(CHIP_ADCDAC_CTRL, 0, 3);
  716. }
  717. unsigned short AudioControlSGTL5000::adcHighPassFilterFreeze(void)
  718. {
  719. return modify(CHIP_ADCDAC_CTRL, 2, 3);
  720. }
  721. unsigned short AudioControlSGTL5000::adcHighPassFilterDisable(void)
  722. {
  723. return modify(CHIP_ADCDAC_CTRL, 1, 3);
  724. }
  725. // DAP_CONTROL
  726. unsigned short AudioControlSGTL5000::audioPreProcessorEnable(void)
  727. {
  728. // audio processor used to pre-process analog input before Teensy
  729. return write(DAP_CONTROL, 1) && write(CHIP_SSS_CTRL, 0x0013);
  730. }
  731. unsigned short AudioControlSGTL5000::audioPostProcessorEnable(void)
  732. {
  733. // audio processor used to post-process Teensy output before headphones/lineout
  734. return write(DAP_CONTROL, 1) && write(CHIP_SSS_CTRL, 0x0070);
  735. }
  736. unsigned short AudioControlSGTL5000::audioProcessorDisable(void)
  737. {
  738. return write(CHIP_SSS_CTRL, 0x0010) && write(DAP_CONTROL, 0);
  739. }
  740. // DAP_PEQ
  741. unsigned short AudioControlSGTL5000::eqFilterCount(uint8_t n) // valid to n&7, 0 thru 7 filters enabled.
  742. {
  743. return modify(DAP_PEQ,(n&7),7);
  744. }
  745. // DAP_AUDIO_EQ
  746. unsigned short AudioControlSGTL5000::eqSelect(uint8_t n) // 0=NONE, 1=PEQ (7 IIR Biquad filters), 2=TONE (tone), 3=GEQ (5 band EQ)
  747. {
  748. return modify(DAP_AUDIO_EQ,n&3,3);
  749. }
  750. unsigned short AudioControlSGTL5000::eqBand(uint8_t bandNum, float n)
  751. {
  752. if(semi_automated) automate(1,3);
  753. return dap_audio_eq_band(bandNum, n);
  754. }
  755. void AudioControlSGTL5000::eqBands(float bass, float mid_bass, float midrange, float mid_treble, float treble)
  756. {
  757. if(semi_automated) automate(1,3);
  758. dap_audio_eq_band(0,bass);
  759. dap_audio_eq_band(1,mid_bass);
  760. dap_audio_eq_band(2,midrange);
  761. dap_audio_eq_band(3,mid_treble);
  762. dap_audio_eq_band(4,treble);
  763. }
  764. void AudioControlSGTL5000::eqBands(float bass, float treble) // dap_audio_eq(2);
  765. {
  766. if(semi_automated) automate(1,2);
  767. dap_audio_eq_band(0,bass);
  768. dap_audio_eq_band(4,treble);
  769. }
  770. // SGTL5000 PEQ Coefficient loader
  771. void AudioControlSGTL5000::eqFilter(uint8_t filterNum, int *filterParameters)
  772. {
  773. // TODO: add the part that selects 7 PEQ filters.
  774. if(semi_automated) automate(1,1,filterNum+1);
  775. modify(DAP_FILTER_COEF_ACCESS,(uint16_t)filterNum,15);
  776. write(DAP_COEF_WR_B0_MSB,(*filterParameters>>4)&65535);
  777. write(DAP_COEF_WR_B0_LSB,(*filterParameters++)&15);
  778. write(DAP_COEF_WR_B1_MSB,(*filterParameters>>4)&65535);
  779. write(DAP_COEF_WR_B1_LSB,(*filterParameters++)&15);
  780. write(DAP_COEF_WR_B2_MSB,(*filterParameters>>4)&65535);
  781. write(DAP_COEF_WR_B2_LSB,(*filterParameters++)&15);
  782. write(DAP_COEF_WR_A1_MSB,(*filterParameters>>4)&65535);
  783. write(DAP_COEF_WR_A1_LSB,(*filterParameters++)&15);
  784. write(DAP_COEF_WR_A2_MSB,(*filterParameters>>4)&65535);
  785. write(DAP_COEF_WR_A2_LSB,(*filterParameters++)&15);
  786. write(DAP_FILTER_COEF_ACCESS,(uint16_t)0x100|filterNum);
  787. }
  788. /* Valid values for dap_avc parameters
  789. maxGain; Maximum gain that can be applied
  790. 0 - 0 dB
  791. 1 - 6.0 dB
  792. 2 - 12 dB
  793. lbiResponse; Integrator Response
  794. 0 - 0 mS
  795. 1 - 25 mS
  796. 2 - 50 mS
  797. 3 - 100 mS
  798. hardLimit
  799. 0 - Hard limit disabled. AVC Compressor/Expander enabled.
  800. 1 - Hard limit enabled. The signal is limited to the programmed threshold (signal saturates at the threshold)
  801. threshold
  802. floating point in range 0 to -96 dB
  803. attack
  804. floating point figure is dB/s rate at which gain is increased
  805. decay
  806. floating point figure is dB/s rate at which gain is reduced
  807. */
  808. unsigned short AudioControlSGTL5000::autoVolumeControl(uint8_t maxGain, uint8_t lbiResponse, uint8_t hardLimit, float threshold, float attack, float decay)
  809. {
  810. //if(semi_automated&&(!read(DAP_CONTROL)&1)) audioProcessorEnable();
  811. if(maxGain>2) maxGain=2;
  812. lbiResponse&=3;
  813. hardLimit&=1;
  814. uint8_t thresh=(pow(10,threshold/20)*0.636)*pow(2,15);
  815. uint8_t att=(1-pow(10,-(attack/(20*44100))))*pow(2,19);
  816. uint8_t dec=(1-pow(10,-(decay/(20*44100))))*pow(2,23);
  817. write(DAP_AVC_THRESHOLD,thresh);
  818. write(DAP_AVC_ATTACK,att);
  819. write(DAP_AVC_DECAY,dec);
  820. return modify(DAP_AVC_CTRL,maxGain<<12|lbiResponse<<8|hardLimit<<5,3<<12|3<<8|1<<5);
  821. }
  822. unsigned short AudioControlSGTL5000::autoVolumeEnable(void)
  823. {
  824. return modify(DAP_AVC_CTRL, 1, 1);
  825. }
  826. unsigned short AudioControlSGTL5000::autoVolumeDisable(void)
  827. {
  828. return modify(DAP_AVC_CTRL, 0, 1);
  829. }
  830. unsigned short AudioControlSGTL5000::enhanceBass(float lr_lev, float bass_lev)
  831. {
  832. return modify(DAP_BASS_ENHANCE_CTRL,((0x3F-calcVol(lr_lev,0x3F))<<8) | (0x7F-calcVol(bass_lev,0x7F)), (0x3F<<8) | 0x7F);
  833. }
  834. unsigned short AudioControlSGTL5000::enhanceBass(float lr_lev, float bass_lev, uint8_t hpf_bypass, uint8_t cutoff)
  835. {
  836. modify(DAP_BASS_ENHANCE,(hpf_bypass&1)<<8|(cutoff&7)<<4,1<<8|7<<4);
  837. return enhanceBass(lr_lev,bass_lev);
  838. }
  839. unsigned short AudioControlSGTL5000::enhanceBassEnable(void)
  840. {
  841. return modify(DAP_BASS_ENHANCE, 1, 1);
  842. }
  843. unsigned short AudioControlSGTL5000::enhanceBassDisable(void)
  844. {
  845. return modify(DAP_BASS_ENHANCE, 0, 1);
  846. }
  847. unsigned short AudioControlSGTL5000::surroundSound(uint8_t width)
  848. {
  849. return modify(DAP_SGTL_SURROUND,(width&7)<<4,7<<4);
  850. }
  851. unsigned short AudioControlSGTL5000::surroundSound(uint8_t width, uint8_t select)
  852. {
  853. return modify(DAP_SGTL_SURROUND,((width&7)<<4)|(select&3), (7<<4)|3);
  854. }
  855. unsigned short AudioControlSGTL5000::surroundSoundEnable(void)
  856. {
  857. return modify(DAP_SGTL_SURROUND, 3, 3);
  858. }
  859. unsigned short AudioControlSGTL5000::surroundSoundDisable(void)
  860. {
  861. return modify(DAP_SGTL_SURROUND, 0, 3);
  862. }
  863. unsigned char AudioControlSGTL5000::calcVol(float n, unsigned char range)
  864. {
  865. // n=(n*(((float)range)/100))+0.499;
  866. n=(n*(float)range)+0.499;
  867. if ((unsigned char)n>range) n=range;
  868. return (unsigned char)n;
  869. }
  870. // DAP_AUDIO_EQ_BASS_BAND0 & DAP_AUDIO_EQ_BAND1 & DAP_AUDIO_EQ_BAND2 etc etc
  871. unsigned short AudioControlSGTL5000::dap_audio_eq_band(uint8_t bandNum, float n) // by signed percentage -100/+100; dap_audio_eq(3);
  872. {
  873. n=(n*48)+0.499;
  874. if(n<-47) n=-47;
  875. if(n>48) n=48;
  876. n+=47;
  877. return modify(DAP_AUDIO_EQ_BASS_BAND0+(bandNum*2),(unsigned int)n,127);
  878. }
  879. void AudioControlSGTL5000::automate(uint8_t dap, uint8_t eq)
  880. {
  881. //if((dap!=0)&&(!(read(DAP_CONTROL)&1))) audioProcessorEnable();
  882. if((read(DAP_AUDIO_EQ)&3) != eq) eqSelect(eq);
  883. }
  884. void AudioControlSGTL5000::automate(uint8_t dap, uint8_t eq, uint8_t filterCount)
  885. {
  886. automate(dap,eq);
  887. if (filterCount > (read(DAP_PEQ)&7)) eqFilterCount(filterCount);
  888. }
  889. // if(SGTL5000_PEQ) quantization_unit=524288; if(AudioFilterBiquad) quantization_unit=2147483648;
  890. void calcBiquad(uint8_t filtertype, float fC, float dB_Gain, float Q, uint32_t quantization_unit, uint32_t fS, int *coef)
  891. {
  892. // I used resources like http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
  893. // to make this routine, I tested most of the filter types and they worked. Such filters have limits and
  894. // before calling this routine with varying values the end user should check that those values are limited
  895. // to valid results.
  896. float A;
  897. if(filtertype<FILTER_PARAEQ) A=pow(10,dB_Gain/20); else A=pow(10,dB_Gain/40);
  898. float W0 = 2*3.14159265358979323846*fC/fS;
  899. float cosw=cosf(W0);
  900. float sinw=sinf(W0);
  901. //float alpha = sinw*sinh((log(2)/2)*BW*W0/sinw);
  902. //float beta = sqrt(2*A);
  903. float alpha = sinw / (2 * Q);
  904. float beta = sqrtf(A)/Q;
  905. float b0,b1,b2,a0,a1,a2;
  906. switch(filtertype) {
  907. case FILTER_LOPASS:
  908. b0 = (1.0F - cosw) * 0.5F; // =(1-COS($H$2))/2
  909. b1 = 1.0F - cosw;
  910. b2 = (1.0F - cosw) * 0.5F;
  911. a0 = 1.0F + alpha;
  912. a1 = 2.0F * cosw;
  913. a2 = alpha - 1.0F;
  914. break;
  915. case FILTER_HIPASS:
  916. b0 = (1.0F + cosw) * 0.5F;
  917. b1 = -(cosw + 1.0F);
  918. b2 = (1.0F + cosw) * 0.5F;
  919. a0 = 1.0F + alpha;
  920. a1 = 2.0F * cosw;
  921. a2 = alpha - 1.0F;
  922. break;
  923. case FILTER_BANDPASS:
  924. b0 = alpha;
  925. b1 = 0.0F;
  926. b2 = -alpha;
  927. a0 = 1.0F + alpha;
  928. a1 = 2.0F * cosw;
  929. a2 = alpha - 1.0F;
  930. break;
  931. case FILTER_NOTCH:
  932. b0=1;
  933. b1=-2*cosw;
  934. b2=1;
  935. a0=1+alpha;
  936. a1=2*cosw;
  937. a2=-(1-alpha);
  938. break;
  939. case FILTER_PARAEQ:
  940. b0 = 1 + (alpha*A);
  941. b1 =-2 * cosw;
  942. b2 = 1 - (alpha*A);
  943. a0 = 1 + (alpha/A);
  944. a1 = 2 * cosw;
  945. a2 =-(1-(alpha/A));
  946. break;
  947. case FILTER_LOSHELF:
  948. b0 = A * ((A+1.0F) - ((A-1.0F)*cosw) + (beta*sinw));
  949. b1 = 2.0F * A * ((A-1.0F) - ((A+1.0F)*cosw));
  950. b2 = A * ((A+1.0F) - ((A-1.0F)*cosw) - (beta*sinw));
  951. a0 = (A+1.0F) + ((A-1.0F)*cosw) + (beta*sinw);
  952. a1 = 2.0F * ((A-1.0F) + ((A+1.0F)*cosw));
  953. a2 = -((A+1.0F) + ((A-1.0F)*cosw) - (beta*sinw));
  954. break;
  955. case FILTER_HISHELF:
  956. b0 = A * ((A+1.0F) + ((A-1.0F)*cosw) + (beta*sinw));
  957. b1 = -2.0F * A * ((A-1.0F) + ((A+1.0F)*cosw));
  958. b2 = A * ((A+1.0F) + ((A-1.0F)*cosw) - (beta*sinw));
  959. a0 = (A+1.0F) - ((A-1.0F)*cosw) + (beta*sinw);
  960. a1 = -2.0F * ((A-1.0F) - ((A+1.0F)*cosw));
  961. a2 = -((A+1.0F) - ((A-1.0F)*cosw) - (beta*sinw));
  962. break;
  963. default:
  964. b0 = 0.5;
  965. b1 = 0.0;
  966. b2 = 0.0;
  967. a0 = 1.0;
  968. a1 = 0.0;
  969. a2 = 0.0;
  970. }
  971. a0=(a0*2)/(float)quantization_unit; // once here instead of five times there...
  972. b0/=a0;
  973. *coef++=(int)(b0+0.499);
  974. b1/=a0;
  975. *coef++=(int)(b1+0.499);
  976. b2/=a0;
  977. *coef++=(int)(b2+0.499);
  978. a1/=a0;
  979. *coef++=(int)(a1+0.499);
  980. a2/=a0;
  981. *coef++=(int)(a2+0.499);
  982. }