Search This Blog

Mar 8, 2012

SiM3U1xx-voltage-supply-monitor


Introduction

  SiM3U1xx and SiM3C1xx include Voltage Supply Monitor (VMON) module which allows devices to function in known, safe operating condition without the need for external hardware. The supply monitor includes additional circuitry that can monitor the main supply voltage and the VREGIN input voltage divided by 4 (VREGIN / 4).

Function Description

The supply monitor module includes the following features:
·         Main supply “VDD Low” (VDD below the early warning threshold) notification.
·         Holds the device in reset if the main VDD supply drops below the VDD Reset threshold.
·         VREGIN divided by 4 (VREGIN / 4) supply “VREGIN Low” notification.

VDD supply monitoring

  The VDD supply monitor senses the voltage on the device VDD supply and can generate an interrupt or reset if the supply drops below the corresponding thresholds.
When enabled and selected as a reset source, any power down transition or power irregularity that causes VDD to drop below the reset threshold will drive the RESET pin low and hold the core in a reset state.
  The VDD monitor also includes a VDD-is-low interrupt. Hardware clears the VDDLI interrupt flag when VDD drops below the early warning threshold.
Below figure illustrates behaviors of VDD supply monitor.

     The high threshold enable (VDDHITHEN) bit can increase the VDD monitor reset and early earning thresholds by approximately 300 mV, if appropriate for the system. This setting is recommended when operating at faster AHB clock speeds. Below table shows threshold under difference conditions.
To protect the integrity of Flash contents, the VDD supply monitor must be enabled and selected as a reset source if software contains routines that erase or write Flash memory. If the VDD supply monitor is not enabled, any erase or write performed on Flash memory will be ignored.
The VDD supply monitor must be enabled before selecting it as a reset source. Selecting the VDD supply monitor as a reset source before it has stabilized may generate a system reset. In systems where this reset would be undesirable, a delay should be introduced between enabling the VDD supply monitor and selecting it as a reset source. No delay should be introduced in systems where software contains routines that erase or write Flash memory. The procedure for enabling the VDD supply monitor and selecting it as a reset source is:
1. Enable the VDD supply monitor (VMONEN = 1).
2. Wait for the VDD supply monitor to stabilize (optional).
3. Select the VDD monitor as a reset source in the device reset sources module.

VREGIN Pin Monitoring

    In addition to monitoring the VDD supply, the VMON module can also monitor the voltage on the VREGIN pin. The VREGIN pin sense enable (VREGINSEN) bit enables this feature in the VMON module. The VREGIN voltage sensing feature of the voltage regulator module (VREGn) must also be enabled in order to monitor the voltage in the VMON module.
The Detailed register descriptions for VMON0 registers list below:
And VREG0 module SENSEEN bit detailed description list below.

Code Implementation

   We used AppBuilder to generate basic code we need, and then added necessary code to make voltage supply monitor works.
void CLKCTRL_setup_default_mode_clock_gates(void)
{
  SI32_CLKCTRL_A_enable_apb_to_modules_0(SI32_CLKCTRL_0,     SI32_CLKCTRL_A_APBCLKG0_PB0);
  SI32_CLKCTRL_A_enable_apb_to_modules_1(SI32_CLKCTRL_0,
                                         SI32_CLKCTRL_A_APBCLKG1_MISC1 |
                                         SI32_CLKCTRL_A_APBCLKG1_MISC0);
}
2.       VREGIN sense enable and disable VBUS invalid interrupt since default setting is enabled.(gVREG0.c)
void VREG0_enter_default_mode_from_reset(void)
{
  SI32_VREG_A_disable_vbus_invalid_interrupt(SI32_VREG_0);
  NVIC_ClearPendingIRQ(VBUSINVALID_IRQn);
  NVIC_DisableIRQ(VBUSINVALID_IRQn);
  SI32_VREG_A_enable_vreg_sense(SI32_VREG_0);
}
3.       Enable VDD low interrupt.  Add VREG0LOW_IRQHandler () and VDDLOW_IRQHandler () interrupt handler functions. VMON default setting is enabled. (gVMON0.c)
void VDDLOW_IRQHandler()
{
  if (SI32_VMON_A_is_vdd_low_interrupt_pending(SI32_VMON_0))
  {
    VDDLOW_vdd_low_handler();
  }
}

void VREG0LOW_IRQHandler()
{
  if (SI32_VMON_A_is_vreg_low_interrupt_pending(SI32_VMON_0))
  {
    VREG0LOW_vreg_low_handler();
  }
}

void VMON0_enter_default_mode_from_reset(void)
{
  SI32_VMON_A_enable_vdd_low_interrupt(SI32_VMON_0);
  NVIC_ClearPendingIRQ(VDDLOW_IRQn);
  NVIC_EnableIRQ(VDDLOW_IRQn);
}

 void SARADC0_enter_default_mode_from_reset(void)
{
  SI32_SARADC_A_enable_module(SI32_SARADC_0);
  SI32_SARADC_A_select_vref_external(SI32_SARADC_0);
  SI32_SARADC_A_select_timeslot0_channel(SI32_SARADC_0, 20);
  SI32_SARADC_A_select_output_packing_mode_lower_halfword_only(SI32_SARADC_0);
}
4.       Added 2nd level interrupts handlers, it set global flag to indicate the voltage drop below the threshold.(myVMON0.c)
void VDDLOW_vdd_low_handler(void)
{
  vdd_low_early_warning = 1;
  SI32_VMON_A_disable_vdd_low_interrupt(SI32_VMON_0);
}
void VREG0LOW_vreg_low_handler(void)
{
  vrefin_low_early_warning = 1;
  SI32_VMON_A_disable_vreg_low_interrupt(SI32_VMON_0);
}
5.       Added two functions to select VDD high threshold and standard threshold mode (myVMON0.c)
void myVMON0_select_vdd_high_threshold(void)
{
  SI32_VMON_A_select_vdd_high_threshold(SI32_VMON_0);
}

void myVMON0_select_vdd_standard_threshold(void)
{
  SI32_VMON_A_select_vdd_standard_threshold(SI32_VMON_0);
}
6.       Provided two functions to select VDD and VREGIN low notification mode.(myVMON0.c)
void myVMON0_enter_vdd_low_notification_mode(void)
{
  SI32_VMON_A_enable_vdd_low_interrupt(SI32_VMON_0);
  NVIC_ClearPendingIRQ(VDDLOW_IRQn);
  NVIC_EnableIRQ(VDDLOW_IRQn);
}
void myVMON0_enter_vrefin_low_notification_mode(void)
{
  SI32_VMON_A_enable_vreg_supply_monitor(SI32_VMON_0);
  SI32_VMON_A_enable_vreg_low_interrupt(SI32_VMON_0);
  NVIC_ClearPendingIRQ(VREG0LOW_IRQn);
  NVIC_EnableIRQ(VREG0LOW_IRQn);
}
7.       Add test code.(main.c)
void blink_led(void)
{
  static uint32_t flag = 0;
  if(flag) {
    SI32_PBSTD_A_write_pins_low (SI32_PBSTD_2, 0x000000400);
    SI32_PBSTD_A_write_pins_high (SI32_PBSTD_2, 0x000000800);
  }else {
    SI32_PBSTD_A_write_pins_high (SI32_PBSTD_2, 0x000000400);
    SI32_PBSTD_A_write_pins_low (SI32_PBSTD_2, 0x000000800);
  }
  flag = !flag;
}

void vdd_check(void)
{
  uint32_t next_1s_msTicks = 500, vdd_was_low = 0;
  while (1)  {
    if(vdd_low_early_warning && (vdd_was_low == 0))  {
      vdd_was_low = 1;
      printf("VDD drop below early warning threshold\n");
    }
    if(next_1s_msTicks < get_msTicks())  {
      next_1s_msTicks = get_msTicks() + 500;
      blink_led();
      if(vdd_low_early_warning)  {
        vdd_low_early_warning = 0;
        SI32_VMON_A_enable_vdd_low_interrupt(SI32_VMON_0);
      }else if(vdd_was_low)  {
        vdd_was_low = 0;
        printf("VDD voltage is above early warning threshold\n");
      }
    }
  }
}

void vregin_check(void)
{
  uint32_t next_1s_msTicks = 500, vregin_was_low = 0;
  while (1) {
    if(vrefin_low_early_warning && (vregin_was_low == 0))  {
      vregin_was_low = 1;
      printf("VREGIN drop below early warning threshold\n");
    }
    if(next_1s_msTicks < get_msTicks())   {
      next_1s_msTicks = get_msTicks() + 500;
      blink_led();
      if(vrefin_low_early_warning)  {
        vrefin_low_early_warning = 0;
        SI32_VMON_A_enable_vreg_low_interrupt(SI32_VMON_0);
      }else if(vregin_was_low)  {
        vregin_was_low = 0;
        printf("VREGIN voltage is above early warning threshold\n");
      }
    }
  }
}

int main(void)
{
  // Enter the default operating mode for this application
  enter_default_mode_from_reset();
 
  // VDD low notification mode
  myVMON0_enter_vdd_low_notification_mode();
  myVMON0_select_vdd_high_threshold();     // warning 2.20v, reset 2.05v
  //myVMON0_select_vdd_standard_threshold(); // warning 1.85v, reset 1.74v
  vdd_check();
 
  // VREFIN low notification mode
  myVMON0_enter_vrefin_low_notification_mode();
  vregin_check();

  while(1)
  {
  }
}

Function validation

   VDD supply monitor has two threshold can be set:  high threshold and standard threshold. For high threshold, the VDD early warning threshold is 2.20v, reset threshold is 2.05v. For standard threshold, the VDD early warning threshold is 1.85v, reset threshold is 1.74v.   VREGIN low warning threshold is 4.4v.
   1) For VDD supply monitoring, Disconnect USB cable, Use DC power supply 3.3v output connect to J50 (VDD).power the MCU Card board.
2) Download the code to a SiM3U1xx device on a SiM3U1xx MCU Card
3) In the IDE, open the debug printf viewer and then run the code.   In uVision, the debug printf viewer can be opened by starting a debug session and then clicking View -> Serial Windows -> Debug (printf) Viewer.
4) Run the code and drop down VDD voltage. And you should see the warning message   when voltage drops below early warning threshold; and then if you raise the voltage above early warning threshold, you shold see message print out that VDD voltage is above the threshold now. The board will be reset if the VDD voltage drop below reset threshold.
1) For VREGIN supply monitoring, Disconnect USB cable, Keep J14 (USB) opening,    Use DC power supply 5.0v output connect to the pin of J14 (USB) which is close    to UDP board edge. power the MCU Card board.
2) Download the code to a SiM3U1xx device on a SiM3U1xx MCU Card
3) In the IDE, open the debug printf viewer and then run the code.  In uVision, the debug printf viewer can be opened by starting a debug session  and then clicking View -> Serial Windows -> Debug (printf) Viewer.
4) Run the code and drop down VREGIN voltage. And you should see the warning  message when voltage drop below early warning threshold; and then if you raise the voltage above early warning  threshold, you shold see message print out that VDD voltage is above the threshold now.

VBUS invalid voltage sensing

   As we already add VREG module to enable VREGIN voltage sensing feature. We can go through this part about VBUS invalid voltage sensing.

Function description

The module has the following additional features:
1. The VREGIN sense enable (SENSEEN) bit enables the internal VREGIN pin voltage sensing. VREGIN voltage sensing must be enabled in order to monitor or measure the VREGIN voltage in other modules, such as measuring the current voltage with the SARADCn module or using the VREGIN supply monitor and the VREGIN low interrupt flag in the VMONn module.
2. The VBUS invalid interrupt enable (VBUSIVLDIEN) bit causes the VREG module to generate an interrupt when the VBUS invalid interrupt (VBUSIVLDI) flag is set.
The VBUS invalid interrupt (VBUSIVLDI) flag indicates that the voltage on the VBUS pin dropped lower than the valid threshold since the last time the flag was cleared. The VREG module will generate an interrupt when VBUSIVLDI is set if this flag is enabled as an interrupt source (VBUSIVLDIEN = 1).

Code implementation

Most parts are same as VMON0, we only list specific code. VBUS invalid interrupt default is enabled.
1.     Added VBUS invalid handler and NVIC enable.(gVREG0.c)
void VBUSINVALID_IRQHandler()
{
  if (SI32_VREG_A_is_vbus_invalid_interrupt_pending(SI32_VREG_0))
  {
    VREG0_vbus_invalid_handler();
  }
}

void VREG0_enter_default_mode_from_reset(void)
{
  // No peripheral code is needed for this mode transition
  SI32_VREG_A_enable_vreg_sense(SI32_VREG_0);
  NVIC_ClearPendingIRQ(VBUSINVALID_IRQn);
  NVIC_EnableIRQ(VBUSINVALID_IRQn);
}
2.     Added code to check VBUS valid or not when interrupt comes in.(myVREG0.c)
void VREG0_vbus_invalid_handler(void)
{
  SI32_VREG_A_clear_vbus_invalid_interrupt(SI32_VREG_0);
  vbus_valid = SI32_VREG_A_is_vbus_valid(SI32_VREG_0);;
}
3.     Added test code. (main.c)
int main(void)
{
  uint32_t next_1s_msTicks = 500, pre_vbus_status = 0;;
  // Enter the default operating mode for this application
  enter_default_mode_from_reset();
  while (1) {
    if(vbus_valid != pre_vbus_status)  {
      if(vbus_valid)
        printf("VBUS is valid\n");
      else
        printf("VBUS is invalid\n");
      pre_vbus_status = vbus_valid;
    }
    if(next_1s_msTicks < get_msTicks())    {
      next_1s_msTicks = get_msTicks() + 500;
      blink_led();
    }
  }
}

Function validation

  This example code uses the VREG module to check VBUS valid status. It will generate an interrupt when USB cable plugs in/out. And it will print out VBUS valid or invalid message in Debug (printf) Viewer within IDE. We need using MCU Card with the UDP motherboard to test VBUS valid function. Connect the MCU card to the UDP motherboard slot. Move the SW5 System Power Select switch to the lower MB position. Connect the USB cable to j16 UDS on the UDP motherboard. Move the S3 power switch on the UDP motherboard to the ON position. Plug in/out USB cable on MCU card J13, the VBUS valid or invalid message should  appear in the debug(printf) Viewer and the LEDs(DS3,DS4) blinking every 500ms.

References

1.       SiM3U1xx/SiM3C1xx Reference Manual: downloadable from the Silicon Labs web site at http://www.silabs.com/pages/DownloadDoc.aspx?FILEURL=Support Documents/TechnicalDocs/SiM3U1xx_SiM3C1xx_RM.pdf&src=DocumentationWebPart

2.       SiM3U1xx Data Sheet: downloadable from the Silicon Labs web site at http://www.silabs.com/pages/DownloadDoc.aspx?FILEURL=Support Documents/TechnicalDocs/SiM3U1xx.pdf&src=DocumentationWebPart

No comments: