/*
 * FreeModbus Libary: BARE Port
 * Copyright (C) 2006 Christian Walter <wolti@sil.at>
 *
 * 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: porttimer.c,v 1.1 2011/10/25 22:39:24 bobh Exp $
 */

/* ----------------------- Platform includes --------------------------------*/
#include "port.h"

/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mbport.h"

/* ----------------------- Start implementation -----------------------------*/

/* If baudrate > 19200 then we should use the fixed timer values
* t35 = 1750us. Otherwise t35 must be 3.5 times the character time.
*/

/* TIMER setup  */
#define FOSC    3686400
#define FCY     (FOSC/2)
#define FS      570		 /* frequency should be 570 for 1750 us*/

#define SAMPPRD (FCY/FS)-1

BOOL
xMBPortTimersInit( USHORT usTim1Timerout50us )
{
   /* you should never have a timeout less than a millisecond */
   if ( usTim1Timerout50us < 20)
      return FALSE;

   /* make sure the timeout timer is disabled */
   vMBPortTimersDisable();

//    PR1 = SAMPPRD;				/* changed 4/28/2015, rah */
						/* to use real code below */
    PR1 = (FCY/20000)*usTim1Timerout50us;
    T1CON = 0x0000;
    
    /* set timer interrupt priority to 2 */
    _T1IP = 2;

    /* Enable the timer interrupt	*/
    IEC0bits.T1IE = 1;
    IFS0bits.T1IF = 0;

    return TRUE;
}

inline void
vMBPortTimersEnable(  )
{
    /* clear timer count */
    TMR1 = 0;           
    /* start timer */
    T1CONbits.TON = 1;  
}

inline void
vMBPortTimersDisable(  )
{
    /* Disable any pending timers. */
    ENTER_CRITICAL_SECTION();
   
    /* stop timer */
    T1CONbits.TON = 0;  
    /* clear irq flag just in case */
    /* it fired in this critical section */
    IFS0bits.T1IF = 0; 
    
    EXIT_CRITICAL_SECTION();
}

/* 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.
 */
void __attribute__ ((interrupt,no_auto_psv)) _T1Interrupt(void)
{
    IFS0bits.T1IF = 0;
    pxMBPortCBTimerExpired();
}

