示例#1
0
static void sound_test_cb(guiObject_t *obj, void *data)
{
    (void)obj;
    u8 idx = (long)data;
#if HAS_EXTENDED_AUDIO && HAS_MUSIC_CONFIG
    MUSIC_Play(MUSIC_GetTelemetryAlarm(MUSIC_TELEMALARM1 + idx));
#else
    MUSIC_Play(MUSIC_TELEMALARM1 + idx);
#endif
}
示例#2
0
void PAGE_SplashEvent()
{
    static unsigned int time=0;
#if HAS_EXTENDED_AUDIO
    static unsigned int time_startup_msg;
#endif
    if(GUI_IsModal())
       return;
//    u8 step = 5;
    if ( 0 == time ) {
    	time = CLOCK_getms() + Transmitter.splash_delay * 100;
#if HAS_EXTENDED_AUDIO
        time_startup_msg = CLOCK_getms() + 5 * 100;	// Dealy 0.5 second to play startup audio
#endif
    }
#if HAS_EXTENDED_AUDIO
    if (time_startup_msg && (CLOCK_getms() > time_startup_msg) ) {
        AUDIO_SetVolume();
        MUSIC_Play(MUSIC_STARTUP);
        time_startup_msg = 0;
    }
#endif

    if ( CLOCK_getms() > time )
	PAGE_ChangeByID(PAGEID_MAIN,0);
/*     if ( offset > 0 ) {
	offset -= step;
	GUI_ChangeImage(&gui->splash_image,SPLASH_FILE,offset,0);
	GUI_Redraw(&gui->splash_image);
    }*/
}
示例#3
0
void TIMER_Power(){
    static u32 timer = 0;
    u32 alert = Transmitter.power_alarm * 60 * 1000;
    static u16 throttle;
    u16 new_throttle;
    u16 elevator;
    unsigned mode = MODE_2 == Transmitter.mode || MODE_4 == Transmitter.mode ? 2 : 1;

    if( 0 == timer)
        timer =  CLOCK_getms() + alert;

    elevator = 2 == mode ? abs(CHAN_ReadInput(INP_THROTTLE)) : abs(CHAN_ReadInput(INP_ELEVATOR));
    new_throttle = 2 == mode ?  abs(CHAN_ReadInput(INP_ELEVATOR)) : abs(CHAN_ReadInput(INP_THROTTLE));
    new_throttle = abs(new_throttle - throttle);
     
    if( elevator < 1000 && abs(CHAN_ReadInput(INP_AILERON)) < 1000 && 
                new_throttle < 1000 && abs(CHAN_ReadInput(INP_RUDDER)) < 1000 &&
                !ScanButtons() && (!HAS_TOUCH || !SPITouch_IRQ()) ) {
        if ( CLOCK_getms() > timer ) {
            timer =  CLOCK_getms() + 2000;
            MUSIC_Play(MUSIC_SHUTDOWN);
        }                
    } else 
           timer =  CLOCK_getms() + alert;
    throttle = 2 == mode ?  abs(CHAN_ReadInput(INP_ELEVATOR)) : abs(CHAN_ReadInput(INP_THROTTLE));
}
示例#4
0
void kb_update_string(struct guiKeyboard *keyboard, u8 ch)
{
    u8 len = strlen(keyboard->text);
    if(ch == '\x08') {
        if (len > 0) {
            keyboard->text[len - 1] = 0;
            _kb_draw_text(keyboard->text);
        }
        return;
    }
    if (keyboard->type == KEYBOARD_NUM) {
        s32 val = atoi(keyboard->text);
        val = val * 10 + (ch - '0');
        if (val > keyboard->max_size)
            return;
        sprintf(keyboard->text, "%d", (int)val);
        _kb_draw_text(keyboard->text);
        return;
    }
    if (len >= keyboard->max_size) {
        MUSIC_Play(MUSIC_MAXLEN);
        return;
    }
    if(! (keyboard->flags & FLAG_CAPS) && ch >= 'A' && ch <= 'Z') {
        ch = (ch - 'A') + 'a';
    }
    keyboard->text[len] = ch;
    keyboard->text[len+1] = 0;
    _kb_draw_text(keyboard->text);
}
示例#5
0
static unsigned _action_cb(u32 button, unsigned flags, void *data)
{
    if (CHAN_ButtonIsPressed(button, BUT_ENTER)) {
        MUSIC_Play(MUSIC_SAVING);
        save_changes();
        return 1;
    }
    return default_button_action_cb(button, flags, data);
}
示例#6
0
void EventLoop()
{
    CLOCK_ResetWatchdog();
    unsigned int time;

#ifdef HEAP_DEBUG
    static int heap = 0;
    int h = _sbrk_r(NULL, 0);
    if(h > heap) {
        printf("heap: %x\n", h);
        heap = h;
    }
#endif
#ifdef TIMING_DEBUG
    debug_timing(0, 0);
#endif
    priority_ready &= ~(1 << MEDIUM_PRIORITY);
    if(PWR_CheckPowerSwitch()) {
        if(! (BATTERY_Check() & BATTERY_CRITICAL)) {
            CONFIG_SaveModelIfNeeded();
            CONFIG_SaveTxIfNeeded();
        }
    	if(Transmitter.music_shutdown) {
	    MUSIC_Play(MUSIC_SHUTDOWN);
            // We wait ~1sec for shutdown music finished
            time = CLOCK_getms()+700;
            while(CLOCK_getms()<time);
	}

        PWR_Shutdown();
    }
    BUTTON_Handler();
    TOUCH_Handler();

    if (priority_ready & (1 << LOW_PRIORITY)) {
        priority_ready  &= ~(1 << LOW_PRIORITY);
        PAGE_Event();
        PROTOCOL_CheckDialogs();
        TIMER_Update();
        TELEMETRY_Alarm();
        BATTERY_Check();
        AUTODIMMER_Update();
#if DATALOG_ENABLED
        DATALOG_Update();
#endif
        GUI_RefreshScreen();
    }
#ifdef TIMING_DEBUG
    debug_timing(0, 1);
#endif
}
示例#7
0
static const char *_buzz_vol_cb(guiObject_t *obj, int dir, void *data)
{
    (void)data;
    u8 *unsigned_data = (u8 *)data;
    u8 changed;
    if (GUI_IsTextSelectEnabled(obj)) {
        *unsigned_data = GUI_TextSelectHelper(*unsigned_data, 0, 10, dir, 1, 1, &changed);
        if (changed)
            MUSIC_Play(MUSIC_VOLUME);
    }
    if (*unsigned_data == 0)
        return _tr("Off");
    sprintf(tempstring, "%d", *unsigned_data);
    return tempstring;
}
示例#8
0
static unsigned _action_cb(u32 button, unsigned flags, void *data)
{
    (void)data;
    if ((flags & BUTTON_PRESS) || (flags & BUTTON_LONGPRESS)) {
        if (CHAN_ButtonIsPressed(button, BUT_EXIT)) {
            PAGE_ChangeByID(PAGEID_MENU, PREVIOUS_ITEM);
        } else if (CHAN_ButtonIsPressed(button, BUT_ENTER)) {
            MUSIC_Play(MUSIC_SAVING);
            save_changes();
        }
        else {
            // only one callback can handle a button press, so we don't handle BUT_ENTER here, let it handled by press cb
            return 0;
        }
    }
    return 1;
}
示例#9
0
MODULE_CALLTYPE
static u16 cflie_callback()
{
    switch (phase) {
    case CFLIE_INIT_SEARCH:
        send_search_packet();
        phase = CFLIE_SEARCH;
        break;
    case CFLIE_INIT_CRTP_LOG:
        if (crtp_log_setup_state_machine()) {
            phase = CFLIE_INIT_DATA;
        }
        break;
    case CFLIE_INIT_DATA:
        send_cmd_packet();
        phase = CFLIE_DATA;
        break;
    case CFLIE_SEARCH:
        switch (packet_ack()) {
        case PKT_PENDING:
            return PACKET_CHKTIME;                 // packet send not yet complete
        case PKT_ACKED:
            phase = CFLIE_DATA;
            PROTOCOL_SetBindState(0);
            MUSIC_Play(MUSIC_DONE_BINDING);
            break;
        case PKT_TIMEOUT:
            send_search_packet();
            counter = BIND_COUNT;
        }
        break;

    case CFLIE_DATA:
        if (Model.proto_opts[PROTOOPTS_TELEMETRY] == TELEM_ON_CRTPLOG) {
            update_telemetry_crtplog();
        } else if (Model.proto_opts[PROTOOPTS_TELEMETRY] == TELEM_ON_ACKPKT) {
            update_telemetry_ackpkt();
        }

        if (packet_ack() == PKT_PENDING)
            return PACKET_CHKTIME;         // packet send not yet complete
        send_cmd_packet();
        break;
    }
    return PACKET_PERIOD;                  // Packet at standard protocol interval
}
示例#10
0
static void navigate_item(struct guiKeyboard *keyboard, short leftRight, short upDown) {
    const char * const *keys = array[keyboard->type];
    MUSIC_Play(MUSIC_KEY_PRESSING);
    short i = keyboard->last_row;
    short j = 0;
    u8 col_len = 0;
    if (! (keyboard->flags & FLAG_BUTTON)) {
        keyboard->lastchar = array[keyboard->type][0][0];
        keyboard->flags |= FLAG_BUTTON;
    }
    if (leftRight != 0) {
        const char *ptr = keys[i];
        col_len = strlen(ptr);
        if (i < 3 || keyboard->type == KEYBOARD_NUM) {
            j = keyboard->last_col;
            j += leftRight;
            if (j < 0) j = col_len -1;
            if (j >= col_len) j = 0;
            keyboard->last_col = j;
        } else {  // when row = 3, don't keep track of its col
            for (j = 0; j < col_len; j++) {
                if (ptr[j] == keyboard->lastchar) {
                    break;
                }
            }
            j += leftRight;
            if (j < 0) j = col_len -1;
            if (j >= col_len) j = 0;
        }
    } else {
        i += upDown;
        if (i < 0) i = 3;
        if (i >= 4) i = 0;
        keyboard->last_row = i;
        j = keyboard->last_col;
        if (j >= (short)strlen(keys[i])) {
            j = strlen(keys[i]) - 1;
        }
    }
    keyboard_cmd(KB_RELEASE, keyboard, NULL);
    keyboard->lastchar = keys[i][j];
    keyboard_cmd(KB_PRESS, keyboard, NULL);
}
示例#11
0
MODULE_CALLTYPE
static u16 cflie_callback()
{
    switch (phase) {
    case CFLIE_INIT_SEARCH:
        send_search_packet();
        phase = CFLIE_SEARCH;
        break;
    case CFLIE_INIT_TELEMETRY:
        if (telemetry_setup_state_machine()) {
            phase = CFLIE_INIT_DATA;
        }
        break;
    case CFLIE_INIT_DATA:
        send_cmd_packet();
        phase = CFLIE_DATA;
        break;
    case CFLIE_SEARCH:
        switch (packet_ack()) {
        case PKT_PENDING:
            return PACKET_CHKTIME;                 // packet send not yet complete
        case PKT_ACKED:
            phase = CFLIE_DATA;
            PROTOCOL_SetBindState(0);
            MUSIC_Play(MUSIC_DONE_BINDING);
            break;
        case PKT_TIMEOUT:
            send_search_packet();
            counter = BIND_COUNT;
        }
        break;

    case CFLIE_DATA:
        update_telemetry();
        if (packet_ack() == PKT_PENDING)
            return PACKET_CHKTIME;         // packet send not yet complete
        send_cmd_packet();
        break;
    }
    return PACKET_PERIOD;                  // Packet at standard protocol interval
}
示例#12
0
void PROTOCOL_CheckDialogs()
{
    if (proto_state & PROTO_MODULEDLG) {
        if(! PAGE_DialogVisible()) {
            //Dialog was dismissed, proceed
            proto_state &= ~PROTO_MODULEDLG;
            PROTOCOL_Init(0);
        }
        return;
    }
    if (PROTOCOL_WaitingForSafe()) {
        PAGE_ShowSafetyDialog();
    } else {
        if (PROTOCOL_Binding()) {
            PAGE_ShowBindingDialog(proto_state & PROTO_BINDDLG);
            proto_state |= PROTO_BINDDLG;
        } else if (proto_state & PROTO_BINDDLG) {
            PAGE_CloseBindingDialog();
            MUSIC_Play(MUSIC_DONE_BINDING);
            proto_state &= ~PROTO_BINDDLG;
        }
    }
}
示例#13
0
static void _vibration_test_cb(guiObject_t *obj, void *data)
{
    (void)obj;
    (void)data;
    MUSIC_Play(MUSIC_TIMER_WARNING);
}
示例#14
0
int main() {

    Init();
#ifndef ENABLE_MODULAR
    //Banner();
#endif
    if(PWR_CheckPowerSwitch()) PWR_Shutdown();

    LCD_Clear(0x0000);
#ifdef TEST_ADC
    ADC_ScanChannels(); while(1);
#endif
    u32 buttons = ScanButtons();
    if (CHAN_ButtonIsPressed(buttons, BUT_ENTER) || !FS_Init()) {
        LCD_DrawUSBLogo(LCD_WIDTH, LCD_HEIGHT);
        USB_Connect();
        LCD_Clear(0x0000);
        FS_Init();
    }

    CONFIG_LoadTx();
    SPI_ProtoInit();
    CONFIG_ReadDisplay();
    CONFIG_ReadModel(CONFIG_GetCurrentModel());
    CONFIG_ReadLang(Transmitter.language);

    BACKLIGHT_Brightness(Transmitter.backlight);
    LCD_Contrast(Transmitter.contrast);
    LCD_SetFont(DEFAULT_FONT.font);
    LCD_SetFontColor(DEFAULT_FONT.font_color);

    GUI_HandleButtons(1);

    MIXER_Init();
    PAGE_Init();

    CLOCK_StartWatchdog();

#if HAS_DATALOG
    DATALOG_Init();
#endif

    priority_ready = 0;
    CLOCK_SetMsecCallback(LOW_PRIORITY, LOW_PRIORITY_MSEC);
    CLOCK_SetMsecCallback(MEDIUM_PRIORITY, MEDIUM_PRIORITY_MSEC);

    // We need to wait until we've actually measured the ADC before proceeding
    while(! (priority_ready & (1 << LOW_PRIORITY)))
        PWR_Sleep();

    //Only do this after we've initialized all channel data so the saftey works
    PROTOCOL_InitModules();
    GUI_DrawScreen();

    // Add startup delay to make sure audio player is initialized
    // AUDIO_Init() has already been called by CONFIG_ReadModel()
#if HAS_EXTENDED_AUDIO
    audio_queue_time = CLOCK_getms() + 1500;
    num_audio=1;
    next_audio=1;
#if (LCD_WIDTH == 480) || (LCD_WIDTH == 320)
    if(Display.background.drawn_background)
        while(CLOCK_getms() < audio_queue_time - 1200);
#endif
    AUDIO_SetVolume(); // Initial setting of voice volume
#endif

    MUSIC_Play(MUSIC_STARTUP);

#ifdef HAS_EVENT_LOOP
    start_event_loop();
#else
    while(1) {
        if(priority_ready) {
            EventLoop();
        }
        //This does not appear to have any impact on power
        //and has been disabled in common/devo/power.c
        //but it helps a huge amount for the emulator
        PWR_Sleep();
    }
#endif
}
示例#15
0
void EventLoop()
{
    CLOCK_ResetWatchdog();

#ifdef HEAP_DEBUG
    static int heap = 0;
    int h = _sbrk_r(NULL, 0);
    if(h > heap) {
        printf("heap: %x\n", h);
        heap = h;
    }
#endif
#ifdef TIMING_DEBUG
    debug_timing(0, 0);
#endif
    priority_ready &= ~(1 << MEDIUM_PRIORITY);
#if !HAS_HARD_POWER_OFF
    if(PWR_CheckPowerSwitch()) {
        if(! (BATTERY_Check() & BATTERY_CRITICAL)) {
            PAGE_Test();
            CONFIG_SaveModelIfNeeded();
            CONFIG_SaveTxIfNeeded();
        }
    	if(Transmitter.music_shutdown) {
#if HAS_EXTENDED_AUDIO
        if(AUDIO_VoiceAvailable()) {
            MUSIC_Play(MUSIC_SHUTDOWN);
            while (CLOCK_getms() < audio_queue_time) {
                // Wait for voice to finished
                CLOCK_ResetWatchdog();
            }
        } else {
#else
        {
            // We wait ~1sec for shutdown buzzer music finished
            unsigned int time;
            MUSIC_Play(MUSIC_SHUTDOWN);
            time = CLOCK_getms()+700;
            while (CLOCK_getms() < time) {
                CLOCK_ResetWatchdog();
            }
#endif
        }
	}

        PWR_Shutdown();
    }
#endif
    BUTTON_Handler();
    TOUCH_Handler();
    INPUT_CheckChanges();

    if (priority_ready & (1 << LOW_PRIORITY)) {
        priority_ready  &= ~(1 << LOW_PRIORITY);
        PAGE_Event();
        PROTOCOL_CheckDialogs();
        TIMER_Update();
        TELEMETRY_Alarm();
        BATTERY_Check();
        AUTODIMMER_Update();
#if HAS_DATALOG
        DATALOG_Update();
#endif
#if HAS_VIDEO
        VIDEO_Update();
#endif
#if HAS_EXTENDED_AUDIO
        AUDIO_CheckQueue();
#endif
        GUI_RefreshScreen();
#if HAS_HARD_POWER_OFF
        if (PAGE_ModelDoneEditing())
            CONFIG_SaveModelIfNeeded();
        CONFIG_SaveTxIfNeeded();
#endif
    }
#ifdef TIMING_DEBUG
    debug_timing(0, 1);
#endif
}

void TOUCH_Handler() {
    if(! HAS_TOUCH)
        return;
    u32 pen_down=0;

    static u32 pen_down_last=0;
    static u32 pen_down_long_at=0;

    struct touch t;

    if(SPITouch_IRQ()) {
        pen_down=1;
        t=SPITouch_GetCoords();
        if (! pen_down_last)
            pen_down_long_at=CLOCK_getms()+500;
    } else {
        pen_down=0;
    }

    if(pen_down && (!pen_down_last)) {
        AUTODIMMER_Check();
        GUI_CheckTouch(&t, 0);
    }

    if(!pen_down && pen_down_last) {
        GUI_TouchRelease();
    }

    if(pen_down && pen_down_last) {
        if(CLOCK_getms()>pen_down_long_at) {
            GUI_CheckTouch(&t, 1);
            pen_down_long_at += 100;
        }
    }
    pen_down_last=pen_down;
}

#if HAS_VIDEO
void VIDEO_Update()
{
    static u8 video_enable = 0;
    static u32 check_standard_ms = 0;

    // Check if Video is turn on
    int enabled = MIXER_SourceAsBoolean(Model.videosrc);

    if (enabled != video_enable) {
        VIDEO_Enable(enabled);
        video_enable = enabled;
        if (enabled) {
            VIDEO_SetChannel(Model.videoch);
            VIDEO_Contrast(Model.video_contrast);
            VIDEO_Brightness(Model.video_brightness);
            check_standard_ms = CLOCK_getms() + 3000;
        }
        else
            check_standard_ms = 0;
    }

    if(video_enable &&
        check_standard_ms > 0
        && check_standard_ms < CLOCK_getms()) {
            u8 video_standard_current = VIDEO_GetStandard();
            if((video_standard_current > 0) &&
               (video_standard_current < 8)) {
                VIDEO_SetStandard(video_standard_current);
                check_standard_ms = 0;
            }
            else {
                check_standard_ms = CLOCK_getms() + 3000;
            }
        }

    if(video_enable)
        AUTODIMMER_Check();
}
#endif //HAS_VIDEO

#ifdef TIMING_DEBUG
void debug_timing(u32 type, int startend)
{
    static u32 last_time[2][100];
    static u32 loop_time[4][101];
    static u32 loop_pos[4] = {-1, -1, -1, -1};
    static u32 max_last[2];
    static u32 max_loop[4];
    static int save_priority;

    if (type == 0) {
        if (! startend)
            save_priority = priority_ready;
        if (save_priority & (1 << MEDIUM_PRIORITY))
            debug_timing(2, startend);
        if (save_priority & (1 << LOW_PRIORITY))
            debug_timing(1, startend);
        return;
    }
    type--;
    if (! startend) {
        u32 t = CLOCK_getms();
        loop_pos[type] = (loop_pos[type] + 1) % 100;
        if (type < 2) {
            last_time[type][loop_pos[type]] = t;
            if (t - last_time[type][(loop_pos[type] + 99) % 100] > max_last[type])
                max_last[type] = t - last_time[type][(loop_pos[type] + 99) % 100];
        }
        loop_time[type][100] = t;
    } else {
        loop_time[type][loop_pos[type]] = CLOCK_getms() - loop_time[type][100];
        if (loop_time[type][loop_pos[type]] > max_loop[type])
            max_loop[type] = loop_time[type][loop_pos[type]];
        if (type == 0 && loop_pos[0] == 99) {
            unsigned avg_loop[4] = {0, 0, 0, 0};
            unsigned avg_last[2] = {0, 0};
            for(int i = 0; i < 99; i++) {
                for(int t = 0; t < 2; t++) {
                    u32 delay = last_time[t][(i + loop_pos[t] + 2) % 100] - last_time[t][(i + loop_pos[t] + 1) % 100];
                    avg_last[t] += delay;
                }
                for(int t = 0; t < 4; t++)
                    avg_loop[t] += loop_time[t][i];
            }
            for(int t = 0; t < 4; t++)
                avg_loop[t] /= 99;
            avg_last[0] /= 99;
            avg_last[1] /= 99;
            printf("Avg: radio: %d mix: %d med: %d/%d low: %d/%d\n", avg_loop[3], avg_loop[2], avg_loop[1], avg_last[1], avg_loop[0], avg_last[0]);
            printf("Max: radio: %d mix: %d med: %d/%d low: %d/%d\n", max_loop[3], max_loop[2], max_loop[1], max_last[1], max_loop[0], max_last[0]);
            memset(max_loop, 0, sizeof(max_loop));
            max_last[0] = 0;
            max_last[1] = 0;
        }
    }
}
#endif

void debug_switches()
{
    s32 data[INP_LAST];
    for(int i = INP_HAS_CALIBRATION+1; i < INP_LAST; i++) {
        data[i] = CHAN_ReadRawInput(i);
    }
    while(1) {
        u32 changed = 0;
        for(int i = INP_HAS_CALIBRATION+1; i < INP_LAST; i++) {
            s32 val = CHAN_ReadRawInput(i);
            if (val != data[i]) {
                printf("%s=%d  ", INPUT_SourceName(tempstring, i), val);
                data[i] = val;
                changed = 1;
            }
        }
        if (changed) { printf("\n"); }
        if(PWR_CheckPowerSwitch()) PWR_Shutdown();
    }
}
示例#16
0
void TIMER_Update()
{
    unsigned i;
    unsigned chan_val = 0;
    u32 t = CLOCK_getms();
    if (PROTOCOL_WaitingForSafe())
        return;
    if( Transmitter.power_alarm > 0 )
        TIMER_Power();
    for (i = 0; i < NUM_TIMERS; i++) {
        if (Model.timer[i].src) {
            s16 val;
            if (MIXER_SRC(Model.timer[i].src) <= NUM_INPUTS) {
                volatile s16 *raw = MIXER_GetInputs();
                val = raw[MIXER_SRC(Model.timer[i].src)];
            } else {
                val = MIXER_GetChannel(Model.timer[i].src - NUM_INPUTS - 1, APPLY_SAFETY);
            }
            if (MIXER_SRC_IS_INV(Model.timer[i].src))
                val = -val;
            if (Model.timer[i].type == TIMER_STOPWATCH_PROP
                || Model.timer[i].type == TIMER_COUNTDOWN_PROP)
            {
               chan_val = RANGE_TO_PCT(abs(val));
               if (chan_val > 100)
                   chan_val = 100;
            } else {
                unsigned new_state = (val - CHAN_MIN_VALUE > (CHAN_MAX_VALUE - CHAN_MIN_VALUE) / 20) ? 1 : 0;
                if (new_state != timer_state[i]) {
                    if (new_state)
                        last_time[i] = t;
                    timer_state[i] = new_state;
                }
            }
        }
        if (timer_state[i]) {
            s32 delta = t - last_time[i];
            if (Model.timer[i].type == TIMER_STOPWATCH_PROP || Model.timer[i].type == TIMER_COUNTDOWN_PROP) {
                delta = delta * chan_val / 100;
            }
            if (Model.timer[i].type == TIMER_PERMANENT) {
                timer_val[i] += delta;
                if( timer_val[i] >= 359999900) // Reset when 99h59mn59sec
                    timer_val[i] = 0 ;
                Model.timer[i].val = timer_val[i];
            } else if (Model.timer[i].type == TIMER_STOPWATCH || Model.timer[i].type == TIMER_STOPWATCH_PROP) {
                timer_val[i] += delta;
            } else {
                s32 warn_time;
                // start to beep  for each prealert_interval at the last prealert_time(seconds)
                if (Transmitter.countdown_timer_settings.prealert_time != 0 &&
                    Transmitter.countdown_timer_settings.prealert_interval != 0 &&
                    timer_val[i] > Transmitter.countdown_timer_settings.prealert_interval &&
                    timer_val[i] < (s32)Transmitter.countdown_timer_settings.prealert_time + 1000) { // give extra 1seconds
                    warn_time = ((timer_val[i] / Transmitter.countdown_timer_settings.prealert_interval)
                            * Transmitter.countdown_timer_settings.prealert_interval);
                    if (timer_val[i] > warn_time && (timer_val[i] - delta) <= warn_time) {
                        MUSIC_Play(MUSIC_TIMER_WARNING);
                    }
                }
                // Beep once for each timeup_interval past 0
                if (timer_val[i] < 0 && Transmitter.countdown_timer_settings.timeup_interval != 0) {
                    warn_time = ((timer_val[i] - Transmitter.countdown_timer_settings.timeup_interval) / Transmitter.countdown_timer_settings.timeup_interval)
                            * Transmitter.countdown_timer_settings.timeup_interval;
                    if (timer_val[i] > warn_time && (timer_val[i] - delta) <= warn_time) {
                        MUSIC_Play(MUSIC_ALARM1 + i);
                    }
                }
                if (timer_val[i] >= 0 && timer_val[i] < delta) {
                    MUSIC_Play(MUSIC_ALARM1 + i);
                }
                timer_val[i] -= delta;
            }
            last_time[i] = t;
        } 
        if (Model.timer[i].resetsrc) {
            s16 val;
            if (MIXER_SRC(Model.timer[i].resetsrc) <= NUM_INPUTS) {
                volatile s16 *raw = MIXER_GetInputs();
                val = raw[MIXER_SRC(Model.timer[i].resetsrc)];
            } else {
                val = MIXER_GetChannel(Model.timer[i].resetsrc - NUM_INPUTS - 1, APPLY_SAFETY);
            }
            if (MIXER_SRC_IS_INV(Model.timer[i].resetsrc))
                val = -val;
            if (val - CHAN_MIN_VALUE > (CHAN_MAX_VALUE - CHAN_MIN_VALUE) / 20) {
                TIMER_Reset(i);
            }
        }
    }
}
示例#17
0
int main() {
    
    Init();
#ifndef MODULAR
    //Banner();
#endif
    if(PWR_CheckPowerSwitch()) PWR_Shutdown();

    LCD_Clear(0x0000);
#ifdef TEST_ADC
    ADC_ScanChannels(); while(1);
#endif
    u32 buttons = ScanButtons();
    if(CHAN_ButtonIsPressed(buttons, BUT_ENTER) || !FS_Mount(NULL, NULL)) {
        LCD_DrawUSBLogo(LCD_WIDTH, LCD_HEIGHT);
        USB_Connect();
        LCD_Clear(0x0000);
        FS_Mount(NULL, NULL);
    }
    
    CONFIG_LoadTx();
    SPI_ProtoInit();
    CONFIG_ReadDisplay();
    CONFIG_ReadModel(CONFIG_GetCurrentModel());
    CONFIG_ReadLang(Transmitter.language);

    BACKLIGHT_Brightness(Transmitter.brightness);
    LCD_Contrast(Transmitter.contrast);
    LCD_SetFont(DEFAULT_FONT.font);
    LCD_SetFontColor(DEFAULT_FONT.font_color);

    MUSIC_Play(MUSIC_STARTUP);
    GUI_HandleButtons(1);

    MIXER_Init();
    PAGE_Init();
    
    CLOCK_StartWatchdog();

#if DATALOG_ENABLED
    DATALOG_Init();
#endif

    priority_ready = 0;
    CLOCK_SetMsecCallback(LOW_PRIORITY, LOW_PRIORITY_MSEC);
    CLOCK_SetMsecCallback(MEDIUM_PRIORITY, MEDIUM_PRIORITY_MSEC);

    // We need to wait until we've actually measured the ADC before proceeding
    while(! (priority_ready & (1 << LOW_PRIORITY)))
        ;

    //Only do this after we've initialized all channel data so the saftey works
    PROTOCOL_Init(0);
    GUI_DrawScreen();

#ifdef HAS_EVENT_LOOP
    start_event_loop();
#else
    while(1) {
        if(priority_ready) {
            EventLoop();
        }
        //PWR_Sleep();  //This does not appear to have any impact on power
    }
#endif
}
示例#18
0
//#define DEBUG_TELEMALARM
void TELEMETRY_Alarm()
{
    //Update 'updated' state every time we get here
    u32 current_time = CLOCK_getms();
    if (current_time - last_time > TELEM_ERROR_TIME) {
        last_time = current_time;
        for(int i = 0; i < TELEM_UPDATE_SIZE; i++) {
            last_updated[i] = Telemetry.updated[i];
            Telemetry.updated[i] = 0;
        }
    }
    // don't need to check all the 6 telem-configs at one time, this is not a critical and urgent task
    // instead, check 1 of them at a time
    telem_idx = (telem_idx + 1) % TELEM_NUM_ALARMS;
    if(! Model.telem_alarm[telem_idx]) {
        alarm &= ~(1 << telem_idx); // clear this set
        return;
    }
    u8 idx = Model.telem_alarm[telem_idx];
    s32 value = TELEMETRY_GetValue(idx);
    if (value == 0) {
        alarm &= ~(1 << telem_idx); // clear this set
        return;
    }

    if (! TELEMETRY_IsUpdated(0xff)) {
        // bug fix: do not alarm when no telem packet is received, it might caused by RX is powered off
        alarm &= ~(1 << telem_idx); // clear this set
        return;
    }

    if (Model.telem_flags & (1 << telem_idx)) {
        if (! (alarm & (1 << telem_idx)) && (value <= Model.telem_alarm_val[telem_idx])) {
            if (alarm_duration[telem_idx] == 0) {
                alarm_duration[telem_idx] = current_time;
            } else if (current_time - alarm_duration[telem_idx] > CHECK_DURATION) {
                alarm_duration[telem_idx] = 0;
                alarm |= 1 << telem_idx;
#ifdef DEBUG_TELEMALARM
                printf("set: 0x%x\n\n", alarm);
#endif
            }
        } else if ((alarm & (1 << telem_idx)) && (value > (s32)Model.telem_alarm_val[telem_idx])) {
            if (alarm_duration[telem_idx] == 0) {
                alarm_duration[telem_idx] = current_time;
            } else if (current_time - alarm_duration[telem_idx] > CHECK_DURATION) {
                alarm_duration[telem_idx] = 0;
                alarm &= ~(1 << telem_idx);
#ifdef DEBUG_TELEMALARM
                printf("clear: 0x%x\n\n", alarm);
#endif
            }
        } else
            alarm_duration[telem_idx] = 0;
    } else {
        if (! (alarm & (1 << telem_idx)) && (value >= Model.telem_alarm_val[telem_idx])) {
            if (alarm_duration[telem_idx] == 0) {
                alarm_duration[telem_idx] = current_time;
            } else if (current_time - alarm_duration[telem_idx] > CHECK_DURATION) {
                alarm_duration[telem_idx] = 0;
                alarm |= 1 << telem_idx;
#ifdef DEBUG_TELEMALARM
                printf("set: 0x%x\n\n", alarm);
#endif
            }
        } else if ((alarm & (1 << telem_idx)) && (value < (s32)Model.telem_alarm_val[telem_idx])) {
            if (alarm_duration[telem_idx] == 0) {
                alarm_duration[telem_idx] = current_time;
            } else if (current_time - alarm_duration[telem_idx] > CHECK_DURATION) {
                alarm_duration[telem_idx] = 0;
                alarm &= ~(1 << telem_idx);
#ifdef DEBUG_TELEMALARM
                printf("clear: 0x%x\n\n", alarm);
#endif
            }
        } else
            alarm_duration[telem_idx] = 0;
    }

    if ((alarm & (1 << telem_idx))) {
        if (current_time >= alarm_time + MUSIC_INTERVAL) {
            alarm_time = current_time;
#ifdef DEBUG_TELEMALARM
            printf("beep: %d\n\n", telem_idx);
#endif
            MUSIC_Play(MUSIC_TELEMALARM1 + telem_idx);
        }
    }
}
示例#19
0
int main() {

    Init();
#ifndef MODULAR
    //Banner();
#endif
    if(PWR_CheckPowerSwitch()) PWR_Shutdown();

    LCD_Clear(0x0000);
#ifdef TEST_ADC
    ADC_ScanChannels(); while(1);
#endif
    u32 buttons = ScanButtons();
    if(CHAN_ButtonIsPressed(buttons, BUT_ENTER) || !FS_Mount(NULL, NULL)) {
        LCD_DrawUSBLogo(LCD_WIDTH, LCD_HEIGHT);
        USB_Connect();
        LCD_Clear(0x0000);
        FS_Mount(NULL, NULL);
    }

    CONFIG_LoadTx();
    SPI_ProtoInit();
    CONFIG_ReadDisplay();
    CONFIG_ReadModel(CONFIG_GetCurrentModel());
    CONFIG_ReadLang(Transmitter.language);

    BACKLIGHT_Brightness(Transmitter.backlight);
    LCD_Contrast(Transmitter.contrast);
    LCD_SetFont(DEFAULT_FONT.font);
    LCD_SetFontColor(DEFAULT_FONT.font_color);

#if !HAS_EXTENDED_AUDIO
    // If Extended Audio is present, move startup msg to Splash page to allow additional audio hardware initialization time
    MUSIC_Play(MUSIC_STARTUP);
#else
    if (Transmitter.splash_delay < 5)
        MUSIC_Play(MUSIC_STARTUP); // if no splash page startup msg is used force playing here
#endif
    GUI_HandleButtons(1);

    MIXER_Init();
    PAGE_Init();

    CLOCK_StartWatchdog();

#if HAS_DATALOG
    DATALOG_Init();
#endif

    priority_ready = 0;
    CLOCK_SetMsecCallback(LOW_PRIORITY, LOW_PRIORITY_MSEC);
    CLOCK_SetMsecCallback(MEDIUM_PRIORITY, MEDIUM_PRIORITY_MSEC);

    // We need to wait until we've actually measured the ADC before proceeding
    while(! (priority_ready & (1 << LOW_PRIORITY)))
        ;

    //Only do this after we've initialized all channel data so the saftey works
    PROTOCOL_InitModules();
    GUI_DrawScreen();

#ifdef HAS_EVENT_LOOP
    start_event_loop();
#else
    while(1) {
        if(priority_ready) {
            EventLoop();
        }
        //This does not appear to have any impact on power
        //and has been disabled in common/devo/power.c
        //but it helps a huge amount for the emulator
        PWR_Sleep();
    }
#endif
}
示例#20
0
文件: music.c 项目: F-D-R/deviation
void MUSIC_PlayValue(u16 music, s32 value, u8 unit, u8 prec)
{
    u32 i;
    char digits[6]; // Do we need more?
    char thousands = 0;
    u8 digit_count = 0;

    if ( !AUDIO_VoiceAvailable() || !AUDIO_AddQueue(music)) {
        if (music < MUSIC_TOTAL)
            MUSIC_Play(music);
        return;
    }

    // Play minutes/hours/seconds for timers
    if (unit == VOICE_UNIT_TIME) {
        if (value >= 3600) {
            i = value / 3600;
            AUDIO_AddQueue(i + MUSIC_TOTAL);
            AUDIO_AddQueue(VOICE_UNIT_HOURS + VOICE_UNIT_OFFSET);
            value %= 3600;
        }
        if (value >= 60) {
            i = value / 60;
            AUDIO_AddQueue(i + MUSIC_TOTAL);
            AUDIO_AddQueue(VOICE_UNIT_MINUTES + VOICE_UNIT_OFFSET);
            value %= 60;
        }
        if (value > 0) {
            AUDIO_AddQueue(value + MUSIC_TOTAL);
            AUDIO_AddQueue(VOICE_UNIT_SECONDS + VOICE_UNIT_OFFSET);
        }
        return;
    }

    // Add minus sign for negative number
    if (value < 0) {
        AUDIO_AddQueue(VOICE_UNIT_MINUS + VOICE_UNIT_OFFSET);
        value *= -1;
    }

    //Add precision digits
    for (i=0; i < prec; i++) {
        digits[digit_count++] = value % 10;
        value /=10;
    }
    //Add decimal seperator
    if (prec > 0) {
        digits[digit_count++] = VOICE_DEC_SEP;
    }

    // Special case value == 0 and not playing TIME
    if (value == 0 && unit != VOICE_UNIT_TIME)
        digits[digit_count++] = 0;
    // Get single digits from remaining value
    while (value > 0) {
        if(value > 999) {
            thousands = value / 1000;
            value %= 1000;
        }
        if(value > 100) {
            digits[digit_count++] = value % 100;
            value /= 100;
            digits[digit_count++] = value + 99;
            if (thousands){
              digits[digit_count++] = 109; // MP3 for "thousands"
              digits[digit_count++] = thousands;
            }
            break;
        }
        if(value < 101 && value > 0) {
            digits[digit_count++] = value;
            break;
        }
        else {
            if (thousands){
                digits[digit_count++] = 109; // MP3 for "thousands"
                digits[digit_count++] = thousands;
            }
        }
    }

    // Fill music queue with digits
    for (i = digit_count; i > 0; i--) {
        AUDIO_AddQueue(digits[i-1] + MUSIC_TOTAL);
    }
    // Add unit for value if specified
    if (unit > VOICE_UNIT_NONE)
        AUDIO_AddQueue(unit + VOICE_UNIT_OFFSET);
}