Esempio n. 1
0
File: input.c Progetto: eknl/gt3b
static void read_ADC(void) {
    u16 *buf = adc_buffer[adc_buffer_pos];
    u8  dead;

    ADC_NEWVAL(0);
    ADC_NEWVAL(1);
    ADC_NEWVAL(2);
    adc_battery_last = ADC_DB3R;

    adc_buffer_pos++;
    adc_buffer_pos &= 3;

    BRES(ADC_CSR, 7);		// remove EOC flag
    BSET(ADC_CR1, 0);		// start new conversion

    // average battery voltage and check battery low
    // ignore very low, which means that it is supplied from SWIM connector
    adc_battery_filt = adc_battery_filt * (ADC_BAT_FILT - 1); // splitted - compiler hack
    adc_battery_filt = (adc_battery_filt + (ADC_BAT_FILT / 2)) / ADC_BAT_FILT
		       + adc_battery_last;
    adc_battery = (u16)((adc_battery_filt + (ADC_BAT_FILT / 2)) / ADC_BAT_FILT);
    // start checking battery after 5s from power on
    if (time_sec >= 5) {
	// wakeup task only when something changed
	if (adc_battery > 50 && adc_battery < battery_low_raw) {
	    // bat low
	    if (!menu_battery_low) {
		menu_battery_low = 1;
		awake(MENU);
	    }
	}
	else {
	    // bat OK, but apply some hysteresis to not switch quickly ON/OFF
	    if (menu_battery_low && adc_battery > battery_low_raw + 100) {
		menu_battery_low = 0;
		awake(MENU);
	    }
	}
    }

    // wakeup MENU task when showing battery or at calibrate
    if (menu_wants_adc)
	awake(MENU);

    // reset inactivity timer when some steering or throttle applied
    dead = cg.steering_dead_zone;
    if (dead < 20)  dead = 20;  // use some minimal dead zone for this check
    if (adc_steering_last < (cg.calib_steering_mid - dead) ||
        adc_steering_last > (cg.calib_steering_mid + dead))
	    reset_inactivity_timer();
    else {
	dead = cg.throttle_dead_zone;
	if (dead < 20)  dead = 20;  // use some minimal dead zone for this check
	if (adc_throttle_last < (cg.calib_throttle_mid - dead) ||
	    adc_throttle_last > (cg.calib_throttle_mid + dead))
		reset_inactivity_timer();
    }
}
Esempio n. 2
0
File: main.c Progetto: SeaPea/HomeP
// Timer event when status update operation times out
void status_change_timeout(void *data) {
  reset_inactivity_timer();
  status_change_timeout_timer = NULL;
  s_device_status_target = DSNone;
  cancel_status_check();
  show_device_status(s_device_status, s_status_changed);
  show_msg("Operation timed out", false, 5);
}
Esempio n. 3
0
   bool Server::register_business_client( QString const & client_name )
   {
      QMutexLocker lock( &mutex_ );
      auto it = business_clients_.insert( BusinessClientsCt::value_type( client_name.toStdString(), BusinessUsersCt() ) );

      reset_inactivity_timer(); 
      return it.second;
   }
Esempio n. 4
0
File: main.c Progetto: SeaPea/HomeP
// Callback for when Device ID list has been fetched
void device_list_fetched() {
  reset_inactivity_timer();
  if (g_device_count == 0) {
    show_msg("No devices found!", false, 0);
    hide_mainwin();
  } else {
    if (!showing_mainwin()) show_mainwin();
    hide_msg();
    g_device_selected = 0;
    device_details_fetch(g_device_id_list[g_device_selected]);
  }
}
Esempio n. 5
0
   void Server::incomingConnection( qintptr handle )
   {
      cout << "server: incomingConnection " << endl;

      Connection * c = new Connection();
      c->setAutoDelete(true);
      c->set_descriptor( handle );

      QMutexLocker lock( &mutex_ );
      threadpool_->start( c );
      reset_inactivity_timer(); 
   }
Esempio n. 6
0
   bool Server::register_business_userid( QString const & client_name, int user_id )
   {
      auto it = business_clients_.find( client_name.toStdString() );
      if( it == business_clients_.end() )
         return false;

      QMutexLocker lock( &mutex_ );
      auto it_u = it->second.insert( BusinessUsersCt::value_type( user_id ) );
      
      reset_inactivity_timer(); 
      return it_u.second;
   }
Esempio n. 7
0
File: main.c Progetto: SeaPea/HomeP
// Callback for when the phone JS indicates the status change was sent to the MyQ server
void device_status_change_sent(int device_id) {
  reset_inactivity_timer();
  if (s_device_status_target != DSNone && g_device_id_list[g_device_selected] == device_id) {
    APP_LOG(APP_LOG_LEVEL_DEBUG, "Status change sent. Checking for status updates...");
    // Start checking for the status reaching the target 
    // (For garage doors, wait 10 seconds before first check due to how long it take)
    int first_check = (s_device_type == DTLightSwitch) ? 3000 : 10000;
    if (status_change_check_timer != NULL)
      app_timer_reschedule(status_change_check_timer, first_check);
    else
      status_change_check_timer = app_timer_register(first_check, status_change_check, NULL);
  }
}
Esempio n. 8
0
File: main.c Progetto: SeaPea/HomeP
// Callback for when user switches between devices
void device_switched() {
  reset_inactivity_timer();
  cancel_status_check();
  cancel_timeout();
  if (status_fetch_delay_timer != NULL) {
    app_timer_cancel(status_fetch_delay_timer);
    status_fetch_delay_timer = NULL;
  }
  // Fetch device details after a brief delay to avoid busy comms error
  if (details_fetch_delay_timer == NULL)
    details_fetch_delay_timer = app_timer_register(500, device_details_fetch_delayed, NULL);
  else
    app_timer_reschedule(details_fetch_delay_timer, 500);
}
Esempio n. 9
0
File: main.c Progetto: SeaPea/HomeP
// Callback to show any error received from the phone JS or MyQ servers
void comms_error(char *error_message) {
  cancel_status_check();
  cancel_timeout();
  show_msg(error_message, false, 0);
  if (g_device_count == 0) {
    if (inactivity_timer != NULL) {
      app_timer_cancel(inactivity_timer);
      inactivity_timer = NULL;
    }
    // If there are no devices, hide main win so the app closes when the error message is closed
    hide_mainwin();
  } else {
    reset_inactivity_timer();
  }
}
Esempio n. 10
0
File: main.c Progetto: SeaPea/HomeP
void handle_init(void) {
  g_device_id_list = NULL;
  show_mainwin();
  show_msg("HomeP\n\nLogging In...", true, 0);
  comms_register_errorhandler(comms_error);
  comms_register_devicelist(device_list_fetched);
  comms_register_devicedetails(device_details_fetched);
  comms_register_devicestatus(device_status_fetched);
  comms_register_devicestatusset(device_status_change_sent);
  ui_register_deviceswitch(device_switched);
  ui_register_statuschange(device_status_change);
  reset_inactivity_timer();
  // Initializing comms will trigger phone JS to fetch device list
  init_comms();
}
Esempio n. 11
0
File: main.c Progetto: SeaPea/HomeP
// Callback for when device details have been fetched
void device_details_fetched(int device_id, char *location, char *name, DeviceType device_type) {
  APP_LOG(APP_LOG_LEVEL_DEBUG, "Details fetched - ID: %d, Location: %s, Name: %s, DeviceType: %d", 
          device_id, location, name, device_type);
  reset_inactivity_timer();
  
  if (g_device_id_list[g_device_selected] == device_id) {
    show_device_details(location, name, device_type);
    s_device_type = device_type;
    s_device_status = DSUpdating;
    show_device_status(DSUpdating, "");
    // Fetch device status after a brief delay to avoid busy comms error
    if (status_fetch_delay_timer == NULL)
      status_fetch_delay_timer = app_timer_register(100, status_fetch_delayed, NULL);
    else
      app_timer_reschedule(status_fetch_delay_timer, 100);
  }
}
Esempio n. 12
0
static void gs_inactivity_alarm(u8 change) {
    if (change == 0xff) {
	lcd_set(L7SEG, LB_EMPTY);
	return;
    }
    if (change) {
	cg.inactivity_alarm = (u8)menu_change_val(cg.inactivity_alarm, 0, 10,
						  1, 1);
	reset_inactivity_timer();
    }
    lcd_7seg(L7_A);
    if (!cg.inactivity_alarm)  lcd_chars("OFF");
    else {
	bl_num2(cg.inactivity_alarm);
	lcd_char(LCHR3, 'M');
    }
}
Esempio n. 13
0
File: main.c Progetto: SeaPea/HomeP
// Callbck for when the device status has been fetched
void device_status_fetched(int device_id, DeviceStatus status, char *status_changed) {
  APP_LOG(APP_LOG_LEVEL_DEBUG, "Status fetched - ID: %d, Status: %d, Selected ID: %d", 
          device_id, status, g_device_id_list[g_device_selected]);
  reset_inactivity_timer();
  
  if (g_device_id_list[g_device_selected] == device_id) {
    if (s_device_status_target != DSNone) {
      // If expecting the device status to change (e.g. Garage door opening/closing)
      cancel_status_check();
      
      if (((status == DSVGDOOpen) ? DSOnOpen : status) != s_device_status_target) {
        APP_LOG(APP_LOG_LEVEL_DEBUG, "Status still not reached target, checking again in 2 seconds...");
        // Still not reached target status, so check again after 2 seconds
        status_change_check_timer = app_timer_register(2000, status_change_check, NULL);
      } else {
        APP_LOG(APP_LOG_LEVEL_DEBUG, "Status has reached target");
        // Status changed, so stop checking
        cancel_timeout();
        s_device_status_target = DSNone;
        s_device_status = status;
        strncpy(s_status_changed, status_changed, sizeof(s_status_changed));
        s_status_changed[sizeof(s_status_changed)-1] = '\0';
        show_device_status(status, status_changed);
        light_enable_interaction();
        vibes_short_pulse();
      }
      
    } else {
      // Not expecting status to change, so just update the display
      cancel_status_check();
      
      if (status != s_device_status) {
        s_device_status = status;
        light_enable_interaction();
      }
      strncpy(s_status_changed, status_changed, sizeof(s_status_changed));
      s_status_changed[sizeof(s_status_changed)-1] = '\0';
      show_device_status(status, status_changed);
    }
  }
}
Esempio n. 14
0
File: main.c Progetto: SeaPea/HomeP
// Callback when user indicates status should be changed
void device_status_change() {
  reset_inactivity_timer();
  switch (s_device_status) {
    case DSOnOpen:
      switch (s_device_type) {
        case DTLightSwitch:
          s_device_status_target = DSOff;
          show_device_status(DSTurningOff, "");
          break;
        default:
          s_device_status_target = DSClosed;
          show_device_status(DSClosing, "");
          break;
      }
      break;
    case DSVGDOOpen:
    case DSOpening:
      s_device_status_target = DSClosed;
      show_device_status(DSClosing, "");
      break;
    case DSOff:
      s_device_status_target = DSOnOpen;
      show_device_status(DSTurningOn, "");
      break;
    case DSClosed:
    case DSClosing:
      s_device_status_target = DSOnOpen;
      show_device_status(DSOpening, "");
      break;
    default:
      // Do nothing
      return;
      break;
  }
  // Send request to MyQ servers to change the status
  device_status_set(g_device_id_list[g_device_selected], s_device_status_target);
  status_change_timeout_timer = app_timer_register(60000, status_change_timeout, NULL);
}
Esempio n. 15
0
File: main.c Progetto: SeaPea/HomeP
// Timer event to update the device status periodically when it is changing
void status_change_check(void *data) {
  reset_inactivity_timer();
  status_change_check_timer = NULL;
  device_status_fetch(g_device_id_list[g_device_selected]);
}
Esempio n. 16
0
File: input.c Progetto: eknl/gt3b
// read all keys
static void read_keys(void) {
    u16 buttons_state_last = buttons_state;
    u16 buttons_last = buttons;
    u16 bit;
    u8 i, lbs, bs;

    // rotate last buttons
    buttons3 = buttons2;
    buttons2 = buttons1;

    // read actual keys status
    buttons1 = read_key_matrix();

    // add CH3 button
    if (adc_ch3_last < 50)  buttons1 |= BTN_CH3;

    // combine last 3 readed buttons
    buttons_state |= buttons1 & buttons2 & buttons3;
    buttons_state &= buttons1 | buttons2 | buttons3;

    // do autorepeat/long_press only when some keys were pressed
    if (buttons_state_last || buttons_state) {
	// key pressed or released, activate backlight
	backlight_on();

	// handle autorepeat for first 8 keys (TRIMs and D/R)
	if (buttons_autorepeat) {
	    for (i = 0, bit = 1; i < 8; i++, bit <<= 1) {
		if (!(bit & buttons_autorepeat))  continue;  // not autorepeated
		lbs = (u8)(buttons_state_last & bit ? 1 : 0);
		bs = (u8)(buttons_state & bit ? 1 : 0);
		if (!lbs) {
		    // last not pressed
		    if (bs) {
			// now pressed, set it pressed and set autorepeat delay
			buttons |= bit;
			buttons_timer[i] = BTN_AUTOREPEAT_DELAY;
		    }
		    // do nothing for now not pressed
		}
		else {
		    // last was pressed
		    if (bs) {
			// now pressed
			if (--buttons_timer[i])  continue;  // not expired yet
			// timer expired, set it pressed and set autorepeat rate
			buttons |= bit;
			buttons_timer[i] = BTN_AUTOREPEAT_RATE;
		    }
		    // do nothing for now not pressed
		}
	    }
	}

	// handle long presses for first 12 keys
	// exclude keys with autorepeat ON
	for (i = 0, bit = 1; i < 12; i++, bit <<= 1) {
	    if (bit & buttons_autorepeat)  continue;  // handled in autorepeat
	    lbs = (u8)(buttons_state_last & bit ? 1 : 0);
	    bs = (u8)(buttons_state & bit ? 1 : 0);
	    if (!lbs) {
		// last not pressed
		if (bs) {
		    // now pressed, set long press delay
		    buttons_timer[i] = cg.long_press_delay;
		}
		// do nothing for now not pressed
	    }
	    else {
		// last was pressed
		if (bs) {
		    // now pressed, check long press delay
		    // if already long or not long enought, skip
		    if (!buttons_timer[i] || --buttons_timer[i])  continue;
		    // set as pressed and long pressed
		    buttons |= bit;
		    buttons_long |= bit;
		}
		else {
		    // now not pressed, set as pressed when no long press was applied
		    if (!buttons_timer[i])  continue;  // was long before
		    buttons |= bit;
		}
	    }
	}

    }


    // add rotate encoder
    if (encoder_timer)  encoder_timer--;
    if (TIM1_CNTRL) {
	// encoder changed
	if ((s8)TIM1_CNTRL >= 0) {
	    // left
	    buttons |= BTN_ROT_L;
	    if (encoder_timer)  buttons_long |= BTN_ROT_L;
	}
	else {
	    // right
	    buttons |= BTN_ROT_R;
	    if (encoder_timer)  buttons_long |= BTN_ROT_R;
	}
	// set it back to default value
	TIM1_CNTRL = 0;
	// init timer
	encoder_timer = ENCODER_FAST_THRESHOLD;
	backlight_on();
    }


    // if some of the keys changed, wakeup MENU task and reset inactivity timer
    if (buttons_last != buttons || buttons_state_last != buttons_state) {
	awake(MENU);
	reset_inactivity_timer();
    }
}