Beispiel #1
0
/**************************************************************************************************
 * @fn          halDriverBegPM
 *
 * @brief       This function is called before entering PM so that drivers can be put into their
 *              lowest power states.
 *
 * input parameters
 *
 * None.
 *
 * output parameters
 *
 * None.
 *
 * @return      None.
 **************************************************************************************************
 */
void halDriverBegPM(void)
{
#if ((defined HAL_LED) && (HAL_LED == TRUE))
    HalLedEnterSleep();
#endif
#if ((defined HAL_KEY) && (HAL_KEY == TRUE))
    HalKeyEnterSleep();
#endif
#if ((defined HAL_I2C) && (HAL_I2C == TRUE))
    HalI2CEnterSleep();
#endif
}
/**************************************************************************************************
 * @fn          DataUpdate_ProcessEvent
 *
 * @brief       Update values from A/D sensor and diags
 *
 * @param       uint8 task_id
 * @param       uint16 events - event mask
 *
 * @return      uint16 - 0 (for now)
 **************************************************************************************************
 */
uint16 DataUpdate_ProcessEvent(uint8 task_id, uint16 events)
{
    #if ADV_DEBUG_MESSAGE_FORMAT==1
    // variables that are needed if we're running the advanced debugging message format
    int vdd_div_3;
    int vdd;
    int16 tempvalCC2541;
    int spare;
    #endif
    
    int tempval;
    int16 tempval2;
    int16 tempval3;
    int16 tempval4;
    int16 tempavg;
    uint16 timeval;
    uint16 sensorval;
    
#if USE_SEPARATE_TEMP_AD_CHANNEL==0
    uint8 lmp_configured;
    uint8 lmp_configure_tries;
#endif

#ifdef FAKE_SENS_DATA

#ifdef O2_SENSOR
    uint16 max_fake = 1000;
    uint16 min_fake = 600;
    static int16  fake_adj = 1;
    static uint16 fakesensorval = 600;
#endif
#ifdef CO_SENSOR
    uint16 max_fake = 1300;
    uint16 min_fake = 380;
    static int16  fake_adj = 1;
    static uint16 fakesensorval = 380;
#endif

    
#endif    
    if (events & 1)
    {

      timeval = (uint16) (osal_GetSystemClock() & 0xffff);
      cyclecount++;
      if (cyclecount>9)
      {
        cyclecount=0;
        // Also, set P1_0 (the LED) as an output, and drive high
        P1DIR = P1DIR | 0x01; 
        P1 = P1 | 0x01;
      }
      
      
       /* Enable channel */
       ADCCFG |= 0x80;
       P0DIR = 0x83; // force P0.0, P0.1, and P0.7 to be inputs
       APCFG = 0x83;
       HalAdcSetReference (0x40); // use AIN7 for ref (0x08 would be AVDD5, 0x00 would be internal ref

#if USE_SEPARATE_TEMP_AD_CHANNEL==0
       // Configure LMP9100 to output temperature
       if (lmp91KinitComplete)
       {
         // Because the processor may have been sleeping, re-configure I2C intf. before 
         // performing the I2C transaction
         HalI2CExitSleep();
         lmp_configure_tries=0;
         lmp_configured=0;
       
         // We can't hang out in this loop forever, but we can retry a couple
         // of times, to get over any instability on the I2C bus
         while ((lmp_configure_tries<4) && (!lmp_configured))
         {
            // Set this flag so that we presume that communication is working.
           // The flag will get cleared (quickly) as a side-effect in the
           // communication routines if we fail again.
           lmp91kOK=1; 

           lmp_configured=LMP91000_I2CSwitchVoutToTempSensor();
           
           lmp_configure_tries++;
         } // end while 
         
          // Because the processor may go into sleep mode, save the state of the I2C
          // interface before continuing.
          HalI2CEnterSleep();
       } // end if (lmp91KinitComplete)
#endif       
       
       
       // Read temperature from LMP9100
       if (!lmp91kOK)
       {
         // If we're not communicating, then the LMP91000 may not be in the right
         // state, so just use a previous value.
         tempval = oldtempval;
       }
       else
       {
         tempval =  HalAdcRead(HAL_ADC_CHANNEL_0, HAL_ADC_RESOLUTION_12);
         tempval2 =  HalAdcRead(HAL_ADC_CHANNEL_0, HAL_ADC_RESOLUTION_12);
         tempval3 =  HalAdcRead(HAL_ADC_CHANNEL_0, HAL_ADC_RESOLUTION_12);
         tempval4 =  HalAdcRead(HAL_ADC_CHANNEL_0, HAL_ADC_RESOLUTION_12);
         // Get a bit of noise out of the temperature measurment by averaging 4
         // samples.
         // By the way, we expect nominal values to be around 1100 or so
         // at room temperature, so we can fairly safely add 4 16-bit values
         // together without thinking too much about overflow.
         // If the nominal values were larger, we'd promote to a larger
         // data type before averaging.
         tempavg = (tempval+tempval2+tempval3+tempval4)/4;
         oldtempval=tempavg;
       }
       
       
       // Convert temp to tenths of degrees C, based on the table in
       // the datasheet for the LMP91000, and assuming a 2.5v ref
       
       tempval = convertTemp(tempavg);

       // Now, get ready to measure the oxygen sensor
       HalAdcSetReference (0x40); // use AIN7 for ref 
       
#if USE_SEPARATE_TEMP_AD_CHANNEL==0
       
       if (lmp91KinitComplete)
       {
         // Because the processor may have been sleeping, re-configure I2C intf. before 
         // performing the I2C transaction(s)
         HalI2CExitSleep();
         
         lmp_configure_tries=0;
         lmp_configured=0;
         // we can't hang out in this loop forever, but we can retry a couple
         // of times, to get over any instability on the I2C
         while ((lmp_configure_tries<4) && (!lmp_configured))
         {
           // Set this flag so that we presume that communication is working.
           // The flag will get cleared (quickly) as a side-effect in the
           // communication routines if we fail again.
           lmp91kOK=1; 
           
           // Likely redundant, but doesn't hurt
           LMP91000_I2CConfigureForO2Sensor( SensTIAGain , SensRLoad, SensRefVoltageSource, SensIntZSel);
           
           if (lmp91kOK)
           {
             lmp_configured = LMP91000_I2CSwitchVoutToO2Sensor(SensModeOp);
           }
 
           lmp_configure_tries++;
         } // end while
         
         // Because the processor may go into sleep mode, save the state of the I2C
         // interface before continuing.
         HalI2CEnterSleep();
       } // end  if (lmp91KinitComplete)

#endif
       
       if (!lmp91kOK)
       {
         // If we're not communicating, then the LMP91000 may not be in the right
         // state, so just use a previous value.
         sensorval = oldsensorval;
       }
       else
       {
#if    USE_SEPARATE_TEMP_AD_CHANNEL==1
       sensorval =  HalAdcRead(HAL_ADC_CHANNEL_1,HAL_ADC_RESOLUTION_12);
#else
       sensorval =  HalAdcRead(HAL_ADC_CHANNEL_0,HAL_ADC_RESOLUTION_12);
#endif
         oldsensorval = sensorval;
       }
       
       // Depending on compile options, build the message, or gather
       // additional diagnostic info and then build the debug mode message
#ifdef FAKE_SENS_DATA
fakesensorval += fake_adj;
if ((fakesensorval >= max_fake) || (fakesensorval <= min_fake))
  fake_adj = -1 * fake_adj;
sensorval = fakesensorval;
#endif
     
       #if ADV_DEBUG_MESSAGE_FORMAT==0
         updateSensorData ((uint16)timeval, (uint16)tempval, (uint16)sensorval);
         DataReadyFlag = 1;
       #else
         // Gather additional interesting diagnostic info before updating structure
         spare = HalAdcRead(0x01, HAL_ADC_RESOLUTION_12); // Spare A/D chan - use for battery measurement later
  
         // Turn on the test mode to enable temperature measurement 
         // from the CC2544's internal temp sensor
         ATEST=1; // ATEST.ATEST_CTRL=0x01;
         TR0=1;   //  TR0.ADCTM=1;
        
         HalAdcSetReference(0); // use internal ref voltage (1.15 V)
         //HalAdcSetReference ( 0x80); // use AVDD5 pin for ref
         
         // CC2541 Internal temp sensor is A/D input 14 (0x0e)
         tempvalCC2541 = HalAdcRead(0x0E, HAL_ADC_RESOLUTION_12); 

         /* Turn off test modes */
         TR0=0; //        TR0.ADCTM=0;
         ATEST=0;

        // The analog temperature sensor in the CC2544 should give back a value 
        // of 1480 at 25 degrees C and VDD=3, 
        // and will change by a value of 4.5 per degree C
        //     
        // So, to get temperature in 0.1 degrees C units, consider the 
        // following formula:
        //  
        tempval2 = tempvalCC2541-1480;
        tempvalCC2541 = (int16) (250.0 + (tempval2/4.5));
      
        HalAdcSetReference(0); // use internal ref voltage (1.15 V)
          
        // Pick up VDD divided by 3
        vdd_div_3 = HalAdcRead(0x0F, HAL_ADC_RESOLUTION_12); // VDD/3
        // Convert to millivolts (and get rid of the divide by 3, since we're doing math
        // vdd = (int) (1.15*vdd_div_3*3.0*1000.0 / 2047.0); // convert to millivolts
        // vdd = (int) (vdd_div_3 * 1.6853932584269662921348314606742); // more precisely
        vdd = (int) (vdd_div_3 * 1.6853); // close enough
        
        // Pick up the spare A/D input
        HalAdcSetReference (0x40); // use AIN7 for ref
        spare = HalAdcRead(0x01, HAL_ADC_RESOLUTION_12); 

        updateSensorData ((uint16)timeval, (uint16)tempval, (uint16)sensorval, (uint16)tempvalCC2541, (uint16)vdd, (uint16)spare);
        DataReadyFlag = 1;
        
        #endif
       
         // Set the light control I/O (LightOn=1 =>  P1_1=0)
        nuSOCKET_updateLight();
        
        // Also, set P1_0 (the LED) as an output, and drive low  
        P1DIR = P1DIR | 0x01; 
        P1 = P1&0xFE;

        
        return (events ^ 1);;
    }
    
    return (0);
} // end DataUpdate_ProcessEvent()