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
34 changes: 15 additions & 19 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,24 @@ jobs:
- name: Checkout code
uses: actions/checkout@v6

- name: Install Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '4.0'

- name: Install Build Tools and Ceedling
- name: Install Build Tools
run: |
sudo apt-get update
sudo apt-get install -y gcc cmake ninja-build gcovr
gem install ceedling
sudo apt-get install -y gcc cmake ninja-build
pip install gcovr

- name: Fetch Dependencies
run: cmake -B build
- name: Configure cmake and run builds
run: |
cmake -B build -S .
cmake --build build

- name: Run Tests
run: ceedling gcov:all
- name: Run Tests and create coverage
run: |
cmake --build build --target test
cmake --build build --target coverage

- name: Upload Coverage
uses: actions/upload-artifact@v7
- name: Render Coverage Summary in CI
if: always()
with:
name: code-coverage-report
path: build/ceedling/artifacts/gcov/gcovr/GcovCoverageResults.html
archive: false
retention-days: 7
run: |
echo "## Code Coverage Summary" >> $GITHUB_STEP_SUMMARY
gcovr -r . -e "tests/" -e "build/" --markdown >> $GITHUB_STEP_SUMMARY
107 changes: 74 additions & 33 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
cmake_minimum_required(VERSION 3.22)
enable_language(C)
project(CommonDrivers)
enable_language(C CXX)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

include(FetchContent)
Expand All @@ -13,14 +17,6 @@ FetchContent_Declare(bmi08
GIT_TAG master
)
FetchContent_MakeAvailable(bmi08)
add_library(bmi08 STATIC
${bmi08_SOURCE_DIR}/bmi08a.c
${bmi08_SOURCE_DIR}/bmi08g.c
${bmi08_SOURCE_DIR}/bmi08xa.c
${bmi08_SOURCE_DIR}/bmi088_mma.c
${bmi08_SOURCE_DIR}/bmi088_anymotiona.c
)
target_include_directories(bmi08 PUBLIC ${bmi08_SOURCE_DIR})

message(STATUS "Resolving bmp5 sensors api dependency...")
FetchContent_Declare(bmp5
Expand All @@ -29,8 +25,6 @@ FetchContent_Declare(bmp5
GIT_TAG master
)
FetchContent_MakeAvailable(bmp5)
add_library(bmp5 STATIC ${bmp5_SOURCE_DIR}/bmp5.c)
target_include_directories(bmp5 PUBLIC ${bmp5_SOURCE_DIR})

message(STATUS "Resolving littlefs dependency...")
FetchContent_Declare(littlefs
Expand All @@ -39,32 +33,79 @@ FetchContent_Declare(littlefs
GIT_TAG master
)
FetchContent_MakeAvailable(littlefs)
add_library(littlefs STATIC
${littlefs_SOURCE_DIR}/lfs.c
${littlefs_SOURCE_DIR}/lfs_util.c
)
target_include_directories(littlefs PUBLIC ${littlefs_SOURCE_DIR})

message(STATUS "Dependencies resolved, now creating library...")
add_library(common_drivers STATIC
"${CMAKE_CURRENT_SOURCE_DIR}/src/flash.c"
"${CMAKE_CURRENT_SOURCE_DIR}/src/flash/gd5f1gq5xe.c"
"${CMAKE_CURRENT_SOURCE_DIR}/src/sensors/bmp581.c"
"${CMAKE_CURRENT_SOURCE_DIR}/src/sensors/bmi088.c"
"${CMAKE_CURRENT_SOURCE_DIR}/src/sensors/CD-PA1616S.c"

message(STATUS "Resolving gtest dependency...")
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG v1.18.0
)
target_include_directories(common_drivers PUBLIC
"${CMAKE_CURRENT_SOURCE_DIR}/include"
"${CMAKE_CURRENT_SOURCE_DIR}/include/flash"
"${CMAKE_CURRENT_SOURCE_DIR}/include/sensors"
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)

message(STATUS "Resolving fff dependency...")
FetchContent_Declare(
fff
GIT_REPOSITORY https://github.com/meekrosoft/fff.git
GIT_TAG master
)

message(STATUS "Linking libary to dependencies...")
target_link_libraries(common_drivers PUBLIC bmi08 bmp5 littlefs)
add_library(common_drivers STATIC)
if(TARGET stm32cubemx)
message(STATUS "Compiling for target host (MCU), linking libraries...")

add_library(bmi08 STATIC
${bmi08_SOURCE_DIR}/bmi08a.c
${bmi08_SOURCE_DIR}/bmi08g.c
${bmi08_SOURCE_DIR}/bmi08xa.c
${bmi08_SOURCE_DIR}/bmi088_mma.c
${bmi08_SOURCE_DIR}/bmi088_anymotiona.c
)
target_include_directories(bmi08 PUBLIC ${bmi08_SOURCE_DIR})

add_library(bmp5 STATIC ${bmp5_SOURCE_DIR}/bmp5.c)
target_include_directories(bmp5 PUBLIC ${bmp5_SOURCE_DIR})

add_library(littlefs STATIC
${littlefs_SOURCE_DIR}/lfs.c
${littlefs_SOURCE_DIR}/lfs_util.c
)
target_include_directories(littlefs PUBLIC ${littlefs_SOURCE_DIR})

message(STATUS "Linking dependencies to library...")
target_link_libraries(common_drivers PUBLIC bmi08 bmp5 littlefs)

if(NOT TARGET stm32cubemx)
# Empty for now, will add stuff for tests later
else()
message(STATUS "Linking stm32 drivers to library....")
target_link_libraries(common_drivers PUBLIC stm32cubemx)
else()
enable_testing()
message(STATUS "Compiling for tests, linking gtest, fff, and mocks to library...")
FetchContent_MakeAvailable(googletest)
FetchContent_MakeAvailable(fff)

add_library(bmp5 INTERFACE)
target_include_directories(bmp5 INTERFACE ${bmp5_SOURCE_DIR})

add_library(littlefs INTERFACE)
target_include_directories(littlefs INTERFACE ${littlefs_SOURCE_DIR})

add_library(bmi08 INTERFACE)
target_include_directories(bmi08 INTERFACE ${bmi08_SOURCE_DIR})

message(STATUS "Linking mock dependencies to library...")
target_link_libraries(common_drivers PUBLIC bmp5 littlefs bmi08)

message(STATUS "Creating tests for library...")
add_compile_definitions(TEST)
add_subdirectory(tests)
endif()

message(STATUS "Adding source files and headers to library...")
add_subdirectory(include)
add_subdirectory(src)

add_custom_target(coverage
COMMAND mkdir -p coverage
COMMAND gcovr -r ${CMAKE_SOURCE_DIR} -e "${CMAKE_SOURCE_DIR}/tests/" -e "${CMAKE_BINARY_DIR}/" --html-details -o coverage/index.html .
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ To write a sensor, you must initialize a struct of the form

```c
struct sensor {
bool (*read)(void*, struct packet*);
bool (*read)(void*, Packet*);
void* ctx;
};
```
Expand Down
6 changes: 6 additions & 0 deletions include/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
target_include_directories(common_drivers PUBLIC
"."
"sensors"
"protocols"
"flash"
)
56 changes: 0 additions & 56 deletions include/defs.h

This file was deleted.

20 changes: 0 additions & 20 deletions include/flash.h

This file was deleted.

28 changes: 28 additions & 0 deletions include/flash/flash.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#ifndef FLASH_H
#define FLASH_H

#include "lfs.h"

#include <stdint.h>

namespace Platform {
class Flash {
protected:
bool is_ready = false;
struct lfs_config config;
lfs_t lfs;

public:
virtual ~Flash() = default;
virtual bool init() = 0;
uint32_t mount();
uint32_t unmount();
uint32_t bootcount(bool update);
uint32_t open(lfs_file_t* file, const char* filename);
uint32_t close(lfs_file_t* file);
bool append(lfs_file_t* file, const uint8_t* bytes, size_t size);
bool ready() const { return is_ready; };
Comment on lines +16 to +24

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good to add a quick brief as to what these functions do.

};
} // namespace Platform

#endif
16 changes: 13 additions & 3 deletions include/flash/gd5f1gq5xe.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,21 @@
#define GD5F1GQ5XE_H

#include "flash.h"
#include "defs.h"
#include "hal.h"
#include "protocol.h"

#include <stddef.h>
#include <stdbool.h>
#include <stddef.h>

namespace Platform {
class GD5F1GQ5XE final : public Flash {
private:
Protocol& protocol;

bool gd5f1gq5xe_init(struct flash *flash, struct handle_spi *spi);
public:
GD5F1GQ5XE(Protocol& protocol_);
bool init() override;
};
} // namespace Platform

#endif
16 changes: 16 additions & 0 deletions include/hal.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#ifndef HAL_H
#define HAL_H

#ifndef TEST
#ifdef USE_STM32_H7XX
#include "stm32h7xx_hal.h"
#elif USE_STM32_L4XX
#include "stm32l4xx_hal.h"
#else
#include "stm32f4xx_hal.h"
#endif
#else
#define HAL_Delay(...) (0)
#endif

#endif
30 changes: 30 additions & 0 deletions include/protocols/i2c.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#ifndef PROTOCOLS_I2C_H
#define PROTOCOLS_I2C_H

#include "protocol.h"

/// I2C tends to be register and address heavy. This really isn't really used
/// for command based sensors so the cmd buffer tends to just be the address
/// of the register to read from instead.
///
/// The AddressSize gets directly converted to I2C's equivalent. Note that
/// unlike qspi, I2C does not support addresses greater than two bytes.
/// We use the `mem` equivalents of I2C because "most" sensors seem to
/// to prefer the pattern of specifying an address to target, followed
/// by a write or read. The `mem` I2C functions do this in one step instead
/// of two. This contrasts with SPI where we are forced to do it in two.
namespace Platform {
class I2C final : public Protocol {
private:
I2C_HandleTypeDef* handle;
const uint32_t address;

public:
I2C(I2C_HandleTypeDef* handle_, uin32_t address_)
: Protocol{ProtocolType::I2C}, handle{handle_}, address{address_} {}
bool read(ConstSpan cmd, Span buffer, AddressSize size) override;
bool write(ConstSpan cmd, ConstSpan buffer, AddressSize size) override;
};
} // namespace Platform

#endif
Loading