Merge branch 'breaking/remove_custom_uart_isr' into 'master'

UART & I2C: remove custom ISR registration function

See merge request espressif/esp-idf!16798
This commit is contained in:
Omar Chebib 2022-01-26 03:54:14 +00:00
commit 08b1d7544b
8 changed files with 35 additions and 116 deletions

View File

@ -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);

View File

@ -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.
*

View File

@ -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
*

View File

@ -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

View File

@ -303,9 +303,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:

View File

@ -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:

View File

@ -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.

View File

@ -303,9 +303,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: