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

* Original commit: espressif/esp-idf@ee104f8de2
This commit is contained in:
aleks
2021-10-12 17:06:13 +02:00
parent 0ddd723239
commit 509c47fc76
9 changed files with 131 additions and 239 deletions

View File

@@ -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 config FMB_TIMER_USE_ISR_DISPATCH_METHOD
int "Slave Timer group number" bool "Modbus timer uses ISR dispatch method"
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"
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. If this option is set the Modbus stack uses ISR dispatch method
This allows to avoid delays related to processing of non-IRAM-safe interrupts to send timeout events from the callback function called from ISR.
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).
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.

View File

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

View File

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

View File

@@ -38,89 +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 static const char *TAG = "MBS_TIMER";
#define MB_DISCR_TIME_US (50) // 50uS = one discreet for timer
#define MB_TIMER_PRESCALLER ((TIMER_BASE_CLK / MB_US50_FREQ) - 1) static xTimerContext_t* pxTimerContext = NULL;
#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 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 timg_dev_t *MB_TG[2] = {&TIMERG0, &TIMERG1};
/* ----------------------- Start implementation -----------------------------*/ /* ----------------------- Start implementation -----------------------------*/
static void IRAM_ATTR vTimerGroupIsr(void *param) static void IRAM_ATTR vTimerAlarmCBHandler(void *param)
{ {
// Retrieve the interrupt status and the counter value pxMBPortCBTimerExpired(); // Timer expired callback function
// from the timer that reported the interrupt pxTimerContext->xTimerState = TRUE;
#if CONFIG_IDF_TARGET_ESP32 ESP_EARLY_LOGD(TAG, "Slave timeout triggered.");
uint32_t intr_status = MB_TG[usTimerGroupIndex]->int_st_timers.val;
#elif CONFIG_IDF_TARGET_ESP32S2BETA
uint32_t intr_status = MB_TG[usTimerGroupIndex]->int_st.val;
#endif
if (intr_status & BIT(usTimerIndex)) {
#if CONFIG_IDF_TARGET_ESP32
MB_TG[usTimerGroupIndex]->int_clr_timers.val |= BIT(usTimerIndex);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
MB_TG[usTimerGroupIndex]->int_clr.val |= BIT(usTimerIndex);
#endif
(void)pxMBPortCBTimerExpired(); // Timer callback function
MB_TG[usTimerGroupIndex]->hw_timer[usTimerIndex].config.alarm_en = TIMER_ALARM_EN;
}
} }
#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; MB_PORT_CHECK(!pxTimerContext, FALSE,
timer_config_t config = { "Modbus timer is already created.");
.alarm_en = TIMER_ALARM_EN, pxTimerContext = calloc(1, sizeof(xTimerContext_t));
.auto_reload = MB_TIMER_WITH_RELOAD, if (!pxTimerContext) {
.counter_dir = TIMER_COUNT_UP, return FALSE;
.divider = MB_TIMER_PRESCALLER, }
.intr_type = TIMER_INTR_LEVEL, pxTimerContext->xTimerIntHandle = NULL;
.counter_en = TIMER_PAUSE, // 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 // Create Modbus timer
xErr = timer_init(usTimerGroupIndex, usTimerIndex, &config); esp_err_t xErr = esp_timer_create(&xTimerConf, &(pxTimerContext->xTimerIntHandle));
MB_PORT_CHECK((xErr == ESP_OK), FALSE, if (xErr) {
"timer init failure, timer_init() returned (0x%x).", xErr); return FALSE;
// 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);
#endif #endif
return TRUE; return TRUE;
} }
@@ -128,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)); MB_PORT_CHECK((pxTimerContext && pxTimerContext->xTimerIntHandle), ; ,
ESP_ERROR_CHECK(timer_set_counter_value(usTimerGroupIndex, usTimerIndex, 0ULL)); "timer is not initialized.");
ESP_ERROR_CHECK(timer_enable_intr(usTimerGroupIndex, usTimerIndex)); uint64_t xToutUs = (pxTimerContext->usT35Ticks * MB_TIMER_TICK_TIME_US);
ESP_ERROR_CHECK(timer_start(usTimerGroupIndex, usTimerIndex)); esp_timer_stop(pxTimerContext->xTimerIntHandle);
esp_timer_start_once(pxTimerContext->xTimerIntHandle, xToutUs);
pxTimerContext->xTimerState = FALSE;
#endif #endif
} }
@@ -139,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() ) { // Disable timer alarm
timer_group_set_counter_enable_in_isr(usTimerGroupIndex, usTimerIndex, TIMER_PAUSE); esp_timer_stop(pxTimerContext->xTimerIntHandle);
} 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));
}
#endif #endif
} }
void vMBPortTimerClose(void) void vMBPortTimerClose(void)
{ {
#ifdef CONFIG_FMB_TIMER_PORT_ENABLED #if CONFIG_FMB_TIMER_PORT_ENABLED
ESP_ERROR_CHECK(timer_deinit(usTimerGroupIndex, usTimerIndex)); // Delete active timer
ESP_ERROR_CHECK(esp_intr_free(xTimerIntHandle)); if (pxTimerContext) {
if (pxTimerContext->xTimerIntHandle) {
esp_timer_stop(pxTimerContext->xTimerIntHandle);
esp_timer_delete(pxTimerContext->xTimerIntHandle);
}
free(pxTimerContext);
pxTimerContext = NULL;
}
#endif #endif
} }

View File

@@ -32,176 +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 static const char *TAG = "MBM_TIMER";
#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)
/* ----------------------- Variables ----------------------------------------*/ /* ----------------------- Variables ----------------------------------------*/
static USHORT usT35TimeOut50us; static xTimerContext_t* pxTimerContext = NULL;
// 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 timg_dev_t *MB_TG[2] = { &TIMERG0, &TIMERG1 };
/* ----------------------- static functions ---------------------------------*/
static void IRAM_ATTR vTimerGroupIsr(void *param)
{
// Retrieve the interrupt status and the counter value
// from the timer that reported the interrupt
#if CONFIG_IDF_TARGET_ESP32
uint32_t intr_status = MB_TG[usTimerGroupIndex]->int_st_timers.val;
#elif CONFIG_IDF_TARGET_ESP32S2BETA
uint32_t intr_status = MB_TG[usTimerGroupIndex]->int_st.val;
#endif
if (intr_status & BIT(usTimerIndex)) {
#if CONFIG_IDF_TARGET_ESP32
MB_TG[usTimerGroupIndex]->int_clr_timers.val |= BIT(usTimerIndex);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
MB_TG[usTimerGroupIndex]->int_clr.val |= BIT(usTimerIndex);
#endif
#if CONFIG_IDF_TARGET_ESP32
MB_TG[usTimerGroupIndex]->hw_timer[usTimerIndex].update = 1;
#elif CONFIG_IDF_TARGET_ESP32S2BETA
MB_TG[usTimerGroupIndex]->hw_timer[usTimerIndex].update.update = 1;
#endif
(void)pxMBMasterPortCBTimerExpired(); // Timer expired callback function
// Enable alarm
MB_TG[usTimerGroupIndex]->hw_timer[usTimerIndex].config.alarm_en = TIMER_ALARM_EN;
}
}
/* ----------------------- Start implementation -----------------------------*/ /* ----------------------- Start implementation -----------------------------*/
static void IRAM_ATTR vTimerAlarmCBHandler(void *param)
{
pxMBMasterPortCBTimerExpired(); // Timer expired callback function
pxTimerContext->xTimerState = TRUE;
ESP_EARLY_LOGD(TAG, "Timer mode: (%d) triggered", xMBMasterGetCurTimerMode());
}
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; pxTimerContext->usT35Ticks = usTimeOut50us;
esp_err_t xErr; esp_timer_create_args_t xTimerConf = {
timer_config_t config = { .callback = vTimerAlarmCBHandler,
.alarm_en = TIMER_ALARM_EN, .arg = NULL,
.auto_reload = MB_TIMER_WITH_RELOAD, #if CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD
.counter_dir = TIMER_COUNT_UP, .dispatch_method = ESP_TIMER_ISR,
.divider = MB_TIMER_PRESCALLER, #else
.intr_type = TIMER_INTR_LEVEL, .dispatch_method = ESP_TIMER_TASK,
.counter_en = TIMER_PAUSE, #endif
.name = "MBM_T35timer"
}; };
// Configure timer // Create Modbus timer
xErr = timer_init(usTimerGroupIndex, usTimerIndex, &config); esp_err_t xErr = esp_timer_create(&xTimerConf, &(pxTimerContext->xTimerIntHandle));
MB_PORT_CHECK((xErr == ESP_OK), FALSE, if (xErr) {
"timer init failure, timer_init() returned (0x%x).", (uint32_t)xErr); return FALSE;
// 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);
return TRUE; return TRUE;
} }
// Set alarm value for usTimerTimeOut50us * 50uS // Set timer alarm value
static BOOL xMBMasterPortTimersEnable(USHORT usTimerTics50us) static BOOL xMBMasterPortTimersEnable(uint64_t xToutUs)
{ {
MB_PORT_CHECK((usTimerTics50us > 0), FALSE, MB_PORT_CHECK(pxTimerContext && (pxTimerContext->xTimerIntHandle), FALSE,
"incorrect tick value for timer = (0x%x).", "timer is not initialized.");
(uint32_t)usTimerTics50us); MB_PORT_CHECK((xToutUs > 0), FALSE,
esp_err_t xErr; "incorrect tick value for timer = (0x%llu).", xToutUs);
xErr = timer_pause(usTimerGroupIndex, usTimerIndex); // stop timer esp_timer_stop(pxTimerContext->xTimerIntHandle);
MB_PORT_CHECK((xErr == ESP_OK), FALSE, esp_timer_start_once(pxTimerContext->xTimerIntHandle, xToutUs);
"timer pause failure, timer_pause() returned (0x%x).", pxTimerContext->xTimerState = FALSE;
(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);
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 // Set timer alarm
(void)xMBMasterPortTimersEnable(usTimerTicks); (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() ) { // Disable timer alarm
timer_group_set_counter_enable_in_isr(usTimerGroupIndex, usTimerIndex, TIMER_PAUSE); esp_timer_stop(pxTimerContext->xTimerIntHandle);
} 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));
}
} }
void vMBMasterPortTimerClose(void) void vMBMasterPortTimerClose(void)
{ {
ESP_ERROR_CHECK(timer_deinit(usTimerGroupIndex, usTimerIndex)); // Delete active timer
ESP_ERROR_CHECK(esp_intr_free(xTimerIntHandle)); if (pxTimerContext) {
if (pxTimerContext->xTimerIntHandle) {
esp_timer_stop(pxTimerContext->xTimerIntHandle);
esp_timer_delete(pxTimerContext->xTimerIntHandle);
}
free(pxTimerContext);
pxTimerContext = NULL;
}
} }

View File

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

View File

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

View File

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

View File

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