Explorar el Código

freemodbus: fix timer port to use esp_timer instead of group timer

aleks hace 4 años
padre
commit
ee104f8de2

+ 5 - 35
components/freemodbus/Kconfig

@@ -193,44 +193,14 @@ menu "Modbus configuration"
                 If this option is set the Modbus stack uses timer for T3.5 time measurement.
                 If this option is set the Modbus stack uses timer for T3.5 time measurement.
                 Else the internal UART TOUT timeout is used for 3.5T symbol time measurement.
                 Else the internal UART TOUT timeout is used for 3.5T symbol time measurement.
 
 
-    config FMB_TIMER_GROUP
-        int "Slave Timer group number"
-        range 0 1
-        default 0
-        help
-                Modbus slave Timer group number that is used for timeout measurement.
-
-    config FMB_TIMER_INDEX
-        int "Slave Timer index in the group"
-        range 0 1
-        default 0
-        help
-                Modbus slave Timer Index in the group that is used for timeout measurement.
-
-    config FMB_MASTER_TIMER_GROUP
-        int "Master Timer group number"
-        range 0 1
-        default FMB_TIMER_GROUP
-        help
-                Modbus master Timer group number that is used for timeout measurement.
-
-    config FMB_MASTER_TIMER_INDEX
-        int "Master Timer index"
-        range 0 1
-        default FMB_TIMER_INDEX
-        help
-                Modbus master Timer Index in the group that is used for timeout measurement.
-                Note: Modbus master and slave should have different timer index to be able to work simultaneously.
-
-    config FMB_TIMER_ISR_IN_IRAM
-        bool "Place timer interrupt handler into IRAM"
+    config FMB_TIMER_USE_ISR_DISPATCH_METHOD
+        bool "Modbus timer uses ISR dispatch method"
         default n
         default n
+        select ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD
         select UART_ISR_IN_IRAM
         select UART_ISR_IN_IRAM
         help
         help
-                This option places Modbus timer IRQ handler into IRAM.
-                This allows to avoid delays related to processing of non-IRAM-safe interrupts
-                during a flash write operation (NVS updating a value, or some other
-                flash API which has to perform an read/write operation and disable CPU cache).
+                If this option is set the Modbus stack uses ISR dispatch method
+                to send timeout events from the callback function called from ISR.
                 This option has dependency with the UART_ISR_IN_IRAM option which places UART interrupt
                 This option has dependency with the UART_ISR_IN_IRAM option which places UART interrupt
                 handler into IRAM to prevent delays related to processing of UART events.
                 handler into IRAM to prevent delays related to processing of UART events.
 
 

+ 8 - 0
components/freemodbus/port/port.h

@@ -40,6 +40,7 @@
 
 
 #include "freertos/FreeRTOS.h"
 #include "freertos/FreeRTOS.h"
 #include "esp_log.h"                // for ESP_LOGE macro
 #include "esp_log.h"                // for ESP_LOGE macro
+#include "esp_timer.h"
 #include "mbconfig.h"
 #include "mbconfig.h"
 
 
 #define INLINE                      inline
 #define INLINE                      inline
@@ -87,6 +88,7 @@
 
 
 // Define number of timer reloads per 1 mS
 // Define number of timer reloads per 1 mS
 #define MB_TIMER_TICS_PER_MS            (20UL)
 #define MB_TIMER_TICS_PER_MS            (20UL)
+#define MB_TIMER_TICK_TIME_US           (1000 / MB_TIMER_TICS_PER_MS) // 50uS = one discreet for timer
 
 
 #define MB_TCP_DEBUG                    (LOG_LOCAL_LEVEL >= ESP_LOG_DEBUG) // Enable legacy debug output in TCP module.
 #define MB_TCP_DEBUG                    (LOG_LOCAL_LEVEL >= ESP_LOG_DEBUG) // Enable legacy debug output in TCP module.
 
 
@@ -142,6 +144,12 @@ typedef enum {
     MB_PORT_IPV6 = 1                      /*!< TCP IPV6 addressing */
     MB_PORT_IPV6 = 1                      /*!< TCP IPV6 addressing */
 } eMBPortIpVer;
 } eMBPortIpVer;
 
 
+typedef struct {
+    esp_timer_handle_t xTimerIntHandle;
+    USHORT usT35Ticks;
+    BOOL xTimerState;
+} xTimerContext_t;
+
 void vMBPortEnterCritical(void);
 void vMBPortEnterCritical(void);
 void vMBPortExitCritical(void);
 void vMBPortExitCritical(void);
 
 

+ 5 - 0
components/freemodbus/port/portserial_m.c

@@ -85,9 +85,14 @@ static USHORT usMBMasterPortSerialRxPoll(size_t xEventSize)
             // Call the Modbus stack callback function and let it fill the stack buffers.
             // Call the Modbus stack callback function and let it fill the stack buffers.
             xReadStatus = pxMBMasterFrameCBByteReceived(); // callback to receive FSM
             xReadStatus = pxMBMasterFrameCBByteReceived(); // callback to receive FSM
         }
         }
+
         // The buffer is transferred into Modbus stack and is not needed here any more
         // The buffer is transferred into Modbus stack and is not needed here any more
         uart_flush_input(ucUartNumber);
         uart_flush_input(ucUartNumber);
         ESP_LOGD(TAG, "Received data: %d(bytes in buffer)\n", (uint32_t)usCnt);
         ESP_LOGD(TAG, "Received data: %d(bytes in buffer)\n", (uint32_t)usCnt);
+#if !CONFIG_FMB_TIMER_PORT_ENABLED
+        vMBMasterSetCurTimerMode(MB_TMODE_T35);
+        pxMBMasterPortCBTimerExpired();
+#endif
     } else {
     } else {
         ESP_LOGE(TAG, "%s: bRxState disabled but junk data (%d bytes) received. ", __func__, xEventSize);
         ESP_LOGE(TAG, "%s: bRxState disabled but junk data (%d bytes) received. ", __func__, xEventSize);
     }
     }

+ 49 - 69
components/freemodbus/port/porttimer.c

@@ -38,77 +38,54 @@
 #include "port.h"
 #include "port.h"
 
 
 /* ----------------------- Modbus includes ----------------------------------*/
 /* ----------------------- Modbus includes ----------------------------------*/
-#include "sdkconfig.h"
 #include "mb.h"
 #include "mb.h"
 #include "mbport.h"
 #include "mbport.h"
-#include "driver/timer.h"
-#include "port_serial_slave.h"
 #include "sdkconfig.h"
 #include "sdkconfig.h"
 
 
 #if CONFIG_FMB_TIMER_PORT_ENABLED
 #if CONFIG_FMB_TIMER_PORT_ENABLED
 
 
-#define MB_US50_FREQ            (20000) // 20kHz 1/20000 = 50mks
-#define MB_DISCR_TIME_US        (50)    // 50uS = one discreet for timer
-
-#define MB_TIMER_PRESCALLER     ((TIMER_BASE_CLK / MB_US50_FREQ) - 1)
-#define MB_TIMER_SCALE          (TIMER_BASE_CLK / TIMER_DIVIDER)  // convert counter value to seconds
-#define MB_TIMER_DIVIDER        ((TIMER_BASE_CLK / 1000000UL) * MB_DISCR_TIME_US - 1) // divider for 50uS
-#define MB_TIMER_WITH_RELOAD    (1)
+static const char *TAG = "MBS_TIMER";
 
 
-static const USHORT usTimerIndex = CONFIG_FMB_TIMER_INDEX;      // Modbus Timer index used by stack
-static const USHORT usTimerGroupIndex = CONFIG_FMB_TIMER_GROUP; // Modbus Timer group index used by stack
-static timer_isr_handle_t xTimerIntHandle;                      // Timer interrupt handle
+static xTimerContext_t* pxTimerContext = NULL;
 
 
 /* ----------------------- Start implementation -----------------------------*/
 /* ----------------------- Start implementation -----------------------------*/
-static void IRAM_ATTR vTimerGroupIsr(void *param)
+static void IRAM_ATTR vTimerAlarmCBHandler(void *param)
 {
 {
-    assert((int)param == usTimerIndex);
-    // Retrieve the counter value from the timer that reported the interrupt
-    timer_group_clr_intr_status_in_isr(usTimerGroupIndex, usTimerIndex);
-    (void)pxMBPortCBTimerExpired(); // Timer callback function
-    // Enable alarm
-    timer_group_enable_alarm_in_isr(usTimerGroupIndex, usTimerIndex);
+    pxMBPortCBTimerExpired(); // Timer expired callback function
+    pxTimerContext->xTimerState = TRUE;
+    ESP_EARLY_LOGD(TAG, "Slave timeout triggered.");
 }
 }
 #endif
 #endif
 
 
-BOOL xMBPortTimersInit(USHORT usTim1Timerout50us)
+BOOL xMBPortTimersInit(USHORT usTimeOut50us)
 {
 {
 #if CONFIG_FMB_TIMER_PORT_ENABLED
 #if CONFIG_FMB_TIMER_PORT_ENABLED
-    MB_PORT_CHECK((usTim1Timerout50us > 0), FALSE,
+    MB_PORT_CHECK((usTimeOut50us > 0), FALSE,
             "Modbus timeout discreet is incorrect.");
             "Modbus timeout discreet is incorrect.");
-    esp_err_t xErr;
-    timer_config_t config = {
-        .alarm_en = TIMER_ALARM_EN,
-        .auto_reload = MB_TIMER_WITH_RELOAD,
-        .counter_dir = TIMER_COUNT_UP,
-        .divider = MB_TIMER_PRESCALLER,
-        .intr_type = TIMER_INTR_LEVEL,
-        .counter_en = TIMER_PAUSE,
+    MB_PORT_CHECK(!pxTimerContext, FALSE,
+                "Modbus timer is already created.");
+    pxTimerContext = calloc(1, sizeof(xTimerContext_t));
+    if (!pxTimerContext) {
+        return FALSE;
+    }
+    pxTimerContext->xTimerIntHandle = NULL;
+    // Save timer reload value for Modbus T35 period
+    pxTimerContext->usT35Ticks = usTimeOut50us;
+    esp_timer_create_args_t xTimerConf = {
+        .callback = vTimerAlarmCBHandler,
+        .arg = NULL,
+#if CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD
+        .dispatch_method = ESP_TIMER_ISR,
+#else
+        .dispatch_method = ESP_TIMER_TASK,
+#endif
+        .name = "MBS_T35timer"
     };
     };
-    // Configure timer
-    xErr = timer_init(usTimerGroupIndex, usTimerIndex, &config);
-    MB_PORT_CHECK((xErr == ESP_OK), FALSE,
-            "timer init failure, timer_init() returned (0x%x).", xErr);
-    // Stop timer counter
-    xErr = timer_pause(usTimerGroupIndex, usTimerIndex);
-    MB_PORT_CHECK((xErr == ESP_OK), FALSE,
-                    "stop timer failure, timer_pause() returned (0x%x).", xErr);
-    // Reset counter value
-    xErr = timer_set_counter_value(usTimerGroupIndex, usTimerIndex, 0x00000000ULL);
-    MB_PORT_CHECK((xErr == ESP_OK), FALSE,
-                    "timer set value failure, timer_set_counter_value() returned (0x%x).", xErr);
-    // wait3T5_us = 35 * 11 * 100000 / baud; // the 3.5T symbol time for baudrate
-    // Set alarm value for usTim1Timerout50us * 50uS
-    xErr = timer_set_alarm_value(usTimerGroupIndex, usTimerIndex, (uint32_t)(usTim1Timerout50us));
-    MB_PORT_CHECK((xErr == ESP_OK), FALSE,
-                    "failure to set alarm failure, timer_set_alarm_value() returned (0x%x).",
-                    (uint32_t)xErr);
-    // Register ISR for timer
-    xErr = timer_isr_register(usTimerGroupIndex, usTimerIndex, vTimerGroupIsr,
-                                (void*)(uint32_t)usTimerIndex, MB_PORT_TIMER_ISR_FLAG, &xTimerIntHandle);
-    MB_PORT_CHECK((xErr == ESP_OK), FALSE,
-                    "timer set value failure, timer_isr_register() returned (0x%x).",
-                    (uint32_t)xErr);
+    // Create Modbus timer
+    esp_err_t xErr = esp_timer_create(&xTimerConf, &(pxTimerContext->xTimerIntHandle));
+    if (xErr) {
+        return FALSE;
+    }
 #endif
 #endif
     return TRUE;
     return TRUE;
 }
 }
@@ -116,10 +93,12 @@ BOOL xMBPortTimersInit(USHORT usTim1Timerout50us)
 void vMBPortTimersEnable(void)
 void vMBPortTimersEnable(void)
 {
 {
 #if CONFIG_FMB_TIMER_PORT_ENABLED
 #if CONFIG_FMB_TIMER_PORT_ENABLED
-    ESP_ERROR_CHECK(timer_pause(usTimerGroupIndex, usTimerIndex));
-    ESP_ERROR_CHECK(timer_set_counter_value(usTimerGroupIndex, usTimerIndex, 0ULL));
-    ESP_ERROR_CHECK(timer_enable_intr(usTimerGroupIndex, usTimerIndex));
-    ESP_ERROR_CHECK(timer_start(usTimerGroupIndex, usTimerIndex));
+    MB_PORT_CHECK((pxTimerContext && pxTimerContext->xTimerIntHandle), ; ,
+                                "timer is not initialized.");
+    uint64_t xToutUs = (pxTimerContext->usT35Ticks * MB_TIMER_TICK_TIME_US);
+    esp_timer_stop(pxTimerContext->xTimerIntHandle);
+    esp_timer_start_once(pxTimerContext->xTimerIntHandle, xToutUs);
+    pxTimerContext->xTimerState = FALSE;
 #endif
 #endif
 }
 }
 
 
@@ -127,21 +106,22 @@ void MB_PORT_ISR_ATTR
 vMBPortTimersDisable(void)
 vMBPortTimersDisable(void)
 {
 {
 #if CONFIG_FMB_TIMER_PORT_ENABLED
 #if CONFIG_FMB_TIMER_PORT_ENABLED
-    if( (BOOL)xPortInIsrContext() ) {
-        timer_group_set_counter_enable_in_isr(usTimerGroupIndex, usTimerIndex, TIMER_PAUSE);
-    } else {
-        ESP_ERROR_CHECK(timer_pause(usTimerGroupIndex, usTimerIndex));
-        ESP_ERROR_CHECK(timer_set_counter_value(usTimerGroupIndex, usTimerIndex, 0ULL));
-        // Disable timer interrupt
-        ESP_ERROR_CHECK(timer_disable_intr(usTimerGroupIndex, usTimerIndex));
-    }
+    // Disable timer alarm
+    esp_timer_stop(pxTimerContext->xTimerIntHandle);
 #endif
 #endif
 }
 }
 
 
 void vMBPortTimerClose(void)
 void vMBPortTimerClose(void)
 {
 {
-#ifdef CONFIG_FMB_TIMER_PORT_ENABLED
-    ESP_ERROR_CHECK(timer_deinit(usTimerGroupIndex, usTimerIndex));
-    ESP_ERROR_CHECK(esp_intr_free(xTimerIntHandle));
+#if CONFIG_FMB_TIMER_PORT_ENABLED
+    // Delete active timer
+    if (pxTimerContext) {
+        if (pxTimerContext->xTimerIntHandle) {
+            esp_timer_stop(pxTimerContext->xTimerIntHandle);
+            esp_timer_delete(pxTimerContext->xTimerIntHandle);
+        }
+        free(pxTimerContext);
+        pxTimerContext = NULL;
+    }
 #endif
 #endif
 }
 }

+ 58 - 103
components/freemodbus/port/porttimer_m.c

@@ -32,158 +32,113 @@
 /* ----------------------- Modbus includes ----------------------------------*/
 /* ----------------------- Modbus includes ----------------------------------*/
 #include "mb_m.h"
 #include "mb_m.h"
 #include "mbport.h"
 #include "mbport.h"
-#include "port_serial_master.h"
 #include "sdkconfig.h"
 #include "sdkconfig.h"
 
 
-#define MB_US50_FREQ            (20000) // 20kHz 1/20000 = 50mks
-#define MB_TICK_TIME_US         (50)    // 50uS = one tick for timer
-
-#define MB_TIMER_PRESCALLER     ((TIMER_BASE_CLK / MB_US50_FREQ) - 1)
-#define MB_TIMER_SCALE          (TIMER_BASE_CLK / TIMER_DIVIDER)
-#define MB_TIMER_DIVIDER        ((TIMER_BASE_CLK / 1000000UL) * MB_TICK_TIME_US - 1) // divider for 50uS
-#define MB_TIMER_WITH_RELOAD    (1)
+static const char *TAG = "MBM_TIMER";
 
 
 /* ----------------------- Variables ----------------------------------------*/
 /* ----------------------- Variables ----------------------------------------*/
-static USHORT usT35TimeOut50us;
-
-// Initialize Modbus Timer group and index used by stack
-static const USHORT usTimerIndex = CONFIG_FMB_MASTER_TIMER_INDEX;
-static const USHORT usTimerGroupIndex = CONFIG_FMB_MASTER_TIMER_GROUP;
-static timer_isr_handle_t xTimerIntHandle;  // Timer interrupt handle
+static xTimerContext_t* pxTimerContext = NULL;
 
 
-/* ----------------------- static functions ---------------------------------*/
-static void IRAM_ATTR vTimerGroupIsr(void *param)
+/* ----------------------- Start implementation -----------------------------*/
+static void IRAM_ATTR vTimerAlarmCBHandler(void *param)
 {
 {
-    assert((int)param == usTimerIndex);
-    // Retrieve the the counter value from the timer that reported the interrupt
-    timer_group_clr_intr_status_in_isr(usTimerGroupIndex, usTimerIndex);
-    (void)pxMBMasterPortCBTimerExpired(); // Timer expired callback function
-    // Enable alarm
-    timer_group_enable_alarm_in_isr(usTimerGroupIndex, usTimerIndex);
+    pxMBMasterPortCBTimerExpired(); // Timer expired callback function
+    pxTimerContext->xTimerState = TRUE;
+    ESP_EARLY_LOGD(TAG, "Timer mode: (%d) triggered", xMBMasterGetCurTimerMode());
 }
 }
 
 
-/* ----------------------- Start implementation -----------------------------*/
 BOOL xMBMasterPortTimersInit(USHORT usTimeOut50us)
 BOOL xMBMasterPortTimersInit(USHORT usTimeOut50us)
 {
 {
     MB_PORT_CHECK((usTimeOut50us > 0), FALSE,
     MB_PORT_CHECK((usTimeOut50us > 0), FALSE,
             "Modbus timeout discreet is incorrect.");
             "Modbus timeout discreet is incorrect.");
+    MB_PORT_CHECK(!pxTimerContext, FALSE,
+                "Modbus timer is already created.");
+    pxTimerContext = calloc(1, sizeof(xTimerContext_t));
+    if (!pxTimerContext) {
+        return FALSE;
+    }
+    pxTimerContext->xTimerIntHandle = NULL;
     // Save timer reload value for Modbus T35 period
     // Save timer reload value for Modbus T35 period
-    usT35TimeOut50us = usTimeOut50us;
-    esp_err_t xErr;
-    timer_config_t config = {
-        .alarm_en = TIMER_ALARM_EN,
-        .auto_reload = MB_TIMER_WITH_RELOAD,
-        .counter_dir = TIMER_COUNT_UP,
-        .divider = MB_TIMER_PRESCALLER,
-        .intr_type = TIMER_INTR_LEVEL,
-        .counter_en = TIMER_PAUSE,
+    pxTimerContext->usT35Ticks = usTimeOut50us;
+    esp_timer_create_args_t xTimerConf = {
+        .callback = vTimerAlarmCBHandler,
+        .arg = NULL,
+#if CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD
+        .dispatch_method = ESP_TIMER_ISR,
+#else
+        .dispatch_method = ESP_TIMER_TASK,
+#endif
+        .name = "MBM_T35timer"
     };
     };
-    // Configure timer
-    xErr = timer_init(usTimerGroupIndex, usTimerIndex, &config);
-    MB_PORT_CHECK((xErr == ESP_OK), FALSE,
-            "timer init failure, timer_init() returned (0x%x).", (uint32_t)xErr);
-    // Stop timer counter
-    xErr = timer_pause(usTimerGroupIndex, usTimerIndex);
-    MB_PORT_CHECK((xErr == ESP_OK), FALSE,
-                    "stop timer failure, timer_pause() returned (0x%x).", (uint32_t)xErr);
-    // Reset counter value
-    xErr = timer_set_counter_value(usTimerGroupIndex, usTimerIndex, 0x00000000ULL);
-    MB_PORT_CHECK((xErr == ESP_OK), FALSE,
-                    "timer set value failure, timer_set_counter_value() returned (0x%x).",
-                    (uint32_t)xErr);
-    // wait3T5_us = 35 * 11 * 100000 / baud; // the 3.5T symbol time for baudrate
-    // Set alarm value for usTimeOut50us * 50uS
-    xErr = timer_set_alarm_value(usTimerGroupIndex, usTimerIndex, (uint32_t)(usTimeOut50us));
-    MB_PORT_CHECK((xErr == ESP_OK), FALSE,
-                    "failure to set alarm failure, timer_set_alarm_value() returned (0x%x).",
-                    (uint32_t)xErr);
-    // Register ISR for timer
-    xErr = timer_isr_register(usTimerGroupIndex, usTimerIndex,
-                                vTimerGroupIsr, (void*)(uint32_t)usTimerIndex, MB_PORT_TIMER_ISR_FLAG, &xTimerIntHandle);
-    MB_PORT_CHECK((xErr == ESP_OK), FALSE,
-                    "timer set value failure, timer_isr_register() returned (0x%x).",
-                    (uint32_t)xErr);
+    // Create Modbus timer
+    esp_err_t xErr = esp_timer_create(&xTimerConf, &(pxTimerContext->xTimerIntHandle));
+    if (xErr) {
+        return FALSE;
+    }
     return TRUE;
     return TRUE;
 }
 }
 
 
-// Set alarm value for usTimerTimeOut50us * 50uS
-static BOOL xMBMasterPortTimersEnable(USHORT usTimerTics50us)
+// Set timer alarm value
+static BOOL xMBMasterPortTimersEnable(uint64_t xToutUs)
 {
 {
-    MB_PORT_CHECK((usTimerTics50us > 0), FALSE,
-                            "incorrect tick value for timer = (0x%x).",
-                            (uint32_t)usTimerTics50us);
-    esp_err_t xErr;
-    xErr = timer_pause(usTimerGroupIndex, usTimerIndex); // stop timer
-    MB_PORT_CHECK((xErr == ESP_OK), FALSE,
-                        "timer pause failure, timer_pause() returned (0x%x).",
-                        (uint32_t)xErr);
-    xErr = timer_set_counter_value(usTimerGroupIndex, usTimerIndex, 0ULL); // reset timer
-    MB_PORT_CHECK((xErr == ESP_OK), FALSE,
-                        "timer set counter failure, timer_set_counter_value() returned (0x%x).",
-                        (uint32_t)xErr);
-    // Set alarm value to number of 50uS ticks
-    xErr = timer_set_alarm_value(usTimerGroupIndex, usTimerIndex,
-                                            (uint32_t)(usTimerTics50us));
-    MB_PORT_CHECK((xErr == ESP_OK), FALSE,
-                    "timer set alarm failure, timer_set_alarm_value() returned (0x%x).",
-                    (uint32_t)xErr);
-    xErr = timer_enable_intr(usTimerGroupIndex, usTimerIndex);
-    MB_PORT_CHECK((xErr == ESP_OK), FALSE,
-                            "timer enable interrupt failure, timer_enable_intr() returned (0x%x).",
-                            (uint32_t)xErr);
-    xErr = timer_start(usTimerGroupIndex, usTimerIndex); // start timer
-    MB_PORT_CHECK((xErr == ESP_OK), FALSE,
-                            "timer start failure, timer_start() returned (0x%x).",
-                            (uint32_t)xErr);
+    MB_PORT_CHECK(pxTimerContext && (pxTimerContext->xTimerIntHandle), FALSE,
+                                "timer is not initialized.");
+    MB_PORT_CHECK((xToutUs > 0), FALSE,
+                            "incorrect tick value for timer = (0x%llu).", xToutUs);
+    esp_timer_stop(pxTimerContext->xTimerIntHandle);
+    esp_timer_start_once(pxTimerContext->xTimerIntHandle, xToutUs);
+    pxTimerContext->xTimerState = FALSE;
     return TRUE;
     return TRUE;
 }
 }
 
 
 void vMBMasterPortTimersT35Enable(void)
 void vMBMasterPortTimersT35Enable(void)
 {
 {
-    USHORT usTimerTicks = usT35TimeOut50us;
+#if CONFIG_FMB_TIMER_PORT_ENABLED
+    uint64_t xToutUs = (pxTimerContext->usT35Ticks * MB_TIMER_TICK_TIME_US);
 
 
     // Set current timer mode, don't change it.
     // Set current timer mode, don't change it.
     vMBMasterSetCurTimerMode(MB_TMODE_T35);
     vMBMasterSetCurTimerMode(MB_TMODE_T35);
-    // Set timer period
-    (void)xMBMasterPortTimersEnable(usTimerTicks);
+    // Set timer alarm
+    (void)xMBMasterPortTimersEnable(xToutUs);
+#endif
 }
 }
 
 
 void vMBMasterPortTimersConvertDelayEnable(void)
 void vMBMasterPortTimersConvertDelayEnable(void)
 {
 {
     // Covert time in milliseconds into ticks
     // Covert time in milliseconds into ticks
-    USHORT usTimerTicks = ((MB_MASTER_DELAY_MS_CONVERT * 1000) / MB_TICK_TIME_US);
+    uint64_t xToutUs = (MB_MASTER_DELAY_MS_CONVERT * 1000);
 
 
     // Set current timer mode
     // Set current timer mode
     vMBMasterSetCurTimerMode(MB_TMODE_CONVERT_DELAY);
     vMBMasterSetCurTimerMode(MB_TMODE_CONVERT_DELAY);
     ESP_LOGD(MB_PORT_TAG,"%s Convert delay enable.", __func__);
     ESP_LOGD(MB_PORT_TAG,"%s Convert delay enable.", __func__);
-    (void)xMBMasterPortTimersEnable(usTimerTicks);
+    (void)xMBMasterPortTimersEnable(xToutUs);
 }
 }
 
 
 void vMBMasterPortTimersRespondTimeoutEnable(void)
 void vMBMasterPortTimersRespondTimeoutEnable(void)
 {
 {
-    USHORT usTimerTicks = (MB_MASTER_TIMEOUT_MS_RESPOND * 1000 / MB_TICK_TIME_US);
+    uint64_t xToutUs = (MB_MASTER_TIMEOUT_MS_RESPOND * 1000);
 
 
     vMBMasterSetCurTimerMode(MB_TMODE_RESPOND_TIMEOUT);
     vMBMasterSetCurTimerMode(MB_TMODE_RESPOND_TIMEOUT);
     ESP_LOGD(MB_PORT_TAG,"%s Respond enable timeout.", __func__);
     ESP_LOGD(MB_PORT_TAG,"%s Respond enable timeout.", __func__);
-    (void)xMBMasterPortTimersEnable(usTimerTicks);
+    (void)xMBMasterPortTimersEnable(xToutUs);
 }
 }
 
 
 void MB_PORT_ISR_ATTR
 void MB_PORT_ISR_ATTR
 vMBMasterPortTimersDisable()
 vMBMasterPortTimersDisable()
 {
 {
-    if( (BOOL)xPortInIsrContext() ) {
-        timer_group_set_counter_enable_in_isr(usTimerGroupIndex, usTimerIndex, TIMER_PAUSE);
-    } else {
-        // Stop timer and then reload timer counter value
-        ESP_ERROR_CHECK(timer_pause(usTimerGroupIndex, usTimerIndex));
-        ESP_ERROR_CHECK(timer_set_counter_value(usTimerGroupIndex, usTimerIndex, 0ULL));
-        // Disable timer interrupt
-        ESP_ERROR_CHECK(timer_disable_intr(usTimerGroupIndex, usTimerIndex));
-    }
+    // Disable timer alarm
+    esp_timer_stop(pxTimerContext->xTimerIntHandle);
 }
 }
 
 
 void vMBMasterPortTimerClose(void)
 void vMBMasterPortTimerClose(void)
 {
 {
-    ESP_ERROR_CHECK(timer_deinit(usTimerGroupIndex, usTimerIndex));
-    ESP_ERROR_CHECK(esp_intr_free(xTimerIntHandle));
+    // Delete active timer
+    if (pxTimerContext) {
+        if (pxTimerContext->xTimerIntHandle) {
+            esp_timer_stop(pxTimerContext->xTimerIntHandle);
+            esp_timer_delete(pxTimerContext->xTimerIntHandle);
+        }
+        free(pxTimerContext);
+        pxTimerContext = NULL;
+    }
 }
 }

+ 1 - 0
examples/protocols/modbus/serial/mb_master/sdkconfig.defaults

@@ -9,3 +9,4 @@ CONFIG_FMB_TIMER_INDEX=0
 CONFIG_FMB_TIMER_ISR_IN_IRAM=y
 CONFIG_FMB_TIMER_ISR_IN_IRAM=y
 CONFIG_FMB_MASTER_DELAY_MS_CONVERT=200
 CONFIG_FMB_MASTER_DELAY_MS_CONVERT=200
 CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=150
 CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=150
+CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD=y

+ 1 - 0
examples/protocols/modbus/serial/mb_slave/sdkconfig.defaults

@@ -8,3 +8,4 @@ CONFIG_FMB_TIMER_PORT_ENABLED=y
 CONFIG_FMB_TIMER_GROUP=0
 CONFIG_FMB_TIMER_GROUP=0
 CONFIG_FMB_TIMER_INDEX=0
 CONFIG_FMB_TIMER_INDEX=0
 CONFIG_FMB_TIMER_ISR_IN_IRAM=y
 CONFIG_FMB_TIMER_ISR_IN_IRAM=y
+CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD=y

+ 1 - 0
examples/protocols/modbus/tcp/mb_tcp_master/sdkconfig.defaults

@@ -17,3 +17,4 @@ CONFIG_FMB_TIMER_ISR_IN_IRAM=y
 CONFIG_MB_MDNS_IP_RESOLVER=n
 CONFIG_MB_MDNS_IP_RESOLVER=n
 CONFIG_MB_SLAVE_IP_FROM_STDIN=y
 CONFIG_MB_SLAVE_IP_FROM_STDIN=y
 CONFIG_EXAMPLE_CONNECT_IPV6=n
 CONFIG_EXAMPLE_CONNECT_IPV6=n
+CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD=y

+ 1 - 0
examples/protocols/modbus/tcp/mb_tcp_slave/sdkconfig.defaults

@@ -19,3 +19,4 @@ CONFIG_MB_SLAVE_IP_FROM_STDIN=y
 CONFIG_MB_SLAVE_ADDR=1
 CONFIG_MB_SLAVE_ADDR=1
 CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y
 CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y
 CONFIG_EXAMPLE_CONNECT_IPV6=n
 CONFIG_EXAMPLE_CONNECT_IPV6=n
+CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD=y