adc.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941
  1. /*
  2. * SPDX-FileCopyrightText: 2016-2021 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <esp_types.h>
  7. #include <stdlib.h>
  8. #include <ctype.h>
  9. #include <string.h>
  10. #include "sdkconfig.h"
  11. #include "esp_intr_alloc.h"
  12. #include "esp_log.h"
  13. #include "esp_pm.h"
  14. #include "esp_check.h"
  15. #include "sys/lock.h"
  16. #include "freertos/FreeRTOS.h"
  17. #include "freertos/semphr.h"
  18. #include "freertos/timers.h"
  19. #include "freertos/ringbuf.h"
  20. #include "driver/periph_ctrl.h"
  21. #include "driver/gpio.h"
  22. #include "driver/adc.h"
  23. #include "hal/adc_types.h"
  24. #include "hal/adc_hal.h"
  25. #include "hal/dma_types.h"
  26. //For calibration
  27. #if CONFIG_IDF_TARGET_ESP32S2
  28. #include "esp_efuse_rtc_table.h"
  29. #elif SOC_ADC_CALIBRATION_V1_SUPPORTED
  30. #include "esp_efuse_rtc_calib.h"
  31. #endif
  32. //For DMA
  33. #if SOC_GDMA_SUPPORTED
  34. #include "esp_private/gdma.h"
  35. #elif CONFIG_IDF_TARGET_ESP32S2
  36. #include "hal/spi_types.h"
  37. #include "driver/spi_common_internal.h"
  38. #elif CONFIG_IDF_TARGET_ESP32
  39. #include "driver/i2s.h"
  40. #include "hal/i2s_types.h"
  41. #include "soc/i2s_periph.h"
  42. #include "esp_private/i2s_platform.h"
  43. #endif
  44. static const char *ADC_TAG = "ADC";
  45. #define ADC_GET_IO_NUM(periph, channel) (adc_channel_io_map[periph][channel])
  46. extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate position after the rtc module is finished.
  47. #define ADC_ENTER_CRITICAL() portENTER_CRITICAL(&rtc_spinlock)
  48. #define ADC_EXIT_CRITICAL() portEXIT_CRITICAL(&rtc_spinlock)
  49. /**
  50. * 1. sar_adc1_lock: this mutex lock is to protect the SARADC1 module.
  51. * 2. sar_adc2_lock: this mutex lock is to protect the SARADC2 module.
  52. * 3. adc_reg_lock: this spin lock is to protect the shared registers used by ADC1 / ADC2 single read mode.
  53. */
  54. static _lock_t sar_adc1_lock;
  55. #define SAR_ADC1_LOCK_ACQUIRE() _lock_acquire(&sar_adc1_lock)
  56. #define SAR_ADC1_LOCK_RELEASE() _lock_release(&sar_adc1_lock)
  57. static _lock_t sar_adc2_lock;
  58. #define SAR_ADC2_LOCK_ACQUIRE() _lock_acquire(&sar_adc2_lock)
  59. #define SAR_ADC2_LOCK_RELEASE() _lock_release(&sar_adc2_lock)
  60. portMUX_TYPE adc_reg_lock = portMUX_INITIALIZER_UNLOCKED;
  61. #define ADC_REG_LOCK_ENTER() portENTER_CRITICAL(&adc_reg_lock)
  62. #define ADC_REG_LOCK_EXIT() portEXIT_CRITICAL(&adc_reg_lock)
  63. #define INTERNAL_BUF_NUM 5
  64. /*---------------------------------------------------------------
  65. Digital Controller Context
  66. ---------------------------------------------------------------*/
  67. typedef struct adc_digi_context_t {
  68. uint8_t *rx_dma_buf; //dma buffer
  69. adc_hal_context_t hal; //hal context
  70. #if SOC_GDMA_SUPPORTED
  71. gdma_channel_handle_t rx_dma_channel; //dma rx channel handle
  72. #elif CONFIG_IDF_TARGET_ESP32S2
  73. spi_host_device_t spi_host; //ADC uses this SPI DMA
  74. intr_handle_t intr_hdl; //Interrupt handler
  75. #elif CONFIG_IDF_TARGET_ESP32
  76. i2s_port_t i2s_host; //ADC uses this I2S DMA
  77. intr_handle_t intr_hdl; //Interrupt handler
  78. #endif
  79. RingbufHandle_t ringbuf_hdl; //RX ringbuffer handler
  80. intptr_t rx_eof_desc_addr; //eof descriptor address of RX channel
  81. bool ringbuf_overflow_flag; //1: ringbuffer overflow
  82. bool driver_start_flag; //1: driver is started; 0: driver is stoped
  83. bool use_adc1; //1: ADC unit1 will be used; 0: ADC unit1 won't be used.
  84. bool use_adc2; //1: ADC unit2 will be used; 0: ADC unit2 won't be used. This determines whether to acquire sar_adc2_mutex lock or not.
  85. adc_atten_t adc1_atten; //Attenuation for ADC1. On this chip each ADC can only support one attenuation.
  86. adc_atten_t adc2_atten; //Attenuation for ADC2. On this chip each ADC can only support one attenuation.
  87. adc_hal_digi_ctrlr_cfg_t hal_digi_ctrlr_cfg; //Hal digital controller configuration
  88. esp_pm_lock_handle_t pm_lock; //For power management
  89. } adc_digi_context_t;
  90. static adc_digi_context_t *s_adc_digi_ctx = NULL;
  91. #ifdef CONFIG_PM_ENABLE
  92. //Only for deprecated API
  93. extern esp_pm_lock_handle_t adc_digi_arbiter_lock;
  94. #endif //CONFIG_PM_ENABLE
  95. #if SOC_ADC_CALIBRATION_V1_SUPPORTED
  96. uint32_t adc_get_calibration_offset(adc_ll_num_t adc_n, adc_channel_t chan, adc_atten_t atten);
  97. #endif
  98. /*---------------------------------------------------------------
  99. ADC Continuous Read Mode (via DMA)
  100. ---------------------------------------------------------------*/
  101. //Function to address transaction
  102. static IRAM_ATTR bool s_adc_dma_intr(adc_digi_context_t *adc_digi_ctx);
  103. #if SOC_GDMA_SUPPORTED
  104. static IRAM_ATTR bool adc_dma_in_suc_eof_callback(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data);
  105. #else
  106. static IRAM_ATTR void adc_dma_intr_handler(void *arg);
  107. #endif
  108. static int8_t adc_digi_get_io_num(uint8_t adc_unit, uint8_t adc_channel)
  109. {
  110. return adc_channel_io_map[adc_unit][adc_channel];
  111. }
  112. static esp_err_t adc_digi_gpio_init(adc_unit_t adc_unit, uint16_t channel_mask)
  113. {
  114. esp_err_t ret = ESP_OK;
  115. uint64_t gpio_mask = 0;
  116. uint32_t n = 0;
  117. int8_t io = 0;
  118. while (channel_mask) {
  119. if (channel_mask & 0x1) {
  120. io = adc_digi_get_io_num(adc_unit, n);
  121. if (io < 0) {
  122. return ESP_ERR_INVALID_ARG;
  123. }
  124. gpio_mask |= BIT64(io);
  125. }
  126. channel_mask = channel_mask >> 1;
  127. n++;
  128. }
  129. gpio_config_t cfg = {
  130. .pin_bit_mask = gpio_mask,
  131. .mode = GPIO_MODE_DISABLE,
  132. };
  133. ret = gpio_config(&cfg);
  134. return ret;
  135. }
  136. esp_err_t adc_digi_initialize(const adc_digi_init_config_t *init_config)
  137. {
  138. esp_err_t ret = ESP_OK;
  139. s_adc_digi_ctx = calloc(1, sizeof(adc_digi_context_t));
  140. if (s_adc_digi_ctx == NULL) {
  141. ret = ESP_ERR_NO_MEM;
  142. goto cleanup;
  143. }
  144. //ringbuffer
  145. s_adc_digi_ctx->ringbuf_hdl = xRingbufferCreate(init_config->max_store_buf_size, RINGBUF_TYPE_BYTEBUF);
  146. if (!s_adc_digi_ctx->ringbuf_hdl) {
  147. ret = ESP_ERR_NO_MEM;
  148. goto cleanup;
  149. }
  150. //malloc internal buffer used by DMA
  151. s_adc_digi_ctx->rx_dma_buf = heap_caps_calloc(1, init_config->conv_num_each_intr * INTERNAL_BUF_NUM, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA);
  152. if (!s_adc_digi_ctx->rx_dma_buf) {
  153. ret = ESP_ERR_NO_MEM;
  154. goto cleanup;
  155. }
  156. //malloc dma descriptor
  157. s_adc_digi_ctx->hal.rx_desc = heap_caps_calloc(1, (sizeof(dma_descriptor_t)) * INTERNAL_BUF_NUM, MALLOC_CAP_DMA);
  158. if (!s_adc_digi_ctx->hal.rx_desc) {
  159. ret = ESP_ERR_NO_MEM;
  160. goto cleanup;
  161. }
  162. //malloc pattern table
  163. s_adc_digi_ctx->hal_digi_ctrlr_cfg.adc_pattern = calloc(1, SOC_ADC_PATT_LEN_MAX * sizeof(adc_digi_pattern_config_t));
  164. if (!s_adc_digi_ctx->hal_digi_ctrlr_cfg.adc_pattern) {
  165. ret = ESP_ERR_NO_MEM;
  166. goto cleanup;
  167. }
  168. #if CONFIG_PM_ENABLE
  169. ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "adc_dma", &s_adc_digi_ctx->pm_lock);
  170. if (ret != ESP_OK) {
  171. goto cleanup;
  172. }
  173. #endif //CONFIG_PM_ENABLE
  174. //init gpio pins
  175. if (init_config->adc1_chan_mask) {
  176. ret = adc_digi_gpio_init(ADC_NUM_1, init_config->adc1_chan_mask);
  177. if (ret != ESP_OK) {
  178. goto cleanup;
  179. }
  180. }
  181. if (init_config->adc2_chan_mask) {
  182. ret = adc_digi_gpio_init(ADC_NUM_2, init_config->adc2_chan_mask);
  183. if (ret != ESP_OK) {
  184. goto cleanup;
  185. }
  186. }
  187. #if SOC_GDMA_SUPPORTED
  188. //alloc rx gdma channel
  189. gdma_channel_alloc_config_t rx_alloc_config = {
  190. .direction = GDMA_CHANNEL_DIRECTION_RX,
  191. };
  192. ret = gdma_new_channel(&rx_alloc_config, &s_adc_digi_ctx->rx_dma_channel);
  193. if (ret != ESP_OK) {
  194. goto cleanup;
  195. }
  196. gdma_connect(s_adc_digi_ctx->rx_dma_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_ADC, 0));
  197. gdma_strategy_config_t strategy_config = {
  198. .auto_update_desc = true,
  199. .owner_check = true
  200. };
  201. gdma_apply_strategy(s_adc_digi_ctx->rx_dma_channel, &strategy_config);
  202. gdma_rx_event_callbacks_t cbs = {
  203. .on_recv_eof = adc_dma_in_suc_eof_callback
  204. };
  205. gdma_register_rx_event_callbacks(s_adc_digi_ctx->rx_dma_channel, &cbs, s_adc_digi_ctx);
  206. int dma_chan;
  207. gdma_get_channel_id(s_adc_digi_ctx->rx_dma_channel, &dma_chan);
  208. #elif CONFIG_IDF_TARGET_ESP32S2
  209. //ADC utilises SPI3 DMA on ESP32S2
  210. bool spi_success = false;
  211. uint32_t dma_chan = 0;
  212. spi_success = spicommon_periph_claim(SPI3_HOST, "adc");
  213. ret = spicommon_dma_chan_alloc(SPI3_HOST, SPI_DMA_CH_AUTO, &dma_chan, &dma_chan);
  214. if (ret == ESP_OK) {
  215. s_adc_digi_ctx->spi_host = SPI3_HOST;
  216. }
  217. if (!spi_success || (s_adc_digi_ctx->spi_host != SPI3_HOST)) {
  218. goto cleanup;
  219. }
  220. ret = esp_intr_alloc(spicommon_irqdma_source_for_host(s_adc_digi_ctx->spi_host), 0, adc_dma_intr_handler,
  221. (void *)s_adc_digi_ctx, &s_adc_digi_ctx->intr_hdl);
  222. if (ret != ESP_OK) {
  223. goto cleanup;
  224. }
  225. #elif CONFIG_IDF_TARGET_ESP32
  226. //ADC utilises I2S0 DMA on ESP32
  227. uint32_t dma_chan = 0;
  228. ret = i2s_priv_register_object(&s_adc_digi_ctx, I2S_NUM_0);
  229. if (ret != ESP_OK) {
  230. goto cleanup;
  231. }
  232. s_adc_digi_ctx->i2s_host = I2S_NUM_0;
  233. ret = esp_intr_alloc(i2s_periph_signal[s_adc_digi_ctx->i2s_host].irq, 0, adc_dma_intr_handler,
  234. (void *)s_adc_digi_ctx, &s_adc_digi_ctx->intr_hdl);
  235. if (ret != ESP_OK) {
  236. goto cleanup;
  237. }
  238. #endif
  239. adc_hal_config_t config = {
  240. #if SOC_GDMA_SUPPORTED
  241. .dev = (void *)GDMA_LL_GET_HW(0),
  242. #elif CONFIG_IDF_TARGET_ESP32S2
  243. .dev = (void *)SPI_LL_GET_HW(s_adc_digi_ctx->spi_host),
  244. #elif CONFIG_IDF_TARGET_ESP32
  245. .dev = (void *)I2S_LL_GET_HW(s_adc_digi_ctx->i2s_host),
  246. #endif
  247. .desc_max_num = INTERNAL_BUF_NUM,
  248. .dma_chan = dma_chan,
  249. .eof_num = init_config->conv_num_each_intr / ADC_HAL_DATA_LEN_PER_CONV
  250. };
  251. adc_hal_context_config(&s_adc_digi_ctx->hal, &config);
  252. //enable SARADC module clock
  253. periph_module_enable(PERIPH_SARADC_MODULE);
  254. #if SOC_ADC_CALIBRATION_V1_SUPPORTED
  255. adc_hal_calibration_init(ADC_NUM_1);
  256. adc_hal_calibration_init(ADC_NUM_2);
  257. #endif //#if SOC_ADC_CALIBRATION_V1_SUPPORTED
  258. return ret;
  259. cleanup:
  260. adc_digi_deinitialize();
  261. return ret;
  262. }
  263. #if SOC_GDMA_SUPPORTED
  264. static IRAM_ATTR bool adc_dma_in_suc_eof_callback(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data)
  265. {
  266. assert(event_data);
  267. s_adc_digi_ctx->rx_eof_desc_addr = event_data->rx_eof_desc_addr;
  268. return s_adc_dma_intr(user_data);
  269. }
  270. #else
  271. static IRAM_ATTR void adc_dma_intr_handler(void *arg)
  272. {
  273. adc_digi_context_t *ctx = (adc_digi_context_t *)arg;
  274. bool need_yield = false;
  275. bool conversion_finish = adc_hal_check_event(&ctx->hal, ADC_HAL_DMA_INTR_MASK);
  276. if (conversion_finish) {
  277. adc_hal_digi_clr_intr(&s_adc_digi_ctx->hal, ADC_HAL_DMA_INTR_MASK);
  278. intptr_t desc_addr = adc_hal_get_desc_addr(&ctx->hal);
  279. ctx->rx_eof_desc_addr = desc_addr;
  280. need_yield = s_adc_dma_intr(ctx);
  281. }
  282. if (need_yield) {
  283. portYIELD_FROM_ISR();
  284. }
  285. }
  286. #endif
  287. static IRAM_ATTR bool s_adc_dma_intr(adc_digi_context_t *adc_digi_ctx)
  288. {
  289. portBASE_TYPE taskAwoken = 0;
  290. BaseType_t ret;
  291. adc_hal_dma_desc_status_t status = false;
  292. dma_descriptor_t *current_desc = NULL;
  293. while (1) {
  294. status = adc_hal_get_reading_result(&adc_digi_ctx->hal, adc_digi_ctx->rx_eof_desc_addr, &current_desc);
  295. if (status != ADC_HAL_DMA_DESC_VALID) {
  296. break;
  297. }
  298. ret = xRingbufferSendFromISR(adc_digi_ctx->ringbuf_hdl, current_desc->buffer, current_desc->dw0.length, &taskAwoken);
  299. if (ret == pdFALSE) {
  300. //ringbuffer overflow
  301. adc_digi_ctx->ringbuf_overflow_flag = 1;
  302. }
  303. }
  304. if (status == ADC_HAL_DMA_DESC_NULL) {
  305. //start next turns of dma operation
  306. adc_hal_digi_start(&adc_digi_ctx->hal, adc_digi_ctx->rx_dma_buf);
  307. }
  308. return (taskAwoken == pdTRUE);
  309. }
  310. esp_err_t adc_digi_start(void)
  311. {
  312. if (s_adc_digi_ctx) {
  313. if (s_adc_digi_ctx->driver_start_flag != 0) {
  314. ESP_LOGE(ADC_TAG, "The driver is already started");
  315. return ESP_ERR_INVALID_STATE;
  316. }
  317. adc_power_acquire();
  318. //reset flags
  319. s_adc_digi_ctx->ringbuf_overflow_flag = 0;
  320. s_adc_digi_ctx->driver_start_flag = 1;
  321. if (s_adc_digi_ctx->use_adc1) {
  322. SAR_ADC1_LOCK_ACQUIRE();
  323. }
  324. if (s_adc_digi_ctx->use_adc2) {
  325. SAR_ADC2_LOCK_ACQUIRE();
  326. }
  327. #if CONFIG_PM_ENABLE
  328. // Lock APB frequency while ADC driver is in use
  329. esp_pm_lock_acquire(s_adc_digi_ctx->pm_lock);
  330. #endif
  331. #if SOC_ADC_CALIBRATION_V1_SUPPORTED
  332. if (s_adc_digi_ctx->use_adc1) {
  333. uint32_t cal_val = adc_get_calibration_offset(ADC_NUM_1, ADC_CHANNEL_MAX, s_adc_digi_ctx->adc1_atten);
  334. adc_hal_set_calibration_param(ADC_NUM_1, cal_val);
  335. }
  336. if (s_adc_digi_ctx->use_adc2) {
  337. uint32_t cal_val = adc_get_calibration_offset(ADC_NUM_2, ADC_CHANNEL_MAX, s_adc_digi_ctx->adc2_atten);
  338. adc_hal_set_calibration_param(ADC_NUM_2, cal_val);
  339. }
  340. #endif //#if SOC_ADC_CALIBRATION_V1_SUPPORTED
  341. adc_hal_init();
  342. #if SOC_ADC_ARBITER_SUPPORTED
  343. adc_arbiter_t config = ADC_ARBITER_CONFIG_DEFAULT();
  344. adc_hal_arbiter_config(&config);
  345. #endif //#if SOC_ADC_ARBITER_SUPPORTED
  346. adc_hal_set_controller(ADC_NUM_1, ADC_HAL_CONTINUOUS_READ_MODE);
  347. adc_hal_set_controller(ADC_NUM_2, ADC_HAL_CONTINUOUS_READ_MODE);
  348. adc_hal_digi_init(&s_adc_digi_ctx->hal);
  349. adc_hal_digi_controller_config(&s_adc_digi_ctx->hal, &s_adc_digi_ctx->hal_digi_ctrlr_cfg);
  350. //start conversion
  351. adc_hal_digi_start(&s_adc_digi_ctx->hal, s_adc_digi_ctx->rx_dma_buf);
  352. }
  353. #if CONFIG_IDF_TARGET_ESP32S2
  354. //For being compatible with the deprecated behaviour
  355. else {
  356. ESP_LOGE(ADC_TAG, "API used without driver initialization before. The following behaviour is deprecated!!");
  357. #ifdef CONFIG_PM_ENABLE
  358. ESP_RETURN_ON_FALSE((adc_digi_arbiter_lock), ESP_FAIL, ADC_TAG, "Should start after call `adc_digi_controller_config`");
  359. esp_pm_lock_acquire(adc_digi_arbiter_lock);
  360. #endif
  361. ADC_ENTER_CRITICAL();
  362. adc_ll_digi_dma_enable();
  363. adc_ll_digi_trigger_enable();
  364. ADC_EXIT_CRITICAL();
  365. }
  366. #endif //#if CONFIG_IDF_TARGET_ESP32S2
  367. return ESP_OK;
  368. }
  369. esp_err_t adc_digi_stop(void)
  370. {
  371. if (s_adc_digi_ctx) {
  372. if (s_adc_digi_ctx->driver_start_flag != 1) {
  373. ESP_LOGE(ADC_TAG, "The driver is already stopped");
  374. return ESP_ERR_INVALID_STATE;
  375. }
  376. s_adc_digi_ctx->driver_start_flag = 0;
  377. //disable the in suc eof intrrupt
  378. adc_hal_digi_dis_intr(&s_adc_digi_ctx->hal, ADC_HAL_DMA_INTR_MASK);
  379. //clear the in suc eof interrupt
  380. adc_hal_digi_clr_intr(&s_adc_digi_ctx->hal, ADC_HAL_DMA_INTR_MASK);
  381. //stop ADC
  382. adc_hal_digi_stop(&s_adc_digi_ctx->hal);
  383. adc_hal_digi_deinit(&s_adc_digi_ctx->hal);
  384. #if CONFIG_PM_ENABLE
  385. if (s_adc_digi_ctx->pm_lock) {
  386. esp_pm_lock_release(s_adc_digi_ctx->pm_lock);
  387. }
  388. #endif //CONFIG_PM_ENABLE
  389. if (s_adc_digi_ctx->use_adc1) {
  390. SAR_ADC1_LOCK_RELEASE();
  391. }
  392. if (s_adc_digi_ctx->use_adc2) {
  393. SAR_ADC2_LOCK_RELEASE();
  394. }
  395. adc_power_release();
  396. }
  397. #if CONFIG_IDF_TARGET_ESP32S2
  398. else {
  399. //For being compatible with the deprecated behaviour
  400. ESP_LOGE(ADC_TAG, "API used without driver initialization before. The following behaviour is deprecated!!");
  401. #ifdef CONFIG_PM_ENABLE
  402. if (adc_digi_arbiter_lock) {
  403. esp_pm_lock_release(adc_digi_arbiter_lock);
  404. }
  405. #endif
  406. ADC_ENTER_CRITICAL();
  407. adc_ll_digi_trigger_disable();
  408. adc_ll_digi_dma_disable();
  409. ADC_EXIT_CRITICAL();
  410. }
  411. #endif //#if CONFIG_IDF_TARGET_ESP32S2
  412. return ESP_OK;
  413. }
  414. esp_err_t adc_digi_read_bytes(uint8_t *buf, uint32_t length_max, uint32_t *out_length, uint32_t timeout_ms)
  415. {
  416. TickType_t ticks_to_wait;
  417. esp_err_t ret = ESP_OK;
  418. uint8_t *data = NULL;
  419. size_t size = 0;
  420. ticks_to_wait = timeout_ms / portTICK_RATE_MS;
  421. if (timeout_ms == ADC_MAX_DELAY) {
  422. ticks_to_wait = portMAX_DELAY;
  423. }
  424. data = xRingbufferReceiveUpTo(s_adc_digi_ctx->ringbuf_hdl, &size, ticks_to_wait, length_max);
  425. if (!data) {
  426. ESP_LOGV(ADC_TAG, "No data, increase timeout or reduce conv_num_each_intr");
  427. ret = ESP_ERR_TIMEOUT;
  428. *out_length = 0;
  429. return ret;
  430. }
  431. memcpy(buf, data, size);
  432. vRingbufferReturnItem(s_adc_digi_ctx->ringbuf_hdl, data);
  433. assert((size % 4) == 0);
  434. *out_length = size;
  435. if (s_adc_digi_ctx->ringbuf_overflow_flag) {
  436. ret = ESP_ERR_INVALID_STATE;
  437. }
  438. return ret;
  439. }
  440. esp_err_t adc_digi_deinitialize(void)
  441. {
  442. if (!s_adc_digi_ctx) {
  443. return ESP_ERR_INVALID_STATE;
  444. }
  445. if (s_adc_digi_ctx->driver_start_flag != 0) {
  446. ESP_LOGE(ADC_TAG, "The driver is not stopped");
  447. return ESP_ERR_INVALID_STATE;
  448. }
  449. if (s_adc_digi_ctx->ringbuf_hdl) {
  450. vRingbufferDelete(s_adc_digi_ctx->ringbuf_hdl);
  451. s_adc_digi_ctx->ringbuf_hdl = NULL;
  452. }
  453. #if CONFIG_PM_ENABLE
  454. if (s_adc_digi_ctx->pm_lock) {
  455. esp_pm_lock_delete(s_adc_digi_ctx->pm_lock);
  456. }
  457. #endif //CONFIG_PM_ENABLE
  458. free(s_adc_digi_ctx->rx_dma_buf);
  459. free(s_adc_digi_ctx->hal.rx_desc);
  460. free(s_adc_digi_ctx->hal_digi_ctrlr_cfg.adc_pattern);
  461. #if SOC_GDMA_SUPPORTED
  462. gdma_disconnect(s_adc_digi_ctx->rx_dma_channel);
  463. gdma_del_channel(s_adc_digi_ctx->rx_dma_channel);
  464. #elif CONFIG_IDF_TARGET_ESP32S2
  465. esp_intr_free(s_adc_digi_ctx->intr_hdl);
  466. spicommon_dma_chan_free(s_adc_digi_ctx->spi_host);
  467. spicommon_periph_free(s_adc_digi_ctx->spi_host);
  468. #elif CONFIG_IDF_TARGET_ESP32
  469. esp_intr_free(s_adc_digi_ctx->intr_hdl);
  470. i2s_priv_deregister_object(s_adc_digi_ctx->i2s_host);
  471. #endif
  472. free(s_adc_digi_ctx);
  473. s_adc_digi_ctx = NULL;
  474. periph_module_disable(PERIPH_SARADC_MODULE);
  475. return ESP_OK;
  476. }
  477. /*---------------------------------------------------------------
  478. Digital controller setting
  479. ---------------------------------------------------------------*/
  480. esp_err_t adc_digi_controller_configure(const adc_digi_configuration_t *config)
  481. {
  482. if (!s_adc_digi_ctx) {
  483. return ESP_ERR_INVALID_STATE;
  484. }
  485. //Pattern related check
  486. ESP_RETURN_ON_FALSE(config->pattern_num <= SOC_ADC_PATT_LEN_MAX, ESP_ERR_INVALID_ARG, ADC_TAG, "Max pattern num is %d", SOC_ADC_PATT_LEN_MAX);
  487. #if CONFIG_IDF_TARGET_ESP32
  488. for (int i = 0; i < config->pattern_num; i++) {
  489. ESP_RETURN_ON_FALSE((config->adc_pattern[i].bit_width >= SOC_ADC_DIGI_MIN_BITWIDTH && config->adc_pattern->bit_width <= SOC_ADC_DIGI_MAX_BITWIDTH), ESP_ERR_INVALID_ARG, ADC_TAG, "ADC bitwidth not supported");
  490. ESP_RETURN_ON_FALSE(config->adc_pattern[i].unit == 0, ESP_ERR_INVALID_ARG, ADC_TAG, "Only support using ADC1 DMA mode");
  491. }
  492. #else
  493. for (int i = 0; i < config->pattern_num; i++) {
  494. ESP_RETURN_ON_FALSE((config->adc_pattern[i].bit_width == SOC_ADC_DIGI_MAX_BITWIDTH), ESP_ERR_INVALID_ARG, ADC_TAG, "ADC bitwidth not supported");
  495. }
  496. #endif
  497. ESP_RETURN_ON_FALSE(config->sample_freq_hz <= SOC_ADC_SAMPLE_FREQ_THRES_HIGH && config->sample_freq_hz >= SOC_ADC_SAMPLE_FREQ_THRES_LOW, ESP_ERR_INVALID_ARG, ADC_TAG, "ADC sampling frequency out of range");
  498. #if CONFIG_IDF_TARGET_ESP32
  499. ESP_RETURN_ON_FALSE(config->conv_limit_en == 1, ESP_ERR_INVALID_ARG, ADC_TAG, "`conv_limit_en` should be set to 1");
  500. #endif
  501. #if CONFIG_IDF_TARGET_ESP32
  502. ESP_RETURN_ON_FALSE(config->format == ADC_DIGI_OUTPUT_FORMAT_TYPE1, ESP_ERR_INVALID_ARG, ADC_TAG, "Please use type1");
  503. #elif CONFIG_IDF_TARGET_ESP32S2
  504. if (config->conv_mode == ADC_CONV_BOTH_UNIT || config->conv_mode == ADC_CONV_ALTER_UNIT) {
  505. ESP_RETURN_ON_FALSE(config->format == ADC_DIGI_OUTPUT_FORMAT_TYPE2, ESP_ERR_INVALID_ARG, ADC_TAG, "Please use type2");
  506. } else if (config->conv_mode == ADC_CONV_SINGLE_UNIT_1 || config->conv_mode == ADC_CONV_SINGLE_UNIT_2) {
  507. ESP_RETURN_ON_FALSE(config->format == ADC_DIGI_OUTPUT_FORMAT_TYPE1, ESP_ERR_INVALID_ARG, ADC_TAG, "Please use type1");
  508. }
  509. #else
  510. ESP_RETURN_ON_FALSE(config->format == ADC_DIGI_OUTPUT_FORMAT_TYPE2, ESP_ERR_INVALID_ARG, ADC_TAG, "Please use type2");
  511. #endif
  512. s_adc_digi_ctx->hal_digi_ctrlr_cfg.conv_limit_en = config->conv_limit_en;
  513. s_adc_digi_ctx->hal_digi_ctrlr_cfg.conv_limit_num = config->conv_limit_num;
  514. s_adc_digi_ctx->hal_digi_ctrlr_cfg.adc_pattern_len = config->pattern_num;
  515. s_adc_digi_ctx->hal_digi_ctrlr_cfg.sample_freq_hz = config->sample_freq_hz;
  516. s_adc_digi_ctx->hal_digi_ctrlr_cfg.conv_mode = config->conv_mode;
  517. memcpy(s_adc_digi_ctx->hal_digi_ctrlr_cfg.adc_pattern, config->adc_pattern, config->pattern_num * sizeof(adc_digi_pattern_config_t));
  518. const int atten_uninitialized = 999;
  519. s_adc_digi_ctx->adc1_atten = atten_uninitialized;
  520. s_adc_digi_ctx->adc2_atten = atten_uninitialized;
  521. s_adc_digi_ctx->use_adc1 = 0;
  522. s_adc_digi_ctx->use_adc2 = 0;
  523. for (int i = 0; i < config->pattern_num; i++) {
  524. const adc_digi_pattern_config_t *pat = &config->adc_pattern[i];
  525. if (pat->unit == ADC_NUM_1) {
  526. s_adc_digi_ctx->use_adc1 = 1;
  527. if (s_adc_digi_ctx->adc1_atten == atten_uninitialized) {
  528. s_adc_digi_ctx->adc1_atten = pat->atten;
  529. } else if (s_adc_digi_ctx->adc1_atten != pat->atten) {
  530. return ESP_ERR_INVALID_ARG;
  531. }
  532. } else if (pat->unit == ADC_NUM_2) {
  533. //See whether ADC2 will be used or not. If yes, the ``sar_adc2_mutex`` should be acquired in the continuous read driver
  534. s_adc_digi_ctx->use_adc2 = 1;
  535. if (s_adc_digi_ctx->adc2_atten == atten_uninitialized) {
  536. s_adc_digi_ctx->adc2_atten = pat->atten;
  537. } else if (s_adc_digi_ctx->adc2_atten != pat->atten) {
  538. return ESP_ERR_INVALID_ARG;
  539. }
  540. }
  541. }
  542. return ESP_OK;
  543. }
  544. #if CONFIG_IDF_TARGET_ESP32C3
  545. /*---------------------------------------------------------------
  546. ADC Single Read Mode
  547. ---------------------------------------------------------------*/
  548. static adc_atten_t s_atten1_single[ADC1_CHANNEL_MAX]; //Array saving attenuate of each channel of ADC1, used by single read API
  549. static adc_atten_t s_atten2_single[ADC2_CHANNEL_MAX]; //Array saving attenuate of each channel of ADC2, used by single read API
  550. esp_err_t adc_vref_to_gpio(adc_unit_t adc_unit, gpio_num_t gpio)
  551. {
  552. esp_err_t ret;
  553. uint32_t channel = ADC2_CHANNEL_MAX;
  554. if (adc_unit == ADC_UNIT_2) {
  555. for (int i = 0; i < ADC2_CHANNEL_MAX; i++) {
  556. if (gpio == ADC_GET_IO_NUM(ADC_NUM_2, i)) {
  557. channel = i;
  558. break;
  559. }
  560. }
  561. if (channel == ADC2_CHANNEL_MAX) {
  562. return ESP_ERR_INVALID_ARG;
  563. }
  564. }
  565. adc_power_acquire();
  566. if (adc_unit & ADC_UNIT_1) {
  567. ADC_ENTER_CRITICAL();
  568. adc_hal_vref_output(ADC_NUM_1, channel, true);
  569. ADC_EXIT_CRITICAL();
  570. } else if (adc_unit & ADC_UNIT_2) {
  571. ADC_ENTER_CRITICAL();
  572. adc_hal_vref_output(ADC_NUM_2, channel, true);
  573. ADC_EXIT_CRITICAL();
  574. }
  575. ret = adc_digi_gpio_init(ADC_NUM_2, BIT(channel));
  576. return ret;
  577. }
  578. esp_err_t adc1_config_width(adc_bits_width_t width_bit)
  579. {
  580. //On ESP32C3, the data width is always 12-bits.
  581. if (width_bit != ADC_WIDTH_BIT_12) {
  582. return ESP_ERR_INVALID_ARG;
  583. }
  584. return ESP_OK;
  585. }
  586. esp_err_t adc1_config_channel_atten(adc1_channel_t channel, adc_atten_t atten)
  587. {
  588. ESP_RETURN_ON_FALSE(channel < SOC_ADC_CHANNEL_NUM(ADC_NUM_1), ESP_ERR_INVALID_ARG, ADC_TAG, "ADC1 channel error");
  589. ESP_RETURN_ON_FALSE((atten < ADC_ATTEN_MAX), ESP_ERR_INVALID_ARG, ADC_TAG, "ADC Atten Err");
  590. esp_err_t ret = ESP_OK;
  591. s_atten1_single[channel] = atten;
  592. ret = adc_digi_gpio_init(ADC_NUM_1, BIT(channel));
  593. adc_hal_calibration_init(ADC_NUM_1);
  594. return ret;
  595. }
  596. int adc1_get_raw(adc1_channel_t channel)
  597. {
  598. int raw_out = 0;
  599. periph_module_enable(PERIPH_SARADC_MODULE);
  600. adc_power_acquire();
  601. SAR_ADC1_LOCK_ACQUIRE();
  602. adc_atten_t atten = s_atten1_single[channel];
  603. uint32_t cal_val = adc_get_calibration_offset(ADC_NUM_1, channel, atten);
  604. adc_hal_set_calibration_param(ADC_NUM_1, cal_val);
  605. ADC_REG_LOCK_ENTER();
  606. adc_hal_set_atten(ADC_NUM_2, channel, atten);
  607. adc_hal_convert(ADC_NUM_1, channel, &raw_out);
  608. ADC_REG_LOCK_EXIT();
  609. SAR_ADC1_LOCK_RELEASE();
  610. adc_power_release();
  611. periph_module_disable(PERIPH_SARADC_MODULE);
  612. return raw_out;
  613. }
  614. esp_err_t adc2_config_channel_atten(adc2_channel_t channel, adc_atten_t atten)
  615. {
  616. ESP_RETURN_ON_FALSE(channel < SOC_ADC_CHANNEL_NUM(ADC_NUM_2), ESP_ERR_INVALID_ARG, ADC_TAG, "ADC2 channel error");
  617. ESP_RETURN_ON_FALSE((atten <= ADC_ATTEN_11db), ESP_ERR_INVALID_ARG, ADC_TAG, "ADC2 Atten Err");
  618. esp_err_t ret = ESP_OK;
  619. s_atten2_single[channel] = atten;
  620. ret = adc_digi_gpio_init(ADC_NUM_2, BIT(channel));
  621. adc_hal_calibration_init(ADC_NUM_2);
  622. return ret;
  623. }
  624. esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *raw_out)
  625. {
  626. //On ESP32C3, the data width is always 12-bits.
  627. if (width_bit != ADC_WIDTH_BIT_12) {
  628. return ESP_ERR_INVALID_ARG;
  629. }
  630. esp_err_t ret = ESP_OK;
  631. periph_module_enable(PERIPH_SARADC_MODULE);
  632. adc_power_acquire();
  633. SAR_ADC2_LOCK_ACQUIRE();
  634. adc_arbiter_t config = ADC_ARBITER_CONFIG_DEFAULT();
  635. adc_hal_arbiter_config(&config);
  636. adc_atten_t atten = s_atten2_single[channel];
  637. uint32_t cal_val = adc_get_calibration_offset(ADC_NUM_2, channel, atten);
  638. adc_hal_set_calibration_param(ADC_NUM_2, cal_val);
  639. ADC_REG_LOCK_ENTER();
  640. adc_hal_set_atten(ADC_NUM_2, channel, atten);
  641. ret = adc_hal_convert(ADC_NUM_2, channel, raw_out);
  642. ADC_REG_LOCK_EXIT();
  643. SAR_ADC2_LOCK_RELEASE();
  644. adc_power_release();
  645. periph_module_disable(PERIPH_SARADC_MODULE);
  646. return ret;
  647. }
  648. /*************************************/
  649. /* Digital controller filter setting */
  650. /*************************************/
  651. esp_err_t adc_digi_filter_reset(adc_digi_filter_idx_t idx)
  652. {
  653. ADC_ENTER_CRITICAL();
  654. adc_hal_digi_filter_reset(idx);
  655. ADC_EXIT_CRITICAL();
  656. return ESP_OK;
  657. }
  658. esp_err_t adc_digi_filter_set_config(adc_digi_filter_idx_t idx, adc_digi_filter_t *config)
  659. {
  660. ADC_ENTER_CRITICAL();
  661. adc_hal_digi_filter_set_factor(idx, config);
  662. ADC_EXIT_CRITICAL();
  663. return ESP_OK;
  664. }
  665. esp_err_t adc_digi_filter_get_config(adc_digi_filter_idx_t idx, adc_digi_filter_t *config)
  666. {
  667. ADC_ENTER_CRITICAL();
  668. adc_hal_digi_filter_get_factor(idx, config);
  669. ADC_EXIT_CRITICAL();
  670. return ESP_OK;
  671. }
  672. esp_err_t adc_digi_filter_enable(adc_digi_filter_idx_t idx, bool enable)
  673. {
  674. ADC_ENTER_CRITICAL();
  675. adc_hal_digi_filter_enable(idx, enable);
  676. ADC_EXIT_CRITICAL();
  677. return ESP_OK;
  678. }
  679. /**************************************/
  680. /* Digital controller monitor setting */
  681. /**************************************/
  682. esp_err_t adc_digi_monitor_set_config(adc_digi_monitor_idx_t idx, adc_digi_monitor_t *config)
  683. {
  684. ADC_ENTER_CRITICAL();
  685. adc_hal_digi_monitor_config(idx, config);
  686. ADC_EXIT_CRITICAL();
  687. return ESP_OK;
  688. }
  689. esp_err_t adc_digi_monitor_enable(adc_digi_monitor_idx_t idx, bool enable)
  690. {
  691. ADC_ENTER_CRITICAL();
  692. adc_hal_digi_monitor_enable(idx, enable);
  693. ADC_EXIT_CRITICAL();
  694. return ESP_OK;
  695. }
  696. #endif //#if CONFIG_IDF_TARGET_ESP32C3
  697. #if SOC_ADC_CALIBRATION_V1_SUPPORTED
  698. /*---------------------------------------------------------------
  699. Hardware Calibration Setting
  700. ---------------------------------------------------------------*/
  701. #if CONFIG_IDF_TARGET_ESP32S2
  702. #define esp_efuse_rtc_calib_get_ver() esp_efuse_rtc_table_read_calib_version()
  703. static inline uint32_t esp_efuse_rtc_calib_get_init_code(int version, uint32_t adc_unit, int atten)
  704. {
  705. int tag = esp_efuse_rtc_table_get_tag(version, adc_unit + 1, atten, RTCCALIB_V2_PARAM_VINIT);
  706. return esp_efuse_rtc_table_get_parsed_efuse_value(tag, false);
  707. }
  708. #endif
  709. static uint16_t s_adc_cali_param[SOC_ADC_PERIPH_NUM][ADC_ATTEN_MAX] = {};
  710. //NOTE: according to calibration version, different types of lock may be taken during the process:
  711. // 1. Semaphore when reading efuse
  712. // 2. Lock (Spinlock, or Mutex) if we actually do ADC calibration in the future
  713. //This function shoudn't be called inside critical section or ISR
  714. uint32_t adc_get_calibration_offset(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten)
  715. {
  716. if (s_adc_cali_param[adc_n][atten]) {
  717. ESP_LOGV(ADC_TAG, "Use calibrated val ADC%d atten=%d: %04X", adc_n, atten, s_adc_cali_param[adc_n][atten]);
  718. return (uint32_t)s_adc_cali_param[adc_n][atten];
  719. }
  720. // check if we can fetch the values from eFuse.
  721. int version = esp_efuse_rtc_calib_get_ver();
  722. uint32_t init_code = 0;
  723. if (version == ESP_EFUSE_ADC_CALIB_VER) {
  724. init_code = esp_efuse_rtc_calib_get_init_code(version, adc_n, atten);
  725. } else {
  726. ESP_LOGD(ADC_TAG, "Calibration eFuse is not configured, use self-calibration for ICode");
  727. adc_power_acquire();
  728. ADC_ENTER_CRITICAL();
  729. const bool internal_gnd = true;
  730. init_code = adc_hal_self_calibration(adc_n, channel, atten, internal_gnd);
  731. ADC_EXIT_CRITICAL();
  732. adc_power_release();
  733. }
  734. s_adc_cali_param[adc_n][atten] = init_code;
  735. ESP_LOGV(ADC_TAG, "Calib(V%d) ADC%d atten=%d: %04X", version, adc_n, atten, init_code);
  736. return init_code;
  737. }
  738. // Internal function to calibrate PWDET for WiFi
  739. esp_err_t adc_cal_offset(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten)
  740. {
  741. adc_hal_calibration_init(adc_n);
  742. uint32_t cal_val = adc_get_calibration_offset(adc_n, channel, atten);
  743. ADC_ENTER_CRITICAL();
  744. adc_hal_set_calibration_param(adc_n, cal_val);
  745. ADC_EXIT_CRITICAL();
  746. return ESP_OK;
  747. }
  748. #endif //#if SOC_ADC_CALIBRATION_V1_SUPPORTED
  749. /*---------------------------------------------------------------
  750. Deprecated API
  751. ---------------------------------------------------------------*/
  752. #if CONFIG_IDF_TARGET_ESP32C3
  753. #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
  754. #include "driver/adc_deprecated.h"
  755. #include "driver/adc_types_deprecated.h"
  756. esp_err_t adc_digi_controller_config(const adc_digi_config_t *config)
  757. {
  758. if (!s_adc_digi_ctx) {
  759. return ESP_ERR_INVALID_STATE;
  760. }
  761. ESP_RETURN_ON_FALSE((config->sample_freq_hz <= SOC_ADC_SAMPLE_FREQ_THRES_HIGH && config->sample_freq_hz >= SOC_ADC_SAMPLE_FREQ_THRES_LOW), ESP_ERR_INVALID_ARG, ADC_TAG, "DC sampling frequency out of range");
  762. s_adc_digi_ctx->hal_digi_ctrlr_cfg.conv_limit_en = config->conv_limit_en;
  763. s_adc_digi_ctx->hal_digi_ctrlr_cfg.conv_limit_num = config->conv_limit_num;
  764. s_adc_digi_ctx->hal_digi_ctrlr_cfg.adc_pattern_len = config->adc_pattern_len;
  765. s_adc_digi_ctx->hal_digi_ctrlr_cfg.sample_freq_hz = config->sample_freq_hz;
  766. for (int i = 0; i < config->adc_pattern_len; i++) {
  767. s_adc_digi_ctx->hal_digi_ctrlr_cfg.adc_pattern[i].atten = config->adc_pattern[i].atten;
  768. s_adc_digi_ctx->hal_digi_ctrlr_cfg.adc_pattern[i].channel = config->adc_pattern[i].channel;
  769. s_adc_digi_ctx->hal_digi_ctrlr_cfg.adc_pattern[i].unit = config->adc_pattern[i].unit;
  770. }
  771. const int atten_uninitialized = 999;
  772. s_adc_digi_ctx->adc1_atten = atten_uninitialized;
  773. s_adc_digi_ctx->adc2_atten = atten_uninitialized;
  774. s_adc_digi_ctx->use_adc1 = 0;
  775. s_adc_digi_ctx->use_adc2 = 0;
  776. for (int i = 0; i < config->adc_pattern_len; i++) {
  777. const adc_digi_pattern_config_t *pat = &s_adc_digi_ctx->hal_digi_ctrlr_cfg.adc_pattern[i];
  778. if (pat->unit == ADC_NUM_1) {
  779. s_adc_digi_ctx->use_adc1 = 1;
  780. if (s_adc_digi_ctx->adc1_atten == atten_uninitialized) {
  781. s_adc_digi_ctx->adc1_atten = pat->atten;
  782. } else if (s_adc_digi_ctx->adc1_atten != pat->atten) {
  783. return ESP_ERR_INVALID_ARG;
  784. }
  785. } else if (pat->unit == ADC_NUM_2) {
  786. //See whether ADC2 will be used or not. If yes, the ``sar_adc2_mutex`` should be acquired in the continuous read driver
  787. s_adc_digi_ctx->use_adc2 = 1;
  788. if (s_adc_digi_ctx->adc2_atten == atten_uninitialized) {
  789. s_adc_digi_ctx->adc2_atten = pat->atten;
  790. } else if (s_adc_digi_ctx->adc2_atten != pat->atten) {
  791. return ESP_ERR_INVALID_ARG;
  792. }
  793. }
  794. }
  795. return ESP_OK;
  796. }
  797. #endif //#if CONFIG_IDF_TARGET_ESP32C3