/* * FreeModbus Libary: BARE Port * Copyright (C) 2006 Christian Walter * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * File: $Id$ */ /* ----------------------- Platform includes --------------------------------*/ #include "port.h" /* ----------------------- Modbus includes ----------------------------------*/ #include "mb.h" #include "mbport.h" #include "main.h" #include "tim.h" #include "elog.h" /* ----------------------- static functions ---------------------------------*/ static void prvvTIMERExpiredISR(void); /* ----------------------- variables ---------------------------------*/ #if MODBUS_USED_FREERTOS /* ----------------------- variables ---------------------------------*/ extern TIM_HandleTypeDef htim7; TIM_HandleTypeDef *pModbusTim = &htim7; volatile uint16_t timeout = 0; volatile uint16_t counter = 0; volatile uint32_t dd = 0; /* ----------------------- Start implementation -----------------------------*/ BOOL xMBPortTimersInit(USHORT usTim1Timerout50us) { TIM_MasterConfigTypeDef sMasterConfig; pModbusTim->Instance = TIM7; pModbusTim->Init.Prescaler = ( 2 * 50 * HAL_RCC_GetPCLK1Freq() / 1000000) - 1; pModbusTim->Init.CounterMode = TIM_COUNTERMODE_UP; pModbusTim->Init.Period = usTim1Timerout50us - 1; pModbusTim->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; timeout = usTim1Timerout50us; // 赋值timeout 多少个周期 if (HAL_TIM_Base_Init(pModbusTim) != HAL_OK) { return FALSE; } sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(pModbusTim, &sMasterConfig) != HAL_OK) { return FALSE; } /* 避免一开始进入了超时中断,关闭中断,停止计数,归0 */ // HAL_NVIC_SetPriority(TIM7_IRQn, 5, 0); // HAL_NVIC_EnableIRQ(TIM7_IRQn); __HAL_TIM_CLEAR_FLAG( &htim7, TIM_FLAG_UPDATE ); // 先清除一下定时器的中断标记,防止使能中断后直接触发中断 __HAL_TIM_CLEAR_IT( &htim7, TIM_IT_UPDATE ); __HAL_TIM_ENABLE_IT(&htim7, TIM_IT_UPDATE); // 使能定时器更新中断 // __HAL_TIM_DISABLE(&htim7); // __HAL_TIM_CLEAR_FLAG( pModbusTim, TIM_FLAG_UPDATE ); // __HAL_TIM_SET_COUNTER( pModbusTim, 0 ); // __HAL_TIM_DISABLE_IT( pModbusTim,TIM_FLAG_UPDATE ); // HAL_TIM_Base_Stop( pModbusTim ); // __HAL_TIM_SET_COUNTER( pModbusTim, 0 ); // HAL_TIM_Base_Stop_IT( pModbusTim ); return TRUE; } inline void vMBPortTimersEnable() { /* Enable the timer with the timeout passed to xMBPortTimersInit( ) */ counter = 0; // 启用定时器时, // HAL_TIM_Base_Start_IT(pModbusTim); // __HAL_TIM_SET_COUNTER(pModbusTim, 0); // 清空计数器 // __HAL_TIM_SET_COUNTER( pModbusTim, 0 ); // __HAL_TIM_ENABLE_IT( pModbusTim,TIM_FLAG_UPDATE ); // HAL_TIM_Base_Start( pModbusTim ); __HAL_TIM_CLEAR_IT(&htim7,TIM_IT_UPDATE); __HAL_TIM_ENABLE_IT(&htim7,TIM_IT_UPDATE); __HAL_TIM_SET_COUNTER(&htim7,0); __HAL_TIM_ENABLE(&htim7); // __HAL_TIM_SET_COUNTER(&htim7, 0); // 清空计数器 // __HAL_TIM_ENABLE(&htim7); // 使能定时器 } inline void vMBPortTimersDisable() { /* Disable any pending timers. */ // HAL_TIM_Base_Stop_IT(pModbusTim); // __HAL_TIM_SET_COUNTER(pModbusTim, 0); // 清空计数器 // __HAL_TIM_SET_COUNTER( pModbusTim, 0 ); // __HAL_TIM_DISABLE_IT( pModbusTim,TIM_FLAG_UPDATE ); // HAL_TIM_Base_Stop( pModbusTim ); // __HAL_TIM_SET_COUNTER( pModbusTim, 0 ); __HAL_TIM_DISABLE(&htim7); __HAL_TIM_SET_COUNTER(&htim7,0); __HAL_TIM_DISABLE_IT(&htim7,TIM_IT_UPDATE); __HAL_TIM_CLEAR_IT(&htim7,TIM_IT_UPDATE); // __HAL_TIM_DISABLE(&htim7); // 禁能定时器 } /* Create an ISR which is called whenever the timer has expired. This function * must then call pxMBPortCBTimerExpired( ) to notify the protocol stack that * the timer has expired. */ static void prvvTIMERExpiredISR(void) { (void)pxMBPortCBTimerExpired(); } void TIM7_IRQHandler(void) { if(__HAL_TIM_GET_FLAG(&htim7, TIM_FLAG_UPDATE) != RESET && __HAL_TIM_GET_IT_SOURCE(&htim7, TIM_IT_UPDATE) !=RESET) // if(__HAL_TIM_GET_FLAG(&htim7, TIM_FLAG_UPDATE)) // 更新中断标记被置位 { dd++; __HAL_TIM_CLEAR_FLAG(&htim7, TIM_FLAG_UPDATE); // 清除中断标记 __HAL_TIM_CLEAR_IT(&htim7,TIM_IT_UPDATE); __HAL_TIM_SET_COUNTER(&htim7, 0); prvvTIMERExpiredISR(); // 通知modbus3.5个字符等待时间到 } HAL_TIM_IRQHandler( &htim7 ); } #else #include // #include /* ----------------------- static functions ---------------------------------*/ osTimerId_t modbusTimerHandle; const osTimerAttr_t modbusTimer_attributes = { .name = "modbusTimer" }; // static TimerHandle_t timer; volatile uint32_t timer_ticks = 0; volatile uint32_t dd = 0; static void prvvTIMERExpiredISR( void ); static void timer_timeout_ind( void* parameter ); /* ----------------------- Start implementation -----------------------------*/ BOOL xMBPortTimersInit( USHORT usTim1Timerout50us ) { /* Freertos can't create timer in isr! 预先创建定时器? 先初始化好? So,I use hardware timer here! req=1Mhz */ timer_ticks = (50 * usTim1Timerout50us) / (1000 * 1000 / configTICK_RATE_HZ) + 1; modbusTimerHandle = osTimerNew( timer_timeout_ind, osTimerOnce, // osTimerOnce osTimerPeriodic NULL, &modbusTimer_attributes ); // modbusTimerHandle = xTimerCreate( // "Slave timer", // (50 * usTim1Timerout50us) / (1000 * 1000 / configTICK_RATE_HZ) + 1, // pdFALSE, (void *)2, timer_timeout_ind); if (modbusTimerHandle == NULL) return FALSE; // osTimerStart( modbusTimerHandle, (50 * usTim1Timerout50us) / (1000 * 1000 / configTICK_RATE_HZ) + 1); return TRUE; } void vMBPortTimersEnable() { // log_i(" enable timer...... %d", timer_ticks ); osTimerStart( modbusTimerHandle, timer_ticks ); if( osTimerIsRunning(modbusTimerHandle) !=) { log_i(" timer running... %d", timer_ticks ); } // osTimerStart 已经包含 (IS_IRQ() } void vMBPortTimersDisable() { // log_i(" disbale timer...... " ); osTimerStop(modbusTimerHandle); // osTimerStop 已经包含 (IS_IRQ() } void prvvTIMERExpiredISR(void) { (void)pxMBPortCBTimerExpired(); } static void timer_timeout_ind( void* parameter ) { dd++; // log_i( " timer timout...... " ); prvvTIMERExpiredISR( ); } #endif #if 0 /* ----------------------- variables ---------------------------------*/ extern TIM_HandleTypeDef htim7; TIM_HandleTypeDef *pModbusTim = &htim7; volatile uint16_t timeout = 0; volatile uint16_t counter = 0; volatile uint32_t dd = 0; /* ----------------------- Start implementation -----------------------------*/ BOOL xMBPortTimersInit(USHORT usTim1Timerout50us) { TIM_MasterConfigTypeDef sMasterConfig; pModbusTim->Instance = TIM7; pModbusTim->Init.Prescaler = ( 2 * 50 * HAL_RCC_GetPCLK1Freq() / 1000000) - 1; pModbusTim->Init.CounterMode = TIM_COUNTERMODE_UP; pModbusTim->Init.Period = usTim1Timerout50us - 1; pModbusTim->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; timeout = usTim1Timerout50us; // 赋值timeout 多少个周期 if (HAL_TIM_Base_Init(pModbusTim) != HAL_OK) { return FALSE; } sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(pModbusTim, &sMasterConfig) != HAL_OK) { return FALSE; } /* 避免一开始进入了超时中断,关闭中断,停止计数,归0 */ // HAL_NVIC_SetPriority(TIM7_IRQn, 5, 0); // HAL_NVIC_EnableIRQ(TIM7_IRQn); __HAL_TIM_CLEAR_FLAG( &htim7, TIM_FLAG_UPDATE ); // 先清除一下定时器的中断标记,防止使能中断后直接触发中断 __HAL_TIM_CLEAR_IT( &htim7, TIM_IT_UPDATE ); __HAL_TIM_ENABLE_IT(&htim7, TIM_IT_UPDATE); // 使能定时器更新中断 // __HAL_TIM_DISABLE(&htim7); // __HAL_TIM_CLEAR_FLAG( pModbusTim, TIM_FLAG_UPDATE ); // __HAL_TIM_SET_COUNTER( pModbusTim, 0 ); // __HAL_TIM_DISABLE_IT( pModbusTim,TIM_FLAG_UPDATE ); // HAL_TIM_Base_Stop( pModbusTim ); // __HAL_TIM_SET_COUNTER( pModbusTim, 0 ); // HAL_TIM_Base_Stop_IT( pModbusTim ); return TRUE; } inline void vMBPortTimersEnable() { /* Enable the timer with the timeout passed to xMBPortTimersInit( ) */ counter = 0; // 启用定时器时, // HAL_TIM_Base_Start_IT(pModbusTim); // __HAL_TIM_SET_COUNTER(pModbusTim, 0); // 清空计数器 // __HAL_TIM_SET_COUNTER( pModbusTim, 0 ); // __HAL_TIM_ENABLE_IT( pModbusTim,TIM_FLAG_UPDATE ); // HAL_TIM_Base_Start( pModbusTim ); __HAL_TIM_CLEAR_IT(&htim7,TIM_IT_UPDATE); __HAL_TIM_ENABLE_IT(&htim7,TIM_IT_UPDATE); __HAL_TIM_SET_COUNTER(&htim7,0); __HAL_TIM_ENABLE(&htim7); // __HAL_TIM_SET_COUNTER(&htim7, 0); // 清空计数器 // __HAL_TIM_ENABLE(&htim7); // 使能定时器 } inline void vMBPortTimersDisable() { /* Disable any pending timers. */ // HAL_TIM_Base_Stop_IT(pModbusTim); // __HAL_TIM_SET_COUNTER(pModbusTim, 0); // 清空计数器 // __HAL_TIM_SET_COUNTER( pModbusTim, 0 ); // __HAL_TIM_DISABLE_IT( pModbusTim,TIM_FLAG_UPDATE ); // HAL_TIM_Base_Stop( pModbusTim ); // __HAL_TIM_SET_COUNTER( pModbusTim, 0 ); __HAL_TIM_DISABLE(&htim7); __HAL_TIM_SET_COUNTER(&htim7,0); __HAL_TIM_DISABLE_IT(&htim7,TIM_IT_UPDATE); __HAL_TIM_CLEAR_IT(&htim7,TIM_IT_UPDATE); // __HAL_TIM_DISABLE(&htim7); // 禁能定时器 } /* Create an ISR which is called whenever the timer has expired. This function * must then call pxMBPortCBTimerExpired( ) to notify the protocol stack that * the timer has expired. */ static void prvvTIMERExpiredISR(void) { (void)pxMBPortCBTimerExpired(); } void TIM7_IRQHandler(void) { // if(__HAL_TIM_GET_FLAG(&htim7, TIM_FLAG_UPDATE) != RESET && __HAL_TIM_GET_IT_SOURCE(&htim7, TIM_IT_UPDATE) !=RESET) if(__HAL_TIM_GET_FLAG(&htim7, TIM_FLAG_UPDATE)) // 更新中断标记被置位 { dd++; __HAL_TIM_CLEAR_FLAG(&htim7, TIM_FLAG_UPDATE); // 清除中断标记 __HAL_TIM_CLEAR_IT(&htim7,TIM_IT_UPDATE); __HAL_TIM_SET_COUNTER(&htim7, 0); prvvTIMERExpiredISR(); // 通知modbus3.5个字符等待时间到 } HAL_TIM_IRQHandler( &htim7 ); } #endif