Jamie Smith / BNO080

Dependents:   BNO080-Examples BNO080-Examples

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BNO080Async.h Source File

BNO080Async.h

00001 #ifndef BNO080_BNO080ASYNC_H
00002 #define BNO080_BNO080ASYNC_H
00003 
00004 #if MBED_CONF_RTOS_PRESENT
00005 
00006 #include <BNO080.h>
00007 #include <Mutex.h>
00008 
00009 /**
00010  * Asynchronous version of the SPI BNO080 driver.
00011  * Since the timing requirements of this driver are so different,
00012  * wouldn't it be great to have a dedicated thread to handle them?
00013  * This class provides exactly that, using an internal thread triggered
00014  * by interrupts to connect to the BNO.
00015  *
00016  * Note: the internal thread is started the first time begin() is called,
00017  * and is shut down when the class is destroyed.
00018  */
00019 class BNO080Async : public BNO080SPI
00020 {
00021 public:
00022     // Mutex protecting all sensor data in the driver.
00023     // You must lock this while reading data and unlock it when done.
00024     // While this is locked, the background thread is prevented from running.
00025     Mutex bnoDataMutex;
00026 
00027 private:
00028     // thread in charge of communicating with the BNO
00029     Thread commThread;
00030 
00031     // EventFlags to allow signalling the thread to wake up
00032     EventFlags wakeupFlags;
00033 
00034     // main function for the thread.
00035     // Handles starting the comm loop.
00036     void threadMain();
00037 
00038     // Code loop to communicate with the BNO.
00039     // Runs forever in normal operation.
00040     // Returns true to request a restart.
00041     // Returns false to request the thread to shutdown.
00042     bool commLoop();
00043 
00044     // flag to indicate that we have valid data to send queued in the TX buffer.
00045     // Protected by bnoDataMutex.
00046     bool dataToSend = false;
00047 
00048     // data for packet to send, if above flag is true
00049     uint8_t txPacketChannelNumber;
00050     uint8_t txPacketDataLength;
00051 
00052     // Condition variable signaled whenever a packet is sent.
00053     ConditionVariable dataSentCV;
00054 
00055     // flag used for updateData() return value.
00056     // True if any data packets have been received since the last update.
00057     bool dataReceived = false;
00058 
00059     // true iff the thread is currently in the middle of a TX/RX operation.
00060     // Causes _int interrupts (which get generated by the comms process) to be ignored.
00061     bool inTXRX = false;
00062 
00063     bool sendPacket(uint8_t channelNumber, uint8_t dataLength) override;
00064 
00065     void clearSendBuffer() override;
00066 
00067     // waiting for packet state info
00068     bool waitingForPacket = false;
00069     uint8_t waitingForChannel;
00070     uint8_t waitingForReportID;
00071     bool waitingPacketArrived = false;
00072     bool clearToRxNextPacket = false;
00073 
00074     ConditionVariable waitingPacketArrivedCV;
00075     ConditionVariable waitingPacketProcessedCV;
00076 
00077     bool waitForPacket(int channel, uint8_t reportID, std::chrono::milliseconds timeout = 125ms) override;
00078 
00079 public:
00080     /**
00081      * Construct a BNO080Async.
00082      * This doesn't actually initialize the chip, you will need to call begin() for that.
00083      *
00084      * NOTE: while some schematics tell you to connect the BOOTN pin to the processor, this driver does not use or require it.
00085      * Just tie it to VCC per the datasheet.
00086      *
00087      * @param debugPort Serial port to write output to.  Cannot be nullptr.
00088      * @param rstPin Hardware reset pin, resets the IMU
00089      * @param intPin Hardware interrupt pin, this is used for the IMU to signal the host that it has a message to send
00090      * @param wakePin Hardware wake pin, this is used by the processor to signal the BNO to wake up and receive a message
00091      * @param misoPin SPI MISO pin
00092      * @param mosiPin SPI MOSI pin
00093      * @param sclkPin SPI SCLK pin
00094      * @param csPin SPI CS pin
00095      * @param spiSpeed SPI frequency.  The BNO's max is 3MHz.
00096      * @param threadPriority Priority to give the internal thread.  Defaults to AboveNormal so it will run whenever it can.
00097      */
00098     BNO080Async(Stream *debugPort, PinName rstPin, PinName intPin, PinName wakePin, PinName misoPin, PinName mosiPin, PinName sclkPin, PinName csPin, int spiSpeed=3000000, osPriority threadPriority=osPriorityAboveNormal);
00099 
00100     /**
00101      * Resets and connects to the IMU.  Verifies that it's connected, and reads out its version
00102      * info into the class variables above.
00103      *
00104      * Async version also starts the internal communication thread, restarting it if it's
00105      * already started.
00106      *
00107      * If this function is failing, it would be a good idea to turn on BNO_DEBUG in the cpp file to get detailed output.
00108      *
00109      * @return whether or not initialization was successful
00110      */
00111     bool begin() override;
00112 
00113     /**
00114      * In BNO080Async, there is no need to call updateData() in order to get new
00115      * results, but this call is provided for compatibility.
00116      *
00117      * It maintains its behavior of returning true iff packets have been received since the last call.
00118      * You must lock bnoDataMutex to call this.
00119      * @return
00120      */
00121     bool updateData() override;
00122 
00123     /**
00124      * Locks the data mutex.
00125      */
00126     void lockMutex() override
00127     {
00128         bnoDataMutex.lock();
00129     }
00130 
00131     /**
00132      * Unlocks the data mutex.
00133      */
00134     void unlockMutex() override
00135     {
00136         bnoDataMutex.unlock();
00137     }
00138 };
00139 
00140 #endif
00141 
00142 
00143 #endif //MBED_CMAKE_TEST_PROJECT_BNO080ASYNC_H