API Reference
API Reference
Section titled “API Reference”Complete API reference for Multiflexmeter 3.7.0 firmware functions and interfaces.
Configuration API
Section titled “Configuration API”rom_conf.cpp
Section titled “rom_conf.cpp”rom_conf_init()
Section titled “rom_conf_init()”void rom_conf_init();
Initializes EEPROM configuration subsystem and loads configuration into memory.
Returns: None
Side Effects:
- Reads from EEPROM
- Populates global configuration structure
- Validates magic bytes
rom_conf_is_valid()
Section titled “rom_conf_is_valid()”bool rom_conf_is_valid();
Checks if EEPROM contains valid configuration.
Returns:
true
- Configuration is validfalse
- Configuration is invalid or corrupted
Validation:
- Checks magic bytes:
"MFM\0"
rom_conf_get_version()
Section titled “rom_conf_get_version()”uint16_t rom_conf_get_version();
Retrieves firmware version from EEPROM hardware version field.
Returns: 16-bit encoded version number
Format: proto[1]:major[5]:minor[5]:patch[5]
Example:
uint16_t version = rom_conf_get_version();// version = 0x8467 = v1.3.7
Sensor API
Section titled “Sensor API”sensors.cpp
Section titled “sensors.cpp”sensorPerform()
Section titled “sensorPerform()”uint8_t sensorPerform(uint8_t sensor_address);
Triggers sensor measurement by sending CMD_PERFORM (0x10).
Parameters:
sensor_address
- I²C address of sensor (typically 0x36)
Returns:
0
- Success1
- Communication error
Example:
if (sensorPerform(SENSOR_ADDRESS) == 0) { delay(100); // Wait for sensor processing}
sensorRead()
Section titled “sensorRead()”uint8_t sensorRead(uint8_t sensor_address, int16_t* data);
Reads measurement data from sensor (CMD_READ = 0x11).
Parameters:
sensor_address
- I²C address of sensordata
- Pointer to array of 8 × int16_t values
Returns:
0
- Success1
- Communication error
Data Format:
- Array of 8 signed 16-bit integers
- Sensor-specific interpretation
Example:
int16_t measurements[8];if (sensorRead(SENSOR_ADDRESS, measurements) == 0) { // Process measurements int16_t value1 = measurements[0]; int16_t value2 = measurements[1]; // ...}
SMBus/I²C API
Section titled “SMBus/I²C API”smbus.cpp
Section titled “smbus.cpp”smBusInit()
Section titled “smBusInit()”void smBusInit();
Initializes SMBus (I²C) communication.
Returns: None
Configuration:
- Clock speed: 100kHz (standard I²C)
- Internal pull-ups: disabled (external 4.7kΩ recommended)
smBusWriteByte()
Section titled “smBusWriteByte()”uint8_t smBusWriteByte(uint8_t address, uint8_t command);
Writes single command byte to SMBus device.
Parameters:
address
- 7-bit I²C addresscommand
- Command byte to send
Returns:
0
- Success1
- NAK or error
smBusReadWord()
Section titled “smBusReadWord()”uint16_t smBusReadWord(uint8_t address, uint8_t command);
Reads 16-bit word from SMBus device.
Parameters:
address
- 7-bit I²C addresscommand
- Command byte
Returns: 16-bit value (little-endian)
Board API
Section titled “Board API”boards/mfm_v3_m1284p.cpp
Section titled “boards/mfm_v3_m1284p.cpp”board_init()
Section titled “board_init()”void board_init();
Initializes board-specific hardware.
Side Effects:
- Configures GPIO pins
- Initializes peripherals
- Sets up power control
board_sleep()
Section titled “board_sleep()”void board_sleep();
Enters low-power sleep mode.
Power Consumption:
- Active: ~10mA
- Sleep: <1mA
board_sensor_power(bool enable)
Section titled “board_sensor_power(bool enable)”void board_sensor_power(bool enable);
Controls power to external sensor.
Parameters:
enable
-true
to power on,false
to power off
Watchdog API
Section titled “Watchdog API”wdt.cpp
Section titled “wdt.cpp”wdt_enable()
Section titled “wdt_enable()”void wdt_enable(uint16_t timeout_ms);
Enables watchdog timer.
Parameters:
timeout_ms
- Timeout in milliseconds (typically 8000ms)
wdt_reset()
Section titled “wdt_reset()”void wdt_reset();
Resets watchdog timer (prevents reboot).
Usage: Call periodically in main loop.
LoRaWAN Integration
Section titled “LoRaWAN Integration”LMIC Job Functions
Section titled “LMIC Job Functions”do_measure()
Section titled “do_measure()”static void do_measure(osjob_t* j);
Job function for triggering sensor measurements.
Flow:
- Power on sensor
- Send CMD_PERFORM
- Wait for processing
- Send CMD_READ
- Power off sensor
- Call
do_send()
do_send()
Section titled “do_send()”static void do_send(osjob_t* j);
Job function for sending LoRaWAN uplink.
Flow:
- Check if TX is ready
- Prepare payload (16 bytes)
- Queue transmission
- LMIC handles radio
onEvent()
Section titled “onEvent()”void onEvent(ev_t ev);
LMIC event handler for LoRaWAN events.
Events:
EV_JOINING
- OTAA join in progressEV_JOINED
- Successfully joined networkEV_TXCOMPLETE
- Transmission completeEV_RXCOMPLETE
- Downlink received
Downlink Handling:
case EV_TXCOMPLETE: if (LMIC.dataLen) { // Process downlink on FPort 1 uint8_t* payload = LMIC.frame + LMIC.dataBeg; uint16_t cmd = (payload[0] << 8) | payload[1]; // Handle command }
Data Structures
Section titled “Data Structures”rom_conf_t
Section titled “rom_conf_t”EEPROM configuration structure:
struct __attribute__((packed)) rom_conf_t { uint8_t MAGIC[4]; // "MFM\0" struct { uint8_t MSB; // Hardware version MSB uint8_t LSB; // Hardware version LSB } HW_VERSION; // Hardware/firmware version (2 bytes) uint8_t APP_EUI[8]; // LoRaWAN Application EUI uint8_t DEV_EUI[8]; // LoRaWAN Device EUI uint8_t APP_KEY[16]; // LoRaWAN Application Key uint16_t MEASUREMENT_INTERVAL; // Measurement interval (seconds, little-endian) uint8_t USE_TTN_FAIR_USE_POLICY; // Fair Use Policy (0=disabled, 1=enabled)};
Total Size: 41 bytes
Constants
Section titled “Constants”Command Codes
Section titled “Command Codes”#define CMD_PERFORM 0x10 // Trigger measurement#define CMD_READ 0x11 // Read measurement data
Downlink Commands
Section titled “Downlink Commands”#define CMD_SET_INTERVAL 0x10 // Update measurement interval#define CMD_SET_MODULE 0x11 // Update module configuration#define CMD_RESET 0xDEAD // Reset device
Limits
Section titled “Limits”#define MIN_INTERVAL 20 // Minimum interval (seconds)#define MAX_INTERVAL 4270 // Maximum interval (seconds)#define SENSOR_ADDRESS 0x36 // Default I²C address
Usage Examples
Section titled “Usage Examples”Complete Measurement Cycle
Section titled “Complete Measurement Cycle”// Power on sensorboard_sensor_power(true);delay(50); // Stabilization time
// Trigger measurementif (sensorPerform(SENSOR_ADDRESS) == 0) { delay(100); // Sensor processing time
// Read data int16_t data[8]; if (sensorRead(SENSOR_ADDRESS, data) == 0) { // Build LoRaWAN payload uint8_t payload[16]; for (int i = 0; i < 8; i++) { payload[i * 2] = (data[i] >> 8) & 0xFF; payload[i * 2 + 1] = data[i] & 0xFF; }
// Send via LoRaWAN LMIC_setTxData2(1, payload, sizeof(payload), 0); }}
// Power off sensorboard_sensor_power(false);
Processing Downlink
Section titled “Processing Downlink”// In onEvent(), case EV_TXCOMPLETE:if (LMIC.dataLen == 4 && LMIC.txrxFlags & TXRX_PORT) { uint8_t port = LMIC.frame[LMIC.dataBeg - 1];
if (port == 1) { // Command port uint8_t* data = LMIC.frame + LMIC.dataBeg; uint16_t cmd = (data[0] << 8) | data[1]; uint16_t value = (data[2] << 8) | data[3];
if (cmd == 0x10) { // Set interval if (value >= MIN_INTERVAL && value <= MAX_INTERVAL) { // Update configuration config.interval = value; // Save to EEPROM // ... } } }}
Next Steps
Section titled “Next Steps”- Firmware Architecture - System design
- Build System - Compilation details
- Development Guide - Practical examples