Search This Blog

Mar 8, 2012

SiM3U1xx-current-voltage-converter


Introduction
  SiM3U1xx and SiM3C1xx include the Current-to_Voltage Converter (IVC) module. The IVC module allows current sourced from a pin (sunk externally) to be measured by SARADCn modules on the device.

Function Description

    The IVC module consists of two channels of current-to-voltage conversion circuitry. Current is sourced from the IVC0.0 or IVC0.1 pins, creating a voltage drop at the pin and the ADC input. A simplified diagram of single channel of the IVC circuitry is shown in below Figure.


The IVC module has selectable full-scale current ranges of 1 mA to 6 mA, configurable in 1 mA steps. The transfer function of the IVC module is a curve that is 0 V with a 0 mA input, and 1.65 V at full scale.

We need to set PB0.7 pin as analog if want to use IVC function. 

And set IVC0 as SARADC input channel.

We need a little math to calculate the current, here is the equation.

Vout = (Vfullscale x code)/1023
Iin = Vout / slope


Where:
code = the left-justified 10 bit SARADC output code
Vfullscale =Full scale output, it 1.65V
Vout = IVC convert voltage output value

Iin = the current sunk externally from IVCn pin.
Slope = 275 mV/mA with condition input range 6mA

Here is the detailed register description for IVC0 registers

 

Code Implementation

   We used AppBuilder to generate basic code we need, and then added necessary code to make temperature sensor 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_APBCLKG0_SARADC0);|
  SI32_CLKCTRL_A_enable_apb_to_modules_1(SI32_CLKCTRL_0,
                                         SI32_CLKCTRL_A_APBCLKG1_MISC1 |
                                         SI32_CLKCTRL_A_APBCLKG1_MISC0);
}
2.       Configure the input range 6mA of the IVC channel and enable the IVC channel.(gIVC0.c)
void IVC0_enter_default_mode_from_reset(void)
{
  SI32_IVC_A_select_channel_0_range(SI32_IVC_0, SI32_IVC_A_CONTROL_IN0RANGE_6_MA_VALUE);
  SI32_IVC_A_enable_channel_0(SI32_IVC_0);
}

3.       Enable SARADC module; Timeslot0 channel is “IVC0.0 Output”; Output packing mode is “Lower half-word only”. And keep default setting of reference GND select as “internal GND” and start of conversion source as “On Demand by writing 1to ADBUSY” (gSARADC.c)
void SARADC0_enter_default_mode_from_reset(void)
{
  SI32_SARADC_A_enable_module(SI32_SARADC_0);
  SI32_SARADC_A_select_output_packing_mode_lower_halfword_only(SI32_SARADC_0);
  SI32_SARADC_A_select_timeslot0_channel(SI32_SARADC_0, 16);
}
4.       Port bank configuration. PB0.0 and PB0.7 need to be set as analog pin and skipped in crossbar.(gPB.c)
void pb_enter_default_mode_from_reset(void)
{
  SI32_PBCFG_A_unlock_ports(SI32_PBCFG_0);
  // PB0 Setup
  SI32_PBSTD_A_set_pins_analog(SI32_PBSTD_0, 0x0081);
  SI32_PBSTD_A_write_pbskipen(SI32_PBSTD_0, 0x2081);
  // PB1 Setup
  SI32_PBSTD_A_set_pins_push_pull_output(SI32_PBSTD_1, 0x0008);
  SI32_PBSTD_A_write_pbskipen(SI32_PBSTD_1, 0x0008);
  // Enable Crossbar0 signals & set properties
  SI32_PBCFG_A_enable_crossbar_0(SI32_PBCFG_0);
  // PB2 Setup
  SI32_PBSTD_A_set_pins_push_pull_output(SI32_PBSTD_2, 0x0C00);
  SI32_PBSTD_A_set_pins_high_drive_strength(SI32_PBSTD_2, 0x0C00);
  // Enable Crossbar1 signals & set properties
  SI32_PBCFG_A_enable_crossbar_1(SI32_PBCFG_0);
}
5.       Caculate IVC output voltage and input current.(mySARADC0.c)
void mySARADC0_current_convert_voltage(void)
{
  uint32_t voltage, current, tmp;
  SI32_SARADC_A_start_conversion(SI32_SARADC_0);
  while((0x20 & SI32_SARADC_A_read_fifostatus(SI32_SARADC_0)) == 0){
  }
  tmp = SI32_SARADC_A_read_data(SI32_SARADC_0);
  // IVC0 full scale output is 1650 mV. SARADC is 10 bit, means max value is 1023
  voltage = 1650 * tmp / 1023;
  current = voltage * 1000 / myIVC0_get_range_slope();
  printf("The Vout=%d mV, Current = %d uA \n",voltage, current );
}

Function validation

   We use series-connected 1K resistors connect P0.7 (IVC0) pin to GND, by choosing difference value ohm resistors; we can get difference current output from P0.7 pin.

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

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

SiM3U1xx-temperature-sensor


Introduction

  SiM3U1xx and SiM3C1xx contain on-chip temperature sensor module.  The temp sensor produces a voltage that is proportional to the temperature of the die in the device.  This voltage is supplied as one of the inputs to SARADC (Analog to Digital Converter).  The ADC conversion result can be converted into a temperature in degrees with a little math.

Function Description

  The temperature sensor is controlled from within the Voltage reference and Temperature Sensor (VREF) module. And here is the VREF diagram.

The temperature sensor is enabled using the TEMPEN bit in the CONTROL register. When enabled, the temperature sensor output is available to any analog peripherals which have a temperature sensor input.  Below is detailed register descriptions for VREF0 registers.


The temperature sensor output is linear with a positive slope; when temperature increases, the output voltage of the sensor increases.  We got figure illustrates the temperature sensor transfer function.


We have equation to calculate temperature from above figure.
Tempc =( Vtemp - offset) / Slope

Where:
Tempc = the die temperature in degrees C.
Vtemp = the output voltage of the temperature sensor in mV
Offset = 760mV at 0 degree C
Slope = 2.8 mV/C

We can refer to the electrical characteristics section of the specific device data sheet for temperature sensor parameters.
And Vtemp can get from SARADC conversion result.
Vtemp   (code/ 1024) x VREF
Where:
code = the left-justified 10 bit SARADC output code
VREF  = the value of the voltage reference, which is around 2.4V or 1.2V if internal VREF is used.



Implementation Considerations

    The temp sensor measures the temperature of the die of the device, which is likely to be a few degrees warmer than the surrounding ambient temperature due to device power dissipation. In order to find the ambient temperature, the temperature increase due to self-heating must be subtracted from the result. The value of this temperature increase can be calculated or measured.
    The temperature increase due to self-heating can be measured in a number of ways. One method is to initiate a conversion soon after applying power to the device to get a 'cold' temperature reading, and then measure again after about a minute of operation, to get a 'hot' temperature reading. The difference between the two measurements is the contribution due to self-heating.
    Another method is to operate the device from a low SYSCLK frequency, for example a 32 kHz watch crystal, and take a temperature measurement, then operate the device at a higher frequency, the 16 MHz internal oscillator for example, and take the difference. The amount of self-heating at the lower clock frequency is negligible because the power dissipation of the device at that frequency is low.

Code Implementation

   We used AppBuilder to generate basic code we need, and then added necessary code to make temperature sensor 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_APBCLKG0_SARADC0);
  SI32_CLKCTRL_A_enable_apb_to_modules_1(SI32_CLKCTRL_0,
                                         SI32_CLKCTRL_A_APBCLKG1_MISC1 |
                                         SI32_CLKCTRL_A_APBCLKG1_MISC0);
}
2.       Enable internal voltage reference and temperature sensor, select 2.4v as reference output  voltage.(gVREF0.c)

void VREF0_enter_default_mode_from_reset(void)
{
  SI32_VREF_A_enable_temperature_sensor(SI32_VREF_0);
  SI32_VREF_A_select_2p4_volts(SI32_VREF_0);
  SI32_VREF_A_enable_voltage_reference(SI32_VREF_0);
}
3.       Enable SARADC module; VREF select External REF pin; Timeslot0 channel is “Temperature Sensor Output”; Output packing mode is “Lower half-word only”. And keep default setting of reference GND select as “internal GND” and start of conversion source as “On Demand by writing 1to ADBUSY” (gSARADC.c)
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.       Port bank configuration. PB0.0 and PB0.12 need to be set as analog pin and skipped in crossbar.(gPB.c)
void pb_enter_default_mode_from_reset(void)
{
  SI32_PBCFG_A_unlock_ports(SI32_PBCFG_0);
  // PB0 Setup
  SI32_PBSTD_A_set_pins_analog(SI32_PBSTD_0, 0x1001);
  SI32_PBSTD_A_write_pbskipen(SI32_PBSTD_0, 0x1001);
  // PB1 Setup
  SI32_PBSTD_A_set_pins_push_pull_output(SI32_PBSTD_1, 0x0008);
  SI32_PBSTD_A_write_pbskipen(SI32_PBSTD_1, 0x0008);
  // Enable Crossbar0 signals & set properties
  SI32_PBCFG_A_enable_crossbar_0(SI32_PBCFG_0);
}
5.       Convert output voltage of temperature sensor and calculate temperate degree C.
//======================================================================
// Read back temperature sensor output and convert it to temperature value.
// The equation is: Vtemp = (code / 2^nbits) * Vref, Temperature=(Vtemp-Voff)/slope
// Notes: We use 10-bit ADC which means 2^10 = 1024; Vref we choose VREF pin
// reference voltage 1.2v or 2.4v, Vref = 1650mV; And Voff is 760mV at 0°C.
// Slope is 2.8 mV/°C
//======================================================================
void mySARADC0_convert_temperature_value(void)
{
  int32_t temperature = 0;
  int32_t vtemp,vref;
   vref = (vref_mode == 0)?1200:2400;
  SI32_SARADC_A_start_conversion(SI32_SARADC_0);
  while((0x20 & SI32_SARADC_A_read_fifostatus(SI32_SARADC_0)) == 0);
  vtemp = ( SI32_SARADC_A_read_data(SI32_SARADC_0) * vref) / 1024;
  temperature = (vtemp - 760) * 10000 / 280;
  printf("The temperature is %i.%02d degrees Celsius, vref = %imV\n",temperature/100,(uint32_t)(temperature % 100),vref); 
}

Function validation

   We can use hairdryer to heat the chip and observer the output of temperature value in the Debug (printf) Viewer.

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

3.       Using the On-Chip Temperature Sensor : downloadable from the Silicon Labs web site at  http://www.silabs.com/Support%20Documents/TechnicalDocs/an103.pdf