///
/// @file timers.h
/// @authors k. headley
/// @date DD MMM 2015

/// Timer IO API : interval, delay, sleep, etc.

/// @sa doxygen-examples.c for more examples of Doxygen markup

/////////////////////////
// Terms of use
/////////////////////////
/*
 Copyright Information
  
 Copyright 2002-2017 MBARI
 Monterey Bay Aquarium Research Institute, all rights reserved.
 
 Terms of Use
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 3 of the License, or
 (at your option) any later version. You can access the GPLv3 license at
 http://www.gnu.org/licenses/gpl-3.0.html
 
 This program 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 General Public License for more details
 (http://www.gnu.org/licenses/gpl-3.0.html)
 
 MBARI provides the documentation and software code "as is", with no warranty,
 express or implied, as to the software, title, non-infringement of third party
 rights, merchantability, or fitness for any particular purpose, the accuracy of
 the code, or the performance or results which you may obtain from its use. You
 assume the entire risk associated with use of the code, and you agree to be
 responsible for the entire cost of repair or servicing of the program with
 which you are using the code.
 
 In no event shall MBARI be liable for any damages, whether general, special,
 incidental or consequential damages, arising out of your use of the software,
 including, but not limited to, the loss or corruption of your data or damages
 of any kind resulting from use of the software, any prohibited use, or your
 inability to use the software. You agree to defend, indemnify and hold harmless
 MBARI and its officers, directors, and employees against any claim, loss,
 liability or expense, including attorneys' fees, resulting from loss of or
 damage to property or the injury to or death of any person arising out of the
 use of the software.
 
 The MBARI software is provided without obligation on the part of the
 Monterey Bay Aquarium Research Institute to assist in its use, correction,
 modification, or enhancement.
 
 MBARI assumes no responsibility or liability for any third party and/or
 commercial software required for the database or applications. Licensee agrees
 to obtain and maintain valid licenses for any additional third party software
 required.
 */

// Always do this
#ifndef TIMERS_H
#define TIMERS_H

/////////////////////////
// Includes 
/////////////////////////
#include "cwgsys.h"
#include "pic24.h"

/////////////////////////
// Macros
/////////////////////////
/// @def TFLAG_BITS(b)
/// @brief return timer flag bits 
/// @param b bitmask
#define TFLAG_BITS(b)     (g_tkpps_flags&b)
/// @def TFLAG_SET_BITS(b)
/// @brief set timer flag bits
/// @param b bitmask
#define TFLAG_SET_BITS(b) (g_tkpps_flags|=b)
/// @def TFLAG_CLR_BITS(b) 
/// @brief clear timer flag bits
/// @param b bitmask
#define TFLAG_CLR_BITS(b) (g_tkpps_flags&=(~b))

/////////////////////////
// Type Definitions
/////////////////////////
/// @typedef uint32_t TickCount_t
/// @brief timer tick count type
typedef uint32_t TickCount_t; 

/// @typedef  struct Timer_s Timer
/// @brief count down timer struct
typedef struct Timer_s{
    /// @var Timer::active
    /// @brief timer active 0:not running >0 running
    BYTE active; 
    /// @var Timer::ticksLeft
    /// @brief number of ticks remaining
    TickCount_t ticksLeft; 
    /// @var Timer::lastRead
    /// @brief system tick count at last update
    TickCount_t lastRead; 
}Timer;

/// @typedef  enum timer_flags
/// @brief timer flag enum
/// set by TMR2 ISR every 1,2 Hz
/// there are 3 of each: bits 0:1 1 Hz, 2:4 2 Hz
/// callers typically read/clear them
typedef enum{
    TFLAG_1HZ_0=0x0001,
    TFLAG_1HZ_1=0x0002,
    TFLAG_1HZ_2=0x0004,
    TFLAG_1HZ_3=0x0008,
    TFLAG_2HZ_0=0x0010,
    TFLAG_2HZ_1=0x0020,
    TFLAG_2HZ_2=0x0040,
    TFLAG_2HZ_3=0x0080,
    TFLAG_1HZ=0x000F,
    TFLAG_2HZ=0x00F0,
    TFLAG_ALL=0xFFFF
}timer_flags;

/////////////////////////
// Exports
/////////////////////////

#ifdef __cplusplus
extern "C" {
#endif
/// @var extern volatile TickCount_t SysTickCount
/// @brief system timer ticks global var
extern volatile TickCount_t SysTickCount; 
extern volatile uint16_t g_tkpps_flags;
extern uint16_t g_tkidle_flags;

/// @fn uint16_t tkReadClr(uint16_t mask)
/// @brief read and clear timer flags
/// @param mask bitmask
/// @return g_tkpps_flags value read
uint16_t tkReadClr(uint16_t mask);

/// @fn void tkInit()
/// @brief initialize timer structures
/// @return none
void tkInit();

/// @fn UINT32 tkTmrStart(Timer* tmr)
/// @brief start a timer
/// @param tmr pointer to timer to start
/// @return ticks left on timer
UINT32 tkTmrStart(Timer* tmr);

/// @fn UINT32 tkTmrStop(Timer* tmr)
/// @brief stop a timer
/// @param tmr timer to stop (can be resumed later)
/// @return Ticks left on timer
UINT32 tkTmrStop(Timer* tmr);

/// @fn void tkTmrReset(Timer* tmr)
/// @brief reset a timer
/// @param zero and disable
/// @return none
void tkTmrReset(Timer* tmr);

/// @fn void tkTmrSet(Timer* tmr, UINT32 period_msec)
/// @brief set a timer (doesn't start it)
/// @param tmr timer to set
/// @param duration number of ticks
/// @return none
void tkTmrSet(Timer* tmr, UINT32 period_msec);

/// @fn UINT32 tkTmrUpdate(Timer* tmr)
/// @brief get time left on time
/// @param tmr timer to check on
/// @return tick left, or 0 if expired
UINT32 tkTmrUpdate(Timer* tmr);

/// @fn void tkDelayTicks(TickCount_t ticks)
/// @brief do nothing for awhile
/// @param ticks number of ticks to wait
/// @return none
void tkDelayTicks(TickCount_t ticks);

/// @fn void tkDelayMs(unsigned int ms)
/// @brief do nothing for some ms
/// @param ms time in milliseconds to wait
/// @return none
void tkDelayMs(unsigned int ms);

/// @fn unsigned long tkGetUptime()
/// @brief get uptime in seconds
/// @return seconds since boot(~500day rollover)
unsigned long tkGetUptime();

/// @fn return_code_t tkDoIdle(UINT32 duration)
/// @brief put system to idle 
/// @param duration maximum time to sleep for (ms), must be at least 
/// SYS_MIN_SLEEP_MSEC ms to go to idle
/// @return ERR_SUCCESS if slept the whole time
/// ERR_FAILURE if something (non T1 ISR) woke it up
return_code_t tkDoIdle(UINT32 duration);

/// @fn TickCount_t tkGetTicks()
/// @brief put system to idle 
/// @return time ticks remaining
TickCount_t tkGetTicks();

/// @fn void TMR2_CallBack(void)
/// @brief TMR2 ISR callback 
/// @return none
//void TMR2_CallBack(void);
void __attribute__ ((weak)) TMR2_CallBack(void);

#ifdef __cplusplus
}
#endif

#endif // THIS_FILE





