Bluetooth Connected TOF Sensor

Dependencies:   BLE_API X_NUCLEO_6180XA1 X_NUCLEO_IDB0XA1 mbed

Fork of BLE_HeartRate_IDB0XA1 by ST

shields/xn6180.cpp

Committer:
hux
Date:
2017-02-02
Revision:
30:e324e95c68a9
Parent:
28:def5e0f0fb06

File content as of revision 30:e324e95c68a9:

// xn6180.cpp - X-NUCLEO 6180XA1 expansion board functionality
//
// This VL6180X Expansion board test application performs a range measurement and an als measurement in interrupt mode
// on the onboard embedded top sensor. 
// The board red slider select on the flight the measurement type as ALS or RANGE; the measured data is diplayed on the 
// on board 4digits display.
//
// User Blue button allows to stop current measurement and the entire program releasing all the resources.
// Reset button is used to restart the program.
//
// Polling operating modes don`t require callback function that handles IRQ 
// Callback IRQ functions are used only for measure that require interrupt
//
// GetMeasurement is asynchronous! It returns NOT_READY if the measurement value 
// is not ready to be read from the corresponding register. So you need to wait
// for the result to be ready
//

#include "mbed.h"
#include "shields/xn6180.h"

#define VL6180X_I2C_SDA   D14 
#define VL6180X_I2C_SCL   D15 

#define RANGE   0
#define ALS     1

#define DELAY 2000  // 2Sec
   
// static DisplayShield *pShield = 0;    // used by IRQ callback to access data

   void DisplayShield::init(const char *msg, int msec)
   {
      if (msg)
         display(msg,msec);         // display "INI" for 1 second
   
         // now init the 6180XA1 expansion board with default values
      
      int err = pBoard->InitBoard();
      if (err)
         printf("Failed to init board!\n\r");
               
         // read the red slider position for ALS/Range measure
         
      slider(IntMeasure);              // update curMode due to slider position
      clear();                         // clear service handling request flag    
   }

   
   DisplayShield::DisplayShield(const char *msg, int msec)
   {
         // first we need an I2C device
         
      pDevice = new DevI2C(VL6180X_I2C_SDA, VL6180X_I2C_SCL);     
      
         // next we create the 6180XA1 expansion board singleton obj 
         // after that we are already able to display the init message
      
//    pBoard = X_NUCLEO_6180XA1::Instance(pDevice, A3, A2, D13, D2);
      pBoard = X_NUCLEO_6180XA1::Instance(pDevice, NC, NC, NC,  NC);

      init(msg,msec);                    // initialize shield
   }

//==============================================================================
// Displaying Messages or Values
//==============================================================================

  
   void DisplayShield::display(const char * msg)  // display max 4 digits
   {
      char buf[5];
      int nmax = sizeof(buf) - 1;
      int len = strlen(msg);

      memset(buf,0,sizeof(buf));         // clear buffer, provide terminator
      for (int j=0; j < nmax; j++)
      {  if (msg[j] == 0)
            break;
         buf[j] = msg[j];
      }

      pBoard->display->DisplayString(buf, strlen(buf));
   }

   
   void DisplayShield::display(const char * msg, int msec)  // display & wait
   {
      Timer timer;
   
      timer.start();
      for(int i=0; i < msec; i = timer.read_ms())
         display(msg);
      timer.stop();
   }


// On board 4 digit local display refresh

   void DisplayShield::refresh(OpMode mode)
   {   
      char str[5];
   
      if(mode == range_continuous_interrupt || mode == range_continuous_polling)
      {
         if (data.range_mm != 0xFFFFFFFF)
         {
            sprintf(str,"%d",data.range_mm);
         }
         else
         {
            sprintf(str,"%s","----");
         }
      }
      else if(mode == als_continuous_interrupt || mode == als_continuous_polling)
      {
         if(data.lux != 0xFFFFFFFF)
         {
            sprintf(str,"%d",data.lux);
         }
         else
         {
            sprintf(str,"%s","----");
         }
      }
      pBoard->display->DisplayString(str, strlen(str));       
   }

   void DisplayShield::refresh()       // refresh display in current mode
   {
       refresh(curMode);
   }


//==============================================================================
// IRQ Functionality
//==============================================================================

          
   void DisplayShield::set()           // set data read service request
   {
      flagService = true;
   }
   
   void DisplayShield::clear()         // clear data read service request
   {
      flagService = false;
   }
   
   bool DisplayShield::request()       // return data read service request
   {
      return flagService;
   }
/*
   static void cbDone(void)            // measurement done callback
   {
      if (pShield)
      {
          pShield->set();              // set service request
          pShield->disable();          // disable further interrupts
          pShield = 0;                 // free-up shield pointer, no more in use
      }
   } 
*/

   int DisplayShield::handle()         // handle ISR and read the measurement
   {
       clear();                        // clear data read service request
       return pBoard->sensor_top->HandleIRQ(curMode, &data); 
   }

   
   void DisplayShield::disable()       // disable interrupt measure detection
   {
      pBoard->sensor_top->DisableInterruptMeasureDetectionIRQ();
   }


   void DisplayShield::ready()         // set data ready status 
   {
       disable();                      // disable interrupts
       set();                          // set data service request flag
   }

   
   int DisplayShield::start(void (*callback)(void))
   {
      int err;                         // error code
      
//    if (pShield != 0)
//       return 0x99;                  // pShield is already booked!
//
//    pShield = this;                  // make access available to cbDone()         
      err = pBoard->sensor_top->StartMeasurement(curMode, callback, NULL, NULL); 

      if (err == 0)                    // if no errors occured
      {
         prvMode = curMode;
         startMessage();               // then report about successful start
      }
        
      return err;
   }


   int DisplayShield::stop()
   {
      int err;                         // error code

//    pShield = 0;                     // free-up pShield pointer  
      err = pBoard->sensor_top->StopMeasurement(prvMode); // stop measurement

      if (err == 0)                    // if no errors occured
         stopMessage();                // then report about successful stop
         
      return err;                      // return error code
   }


//==============================================================================
// Examine Red Slider Position
//==============================================================================
   
   bool DisplayShield::red()
   {
      return (pBoard->RdSwitch() == RANGE);
   }
   
   bool DisplayShield::slider(enum OpModeIntPoll_t mode)
   {
      int measure = pBoard->RdSwitch();

      switch (mode)
      {
         case PollMeasure:
            if (measure == RANGE)
               curMode = range_continuous_polling;
            else if(measure==ALS)
               curMode = als_continuous_polling;           
            break;
    
         case IntMeasure:
            if(measure == RANGE)
               curMode = range_continuous_interrupt;
            else if(measure == ALS)
               curMode = als_continuous_interrupt;     
            break;
      }
      
      return (curMode != prvMode);     // slider position changed?
   }

   bool DisplayShield::setup(OpMode mode)
   {
      switch (mode)
      {
         case range_continuous_polling:
         case als_continuous_polling:           
         case range_continuous_interrupt:
         case als_continuous_interrupt:
            curMode = mode;
            prvMode = mode;
            return 0;                  // no errors
      }
      return 1;                        // return with error code 1      
   }


//==============================================================================
// Trace Message Printing
//==============================================================================

   void DisplayShield::startMessage(OpMode mode)
   {
      if (mode == range_continuous_interrupt)
         printf("\nStarted range continuous interrupt measure\n\r");
      else if(prvMode == als_continuous_interrupt)
         printf("\nStarted als continuous interrupt measure\n\r");
   }

   void DisplayShield::startMessage()
   {
       startMessage(curMode);
   }

   void DisplayShield::stopMessage(OpMode mode)
   {
      if (mode == range_continuous_interrupt)
         printf("Stopped range continuous interrupt measure\n\r");
      else if(prvMode == als_continuous_interrupt)
         printf("Stopped als continuous interrupt measure\n\r");
   }

   void DisplayShield::stopMessage()
   {
       stopMessage(prvMode);
   }

// eof