Quantcast
Channel: xda-developers - HD2 Android NAND Development
Viewing all articles
Browse latest Browse all 164

[DEV][14/Nov/2012]HD2 off-mode Alarm Clock(cLK)[WIP]

$
0
0
  • This is an experiment - project. It is about adding off-mode alarm clock to the HD2.
    (If you don't have cLK installed (at least v1.5.1.4), then this is not applicable for you)
    Quote:

    Originally Posted by kokotas (Post 21158811)
    Is it even possible to include something like auto-power-on in cLK, for alarm clock purposes? :)

    After ~10 months, zicoxx asked more or less the same thing:
    Quote:

    Originally Posted by zicoxx (Post 33758859)
    i want to suggest a feature for clk and our hd2..offline alarms

    So lets see what we have so far...
  • This project depends on 3 factors, (1)Kernel, (2)Android application, (3)Bootloader.
    1. Kernel
      The kernel has a function in arch\arm\mach-msm\pm.c which handles the reboot reason:
      Code:

      static int msm_reboot_call(struct notifier_block *this, unsigned long code, void *_cmd)
      {
              if((code == SYS_RESTART) && _cmd) {
                      char *cmd = _cmd;
                      if (!strcmp(cmd, "bootloader")) {
                              restart_reason = 0x77665500;
                      } else if (!strcmp(cmd, "recovery")) {
                              restart_reason = 0x77665502;
                      } else if (!strcmp(cmd, "eraseflash")) {
                              restart_reason = 0x776655EF;
                      } else if (!strncmp(cmd, "oem-", 4)) {
                              unsigned code = simple_strtoul(cmd + 4, 0, 16) & 0xff;
                              restart_reason = 0x6f656d00 | code;
                     
                      //This is the proposed patch to our kernel
                      //(thanks Rick_1995 for suggesting it to bypass the time limit of 255 min)
                      } else if (!strncmp(cmd, "S", 1)) {
                              unsigned code = simple_strtoul(cmd + 1, 0, 16) & 0x00ffffff;
                              restart_reason = 0x53000000 | code;

                      } else if (!strcmp(cmd, "force-hard")) {
                              restart_reason = 0x776655AA;
                      } else {
                              restart_reason = 0x77665501;
                      }
              }
              return NOTIFY_DONE;
      }

      Not being able to compile a new kernel with a change like the green text in the above function, I just used the "oem-" prefix in the reboot reason passed from the application. The downside of this is that we can't set an alarm for more than 255 min from the current time.
    2. Application
      The application is able to:
      1. reboot the device using the PowerManager class since it is signed and placed in /system/app:
        Code:

        //MinutesToSuspend is set using a TimePicker
        mPowerManager.reboot("oem-" + MinutesToSuspend);

        //In case we have a kernel with the above patch included
        mPowerManager.reboot("S" + MinutesToSuspend);

      2. play the alarm when the device has booted usind the BroadcastReceiver class that will get the BOOT_COMPLETED action.
    3. Bootloader
      The bootloader (in this case cLK):
      1. detects the boot reason and decodes the MinutesToSuspend from it and enters a sort of suspend mode with a timeout equal to MinutesToSuspend converted to msec
        Code:

        if(target_check_reboot_mode() == (target_check_reboot_mode() | 0x6f656d00)) {
                char str[16];
                char *endptr;
                unsigned MinutesToSuspend;
                unsigned msecToSuspend = 0;
                // Decode the MinutesToSuspend from the reboot_mode
                sprintf(str, "%i", (target_check_reboot_mode() ^ 0x6f656d00));
                MinutesToSuspend = strtol(str, &endptr, 16);
                if (MinutesToSuspend < 3)
                        msecToSuspend = (MinutesToSuspend * 60000);
                else
                        msecToSuspend = (MinutesToSuspend * 60000) - (120000);
                               
                suspend_time = msecToSuspend;
                show_multi_boot_screen = 0;
                boot_into_recovery = 0;
        }

        //In case we have a kernel with the above patch included
        #define MARK_ALARM_TAG        0x53000000
        if(target_check_reboot_mode() & 0xFF000000 == MARK_ALARM_TAG) {
                uint32_t MinutesToSuspend;
                // Decode the MinutesToSuspend from the reboot_mode
                MinutesToSuspend = target_check_reboot_mode() ^ MARK_ALARM_TAG;
                if (MinutesToSuspend > 3)
                        MinutesToSuspend -= 2;

                suspend_time = MinutesToSuspend * 60000;
                show_multi_boot_screen = 0;
                boot_into_recovery = 0;
        }

        if(suspend_time) {
                msm_acpu_clock_init(1); // 384MHz (acpu_freq_tbl[0])
                //Could try setting cpu clock at 245...
                //msm_acpu_clock_init(0); // 245MHz (acpu_freq_tbl[0])
                htcleo_suspend(suspend_time);
        }

      2. the suspend mode is implemented using this function
        Code:

        #define DS2746_SAFE_CHG_VOLTAGE        4200 // mV

        void htcleo_suspend(unsigned timeout)
        {
                uint32_t        voltage;
                //int16_t        current;
                bool                usb_cable_connected;
                time_t                start_time;

                start_time = current_time();
                if (timeout)
                        htcleo_panel_bkl_pwr(0);
                       
                do {
                        //current = ds2746_current(DS2746_I2C_SLAVE_ADDR, 1200);
                        voltage = ds2746_voltage(DS2746_I2C_SLAVE_ADDR);
                        usb_cable_connected = htcleo_usb_online();

                        if (usb_cable_connected) {
                                if (voltage < DS2746_SAFE_CHG_VOLTAGE) {
                                        // If battery needs charging, set new charger state
                                        if (htcleo_ac_online()) {
                                                if (htcleo_charger_state() != CHG_AC ) {
                                                        writel(0x00080000, USB_USBCMD);
                                                        ulpi_write(0x48, 0x04);
                                                        htcleo_set_charger(CHG_AC);
                                                }
                                        } else {
                                                if (htcleo_charger_state() != CHG_USB_LOW ) {
                                                        writel(0x00080001, USB_USBCMD);
                                                        mdelay(10);
                                                        htcleo_set_charger(CHG_USB_LOW);
                                                }
                                        }
                                        // Led = solid amber
                                        if (htcleo_notif_led_mode != 2)
                                                thread_resume(thread_create("htcleo_notif_led_set_mode_2",
                                                                                                        &htcleo_notif_led_set_mode,
                                                                                                        (void *)2,
                                                                                                        HIGH_PRIORITY,
                                                                                                        DEFAULT_STACK_SIZE));
                                } else {
                                        // Battery is full
                                        if(timeout) {
                                                // Set charger state to CHG_OFF_FULL_BAT
                                                if (htcleo_charger_state() != CHG_OFF_FULL_BAT ) {
                                                        writel(0x00080001, USB_USBCMD);
                                                        mdelay(10);
                                                        htcleo_set_charger(CHG_OFF_FULL_BAT);
                                                }
                                                // and turn led solid green
                                                if (htcleo_usb_online() && (htcleo_notif_led_mode != 1))
                                                        thread_resume(thread_create("htcleo_notif_led_set_mode_1",
                                                                                                                &htcleo_notif_led_set_mode,
                                                                                                                (void *)1,
                                                                                                                HIGH_PRIORITY,
                                                                                                                DEFAULT_STACK_SIZE));
                                        } else {
                                                // exit while if we don't have a timeout
                                                break;
                                        }
                                }
                        } else {
                                // Set charger state to CHG_OFF
                                if (htcleo_charger_state() != CHG_OFF ) {
                                        writel(0x00080001, USB_USBCMD);
                                        mdelay(10);
                                        htcleo_set_charger(CHG_OFF);
                                }
                                // and turn off led
                                if (htcleo_notif_led_mode != 0)
                                        thread_resume(thread_create("htcleo_notif_led_set_off",
                                                                                                &htcleo_notif_led_set_mode,
                                                                                                (void *)0,
                                                                                                HIGH_PRIORITY,
                                                                                                DEFAULT_STACK_SIZE));
                        }
                        // While in loop keep tracking if POWER button is pressed
                        // in order to (re)boot the device
                        for (int i=0; i<6; i++) {
                                if(keys_get_state(KEY_POWER)!=0) {
                                        target_reboot(0);
                                        return;//:)
                                }
                                mdelay(96);//total delay ~500ms per loop
                        }
                        // And check if timeout exceeded in order to reboot
                        if (timeout && (current_time() - start_time >= timeout))
                                target_reboot(0);
                } while ( (usb_cable_connected) /* && current >= 0) */
                                ||(timeout) ); // If we have a timeout this while-loop never breaks if we don't reboot.
                       
                // Double check voltage
                mdelay(10);
                voltage = ds2746_voltage(DS2746_I2C_SLAVE_ADDR);
               
                if (voltage < DS2746_SAFE_CHG_VOLTAGE) {
                        // If battery is not full then
                        // EITHER the cable is unplugged
                        // OR the double check of voltage gave us
                        // a value less than the safe voltage.
                        // Set charger state to CHG_OFF
                        writel(0x00080001, USB_USBCMD);
                        mdelay(10);
                        htcleo_set_charger(CHG_OFF);
                } else {
                        // If battery is full
                        // set charger state to CHG_OFF_FULL_BAT
                        writel(0x00080001, USB_USBCMD);
                        mdelay(10);
                        htcleo_set_charger(CHG_OFF_FULL_BAT);
                        // and turn led solid green
                        if (htcleo_usb_online() && (htcleo_notif_led_mode != 1))
                                thread_resume(thread_create("htcleo_notif_led_set_mode_1",
                                                                                        &htcleo_notif_led_set_mode,
                                                                                        (void *)1,
                                                                                        HIGH_PRIORITY,
                                                                                        DEFAULT_STACK_SIZE));
                        // While usb cable is connected
                        // keep tracking if POWER button is pressed OR timeout exceeded
                        // in order to (re)boot the device
                        while (htcleo_usb_online()) {                                       
                                if(keys_get_state(KEY_POWER)!=0)
                                        target_reboot(0);
                                /* if (timeout && (current_time() - start_time >= timeout))
                                        break; */
                        }
                }
               
                // If we've set a timeout and reached it, reboot the device
                /* if (timeout && (current_time() - start_time >= timeout))
                        target_reboot(0); */
                               
                // Shutdown the device
                enter_critical_section();
                platform_exit();
                msm_proc_comm(PCOM_POWER_DOWN, 0, 0);
                for (;;) ;
        }

  • Any suggestions or observations are welcomed!
  • This is open for everyone to use or contribute. Source is available at https://github.com/n0d3/HD2_Alarm_Clock
  • If you have to ask for an apk to test, then you may download this example's apk from here.But don't consider this as an application release thread.

Viewing all articles
Browse latest Browse all 164

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>