TAS5711AudioSink.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #include "TAS5711AudioSink.h"
  2. struct tas5711_cmd_s {
  3. uint8_t reg;
  4. uint8_t value;
  5. };
  6. static const struct tas5711_cmd_s tas5711_init_sequence[] = {
  7. { 0x00, 0x6c }, // 0x6c - 256 x mclk
  8. { 0x04, 0x03 }, // 0x03 - 16 bit i2s
  9. { 0x05, 0x00 }, // system control 0x00 is audio playback
  10. { 0x06, 0x00 }, // disable mute
  11. { 0x07, 0x50 }, // volume register
  12. { 0xff, 0xff }
  13. };
  14. i2c_ack_type_t ACK_CHECK_EN = (i2c_ack_type_t)0x1;
  15. TAS5711AudioSink::TAS5711AudioSink()
  16. {
  17. i2s_config_t i2s_config = {
  18. .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX), // Only TX
  19. .sample_rate = 44100,
  20. .bits_per_sample = (i2s_bits_per_sample_t)16,
  21. .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, //2-channels
  22. .communication_format = (i2s_comm_format_t)I2S_COMM_FORMAT_STAND_MSB,
  23. .intr_alloc_flags = 0, //Default interrupt priority
  24. .dma_buf_count = 8,
  25. .dma_buf_len = 512,
  26. .use_apll = true,
  27. .tx_desc_auto_clear = true, //Auto clear tx descriptor on underflow
  28. .fixed_mclk = 256 * 44100
  29. };
  30. i2s_pin_config_t pin_config = {
  31. .bck_io_num = 5,
  32. .ws_io_num = 25,
  33. .data_out_num = 26,
  34. .data_in_num = -1 //Not used
  35. };
  36. i2s_driver_install((i2s_port_t)0, &i2s_config, 0, NULL);
  37. i2s_set_pin((i2s_port_t)0, &pin_config);
  38. // configure i2c
  39. i2c_config = {
  40. .mode = I2C_MODE_MASTER,
  41. .sda_io_num = 21,
  42. .scl_io_num = 23,
  43. .sda_pullup_en = GPIO_PULLUP_DISABLE,
  44. .scl_pullup_en = GPIO_PULLUP_DISABLE,
  45. };
  46. i2c_config.master.clk_speed = 250000;
  47. i2c_param_config(i2c_port, &i2c_config);
  48. i2c_driver_install(i2c_port, I2C_MODE_MASTER, false, false, false);
  49. i2c_cmd_handle_t i2c_cmd = i2c_cmd_link_create();
  50. uint8_t data, addr = (0x1b);
  51. i2c_master_start(i2c_cmd);
  52. i2c_master_write_byte(i2c_cmd, (addr << 1) | I2C_MASTER_WRITE, ACK_CHECK_EN);
  53. i2c_master_write_byte(i2c_cmd, 00, ACK_CHECK_EN);
  54. i2c_master_start(i2c_cmd);
  55. i2c_master_write_byte(i2c_cmd, (addr << 1) | I2C_MASTER_READ, ACK_CHECK_EN);
  56. i2c_master_read_byte(i2c_cmd, &data, ACK_CHECK_EN);
  57. i2c_master_stop(i2c_cmd);
  58. int ret = i2c_master_cmd_begin(i2c_port, i2c_cmd, 50 / portTICK_PERIOD_MS);
  59. i2c_cmd_link_delete(i2c_cmd);
  60. if (ret == ESP_OK) {
  61. ESP_LOGI("RR", "Detected TAS");
  62. }
  63. else {
  64. ESP_LOGI("RR", "Unable to detect dac");
  65. }
  66. writeReg(0x1b, 0x00);
  67. vTaskDelay(100 / portTICK_PERIOD_MS);
  68. for (int i = 0; tas5711_init_sequence[i].reg != 0xff; i++) {
  69. writeReg(tas5711_init_sequence[i].reg, tas5711_init_sequence[i].value);
  70. vTaskDelay(1 / portTICK_PERIOD_MS);
  71. }
  72. startI2sFeed();
  73. }
  74. void TAS5711AudioSink::writeReg(uint8_t reg, uint8_t value)
  75. {
  76. i2c_cmd_handle_t i2c_cmd = i2c_cmd_link_create();
  77. i2c_master_start(i2c_cmd);
  78. i2c_master_write_byte(i2c_cmd, (0x1b << 1) | I2C_MASTER_WRITE, ACK_CHECK_EN);
  79. i2c_master_write_byte(i2c_cmd, reg, ACK_CHECK_EN);
  80. i2c_master_write_byte(i2c_cmd, value, ACK_CHECK_EN);
  81. i2c_master_stop(i2c_cmd);
  82. esp_err_t res = i2c_master_cmd_begin(i2c_port, i2c_cmd, 500 / portTICK_PERIOD_MS);
  83. if (res != ESP_OK) {
  84. ESP_LOGE("RR", "Unable to write to TAS5711");
  85. }
  86. i2c_cmd_link_delete(i2c_cmd);
  87. }
  88. TAS5711AudioSink::~TAS5711AudioSink()
  89. {
  90. }