i2s_platform.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. /*
  2. * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include "esp_check.h"
  7. #include "i2s_private.h"
  8. static const char *TAG = "i2s_platform";
  9. /**
  10. * @brief Global i2s platform object
  11. * @note For saving all the I2S related information
  12. */
  13. i2s_platform_t g_i2s = {
  14. .spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED,
  15. .controller[0 ... (SOC_I2S_NUM - 1)] = NULL, // groups will be lazy installed
  16. .comp_name[0 ... (SOC_I2S_NUM - 1)] = NULL,
  17. };
  18. /*---------------------------------------------------------------------------
  19. I2S Platform APIs
  20. ----------------------------------------------------------------------------
  21. Scope: This file and ADC/DAC/LCD driver
  22. ----------------------------------------------------------------------------*/
  23. esp_err_t i2s_platform_acquire_occupation(int id, const char *comp_name)
  24. {
  25. esp_err_t ret = ESP_OK;
  26. const char *occupied_comp = NULL;
  27. ESP_RETURN_ON_FALSE(id < SOC_I2S_NUM, ESP_ERR_INVALID_ARG, TAG, "invalid i2s port id");
  28. portENTER_CRITICAL(&g_i2s.spinlock);
  29. if ((!g_i2s.controller[id]) && (g_i2s.comp_name[id] == NULL)) {
  30. g_i2s.comp_name[id] = comp_name;
  31. /* Enable module clock */
  32. I2S_RCC_ATOMIC() {
  33. i2s_ll_enable_bus_clock(id, true);
  34. i2s_ll_reset_register(id);
  35. i2s_ll_enable_core_clock(I2S_LL_GET_HW(id), true);
  36. }
  37. } else {
  38. occupied_comp = g_i2s.comp_name[id];
  39. ret = ESP_ERR_NOT_FOUND;
  40. }
  41. portEXIT_CRITICAL(&g_i2s.spinlock);
  42. if (occupied_comp != NULL) {
  43. ESP_LOGW(TAG, "i2s controller %d has been occupied by %s", id, occupied_comp);
  44. }
  45. return ret;
  46. }
  47. esp_err_t i2s_platform_release_occupation(int id)
  48. {
  49. esp_err_t ret = ESP_OK;
  50. ESP_RETURN_ON_FALSE(id < SOC_I2S_NUM, ESP_ERR_INVALID_ARG, TAG, "invalid i2s port id");
  51. portENTER_CRITICAL(&g_i2s.spinlock);
  52. if (!g_i2s.controller[id]) {
  53. g_i2s.comp_name[id] = NULL;
  54. /* Disable module clock */
  55. I2S_RCC_ATOMIC() {
  56. i2s_ll_enable_bus_clock(id, false);
  57. i2s_ll_enable_core_clock(I2S_LL_GET_HW(id), false);
  58. }
  59. } else {
  60. ret = ESP_ERR_INVALID_STATE;
  61. }
  62. portEXIT_CRITICAL(&g_i2s.spinlock);
  63. return ret;
  64. }
  65. // Only used in `test_i2s_iram.c` to write DMA buffer directly
  66. size_t i2s_platform_get_dma_buffer_offset(void)
  67. {
  68. /* Force to transfer address '0' into 'i2s_chan_handle_t' type,
  69. * then find the corresponding field , the address of this field is the offset of this type */
  70. return (size_t)&(((i2s_chan_handle_t)0)->dma.bufs);
  71. }