Merge from kseries
authoraleph <aleph@38d2e660-2303-0410-9eaa-f027e97ec537>
Mon, 2 Aug 2004 20:20:29 +0000 (20:20 +0000)
committeraleph <aleph@38d2e660-2303-0410-9eaa-f027e97ec537>
Mon, 2 Aug 2004 20:20:29 +0000 (20:20 +0000)
git-svn-id: https://src.develer.com/svnoss/bertos/trunk@99 38d2e660-2303-0410-9eaa-f027e97ec537

compiler.h
cpu.h
drv/kdebug.c
drv/ser.h
drv/ser_avr.c
drv/timer.c
drv/timer.h
drv/timer_avr.h
kern/proc.c
kern/switch_avr.S
mware/fifobuf.h

index 0f6e8f7b423dcd81e79556e58005f53470ed077c..a2689e8e46b770ee417a2a861d714140b3e20c8d 100755 (executable)
@@ -15,6 +15,9 @@
 
 /*
  * $Log$
+ * Revision 1.13  2004/08/02 20:20:29  aleph
+ * Merge from project_ks
+ *
  * Revision 1.12  2004/08/01 01:21:17  bernie
  * LIKELY(), UNLIKELY(): New compiler-specific macros.
  *
 
 
 /* Simple macros */
-#define ABS(a)      (((a) < 0) ? -(a) : (a))
-#define MIN(a,b)    (((a) < (b)) ? (a) : (b))
-#define MAX(a,b)    (((a) > (b)) ? (a) : (b))
+#if GNUC_PREREQ(2,0)
+       #define ABS(n) ({ \
+               __typeof__(n) _n = (n); \
+               (_n < 0) ? -_n : _n; \
+       })
+       #define MIN(a,b) ({ \
+               __typeof__(a) _a = (a); \
+               __typeof__(b) _b = (b); \
+               (void)(&_a == &_b); /* ensure same type */ \
+               (_a < _b) ? _a : _b; \
+       })
+       #define MAX(a,b) ({ \
+               __typeof__(a) _a = (a); \
+               __typeof__(b) _b = (b); \
+               (void)(&_a == &_b); /* ensure same type */ \
+               (_a > _b) ? _a : _b; \
+       })
+#else /* !GNUC */
+       /* Buggy macros for inferior compilers */
+       #define ABS(a)          (((a) < 0) ? -(a) : (a))
+       #define MIN(a,b)        (((a) < (b)) ? (a) : (b))
+       #define MAX(a,b)        (((a) > (b)) ? (a) : (b))
+#endif /* !GNUC */
 
 #ifndef BV
 /*! Convert a bit value to a binary flag */
diff --git a/cpu.h b/cpu.h
index f373b7b1ac55e2b3f9a3dc52a8b240dc797b0525..096a5563e5f39b97d61a73d82436b07b266c767b 100755 (executable)
--- a/cpu.h
+++ b/cpu.h
@@ -17,6 +17,9 @@
 
 /*
  * $Log$
+ * Revision 1.10  2004/08/02 20:20:29  aleph
+ * Merge from project_ks
+ *
  * Revision 1.9  2004/07/30 14:24:16  rasky
  * Task switching con salvataggio perfetto stato di interrupt (SR)
  * Kernel monitor per dump informazioni su stack dei processi
 #include "compiler.h"
 
 
-//! Initialization value for registers in stack frame
-#define CPU_REG_INIT_VALUE(reg)     0
-
-// Macros for determining CPU endianess
+// Macros for determining CPU endianness
 #define CPU_BIG_ENDIAN    0x1234
 #define CPU_LITTLE_ENDIAN 0x3412
 
 // Macros to include cpu-specific version of the headers
-#define CPU_HEADER(module)          PP_STRINGIZE(PP_CAT4(module, _, CPU_ID, .h))
+#define CPU_HEADER(module)          PP_STRINGIZE(PP_CAT3(module, _, CPU_ID).h)
 
 
 #if CPU_I196
        typedef uint8_t cpuflags_t;
        typedef uint8_t cpustack_t;
 
-       #define CPU_REGS_CNT            32
-       #define CPU_SAVED_REGS_CNT      18
+       /* Register counts include SREG too */
+       #define CPU_REGS_CNT            33
+       #define CPU_SAVED_REGS_CNT      19
        #define CPU_STACK_GROWS_UPWARD  0
        #define CPU_SP_ON_EMPTY_SLOT    1
        #define CPU_BYTE_ORDER          CPU_LITTLE_ENDIAN
+
+       /*!
+        * Initialization value for registers in stack frame.
+        * The register index is not directly corrispondent to CPU
+        * register numbers. Index 0 is the SREG register: the initial
+        * value is all 0 but the interrupt bit (bit 7).
+        */
+       #define CPU_REG_INIT_VALUE(reg) (reg == 0 ? 0x80 : 0)
+
+#endif
+
+
+//! Default for macro not defined in the right arch section
+#ifndef CPU_REG_INIT_VALUE
+       #define CPU_REG_INIT_VALUE(reg)     0
 #endif
 
 
index 063df825415520e6fc83b916daed2aa5fe59a22e..ff692b341fce67f1c23b6b1fc9c2c041050b145c 100755 (executable)
@@ -16,6 +16,9 @@
 
 /*
  * $Log$
+ * Revision 1.9  2004/08/02 20:20:29  aleph
+ * Merge from project_ks
+ *
  * Revision 1.8  2004/07/30 14:26:33  rasky
  * Semplificato l'output dell'ASSERT
  * Aggiunta ASSERT2 con stringa di help opzionalmente disattivabile
 #elif CPU_AVR
        #include <avr/io.h>
        #if CONFIG_KDEBUG_PORT == 0
+
+               /* External 485 transceiver on UART0 (to be overridden in "hw.h").  */
+               #if !defined(SER_UART0_485_INIT)
+                       #if defined(SER_UART0_485_RX) || defined(SER_UART0_485_TX)
+                               #error SER_UART0_485_INIT, SER_UART0_485_RX and SER_UART0_485_TX must be defined together
+                       #endif
+                       #define SER_UART0_485_INIT  do {} while (0)
+                       #define SER_UART0_485_TX    do {} while (0)
+                       #define SER_UART0_485_RX    do {} while (0)
+               #elif !defined(SER_UART0_485_RX) || !defined(SER_UART0_485_TX)
+                       #error SER_UART0_485_INIT, SER_UART0_485_RX and SER_UART0_485_TX must be defined together
+               #endif
+
                #if defined(__AVR_ATmega64__)
                        #define UCR UCSR0B
                        #define UDR UDR0
                        #define UCR UCSRB
                        #define USR UCSRA
                #endif
+
                #define KDBG_WAIT_READY()     do { loop_until_bit_is_set(USR, UDRE); } while(0)
-               #define KDBG_WRITE_CHAR(c)    do { UCR |= BV(TXEN); UDR = (c); } while(0)
-               #define KDBG_MASK_IRQ(old)    do { (old) = UCR & BV(TXCIE); cbi(UCR, TXCIE); } while(0)
-               #define KDBG_RESTORE_IRQ(old) do { UCR |= (old); } while(0)
+               #define KDBG_WAIT_TXDONE()    do { loop_until_bit_is_set(USR, TXC); } while(0)
+               /*
+                * BUG: before sending a new character the TXC flag is cleared to allow
+                * KDBG_WAIT_TXDONE() to work properly, but, if KDBG_WRITE_CHAR() is called
+                * after the RXC flag is set by hardware, a new TXC could be generated
+                * after we clear it and before the new character is put in UDR. In this
+                * case if a 485 is used the transceiver will be put in RX mode while
+                * transmitting the last char.
+                */
+               #define KDBG_WRITE_CHAR(c)    do { USR |= BV(TXC); UDR = (c); } while(0)
+
+               #define KDBG_MASK_IRQ(old)    do { \
+                       SER_UART0_485_TX; \
+                       (old) = UCR; \
+                       UCR |= BV(TXEN); \
+                       UCR &= ~(BV(TXCIE) | BV(UDRIE)); \
+               } while(0)
+
+               #define KDBG_RESTORE_IRQ(old) do { \
+                       KDBG_WAIT_TXDONE(); \
+                       SER_UART0_485_RX; \
+                       UCR = (old); \
+               } while(0)
+
        #elif CONFIG_KDEBUG_PORT == 1
+
+               /* External 485 transceiver on UART1 (to be overridden in "hw.h").  */
+               #ifndef SER_UART1_485_INIT
+                       #if defined(SER_UART1_485_RX) || defined(SER_UART1_485_TX)
+                               #error SER_UART1_485_INIT, SER_UART1_485_RX and SER_UART1_485_TX must be defined together
+                       #endif
+                       #define SER_UART1_485_INIT  do {} while (0)
+                       #define SER_UART1_485_TX    do {} while (0)
+                       #define SER_UART1_485_RX    do {} while (0)
+               #elif !defined(SER_UART1_485_RX) || !defined(SER_UART1_485_TX)
+                       #error SER_UART1_485_INIT, SER_UART1_485_RX and SER_UART1_485_TX must be defined together
+               #endif
+
                #define KDBG_WAIT_READY()     do { loop_until_bit_is_set(UCSR1A, UDRE); } while(0)
-               #define KDBG_WRITE_CHAR(c)    do { UCSR1B |= BV(TXEN); UDR1 = (c); } while(0)
-               #define KDBG_MASK_IRQ(old)    do { (old) = UCSR1B & BV(TXCIE); cbi(UCSR1B, TXCIE); } while(0)
-               #define KDBG_RESTORE_IRQ(old) do { UCSR1B |= (old); } while(0)
+               #define KDBG_WAIT_TXDONE()    do { loop_until_bit_is_set(UCSR1A, TXC); } while(0)
+               #define KDBG_WRITE_CHAR(c)    do { UCSR1A |= BV(TXC); UDR1 = (c); } while(0)
+
+               #define KDBG_MASK_IRQ(old)    do { \
+                       SER_UART1_485_TX; \
+                       (old) = UCSR1B; \
+                       UCSR1B |= BV(TXEN); \
+                       UCSR1B &= ~(BV(TXCIE) | BV(UDRIE)); \
+               } while(0)
+
+               #define KDBG_RESTORE_IRQ(old) do { \
+                       KDBG_WAIT_TXDONE(); \
+                       SER_UART1_485_RX; \
+                       UCSR1B = (old); \
+               } while(0)
+
        #else
                #error CONFIG_KDEBUG_PORT should be either 0 or 1
        #endif
@@ -123,9 +187,11 @@ void kdbg_init(void)
                #if CONFIG_KDEBUG_PORT == 0
                        UBRR0H = (uint8_t)(period>>8);
                        UBRR0L = (uint8_t)period;
+                       SER_UART0_485_INIT;
                #elif CONFIG_KDEBUG_PORT == 1
                        UBRR1H = (uint8_t)(period>>8);
                        UBRR1L = (uint8_t)period;
+                       SER_UART1_485_INIT;
                #else
                        #error CONFIG_KDEBUG_PORT must be either 0 or 1
                #endif
@@ -134,6 +200,7 @@ void kdbg_init(void)
                UBRRL = (uint8_t)period;
        #elif defined(__AVR_ATmega103__)
                UBRR = (uint8_t)period;
+               SER_UART0_485_INIT;
        #else
                #error Unknown arch
        #endif
index e43505566443e6adfc9b817a29c9961596fe106c..dd38f3e0bc3ec6b38bbb6d2a29bde8acf1c9490f 100755 (executable)
--- a/drv/ser.h
+++ b/drv/ser.h
@@ -14,6 +14,9 @@
 
 /*
  * $Log$
+ * Revision 1.8  2004/08/02 20:20:29  aleph
+ * Merge from project_ks
+ *
  * Revision 1.7  2004/07/30 14:15:53  rasky
  * Nuovo supporto unificato per detect della CPU
  *
@@ -108,10 +111,9 @@ enum
 #else
        #error unknown architecture
 #endif
-
-       SER_CNT       /**< Number of serial ports */
+       SER_CNT  /*!< Number of serial ports */
 };
-/* @} */
+/*\}*/
 
 
 struct SerialHardware;
index 2e94c2192520bf912cd9f3fb4c353d7f61495964..c43f7238b70763937b905dfdb9a22a4e56d4ae6f 100755 (executable)
@@ -38,6 +38,9 @@
 
 /*
  * $Log$
+ * Revision 1.9  2004/08/02 20:20:29  aleph
+ * Merge from project_ks
+ *
  * Revision 1.8  2004/07/29 22:57:09  bernie
  * Several tweaks to reduce code size on ATmega8.
  *
 #endif
 
 /* External 485 transceiver on UART0 (to be overridden in "hw.h").  */
-#ifndef SER_UART0_485_INIT
-#define SER_UART0_485_INIT  do {} while (0)
+#if !defined(SER_UART0_485_INIT)
+       #if defined(SER_UART0_485_RX) || defined(SER_UART0_485_TX)
+               #error SER_UART0_485_INIT, SER_UART0_485_RX and SER_UART0_485_TX must be defined together
+       #endif
+       #define SER_UART0_485_INIT  do {} while (0)
+       #define SER_UART0_485_TX    do {} while (0)
+       /* SER_UART0_485_RX must not be defined! */
+#elif !defined(SER_UART0_485_RX) || !defined(SER_UART0_485_TX)
+       #error SER_UART0_485_INIT, SER_UART0_485_RX and SER_UART0_485_TX must be defined together
 #endif
-#ifndef SER_UART0_485_TX
-#define SER_UART0_485_TX    do {} while (0)
+
+/* External 485 transceiver on UART1 (to be overridden in "hw.h").  */
+#ifndef SER_UART1_485_INIT
+       #if defined(SER_UART1_485_RX) || defined(SER_UART1_485_TX)
+               #error SER_UART1_485_INIT, SER_UART1_485_RX and SER_UART1_485_TX must be defined together
+       #endif
+       #define SER_UART1_485_INIT  do {} while (0)
+       #define SER_UART1_485_TX    do {} while (0)
+       /* SER_UART1_485_RX must not be defined! */
+#elif !defined(SER_UART1_485_RX) || !defined(SER_UART1_485_TX)
+       #error SER_UART1_485_INIT, SER_UART1_485_RX and SER_UART1_485_TX must be defined together
 #endif
 
 
@@ -199,12 +218,13 @@ static void uart0_setbaudrate(UNUSED(struct SerialHardware *, _hw), unsigned lon
 {
        /* Compute baud-rate period */
        uint16_t period = (((CLOCK_FREQ / 16UL) + (rate / 2)) / rate) - 1;
-       DB(kprintf("uart0_setbaudrate(rate=%lu): period=%d\n", rate, period);)
 
 #ifndef __AVR_ATmega103__
        UBRR0H = (period) >> 8;
 #endif
        UBRR0L = (period);
+
+       DB(kprintf("uart0_setbaudrate(rate=%lu): period=%d\n", rate, period);)
 }
 
 static void uart0_setparity(UNUSED(struct SerialHardware *, _hw), int parity)
@@ -220,6 +240,10 @@ static void uart1_enabletxirq(UNUSED(struct SerialHardware *, _hw))
 {
 #if CONFIG_SER_TXFILL && (CONFIG_KBUS_PORT == 1)
        UCSR1B = BV(RXCIE) | BV(UDRIE) | BV(RXEN) | BV(TXEN) | BV(UCSZ2);
+#elif defined(SER_UART1_485_TX)
+       /* Disable receiver, enable transmitter, switch 485 transceiver. */
+       UCSR1B = BV(UDRIE) | BV(TXEN);
+       SER_UART1_485_TX;
 #else
        UCSR1B = BV(RXCIE) | BV(UDRIE) | BV(RXEN) | BV(TXEN);
 #endif
@@ -242,7 +266,7 @@ static void uart1_init(UNUSED(struct SerialHardware *, _hw), UNUSED(struct Seria
 #else
        UCSR1B = BV(RXCIE) | BV(RXEN);
 #endif
-
+       SER_UART1_485_INIT;
        RTS_ON;
 }
 
@@ -255,10 +279,11 @@ static void uart1_setbaudrate(UNUSED(struct SerialHardware *, _hw), unsigned lon
 {
        /* Compute baud-rate period */
        uint16_t period = (((CLOCK_FREQ / 16UL) + (rate / 2)) / rate) - 1;
-       DB(kprintf("uart1_setbaudrate(rate=%ld): period=%d\n", rate, period);)
 
        UBRR1H = (period) >> 8;
        UBRR1L = (period);
+
+       DB(kprintf("uart1_setbaudrate(rate=%ld): period=%d\n", rate, period);)
 }
 
 static void uart1_setparity(UNUSED(struct SerialHardware *, _hw), int parity)
@@ -409,6 +434,13 @@ SIGNAL(SIG_UART1_DATA)
                 */
                UCSR1B &= ~BV(TXB8);
                UDR1 = SER_FILL_BYTE;
+#elif defined(SER_UART1_485_RX)
+               /*
+                * - Disable UDR empty interrupt
+                * - Disable the transmitter (the in-progress transfer will complete)
+                * - Enable the transmit complete interrupt for the 485 tranceiver.
+                */
+               UCSR1B = BV(TXCIE);
 #else
                /* Disable UDR empty interrupt and transmitter */
                UCSR1B = BV(RXCIE) | BV(RXEN);
@@ -432,6 +464,23 @@ SIGNAL(SIG_UART1_DATA)
                UDR1 = fifo_pop(txfifo);
        }
 }
+
+#ifdef SER_UART1_485_RX
+/*!
+ * Serial port 1 TX complete interrupt handler.
+ *
+ * \sa port 0 TX complete handler.
+ */
+SIGNAL(SIG_UART1_TRANS)
+{
+       /* Turn the 485 tranceiver into receive mode. */
+       SER_UART1_485_RX;
+
+       /* Enable UART receiver and receive interrupt. */
+       UCSR1B = BV(RXCIE) | BV(RXEN);
+}
+#endif /* SER_UART1_485_RX */
+
 #endif // AVR_HAS_UART1
 
 
index f471cb57ad7ac3824ddda0429153430542d5b08d..24287cb982569748ea4e0165355aa1865ae0174b 100755 (executable)
@@ -15,6 +15,9 @@
 
 /*
  * $Log$
+ * Revision 1.11  2004/08/02 20:20:29  aleph
+ * Merge from project_ks
+ *
  * Revision 1.10  2004/07/30 14:15:53  rasky
  * Nuovo supporto unificato per detect della CPU
  *
@@ -216,7 +219,7 @@ DEFINE_TIMER_ISR
                REMOVE((Node *)timer);
 
                /* Execute the associated event */
-               event_doIntr(&timer->expire);
+               event_do(&timer->expire);
        }
 #endif /* CONFIG_TIMER_DISABLE_EVENTS */
 
index 07147416e1eaaf9f831b702aa737b1dd18abc0d4..3180e1b81e8e914aa3baf23adfa5ea3037271108 100755 (executable)
@@ -15,6 +15,9 @@
 
 /*
  * $Log$
+ * Revision 1.13  2004/08/02 20:20:29  aleph
+ * Merge from project_ks
+ *
  * Revision 1.12  2004/07/30 14:34:10  rasky
  * Vari fix per documentazione e commenti
  * Aggiunte PP_CATn e STATIC_ASSERT
@@ -62,7 +65,7 @@
 #include <mware/list.h>
 
 /*! Number of timer ticks per second. */
-#define TICKS_PER_SEC       1000
+#define TICKS_PER_SEC  ((time_t)1000)
 
 /* Function protos */
 extern void timer_init(void);
@@ -180,5 +183,18 @@ INLINE time_t timer_tick_unlocked(void)
 /* OBSOLETE */
 #define timer_gettick_irq timer_tick_unlocked
 
+
+/*!
+ * Return the minutes passed since timer start.
+ *
+ * The minutes uptime is computed directly from system tick counter:
+ * in case of a 4 bytes time_t after 71582 minutes the value will
+ * wrap around.
+ */
+INLINE time_t timer_minutes(void)
+{
+       return timer_gettick() / (TICKS_PER_SEC * 60);
+}
+
 #endif /* DRV_TIMER_H */
 
index b536c95393e4a6744e327a86387779c6c355b7ff..7a68b61598b1add9b917087192961c46a53e8eaa 100755 (executable)
@@ -15,6 +15,9 @@
 
 /*
  * $Log$
+ * Revision 1.10  2004/08/02 20:20:29  aleph
+ * Merge from project_ks
+ *
  * Revision 1.9  2004/07/22 02:01:14  bernie
  * Use TIMER_PRESCALER consistently.
  *
                TIFR = BV(OCF2) | BV(TOV2);
 
                /* Setup Timer/Counter interrupt */
-#warning Aleph, please use TIMER_PRESCALER here
-               TCCR2 = BV(WGM21) | BV(CS21) | BV(CS20);
+               TCCR2 = BV(WGM21) 
+                       #if TIMER_PRESCALER == 64
+                               | BV(CS21) | BV(CS20)
+                       #else
+                               #error Unsupported value of TIMER_PRESCALER
+                       #endif
+               ;
                /* Clear on Compare match & prescaler = 64, internal sys clock.
                   When changing prescaler change TIMER_HW_HPTICKS_PER_SEC too */
                TCNT2 = 0x00;         /* initialization of Timer/Counter */
index 3971df00bb54907424748e89878b691151851de0..6ce3071aaf104379519f69e74ec7f799ac1c5424 100755 (executable)
@@ -17,6 +17,9 @@
 
 /*
  * $Log$
+ * Revision 1.7  2004/08/02 20:20:29  aleph
+ * Merge from project_ks
+ *
  * Revision 1.6  2004/07/30 14:24:16  rasky
  * Task switching con salvataggio perfetto stato di interrupt (SR)
  * Kernel monitor per dump informazioni su stack dei processi
@@ -47,7 +50,7 @@
 
 #include <string.h> /* memset() */
 
-/*! CPU dependent context switching routines 
+/*! CPU dependent context switching routines
  *  \note This function *MUST* preserve also the status of the interrupts.
  */
 extern void asm_switch_context(cpustack_t **new_sp, cpustack_t **save_sp);
@@ -157,6 +160,9 @@ void monitor_debug_stacks(void)
 
 static void proc_init_struct(Process* proc)
 {
+       /* Avoid warning for unused argument */
+       (void)proc;
+
 #if CONFIG_KERN_SIGNALS
        proc->sig_recv = 0;
 #endif
@@ -166,6 +172,7 @@ static void proc_init_struct(Process* proc)
 #endif
 }
 
+
 void proc_init(void)
 {
        INITLIST(&ProcReadyList);
index 08dfbe8d5384b6395a5a0fe081ceb0bcd4753c68..84fa14d3287af07337649412ce29d9a2e8bd3233 100755 (executable)
 
 #include <avr/io.h>
 
+/*
+ * NOTE: At each change of this function affecting proc.c
+ * (i.e. arguments, data stored in the stack) bump up version
+ * number in asm_switch_version().
+ */
+
 /* void asm_switch_context(void **new_sp, void **save_sp) */
 .globl asm_switch_context
 asm_switch_context:
 
+       in      r0,SREG-__SFR_OFFSET
+       push    r0
 ;      push    r0      caller-save
 ;      push    r1      caller-save
        push    r2
@@ -98,5 +106,16 @@ asm_switch_context:
        pop     r2
 ;      pop     r1      caller-save
 ;      pop     r0      caller-save
+       pop     r0
+       out     SREG-__SFR_OFFSET,r0
+
+       ret
+
 
+/* int asm_switch_version(void) */
+.globl asm_switch_version
+asm_switch_version:
+       ldi r24,lo8(1)
+       ldi r25,hi8(1)
        ret
+
index a643a7e6ed2e2fe9a0986fd9d3ad2f2e5596755a..12de29495cf64fc9bbafc8eb0ba14cfeb366c664 100755 (executable)
@@ -43,6 +43,9 @@
 
 /*
  * $Log$
+ * Revision 1.12  2004/08/02 20:20:29  aleph
+ * Merge from project_ks
+ *
  * Revision 1.11  2004/07/30 14:15:53  rasky
  * Nuovo supporto unificato per detect della CPU
  *
@@ -248,7 +251,7 @@ INLINE void fifo_flush(FIFOBuffer *fb)
                ENABLE_IRQRESTORE(flags);
        }
 
-#endif /* !__AVR__ */
+#endif /* !CPU_AVR */
 
 
 /*!