Add DIV_ROUND macro.
authorbatt <batt@38d2e660-2303-0410-9eaa-f027e97ec537>
Tue, 23 Oct 2007 15:57:59 +0000 (15:57 +0000)
committerbatt <batt@38d2e660-2303-0410-9eaa-f027e97ec537>
Tue, 23 Oct 2007 15:57:59 +0000 (15:57 +0000)
git-svn-id: https://src.develer.com/svnoss/bertos/trunk@932 38d2e660-2303-0410-9eaa-f027e97ec537

cfg/macros.h
cpu/arm/drv/kdebug_at91.c
cpu/avr/drv/kdebug_avr.c
cpu/avr/drv/ser_avr.c
cpu/avr/drv/ser_simple_avr.c
cpu/avr/drv/timer_avr.h
drv/phase.c
drv/timer.h

index 5e9e25ed04fcf4dd75ef4f8e0d38d8e586e64f49..b3be457fb9b8c185aa0d1932678fdc39db1403cc 100644 (file)
  * \author Bernardo Innocenti <bernie@develer.com>
  * \author Giovanni Bajo <rasky@develer.com>
  */
-
-/*#*
- *#* $Log$
- *#* Revision 1.11  2007/02/06 15:22:12  asterix
- *#* Add ROTL and ROTR macros for bit rotating.
- *#*
- *#* Revision 1.10  2006/09/13 18:31:37  bernie
- *#* BV8(), BV16(), BV32(): New macros for CPUs with small word size; SWAP_T(): New macro to support old compilers.
- *#*
- *#* Revision 1.9  2006/07/19 12:56:25  bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.8  2006/03/13 02:06:55  bernie
- *#* ROUND_UP2: Rename from ROUND2.
- *#*
- *#* Revision 1.7  2006/02/20 14:34:58  bernie
- *#* Use portable type checking.
- *#*
- *#* Revision 1.6  2006/02/10 12:36:57  bernie
- *#* Pacify IAR warnings for side-effects.
- *#*
- *#* Revision 1.5  2005/11/04 16:20:01  bernie
- *#* Fix reference to README.devlib in header.
- *#*
- *#* Revision 1.4  2005/07/03 15:19:09  bernie
- *#* Doxygen fix.
- *#*
- *#* Revision 1.3  2005/06/27 21:23:32  bernie
- *#* ROUND_DOWN, ROUND_UP, ROUND_NEAREST: New macros.
- *#*
- *#* Revision 1.2  2005/04/11 19:10:27  bernie
- *#* Include top-level headers from cfg/ subdir.
- *#*
- *#* Revision 1.1  2005/04/11 19:04:13  bernie
- *#* Move top-level headers to cfg/ subdir.
- *#*
- *#* Revision 1.10  2005/01/22 04:19:50  bernie
- *#* Use non-uglified typeof().
- *#*
- *#* Revision 1.9  2004/12/08 08:51:34  bernie
- *#* Add type-generic macros for C++.
- *#*
- *#* Revision 1.8  2004/10/19 07:14:20  bernie
- *#* Add macros to test for specific compiler features.
- *#*
- *#* Revision 1.7  2004/09/20 03:30:45  bernie
- *#* C++ also has variadic macros.
- *#*
- *#* Revision 1.6  2004/09/14 21:02:04  bernie
- *#* SWAP(), MINMAX(): New macros.
- *#*
- *#* Revision 1.5  2004/08/29 21:57:58  bernie
- *#* Move back STATIC_ASSERT() to compiler.h as it's needed in cpu.h;
- *#* iptr_t, const_iptr_t: Replace IPTR macro with a real typedef.
- *#*
- *#* Revision 1.3  2004/08/24 14:13:48  bernie
- *#* Restore a few macros that were lost in the way.
- *#*
- *#* Revision 1.2  2004/08/24 13:32:14  bernie
- *#* PP_CAT(), PP_STRINGIZE(): Move back to compiler.h to break circular dependency between cpu.h/compiler.h/macros.h;
- *#* offsetof(), countof(): Move back to compiler.h to avoid including macros.h almost everywhere;
- *#* Trim CVS log;
- *#* Rename header guards;
- *#* Don't include arch_config.h in compiler.h as it's not needed there.
- *#*
- *#* Revision 1.1  2004/08/14 19:37:57  rasky
- *#* Merge da SC: macros.h, pool.h, BIT_CHANGE, nome dei processi, etc.
- *#*
- *#* Revision 1.4  2004/08/14 18:36:50  rasky
- *#* Doxygen fix e un livello di parentesi aggiuntivi per la macro
- *#*
- *#* Revision 1.3  2004/08/12 20:01:32  rasky
- *#* Aggiunte macro BIT_CHANGE e BIT_CHANGE_BV
- *#*
- *#* Revision 1.2  2004/08/10 21:36:14  rasky
- *#* Aggiunto include macros.h dove serve
- *#* Aggiunta dipendenza da compiler.h in macros.h
- *#*
- *#* Revision 1.1  2004/08/10 21:30:00  rasky
- *#* Estratte le funzioni macro in macros.h
- *#*
- *#*/
-
-#ifndef MACROS_H
-#define MACROS_H
+#ifndef CFG_MACROS_H
+#define CFG_MACROS_H
 
 #include <cfg/compiler.h>
 
 /** Same as BV() but with 8 bit result */
 #define BV8(x)  ((uint8_t)1<<(x))
 
-
+/**
+ * Perform an integer division rounding the result to the nearest int value.
+ * \note \a divisor should preferibly be a costant, otherwise this macro generates
+ * 2 division. Also divisor is evaluated twice.
+ */
+#define DIV_ROUND(dividend, divisor)  (((dividend) + (divisor) / 2) / (divisor))
 
 /** Round up \a x to an even multiple of the 2's power \a pad. */
 #define ROUND_UP2(x, pad) (((x) + ((pad) - 1)) & ~((pad) - 1))
index 7de1c6d939e10b7c5552a779506e00034e0fe970..a5ec8343e7362a8fd30edd55bb516f4700f1ae41 100644 (file)
@@ -37,7 +37,7 @@
  */
 
 #include "kdebug_at91.h"
-#include <cfg/macros.h> /* for BV() */
+#include <cfg/macros.h> /* for BV(), DIV_ROUND */
 #include <appconfig.h>
 #include <hw_cpu.h>     /* for CLOCK_FREQ */
 #include <hw_ser.h>     /* Required for bus macros overrides */
@@ -71,7 +71,7 @@ INLINE void kdbg_hw_init(void)
                /* Reset DBGU */
                DBGU_CR =  BV(US_RSTRX) | BV(US_RSTTX) | BV(US_RXDIS) | BV(US_TXDIS);
                /* Set baudrate */
-               DBGU_BRGR = (CLOCK_FREQ + (16 * CONFIG_KDEBUG_BAUDRATE) / 2) / (16 * CONFIG_KDEBUG_BAUDRATE);
+               DBGU_BRGR = DIV_ROUND(CLOCK_FREQ, 16 * CONFIG_KDEBUG_BAUDRATE);
                /* Set DBGU mode to 8 data bits, no parity and 1 stop bit. */
                DBGU_MR =  US_CHMODE_NORMAL | US_CHRL_8 | US_PAR_NO | US_NBSTOP_1;
                /* Enable DBGU transmitter. */
index d3a77615447b0972399112d54cf19e25d56b4d94..35d0645d6867a61485ca708f3f5a3ce333a5fde1 100644 (file)
@@ -41,7 +41,7 @@
 
 #include <cpu/types.h>
 #include <cpu/attr.h>
-#include <cfg/macros.h> /* for BV() */
+#include <cfg/macros.h> /* for BV(), DIV_ROUND */
 #include <appconfig.h>
 #include <hw_cpu.h>     /* for CLOCK_FREQ */
 #include <hw_ser.h>     /* Required for bus macros overrides */
@@ -223,7 +223,7 @@ INLINE void kdbg_hw_init(void)
                SER_BITBANG_INIT;
        #else /* CONFIG_KDEBUG_PORT != 666 */
                /* Compute the baud rate */
-               uint16_t period = (((CLOCK_FREQ / 16UL) + (CONFIG_KDEBUG_BAUDRATE / 2)) / CONFIG_KDEBUG_BAUDRATE) - 1;
+               uint16_t period = DIV_ROUND(CLOCK_FREQ / 16UL, CONFIG_KDEBUG_BAUDRATE) - 1;
 
                #if (CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128)
                        #if CONFIG_KDEBUG_PORT == 0
index 495c52bafad0a1ed73bdcd9f1209d5122a49a0cf..d690a65f4566424913bc6abd8545062d2b48b3b3 100644 (file)
 #include <hw_cpu.h>  /* CLOCK_FREQ */
 #include <appconfig.h>
 
+#include <cfg/macros.h> /* DIV_ROUND */
 #include <cfg/debug.h>
 #include <drv/timer.h>
 #include <mware/fifobuf.h>
@@ -509,7 +510,7 @@ static void uart0_enabletxirq(struct SerialHardware *_hw)
 static void uart0_setbaudrate(UNUSED_ARG(struct SerialHardware *, _hw), unsigned long rate)
 {
        /* Compute baud-rate period */
-       uint16_t period = (((CLOCK_FREQ / 16UL) + (rate / 2)) / rate) - 1;
+       uint16_t period = DIV_ROUND(CLOCK_FREQ / 16UL, rate) - 1;
 
 #if !CPU_AVR_ATMEGA103
        UBRR0H = (period) >> 8;
@@ -562,7 +563,7 @@ static void uart1_enabletxirq(struct SerialHardware *_hw)
 static void uart1_setbaudrate(UNUSED_ARG(struct SerialHardware *, _hw), unsigned long rate)
 {
        /* Compute baud-rate period */
-       uint16_t period = (((CLOCK_FREQ / 16UL) + (rate / 2)) / rate) - 1;
+       uint16_t period = DIV_ROUND(CLOCK_FREQ / 16UL, rate) - 1;
 
        UBRR1H = (period) >> 8;
        UBRR1L = (period);
index 7805892a9912769604962e288c271ccac2f1f521..d71ce58530ebb84d5c677c96050f6f112517d7be 100644 (file)
@@ -136,7 +136,7 @@ void _ser_settimeouts(void)
 void _ser_setbaudrate(unsigned long rate)
 {
        /* Compute baud-rate period */
-       uint16_t period = (((CLOCK_FREQ / 16UL) + (rate / 2)) / rate) - 1;
+       uint16_t period = DIV_ROUND(CLOCK_FREQ / 16UL, rate) - 1;
 
        UBRR0H = (period) >> 8;
        UBRR0L = (period);
index 5d0eba36eb8e632738a9b1be21c72caca8a68aa1..74414263123c9dbcdd838f6a460ea6b2e8d0ec24 100644 (file)
@@ -88,6 +88,7 @@
 
 #include <appconfig.h>     /* CONFIG_TIMER */
 #include <cfg/compiler.h>  /* uint8_t */
+#include <cfg/macros.h>    /* DIV_ROUND */
 #include <hw_cpu.h>        /* CLOCK_FREQ */
 
 /**
        /** This value is the maximum in overflow based timers. */
        #define TIMER_HW_CNT         (1 << TIMER_HW_BITS)
        #define DEFINE_TIMER_ISR     SIGNAL(SIG_OVERFLOW1)
-       #define TIMER_TICKS_PER_SEC  ((TIMER_HW_HPTICKS_PER_SEC + TIMER_HW_CNT / 2) / TIMER_HW_CNT)
+       #define TIMER_TICKS_PER_SEC  DIV_ROUND(TIMER_HW_HPTICKS_PER_SEC, TIMER_HW_CNT)
 
        /// Type of time expressed in ticks of the hardware high precision timer
        typedef uint16_t hptime_t;
        /** This value is the maximum in overflow based timers. */
        #define TIMER_HW_CNT         (1 << TIMER_HW_BITS)
        #define DEFINE_TIMER_ISR     SIGNAL(SIG_OVERFLOW3)
-       #define TIMER_TICKS_PER_SEC  ((TIMER_HW_HPTICKS_PER_SEC + TIMER_HW_CNT / 2) / TIMER_HW_CNT)
+       #define TIMER_TICKS_PER_SEC  DIV_ROUND(TIMER_HW_HPTICKS_PER_SEC, TIMER_HW_CNT)
 
        /// Type of time expressed in ticks of the hardware high precision timer
        typedef uint16_t hptime_t;
 
 
 /** Frequency of the hardware high precision timer. */
-#define TIMER_HW_HPTICKS_PER_SEC  ((CLOCK_FREQ + TIMER_PRESCALER / 2) / TIMER_PRESCALER)
+#define TIMER_HW_HPTICKS_PER_SEC  DIV_ROUND(CLOCK_FREQ, TIMER_PRESCALER)
 
 /**
  * System timer: additional division after the prescaler
  * 12288000 / 64 / 192 (0..191) = 1 ms
  */
-#define OCR_DIVISOR  (((CLOCK_FREQ + TIMER_PRESCALER / 2) / TIMER_PRESCALER + TIMER_TICKS_PER_SEC / 2) / TIMER_TICKS_PER_SEC - 1)
+#define OCR_DIVISOR  (DIV_ROUND(DIV_ROUND(CLOCK_FREQ, TIMER_PRESCALER), TIMER_TICKS_PER_SEC) - 1)
 
 /** Not needed, IRQ timer flag cleared automatically */
 #define timer_hw_irq() do {} while (0)
index 04c895d780a6994d9a503aaac58fcf83db4dfadb..e30f46681e2694a562dc537ec21807df9ed9df72 100644 (file)
@@ -78,7 +78,7 @@ DEFINE_ZEROCROSS_ISR()
                if (triacs[dev].duty != TRIAC_MAX_DUTY)
                        TRIAC_OFF(dev);
                /* Compute delay from duty */
-               timer_setDelay(&triacs[dev].timer, ((period * (TRIAC_MAX_DUTY - triacs[dev].duty) + TRIAC_MAX_DUTY / 2) / TRIAC_MAX_DUTY));
+               timer_setDelay(&triacs[dev].timer, DIV_ROUND(period * (TRIAC_MAX_DUTY - triacs[dev].duty), TRIAC_MAX_DUTY));
 
                /* This check avoids inserting the same timer twice
                 * in case of an intempestive zerocross or spike */
index bcf10200c22191d3e65aa2a91e81a9c7b09e0eef..cd7aa1b48f6344f8bda8d235a4557b1b901b3f4b 100644 (file)
 #define DRV_TIMER_H
 
 #include <cfg/os.h>
+#include <cfg/macros.h>
 #include <cpu/attr.h>
 #include <cpu/irq.h>
 
+
 /*
  * Include platform-specific binding header if we're hosted.
  * Try the CPU specific one for bare-metal environments.
@@ -113,7 +115,7 @@ INLINE ticks_t ms_to_ticks(mtime_t ms)
        return (ms * TIMER_TICKS_PER_SEC) / 1000;
 #else
        /* Fast timer: don't overflow ticks_t. */
-       return ms * ((TIMER_TICKS_PER_SEC + 500) / 1000);
+       return ms * DIV_ROUND(TIMER_TICKS_PER_SEC, 1000);
 #endif
 }
 
@@ -125,7 +127,7 @@ INLINE ticks_t us_to_ticks(utime_t us)
        return ((us / 1000) * TIMER_TICKS_PER_SEC) / 1000;
 #else
        /* Fast timer: don't overflow ticks_t. */
-       return (us * ((TIMER_TICKS_PER_SEC + 500) / 1000)) / 1000;
+       return (us * DIV_ROUND(TIMER_TICKS_PER_SEC, 1000)) / 1000;
 #endif
 }
 
@@ -157,7 +159,7 @@ INLINE utime_t ticks_to_us(ticks_t ticks)
 INLINE hptime_t us_to_hptime(utime_t us)
 {
 #if TIMER_HW_HPTICKS_PER_SEC > 10000000UL
-       return us * ((TIMER_HW_HPTICKS_PER_SEC + 500000UL) / 1000000UL);
+       return us * DIV_ROUND(TIMER_HW_HPTICKS_PER_SEC, 1000000UL);
 #else
        return (us * ((TIMER_HW_HPTICKS_PER_SEC + 500) / 1000UL) + 500) / 1000UL;
 #endif
@@ -167,9 +169,9 @@ INLINE hptime_t us_to_hptime(utime_t us)
 INLINE utime_t hptime_to_us(hptime_t hpticks)
 {
 #if TIMER_HW_HPTICKS_PER_SEC < 100000UL
-       return hpticks * ((1000000UL + TIMER_HW_HPTICKS_PER_SEC / 2) / TIMER_HW_HPTICKS_PER_SEC);
+       return hpticks * DIV_ROUND(1000000UL, TIMER_HW_HPTICKS_PER_SEC);
 #else
-       return (hpticks * 1000UL) / ((TIMER_HW_HPTICKS_PER_SEC + 500) / 1000UL);
+       return (hpticks * 1000UL) / DIV_ROUND(TIMER_HW_HPTICKS_PER_SEC, 1000UL);
 #endif /* TIMER_HW_HPTICKS_PER_SEC < 100000UL */
 }