dac_common.c 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /*
  2. * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <stdint.h>
  7. #include <string.h>
  8. #include "freertos/FreeRTOS.h"
  9. #include "soc/soc_caps.h"
  10. #include "soc/dac_periph.h"
  11. #include "hal/dac_types.h"
  12. #include "hal/dac_ll.h"
  13. #include "driver/rtc_io.h"
  14. #include "esp_check.h"
  15. #include "dac_priv_common.h"
  16. typedef struct {
  17. bool in_use;
  18. bool is_enabled;
  19. const char *mode;
  20. } dac_channel_info_t;
  21. static dac_channel_info_t s_dac_chan[SOC_DAC_CHAN_NUM] = {
  22. [0 ... SOC_DAC_CHAN_NUM - 1] = {
  23. .in_use = false,
  24. .is_enabled = false,
  25. .mode = NULL,
  26. }
  27. };
  28. /* Global dac spin lock for the whole DAC driver */
  29. portMUX_TYPE dac_spinlock = portMUX_INITIALIZER_UNLOCKED;
  30. static const char *TAG = "dac_common";
  31. esp_err_t dac_priv_register_channel(dac_channel_t chan_id, const char *mode_name)
  32. {
  33. ESP_RETURN_ON_FALSE(chan_id < SOC_DAC_CHAN_NUM, ESP_ERR_INVALID_ARG, TAG, "channel id is invalid");
  34. DAC_NULL_POINTER_CHECK(mode_name);
  35. esp_err_t ret = ESP_OK;
  36. if (!s_dac_chan[chan_id].in_use) {
  37. s_dac_chan[chan_id].in_use = true;
  38. s_dac_chan[chan_id].mode = mode_name;
  39. } else {
  40. ret = ESP_ERR_INVALID_STATE;
  41. }
  42. if (ret != ESP_OK) {
  43. ESP_LOGE(TAG, "dac channel %d has been registered by %s", chan_id, s_dac_chan[chan_id].mode);
  44. }
  45. return ret;
  46. }
  47. esp_err_t dac_priv_deregister_channel(dac_channel_t chan_id)
  48. {
  49. ESP_RETURN_ON_FALSE(chan_id < SOC_DAC_CHAN_NUM, ESP_ERR_INVALID_ARG, TAG, "channel id is invalid");
  50. ESP_RETURN_ON_FALSE(!s_dac_chan[chan_id].is_enabled, ESP_ERR_INVALID_STATE, TAG, "the channel is still enabled");
  51. esp_err_t ret = ESP_OK;
  52. if (s_dac_chan[chan_id].in_use) {
  53. s_dac_chan[chan_id].in_use = false;
  54. s_dac_chan[chan_id].mode = NULL;
  55. } else {
  56. ret = ESP_ERR_INVALID_STATE;
  57. }
  58. return ret;
  59. }
  60. esp_err_t dac_priv_enable_channel(dac_channel_t chan_id)
  61. {
  62. ESP_RETURN_ON_FALSE(chan_id < SOC_DAC_CHAN_NUM, ESP_ERR_INVALID_ARG, TAG, "channel id is invalid");
  63. ESP_RETURN_ON_FALSE(s_dac_chan[chan_id].in_use, ESP_ERR_INVALID_STATE, TAG, "the channel is not registered");
  64. gpio_num_t gpio_num = (gpio_num_t)dac_periph_signal.dac_channel_io_num[chan_id];
  65. rtc_gpio_init(gpio_num);
  66. rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_DISABLED);
  67. rtc_gpio_pullup_dis(gpio_num);
  68. rtc_gpio_pulldown_dis(gpio_num);
  69. DAC_RTC_ENTER_CRITICAL();
  70. dac_ll_power_on(chan_id);
  71. dac_ll_rtc_sync_by_adc(false);
  72. DAC_RTC_EXIT_CRITICAL();
  73. s_dac_chan[chan_id].is_enabled = true;
  74. return ESP_OK;
  75. }
  76. esp_err_t dac_priv_disable_channel(dac_channel_t chan_id)
  77. {
  78. ESP_RETURN_ON_FALSE(chan_id < SOC_DAC_CHAN_NUM, ESP_ERR_INVALID_ARG, TAG, "channel id is invalid");
  79. ESP_RETURN_ON_FALSE(s_dac_chan[chan_id].in_use, ESP_ERR_INVALID_STATE, TAG, "the channel is not registered");
  80. gpio_num_t gpio_num = (gpio_num_t)dac_periph_signal.dac_channel_io_num[chan_id];
  81. rtc_gpio_deinit(gpio_num);
  82. DAC_RTC_ENTER_CRITICAL();
  83. dac_ll_power_down(chan_id);
  84. DAC_RTC_EXIT_CRITICAL();
  85. s_dac_chan[chan_id].is_enabled = false;
  86. return ESP_OK;
  87. }