Merge remote-tracking branch 'mjb/altosdroid'
authorKeith Packard <keithp@keithp.com>
Fri, 26 Oct 2012 21:08:32 +0000 (14:08 -0700)
committerKeith Packard <keithp@keithp.com>
Fri, 26 Oct 2012 21:08:32 +0000 (14:08 -0700)
18 files changed:
src/avr/ao_arch.h
src/cc1111/ao_arch.h
src/core/ao_ignite.c
src/core/ao_list.h
src/core/ao_task.c
src/core/ao_task.h
src/drivers/ao_cc1120.c
src/drivers/ao_ms5607.c
src/drivers/ao_radio_master.c
src/stm/ao_arch.h
src/stm/ao_arch_funcs.h
src/stm/ao_i2c_stm.c
src/stm/ao_lcd_stm.c
src/stm/ao_serial_stm.c
src/stm/ao_timer.c
src/stm/ao_usb_stm.c
src/stm/registers.ld
src/stm/stm32l.h

index c82612a8ca12bf98666cc7f2970b147229ca6657..d626e830ee97bf4bdb7bf760ef2832fff698853a 100644 (file)
@@ -112,7 +112,6 @@ extern uint8_t      ao_cpu_sleep_disable;
                asm("push r9" "\n\t" "push r8" "\n\t" "push r7" "\n\t" "push r6" "\n\t" "push r5"); \
                asm("push r4" "\n\t" "push r3" "\n\t" "push r2" "\n\t" "push r1" "\n\t" "push r0"); \
                asm("in r0, __SREG__" "\n\t" "push r0");                \
-               sei();                                                  \
        } while (0)
 
 #define ao_arch_save_stack() do {                                      \
@@ -124,16 +123,28 @@ extern uint8_t    ao_cpu_sleep_disable;
 
 #define ao_arch_isr_stack()    /* nothing */
 
-#define ao_arch_cpu_idle() do {                        \
-               if (!ao_cpu_sleep_disable)      \
+/* Idle the CPU (if possible) waiting for an interrupt. Enabling
+ * interrupts and sleeping the CPU must be adjacent to eliminate race
+ * conditions. In all cases, we execute a single nop with interrupts
+ * enabled
+ */
+#define ao_arch_wait_interrupt() do {          \
+               if (!ao_cpu_sleep_disable) {    \
+                       sleep_enable();         \
+                       sei();                  \
                        sleep_cpu();            \
+                       sleep_disable();        \
+               } else {                        \
+                       sei();                  \
+               }                               \
+               ao_arch_nop();                  \
+               cli();                          \
        } while (0)
 
 #define ao_arch_restore_stack() do { \
                uint8_t sp_l, sp_h;                                     \
                sp_l = (uint16_t) ao_cur_task->sp;                      \
                sp_h = ((uint16_t) ao_cur_task->sp) >> 8;               \
-               cli();                                                  \
                asm("out __SP_H__,%0" : : "r" (sp_h) );                 \
                asm("out __SP_L__,%0" : : "r" (sp_l) );                 \
                asm("pop r0"    "\n\t"                                  \
index f2442eb69775c36a98d54df3ca543731fb35c65c..9097557ffd3460359f148aa8343dba3851b0a462 100644 (file)
@@ -112,9 +112,7 @@ extern AO_ROMCONFIG_SYMBOL(0x00a6) uint32_t ao_radio_cal;
        /* Push ACC first, as when restoring the context it must be restored \
         * last (it is used to set the IE register). */                 \
        push    ACC                                                     \
-       /* Store the IE register then enable interrupts. */             \
        push    _IEN0                                                   \
-       setb    _EA                                                     \
        push    DPL                                                     \
        push    DPH                                                     \
        push    b                                                       \
@@ -147,16 +145,18 @@ extern AO_ROMCONFIG_SYMBOL(0x00a6) uint32_t ao_radio_cal;
                while (--stack_len);                                    \
        }
 
-#define ao_arch_isr_stack()                                            \
-       /* Empty the stack; might as well let interrupts have the whole thing */ \
-       (SP = AO_STACK_START - 1)
+/* Empty the stack; might as well let interrupts have the whole thing */
+#define ao_arch_isr_stack()            (SP = AO_STACK_START - 1)
 
-#define ao_arch_cpu_idle()     (PCON = PCON_IDLE)
+#define ao_arch_block_interrupts()     __asm clr _EA __endasm
+#define ao_arch_release_interrupts()   __asm setb _EA __endasm
 
-#define ao_arch_block_interrupts()     __asm clr ea __endasm
-#define ao_arch_release_interrupts()   __asm setb ea __endasm
-#define cli() ao_arch_block_interrupts()
-#define sei() ao_arch_release_interrupts()
+/* Idle the CPU, waking when an interrupt occurs */
+#define ao_arch_wait_interrupt() do {          \
+               ao_arch_release_interrupts();   \
+               (PCON = PCON_IDLE);             \
+               ao_arch_block_interrupts();     \
+       } while (0)
 
 #define ao_arch_restore_stack() {                                      \
                uint8_t stack_len;                                      \
@@ -197,7 +197,7 @@ extern AO_ROMCONFIG_SYMBOL(0x00a6) uint32_t ao_radio_cal;
                0098$:                                                  \
                        SETB            _EA                             \
                0099$:                                                  \
-               /* Finally pop off the ACC, which was the first register saved. */ \
+               /* Finally restore ACC, which was the first register saved. */ \
                pop             ACC                                     \
                ret                                                     \
                __endasm;                                               \
index 693b7c7aaeb17e3dc384852bc46204ed546fa156..74bd0c5aea021a55a4e7f16d45300f9fcb97bebe 100644 (file)
@@ -23,10 +23,10 @@ __xdata struct ao_ignition ao_ignition[2];
 void
 ao_ignite(enum ao_igniter igniter)
 {
-       cli();
+       ao_arch_block_interrupts();
        ao_ignition[igniter].request = 1;
        ao_wakeup(&ao_ignition);
-       sei();
+       ao_arch_release_interrupts();
 }
 
 #ifndef AO_SENSE_DROGUE
index 23cf18417ed7f292bb3ecdc728131232207909d1..8a6fa4d92eb90571ec949f3db17a02215b9e90df 100644 (file)
@@ -137,7 +137,7 @@ ao_list_is_empty(struct ao_list *head)
  * @return A pointer to the data struct containing the list head.
  */
 #define ao_container_of(ptr, type, member) \
-    (type *)((char *)(ptr) - offsetof(type, member))
+       ((type *)((char *)(ptr) - offsetof(type, member)))
 
 /**
  * Alias of ao_container_of
index a11979f0a81fb78a5063ee9066189647c649285e..0411fbdd425921c42f26b68d5116f932bfc18d96 100644 (file)
@@ -114,6 +114,8 @@ ao_task_validate_alarm_queue(void)
 #define ao_task_validate_alarm_queue()
 #endif
 
+uint16_t       ao_task_alarm_tick;
+
 static void
 ao_task_to_alarm_queue(struct ao_task *task)
 {
@@ -126,6 +128,7 @@ ao_task_to_alarm_queue(struct ao_task *task)
                }
        }
        ao_list_append(&task->alarm_queue, &alarm_queue);
+       ao_task_alarm_tick = ao_list_first_entry(&alarm_queue, struct ao_task, alarm_queue)->alarm;
        ao_task_validate_alarm_queue();
 }
 
@@ -133,6 +136,10 @@ static void
 ao_task_from_alarm_queue(struct ao_task *task)
 {
        ao_list_del(&task->alarm_queue);
+       if (ao_list_is_empty(&alarm_queue))
+               ao_task_alarm_tick = 0;
+       else
+               ao_task_alarm_tick = ao_list_first_entry(&alarm_queue, struct ao_task, alarm_queue)->alarm;
        ao_task_validate_alarm_queue();
 }
 
@@ -154,10 +161,7 @@ void
 ao_task_check_alarm(uint16_t tick)
 {
        struct ao_task  *alarm, *next;
-       int             i;
 
-       if (ao_num_tasks == 0)
-               return;
        ao_list_for_each_entry_safe(alarm, next, &alarm_queue, struct ao_task, alarm_queue) {
                if ((int16_t) (tick - alarm->alarm) < 0)
                        break;
@@ -173,6 +177,7 @@ ao_task_init(void)
        uint8_t i;
        ao_list_init(&run_queue);
        ao_list_init(&alarm_queue);
+       ao_task_alarm_tick = 0;
        for (i = 0; i < SLEEP_HASH_SIZE; i++)
                ao_list_init(&sleep_queue[i]);
 }
@@ -264,14 +269,9 @@ ao_task_validate(void)
                }
        }
 }
-#else
-#define ao_task_validate()
-#endif
+#endif /* DEBUG */
 
-#else
-#define ao_task_to_run_queue(task)
-#define ao_task_to_alarm_queue(task)
-#endif
+#endif /* HAS_TASK_QUEUE */
 
 void
 ao_add_task(__xdata struct ao_task * task, void (*start)(void), __code char *name) __reentrant
@@ -331,6 +331,7 @@ ao_yield(void) ao_arch_naked_define
        }
 
        ao_arch_isr_stack();
+       ao_arch_block_interrupts();
 
 #if AO_CHECK_STACK
        in_yield = 1;
@@ -339,21 +340,19 @@ ao_yield(void) ao_arch_naked_define
         * this loop will run forever, which is just fine
         */
 #if HAS_TASK_QUEUE
-       if (ao_cur_task->wchan == NULL) {
-               uint32_t flags;
-               flags = ao_arch_irqsave();
+       /* If the current task is running, move it to the
+        * end of the queue to allow other tasks a chance
+        */
+       if (ao_cur_task->wchan == NULL)
                ao_task_to_run_queue(ao_cur_task);
-               ao_arch_irqrestore(flags);
-       }
        ao_cur_task = NULL;
-
        for (;;) {
                ao_arch_memory_barrier();
                if (!ao_list_is_empty(&run_queue))
                        break;
-               ao_arch_cpu_idle();
+               /* Wait for interrupts when there's nothing ready */
+               ao_arch_wait_interrupt();
        }
-               
        ao_cur_task = ao_list_first_entry(&run_queue, struct ao_task, queue);
 #else
        {
@@ -374,20 +373,19 @@ ao_yield(void) ao_arch_naked_define
                            (int16_t) (ao_time() - ao_cur_task->alarm) >= 0)
                                break;
 
-                       /* Enter lower power mode when there isn't anything to do */
+                       /* Wait for interrupts when there's nothing ready */
                        if (ao_cur_task_index == ao_last_task_index)
-                               ao_arch_cpu_idle();
+                               ao_arch_wait_interrupt();
                }
-#if HAS_SAMPLE_PROFILE
-               ao_cur_task->start = ao_sample_profile_timer_value();
-#endif
        }
 #endif
+#if HAS_SAMPLE_PROFILE
+       ao_cur_task->start = ao_sample_profile_timer_value();
+#endif
 #if HAS_STACK_GUARD
        ao_mpu_stack_guard(ao_cur_task->stack);
 #endif
 #if AO_CHECK_STACK
-       ao_arch_block_interrupts();
        in_yield = 0;
 #endif
        ao_arch_restore_stack();
@@ -519,7 +517,7 @@ ao_task_info(void)
                       task->name,
                       (int) task->wchan);
        }
-#if HAS_TASK_QUEUE
+#if HAS_TASK_QUEUE && DEBUG
        ao_task_validate();
 #endif
 }
index b3f152a04c0f47d42ebd2833cf06c617694ca881..049f69a7c2fb121d2dbdffd2564d7bb8f989fe4e 100644 (file)
@@ -82,6 +82,7 @@ ao_add_task(__xdata struct ao_task * task, void (*start)(void), __code char *nam
 
 #if HAS_TASK_QUEUE
 /* Called on timer interrupt to check alarms */
+extern uint16_t        ao_task_alarm_tick;
 void
 ao_task_check_alarm(uint16_t tick);
 #endif
index 7428bead1131bc31bfafc3de6d6c12c2de214bdc..bad313ebaad23bdac7886812c48d3f51678ec7f6 100644 (file)
@@ -469,10 +469,10 @@ ao_rdf_run(void)
 {
        ao_radio_start_tx();
 
-       cli();
+       ao_arch_block_interrupts();
        while (!ao_radio_wake && !ao_radio_abort)
                ao_sleep(&ao_radio_wake);
-       sei();
+       ao_arch_release_interrupts();
        if (!ao_radio_wake)
                ao_radio_idle();
        ao_radio_put();
@@ -603,10 +603,10 @@ ao_radio_send(const void *d, uint8_t size)
                        
                do {
                        ao_radio_wake = 0;
-                       cli();
+                       ao_arch_block_interrupts();
                        while (!ao_radio_wake)
                                ao_sleep(&ao_radio_wake);
-                       sei();
+                       ao_arch_release_interrupts();
                        if (!encode_len)
                                break;
                        fifo_space = ao_radio_tx_fifo_space();
@@ -660,14 +660,14 @@ ao_radio_rx_isr(void)
 static uint16_t
 ao_radio_rx_wait(void)
 {
-       cli();
+       ao_arch_block_interrupts();
        rx_waiting = 1;
        while (rx_data_cur - rx_data_consumed < AO_FEC_DECODE_BLOCK &&
               !ao_radio_abort) {
                ao_sleep(&ao_radio_wake);
        }
        rx_waiting = 0;
-       sei();
+       ao_arch_release_interrupts();
        if (ao_radio_abort)
                return 0;
        rx_data_consumed += AO_FEC_DECODE_BLOCK;
index ce0bcf4bcfb79e6a123e00a62c78d7d315c47f01..55bea563498701775f1580f28bc8e122dd92bfb0 100644 (file)
@@ -130,7 +130,6 @@ static uint32_t
 ao_ms5607_get_sample(uint8_t cmd) {
        uint8_t reply[3];
        uint8_t read;
-       uint32_t loops;
 
        ao_ms5607_done = 0;
 
@@ -142,15 +141,10 @@ ao_ms5607_get_sample(uint8_t cmd) {
 #if AO_MS5607_PRIVATE_PINS
        ao_spi_put(AO_MS5607_SPI_INDEX);
 #endif
-//     loops = 0;
-       cli();
-       while (!ao_ms5607_done) {
-//             loops++;
+       ao_arch_block_interrupts();
+       while (!ao_ms5607_done)
                ao_sleep((void *) &ao_ms5607_done);
-       }
-       sei();
-//     if (loops > 1)
-//             printf ("ms5607 loops %d\n", loops);
+       ao_arch_release_interrupts();
 #if AO_MS5607_PRIVATE_PINS
        stm_gpio_set(AO_MS5607_CS_PORT, AO_MS5607_CS_PIN, 1);
 #else
index 4a37ace06c39aefd66501e79af0aea295244bd5d..1e0050c8d4bc822921ce61d9113bf5c6bb9d9863 100644 (file)
@@ -75,7 +75,7 @@ ao_radio_master_send(void)
         */
 
        PRINTD("Waiting radio ready\n");
-       cli();
+       ao_arch_block_interrupts();
        ao_radio_ready = ao_gpio_get(AO_RADIO_INT_PORT,
                                     AO_RADIO_INT_PIN, AO_RADIO_INT);
        ret = 0;
@@ -84,7 +84,7 @@ ao_radio_master_send(void)
                if (ret)
                        break;
        }
-       sei();
+       ao_arch_release_interrupts();
        if (ret)
                return 0;
 
@@ -99,11 +99,11 @@ ao_radio_master_send(void)
                    AO_RADIO_SPI_BUS);
        ao_radio_master_stop();
        PRINTD("waiting for send done %d\n", ao_radio_done);
-       cli();
+       ao_arch_block_interrupts();
        while (!ao_radio_done)
                if (ao_sleep((void *) &ao_radio_done))
                        break;
-       sei();
+       ao_arch_release_interrupts();
        PRINTD ("sent, radio done %d isr_0 %d isr_1 %d\n", ao_radio_done, isr_0_count, isr_1_count);
        return ao_radio_done;
 }
index 0c3cfc915f9513813a1153041249746d5e0c1bb9..e270199ec701aebcc7860b7a5601aa4e8f29ff8e 100644 (file)
@@ -46,9 +46,9 @@
 #define __interrupt(n)
 #define __at(n)
 
-#define CORTEX_M3_AIRCR                ((uint32_t *) 0xe000ed0c)
-
-#define ao_arch_reboot()       (*((uint32_t *) 0xe000ed0c) = 0x05fa0004)
+#define ao_arch_reboot() \
+       (stm_scb.aircr = ((STM_SCB_AIRCR_VECTKEY_KEY << STM_SCB_AIRCR_VECTKEY) | \
+                         (1 << STM_SCB_AIRCR_SYSRESETREQ)))
 
 #define ao_arch_nop()          asm("nop")
 
@@ -77,118 +77,12 @@ extern const uint16_t ao_romconfig_check;
 extern const uint16_t ao_serial_number;
 extern const uint32_t ao_radio_cal;
 
-#define ARM_PUSH32(stack, val) (*(--(stack)) = (val))
-
 #define ao_arch_task_members\
        uint32_t *sp;                   /* saved stack pointer */
 
 #define ao_arch_block_interrupts()     asm("cpsid i")
 #define ao_arch_release_interrupts()   asm("cpsie i")
 
-#define cli()  ao_arch_block_interrupts()
-#define sei()  ao_arch_release_interrupts()
-
-static uint32_t
-ao_arch_irqsave(void) {
-       uint32_t        primask;
-       asm("mrs %0,primask" : "=&r" (primask));
-       ao_arch_block_interrupts();
-       return primask;
-}
-
-static void
-ao_arch_irqrestore(uint32_t primask) {
-       asm("msr primask,%0" : : "r" (primask));
-}
-
-static void
-ao_arch_memory_barrier() {
-       asm volatile("" ::: "memory");
-}
-
-#define ao_arch_init_stack(task, start) do {                           \
-               uint32_t        *sp = (uint32_t *) (task->stack + AO_STACK_SIZE); \
-               uint32_t        a = (uint32_t) start;                   \
-               int             i;                                      \
-                                                                       \
-               /* Return address (goes into LR) */                     \
-               ARM_PUSH32(sp, a);                                      \
-                                                                       \
-               /* Clear register values r0-r12 */                      \
-               i = 13;                                                 \
-               while (i--)                                             \
-                       ARM_PUSH32(sp, 0);                              \
-                                                                       \
-               /* APSR */                                              \
-               ARM_PUSH32(sp, 0);                                      \
-                                                                       \
-               /* PRIMASK with interrupts enabled */                   \
-               ARM_PUSH32(sp, 0);                                      \
-                                                                       \
-               task->sp = sp;                                          \
-} while (0);
-       
-#define ao_arch_save_regs()    do {                                    \
-               /* Save general registers */                            \
-               asm("push {r0-r12,lr}\n");                              \
-                                                                       \
-               /* Save APSR */                                         \
-               asm("mrs r0,apsr");                                     \
-               asm("push {r0}");                                       \
-                                                                       \
-               /* Save PRIMASK */                                      \
-               asm("mrs r0,primask");                                  \
-               asm("push {r0}");                                       \
-                                                                       \
-               /* Enable interrupts */                                 \
-               sei();                                                  \
-       } while (0)
-
-#define ao_arch_save_stack() do {                                      \
-               uint32_t        *sp;                                    \
-               asm("mov %0,sp" : "=&r" (sp) );                         \
-               ao_cur_task->sp = (sp);                                 \
-               if ((uint8_t *) sp < &ao_cur_task->stack[0])            \
-                       ao_panic (AO_PANIC_STACK);                      \
-       } while (0)
-
-#if 0
-#define ao_arch_isr_stack() do {                               \
-               uint32_t        *sp = (uint32_t *) 0x20004000;  \
-               asm("mov %0,sp" : "=&r" (sp) );                 \
-       } while (0)
-#else
-#define ao_arch_isr_stack()
-#endif
-
-
-#define ao_arch_cpu_idle() do {                        \
-               asm(".global ao_idle_loc\n\twfi\nao_idle_loc:");        \
-       } while (0)
-
-#define ao_arch_restore_stack() do { \
-               uint32_t        sp;                                     \
-               sp = (uint32_t) ao_cur_task->sp;                        \
-                                                                       \
-               /* Switch stacks */                                     \
-               asm("mov sp, %0" : : "r" (sp) );                        \
-                                                                       \
-               /* Restore PRIMASK */                                   \
-               asm("pop {r0}");                                        \
-               asm("msr primask,r0");                                  \
-                                                                       \
-               /* Restore APSR */                                      \
-               asm("pop {r0}");                                        \
-               asm("msr apsr,r0");                                     \
-                                                                       \
-               /* Restore general registers */                         \
-               asm("pop {r0-r12,lr}\n");                               \
-                                                                       \
-               /* Return to calling function */                        \
-               asm("bx lr");                                           \
-       } while(0)
-
-#define ao_arch_critical(b) do { cli(); do { b } while (0); sei(); } while (0)
 
 /*
  * For now, we're running at a weird frequency
index e66d20d72cbc568ca9c74e443fc5a7e5d7a96112..d6ab1465c73cd1b9a5f0c46080ba1ef780afd1aa 100644 (file)
@@ -210,4 +210,105 @@ ao_i2c_recv(void *block, uint16_t len, uint8_t i2c_index, uint8_t stop);
 void
 ao_i2c_init(void);
 
+#define ARM_PUSH32(stack, val) (*(--(stack)) = (val))
+
+static inline uint32_t
+ao_arch_irqsave(void) {
+       uint32_t        primask;
+       asm("mrs %0,primask" : "=&r" (primask));
+       ao_arch_block_interrupts();
+       return primask;
+}
+
+static inline void
+ao_arch_irqrestore(uint32_t primask) {
+       asm("msr primask,%0" : : "r" (primask));
+}
+
+static inline void
+ao_arch_memory_barrier() {
+       asm volatile("" ::: "memory");
+}
+
+static inline void
+ao_arch_init_stack(struct ao_task *task, void *start)
+{
+       uint32_t        *sp = (uint32_t *) (task->stack + AO_STACK_SIZE);
+       uint32_t        a = (uint32_t) start;
+       int             i;
+
+       /* Return address (goes into LR) */
+       ARM_PUSH32(sp, a);
+
+       /* Clear register values r0-r12 */
+       i = 13;
+       while (i--)
+               ARM_PUSH32(sp, 0);
+
+       /* APSR */
+       ARM_PUSH32(sp, 0);
+
+       /* PRIMASK with interrupts enabled */
+       ARM_PUSH32(sp, 0);
+
+       task->sp = sp;
+}
+
+static inline void ao_arch_save_regs(void) {
+       /* Save general registers */
+       asm("push {r0-r12,lr}\n");
+
+       /* Save APSR */
+       asm("mrs r0,apsr");
+       asm("push {r0}");
+
+       /* Save PRIMASK */
+       asm("mrs r0,primask");
+       asm("push {r0}");
+}
+
+static inline void ao_arch_save_stack(void) {
+       uint32_t        *sp;
+       asm("mov %0,sp" : "=&r" (sp) );
+       ao_cur_task->sp = (sp);
+       if ((uint8_t *) sp < &ao_cur_task->stack[0])
+               ao_panic (AO_PANIC_STACK);
+}
+
+static inline void ao_arch_restore_stack(void) {
+       uint32_t        sp;
+       sp = (uint32_t) ao_cur_task->sp;
+
+       /* Switch stacks */
+       asm("mov sp, %0" : : "r" (sp) );
+
+       /* Restore PRIMASK */
+       asm("pop {r0}");
+       asm("msr primask,r0");
+
+       /* Restore APSR */
+       asm("pop {r0}");
+       asm("msr apsr,r0");
+
+       /* Restore general registers */
+       asm("pop {r0-r12,lr}\n");
+
+       /* Return to calling function */
+       asm("bx lr");
+}
+
+#define ao_arch_isr_stack()
+
+#define ao_arch_wait_interrupt() do {                  \
+               asm(".global ao_idle_loc\n\twfi\nao_idle_loc:");        \
+               ao_arch_release_interrupts();                           \
+               ao_arch_block_interrupts();                             \
+       } while (0)
+
+#define ao_arch_critical(b) do {                               \
+               ao_arch_block_interrupts();                     \
+               do { b } while (0);                             \
+               ao_arch_release_interrupts();                   \
+       } while (0)
+
 #endif /* _AO_ARCH_FUNCS_H_ */
index b6dd7056e426e6db55b6b89413f059cbeba952e1..779e227503110971abcb3c8aa14744ef1594b1ed 100644 (file)
@@ -197,13 +197,13 @@ ao_i2c_start(uint8_t index, uint16_t addr)
                        break;
        }
        ao_alarm(AO_MS_TO_TICKS(250));
-       cli();
+       ao_arch_block_interrupts();
        stm_i2c->cr2 = AO_STM_I2C_CR2 | (1 << STM_I2C_CR2_ITEVTEN) | (1 << STM_I2C_CR2_ITERREN);
        ao_i2c_ev_isr(index);
        while (ao_i2c_state[index] == I2C_IDLE)
                if (ao_sleep(&ao_i2c_state[index]))
                        break;
-       sei();
+       ao_arch_release_interrupts();
        ao_clear_alarm();
        return ao_i2c_state[index] == I2C_RUNNING;
 }
@@ -263,7 +263,7 @@ ao_i2c_send(void *block, uint16_t len, uint8_t index, uint8_t stop)
                           
        ao_dma_start(tx_dma_index);
        ao_alarm(1 + len);
-       cli();
+       ao_arch_block_interrupts();
        while (!ao_dma_done[tx_dma_index])
                if (ao_sleep(&ao_dma_done[tx_dma_index]))
                        break;
@@ -274,7 +274,7 @@ ao_i2c_send(void *block, uint16_t len, uint8_t index, uint8_t stop)
                if (ao_sleep(&ao_i2c_state[index]))
                        break;
        stm_i2c->cr2 = AO_STM_I2C_CR2;
-       sei();
+       ao_arch_release_interrupts();
        if (stop) {
                stm_i2c->cr1 = AO_STM_I2C_CR1 | (1 << STM_I2C_CR1_STOP);
                ao_i2c_wait_stop(index);
@@ -328,11 +328,11 @@ ao_i2c_recv(void *block, uint16_t len, uint8_t index, uint8_t stop)
                        stm_i2c->cr1 = AO_STM_I2C_CR1 | (1 << STM_I2C_CR1_STOP);
 
                ao_alarm(1);
-               cli();
+               ao_arch_block_interrupts();
                while (ao_i2c_recv_len[index])
                        if (ao_sleep(&ao_i2c_recv_len[index]))
                                break;
-               sei();
+               ao_arch_release_interrupts();
                ret = ao_i2c_recv_len[index] == 0;
                ao_clear_alarm();
        } else {
@@ -358,11 +358,11 @@ ao_i2c_recv(void *block, uint16_t len, uint8_t index, uint8_t stop)
 
                ao_dma_start(rx_dma_index);
                ao_alarm(len);
-               cli();
+               ao_arch_block_interrupts();
                while (!ao_dma_done[rx_dma_index])
                        if (ao_sleep(&ao_dma_done[rx_dma_index]))
                                break;
-               sei();
+               ao_arch_release_interrupts();
                ao_clear_alarm();
                ret = ao_dma_done[rx_dma_index];
                ao_dma_done_transfer(rx_dma_index);
index 0f9a8eb53ee4325ab2c55f24be7df6b413a9604d..4f2a2242aeded5e0ef55e7d4b00dfa751b1b30a7 100644 (file)
@@ -253,12 +253,12 @@ ao_lcd_stm_fcr_sync(void)
 void
 ao_lcd_flush(void)
 {
-       cli();
+       ao_arch_block_interrupts();
        ao_lcd_update_active = 1;
        stm_lcd.sr = (1 << STM_LCD_SR_UDR);
        while (ao_lcd_update_active)
                ao_sleep(&ao_lcd_update_active);
-       sei();
+       ao_arch_release_interrupts();
 }
 
 void
index 406da9fbb6739099c12fa4867eec61611a5f7a88..00409f4a85957e16e53825f4e8420e85a168c535 100644 (file)
@@ -34,7 +34,7 @@ ao_debug_out(char c)
 }
 
 static void
-ao_usart_tx_start(struct ao_stm_usart *usart)
+_ao_usart_tx_start(struct ao_stm_usart *usart)
 {
        if (!ao_fifo_empty(usart->tx_fifo) && !usart->tx_started)
        {
@@ -61,7 +61,7 @@ ao_usart_isr(struct ao_stm_usart *usart, int stdin)
        }
        if (sr & (1 << STM_USART_SR_TC)) {
                usart->tx_started = 0;
-               ao_usart_tx_start(usart);
+               _ao_usart_tx_start(usart);
                ao_wakeup(&usart->tx_fifo);
        }
 }
@@ -70,11 +70,11 @@ char
 ao_usart_getchar(struct ao_stm_usart *usart)
 {
        char c;
-       cli();
+       ao_arch_block_interrupts();
        while (ao_fifo_empty(usart->rx_fifo))
                ao_sleep(&usart->rx_fifo);
        ao_fifo_remove(usart->rx_fifo, c);
-       sei();
+       ao_arch_release_interrupts();
        return c;
 }
 
@@ -82,34 +82,34 @@ char
 ao_usart_pollchar(struct ao_stm_usart *usart)
 {
        char    c;
-       cli();
-       if (ao_fifo_empty(usart->rx_fifo)) {
-               sei();
-               return AO_READ_AGAIN;
-       }
-       ao_fifo_remove(usart->rx_fifo,c);
-       sei();
+       
+       ao_arch_block_interrupts();
+       if (ao_fifo_empty(usart->rx_fifo))
+               c = AO_READ_AGAIN;
+       else
+               ao_fifo_remove(usart->rx_fifo,c);
+       ao_arch_release_interrupts();
        return c;
 }
 
 void
 ao_usart_putchar(struct ao_stm_usart *usart, char c)
 {
-       cli();
+       ao_arch_block_interrupts();
        while (ao_fifo_full(usart->tx_fifo))
                ao_sleep(&usart->tx_fifo);
        ao_fifo_insert(usart->tx_fifo, c);
-       ao_usart_tx_start(usart);
-       sei();
+       _ao_usart_tx_start(usart);
+       ao_arch_release_interrupts();
 }
 
 void
 ao_usart_drain(struct ao_stm_usart *usart)
 {
-       cli();
+       ao_arch_block_interrupts();
        while (!ao_fifo_empty(usart->tx_fifo))
                ao_sleep(&usart->tx_fifo);
-       sei();
+       ao_arch_release_interrupts();
 }
 
 static const struct {
index d69035f82b76227c2033eb3397a15a1d4f3c51f9..e07625d8d7d1e809db29f18c5f6deaae388f0869 100644 (file)
@@ -44,7 +44,8 @@ void stm_tim6_isr(void)
                stm_tim6.sr = 0;
                ++ao_tick_count;
 #if HAS_TASK_QUEUE
-               ao_task_check_alarm((uint16_t) ao_tick_count);
+               if (ao_task_alarm_tick && (int16_t) (ao_tick_count - ao_task_alarm_tick) >= 0)
+                       ao_task_check_alarm((uint16_t) ao_tick_count);
 #endif
 #if AO_DATA_ALL
                if (++ao_data_count == ao_data_interval) {
index 8e7dacc53e2bf98e37d4bb3d0ad48cbc2ef1fa92..d93a0c174c16a7a851669241fa98fbd68083d2d9 100644 (file)
@@ -223,16 +223,16 @@ _ao_usb_set_stat_tx(int ep, uint32_t stat_tx)
 static void
 ao_usb_set_stat_tx(int ep, uint32_t stat_tx)
 {
-       cli();
+       ao_arch_block_interrupts();
        _ao_usb_set_stat_tx(ep, stat_tx);
-       sei();
+       ao_arch_release_interrupts();
 }
 
 static void
 ao_usb_set_stat_rx(int ep, uint32_t stat_rx) {
        uint32_t        epr_write, epr_old;
 
-       cli();
+       ao_arch_block_interrupts();
        epr_write = epr_old = stm_usb.epr[ep];
        epr_write &= STM_USB_EPR_PRESERVE_MASK;
        epr_write |= STM_USB_EPR_INVARIANT;
@@ -240,7 +240,7 @@ ao_usb_set_stat_rx(int ep, uint32_t stat_rx) {
                              STM_USB_EPR_STAT_RX_MASK << STM_USB_EPR_STAT_RX,
                              stat_rx << STM_USB_EPR_STAT_RX);
        stm_usb.epr[ep] = epr_write;
-       sei();
+       ao_arch_release_interrupts();
 }
 
 /*
@@ -251,7 +251,7 @@ static void
 ao_usb_init_ep(uint8_t ep, uint32_t addr, uint32_t type, uint32_t stat_rx, uint32_t stat_tx)
 {
        uint32_t                epr;
-       cli();
+       ao_arch_block_interrupts();
        epr = stm_usb.epr[ep];
        epr = ((0 << STM_USB_EPR_CTR_RX) |
               (epr & (1 << STM_USB_EPR_DTOG_RX)) |
@@ -267,7 +267,7 @@ ao_usb_init_ep(uint8_t ep, uint32_t addr, uint32_t type, uint32_t stat_rx, uint3
                          (stat_tx << STM_USB_EPR_STAT_TX)) |
               (addr << STM_USB_EPR_EA));
        stm_usb.epr[ep] = epr;
-       sei();
+       ao_arch_release_interrupts();
        debug ("writing epr[%d] 0x%08x wrote 0x%08x\n",
               ep, epr, stm_usb.epr[ep]);
 }
index f8b224a2d67d01f831ea003d52fcb42dc4f39428..95a86e358fc3f51019aa29b098271dd7034b12c0 100644 (file)
@@ -46,6 +46,8 @@ stm_tim2   = 0x40000000;
 
 stm_nvic   = 0xe000e100;
 
+stm_scb    = 0xe000ed00;
+
 stm_mpu    = 0xe000ed90;
 
 /* calibration data in system memory */
index d953aee433d5691b4061d82a49b882ac6fe82ad5..0dbfae39814c0fd4a5e43805bbbe66c120800ce9 100644 (file)
@@ -901,6 +901,36 @@ stm_nvic_get_priority(int irq) {
        return (stm_nvic.ipr[IRQ_PRIO_REG(irq)] >> IRQ_PRIO_BIT(irq)) & IRQ_PRIO_MASK(0);
 }
 
+struct stm_scb {
+       vuint32_t       cpuid;
+       vuint32_t       icsr;
+       vuint32_t       vtor;
+       vuint32_t       aircr;
+
+       vuint32_t       scr;
+       vuint32_t       ccr;
+       vuint32_t       shpr1;
+       vuint32_t       shpr2;
+
+       vuint32_t       shpr3;
+       vuint32_t       shcrs;
+       vuint32_t       cfsr;
+       vuint32_t       hfsr;
+
+       uint32_t        unused_30;
+       vuint32_t       mmfar;
+       vuint32_t       bfar;
+};
+
+extern struct stm_scb stm_scb;
+
+#define STM_SCB_AIRCR_VECTKEY          16
+#define  STM_SCB_AIRCR_VECTKEY_KEY             0x05fa
+#define STM_SCB_AIRCR_PRIGROUP         8
+#define STM_SCB_AIRCR_SYSRESETREQ      2
+#define STM_SCB_AIRCR_VECTCLRACTIVE    1
+#define STM_SCB_AIRCR_VECTRESET                0
+
 struct stm_mpu {
        vuint32_t       typer;
        vuint32_t       cr;