|
- /*!
- * \file jiffies.c
- * \brief
- * A target independent jiffy functionality
- *
- * Author: Christos Choutouridis AEM: 8997
- * email : <cchoutou@ece.auth.gr>
- *
- */
- #include "jiffies.h"
-
- static jf_t _jf;
-
- #define JF_MAX_TIM_VALUE (0xFFFF) // 16bit counters
-
- /*
- * ====================== Public functions ======================
- */
-
- /*
- * Link and Glue functions
- */
-
- /*!
- * \brief
- * Connect the Driver's Set frequency function to jiffy struct
- * \note
- * This function get a freq value and returns the timers max jiffy value
- * (usual this refers to timer'sauto reload value).
- */
- void jf_link_setfreq (jf_setfreq_pt pfun) {
- _jf.setfreq = (pfun != 0) ? pfun : 0;
- }
-
- /*!
- * \brief
- * Connect the timer's value to jiffy struct
- */
- void jf_link_value (jiffy_t* v) {
- _jf.value = (v != 0) ? v : 0;
- }
-
-
-
- /*
- * User Functions
- */
-
- /*!
- * \brief
- * Check jiffy's status
- * \return status
- */
- inline drv_status_en jf_probe (void) {
- return _jf.status;
- }
-
- /*!
- * \brief
- * De-Initialize the jf data and un-connect the functions
- * from the driver
- */
- void jf_deinit (void)
- {
- if (_jf.setfreq) _jf.setfreq (0, 0);
- memset ((void*)&_jf, 0, sizeof (jf_t));
- _jf.status = DRV_NODEV;
- }
-
- /*!
- * \brief
- * Initialize the jf to a desired jiffy frequency
- * \note
- * This function has no effect if the inner jiffy struct
- * is un-connected to driver. So you have to call
- * \sa jf_connect_setfreq() and \sa jf_connect_value() first.
- * \return The status of the operation
- * \arg DRV_ERROR If the init process fail
- * \arg DRV_NODEV If there is no linked jiffy HW, no setfreq function
- * \arg DRV_READY Success
- */
- drv_status_en jf_init (uint32_t jf_freq, jiffy_t jiffies)
- {
- if (_jf.setfreq) {
- _jf.status = DRV_NOINIT;
- if ( _jf.setfreq (jf_freq, jiffies) )
- return DRV_ERROR;
- _jf.jiffies = jiffies;
- _jf.freq = jf_freq;
- _jf.jp1ms = jf_per_msec ();
- _jf.jp1us = jf_per_usec ();
- _jf.jp100ns = jf_per_100nsec ();
- return _jf.status = DRV_READY;
- }
- return _jf.status = DRV_NODEV;
- }
-
- /*!
- * \brief
- * Return the maximum jiffy value.
- */
- jiffy_t jf_get_jiffies (void){
- return _jf.jiffies;
- }
-
- /*!
- * \brief
- * Return the current jiffy value.
- * \note
- * Usual this function returns the value of a register from a timer peripheral
- * in the MCU. Keep in mind that its value is a moving target!
- */
- jiffy_t jf_get_jiffy (void){
- return *_jf.value;
- }
-
- /*!
- * \brief
- * Return the systems best approximation for jiffies per msec
- * \return
- * The calculated value or zero if no calculation can apply
- *
- * \note
- * The result tend to differ as the jiffies and freq values decreasing
- */
- jiffy_t jf_per_msec (void)
- {
- jiffy_t jf = (jiffy_t)(_jf.freq / 1000);
- /* 1
- * 1000Hz = ----- , Its not a magic number
- * 1msec
- */
- if (jf <= 1) return 1;
- else return jf;
- }
-
- /*!
- * \brief
- * Return the systems best approximation for jiffies per usec
- * \return
- * The calculated value or zero if no calculation can apply
- *
- * \note
- * The result tend to differ as the jiffies and freq values decreasing
- */
- jiffy_t jf_per_usec (void)
- {
- jiffy_t jf = (jiffy_t)(_jf.freq / 1000000);
- /* 1
- * 1000000Hz = ------ , Its not a magic number
- * 1usec
- */
- if (jf <= 1) return 1;
- else return jf;
- }
-
- /*!
- * \brief
- * Return the systems best approximation for jiffies per usec
- * \return
- * The calculated value or zero if no calculation can apply
- *
- * \note
- * The result tend to differ as the jiffies and freq values decreasing
- */
- jiffy_t jf_per_100nsec (void)
- {
- jiffy_t jf = (jiffy_t)(_jf.freq / 10000000);
- /* 1
- * 10000000Hz = ------- , Its not a magic number
- * 100nsec
- */
- if (jf <= 1) return 1;
- else return jf;
- }
-
- /*!
- * \brief
- * A code based delay implementation, using jiffies for timing.
- * This is NOT accurate but it ensures that the time passed is always
- * more than the requested value.
- * The delay values are multiplications of 1 msec.
- * \param msec Time in msec for delay
- */
- void jf_delay_ms (jtime_t msec)
- {
- jtime_t m, m2, m1 = (jtime_t)*_jf.value;
-
- msec *= _jf.jp1ms;
-
- // Eat the time difference from msec value.
- do {
- m2 = (jtime_t)(*_jf.value);
- m = m2 - m1;
- msec -= (m>=0) ? m : _jf.jiffies + m;
- m1 = m2;
- } while (msec>0);
- }
-
- /*!
- * \brief
- * A code based delay implementation, using jiffies for timing.
- * This is NOT accurate but it ensures that the time passed is always
- * more than the requested value.
- * The delay values are multiplications of 1 usec.
- * \param usec Time in usec for delay
- */
- void jf_delay_us (jtime_t usec)
- {
- jtime_t m, m2, m1 = (jtime_t)*_jf.value;
-
- usec *= _jf.jp1us;
- if ((jtime_t)(*_jf.value) - m1 > usec) // Very small delays may return here.
- return;
-
- // Eat the time difference from usec value.
- do {
- m2 = (jtime_t)(*_jf.value);
- m = m2 - m1;
- usec -= (m>=0) ? m : _jf.jiffies + m;
- m1 = m2;
- } while (usec>0);
- }
-
- /*!
- * \brief
- * A code based delay implementation, using jiffies for timing.
- * This is NOT accurate but it ensures that the time passed is always
- * more than the requested value.
- * The delay values are multiplications of 100 nsec.
- * \param _100nsec Time in 100nsec for delay
- */
- void jf_delay_100ns (jtime_t _100nsec)
- {
- jtime_t m, m2, m1 = (jtime_t)*_jf.value;
-
- _100nsec *= _jf.jp100ns;
- if ((jtime_t)(*_jf.value) - m1 > _100nsec) // Very small delays may return here.
- return;
-
- // Eat the time difference from _100nsec value.
- do {
- m2 = (jtime_t)(*_jf.value);
- m = m2 - m1;
- _100nsec -= (m>=0) ? m : _jf.jiffies + m;
- m1 = m2;
- } while (_100nsec>0);
- }
-
- /*!
- * \brief
- * A code based polling version delay implementation, using jiffies for timing.
- * This is NOT accurate but it ensures that the time passed is always
- * more than the requested value.
- * The delay values are multiplications of 1 msec.
- * \param msec Time in msec for delay
- * \return The status of ongoing delay
- * \arg 0: Delay time has passed
- * \arg 1: Delay is ongoing, keep calling
- */
- int jf_check_msec (jtime_t msec)
- {
- static jtime_t m1=-1, cnt;
- jtime_t m, m2;
-
- if (m1 == -1) {
- m1 = *_jf.value;
- cnt = _jf.jp1ms * msec;
- }
-
- // Eat the time difference from msec value.
- if (cnt>0) {
- m2 = (jtime_t)(*_jf.value);
- m = m2-m1;
- cnt -= (m>=0) ? m : _jf.jiffies + m;
- m1 = m2;
- return 1; // wait
- }
- else {
- m1 = -1;
- return 0; // do not wait any more
- }
- }
-
- /*!
- * \brief
- * A code based polling version delay implementation, using jiffies for timing.
- * This is NOT accurate but it ensures that the time passed is always
- * more than the requested value.
- * The delay values are multiplications of 1 usec.
- * \param usec Time in usec for delay
- * \return The status of ongoing delay
- * \arg 0: Delay time has passed
- * \arg 1: Delay is ongoing, keep calling
- */
- int jf_check_usec (jtime_t usec)
- {
- static jtime_t m1=-1, cnt;
- jtime_t m, m2;
-
- if (m1 == -1) {
- m1 = *_jf.value;
- cnt = _jf.jp1us * usec;
- }
-
- // Eat the time difference from usec value.
- if (cnt>0) {
- m2 = (jtime_t)(*_jf.value);
- m = m2-m1;
- cnt -= (m>=0) ? m : _jf.jiffies + m;
- m1 = m2;
- return 1; // wait
- }
- else {
- m1 = -1;
- return 0; // do not wait any more
- }
- }
-
-
- /*!
- * \brief
- * A code based polling version delay implementation, using jiffies for timing.
- * This is NOT accurate but it ensures that the time passed is always
- * more than the requested value.
- * The delay values are multiplications of 100 nsec.
- * \param
- * _100nsec Time in 100nsec for delay
- * \return The status of ongoing delay
- * \arg 0: Delay time has passed
- * \arg 1: Delay is ongoing, keep calling
- */
- int jf_check_100nsec (jtime_t _100nsec)
- {
- static jtime_t m1=-1, cnt;
- jtime_t m, m2;
-
- if (m1 == -1) {
- m1 = *_jf.value;
- cnt = _jf.jp100ns * _100nsec;
- }
-
- // Eat the time difference from _100nsec value.
- if (cnt>0) {
- m2 = (jtime_t)(*_jf.value);
- m = m2-m1;
- cnt -= (m>=0) ? m : _jf.jiffies + m;
- m1 = m2;
- return 1; // wait
- }
- else {
- m1 = -1;
- return 0; // do not wait any more
- }
- }
|