dac_5713.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*
  2. * Squeezelite for esp32
  3. *
  4. * (c) Sebastien 2019
  5. * Philippe G. 2019, philippe_44@outlook.com
  6. *
  7. * This software is released under the MIT License.
  8. * https://opensource.org/licenses/MIT
  9. *
  10. * (c) C. Rohs 2020 added support for the tas5713 (eg. HiFiBerry AMP+)
  11. */
  12. #include <string.h>
  13. #include "freertos/FreeRTOS.h"
  14. #include "freertos/task.h"
  15. #include "driver/i2s.h"
  16. #include "driver/i2c.h"
  17. #include "driver/gpio.h"
  18. #include "esp_log.h"
  19. #include "adac.h"
  20. #define ARRAY_SIZE(array) (sizeof(array) / sizeof(*array))
  21. #define TAS5713 (0x36 >> 1) /* i2c address of TAS5713 */
  22. // TAS5713 I2C-bus register addresses
  23. #define TAS5713_CLOCK_CTRL 0x00
  24. #define TAS5713_DEVICE_ID 0x01
  25. #define TAS5713_ERROR_STATUS 0x02
  26. #define TAS5713_SYSTEM_CTRL1 0x03
  27. #define TAS5713_SERIAL_DATA_INTERFACE 0x04
  28. #define TAS5713_SYSTEM_CTRL2 0x05
  29. #define TAS5713_SOFT_MUTE 0x06
  30. #define TAS5713_VOL_MASTER 0x07
  31. #define TAS5713_VOL_CH1 0x08
  32. #define TAS5713_VOL_CH2 0x09
  33. #define TAS5713_VOL_HEADPHONE 0x0A
  34. #define TAS5713_OSC_TRIM 0x1B
  35. static const char TAG[] = "TAS5713";
  36. static bool init(char *config, int i2c_port_num, i2s_config_t *i2s_config);
  37. static void speaker(bool active) { };
  38. static void headset(bool active) { } ;
  39. static bool volume(unsigned left, unsigned right);
  40. static void power(adac_power_e mode) { };
  41. const struct adac_s dac_tas5713 = {"TAS5713", init, adac_deinit, power, speaker, headset, volume};
  42. struct tas5713_cmd_s {
  43. uint8_t reg;
  44. uint8_t value;
  45. };
  46. // matching orders
  47. typedef enum {
  48. TAS57_ACTIVE = 0,
  49. TAS57_STANDBY,
  50. TAS57_DOWN,
  51. TAS57_ANALOGUE_OFF,
  52. TAS57_ANALOGUE_ON,
  53. TAS57_VOLUME
  54. } dac_cmd_e;
  55. /****************************************************************************************
  56. * init
  57. */
  58. static bool init(char *config, int i2c_port, i2s_config_t *i2s_config) {
  59. /* find if there is a tas5713 attached. Reg 0 should read non-zero but not 255 if so */
  60. adac_init(config, i2c_port);
  61. if (adac_read_byte(TAS5713, 0x00) == 255) {
  62. ESP_LOGW(TAG, "No TAS5713 detected");
  63. adac_deinit();
  64. return 0;
  65. }
  66. ESP_LOGI(TAG, "TAS5713 found");
  67. /* do the init sequence */
  68. esp_err_t res = adac_write_byte(TAS5713, TAS5713_OSC_TRIM, 0x00); /* a delay is required after this */
  69. vTaskDelay(50 / portTICK_PERIOD_MS);
  70. res |= adac_write_byte(TAS5713, TAS5713_SERIAL_DATA_INTERFACE, 0x03); /* I2S LJ 16 bit */
  71. res |= adac_write_byte(TAS5713, TAS5713_SYSTEM_CTRL2, 0x00); /* exit all channel shutdown */
  72. res |= adac_write_byte(TAS5713, TAS5713_SOFT_MUTE, 0x00); /* unmute */
  73. res |= adac_write_byte(TAS5713, TAS5713_VOL_MASTER, 0x20);
  74. res |= adac_write_byte(TAS5713, TAS5713_VOL_CH1, 0x30);
  75. res |= adac_write_byte(TAS5713, TAS5713_VOL_CH2, 0x30);
  76. res |= adac_write_byte(TAS5713, TAS5713_VOL_HEADPHONE, 0xFF);
  77. /* The tas5713 typically has the mclk connected to the sclk. In this
  78. configuration, mclk must be a multiple of the sclk. The lowest workable
  79. multiple is 64x. To achieve this, 32 bits per channel on must be sent
  80. over I2S. Reconfigure the I2S for that here, and expand the I2S stream
  81. when it is sent */
  82. i2s_config->bits_per_sample = 32;
  83. if (res != ESP_OK) {
  84. ESP_LOGE(TAG, "could not intialize TAS5713 %d", res);
  85. return false;
  86. }
  87. return true;
  88. }
  89. /****************************************************************************************
  90. * change volume
  91. */
  92. static bool volume(unsigned left, unsigned right) {
  93. return false;
  94. }