|
|
@@ -32,158 +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 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)
|
|
|
{
|
|
|
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;
|
|
|
+ }
|
|
|
}
|