/*..........................................................................*/
int16_t QF_run(void) {
    QF_INT_DISABLE();
    initialize();
    QF_onStartup();                                     /* startup callback */
    QF_INT_ENABLE();

    for (;;) {                                          /* the QK idle loop */
        QK_onIdle();                      /* invoke the QK on-idle callback */
    }

    return (int16_t)0; /* this unreachable return is to make compiler happy */
}
Пример #2
0
/*..........................................................................*/
void QV_onIdle(void) {  /* called with interrupts disabled, see NOTE01 */
#ifdef Q_SPY
#  if 0
    QS_rxParse();  /* parse all the received bytes */

    // Push out QS buffer to UART
    if (!nrf_drv_uart_tx_in_progress()) {  /* is TXE empty? */
        static uint16_t b;

        QF_INT_DISABLE();
        b = QS_getByte();
        QF_INT_ENABLE();

        if (b != QS_EOD) {  /* not End-Of-Data? */
        	nrf_drv_uart_tx((const uint8_t*)&b, 1);
        }
    }
#  else
    QF_INT_ENABLE();
    //sd_app_evt_wait();
    __WFE(); //__SEV();  __WFE();
#  endif
#elif defined NDEBUG
    /* Put the CPU and peripherals to the low-power mode.
    * you might need to customize the clock management for your application,
    * see the datasheet for your particular Cortex-M MCU.
    */
    /* !!!CAUTION!!!
    * The QF_CPU_SLEEP() contains the WFI instruction, which stops the CPU
    * clock, which unfortunately disables the JTAG port, so the ST-Link
    * debugger can no longer connect to the board. For that reason, the call
    * to QF_CPU_SLEEP() has to be used with CAUTION.
    */
    //QV_CPU_SLEEP(); //atomically go to SHALLOW sleep and enable interrupts
    __WFE();
    QF_INT_ENABLE(); /* for now, just enable interrupts */
#else
    QF_INT_ENABLE(); /* just enable interrupts */
#endif
}
Пример #3
0
//****************************************************************************
/// @description
/// Initializes QXK and must be called by the application exactly once
/// before QP::QF::run().
///
/// @param[in]  idleStkSto  pointer to the stack storage for the idle thread
/// @param[in]  idleStkSize idle thread stack size (in bytes)
///
/// @note QP::QXK::init() must be called once before QP::QF::run().
///
void QXK::init(void * const idleStkSto, uint_fast16_t const idleStkSize) {
    // initialize the stack of the idle thread
    QXK_stackInit_(&l_idleThread,
        reinterpret_cast<QXThreadHandler>(l_idleThread.m_temp.act),
        idleStkSto, idleStkSize);

    // idle thread priority is zero
    l_idleThread.m_prio = static_cast<uint_fast8_t>(0);

    QF_INT_DISABLE();
    QF::active_[0] = &l_idleThread;
    QF_INT_ENABLE();
}
Пример #4
0
/*..........................................................................*/
void QF_onIdle(void) {      /* entered with interrupts DISABLED, see NOTE01 */

    /* toggle the User LED on and then off, see NOTE02 */
    //GPIOSetValue(LED_PORT, LED_BIT, LED_ON);                     /* LED on  */
    //GPIOSetValue(LED_PORT, LED_BIT, LED_OFF);                    /* LED off */

#ifdef NDEBUG
    /* put the CPU and peripherals to the low-power mode */
    QF_CPU_SLEEP();         /* atomically go to sleep and enable interrupts */
#else
    QF_INT_ENABLE();                              /* just enable interrupts */
#endif
}
Пример #5
0
/* @(/2/0/9/1/2/1) .........................................................*/
QState CoffeeAO_setBrewStrength(CoffeeAO * const me, QEvt const * const e) {
    QState status_;
    switch (e->sig) {
        /* @(/2/0/9/1/2/1) */
        case Q_ENTRY_SIG: {
            lcd_clear();
            set_cursor(0, 0);
            lcd_print("Use AD-Wheel");
            set_cursor(0, 1);
            lcd_print("Use int0 to save");
            printf("Changing brew strength...\n");
            status_ = Q_HANDLED();
            break;
        }
        /* @(/2/0/9/1/2/1) */
        case Q_EXIT_SIG: {
            printf("saved brew strength: %u\n", l_CoffeeAO.current_brew_strength);
            status_ = Q_HANDLED();
            break;
        }
        /* @(/2/0/9/1/2/1/0) */
        case ADWHEEL_SIG: {
            const int led_count = 8;
            int i = 0;
            l_CoffeeAO.current_brew_strength = ((AdEvt*)e)->val * led_count / 1024;
            for(i = 0; i < led_count; i++) {
                if (i <= l_CoffeeAO.current_brew_strength) {
                    LED_On(i);
                } else {
                    LED_Off(i);
                }
            }

            status_ = Q_HANDLED();
            break;
        }
        /* @(/2/0/9/1/2/1/1) */
        case INT_SIG: {
            QF_INT_ENABLE();
            QActive_postFIFO((QActive *)&l_CoffeeAO, Q_NEW(QEvent, GO_BACK_SIG));
            QF_INT_DISABLE();
            status_ = Q_HANDLED();
            break;
        }
        default: {
            status_ = Q_SUPER(&CoffeeAO_submenu);
            break;
        }
    }
    return status_;
}
Пример #6
0
/*..........................................................................*/
void QK_onIdle(void) { /* called with interrupts enabled */

    /* toggle an LED on and then off (not enough LEDs, see NOTE01) */
    QF_INT_DISABLE();
    //GPIOA->BSRR |= (LED_LD2);        /* turn LED[n] on  */
    //GPIOA->BSRR |= (LED_LD2 << 16);  /* turn LED[n] off */
    QF_INT_ENABLE();

#ifdef Q_SPY
    if ((USART2->SR & 0x0080U) != 0) {  /* is TXE empty? */
        uint16_t b;

        QF_INT_DISABLE();
        b = QS_getByte();
        QF_INT_ENABLE();

        if (b != QS_EOD) {  /* not End-Of-Data? */
            USART2->DR  = (b & 0xFFU);  /* put into the DR register */
        }
    }
#elif defined NDEBUG
    /* Put the CPU and peripherals to the low-power mode.
    * you might need to customize the clock management for your application,
    * see the datasheet for your particular Cortex-M3 MCU.
    */
    /* !!!CAUTION!!!
    * The WFI instruction stops the CPU clock, which unfortunately disables
    * the JTAG port, so the ST-Link debugger can no longer connect to the
    * board. For that reason, the call to __WFI() has to be used with CAUTION.
    *
    * NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and
    * reset the board, then connect with ST-Link Utilities and erase the part.
    * The trick with BOOT(0) is it gets the part to run the System Loader
    * instead of your broken code. When done disconnect BOOT0, and start over.
    */
    //__WFI(); /* Wait-For-Interrupt */
#endif
}
Пример #7
0
/*..........................................................................*/
void QF_onCleanup(void) {
                               /* restore the DOS system clock tick rate... */
    QF_INT_DISABLE();
    outp(0x43, 0x36);                 /* use mode-3 for timer 0 in the 8254 */
    outp(0x40, 0);                             /* load low  byte of timer 0 */
    outp(0x40, 0);                             /* load high byte of timer 0 */
                                   /* restore the original DOS vectors ... */
    _dos_setvect(TMR_VECTOR, l_dosTmrISR);
    _dos_setvect(KBD_VECTOR, l_dosKbdISR);
    QF_INT_ENABLE();

    QS_EXIT();                                                   /* exit QS */
    _exit(0);                                                /* exit to DOS */
}
Пример #8
0
/*..........................................................................*/
__ramfunc
void QK_onIdle(void) {

    /* toggle first LED on and off, see NOTE01 */
    QF_INT_DISABLE();
    LED_ON(3);  /* turn LED on  */
    LED_OFF(3); /* turn LED off */
    QF_INT_ENABLE();

#ifdef NDEBUG /* only if not debugging (idle mode hinders debugging) */
    AT91C_BASE_PMC->PMC_SCDR = 1;/* Power-Management: disable the CPU clock */
    /* NOTE: an interrupt starts the CPU clock again */
#endif
}
Пример #9
0
/*..........................................................................*/
void QK_onIdle(void) {

    QF_INT_DISABLE();
    LED1_on();                                    /* switch LED1 on and off */
    LED1_off();
    QF_INT_ENABLE();

#ifdef Q_SPY
    if (((IFG2 & UCA0TXIFG)) != 0) {
        uint16_t b;

        QF_INT_DISABLE();
        b = QS_getByte();
        QF_INT_ENABLE();

        if (b != QS_EOD) {
            UCA0TXBUF = (uint8_t)b;         /* stick the byte to the TX BUF */
        }
    }
#elif defined NDEBUG
    __low_power_mode_1();            /* Enter LPM1; also UNLOCKS interrupts */
#endif
}
Пример #10
0
/*..........................................................................*/
void QK_onIdle(void) {
    /* toggle LED1 on and then off, see NOTE01 */
    QF_INT_DISABLE();
    GPIO->P[LED_PORT].DOUT |=  (1U << LED1_PIN);
    GPIO->P[LED_PORT].DOUT &= ~(1U << LED1_PIN);
    QF_INT_ENABLE();

#ifdef NDEBUG
    /* Put the CPU and peripherals to the low-power mode.
    * you might need to customize the clock management for your application,
    * see the datasheet for your particular Cortex-M3 MCU.
    */
    __WFI(); /* Wait-For-Interrupt */
#endif
}
Пример #11
0
/*..........................................................................*/
void QF_onIdle(void) {       /* called with interrupts disabled, see NOTE01 */

    //GPIOF->DATA_Bits[LED_RED] = LED_RED;          /* turn the Red LED on  */
    //GPIOF->DATA_Bits[LED_RED] = 0;                /* turn the Red LED off */

#ifdef NDEBUG
    /* Put the CPU and peripherals to the low-power mode.
    * you might need to customize the clock management for your application,
    * see the datasheet for your particular Cortex-M3 MCU.
    */
    QF_CPU_SLEEP();         /* atomically go to sleep and enable interrupts */
#else
    QF_INT_ENABLE();                              /* just enable interrupts */
#endif
}
/*..........................................................................*/
void QK_onIdle(void) {

    QF_INT_DISABLE();
    LED_ON (IDLE_LED);                    /* blink the IDLE LED, see NOTE01 */
    LED_OFF(IDLE_LED);
    QF_INT_ENABLE();

#ifdef Q_SPY
    while (U2STAbits.UTXBF == 0U) {                  /* TX Buffer not full? */
        uint16_t b;

        QF_INT_DISABLE();
        b = QS_getByte();
        QF_INT_ENABLE();

        if (b == QS_EOD) {                          /* End-Of-Data reached? */
            break;                                 /* break out of the loop */
        }
        U2TXREG = (uint8_t)b;   /* stick the byte to TXREG for transmission */
    }
#elif defined NDEBUG
    Idle();                                      /* transition to Idle mode */
#endif
}
Пример #13
0
/*..........................................................................*/
void QV_onIdle(void) { /* called with interrupts disabled, see NOTE01 */
    /* toggle the LED on and then off, see NOTE02 */
    QF_INT_DISABLE();
    LPC_GPIO1->FIOSET = LED_4;  /* turn LED on  */
    __NOP();   /* a couple of NOPs to actually see the LED glow */
    __NOP();
    __NOP();
    __NOP();
    LPC_GPIO1->FIOCLR = LED_4;  /* turn LED off */
    QF_INT_ENABLE();

#ifdef Q_SPY

    if ((LPC_UART0->LSR & 0x20U) != 0U) {  /* TX Holding Register empty? */
        uint16_t fifo = UART_TXFIFO_DEPTH; /* max bytes we can accept */
        uint8_t const *block;

        QF_INT_DISABLE();
        block = QS_getBlock(&fifo); /* try to get next block to transmit */
        QF_INT_ENABLE();

        while (fifo-- != 0) { /* any bytes in the block? */
            LPC_UART0->THR = *block++; /* put into the FIFO */
        }
    }

#elif defined NDEBUG
    /* Put the CPU and peripherals to the low-power mode.
    * you might need to customize the clock management for your application,
    * see the datasheet for your particular Cortex-M MCU.
    */
    QV_CPU_SLEEP();  /* atomically go to sleep and enable interrupts */
#else
    QF_INT_ENABLE(); /* just enable interrupts */
#endif
}
Пример #14
0
//............................................................................
void QV::onIdle(void) { // NOTE: called with interrutps DISABLED, see NOTE1
    // toggle LED2 on and then off, see NOTE2
    P1OUT |=  LED2;   // turn LED2 on
    P1OUT &= ~LED2;   // turn LED2 off

#ifdef NDEBUG
    // Put the CPU and peripherals to the low-power mode.
    // you might need to customize the clock management for your application,
    // see the datasheet for your particular MSP430 MCU.
    //
    __low_power_mode_1(); // Enter LPM1; also ENABLES interrupts
#else
    QF_INT_ENABLE(); // just enable interrupts
#endif
}
Пример #15
0
/*..........................................................................*/
void QF_onIdle(void) {                  /* invoked with interrupts DISABLED */

    LED1_on();                                    /* switch LED1 on and off */
    LED1_off();

#ifdef Q_SPY

    if (((IFG2 & UCA0TXIFG)) != 0) {
        uint16_t b = QS_getByte();
        QF_INT_ENABLE();

        if (b != QS_EOD) {
            UCA0TXBUF = (uint8_t)b;         /* stick the byte to the TX BUF */
        }
    }
    else {
        QF_INT_ENABLE();
    }
#elif defined NDEBUG
    __low_power_mode_1();    /* Enter LPM1 and ENABLE interrupts atomically */
#else
    QF_INT_ENABLE();
#endif
}
Пример #16
0
//............................................................................
void QF::onCleanup(void) {
                                  // restore the DOS system clock tick rate...
    QF_INT_DISABLE();
    outp(0x43, 0x36);                    // use mode-3 for timer 0 in the 8254
    outp(0x40, 0);                                // load low  byte of timer 0
    outp(0x40, 0);                                // load high byte of timer 0
                                       // restore the original DOS vectors ...
    _dos_setvect(TMR_VECTOR, l_dosTmrISR);
    _dos_setvect(KBD_VECTOR, l_dosKbdISR);
    _dos_setvect(SPARE_VECTOR, l_dosSpareISR);
    QF_INT_ENABLE();

    QS_EXIT();                                                      // exit QS
    _exit(0);                                                   // exit to DOS
}
Пример #17
0
/*..........................................................................*/
void QV_onIdle(void) { /* NOTE: called with interrutps DISABLED, see NOTE1 */
    /* toggle LED2 on and then off, see NOTE2 */
    P4OUT |=  LED2;        /* turn LED2 on */
    P4OUT &= ~LED2;        /* turn LED2 off */

#ifdef NDEBUG
    /* Put the CPU and peripherals to the low-power mode.
    * you might need to customize the clock management for your application,
    * see the datasheet for your particular MSP430 MCU.
    */
    __low_power_mode_1(); /* Enter LPM1; also ENABLES interrupts */
#else
    QF_INT_ENABLE(); /* just enable interrupts */
#endif
}
Пример #18
0
/*..........................................................................*/
void QV_onIdle(void) {   /* called with interrupts DISABLED, see NOTE1 */
    /* toggle the User LED, see NOTE1 , not enough LEDs to implement! */
    //PORTB |= LED_L;
    //PORTB &= ~LED_L;

#ifdef NDEBUG
    /* Put the CPU and peripherals to the low-power mode.
    * you might need to customize the clock management for your application,
    * see the datasheet for your particular AVR MCU.
    */
    SMCR = (0 << SM0) | (1 << SE); /* idle mode, adjust to your project */
    QV_CPU_SLEEP();  /* atomically go to sleep and enable interrupts */
#else
    QF_INT_ENABLE(); /* just enable interrupts */
#endif
}
Пример #19
0
/*..........................................................................*/
void QF_onStartup(void) {
    uint16_t count;
                                      /* save the origingal DOS vectors ... */
    l_dosTmrISR   = _dos_getvect(TMR_VECTOR);
    l_dosKbdISR   = _dos_getvect(KBD_VECTOR);

    QF_INT_DISABLE();
    count = (uint16_t)(((1193180 * 2) / BSP_TICKS_PER_SEC + 1) >> 1);
    outp(0x43, 0x36);                 /* use mode-3 for timer 0 in the 8254 */
    outp(0x40, count & 0xFF);                  /* load low  byte of timer 0 */
    outp(0x40, (count >> 8) & 0xFF);           /* load high byte of timer 0 */

    _dos_setvect(TMR_VECTOR, &ISR_tmr);
    _dos_setvect(KBD_VECTOR, &ISR_kbd);
    QF_INT_ENABLE();
}
Пример #20
0
//............................................................................
void QV::onIdle(void) { // CATION: called with interrupts DISABLED, NOTE01

    // toggle LED2 on and then off, see NOTE01
    GPIOF->DATA_Bits[LED_BLUE] = 0xFFU;
    GPIOF->DATA_Bits[LED_BLUE] = 0x00U;

#ifdef NDEBUG
    // Put the CPU and peripherals to the low-power mode.
    // you might need to customize the clock management for your application,
    // see the datasheet for your particular Cortex-M3 MCU.
    //
    QV_CPU_SLEEP();  // atomically go to sleep and enable interrupts
#else
    QF_INT_ENABLE(); // just enable interrupts
#endif
}
/*..........................................................................*/
void QK_onIdle(void) {
#ifdef Q_SPY
    if ((SCI3_2.SSR.BYTE & 0x80) != 0) {                 /* TDRE not ready? */
        uint16_t b;
        QF_INT_DISABLE();                             /* disable interrupts */
        b = QS_getByte();
        QF_INT_ENABLE();                               /* enable interrupts */
        if (b != QS_EOD) {
            SCI3_2.TDR = (uint8_t)b;    /* put the byte to TX data register */
        }
    }
#elif (defined NDEBUG)          /* low-power mode interferes with debugging */
    /* stop all peripheral clocks that you can in your applicaiton ... */
    sleep();                      /*  before entering any pending interrupt */
#endif
}
Пример #22
0
/* @(/2/0/9/1/2/8) .........................................................*/
QState CoffeeAO_set_clock_m2(CoffeeAO * const me, QEvt const * const e) {
    QState status_;
    switch (e->sig) {
        /* @(/2/0/9/1/2/8) */
        case Q_ENTRY_SIG: {
            lcd_clear();
            status_ = Q_HANDLED();
            break;
        }
        /* @(/2/0/9/1/2/8/0) */
        case ADWHEEL_SIG: {
            char clock_message[20];
            int value = ((AdEvt*)e)->val * 10 / 1024;
            HourAndMinute* ham = &l_CoffeeAO.alarm.current_time;
            ham->minutes = (ham->minutes / 10) * 10 + value;
            sprintf(clock_message, "%02u:%02u", ham->hours, ham->minutes);

            set_cursor(0, 0);
            lcd_print(clock_message);
            set_cursor(4, 1);
            lcd_print("^");
            status_ = Q_HANDLED();
            break;
        }
        /* @(/2/0/9/1/2/8/1) */
        case INT_SIG: {
            RtcEvt* rtc_evt = Q_NEW(RtcEvt, TIME_SET_SIG);
            rtc_evt->rtc.hours = l_CoffeeAO.alarm.current_time.hours;
            rtc_evt->rtc.minutes = l_CoffeeAO.alarm.current_time.minutes;

            Alarm_dispatch((QFsm *)&l_CoffeeAO.alarm, (QEvt *) rtc_evt);
            QF_INT_ENABLE();
            QActive_postFIFO((QActive *)&l_CoffeeAO, Q_NEW(QEvent, GO_BACK_SIG));
            QF_INT_DISABLE();

            status_ = Q_HANDLED();
            break;
        }
        default: {
            status_ = Q_SUPER(&CoffeeAO_submenu);
            break;
        }
    }
    return status_;
}
Пример #23
0
/*..........................................................................*/
void QK_onIdle(void) {
    /* test code to use the FPU ... */
    float volatile x = 3.1415926F;
    x = x + 2.7182818F;

    /* toggle the Blue LED on and then off, see NOTE01 */
    QF_INT_DISABLE();
    GPIOF->DATA_Bits[LED_BLUE] = LED_BLUE;         /* turn the Blue LED on  */
    GPIOF->DATA_Bits[LED_BLUE] = 0;                /* turn the Blue LED off */
    QF_INT_ENABLE();

#ifdef NDEBUG
    /* Put the CPU and peripherals to the low-power mode.
    * you might need to customize the clock management for your application,
    * see the datasheet for your particular Cortex-M MCU.
    */
    asm(" WFI");                                      /* Wait-For-Interrupt */
#endif
}
Пример #24
0
/* RTX callbacks ===========================================================*/
void os_idle_demon(void); /* prototype */
void os_idle_demon(void) {
    /* The RTX idle demon is a system thread, running when no other thread
    * is ready to run.
    */

    for (;;) { /* idle-loop */
        QF_INT_DISABLE();
        GPIOF->DATA_Bits[LED_BLUE] = 0xFFU; /* turn LED on  */
        GPIOF->DATA_Bits[LED_BLUE] = 0x00U; /* turn LED off */
        QF_INT_ENABLE();

#ifdef NDEBUG
        /* Put the CPU and peripherals to the low-power mode.
        * You might need to customize the clock management for your
        * application, see the datasheet for your particular MCU.
        */
        __WFI(); /* Wait-For-Interrupt */
#endif
    } /* idle-loop */
}
Пример #25
0
/* @(/2/0/9/1/2/2) .........................................................*/
QState CoffeeAO_startBrewingNow(CoffeeAO * const me, QEvt const * const e) {
    QState status_;
    switch (e->sig) {
        /* @(/2/0/9/1/2/2) */
        case Q_ENTRY_SIG: {
            QF_INT_ENABLE();
            printf("Starting to brew\n %i", l_CoffeeAO.i++);
            QActive_postFIFO((QActive *)&l_CoffeeAO, Q_NEW(QEvent, BREW_SIG));
            QActive_postFIFO((QActive *)&l_CoffeeAO, Q_NEW(QEvent, GO_BACK_SIG));
            QF_INT_DISABLE();

            status_ = Q_HANDLED();
            break;
        }
        default: {
            status_ = Q_SUPER(&CoffeeAO_submenu);
            break;
        }
    }
    return status_;
}
Пример #26
0
/* @(/2/0/9/1/2/11) ........................................................*/
QState CoffeeAO_set_brew_m2(CoffeeAO * const me, QEvt const * const e) {
    QState status_;
    switch (e->sig) {
        /* @(/2/0/9/1/2/11) */
        case Q_ENTRY_SIG: {
            lcd_clear();
            status_ = Q_HANDLED();
            break;
        }
        /* @(/2/0/9/1/2/11/0) */
        case ADWHEEL_SIG: {
            char clock_message[20];
            int value = ((AdEvt*)e)->val * 10 / 1024;
            HourAndMinute* ham = &l_CoffeeAO.alarm.alarm_time;
            ham->minutes = MIN((ham->minutes / 10) * 10 + value, 59);
            sprintf(clock_message, "%02u:%02u", ham->hours, ham->minutes);

            set_cursor(0, 0);
            lcd_print(clock_message);
            set_cursor(4, 1);
            lcd_print("^");
            status_ = Q_HANDLED();
            break;
        }
        /* @(/2/0/9/1/2/11/1) */
        case INT_SIG: {
            QF_INT_ENABLE();
            QActive_postFIFO((QActive *)&l_CoffeeAO, Q_NEW(QEvent, GO_BACK_SIG));
            QF_INT_DISABLE();
            status_ = Q_HANDLED();
            break;
        }
        default: {
            status_ = Q_SUPER(&CoffeeAO_submenu);
            break;
        }
    }
    return status_;
}
Пример #27
0
//............................................................................
void QXK::onIdle(void) {
    QF_INT_DISABLE();
    if (((l_activeSet & (1U << SYSTICK_ACTIVE)) != 0U) // rate-0 enabled?
        && QP::QF::noTimeEvtsActiveX(0U))  // no time events at rate-0?
    {
        // safe to disable SysTick and interrupt
        SysTick->CTRL &= ~(SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk);
        l_activeSet &= ~(1U << SYSTICK_ACTIVE); // mark rate-0 as disabled
    }
    if (((l_activeSet & (1U << TIMER0_ACTIVE)) != 0U) // rate-1 enabled?
        && QP::QF::noTimeEvtsActiveX(1U))  // no time events at rate-1?
    {
        // safe to disable Timer0 and interrupt
        TIMER0->CTL  &= ~(1U << 0); // disable Timer0
        TIMER0->IMR  &= ~(1U << 0); // disable timer interrupt
        l_activeSet &= ~(1U << TIMER0_ACTIVE); // mark rate-1 as disabled
    }
    QF_INT_ENABLE();

    GPIOF->DATA_Bits[LED_RED] = 0xFFU; // turn LED on, see NOTE2
    __WFI(); // wait for interrupt
    GPIOF->DATA_Bits[LED_RED] = 0x00U; // turn LED off, see NOTE2
}
Пример #28
0
/*..........................................................................*/
void QF_onIdle(void) {            /* NOTE: entered with interrupts DISABLED */
    QF_INT_ENABLE();                     /* must at least enable interrupts */
}
Пример #29
0
/* @(/2/0/9/1/1) ...........................................................*/
QState CoffeeAO_menu(CoffeeAO * const me, QEvt const * const e) {
    QState status_;
    switch (e->sig) {
        /* @(/2/0/9/1/1/0) */
        case ADWHEEL_SIG: {
            // calculate current menu entry
            char menu_text[20];
            struct Entry* menu_entry = &menu_entries[me->current_menu_index];
            me->current_menu_index = ((AdEvt*)e)->val * me->max_menu_index / 1024;
            lcd_clear();
            set_cursor(0, 0);
            switch (menu_entry->interpolate_with) {
            case NOTHING:
                strcpy(menu_text, menu_entry->menu_label);
                break;
            case BREW_STRENGTH:
                sprintf(menu_text, menu_entry->menu_label, l_CoffeeAO.current_brew_strength + 1);
                break;
            case IS_COFFEE_POT_IN_MACHINE:
                sprintf(menu_text, menu_entry->menu_label, l_CoffeeAO.is_coffee_pot_in_machine);
                break;
            case IS_AUTOMATIC_BREW_ACTIVE:
                sprintf(menu_text, menu_entry->menu_label, l_CoffeeAO.is_automatic_brew_active);
                break;
            }
            lcd_print(menu_text);

            set_cursor(4, 1);
            sprintf(menu_text, "%02u:%02u:%02u", l_CoffeeAO.alarm.real_current_time.hours, l_CoffeeAO.alarm.real_current_time.minutes, l_CoffeeAO.alarm.real_current_time.seconds);
            lcd_print(menu_text);
            status_ = Q_HANDLED();
            break;
        }
        /* @(/2/0/9/1/1/1) */
        case INT_SIG: {
            QEvent *menuEvt = Q_NEW(QEvent, menu_entries[me->current_menu_index].signal);
            //QEvent *menuEvt = Q_NEW(QEvent, GO_COFFEE_POT_TOGGLE_SIG);
            QF_INT_ENABLE();
            QActive_postFIFO((QActive *)&l_CoffeeAO, menuEvt);
            QF_INT_DISABLE();

            status_ = Q_HANDLED();
            break;
        }
        /* @(/2/0/9/1/1/2) */
        case GO_COFFEE_POT_TOGGLE_SIG: {
            status_ = Q_TRAN(&CoffeeAO_coffeePotToggle);
            break;
        }
        /* @(/2/0/9/1/1/3) */
        case GO_TIME_BREW_TOGGLE_SIG: {
            status_ = Q_TRAN(&CoffeeAO_timeBrewActivatedToggle);
            break;
        }
        /* @(/2/0/9/1/1/4) */
        case GO_SET_BREW_TIME_CLOCK_SIG: {
            status_ = Q_TRAN(&CoffeeAO_set_brew_h1);
            break;
        }
        /* @(/2/0/9/1/1/5) */
        case GO_SET_TIME_OF_DAY_SIG: {
            status_ = Q_TRAN(&CoffeeAO_set_clock_h1);
            break;
        }
        /* @(/2/0/9/1/1/6) */
        case GO_START_BREWING_SIG: {
            status_ = Q_TRAN(&CoffeeAO_startBrewingNow);
            break;
        }
        /* @(/2/0/9/1/1/7) */
        case GO_SET_BREW_STRENGTH_SIG: {
            status_ = Q_TRAN(&CoffeeAO_setBrewStrength);
            break;
        }
        default: {
            status_ = Q_SUPER(&CoffeeAO_coffeemachine);
            break;
        }
    }
    return status_;
}
Пример #30
0
/**
* \description
* The "extended" QK scheduler performs all the steps of the regular scheduler
* QK_sched_() and additionally switches the Thread-Local Storage (TLS) and
* handles the extended context-switch.
*
* \arguments
* \arg[in] \c p  priority of the next AO to schedule
*
* \note The "extended" QK scheduler needs to be called only to handle
* "asynchronous" preemption, under the assumption that neither the ISRs
* nor the QK idle loop use TLS or the co-processors requiring
* extended context switch (see [PSiCC2] Section 10.4.3).
*
* \note QK_schedExt_() must be always called with interrupts DISABLED.
*
* \note The extended scheduler might enable interrupts internally,
* but always returns with interrupts DISABLED.
*/
void QK_schedExt_(uint_fast8_t p) {
    uint_fast8_t pin = QK_currPrio_; /* save the initial priority */

    /* thread-local storage used? */
#ifdef QK_TLS
    uint_fast8_t pprev = pin;
#endif
    QActive *a;

    /* extended context-switch used? */
#ifdef QK_EXT_SAVE
    /* aren't we preempting the idle loop? (idle loop has prio==0)  */
    if (pin != (uint_fast8_t)0) {
        a = QF_active_[pin]; /* the pointer to the preempted AO */
        QK_EXT_SAVE(a);      /* save the extended context */
    }
#endif

    /* loop until have ready-to-run AOs of higher priority than the initial */
    do {
        QEvt const *e;
        a = QF_active_[p]; /* obtain the pointer to the AO */

        QK_currPrio_ = p;  /* this becomes the current task priority */

    /* thread-local storage used? */
#ifdef QK_TLS
        /* are we changing threads? */
        if (p != pprev) {
            QK_TLS(a); /* switch new thread-local storage */
            pprev = p;
        }
#endif
        QS_BEGIN_NOCRIT_(QS_QK_SCHEDULE, QS_priv_.aoObjFilter, a)
            QS_TIME_();           /* timestamp */
            QS_U8_((uint8_t)p);   /* the priority of the AO */
            QS_U8_((uint8_t)pin); /* the preempted priority */
        QS_END_NOCRIT_()

        QF_INT_ENABLE(); /* unconditionally enable interrupts */

        /* perform the run-to-completion (RTS) step...
        * 1. retrieve the event from the AO's event queue, which by this
        *    time must be non-empty and QActive_get_() asserts it.
        * 2. dispatch the event to the AO's state machine.
        * 3. determine if event is garbage and collect it if so
        */
        e = QActive_get_(a);
        QMSM_DISPATCH(&a->super, e);
        QF_gc(e);

        QF_INT_DISABLE(); /* disable interrupts */

        /* find new highest-priority AO ready to run... */
#if (QF_MAX_ACTIVE <= 8)
        QPSet8_findMax(&QK_readySet_, p);
#else
        QPSet64_findMax(&QK_readySet_, p);
#endif
        /* is the new priority below the current preemption threshold? */
        if (p <= pin) {
            p = (uint_fast8_t)0;
        }
#ifndef QK_NO_MUTEX
        /* is the new priority below the mutex ceiling? */
        else if (p <= QK_ceilingPrio_) {
            p = (uint_fast8_t)0;
        }
        else {
            /* empty */
        }
#endif
    } while (p != (uint_fast8_t)0);

    QK_currPrio_ = pin; /* restore the initial priority */

#if defined(QK_TLS) || defined(QK_EXT_RESTORE)
    /* aren't we preempting the idle loop? (idle loop has prio==0) */
    if (pin != (uint_fast8_t)0) {
        a = QF_active_[pin]; /* the pointer to the preempted AO */

        /* thread-local storage used? */
#ifdef QK_TLS
        QK_TLS(a); /* restore the original TLS */
#endif

        /* extended context-switch used? */
#ifdef QK_EXT_RESTORE
        QK_EXT_RESTORE(a); /* restore the extended context */
#endif
    }
#endif
}