PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
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_cs42448.cpp 5.7KB

3 vuotta sitten
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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_cs42448.h"
  28. #include "Wire.h"
  29. #define CS42448_Chip_ID 0x01
  30. #define CS42448_Power_Control 0x02
  31. #define CS42448_Functional_Mode 0x03
  32. #define CS42448_Interface_Formats 0x04
  33. #define CS42448_ADC_Control_DAC_DeEmphasis 0x05
  34. #define CS42448_Transition_Control 0x06
  35. #define CS42448_DAC_Channel_Mute 0x07
  36. #define CS42448_AOUT1_Volume_Control 0x08
  37. #define CS42448_AOUT2_Volume_Control 0x09
  38. #define CS42448_AOUT3_Volume_Control 0x0A
  39. #define CS42448_AOUT4_Volume_Control 0x0B
  40. #define CS42448_AOUT5_Volume_Control 0x0C
  41. #define CS42448_AOUT6_Volume_Control 0x0D
  42. #define CS42448_AOUT7_Volume_Control 0x0E
  43. #define CS42448_AOUT8_Volume_Control 0x0F
  44. #define CS42448_DAC_Channel_Invert 0x10
  45. #define CS42448_AIN1_Volume_Control 0x11
  46. #define CS42448_AIN2_Volume_Control 0x12
  47. #define CS42448_AIN3_Volume_Control 0x13
  48. #define CS42448_AIN4_Volume_Control 0x14
  49. #define CS42448_AIN5_Volume_Control 0x15
  50. #define CS42448_AIN6_Volume_Control 0x16
  51. #define CS42448_ADC_Channel_Invert 0x17
  52. #define CS42448_Status_Control 0x18
  53. #define CS42448_Status 0x19
  54. #define CS42448_Status_Mask 0x1A
  55. #define CS42448_MUTEC_Pin_Control 0x1B
  56. // 4.9 Recommended Power-Up Sequence
  57. // 1. Hold RST low until the power supply and clocks are stable. In this state,
  58. // the control port is reset to its default settings and VQ will remain low.
  59. // 2. Bring RST high. The device will initially be in a low power state with VQ
  60. // low. All features will default as described in the "Register Quick Reference"
  61. // on page 40.
  62. // 3. Perform a write operation to the Power Control register ("Power Control
  63. // (Address 02h)" on page 43) to set bit 0 to a '1'b. This will place the
  64. // device in a power down state.
  65. // 4. Load the desired register settings while keeping the PDN bit set to '1'b.
  66. // 5. Mute all DACs. Muting the DACs suppresses any noise associated with the
  67. // CODEC's first initialization after power is applied.
  68. // 6. Set the PDN bit in the power control register to '0'b. VQ will ramp to
  69. // approximately VA/2 according to the Popguard specification in section
  70. // "Popguard" on page 29.
  71. // 7. Following approximately 2000 LRCK cycles, the device is initialized and
  72. // ready for normal operation.
  73. // 8. After the CODEC is initialized, wait ~90 LRCK cycles (~1.9 ms @48 kHz) and
  74. // then un-mute the DACs.
  75. // 9. Normal operation begins.
  76. // Some people have found their CS42448 goes into a strange mode where VQ is 1.25V
  77. // instead of the normal 2.5V. Apparently there is a workaround for this problem
  78. // which involves writing to an undocumented bit. Details here:
  79. // https://forum.pjrc.com/threads/41371?p=215881&viewfull=1#post215881
  80. static const uint8_t default_config[] = {
  81. 0xF4, // CS42448_Functional_Mode = slave mode, MCLK 25.6 MHz max
  82. 0x76, // CS42448_Interface_Formats = TDM mode
  83. 0x1C, // CS42448_ADC_Control_DAC_DeEmphasis = single ended ADC
  84. 0x63, // CS42448_Transition_Control = soft vol control
  85. 0xFF // CS42448_DAC_Channel_Mute = all outputs mute
  86. };
  87. bool AudioControlCS42448::enable(void)
  88. {
  89. Wire.begin();
  90. // TODO: wait for reset signal high??
  91. if (!write(CS42448_Power_Control, 0xFF)) return false; // power down
  92. if (!write(CS42448_Functional_Mode, default_config, sizeof(default_config))) return false;
  93. if (!write(CS42448_Power_Control, 0)) return false; // power up
  94. return true;
  95. }
  96. bool AudioControlCS42448::volumeInteger(uint32_t n)
  97. {
  98. uint8_t data[9];
  99. data[0] = 0;
  100. for (int i=1; i < 9; i++) {
  101. data[i] = n;
  102. }
  103. return write(CS42448_DAC_Channel_Mute, data, 9);
  104. }
  105. bool AudioControlCS42448::volumeInteger(int channel, uint32_t n)
  106. {
  107. return true;
  108. }
  109. bool AudioControlCS42448::inputLevelInteger(int32_t n)
  110. {
  111. return true;
  112. }
  113. bool AudioControlCS42448::inputLevelInteger(int chnnel, int32_t n)
  114. {
  115. return true;
  116. }
  117. bool AudioControlCS42448::write(uint32_t address, uint32_t data)
  118. {
  119. Wire.beginTransmission(i2c_addr);
  120. Wire.write(address);
  121. Wire.write(data);
  122. if (Wire.endTransmission() == 0) return true;
  123. return false;
  124. }
  125. bool AudioControlCS42448::write(uint32_t address, const void *data, uint32_t len)
  126. {
  127. Wire.beginTransmission(i2c_addr);
  128. Wire.write(address | 0x80);
  129. const uint8_t *p = (const uint8_t *)data;
  130. const uint8_t *end = p + len;
  131. while (p < end) {
  132. Wire.write(*p++);
  133. }
  134. if (Wire.endTransmission() == 0) return true;
  135. return false;
  136. }