forked from espressif/esp-modbus
freemodbus: fix timer port to use esp_timer instead of group timer
* Original commit: espressif/esp-idf@ee104f8de2
This commit is contained in:
@@ -193,44 +193,14 @@ menu "Modbus configuration"
|
||||
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.
|
||||
|
||||
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
|
||||
select ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD
|
||||
select UART_ISR_IN_IRAM
|
||||
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
|
||||
handler into IRAM to prevent delays related to processing of UART events.
|
||||
|
||||
|
@@ -40,6 +40,7 @@
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "esp_log.h" // for ESP_LOGE macro
|
||||
#include "esp_timer.h"
|
||||
#include "mbconfig.h"
|
||||
|
||||
#define INLINE inline
|
||||
@@ -87,6 +88,7 @@
|
||||
|
||||
// Define number of timer reloads per 1 mS
|
||||
#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.
|
||||
|
||||
@@ -142,6 +144,12 @@ typedef enum {
|
||||
MB_PORT_IPV6 = 1 /*!< TCP IPV6 addressing */
|
||||
} eMBPortIpVer;
|
||||
|
||||
typedef struct {
|
||||
esp_timer_handle_t xTimerIntHandle;
|
||||
USHORT usT35Ticks;
|
||||
BOOL xTimerState;
|
||||
} xTimerContext_t;
|
||||
|
||||
void vMBPortEnterCritical(void);
|
||||
void vMBPortExitCritical(void);
|
||||
|
||||
|
@@ -85,9 +85,14 @@ static USHORT usMBMasterPortSerialRxPoll(size_t xEventSize)
|
||||
// Call the Modbus stack callback function and let it fill the stack buffers.
|
||||
xReadStatus = pxMBMasterFrameCBByteReceived(); // callback to receive FSM
|
||||
}
|
||||
|
||||
// The buffer is transferred into Modbus stack and is not needed here any more
|
||||
uart_flush_input(ucUartNumber);
|
||||
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 {
|
||||
ESP_LOGE(TAG, "%s: bRxState disabled but junk data (%d bytes) received. ", __func__, xEventSize);
|
||||
}
|
||||
|
@@ -38,89 +38,54 @@
|
||||
#include "port.h"
|
||||
|
||||
/* ----------------------- Modbus includes ----------------------------------*/
|
||||
#include "sdkconfig.h"
|
||||
#include "mb.h"
|
||||
#include "mbport.h"
|
||||
#include "driver/timer.h"
|
||||
#include "port_serial_slave.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#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
|
||||
static const char *TAG = "MBS_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 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};
|
||||
static xTimerContext_t* pxTimerContext = NULL;
|
||||
|
||||
/* ----------------------- Start implementation -----------------------------*/
|
||||
static void IRAM_ATTR vTimerGroupIsr(void *param)
|
||||
static void IRAM_ATTR vTimerAlarmCBHandler(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
|
||||
(void)pxMBPortCBTimerExpired(); // Timer callback function
|
||||
MB_TG[usTimerGroupIndex]->hw_timer[usTimerIndex].config.alarm_en = TIMER_ALARM_EN;
|
||||
}
|
||||
pxMBPortCBTimerExpired(); // Timer expired callback function
|
||||
pxTimerContext->xTimerState = TRUE;
|
||||
ESP_EARLY_LOGD(TAG, "Slave timeout triggered.");
|
||||
}
|
||||
#endif
|
||||
|
||||
BOOL xMBPortTimersInit(USHORT usTim1Timerout50us)
|
||||
BOOL xMBPortTimersInit(USHORT usTimeOut50us)
|
||||
{
|
||||
#if CONFIG_FMB_TIMER_PORT_ENABLED
|
||||
MB_PORT_CHECK((usTim1Timerout50us > 0), FALSE,
|
||||
MB_PORT_CHECK((usTimeOut50us > 0), FALSE,
|
||||
"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
|
||||
return TRUE;
|
||||
}
|
||||
@@ -128,10 +93,12 @@ BOOL xMBPortTimersInit(USHORT usTim1Timerout50us)
|
||||
void vMBPortTimersEnable(void)
|
||||
{
|
||||
#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
|
||||
}
|
||||
|
||||
@@ -139,21 +106,22 @@ void MB_PORT_ISR_ATTR
|
||||
vMBPortTimersDisable(void)
|
||||
{
|
||||
#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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
@@ -32,176 +32,113 @@
|
||||
/* ----------------------- Modbus includes ----------------------------------*/
|
||||
#include "mb_m.h"
|
||||
#include "mbport.h"
|
||||
#include "port_serial_master.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 ----------------------------------------*/
|
||||
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 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;
|
||||
}
|
||||
}
|
||||
static xTimerContext_t* pxTimerContext = NULL;
|
||||
|
||||
/* ----------------------- 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)
|
||||
{
|
||||
MB_PORT_CHECK((usTimeOut50us > 0), FALSE,
|
||||
"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
|
||||
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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
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.
|
||||
vMBMasterSetCurTimerMode(MB_TMODE_T35);
|
||||
// Set timer period
|
||||
(void)xMBMasterPortTimersEnable(usTimerTicks);
|
||||
// Set timer alarm
|
||||
(void)xMBMasterPortTimersEnable(xToutUs);
|
||||
#endif
|
||||
}
|
||||
|
||||
void vMBMasterPortTimersConvertDelayEnable(void)
|
||||
{
|
||||
// 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
|
||||
vMBMasterSetCurTimerMode(MB_TMODE_CONVERT_DELAY);
|
||||
ESP_LOGD(MB_PORT_TAG,"%s Convert delay enable.", __func__);
|
||||
(void)xMBMasterPortTimersEnable(usTimerTicks);
|
||||
(void)xMBMasterPortTimersEnable(xToutUs);
|
||||
}
|
||||
|
||||
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);
|
||||
ESP_LOGD(MB_PORT_TAG,"%s Respond enable timeout.", __func__);
|
||||
(void)xMBMasterPortTimersEnable(usTimerTicks);
|
||||
(void)xMBMasterPortTimersEnable(xToutUs);
|
||||
}
|
||||
|
||||
void MB_PORT_ISR_ATTR
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@@ -9,3 +9,4 @@ CONFIG_FMB_TIMER_INDEX=0
|
||||
CONFIG_FMB_TIMER_ISR_IN_IRAM=y
|
||||
CONFIG_FMB_MASTER_DELAY_MS_CONVERT=200
|
||||
CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=150
|
||||
CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD=y
|
||||
|
@@ -8,3 +8,4 @@ CONFIG_FMB_TIMER_PORT_ENABLED=y
|
||||
CONFIG_FMB_TIMER_GROUP=0
|
||||
CONFIG_FMB_TIMER_INDEX=0
|
||||
CONFIG_FMB_TIMER_ISR_IN_IRAM=y
|
||||
CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD=y
|
||||
|
@@ -17,3 +17,4 @@ CONFIG_FMB_TIMER_ISR_IN_IRAM=y
|
||||
CONFIG_MB_MDNS_IP_RESOLVER=n
|
||||
CONFIG_MB_SLAVE_IP_FROM_STDIN=y
|
||||
CONFIG_EXAMPLE_CONNECT_IPV6=n
|
||||
CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD=y
|
||||
|
@@ -19,3 +19,4 @@ CONFIG_MB_SLAVE_IP_FROM_STDIN=y
|
||||
CONFIG_MB_SLAVE_ADDR=1
|
||||
CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y
|
||||
CONFIG_EXAMPLE_CONNECT_IPV6=n
|
||||
CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD=y
|
||||
|
Reference in New Issue
Block a user