dac_external.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  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. */
  11. #include <freertos/FreeRTOS.h>
  12. #include <freertos/task.h>
  13. #include <driver/i2s.h>
  14. #include "driver/i2c.h"
  15. #include "esp_log.h"
  16. #include "cJSON.h"
  17. #include "platform_config.h"
  18. #include "adac.h"
  19. static const char TAG[] = "DAC external";
  20. static void speaker(bool active) { }
  21. static void headset(bool active) { }
  22. static bool volume(unsigned left, unsigned right) { return false; }
  23. static void power(adac_power_e mode);
  24. static bool init(char *config, int i2c_port_num, i2s_config_t *i2s_config);
  25. static bool i2c_json_execute(char *set);
  26. const struct adac_s dac_external = { "i2s", init, adac_deinit, power, speaker, headset, volume };
  27. static cJSON *i2c_json;
  28. static int i2c_addr;
  29. /****************************************************************************************
  30. * init
  31. */
  32. static bool init(char *config, int i2c_port_num, i2s_config_t *i2s_config) {
  33. char *p;
  34. i2c_addr = adac_init(config, i2c_port_num);
  35. if (!i2c_addr) return false;
  36. ESP_LOGI(TAG, "DAC on I2C @%d", i2c_addr);
  37. p = config_alloc_get_str("dac_controlset", CONFIG_DAC_CONTROLSET, NULL);
  38. i2c_json = cJSON_Parse(p);
  39. if (!i2c_json) {
  40. if (p) free(p);
  41. ESP_LOGW(TAG, "no i2c controlset found");
  42. return true;
  43. }
  44. if (!i2c_json_execute("init")) {
  45. ESP_LOGE(TAG, "could not intialize DAC");
  46. return false;
  47. }
  48. return true;
  49. }
  50. /****************************************************************************************
  51. * power
  52. */
  53. static void power(adac_power_e mode) {
  54. if (mode == ADAC_STANDBY || mode == ADAC_OFF) i2c_json_execute("poweroff");
  55. else i2c_json_execute("poweron");
  56. }
  57. /****************************************************************************************
  58. *
  59. */
  60. bool i2c_json_execute(char *set) {
  61. cJSON *json_set = cJSON_GetObjectItemCaseSensitive(i2c_json, set);
  62. cJSON *item;
  63. if (!json_set) return true;
  64. cJSON_ArrayForEach(item, json_set)
  65. {
  66. cJSON *reg = cJSON_GetObjectItemCaseSensitive(item, "reg");
  67. cJSON *val = cJSON_GetObjectItemCaseSensitive(item, "val");
  68. cJSON *mode = cJSON_GetObjectItemCaseSensitive(item, "mode");
  69. if (!reg || !val) continue;
  70. if (!mode) {
  71. adac_write_byte(i2c_addr, reg->valueint, val->valueint);
  72. } else if (!strcasecmp(mode->valuestring, "or")) {
  73. uint8_t data = adac_read_byte(i2c_addr,reg->valueint);
  74. data |= (uint8_t) val->valueint;
  75. adac_write_byte(i2c_addr, reg->valueint, data);
  76. } else if (!strcasecmp(mode->valuestring, "and")) {
  77. uint8_t data = adac_read_byte(i2c_addr, reg->valueint);
  78. data &= (uint8_t) val->valueint;
  79. adac_write_byte(i2c_addr, reg->valueint, data);
  80. }
  81. }
  82. return true;
  83. }