Hello All,
I have simplified my example and included all files from my Arduino sketchbook below.
All files seem to be included in the sketch, it's just the struct itself that doesn't work. I've hardcoded the address instead of using the structure and everything worked fine, but when using the structure I'm still getting "undefined reference to `Sensor_0'" in main.
I removed the "extern" before const, and the error went away, but it still didn't recognize the structure data.
main.ino
/*
* ======== main.c ========
* Simple example that uses the Sensors APIs
*/
#include "Sensor.hpp"
#include <Wire.h>
extern const Sensor_Handle Sensor_0;
void setup()
{
Wire.begin();
Sensor_config(Sensor_0);
Serial.begin(9600);
}
void loop()
{
uint16_t result_hex1;
result_hex1 = Sensor_readReg(Sensor_0, 0x3E);
Serial.print(result_hex1);
Serial.print("\n");
delay(1000);
}
Sensor.cpp
#include <stddef.h>
#include <stdint.h>
#include "Sensor.hpp"
#include "mcu.hpp"
static Sensor_State Sensor_0_state = {
.busId = 0,
.devAddr = 0x43,
};
const Sensor_Handle Sensor_0 = &Sensor_0_state;
#define MSB(u16) (((u16) & 0xFF00U) >> 8)
#define LSB(u16) ((u16) & 0xFFU)
/*
* ======== Sensor_writeReg ========
* Write register
*/
void Sensor_writeReg(Sensor_Handle sensor, uint8_t regAddr, uint16_t value)
{
uint8_t txBuf[3] = {0}; //All writable registers are 2 bytes
txBuf[0] = regAddr;
txBuf[1] = MSB(value);
txBuf[2] = LSB(value);
mcu_i2cTransfer(sensor->busId, sensor->devAddr, txBuf, 3, NULL, 0);
}
/*
* ======== Sensor_Sensor ========
* Sensorure device with current settings.
*/
void Sensor_config(Sensor_Handle sensor)
{
//Initialize the bus containing this sensor
mcu_i2cInit(sensor->busId);
}
/*
* ======== Sensor_readReg ========
* Read register
*/
uint64_t Sensor_readReg(Sensor_Handle sensor, uint8_t regAddr)
{
uint64_t value;
int i;
uint8_t txBuf[1] = {0};
uint8_t rxBuf[2] = {0}; //max buffer size
txBuf[0] = regAddr;
//Read register
mcu_i2cTransfer(sensor->busId, sensor->devAddr, txBuf, 1, rxBuf, 2);
//Combine bytes
value = (rxBuf[0] << 8) | rxBuf[1];
return value;
}
Sensor.hpp
/*
* ======== Sensor.h ========
* Sensor Interface
*/
#ifndef sensors_Sensor__include
#define sensors_Sensor__include 1
#include <stdint.h>
/* support C++ sources */
#ifdef __cplusplus
extern "C" {
#endif
/*
* ======== Sensor_State ========
* Initial configuration state for a Sensor sensor
*/
typedef struct Sensor_State {
uint8_t busId; /* I2C bus id */
uint8_t devAddr; /* Sensor's I2C address on the bus */
} Sensor_State;
/*
* ======== Sensor_Handle ========
* First argument to all Sensor methods
*/
typedef Sensor_State *Sensor_Handle;
/*
* ======== Sensor_writeReg ========
* Write register
*/
extern void Sensor_writeReg(Sensor_Handle sensor, uint8_t regAddr, uint16_t value);
/*
* ======== Sensor_config ========
* Configure device with current settings
*/
extern void Sensor_config(Sensor_Handle sensor);
/*
* ======== Sensor_readReg ========
* Read register
*/
extern uint64_t Sensor_readReg(Sensor_Handle sensor, uint8_t regAddr);
/* support C++ sources */
#ifdef __cplusplus
}
#endif
#endif
mcu.cpp
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include "mcu.hpp"
#include <Wire.h>
void mcu_i2cInit(uint8_t busId)
{
Wire.begin();
}
int8_t mcu_i2cTransfer( uint8_t busId, uint8_t i2cAddr,
uint8_t *dataToWrite, uint8_t writeLength,
uint8_t *dataToRead, uint8_t readLength)
{
if(writeLength > 0)
{
Wire.beginTransmission(i2cAddr);
Wire.write(dataToWrite, writeLength); // sends five bytes
Wire.endTransmission(); // stop transmitting
}
if(readLength > 0)
{
Wire.requestFrom(i2cAddr, readLength); // request 6 bytes from slave device #8
while (Wire.available()) // slave may send less than requested
{
dataToRead = Wire.read(); // receive a byte as character
}
}
return (0);
}
mcu.hpp
/*
* ======== mcu.h ========
* MCU hardware abstraction used sensor API implementations
*/
#ifndef sensors_MCU__include
#define sensors_MCU__include 1
#include <stdint.h>
/* support C++ sources */
#ifdef __cplusplus
extern "C" {
#endif
/*
* ======== mcu_i2cInit ========
* Initialize the specified I2C bus for first use
*/
extern void mcu_i2cInit(uint8_t busId);
/*
* ======== mcu_i2cTransfer ========
* Transfer data to and from an I2C slave
*/
extern int8_t mcu_i2cTransfer(uint8_t busId, uint8_t sensorAddress,
uint8_t *dataToWrite, uint8_t writeLength,
uint8_t *dataToRead, uint8_t readLength);
/* support C++ sources */
#ifdef __cplusplus
}
#endif
#endif /* sensors_MCU__include */