diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/Makefile b/bacnet-stack/ports/bdk-atxx4-mstp/Makefile index 03f837d5..1820d085 100644 --- a/bacnet-stack/ports/bdk-atxx4-mstp/Makefile +++ b/bacnet-stack/ports/bdk-atxx4-mstp/Makefile @@ -55,6 +55,7 @@ CSRC = main.c \ serial.c \ rs485.c \ timer2.c \ + timer.c \ led.c \ eeprom.c \ seeprom.c \ diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/dlmstp.c b/bacnet-stack/ports/bdk-atxx4-mstp/dlmstp.c index 45a6b0e2..ffd35c9a 100644 --- a/bacnet-stack/ports/bdk-atxx4-mstp/dlmstp.c +++ b/bacnet-stack/ports/bdk-atxx4-mstp/dlmstp.c @@ -459,10 +459,10 @@ static void MSTP_Receive_Frame_FSM( for the beginning of a frame. */ if (rs485_receive_error()) { /* EatAnError */ - timer_reset(TIMER_SILENCE); + rs485_silence_time_reset(); INCREMENT_AND_LIMIT_UINT8(EventCount); } else if (rs485_byte_available(&DataRegister)) { - timer_reset(TIMER_SILENCE); + rs485_silence_time_reset(); INCREMENT_AND_LIMIT_UINT8(EventCount); if (DataRegister == 0x55) { /* Preamble1 */ @@ -474,19 +474,19 @@ static void MSTP_Receive_Frame_FSM( case MSTP_RECEIVE_STATE_PREAMBLE: /* In the PREAMBLE state, the node waits for the second octet of the preamble. */ - if (timer_elapsed_milliseconds(TIMER_SILENCE, Tframe_abort)) { + if (rs485_silence_time_elapsed(Tframe_abort)) { /* Timeout */ /* a correct preamble has not been received */ /* wait for the start of a frame. */ Receive_State = MSTP_RECEIVE_STATE_IDLE; } else if (rs485_receive_error()) { /* Error */ - timer_reset(TIMER_SILENCE); + rs485_silence_time_reset(); INCREMENT_AND_LIMIT_UINT8(EventCount); /* wait for the start of a frame. */ Receive_State = MSTP_RECEIVE_STATE_IDLE; } else if (rs485_byte_available(&DataRegister)) { - timer_reset(TIMER_SILENCE); + rs485_silence_time_reset(); INCREMENT_AND_LIMIT_UINT8(EventCount); if (DataRegister == 0xFF) { /* Preamble2 */ @@ -508,7 +508,7 @@ static void MSTP_Receive_Frame_FSM( case MSTP_RECEIVE_STATE_HEADER: /* In the HEADER state, the node waits for the fixed message header. */ - if (timer_elapsed_milliseconds(TIMER_SILENCE, Tframe_abort)) { + if (rs485_silence_time_elapsed(Tframe_abort)) { /* Timeout */ /* indicate that an error has occurred during the reception of a frame */ @@ -517,7 +517,7 @@ static void MSTP_Receive_Frame_FSM( Receive_State = MSTP_RECEIVE_STATE_IDLE; } else if (rs485_receive_error()) { /* Error */ - timer_reset(TIMER_SILENCE); + rs485_silence_time_reset(); INCREMENT_AND_LIMIT_UINT8(EventCount); /* indicate that an error has occurred during the reception of a frame */ @@ -525,7 +525,7 @@ static void MSTP_Receive_Frame_FSM( /* wait for the start of a frame. */ Receive_State = MSTP_RECEIVE_STATE_IDLE; } else if (rs485_byte_available(&DataRegister)) { - timer_reset(TIMER_SILENCE); + rs485_silence_time_reset(); INCREMENT_AND_LIMIT_UINT8(EventCount); if (Index == 0) { /* FrameType */ @@ -610,7 +610,7 @@ static void MSTP_Receive_Frame_FSM( case MSTP_RECEIVE_STATE_DATA: /* In the DATA state, the node waits for the data portion of a frame. */ - if (timer_elapsed_milliseconds(TIMER_SILENCE, Tframe_abort)) { + if (rs485_silence_time_elapsed(Tframe_abort)) { /* Timeout */ /* indicate that an error has occurred during the reception of a frame */ @@ -619,7 +619,7 @@ static void MSTP_Receive_Frame_FSM( Receive_State = MSTP_RECEIVE_STATE_IDLE; } else if (rs485_receive_error()) { /* Error */ - timer_reset(TIMER_SILENCE); + rs485_silence_time_reset(); INCREMENT_AND_LIMIT_UINT8(EventCount); /* indicate that an error has occurred during the reception of a frame */ @@ -627,7 +627,7 @@ static void MSTP_Receive_Frame_FSM( /* wait for the start of the next frame. */ Receive_State = MSTP_RECEIVE_STATE_IDLE; } else if (rs485_byte_available(&DataRegister)) { - timer_reset(TIMER_SILENCE); + rs485_silence_time_reset(); INCREMENT_AND_LIMIT_UINT8(EventCount); if (Index < DataLength) { /* DataOctet */ @@ -736,7 +736,7 @@ static bool MSTP_Master_Node_FSM( break; case MSTP_MASTER_STATE_IDLE: /* In the IDLE state, the node waits for a frame. */ - if (timer_elapsed_milliseconds(TIMER_SILENCE, Tno_token)) { + if (rs485_silence_time_elapsed(Tno_token)) { /* LostToken */ /* assume that the token has been lost */ EventCount = 0; /* Addendum 135-2004d-8 */ @@ -842,7 +842,7 @@ static bool MSTP_Master_Node_FSM( case MSTP_MASTER_STATE_WAIT_FOR_REPLY: /* In the WAIT_FOR_REPLY state, the node waits for */ /* a reply from another node. */ - if (timer_elapsed_milliseconds(TIMER_SILENCE, Treply_timeout)) { + if (rs485_silence_time_elapsed(Treply_timeout)) { /* ReplyTimeout */ /* assume that the request has failed */ FrameCount = Nmax_info_frames; @@ -979,7 +979,7 @@ static bool MSTP_Master_Node_FSM( /* The PASS_TOKEN state listens for a successor to begin using */ /* the token that this node has just attempted to pass. */ case MSTP_MASTER_STATE_PASS_TOKEN: - if (timer_elapsed_milliseconds(TIMER_SILENCE, Tusage_timeout)) { + if (rs485_silence_time_elapsed(Tusage_timeout)) { if (RetryCount < Nretry_token) { /* RetrySendToken */ RetryCount++; @@ -1022,11 +1022,11 @@ static bool MSTP_Master_Node_FSM( whether or not this node may create a token. */ case MSTP_MASTER_STATE_NO_TOKEN: my_timeout = Tno_token + (Tslot * This_Station); - if (timer_elapsed_milliseconds(TIMER_SILENCE, my_timeout)) { + if (rs485_silence_time_elapsed(my_timeout)) { ns_timeout = Tno_token + (Tslot * (This_Station + 1)); - if (timer_elapsed_milliseconds(TIMER_SILENCE, ns_timeout)) { + if (rs485_silence_time_elapsed(ns_timeout)) { /* should never get here unless timer resolution is bad */ - timer_reset(TIMER_SILENCE); + rs485_silence_time_reset(); Master_State = MSTP_MASTER_STATE_IDLE; } else { /* GenerateToken */ @@ -1084,8 +1084,7 @@ static bool MSTP_Master_Node_FSM( transition_now = true; } MSTP_Flag.ReceivedValidFrame = false; - } else if ((timer_elapsed_milliseconds(TIMER_SILENCE, - Tusage_timeout)) || + } else if ((rs485_silence_time_elapsed(Tusage_timeout)) || (MSTP_Flag.ReceivedInvalidFrame == true)) { if (MSTP_Flag.SoleMaster == true) { /* SoleMaster */ diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/hardware.h b/bacnet-stack/ports/bdk-atxx4-mstp/hardware.h index 0ecf2069..fc0929ac 100644 --- a/bacnet-stack/ports/bdk-atxx4-mstp/hardware.h +++ b/bacnet-stack/ports/bdk-atxx4-mstp/hardware.h @@ -52,15 +52,4 @@ #define SEEPROM_PAGE_SIZE 16 #define SEEPROM_WORD_ADDRESS_16BIT 0 -/* reserve the millisecond timer indexes as needed for each module */ -#define TIMER_SILENCE 0 -#define TIMER_DEBOUNCE 1 -#define TIMER_LED_1 2 -#define TIMER_LED_2 3 -#define TIMER_LED_3 4 -#define TIMER_LED_4 5 -#define TIMER_DCC 6 -#define TIMER_TEST 7 -#define MAX_MILLISECOND_TIMERS 8 - #endif diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/input.c b/bacnet-stack/ports/bdk-atxx4-mstp/input.c index cef65d15..82ed682f 100644 --- a/bacnet-stack/ports/bdk-atxx4-mstp/input.c +++ b/bacnet-stack/ports/bdk-atxx4-mstp/input.c @@ -29,6 +29,7 @@ static uint8_t Address_Switch; static uint8_t Buttons; +static struct itimer Debounce_Timer; #define BDK_V1_HACK 0 @@ -75,8 +76,8 @@ void input_task( static uint8_t old_buttons = 0; /* only check the inputs every debounce time */ - if (timer_elapsed_milliseconds(TIMER_DEBOUNCE, 30)) { - timer_reset(TIMER_DEBOUNCE); + if (timer_interval_expired(&Debounce_Timer)) { + timer_interval_reset(&Debounce_Timer); /* pins used are PA6, PA5, PA4, PA3, PA2, PA1, PA0 */ #if BDK_V1_HACK /* version 1 BDK - workaround */ @@ -161,5 +162,5 @@ void input_init( BIT_CLEAR(DDRB, DDB2); BIT_CLEAR(DDRB, DDB3); BIT_CLEAR(DDRB, DDB4); - timer_reset(TIMER_DEBOUNCE); + timer_interval_start(&Debounce_Timer, 30); } diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/led.c b/bacnet-stack/ports/bdk-atxx4-mstp/led.c index 7ece96ca..4fcfd12f 100644 --- a/bacnet-stack/ports/bdk-atxx4-mstp/led.c +++ b/bacnet-stack/ports/bdk-atxx4-mstp/led.c @@ -26,10 +26,7 @@ #include "timer.h" #include "led.h" -static uint32_t Off_Delay_Milliseconds_1; -static uint32_t Off_Delay_Milliseconds_2; -static uint32_t Off_Delay_Milliseconds_3; -static uint32_t Off_Delay_Milliseconds_4; +static struct itimer Off_Delay_Timer[MAX_LEDS]; /************************************************************************* * Description: Turn on an LED @@ -55,6 +52,9 @@ void led_on( default: break; } + if (index < MAX_LEDS) { + timer_interval_no_expire(&Off_Delay_Timer[index]); + } } /************************************************************************* @@ -81,6 +81,9 @@ void led_off( default: break; } + if (index < MAX_LEDS) { + timer_interval_no_expire(&Off_Delay_Timer[index]); + } } /************************************************************************* @@ -135,25 +138,8 @@ void led_off_delay( uint8_t index, uint32_t delay_ms) { - switch (index) { - case LED_1: - Off_Delay_Milliseconds_1 = delay_ms; - timer_reset(TIMER_LED_1); - break; - case LED_2: - Off_Delay_Milliseconds_2 = delay_ms; - timer_reset(TIMER_LED_2); - break; - case LED_3: - Off_Delay_Milliseconds_3 = delay_ms; - timer_reset(TIMER_LED_3); - break; - case LED_4: - Off_Delay_Milliseconds_4 = delay_ms; - timer_reset(TIMER_LED_4); - break; - default: - break; + if (index < MAX_LEDS) { + timer_interval_start(&Off_Delay_Timer[index], delay_ms); } } @@ -165,28 +151,12 @@ void led_off_delay( void led_task( void) { - if (Off_Delay_Milliseconds_1) { - if (timer_elapsed_milliseconds(TIMER_LED_1, Off_Delay_Milliseconds_1)) { - Off_Delay_Milliseconds_1 = 0; - led_off(LED_1); - } - } - if (Off_Delay_Milliseconds_2) { - if (timer_elapsed_milliseconds(TIMER_LED_2, Off_Delay_Milliseconds_2)) { - Off_Delay_Milliseconds_2 = 0; - led_off(LED_2); - } - } - if (Off_Delay_Milliseconds_3) { - if (timer_elapsed_milliseconds(TIMER_LED_3, Off_Delay_Milliseconds_3)) { - Off_Delay_Milliseconds_3 = 0; - led_off(LED_3); - } - } - if (Off_Delay_Milliseconds_4) { - if (timer_elapsed_milliseconds(TIMER_LED_4, Off_Delay_Milliseconds_4)) { - Off_Delay_Milliseconds_4 = 0; - led_off(LED_4); + uint8_t i; /* loop counter */ + + for (i = 0; i < MAX_LEDS; i++) { + if (timer_interval_expired(&Off_Delay_Timer[i])) { + timer_interval_no_expire(&Off_Delay_Timer[i]); + led_off(i); } } } @@ -199,13 +169,14 @@ void led_task( void led_init( void) { + uint8_t i; /* loop counter */ + /* configure the port pins as outputs */ BIT_SET(DDRC, DDC7); BIT_SET(DDRC, DDC6); BIT_SET(DDRD, DDD7); BIT_SET(DDRD, DDD6); - led_off(LED_1); - led_off(LED_2); - led_off(LED_3); - led_off(LED_4); + for (i = 0; i < MAX_LEDS; i++) { + led_off(i); + } } diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/main.c b/bacnet-stack/ports/bdk-atxx4-mstp/main.c index 823b7841..62e837aa 100644 --- a/bacnet-stack/ports/bdk-atxx4-mstp/main.c +++ b/bacnet-stack/ports/bdk-atxx4-mstp/main.c @@ -54,6 +54,11 @@ const char *BACnet_Version = "1.0"; /* MAC Address of MS/TP */ static uint8_t MSTP_MAC_Address; +/* timer for device communications control */ +static struct itimer DCC_Timer; +#define DCC_CYCLE_SECONDS 1 +/* timer for test task */ +static struct itimer Test_Timer; /* For porting to IAR, see: http://www.avrfreaks.net/wiki/index.php/Documentation:AVR_GCC/IarToAvrgcc*/ @@ -114,7 +119,9 @@ static void bacnet_init( /* handle communication so we can shutup when asked */ apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, handler_device_communication_control); - + /* start the cyclic 1 second timer for DCC */ + timer_interval_start_seconds(&DCC_Timer, DCC_CYCLE_SECONDS); + /* Hello World! */ Send_I_Am(&Handler_Transmit_Buffer[0]); } @@ -149,9 +156,9 @@ static void bacnet_task( Binary_Input_Present_Value_Set(i, binary_value); } /* handle the communication timer */ - if (timer_elapsed_seconds(TIMER_DCC, 1)) { - timer_reset(TIMER_DCC); - dcc_timer_seconds(1); + if (timer_interval_expired(&DCC_Timer)) { + timer_interval_reset(&DCC_Timer); + dcc_timer_seconds(DCC_CYCLE_SECONDS); } /* handle the messaging */ pdu_len = datalink_receive(&src, &PDUBuffer[0], sizeof(PDUBuffer), 0); @@ -163,9 +170,7 @@ static void bacnet_task( void test_init( void) { - timer_reset(TIMER_LED_3); - timer_reset(TIMER_LED_4); - timer_reset(TIMER_TEST); + timer_interval_start_seconds(&Test_Timer, 1); } void test_task( @@ -175,8 +180,8 @@ void test_task( uint8_t nbytes = 17; uint8_t data_register = 0; - if (timer_elapsed_seconds(TIMER_TEST, 1)) { - timer_reset(TIMER_TEST); + if (timer_interval_expired(&Test_Timer)) { + timer_interval_reset(&Test_Timer); buffer[8] = (MSTP_MAC_Address & BIT0) ? '1' : '0'; buffer[9] = (MSTP_MAC_Address & BIT1) ? '1' : '0'; buffer[10] = (MSTP_MAC_Address & BIT2) ? '1' : '0'; diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/rs485.c b/bacnet-stack/ports/bdk-atxx4-mstp/rs485.c index 5ba58cc6..ccb9d604 100644 --- a/bacnet-stack/ports/bdk-atxx4-mstp/rs485.c +++ b/bacnet-stack/ports/bdk-atxx4-mstp/rs485.c @@ -49,6 +49,18 @@ static uint32_t Baud_Rate = 9600; static uint8_t Receive_Buffer_Data[128]; static FIFO_BUFFER Receive_Buffer; +static struct etimer Silence_Timer; + +bool rs485_silence_time_elapsed(uint32_t milliseconds) +{ + return timer_elapsed_milliseconds(&Silence_Timer, milliseconds); +} + +void rs485_silence_time_reset(void) +{ + timer_elapsed_start(&Silence_Timer); +} + static void rs485_rts_init( void) { @@ -82,7 +94,7 @@ void rs485_turnaround_delay( /* wait a minimum 40 bit times since reception */ /* at least 1 ms for errors: rounding, clock tick */ turnaround_time = 1 + ((Tturnaround * 1000UL) / Baud_Rate); - while (!timer_elapsed_milliseconds(TIMER_SILENCE, turnaround_time)) { + while (!timer_elapsed_milliseconds(&Silence_Timer, turnaround_time)) { /* do nothing - wait for timer to increment */ }; } @@ -95,7 +107,7 @@ ISR(USART0_RX_vect) /* data is available */ data_byte = UDR0; (void) FIFO_Put(&Receive_Buffer, data_byte); - timer_reset(TIMER_SILENCE); + timer_elapsed_start(&Silence_Timer); } } @@ -144,7 +156,7 @@ void rs485_bytes_send( } /* Clear the Transmit Complete flag by writing a one to it. */ BIT_SET(UCSR0A, TXC0); - timer_reset(TIMER_SILENCE); + timer_elapsed_start(&Silence_Timer); led_off_delay(LED_2, 1); return; @@ -249,6 +261,7 @@ void rs485_init( { FIFO_Init(&Receive_Buffer, &Receive_Buffer_Data[0], (unsigned) sizeof(Receive_Buffer_Data)); + timer_elapsed_start(&Silence_Timer); rs485_rts_init(); rs485_usart_init(); rs485_init_nvdata(); diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/rs485.h b/bacnet-stack/ports/bdk-atxx4-mstp/rs485.h index 6fe90585..290e1a7d 100644 --- a/bacnet-stack/ports/bdk-atxx4-mstp/rs485.h +++ b/bacnet-stack/ports/bdk-atxx4-mstp/rs485.h @@ -60,6 +60,8 @@ extern "C" { void rs485_turnaround_delay( void); + void rs485_silence_time_reset(void); + bool rs485_silence_time_elapsed(uint32_t milliseconds); #ifdef __cplusplus } diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/timer.c b/bacnet-stack/ports/bdk-atxx4-mstp/timer.c new file mode 100644 index 00000000..c5d868fe --- /dev/null +++ b/bacnet-stack/ports/bdk-atxx4-mstp/timer.c @@ -0,0 +1,262 @@ +/************************************************************************** +* +* Copyright (C) 2009 Steve Karg +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*********************************************************************/ +#include +#include +#include "timer.h" + +/* generic elapsed timer handling */ + +/************************************************************************* +* Description: Sets the start time for an elapsed timer +* Returns: the value of the start timer +* Notes: none +*************************************************************************/ +void timer_elapsed_start( + struct etimer *t) +{ + uint32_t now = timer_milliseconds(); + + if (t) { + t->start = now; + } +} + +/************************************************************************* +* Description: Gets the amount of elapsed time in milliseconds +* Returns: elapsed time in milliseconds +* Notes: none +*************************************************************************/ +uint32_t timer_elapsed_time( + struct etimer *t) +{ + uint32_t now = timer_milliseconds(); + uint32_t delta = 0; + + if (t) { + delta = now - t->start; + } + + return delta; +} + +/************************************************************************* +* Description: Sets the start time with an offset +* Returns: elapsed time in milliseconds +* Notes: none +*************************************************************************/ +void timer_elapsed_start_offset( + struct etimer *t, + uint32_t offset) +{ + uint32_t now = timer_milliseconds(); + + if (t) { + t->start = now + offset; + } +} + +/************************************************************************* +* Description: Tests to see if time has elapsed +* Returns: true if time has elapsed +* Notes: none +*************************************************************************/ +bool timer_elapsed_milliseconds( + struct etimer *t, + uint32_t milliseconds) +{ + return (timer_elapsed_time(t) >= milliseconds); +} + +/************************************************************************* +* Description: Tests to see if time has elapsed +* Returns: true if time has elapsed +* Notes: none +*************************************************************************/ +bool timer_elapsed_seconds( + struct etimer *t, + uint32_t seconds) +{ + uint32_t milliseconds = seconds; + + milliseconds *= 1000L; + + return timer_elapsed_milliseconds(t, milliseconds); +} + +/************************************************************************* +* Description: Tests to see if time has elapsed +* Returns: true if time has elapsed +* Notes: none +*************************************************************************/ +bool timer_elapsed_minutes( + struct etimer *t, + uint32_t minutes) +{ + uint32_t milliseconds = minutes; + + milliseconds *= 1000L; + milliseconds *= 60L; + + return timer_elapsed_milliseconds(t, milliseconds); +} + +/************************************************************************* +* Description: Starts an interval timer +* Returns: nothing +* Notes: none +*************************************************************************/ +void timer_interval_start( + struct itimer *t, + uint32_t interval) +{ + if (t) { + t->start = timer_milliseconds(); + t->interval = interval; + } +} + +/************************************************************************* +* Description: Starts an interval timer +* Returns: nothing +* Notes: none +*************************************************************************/ +void timer_interval_start_seconds( + struct itimer *t, + uint32_t seconds) +{ + uint32_t interval = seconds; + + interval *= 1000L; + timer_interval_start(t, interval); +} + +/************************************************************************* +* Description: Starts an interval timer +* Returns: nothing +* Notes: none +*************************************************************************/ +void timer_interval_start_minutes( + struct itimer *t, + uint32_t minutes) +{ + uint32_t interval = minutes; + + interval *= 1000L; + interval *= 60L; + timer_interval_start(t, interval); +} + +/************************************************************************* +* Description: Determines the amount of time that has elapsed +* Returns: elapsed milliseconds +* Notes: none +*************************************************************************/ +uint32_t timer_interval_elapsed( + struct itimer *t) +{ + uint32_t now = timer_milliseconds(); + uint32_t delta = 0; + + if (t) { + delta = now - t->start; + } + + return delta; +} + +/************************************************************************* +* Description: Determines the amount of time that has elapsed +* Returns: elapsed milliseconds +* Notes: none +*************************************************************************/ +uint32_t timer_interval( + struct itimer *t) +{ + uint32_t interval = 0; + + if (t) { + interval = t->interval; + } + + return interval; +} + +/************************************************************************* +* Description: Tests to see if time has elapsed +* Returns: true if time has elapsed +* Notes: none +*************************************************************************/ +bool timer_interval_expired( + struct itimer *t) +{ + bool expired = false; + + if (t) { + if (t->interval) { + expired = timer_interval_elapsed(t) >= t->interval; + } + } + + return expired; +} + +/************************************************************************* +* Description: Sets the interval value to zero so it never expires +* Returns: nothing +* Notes: none +*************************************************************************/ +void timer_interval_no_expire( + struct itimer *t) +{ + if (t) { + t->interval = 0; + } +} + +/************************************************************************* +* Description: Adds another interval to the start time. Used for cyclic +* timers that won't lose ticks. +* Returns: nothing +* Notes: none +*************************************************************************/ +void timer_interval_reset( + struct itimer *t) +{ + if (t) { + t->start += t->interval; + } +} + +/************************************************************************* +* Description: Restarts the timer with the same interval +* Returns: nothing +* Notes: none +*************************************************************************/ +void timer_interval_restart( + struct itimer *t) +{ + if (t) { + t->start = timer_milliseconds(); + } +} diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/timer.h b/bacnet-stack/ports/bdk-atxx4-mstp/timer.h index 9d7be882..0c6b2016 100644 --- a/bacnet-stack/ports/bdk-atxx4-mstp/timer.h +++ b/bacnet-stack/ports/bdk-atxx4-mstp/timer.h @@ -30,28 +30,69 @@ /* Timer Module */ +/* elapsed timer structure */ +struct etimer { + uint32_t start; +}; +/* interval timer structure */ +struct itimer { + uint32_t start; + uint32_t interval; +}; + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ + /* these 3 functions are created in the hardware specific module */ void timer_init( void); - unsigned long timer_milliseconds( - unsigned index); + uint32_t timer_milliseconds(void); + uint32_t timer_milliseconds_set( + uint32_t value); + + /* these functions are in the generic timer.c module */ + + /* elapsed timer */ + void timer_elapsed_start( + struct etimer *t); + void timer_elapsed_start_offset( + struct etimer *t, + uint32_t offset); + uint32_t timer_elapsed_time( + struct etimer *t); bool timer_elapsed_milliseconds( - unsigned index, - unsigned long value); + struct etimer *t, + uint32_t value); bool timer_elapsed_seconds( - unsigned index, - unsigned long value); + struct etimer *t, + uint32_t value); bool timer_elapsed_minutes( - unsigned index, - unsigned long seconds); - unsigned long timer_milliseconds_set( - unsigned index, - unsigned long value); - unsigned long timer_reset( - unsigned index); + struct etimer *t, + uint32_t seconds); + + /* interval timer */ + void timer_interval_start( + struct itimer *t, + uint32_t interval); + void timer_interval_start_seconds( + struct itimer *t, + uint32_t interval); + void timer_interval_start_minutes( + struct itimer *t, + uint32_t interval); + bool timer_interval_expired( + struct itimer *t); + uint32_t timer_interval( + struct itimer *t); + uint32_t timer_interval_elapsed( + struct itimer *t); + void timer_interval_no_expire( + struct itimer *t); + void timer_interval_reset( + struct itimer *t); + void timer_interval_restart( + struct itimer *t); #ifdef __cplusplus } diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/timer2.c b/bacnet-stack/ports/bdk-atxx4-mstp/timer2.c index d8165447..4253f4e9 100644 --- a/bacnet-stack/ports/bdk-atxx4-mstp/timer2.c +++ b/bacnet-stack/ports/bdk-atxx4-mstp/timer2.c @@ -26,11 +26,6 @@ #include "hardware.h" #include "timer.h" -/* define various timers in timer.h file */ -#ifndef MAX_MILLISECOND_TIMERS -#define MAX_MILLISECOND_TIMERS 2 -#endif - /* Timer2 Prescaling: 1, 8, 32, 64, 128, 256, or 1024 */ #define TIMER2_PRESCALER 128 /* Count: Timer counts up to 0xFF and then signals overflow */ @@ -40,24 +35,8 @@ #endif #define TIMER2_COUNT (0xFF-TIMER2_TICKS) -/* counter for the various timers */ -static volatile unsigned long Millisecond_Counter[MAX_MILLISECOND_TIMERS]; - -/************************************************************************* -* Description: Timer Interrupt Handler -* Returns: none -* Notes: Global interupts must be enabled -*************************************************************************/ -static inline void timer_interrupt_handler( - void) -{ - unsigned i; /* loop counter */ - - /* increment the tick count */ - for (i = 0; i < MAX_MILLISECOND_TIMERS; i++) { - Millisecond_Counter[i]++; - } -} +/* counter for the the timer which wraps every 49.7 days */ +static volatile uint32_t Millisecond_Counter; /************************************************************************* * Description: Timer Interrupt Service Routine - Timer Overflowed! @@ -68,7 +47,7 @@ ISR(TIMER2_OVF_vect) { /* Set the counter for the next interrupt */ TCNT2 = TIMER2_COUNT; - timer_interrupt_handler(); + Millisecond_Counter++; } /************************************************************************* @@ -76,20 +55,17 @@ ISR(TIMER2_OVF_vect) * Returns: none * Notes: none *************************************************************************/ -unsigned long timer_milliseconds_set( - unsigned index, - unsigned long value) +uint32_t timer_milliseconds_set( + uint32_t value) { uint8_t sreg = 0; /* holds interrupts pending */ - unsigned long old_value = 0; /* return value */ + uint32_t old_value = 0; /* return value */ - if (index < MAX_MILLISECOND_TIMERS) { - sreg = SREG; - __disable_interrupt(); - old_value = Millisecond_Counter[index]; - Millisecond_Counter[index] = value; - SREG = sreg; - } + sreg = SREG; + __disable_interrupt(); + old_value = Millisecond_Counter; + Millisecond_Counter = value; + SREG = sreg; return old_value; } @@ -99,76 +75,25 @@ unsigned long timer_milliseconds_set( * Returns: none * Notes: none *************************************************************************/ -unsigned long timer_milliseconds( - unsigned index) +uint32_t timer_milliseconds(void) { - unsigned long timer_value = 0; /* return value */ + uint32_t timer_value = 0; /* return value */ uint8_t sreg = 0; /* holds interrupts pending */ - if (index < MAX_MILLISECOND_TIMERS) { - sreg = SREG; - __disable_interrupt(); - timer_value = Millisecond_Counter[index]; - SREG = sreg; - } + sreg = SREG; + __disable_interrupt(); + timer_value = Millisecond_Counter; + SREG = sreg; return timer_value; } -/************************************************************************* -* Description: compares the current time count with a value -* Returns: true if the time has elapsed -* Notes: none -*************************************************************************/ -bool timer_elapsed_milliseconds( - unsigned index, - unsigned long value) -{ - return (timer_milliseconds(index) >= value); -} - -/************************************************************************* -* Description: compares the current time count with a value -* Returns: true if the time has elapsed -* Notes: none -*************************************************************************/ -bool timer_elapsed_seconds( - unsigned index, - unsigned long seconds) -{ - return ((timer_milliseconds(index) / 1000UL) >= seconds); -} - -/************************************************************************* -* Description: compares the current time count with a value -* Returns: true if the time has elapsed -* Notes: none -*************************************************************************/ -bool timer_elapsed_minutes( - unsigned index, - unsigned long minutes) -{ - return ((timer_milliseconds(index) / (1000UL * 60UL)) >= minutes); -} - -/************************************************************************* -* Description: Sets the timer counter to zero. -* Returns: none -* Notes: none -*************************************************************************/ -unsigned long timer_reset( - unsigned index) -{ - return timer_milliseconds_set(index, 0); -} - /************************************************************************* * Description: Initialization for Timer * Returns: none * Notes: none *************************************************************************/ -static void timer2_init( - void) +void timer_init(void) { /* Normal Operation */ TCCR2A = 0; @@ -210,14 +135,3 @@ static void timer2_init( /* Clear the Power Reduction Timer/Counter0 */ BIT_CLEAR(PRR, PRTIM2); } - -/************************************************************************* -* Description: Initialization for Timer -* Returns: none -* Notes: none -*************************************************************************/ -void timer_init( - void) -{ - timer2_init(); -}