0

It's my first time learning how to do documentation using Doxygen and I do this by practicing on doxy'd codes of ADXL345 in Github as basis here. I was able to generate the Doxygen html site by changing the comments but while my Adafruit_ADXL345_U.h header file is showed properly, the Adafruit_ADXL345_U.cpp lack the documentation showed in the site. It only showed one static function "spixfer()".

Adafruit_ADXL345_U.cpp doxygen.

I don't see in the documentation the inline and other functions.

The Doxywizard version I'm using is 1.9.1, the *.cpp extension is present and the configuration I used are:

ALWAYS_DETAILED_SEC = YES
INLINE_INHERITED_MEMB = YES
FULL_PATH_NAMES = YES
JAVADOC_AUTOBRIEF = NO    
INHERIT_DOCS = YES
BUILTIN_STL_SUPPORT = YES
CPP_CLI_SUPPORT = YES
EXTRACT_ALL = YES
EXTRACT_PRIVATE = YES
EXTRACT_PRIV_VIRTUAL = YES
EXTRACT_PACKAGE = YES
EXTRACT_STATIC = YES
EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_METHODS = YES
EXTRACT_ANON_NSPACES = YES
INTERNAL_DOCS = YES
CASE_SENSE_NAMES = YES
SHOW_GROUPED_MEMB_INC = YES
FORCE_LOCAL_INCLUDES = YES
RECURSIVE = YES
SOURCE_BROWSER = YES
INLINE_SOURCE = YES
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
SKIP_FUNCTION_MACROS = YES

Code used below:

Adafruit_ADXL345_U.h

/**************************************************************************/
/*!
    @file     Adafruit_ADXL345_U.h
    @author   K. Townsend (Adafruit Industries)
    The ADXL345 is a digital accelerometer with 13-bit resolution, capable
    of measuring up to +/-16g.  This driver communicate using I2C.
    This is a library for the Adafruit ADXL345 breakout
    ----> https://www.adafruit.com/products/1231
    Adafruit invests time and resources providing this open source code,
    please support Adafruit and open-source hardware by purchasing
    products from Adafruit!
    @section license License
    BSD (see license.txt)
    @section  HISTORY
    v1.1 - Added Adafruit_Sensor library support
    v1.0 - First release
*/
/**************************************************************************/

#ifndef Adafruit_ADXL345_h
#define Adafruit_ADXL345_h

#if ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

#include <Adafruit_Sensor.h>
#include <Wire.h>

/*=========================================================================
    I2C ADDRESS/BITS
    -----------------------------------------------------------------------*/
#define ADXL345_DEFAULT_ADDRESS (0x53) ///< Assumes ALT address pin low
/*=========================================================================*/

/*=========================================================================
    REGISTERS
    -----------------------------------------------------------------------*/
#define ADXL345_REG_DEVID (0x00)        ///< Device ID
#define ADXL345_REG_THRESH_TAP (0x1D)   ///< Tap threshold
#define ADXL345_REG_OFSX (0x1E)         ///< X-axis offset
#define ADXL345_REG_OFSY (0x1F)         ///< Y-axis offset
#define ADXL345_REG_OFSZ (0x20)         ///< Z-axis offset
#define ADXL345_REG_DUR (0x21)          ///< Tap duration
#define ADXL345_REG_LATENT (0x22)       ///< Tap latency
#define ADXL345_REG_WINDOW (0x23)       ///< Tap window
#define ADXL345_REG_THRESH_ACT (0x24)   ///< Activity threshold
#define ADXL345_REG_THRESH_INACT (0x25) ///< Inactivity threshold
#define ADXL345_REG_TIME_INACT (0x26)   ///< Inactivity time
#define ADXL345_REG_ACT_INACT_CTL                                              \
  (0x27) ///< Axis enable control for activity and inactivity detection
#define ADXL345_REG_THRESH_FF (0x28) ///< Free-fall threshold
#define ADXL345_REG_TIME_FF (0x29)   ///< Free-fall time
#define ADXL345_REG_TAP_AXES (0x2A)  ///< Axis control for single/double tap
#define ADXL345_REG_ACT_TAP_STATUS (0x2B) ///< Source for single/double tap
#define ADXL345_REG_BW_RATE (0x2C)        ///< Data rate and power mode control
#define ADXL345_REG_POWER_CTL (0x2D)      ///< Power-saving features control
#define ADXL345_REG_INT_ENABLE (0x2E)     ///< Interrupt enable control
#define ADXL345_REG_INT_MAP (0x2F)        ///< Interrupt mapping control
#define ADXL345_REG_INT_SOURCE (0x30)     ///< Source of interrupts
#define ADXL345_REG_DATA_FORMAT (0x31)    ///< Data format control
#define ADXL345_REG_DATAX0 (0x32)         ///< X-axis data 0
#define ADXL345_REG_DATAX1 (0x33)         ///< X-axis data 1
#define ADXL345_REG_DATAY0 (0x34)         ///< Y-axis data 0
#define ADXL345_REG_DATAY1 (0x35)         ///< Y-axis data 1
#define ADXL345_REG_DATAZ0 (0x36)         ///< Z-axis data 0
#define ADXL345_REG_DATAZ1 (0x37)         ///< Z-axis data 1
#define ADXL345_REG_FIFO_CTL (0x38)       ///< FIFO control
#define ADXL345_REG_FIFO_STATUS (0x39)    ///< FIFO status
/*=========================================================================*/

/*=========================================================================
    REGISTERS
    -----------------------------------------------------------------------*/
#define ADXL345_MG2G_MULTIPLIER (0.004) ///< 4mg per lsb
/*=========================================================================*/

/**
 * @brief Used with register 0x2C (ADXL345_REG_BW_RATE) to set bandwidth
*/
typedef enum {
  ADXL345_DATARATE_3200_HZ = 0b1111, ///< 1600Hz Bandwidth   140�A IDD
  ADXL345_DATARATE_1600_HZ = 0b1110, ///<  800Hz Bandwidth    90�A IDD
  ADXL345_DATARATE_800_HZ = 0b1101,  ///<  400Hz Bandwidth   140�A IDD
  ADXL345_DATARATE_400_HZ = 0b1100,  ///<  200Hz Bandwidth   140�A IDD
  ADXL345_DATARATE_200_HZ = 0b1011,  ///<  100Hz Bandwidth   140�A IDD
  ADXL345_DATARATE_100_HZ = 0b1010,  ///<   50Hz Bandwidth   140�A IDD
  ADXL345_DATARATE_50_HZ = 0b1001,   ///<   25Hz Bandwidth    90�A IDD
  ADXL345_DATARATE_25_HZ = 0b1000,   ///< 12.5Hz Bandwidth    60�A IDD
  ADXL345_DATARATE_12_5_HZ = 0b0111, ///< 6.25Hz Bandwidth    50�A IDD
  ADXL345_DATARATE_6_25HZ = 0b0110,  ///< 3.13Hz Bandwidth    45�A IDD
  ADXL345_DATARATE_3_13_HZ = 0b0101, ///< 1.56Hz Bandwidth    40�A IDD
  ADXL345_DATARATE_1_56_HZ = 0b0100, ///< 0.78Hz Bandwidth    34�A IDD
  ADXL345_DATARATE_0_78_HZ = 0b0011, ///< 0.39Hz Bandwidth    23�A IDD
  ADXL345_DATARATE_0_39_HZ = 0b0010, ///< 0.20Hz Bandwidth    23�A IDD
  ADXL345_DATARATE_0_20_HZ = 0b0001, ///< 0.10Hz Bandwidth    23�A IDD
  ADXL345_DATARATE_0_10_HZ =
      0b0000 ///< 0.05Hz Bandwidth    23�A IDD (default value)
} dataRate_t;

/**
 * @brief  Used with register 0x31 (ADXL345_REG_DATA_FORMAT) to set g range
 *
 */
typedef enum {
  ADXL345_RANGE_16_G = 0b11, ///< +/- 16g
  ADXL345_RANGE_8_G = 0b10,  ///< +/- 8g
  ADXL345_RANGE_4_G = 0b01,  ///< +/- 4g
  ADXL345_RANGE_2_G = 0b00   ///< +/- 2g (default value)
} range_t;

/**
 * @brief Class to interact with the ADXL345 accelerometer
 *
 */
class Adafruit_ADXL345_Unified : public Adafruit_Sensor {
public:
  Adafruit_ADXL345_Unified(int32_t sensorID = -1);
  Adafruit_ADXL345_Unified(uint8_t clock, uint8_t miso, uint8_t mosi,
                           uint8_t cs, int32_t sensorID = -1);

  bool begin(uint8_t addr = ADXL345_DEFAULT_ADDRESS);
  void setRange(range_t range);
  range_t getRange(void);
  void setDataRate(dataRate_t dataRate);
  dataRate_t getDataRate(void);
  bool getEvent(sensors_event_t *);
  void getSensor(sensor_t *);

  uint8_t getDeviceID(void);
  void writeRegister(uint8_t reg, uint8_t value);
  uint8_t readRegister(uint8_t reg);
  int16_t read16(uint8_t reg);

  int16_t getX(void), getY(void), getZ(void);

private:
  inline uint8_t i2cread(void);
  inline void i2cwrite(uint8_t x);

  int32_t _sensorID;
  range_t _range;
  uint8_t _clk, _do, _di, _cs;
  bool _i2c;
  int8_t _i2caddr;
};

#endif // Adafruit_ADXL345_h

Adafruit_ADXL345_U.cpp

/**************************************************************************/
/*!
    @file     Adafruit_ADXL345_U.cpp
    @author   K.Townsend (Adafruit Industries)
*/
/**************************************************************************/
#if ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

#include <Wire.h>
#include <limits.h>

#include "Adafruit_ADXL345_U.h"

/**************************************************************************/
/*!
    @brief  And abstract 'send' method for different versions of the Arduino
   Wire library
    @returns The byte read
*/
/**************************************************************************/
inline uint8_t Adafruit_ADXL345_Unified::i2cread(void) {
#if ARDUINO >= 100
  return Wire.read();
#else
  return Wire.receive();
#endif
}

/**************************************************************************/
/*!
    @brief  And abstract 'send' method for different versions of the Arduino
   Wire library
    @param x The byte to send
*/
/**************************************************************************/
inline void Adafruit_ADXL345_Unified::i2cwrite(uint8_t x) {
#if ARDUINO >= 100
  Wire.write((uint8_t)x);
#else
  Wire.send(x);
#endif
}

/**************************************************************************/

/**
 * @brief  Abstract away SPI receiver & transmitter
 * @param clock The pin number for SCK, the SPI ClocK line
 * @param miso The pin number for MISO, the SPI Master In Slave Out line
 * @param mosi The pin number for MOSI, the SPI Master Out Slave In line
 * @param data The byte to send
 *
 * @return uint8_t The single byte response
 */
static uint8_t spixfer(uint8_t clock, uint8_t miso, uint8_t mosi,
                       uint8_t data) {
  uint8_t reply = 0;
  for (int i = 7; i >= 0; i--) {
    reply <<= 1;
    digitalWrite(clock, LOW);
    digitalWrite(mosi, data & (1 << i));
    digitalWrite(clock, HIGH);
    if (digitalRead(miso))
      reply |= 1;
  }
  return reply;
}

/**************************************************************************/
/*!
    @brief  Writes one byte to the specified destination register
    @param reg The address of the register to write to
    @param value The value to set the register to
*/
/**************************************************************************/
void Adafruit_ADXL345_Unified::writeRegister(uint8_t reg, uint8_t value) {
  if (_i2c) {
    Wire.beginTransmission((uint8_t)_i2caddr);
    i2cwrite((uint8_t)reg);
    i2cwrite((uint8_t)(value));
    Wire.endTransmission();
  } else {
    digitalWrite(_cs, LOW);
    spixfer(_clk, _di, _do, reg);
    spixfer(_clk, _di, _do, value);
    digitalWrite(_cs, HIGH);
  }
}

/**************************************************************************/
/*!
    @brief Reads one byte from the specified register
    @param reg The address of the register to read from
    @returns The single byte value of the requested register
*/
/**************************************************************************/
uint8_t Adafruit_ADXL345_Unified::readRegister(uint8_t reg) {
  if (_i2c) {
    Wire.beginTransmission((uint8_t)_i2caddr);
    i2cwrite(reg);
    Wire.endTransmission();
    Wire.requestFrom((uint8_t)_i2caddr, 1);
    return (i2cread());
  } else {
    reg |= 0x80; // read byte
    digitalWrite(_cs, LOW);
    spixfer(_clk, _di, _do, reg);
    uint8_t reply = spixfer(_clk, _di, _do, 0xFF);
    digitalWrite(_cs, HIGH);
    return reply;
  }
}

/**************************************************************************/
/*!
    @brief Reads two bytes from the specified register
    @param reg The address of the register to read from
    @return The two bytes read from the sensor starting at the given address
*/
/**************************************************************************/
int16_t Adafruit_ADXL345_Unified::read16(uint8_t reg) {
  if (_i2c) {
    Wire.beginTransmission((uint8_t)_i2caddr);
    i2cwrite(reg);
    Wire.endTransmission();
    Wire.requestFrom((uint8_t)_i2caddr, 2);
    return (uint16_t)(i2cread() | (i2cread() << 8));
  } else {
    reg |= 0x80 | 0x40; // read byte | multibyte
    digitalWrite(_cs, LOW);
    spixfer(_clk, _di, _do, reg);
    uint16_t reply =
        spixfer(_clk, _di, _do, 0xFF) | (spixfer(_clk, _di, _do, 0xFF) << 8);
    digitalWrite(_cs, HIGH);
    return reply;
  }
}

/**************************************************************************/
/*!
    @brief  Reads the device ID (can be used to check connection)
    @return The Device ID of the connected sensor
*/
/**************************************************************************/
uint8_t Adafruit_ADXL345_Unified::getDeviceID(void) {
  // Check device ID register
  return readRegister(ADXL345_REG_DEVID);
}

/**************************************************************************/
/*!
    @brief  Gets the most recent X axis value
    @return The raw `int16_t` unscaled x-axis acceleration value
*/
/**************************************************************************/
int16_t Adafruit_ADXL345_Unified::getX(void) {
  return read16(ADXL345_REG_DATAX0);
}

/**************************************************************************/
/*!
    @brief  Gets the most recent Y axis value
    @return The raw `int16_t` unscaled y-axis acceleration value
*/
/**************************************************************************/
int16_t Adafruit_ADXL345_Unified::getY(void) {
  return read16(ADXL345_REG_DATAY0);
}

/**************************************************************************/
/*!
    @brief  Gets the most recent Z axis value
    @return The raw `int16_t` unscaled z-axis acceleration value
*/
/**************************************************************************/
int16_t Adafruit_ADXL345_Unified::getZ(void) {
  return read16(ADXL345_REG_DATAZ0);
}

/**************************************************************************/
/*!
    @brief  Instantiates a new ADXL345 class
    @param sensorID A unique ID to use to differentiate the sensor from others
*/
/**************************************************************************/
Adafruit_ADXL345_Unified::Adafruit_ADXL345_Unified(int32_t sensorID) {
  _sensorID = sensorID;
  _range = ADXL345_RANGE_2_G;
  _i2c = true;
}

/**************************************************************************/
/*!
    @brief  Instantiates a new ADXL345 class in SPI mode
    @param clock The pin number for SCK, the SPI ClocK line
    @param miso The pin number for MISO, the SPI Master In Slave Out line
    @param mosi The pin number for MOSI, the SPI Master Out Slave In line
    @param cs The pin number for CS, the SPI Chip Select line
    @param sensorID A unique ID to use to differentiate the sensor from others
*/
/**************************************************************************/
Adafruit_ADXL345_Unified::Adafruit_ADXL345_Unified(uint8_t clock, uint8_t miso,
                                                   uint8_t mosi, uint8_t cs,
                                                   int32_t sensorID) {
  _sensorID = sensorID;
  _range = ADXL345_RANGE_2_G;
  _cs = cs;
  _clk = clock;
  _do = mosi;
  _di = miso;
  _i2c = false;
}

/**************************************************************************/
/*!
    @brief  Setups the HW (reads coefficients values, etc.)
    @param i2caddr The I2C address to begin communication with
    @return true: success false: a sensor with the correct ID was not found
*/
/**************************************************************************/
bool Adafruit_ADXL345_Unified::begin(uint8_t i2caddr) {
  _i2caddr = i2caddr;

  if (_i2c)
    Wire.begin();
  else {
    pinMode(_cs, OUTPUT);
    digitalWrite(_cs, HIGH);
    pinMode(_clk, OUTPUT);
    digitalWrite(_clk, HIGH);
    pinMode(_do, OUTPUT);
    pinMode(_di, INPUT);
  }

  /* Check connection */
  uint8_t deviceid = getDeviceID();
  if (deviceid != 0xE5) {
    /* No ADXL345 detected ... return false */
    return false;
  }

  // Enable measurements
  writeRegister(ADXL345_REG_POWER_CTL, 0x08);

  return true;
}

/**************************************************************************/
/*!
    @brief  Sets the g range for the accelerometer
    @param range The new `range_t` to set the accelerometer to
*/
/**************************************************************************/
void Adafruit_ADXL345_Unified::setRange(range_t range) {
  /* Read the data format register to preserve bits */
  uint8_t format = readRegister(ADXL345_REG_DATA_FORMAT);

  /* Update the data rate */
  format &= ~0x0F;
  format |= range;

  /* Make sure that the FULL-RES bit is enabled for range scaling */
  format |= 0x08;

  /* Write the register back to the IC */
  writeRegister(ADXL345_REG_DATA_FORMAT, format);

  /* Keep track of the current range (to avoid readbacks) */
  _range = range;
}

/**************************************************************************/
/*!
    @brief  Gets the g range for the accelerometer
    @return The current `range_t` value
*/
/**************************************************************************/
range_t Adafruit_ADXL345_Unified::getRange(void) {
  /* Read the data format register to preserve bits */
  return (range_t)(readRegister(ADXL345_REG_DATA_FORMAT) & 0x03);
}

/**************************************************************************/
/*!
    @brief  Sets the data rate for the ADXL345 (controls power consumption)
    @param dataRate The `dataRate_t` to set
*/
/**************************************************************************/
void Adafruit_ADXL345_Unified::setDataRate(dataRate_t dataRate) {
  /* Note: The LOW_POWER bits are currently ignored and we always keep
     the device in 'normal' mode */
  writeRegister(ADXL345_REG_BW_RATE, dataRate);
}

/**************************************************************************/
/*!
    @brief  Gets the data rate for the ADXL345 (controls power consumption)
    @return The current data rate
*/
/**************************************************************************/
dataRate_t Adafruit_ADXL345_Unified::getDataRate(void) {
  return (dataRate_t)(readRegister(ADXL345_REG_BW_RATE) & 0x0F);
}

/**************************************************************************/
/*!
    @brief  Gets the most recent sensor event
    @param event Pointer to the event object to fill
    @return true: success
*/
/**************************************************************************/
bool Adafruit_ADXL345_Unified::getEvent(sensors_event_t *event) {
  /* Clear the event */
  memset(event, 0, sizeof(sensors_event_t));

  event->version = sizeof(sensors_event_t);
  event->sensor_id = _sensorID;
  event->type = SENSOR_TYPE_ACCELEROMETER;
  event->timestamp = 0;
  event->acceleration.x =
      getX() * ADXL345_MG2G_MULTIPLIER * SENSORS_GRAVITY_STANDARD;
  event->acceleration.y =
      getY() * ADXL345_MG2G_MULTIPLIER * SENSORS_GRAVITY_STANDARD;
  event->acceleration.z =
      getZ() * ADXL345_MG2G_MULTIPLIER * SENSORS_GRAVITY_STANDARD;

  return true;
}

/**************************************************************************/
/*!
 */
/**************************************************************************/

/**
 * @brief Fill a `sensor_t` struct with information about the sensor
 *
 * @param sensor Pointer to a `sensor_t` struct to fill
 */
void Adafruit_ADXL345_Unified::getSensor(sensor_t *sensor) {
  /* Clear the sensor_t object */
  memset(sensor, 0, sizeof(sensor_t));

  /* Insert the sensor name in the fixed length char array */
  strncpy(sensor->name, "ADXL345", sizeof(sensor->name) - 1);
  sensor->name[sizeof(sensor->name) - 1] = 0;
  sensor->version = 1;
  sensor->sensor_id = _sensorID;
  sensor->type = SENSOR_TYPE_ACCELEROMETER;
  sensor->min_delay = 0;
  sensor->max_value = -156.9064F; /* -16g = 156.9064 m/s^2  */
  sensor->min_value = 156.9064F;  /*  16g = 156.9064 m/s^2  */
  sensor->resolution = 0.03923F;  /*  4mg = 0.0392266 m/s^2 */
}

May I ask what can I change in the configuration in order to view the rest of the documentation comments?

  • I think that Doxygen does not follow `#include`, so you must instruct it to read header files (`*.h`), too, not just `*.cpp`. – j6t Mar 23 '21 at 07:08
  • @j6t Are you referring to the FILE_PATTERNS? `*.h` is present in the list. I can view it pretty well but compared to the source file (`*.cpp`), it's more complete. The source file is rather lacking of documentation with only one static function to show for. Is this a normal thing for source files? – stall_call Mar 23 '21 at 07:58
  • Yes, I was referring to `FILE_PATTERNS`. Show an example of a function that you expect that is documented, but isn't. – j6t Mar 23 '21 at 08:22
  • Please show some code, just the links don't work and their content will change in time. Also have a look at the settings like ENABLE_PREPROCESSING. MACRO_EXPANSION etc. – albert Mar 23 '21 at 08:49
  • @j6t I'm not entirely sure if this is a function or a method but an example would be `inline uint8_t Adafruit_ADXL345_Unified::i2cread(void)`. I dont have a good grasp yet on classes and methods so I might be wrong. – stall_call Mar 23 '21 at 11:51
  • @albert I have edited my question to add the code for reference. For the preprocessor, have also added it in during my edit but here is also my configuration: `ENABLE_PREPROCESSING = YES MACRO_EXPANSION = YES EXPAND_ONLY_PREDEF = NO SEARCH_INCLUDES = YES SKIP_FUNCTION_MACROS = YES` – stall_call Mar 23 '21 at 11:55
  • As far as I can see all functions are present. The functions "missing" look to me all to be functions from the class and documented at that place, see in the classes button and inyour output: html/classAdafruit__ADXL345__Unified.html did I overlook a function or missed something else? – albert Mar 23 '21 at 13:06
  • @albert Yes, I saw that as well but I'm confused as to why it would appear there and not in the Adafruit345_U.cpp file reference, can you provide an explanation as to why this occurred? – stall_call Mar 23 '21 at 14:50
  • Classes are different entities and as such kept together. The cpp file normally only contains the implementation of the files like the h file contains the definition (prototype). In the h file you see a reference to the class though. – albert Mar 23 '21 at 14:53
  • I'm a bit unfamiliar with implementation and definition and why .cpp is for implementation and .h is for definition so I'll have to study that for the moment. If you can give a bit of reason as to why I'd appreciate that. – stall_call Mar 23 '21 at 17:09

0 Answers0