Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build/
56 changes: 56 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# MakerPlane CAN-FIX Arduino Library

**Status:** Open Source — Experimental Amateur-Built Category
**License:** See COPYING
**Protocol:** CAN-FIX (CAN bus implementation of the Flight Information eXchange protocol)

---

## What This Is

This is an Arduino library that enables Arduino-based devices to participate in a **CAN-FIX avionics network**. CAN-FIX is an open-source protocol designed specifically for Experimental Amateur-Built (E-AB) aircraft to exchange flight data between avionics nodes in a vendor-neutral way.

With this library, Arduino hardware can:
- Read and write named flight data parameters (airspeed, altitude, heading, engine data, etc.) on the CAN bus
- Act as a sensor node, sending data from connected hardware into the avionics network
- Act as an actuator or display node, receiving and responding to parameter updates
- Interoperate with other CAN-FIX devices including FIX-Gateway, pyEfis, and custom electronics

## Protocol Background

**FIX** (Flight Information eXchange) is a family of open, Creative Commons-licensed specifications for aircraft avionics communication. **CAN-FIX** is the CAN bus implementation of FIX. It is designed to:

- Allow any builder to construct devices that communicate with other FIX-compatible hardware without licensing fees
- Provide a standard parameter namespace covering the full range of aircraft state (position, attitude, airspeed, engine data, control surfaces, systems status)
- Enable redundancy through multiple nodes publishing the same parameter type on separate identifiers

See the [canfix-spec](../canfix-spec) repository for the full protocol specification.

## Repository Contents

| File | Description |
|---|---|
| `canfix.h` | Library header — parameter definitions, message structures, node API |
| `canfix.cpp` | Library implementation |
| `examples/` | Example Arduino sketches demonstrating common use patterns |
| `keywords.txt` | Arduino IDE syntax highlighting keywords |

## Installation

Follow standard Arduino library installation:
1. Download or clone this repository
2. Copy the folder into your Arduino `libraries/` directory
3. Restart the Arduino IDE
4. Access the library under **Sketch → Include Library → CAN-FIX**

For detailed installation guidance see: http://arduino.cc/en/Guide/Libraries

## Hardware Requirements

- Any Arduino board with a CAN controller, or an Arduino paired with a CAN transceiver module (MCP2515-based shields are common in the MakerPlane ecosystem)
- CAN bus wiring per the CAN-FIX physical layer spec (120Ω termination at each end)

## Important Disclaimer

> **This library is experimental and is not suited for primary or backup flight/engine instrumentation or navigation. Use at your own risk.**
> For Experimental Amateur-Built aircraft use only. Not FAA-approved avionics software.
47 changes: 47 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
cmake_minimum_required(VERSION 3.12)
project(canfix_tests CXX)

set(CMAKE_CXX_STANDARD 14)

# ── GoogleTest via FetchContent ───────────────────────────────────────────────
include(FetchContent)
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG release-1.12.1
GIT_SHALLOW TRUE
)
# Prevent overriding the parent project's compiler/linker settings on Windows
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_GetProperties(googletest)
if(NOT googletest_POPULATED)
FetchContent_Populate(googletest)
add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR})
endif()

# ── canfix library (compiled with mock headers) ───────────────────────────────
add_library(canfix_lib STATIC
../canfix.cpp
mock_impl.cpp
)
target_include_directories(canfix_lib PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/mocks # provides can.h, EEPROM.h
${CMAKE_CURRENT_SOURCE_DIR}/.. # provides canfix.h
)

# ── Test executable ───────────────────────────────────────────────────────────
add_executable(canfix_tests
test_canfix.cpp
)
target_include_directories(canfix_tests PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/mocks
${CMAKE_CURRENT_SOURCE_DIR}/..
)
target_link_libraries(canfix_tests
canfix_lib
GTest::gtest_main
)

# ── CTest integration ─────────────────────────────────────────────────────────
include(GoogleTest)
gtest_discover_tests(canfix_tests)
8 changes: 8 additions & 0 deletions tests/mock_impl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* Global mock object instances — compiled once, linked with all test objects.
*/
#include "mocks/can.h"
#include "mocks/EEPROM.h"

MockCanState g_can;
EEPROMClass EEPROM;
28 changes: 28 additions & 0 deletions tests/mocks/EEPROM.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Mock EEPROM.h for unit testing canfix.cpp outside of the Arduino environment.
* Simulates a 512-byte EEPROM with read/write and the bitRead/bitSet/bitClear macros.
*/
#pragma once
#include <cstdint>
#include <cstring>

#define EEPROM_SIZE 512

struct EEPROMClass {
uint8_t data[EEPROM_SIZE];

EEPROMClass() { memset(data, 0xFF, sizeof(data)); }

uint8_t read(int addr) { return data[addr]; }
void write(int addr, uint8_t v) { data[addr] = v; }

void reset() { memset(data, 0xFF, sizeof(data)); }
};

extern EEPROMClass EEPROM;

// Arduino bit manipulation macros
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
#define bitWrite(value, bit, bv) ((bv) ? bitSet(value, bit) : bitClear(value, bit))
57 changes: 57 additions & 0 deletions tests/mocks/can.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Mock can.h for unit testing canfix.cpp outside of the Arduino environment.
* Records last frame written so tests can inspect it.
*/
#pragma once
#include <cstdint>

typedef uint8_t byte;
typedef uint16_t word;

struct CanFrame {
uint16_t id;
uint8_t eid;
uint8_t data[8];
uint8_t length;
};

// Commands and modes used by canfix.cpp
#define CMD_RESET 0
#define MODE_CONFIG 1
#define MODE_NORMAL 2

// Recorded state for test inspection
struct MockCanState {
CanFrame last_written;
int write_count;
uint8_t rx_status; // returned by getRxStatus()
CanFrame rx_frame[2]; // frame available for reading

MockCanState() : write_count(0), rx_status(0) {
last_written = {};
rx_frame[0] = {};
rx_frame[1] = {};
}
};

extern MockCanState g_can;

class CAN {
public:
explicit CAN(uint8_t pin) { (void)pin; }
void sendCommand(uint8_t cmd) { (void)cmd; }
void setBitRate(int rate) { (void)rate; }
void setMode(uint8_t mode) { (void)mode; }

uint8_t writeFrame(CanFrame frame) {
g_can.last_written = frame;
g_can.write_count++;
return 0; // success
}

uint8_t getRxStatus() { return g_can.rx_status; }

CanFrame readFrame(uint8_t buffer) {
return g_can.rx_frame[buffer];
}
};
Loading