Skip to content

[RE Mote] Power Management on rev. B

Devel edited this page Feb 6, 2018 · 15 revisions

RE-Mote Rev.B Power Management

RE-Mote in revision B has a different functionality than older versions. This section describes the functionality, commands and procedure specs of the power management on rev.B. The main goal was place a power supply microcontroller to manage multiple options from battery charger and add additional control enhacements. The duty cycle when system is off has controlled better, and we can get more information of that.

With all, we can added these basic characteristics:

  • PIC16F1509 as main power supply microcontroller.
  • I2C communication commands.
  • Low power that turns off the system (by command).
  • Get information about what still doing the battery charger.
  • 200 bytes of additional user data.
  • Interface more easely than last versions.

Communication with power management

To communicate with power management module is through I2C. The address is 0x7F (support 100 kpbs at maximum). Drivers of power suplpy is uploaded in repo.

The next section analyses the commands one by one, explaining all options of that.

Registers

Next commands will be avaliable on contiki drivers

Name Register Number Bits num Read/Write
- Power Enable 0x22 8 bits R/W
- Current Charge Limit 0x23 8 bits R/W
- Charge Enable 0x24 8 bits R/W
- System Enable Input 0x25 8 bits R/W
- Config External Reference 0x26 8 bits R/W
- Hard Sleep Configuration 0x27 8 bits R/W
- Soft Sleep Configuration 0x28 8 bits R/W
- Secure Soft Time 0x29 32 bits R/W
- Get Voltage 0x2A 16 Bits R
- Get Firmware Version 0x2B 8 Bits R/W
- Get Number Cycles 0x2C 32 Bits R/W*
- Data Custom Bytes [0x32:0xFA]* 8 Bits R/W

Power Enable

Register bits (address 0x22):

9 8 7 6 5 4 3 2 1 0
N/A N/A N/A N/A N/A N/A N/A N/A N/A Enable bit

This command cuts the general battery voltage to all system. Enabling this writting a "1" in this register means that these parts will not been powered:

  • CC2538
  • CC1200
  • Power charger
  • SD

Current Charge Limit

Register bits (address 0x23):

9 8 7 6 5 4 3 2 1 0
N/A N/A N/A N/A N/A N/A N/A N/A Major bit Minor bit
In this register, only the two LSB bits is allowed.
This register describes the current limit to charge the battery.
Value Description
0 100mA
1 500mA
2 By External Resistor
3 Stand By current

Charge Enable

Register bits (address 0x24):

9 8 7 6 5 4 3 2 1 0
N/A N/A N/A N/A N/A N/A N/A N/A N/A Enable bit
One special option on power management is to stop the option to charge the battery. When this register is disabled (by 0), automatically stops the charge mode. This can be useful to get more control in battery charge, and it can be disabled if no battery is present on system.

System Enable Input

Register bits (address 0x25):

9 8 7 6 5 4 3 2 1 0
N/A N/A N/A N/A N/A N/A N/A N/A N/A Enable bit
Write 1 to connect the battery to the system output. Charging is also disabled.

Config External Reference

Register bits (address 0x26):

9 8 7 6 5 4 3 2 1 0
N/A N/A N/A N/A N/A N/A N/A N/A N/A Enable bit

This register is related with the acquisition of battery voltage. Writting "1" means that the acquisition will be from external circuitery placed around power supply controller. Writting "0" is a microcontroller internal acquisition. There have no differences in fact, << make tests on two options >>.


Hard Sleep Configuration

Register bits (address 0x27):

9 8 7 6 5 4 3 2 1 0
N/A N/A N/A N/A N/A N/A N/A N/A N/A Enable bit

Hard sleep is used with RTC. Enabling this method, the PM will wait until an event of RTC is made.

  • it can be used with SOFT_TIME register if we want to get a security methor to start-up if the RTCC fails. But, it consumes more power (Because the microcontroller will be checking this continually).
  • it needs a shutdown_now command

Soft Sleep Configuration

Register bits (address 0x28):

9 8 7 6 5 4 3 2 1 0
N/A N/A N/A N/A N/A N/A N/A N/A N/A Enable bit

Writing "1" in this, cause a shut down in all system. This needs a previous "Secure Soft Time".


Secure Soft Time

Register bits (address 0x29):

This register is the time Out expiration for Hard or Soft sleep. Any value highter than 0 placed here will count at sleep process. This is a 32-bit register.


Get Voltage

Register bits (address 0x2a):

When we read this register, we will obtain the current voltage of the battery. The battery voltage is obtained by the same read command, and it could need a little time. The format of output is a uint16_t /100. Example: 338 --> 3,38 Volts


Get Firmware Version

Register bits (address 0x2b): Get the firmware version. If is 15, we need to divide by 10 (1.5).


Get Number Cycles

Register bits (address 0x2c) Number cycles have been placed as the number of sleeps taken. This could be useful if we use the external RTC (as hard sleep mode) and we will not fix the same date at init. Then, any star-up after 0 will not write the initial date config. Writing any value in this register cause to reset to 0.


Data Custom Bytes

Register bits: Starting accessible address: 0x32 Final accessible address: 0xFA

This 200 bytes space have been left free by user custom actions. User can save and load data temporally (is not flash) until the device will not powered.


Fill examples:

Test code

Soft Sleep Code

Firstly of our implementation, we need to ensure that we have the needed prequisites.

    err = pm_set_timeout(2);
    if (err == PM_SUCCESS) {
      printf("pm_set_timeout: %d, pm_get_timeout: %ld\n", 
                                                  PM_SOFT_SHTDN_1_3_SEC, 
                                                  (uint32_t)pm_get_timeout());
      
      // We need to write when can enter into soft sleep
      err = pm_write_byte(PM_SOFT_SLEEP_CONFIG, PM_ENABLE);      
      if (err == PM_SUCCESS) {
        printf("Readed: %u\n ", pm_read_byte(PM_SOFT_SLEEP_CONFIG));
      }
    } else {
      printf("%s error\n", print_pm(PM_SOFT_TIME));
    }
    break;

Hard Sleep Code

As prior code, the first of our test, place in our Makefile the definition of "DATE" extracted from system. This is a code for a Linux, Mac OS should be similar:

CFLAGS = -DDATE="\"`date +"%02u %02d %02m %02y %02H %02M %02S"`\""

Also, we need to add the libraries on our code file:

#include "power-mgmt.h"
#include "rtcc.h"

This is an example test code function to set a Hard sleep period. The definition of PM_TEST_WITH_SOFT_SECURITY submit a soft timer in low power management as timeout. This code it could be placed inside any thread with:

    /* Local defines */
    #define TEST_ALARM_MINUTE  16

    /* Hard Sleep: RTC Configuration */
    printf("RE-Mote RTCC+HARD SHUTDOWN test, system date: %s\n", DATE);
    if(strcmp("Unknown", DATE) == 0) {
      printf("Fail: could not retrieve date from system\n");
      PROCESS_EXIT();
    }

    /* Configure RTC and return structure with all parameters */
    rtcc_init();

    if (pm_get_num_cycles() == 0) {
      /* Configure the RTC with the current values */
      simple_td->weekdays    = (uint8_t)strtol(DATE, &next, 10);
      simple_td->day         = (uint8_t)strtol(next, &next, 10);
      simple_td->months      = (uint8_t)strtol(next, &next, 10);
      simple_td->years       = (uint8_t)strtol(next, &next, 10);
      simple_td->hours       = (uint8_t)strtol(next, &next, 10);
      simple_td->minutes     = (uint8_t)strtol(next, &next, 10);
      simple_td->seconds     = (uint8_t)strtol(next, NULL, 10);
    
      simple_td->miliseconds = 0;
      simple_td->mode = RTCC_24H_MODE;
      simple_td->century = RTCC_CENTURY_20XX;
    
      if(rtcc_set_time_date(simple_td) == AB08_ERROR) {
        printf("Fail: Time and date not configured\n");
      }
      printf("Wait a bit\n");

      etimer_set(&et, (CLOCK_SECOND * 2));
      PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
    }

    if(rtcc_get_time_date(simple_td) == AB08_ERROR) {
      printf("Fail: Couldn't read time and date\n");
      PROCESS_EXIT();
    }

    printf("Configured time: ");
    rtcc_print(RTCC_PRINT_DATE_DEC);

    /* Configure the RTCC to trigger an alarm every TEST_ALARM_SECOND tick */
    printf("Setting an alarm to tick at %u minutes\n", TEST_ALARM_MINUTE);
    simple_td->minutes = TEST_ALARM_MINUTE;

    if(rtcc_set_alarm_time_date(simple_td, RTCC_ALARM_ON,
                          RTCC_REPEAT_HOUR, 
                          RTCC_EVENT_RTCC_WITH_EXT_SYSTEM) == AB08_ERROR) {
      printf("Fail: couldn't set the alarm\n");
      PROCESS_EXIT();
    }

    printf("Alarm set to match: ");
    rtcc_print(RTCC_PRINT_ALARM_DEC);

    /* Config PIC to get the event from the RTCC to shutdown the system */        

    #ifdef PM_TEST_WITH_SOFT_SECURITY
        err = pm_set_timeout(2);
        if (err == PM_SUCCESS) {
          printf("pm_set_timeout: %d, pm_get_timeout: %ld\n", 
                                                  PM_SOFT_SHTDN_1_3_SEC, 
                                                  (uint32_t)pm_get_timeout());
        }
    #endif
    err = pm_write_byte(PM_HARD_SLEEP_CONFIG, PM_ENABLE);
    if (err == PM_SUCCESS) {
      printf("Readed: %u\n ", pm_read_byte(PM_HARD_SLEEP_CONFIG));
    }
    err = pm_shutdown_now(PM_HARD_SLEEP_CONFIG);
    if (err == PM_SUCCESS) {
      printf("Theorically never reaches here: %u\n ", pm_read_byte(PM_HARD_SLEEP_CONFIG));
    }

With this code in your application, the system will be shutdown preiodically each 1,3 seconds when arrives at minute defined by TEST_ALARM_MINUTE.

Add image and capture of the cycles:

Add power supply data:

Clone this wiki locally