diff --git a/components/driver/i2c.c b/components/driver/i2c.c index 1199df3ce8..e7bb2e9683 100644 --- a/components/driver/i2c.c +++ b/components/driver/i2c.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -38,8 +38,9 @@ static const char *I2C_TAG = "i2c"; #define I2C_DRIVER_ERR_STR "i2c driver install error" #define I2C_DRIVER_MALLOC_ERR_STR "i2c driver malloc error" +#define I2C_INTR_ALLOC_ERR_STR "i2c interrupt allocation error" #define I2C_NUM_ERROR_STR "i2c number error" -#define I2C_TIMING_VAL_ERR_STR "i2c timing value error" +#define I2C_TIMING_VAL_ERR_STR "i2c timing value error" #define I2C_ADDR_ERROR_STR "i2c null address error" #define I2C_DRIVER_NOT_INSTALL_ERR_STR "i2c driver not installed" #define I2C_SLAVE_BUFFER_LEN_ERR_STR "i2c buffer size too small for slave mode" @@ -243,6 +244,8 @@ esp_err_t i2c_driver_install(i2c_port_t i2c_num, i2c_mode_t mode, size_t slv_rx_ ESP_RETURN_ON_FALSE(i2c_num < I2C_NUM_MAX, ESP_ERR_INVALID_ARG, I2C_TAG, I2C_NUM_ERROR_STR); ESP_RETURN_ON_FALSE(mode == I2C_MODE_MASTER || ( slv_rx_buf_len > 100 || slv_tx_buf_len > 100 ), ESP_ERR_INVALID_ARG, I2C_TAG, I2C_SLAVE_BUFFER_LEN_ERR_STR); + esp_err_t ret = ESP_OK; + if (p_i2c_obj[i2c_num] == NULL) { #if !CONFIG_SPIRAM_USE_MALLOC @@ -346,7 +349,10 @@ esp_err_t i2c_driver_install(i2c_port_t i2c_num, i2c_mode_t mode, size_t slv_rx_ i2c_hal_disable_intr_mask(&(i2c_context[i2c_num].hal), I2C_LL_INTR_MASK); i2c_hal_clr_intsts_mask(&(i2c_context[i2c_num].hal), I2C_LL_INTR_MASK); //hook isr handler - i2c_isr_register(i2c_num, i2c_isr_handler_default, p_i2c_obj[i2c_num], intr_alloc_flags, &p_i2c_obj[i2c_num]->intr_handle); + ret = esp_intr_alloc(i2c_periph_signal[i2c_num].irq, intr_alloc_flags, + i2c_isr_handler_default, p_i2c_obj[i2c_num], + &p_i2c_obj[i2c_num]->intr_handle); + ESP_GOTO_ON_ERROR(ret, err, I2C_TAG, I2C_INTR_ALLOC_ERR_STR); //Enable I2C slave rx interrupt if (mode == I2C_MODE_SLAVE) { i2c_hal_enable_slave_rx_it(&(i2c_context[i2c_num].hal)); @@ -829,19 +835,6 @@ esp_err_t i2c_get_timeout(i2c_port_t i2c_num, int *timeout) return ESP_OK; } -esp_err_t i2c_isr_register(i2c_port_t i2c_num, void (*fn)(void *), void *arg, int intr_alloc_flags, intr_handle_t *handle) -{ - ESP_RETURN_ON_FALSE(i2c_num < I2C_NUM_MAX, ESP_ERR_INVALID_ARG, I2C_TAG, I2C_NUM_ERROR_STR); - ESP_RETURN_ON_FALSE(fn != NULL, ESP_ERR_INVALID_ARG, I2C_TAG, I2C_ADDR_ERROR_STR); - esp_err_t ret = esp_intr_alloc(i2c_periph_signal[i2c_num].irq, intr_alloc_flags, fn, arg, handle); - return ret; -} - -esp_err_t i2c_isr_free(intr_handle_t handle) -{ - return esp_intr_free(handle); -} - esp_err_t i2c_set_pin(i2c_port_t i2c_num, int sda_io_num, int scl_io_num, bool sda_pullup_en, bool scl_pullup_en, i2c_mode_t mode) { ESP_RETURN_ON_FALSE(( i2c_num < I2C_NUM_MAX ), ESP_ERR_INVALID_ARG, I2C_TAG, I2C_NUM_ERROR_STR); diff --git a/components/driver/include/driver/i2c.h b/components/driver/include/driver/i2c.h index 4a6e1e6983..9eec372099 100644 --- a/components/driver/include/driver/i2c.h +++ b/components/driver/include/driver/i2c.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -156,33 +156,6 @@ esp_err_t i2c_reset_tx_fifo(i2c_port_t i2c_num); */ esp_err_t i2c_reset_rx_fifo(i2c_port_t i2c_num); -/** - * @brief Register an I2C ISR handler. - * - * @param i2c_num I2C port number to attach handler to - * @param fn ISR handler function - * @param arg Parameter for the ISR handler - * @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred) - * ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info. - * @param handle Handle return from esp_intr_alloc. - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t i2c_isr_register(i2c_port_t i2c_num, void (*fn)(void *), void *arg, int intr_alloc_flags, intr_handle_t *handle); - -/** - * @brief Delete and free I2C ISR handle. - * - * @param handle Handle of isr to delete. - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t i2c_isr_free(intr_handle_t handle); - /** * @brief Configure GPIO pins for I2C SCK and SDA signals. * diff --git a/components/driver/include/driver/uart.h b/components/driver/include/driver/uart.h index 76aa424fa2..0832b83271 100644 --- a/components/driver/include/driver/uart.h +++ b/components/driver/include/driver/uart.h @@ -351,37 +351,6 @@ esp_err_t uart_disable_tx_intr(uart_port_t uart_num); */ esp_err_t uart_enable_tx_intr(uart_port_t uart_num, int enable, int thresh); -/** - * @brief Register UART interrupt handler (ISR). - * - * @note UART ISR handler will be attached to the same CPU core that this function is running on. - * - * @param uart_num UART port number, the max port number is (UART_NUM_MAX -1). - * @param fn Interrupt handler function. - * @param arg parameter for handler function - * @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred) - * ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info. - * @param handle Pointer to return handle. If non-NULL, a handle for the interrupt will - * be returned here. - * - * @return - * - ESP_OK Success - * - ESP_FAIL Parameter error - */ -esp_err_t uart_isr_register(uart_port_t uart_num, void (*fn)(void*), void * arg, int intr_alloc_flags, uart_isr_handle_t *handle); - -/** - * @brief Free UART interrupt handler registered by uart_isr_register. Must be called on the same core as - * uart_isr_register was called. - * - * @param uart_num UART port number, the max port number is (UART_NUM_MAX -1). - * - * @return - * - ESP_OK Success - * - ESP_FAIL Parameter error - */ -esp_err_t uart_isr_free(uart_port_t uart_num); - /** * @brief Assign signals of a UART peripheral to GPIO pins * diff --git a/components/driver/uart.c b/components/driver/uart.c index cc133237cf..8d9cafe30b 100644 --- a/components/driver/uart.c +++ b/components/driver/uart.c @@ -600,29 +600,6 @@ esp_err_t uart_enable_tx_intr(uart_port_t uart_num, int enable, int thresh) return ESP_OK; } -esp_err_t uart_isr_register(uart_port_t uart_num, void (*fn)(void *), void *arg, int intr_alloc_flags, uart_isr_handle_t *handle) -{ - int ret; - ESP_RETURN_ON_FALSE((uart_num < UART_NUM_MAX), ESP_FAIL, UART_TAG, "uart_num error"); - UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock)); - ret = esp_intr_alloc(uart_periph_signal[uart_num].irq, intr_alloc_flags, fn, arg, handle); - UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock)); - return ret; -} - -esp_err_t uart_isr_free(uart_port_t uart_num) -{ - esp_err_t ret; - ESP_RETURN_ON_FALSE((uart_num < UART_NUM_MAX), ESP_FAIL, UART_TAG, "uart_num error"); - ESP_RETURN_ON_FALSE((p_uart_obj[uart_num]), ESP_FAIL, UART_TAG, "uart driver error"); - ESP_RETURN_ON_FALSE((p_uart_obj[uart_num]->intr_handle != NULL), ESP_ERR_INVALID_ARG, UART_TAG, "uart driver error"); - UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock)); - ret = esp_intr_free(p_uart_obj[uart_num]->intr_handle); - p_uart_obj[uart_num]->intr_handle = NULL; - UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock)); - return ret; -} - static bool uart_try_set_iomux_pin(uart_port_t uart_num, int io_num, uint32_t idx) { /* Store a pointer to the default pin, to optimize access to its fields. */ @@ -1528,7 +1505,7 @@ err: esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_buffer_size, int event_queue_size, QueueHandle_t *uart_queue, int intr_alloc_flags) { - esp_err_t r; + esp_err_t ret; #ifdef CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME ESP_RETURN_ON_FALSE((uart_num != CONFIG_ESP_CONSOLE_UART_NUM), ESP_FAIL, UART_TAG, "UART used by GDB-stubs! Please disable GDB in menuconfig."); #endif // CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME @@ -1593,19 +1570,20 @@ esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_b uart_module_enable(uart_num); uart_hal_disable_intr_mask(&(uart_context[uart_num].hal), UART_LL_INTR_MASK); uart_hal_clr_intsts_mask(&(uart_context[uart_num].hal), UART_LL_INTR_MASK); - r = uart_isr_register(uart_num, uart_rx_intr_handler_default, p_uart_obj[uart_num], intr_alloc_flags, &p_uart_obj[uart_num]->intr_handle); - if (r != ESP_OK) { - goto err; - } - r = uart_intr_config(uart_num, &uart_intr); - if (r != ESP_OK) { - goto err; - } - return r; + + ret = esp_intr_alloc(uart_periph_signal[uart_num].irq, intr_alloc_flags, + uart_rx_intr_handler_default, p_uart_obj[uart_num], + &p_uart_obj[uart_num]->intr_handle); + ESP_GOTO_ON_ERROR(ret, err, UART_TAG, "Could not allocate an interrupt for UART"); + + ret = uart_intr_config(uart_num, &uart_intr); + ESP_GOTO_ON_ERROR(ret, err, UART_TAG, "Could not configure the interrupt for UART"); + + return ret; err: uart_driver_delete(uart_num); - return r; + return ret; } //Make sure no other tasks are still using UART before you call this function diff --git a/docs/en/api-reference/peripherals/i2c.rst b/docs/en/api-reference/peripherals/i2c.rst index 29e95101a3..404e666207 100644 --- a/docs/en/api-reference/peripherals/i2c.rst +++ b/docs/en/api-reference/peripherals/i2c.rst @@ -307,9 +307,7 @@ A code example showing how to use these functions can be found in :example:`peri Interrupt Handling ^^^^^^^^^^^^^^^^^^ -During driver installation, an interrupt handler is installed by default. However, you can register your own interrupt handler instead of the default one by calling the function :cpp:func:`i2c_isr_register`. When implementing your own interrupt handler, refer to *{IDF_TARGET_NAME} Technical Reference Manual* > *I2C Controller (I2C)* > *Interrupts* [`PDF <{IDF_TARGET_TRM_EN_URL}#i2c>`__] for the description of interrupts triggered by the I2C controller. - -To delete an interrupt handler, call :cpp:func:`i2c_isr_free`. +During driver installation, an interrupt handler is installed by default. .. _i2c-api-customized-configuration: diff --git a/docs/en/api-reference/peripherals/uart.rst b/docs/en/api-reference/peripherals/uart.rst index 4b606745f2..806f4f056b 100644 --- a/docs/en/api-reference/peripherals/uart.rst +++ b/docs/en/api-reference/peripherals/uart.rst @@ -223,7 +223,7 @@ Using Interrupts There are many interrupts that can be generated following specific UART states or detected errors. The full list of available interrupts is provided in *{IDF_TARGET_NAME} Technical Reference Manual* > *UART Controller (UART)* > *UART Interrupts* and *UHCI Interrupts* [`PDF <{IDF_TARGET_TRM_EN_URL}#uart>`__]. You can enable or disable specific interrupts by calling :cpp:func:`uart_enable_intr_mask` or :cpp:func:`uart_disable_intr_mask` respectively. The mask of all interrupts is available as :c:macro:`UART_INTR_MASK`. -By default, the :cpp:func:`uart_driver_install` function installs the driver's internal interrupt handler to manage the Tx and Rx ring buffers and provides high-level API functions like events (see below). It is also possible to register a lower level interrupt handler instead using :cpp:func:`uart_isr_register`, and to free it again using :cpp:func:`uart_isr_free`. Some UART driver functions which use the Tx and Rx ring buffers, events, etc. will not automatically work in this case - it is necessary to handle the interrupts directly in the ISR. Inside the custom handler implementation, clear the interrupt status bits using :cpp:func:`uart_clear_intr_status`. +The :cpp:func:`uart_driver_install` function installs the driver's internal interrupt handler to manage the Tx and Rx ring buffers and provides high-level API functions like events (see below). The API provides a convenient way to handle specific interrupts discussed in this document by wrapping them into dedicated functions: diff --git a/docs/en/migration-guides/peripherals.rst b/docs/en/migration-guides/peripherals.rst index 65b9b5cba8..6e4305c3a9 100644 --- a/docs/en/migration-guides/peripherals.rst +++ b/docs/en/migration-guides/peripherals.rst @@ -53,3 +53,13 @@ Breaking Changes in Usage - The driver will install the interrupt service as well if :cpp:member:`on_alarm` is set to a valid callback function. In the callback, user doesn't have to deal with the low level registers (like "clear interrupt status", "re-enable alarm event" and so on). So functions like ``timer_group_get_intr_status_in_isr`` and ``timer_group_get_auto_reload_in_isr`` are not used anymore. - To update the alarm configurations when alarm event happens, one can call :cpp:func:`gptimer_set_alarm_action` in the interrupt callback, then the alarm will be re-enabled again. - Alarm will always be re-enabled by the driver if :cpp:member:`auto_reload_on_alarm` is set to true. + +UART +~~~~ + +- :cpp:member:`uart_isr_register` and :cpp:member:`uart_isr_free` have been removed as the UART interrupt handling is closely related to the driver implementation. + +I2C +~~~~ + +- :cpp:member:`i2c_isr_register` and :cpp:member:`i2c_isr_free` have been removed as the I2C interrupt handling is closely related to the driver implementation. diff --git a/docs/zh_CN/api-reference/peripherals/i2c.rst b/docs/zh_CN/api-reference/peripherals/i2c.rst index a88d8604b9..133f6654ed 100644 --- a/docs/zh_CN/api-reference/peripherals/i2c.rst +++ b/docs/zh_CN/api-reference/peripherals/i2c.rst @@ -307,9 +307,7 @@ API 为从机提供以下功能: 中断处理 ^^^^^^^^^^^ -安装驱动程序时,默认情况下会安装中断处理程序。但是,您可以通过调用函数 :cpp:func:`i2c_isr_register` 来注册自己的而不是默认的中断处理程序。在运行自己的中断处理程序时,可以参考 *{IDF_TARGET_NAME} 技术参考手册* > *I2C 控制器 (I2C)* > *中断* [`PDF <{IDF_TARGET_TRM_CN_URL}#i2c>`__],以获取有关 I2C 控制器触发的中断描述。 - -调用函数 :cpp:func:`i2c_isr_free` 删除中断处理程序。 +安装驱动程序时,默认情况下会安装中断处理程序。 .. _i2c-api-customized-configuration: