This commit is contained in:
Ken Van Hoeylandt 2026-01-17 20:47:57 +01:00
parent 1f843750cd
commit 5699d05675
53 changed files with 386 additions and 216 deletions

View File

@ -124,7 +124,7 @@ def write_device(file, device: Device, bindings: list[Binding], verbose: bool):
file.write(f"\t.config = &{config_instance_name},\n") file.write(f"\t.config = &{config_instance_name},\n")
file.write(f"\t.api = &{api_instance_name},\n") file.write(f"\t.api = &{api_instance_name},\n")
file.write("\t.state = { .init_result = 0, .initialized = false },\n") file.write("\t.state = { .init_result = 0, .initialized = false },\n")
file.write("\t.data = nullptr,\n") file.write("\t.data = NULL,\n")
file.write("\t.operations = { ") file.write("\t.operations = { ")
file.write(f".init = {init_function_name}, ") file.write(f".init = {init_function_name}, ")
file.write(f".deinit = {deinit_function_name}") file.write(f".deinit = {deinit_function_name}")
@ -157,7 +157,7 @@ def write_device_list(file, devices: list[Device]):
for device in devices: for device in devices:
write_device_list_entry(file, device) write_device_list_entry(file, device)
# Terminator # Terminator
file.write(f"\tnullptr\n") file.write(f"\tNULL\n")
file.write("};\n\n") file.write("};\n\n")
def generate_devicetree_c(filename: str, items: list[object], bindings: list[Binding], verbose: bool): def generate_devicetree_c(filename: str, items: list[object], bindings: list[Binding], verbose: bool):
@ -184,14 +184,14 @@ def generate_devicetree_h(filename: str):
with open(filename, "w") as file: with open(filename, "w") as file:
file.write(dedent('''\ file.write(dedent('''\
#pragma once #pragma once
#include <device.h> #include <tactility/device.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/** /**
* @return an array of device* where the last item in the array is nullptr * @return an array of device* where the last item in the array is NULL
*/ */
struct device** devices_builtin_get(); struct device** devices_builtin_get();

View File

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.20) cmake_minimum_required(VERSION 3.20)
set(CMAKE_CXX_STANDARD 26) set(CMAKE_CXX_STANDARD 23)
set(CMAKE_ASM_COMPILE_OBJECT "${CMAKE_CXX_COMPILER_TARGET}") set(CMAKE_ASM_COMPILE_OBJECT "${CMAKE_CXX_COMPILER_TARGET}")
include("Buildscripts/logo.cmake") include("Buildscripts/logo.cmake")
@ -32,6 +32,7 @@ if (DEFINED ENV{ESP_IDF_VERSION})
"Firmware" "Firmware"
"Devices/${TACTILITY_DEVICE_PROJECT}" "Devices/${TACTILITY_DEVICE_PROJECT}"
"Drivers" "Drivers"
"core"
"Tactility" "Tactility"
"TactilityC" "TactilityC"
"TactilityCore" "TactilityCore"
@ -80,8 +81,7 @@ if (NOT DEFINED ENV{ESP_IDF_VERSION})
add_subdirectory(Libraries/QRCode) add_subdirectory(Libraries/QRCode)
add_subdirectory(Libraries/minitar) add_subdirectory(Libraries/minitar)
add_subdirectory(Libraries/minmea) add_subdirectory(Libraries/minmea)
add_subdirectory(Drivers/drivers-abstract) add_subdirectory(core)
add_subdirectory(Drivers/drivers-core)
# FreeRTOS # FreeRTOS
set(FREERTOS_CONFIG_FILE_DIRECTORY ${PROJECT_SOURCE_DIR}/Devices/simulator/Source CACHE STRING "") set(FREERTOS_CONFIG_FILE_DIRECTORY ${PROJECT_SOURCE_DIR}/Devices/simulator/Source CACHE STRING "")

View File

@ -1,12 +1,7 @@
file(GLOB_RECURSE SOURCE_FILES Source/*.c*) file(GLOB_RECURSE SOURCE_FILES Source/*.c*)
set(CMAKE_CXX_STANDARD 26)
set(CMAKE_C_STANDARD 23)
idf_component_register( idf_component_register(
SRCS ${SOURCE_FILES} SRCS ${SOURCE_FILES}
INCLUDE_DIRS "Source" INCLUDE_DIRS "Source"
REQUIRES Tactility esp_lcd ST7796 BQ25896 BQ27220 TCA8418 DRV2605 PwmBacklight driver esp_adc drivers-esp REQUIRES Tactility esp_lcd ST7796 BQ25896 BQ27220 TCA8418 DRV2605 PwmBacklight driver esp_adc drivers-esp
) )
target_compile_options(${COMPONENT_LIB} PRIVATE -std=c23)

View File

@ -4,8 +4,8 @@
extern "C" { extern "C" {
#endif #endif
#include <device.h> #include <tactility/device.h>
#include <drivers/root.h> #include <tactility/drivers/root.h>
// Inherit base config // Inherit base config
#define tlora_pager_config root_config #define tlora_pager_config root_config

View File

@ -1,8 +1,8 @@
/dts-v1/; /dts-v1/;
#include <drivers/tlora_pager.h> #include <drivers/tlora_pager.h>
#include <drivers-esp/esp32_gpio.h> #include <tactility/drivers/esp32_gpio.h>
#include <drivers-esp/esp32_i2c.h> #include <tactility/drivers/esp32_i2c.h>
/ { / {
compatible = "lilygo,tlora-pager"; compatible = "lilygo,tlora-pager";
@ -18,5 +18,6 @@
clock-frequency = <100000>; clock-frequency = <100000>;
pin-sda = <&gpio0 3 GPIO_ACTIVE_HIGH>; pin-sda = <&gpio0 3 GPIO_ACTIVE_HIGH>;
pin-scl = <&gpio0 2 GPIO_ACTIVE_HIGH>; pin-scl = <&gpio0 2 GPIO_ACTIVE_HIGH>;
port = <I2C_NUM_0>;
}; };
}; };

View File

@ -1,4 +1,4 @@
dependencies: dependencies:
- Drivers/drivers-abstract - core
bindings: ./ bindings: ./
dts: simulator.dts dts: simulator.dts

View File

@ -1,7 +1,7 @@
/dts-v1/; /dts-v1/;
#include <device.h> #include <tactility/device.h>
#include <drivers/root.h> #include <tactility/drivers/root.h>
/ { / {
model = "Simulator"; model = "Simulator";

View File

@ -1,23 +0,0 @@
cmake_minimum_required(VERSION 3.20)
file(GLOB_RECURSE SOURCES "source/*.c**")
if (DEFINED ENV{ESP_IDF_VERSION})
idf_component_register(
SRCS ${SOURCES}
INCLUDE_DIRS "include/"
REQUIRES drivers-core
)
target_compile_options(${COMPONENT_LIB} PRIVATE -std=c23)
else ()
add_library(drivers-abstract OBJECT)
target_sources(drivers-abstract PRIVATE ${SOURCES})
target_include_directories(drivers-abstract PUBLIC include/)
target_link_libraries(drivers-abstract PUBLIC drivers-core)
target_compile_options(drivers-abstract PRIVATE -std=c23)
endif ()

View File

@ -1,23 +0,0 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include "gpio.h"
struct i2c_controller_config {
uint32_t clock_frequency;
struct gpio_pin_config pin_sda;
struct gpio_pin_config pin_scl;
};
struct i2c_controller_api {
bool (*master_read)(struct device* dev, uint8_t address, uint8_t* data, size_t dataSize); // TODO: add timeout
bool (*master_write)(struct device* dev, uint8_t address, const uint8_t* data, uint16_t dataSize); // TODO: add timeout
};
#ifdef __cplusplus
}
#endif

View File

@ -1,5 +0,0 @@
#include "drivers/i2c_controller.h"
#if !defined(CONFIG_I2C_CONTROLLER_DEVICE_COUNT_LIMIT)
#define CONFIG_I2C_CONTROLLER_DEVICE_COUNT_LIMIT 4
#endif

View File

@ -1,21 +0,0 @@
cmake_minimum_required(VERSION 3.20)
file(GLOB_RECURSE SOURCES "source/*.c**")
if (DEFINED ENV{ESP_IDF_VERSION})
idf_component_register(
SRCS ${SOURCES}
INCLUDE_DIRS "include/"
)
target_compile_options(${COMPONENT_LIB} PRIVATE -std=c23)
else ()
add_library(drivers-core OBJECT)
target_sources(drivers-core PRIVATE ${SOURCES})
target_include_directories(drivers-core PUBLIC include/)
target_compile_options(drivers-core PRIVATE -std=c23)
endif ()

View File

@ -7,17 +7,14 @@ if (DEFINED ENV{ESP_IDF_VERSION})
idf_component_register( idf_component_register(
SRCS ${SOURCES} SRCS ${SOURCES}
INCLUDE_DIRS "include/" INCLUDE_DIRS "include/"
REQUIRES drivers-abstract driver REQUIRES core driver
) )
target_compile_options(${COMPONENT_LIB} PRIVATE -std=c23)
else () else ()
add_library(drivers-esp OBJECT) add_library(drivers-esp OBJECT)
target_sources(drivers-esp PRIVATE ${SOURCES}) target_sources(drivers-esp PRIVATE ${SOURCES})
target_include_directories(drivers-esp PUBLIC include/) target_include_directories(drivers-esp PUBLIC include/)
target_link_libraries(drivers-esp PUBLIC drivers-abstract) target_link_libraries(drivers-esp PUBLIC core)
target_compile_options(drivers-esp PRIVATE -std=c23)
endif () endif ()

View File

@ -1,3 +1,10 @@
description: ESP32 GPIO Controller description: ESP32 GPIO Controller
include: ["i2c-controller.yaml"] include: ["i2c-controller.yaml"]
properties:
port:
type: int
description: |
The port number, defined by i2c_port_t.
Depending on the hardware, these values are available: I2C_NUM_0, I2C_NUM_1, LP_I2C_NUM_0

View File

@ -1,3 +1,3 @@
dependencies: dependencies:
- Drivers/drivers-abstract - core
bindings: bindings bindings: bindings

View File

@ -1,22 +0,0 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <device.h>
#include <drivers/i2c_controller.h>
// Inherit base config
#define esp32_i2c_config i2c_controller_config
// Inherit base API
#define esp32_i2c_api i2c_controller_api
int esp32_i2c_init(const struct device* device);
int esp32_i2c_deinit(const struct device* device);
#ifdef __cplusplus
}
#endif

View File

@ -4,10 +4,13 @@
extern "C" { extern "C" {
#endif #endif
#include <device.h> #include <tactility/device.h>
#include <drivers/gpio_controller.h> #include <tactility/drivers/gpio_controller.h>
struct esp32_gpio_config {
uint8_t gpio_count;
};
#define esp32_gpio_config gpio_controller_config
#define esp32_gpio_api gpio_controller_api #define esp32_gpio_api gpio_controller_api
int esp32_gpio_init(const struct device* device); int esp32_gpio_init(const struct device* device);

View File

@ -0,0 +1,28 @@
#pragma once
#include <hal/i2c_types.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <tactility/device.h>
#include <tactility/drivers/i2c_controller.h>
struct esp32_i2c_config {
uint32_t clock_frequency;
struct gpio_pin_config pin_sda;
struct gpio_pin_config pin_scl;
const i2c_port_t port;
};
// Inherit base API
#define esp32_i2c_api i2c_controller_api
int esp32_i2c_init(const struct device* device);
int esp32_i2c_deinit(const struct device* device);
#ifdef __cplusplus
}
#endif

View File

@ -1,12 +1,13 @@
#include <drivers-esp/esp32_gpio.h> #include <tactility/drivers/esp32_gpio.h>
#include <drivers/gpio_controller.h> #include <tactility/drivers/gpio_controller.h>
#include <drivers/gpio.h>
// ESP
#include <esp_log.h>
#include <driver/gpio.h> #include <driver/gpio.h>
#include <esp_log.h>
#define TAG "esp32_gpio" #define TAG "esp32_gpio"
#define GET_CONFIG(dev) ((struct esp32_gpio_config*)dev->config)
static bool set_level(const struct device* dev, gpio_pin_t pin, bool high) { static bool set_level(const struct device* dev, gpio_pin_t pin, bool high) {
return gpio_set_level(pin, high) == ESP_OK; return gpio_set_level(pin, high) == ESP_OK;
} }
@ -17,16 +18,70 @@ static bool get_level(const struct device* dev, gpio_pin_t pin, bool* high) {
} }
static bool set_options(const struct device* dev, gpio_pin_t pin, gpio_flags_t options) { static bool set_options(const struct device* dev, gpio_pin_t pin, gpio_flags_t options) {
// TODO const struct esp32_gpio_config* config = GET_CONFIG(dev);
// gpio_set_direction()
// gpio_set_pull_mode() if (pin >= config->gpio_count) {
return true; return false;
}
gpio_mode_t mode;
if (options & (GPIO_DIRECTION_INPUT_OUTPUT)) {
mode = GPIO_MODE_INPUT_OUTPUT;
} else if (options & GPIO_DIRECTION_INPUT) {
mode = GPIO_MODE_INPUT;
} else if (options & GPIO_DIRECTION_OUTPUT) {
mode = GPIO_MODE_OUTPUT;
} else {
assert(false);
}
const gpio_config_t esp_config = {
.pin_bit_mask = 1UL << pin,
.mode = mode,
.pull_up_en = (options & GPIO_PULL_UP) ? GPIO_PULLUP_ENABLE : GPIO_PULLUP_DISABLE,
.pull_down_en = (options & GPIO_PULL_DOWN) ? GPIO_PULLDOWN_ENABLE : GPIO_PULLDOWN_DISABLE,
.intr_type = GPIO_INTERRUPT_FROM_OPTIONS(options),
#if SOC_GPIO_SUPPORT_PIN_HYS_FILTER
.hys_ctrl_mode = GPIO_HYS_CTRL_EFUSE
#endif
};
return gpio_config(&esp_config) == ESP_OK;
} }
static bool get_options(const struct device* dev, gpio_pin_t pin, gpio_flags_t* options) { static bool get_options(const struct device* dev, gpio_pin_t pin, gpio_flags_t* options) {
// gpio_get_direction() gpio_io_config_t esp_config;
// gpio_get_pull_mode() if (gpio_get_io_config((gpio_num_t)pin, &esp_config) != ESP_OK) {
// TODO return false;
}
gpio_flags_t output = 0;
if (esp_config.pu) {
output |= GPIO_PULL_UP;
}
if (esp_config.pd) {
output |= GPIO_PULL_DOWN;
}
if (esp_config.ie) {
output |= GPIO_DIRECTION_INPUT;
}
if (esp_config.oe) {
output |= GPIO_DIRECTION_OUTPUT;
}
if (esp_config.oe) {
output |= GPIO_DIRECTION_OUTPUT;
}
if (esp_config.oe_inv) {
output |= GPIO_ACTIVE_LOW;
}
*options = output;
return true; return true;
} }

View File

@ -1,23 +1,39 @@
#include "drivers-esp/esp32_i2c.h" #include "tactility/drivers/esp32_i2c.h"
#include <drivers/i2c_controller.h>
#include "driver/i2c.h"
#include <esp_log.h> #include <esp_log.h>
#include <stdio.h> #include <tactility/drivers/i2c_controller.h>
#define TAG "esp32_i2c" #define TAG "esp32_i2c"
#define GET_CONFIG(dev) static_cast<struct i2c_esp_config>(dev->config) #define GET_CONFIG(dev) ((struct esp32_i2c_config*)dev->config)
static bool master_read(struct device* dev, uint8_t address, uint8_t* data, size_t dataSize) { static bool read(struct device* dev, uint8_t address, uint8_t* data, size_t dataSize, TickType_t timeout) {
return true; // TODO: mutex
esp_err_t result = i2c_master_read_from_device(GET_CONFIG(dev)->port, address, data, dataSize, timeout);
ESP_ERROR_CHECK_WITHOUT_ABORT(result);
return result == ESP_OK;
} }
static bool master_write(struct device* dev, uint8_t address, const uint8_t* data, uint16_t dataSize) { static bool write(struct device* dev, uint8_t address, const uint8_t* data, uint16_t dataSize, TickType_t timeout) {
return true; // TODO: mutex
esp_err_t result = i2c_master_write_to_device(GET_CONFIG(dev)->port, address, data, dataSize, timeout);
ESP_ERROR_CHECK_WITHOUT_ABORT(result);
return result == ESP_OK;
}
static bool write_read(struct device* dev, uint8_t address, const uint8_t* write_data, size_t write_data_size, uint8_t* read_data, size_t read_data_size, TickType_t timeout) {
// TODO: mutex
esp_err_t result = i2c_master_write_read_device(GET_CONFIG(dev)->port, address, write_data, write_data_size, read_data, read_data_size, timeout);
ESP_ERROR_CHECK_WITHOUT_ABORT(result);
return result == ESP_OK;
} }
const struct esp32_i2c_api esp32_i2c_api_instance = { const struct esp32_i2c_api esp32_i2c_api_instance = {
.master_read = master_read, .read = read,
.master_write = master_write .write = write,
.write_read = write_read
}; };
int esp32_i2c_init(const struct device* device) { int esp32_i2c_init(const struct device* device) {

View File

@ -1,8 +1,5 @@
cmake_minimum_required(VERSION 3.20) cmake_minimum_required(VERSION 3.20)
set(CMAKE_CXX_STANDARD 26)
set(CMAKE_C_STANDARD 23)
file(GLOB_RECURSE SOURCE_FILES "Source/*.c*") file(GLOB_RECURSE SOURCE_FILES "Source/*.c*")
# Determine device identifier and project location # Determine device identifier and project location
@ -25,9 +22,8 @@ if (DEFINED ENV{ESP_IDF_VERSION})
idf_component_register( idf_component_register(
SRCS ${SOURCE_FILES} SRCS ${SOURCE_FILES}
REQUIRES ${DEVICE_COMPONENTS} REQUIRES ${DEVICE_COMPONENTS}
REQUIRES Tactility TactilityC drivers-core drivers-abstract drivers-esp ${TACTILITY_DEVICE_PROJECT} REQUIRES Tactility TactilityC core drivers-esp ${TACTILITY_DEVICE_PROJECT}
) )
target_compile_options(${COMPONENT_LIB} PRIVATE -std=c23)
else () else ()
@ -38,12 +34,10 @@ else ()
PRIVATE TactilityFreeRtos PRIVATE TactilityFreeRtos
PRIVATE Simulator PRIVATE Simulator
PRIVATE SDL2::SDL2-static SDL2-static PRIVATE SDL2::SDL2-static SDL2-static
PRIVATE drivers-abstract PRIVATE core
PRIVATE drivers-core
) )
target_include_directories(FirmwareSim PRIVATE "${CMAKE_SOURCE_DIR}/Firmware/Generated") target_include_directories(FirmwareSim PRIVATE "${CMAKE_SOURCE_DIR}/Firmware/Generated")
target_compile_options(FirmwareSim PRIVATE -std=c++23)
add_definitions(-D_Nullable=) add_definitions(-D_Nullable=)
add_definitions(-D_Nonnull=) add_definitions(-D_Nonnull=)

View File

@ -1,9 +1,5 @@
cmake_minimum_required(VERSION 3.20) cmake_minimum_required(VERSION 3.20)
set(CMAKE_CXX_STANDARD 26)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
if (DEFINED ENV{ESP_IDF_VERSION}) if (DEFINED ENV{ESP_IDF_VERSION})
idf_component_register( idf_component_register(
SRC_DIRS "Source/" SRC_DIRS "Source/"

View File

@ -1,9 +1,5 @@
cmake_minimum_required(VERSION 3.20) cmake_minimum_required(VERSION 3.20)
set(CMAKE_CXX_STANDARD 26)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
if (DEFINED ENV{ESP_IDF_VERSION}) if (DEFINED ENV{ESP_IDF_VERSION})
idf_component_register( idf_component_register(
SRC_DIRS "Source/" SRC_DIRS "Source/"

View File

@ -1,12 +1,10 @@
cmake_minimum_required(VERSION 3.20) cmake_minimum_required(VERSION 3.20)
set(CMAKE_CXX_STANDARD 26)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if (DEFINED ENV{ESP_IDF_VERSION}) if (DEFINED ENV{ESP_IDF_VERSION})
file(GLOB_RECURSE SOURCE_FILES Source/*.c*) file(GLOB_RECURSE SOURCE_FILES Source/*.c*)
list(APPEND REQUIRES_LIST list(APPEND REQUIRES_LIST
core
TactilityCore TactilityCore
TactilityFreeRtos TactilityFreeRtos
lvgl lvgl
@ -27,8 +25,6 @@ if (DEFINED ENV{ESP_IDF_VERSION})
vfs vfs
fatfs fatfs
lwip lwip
drivers-abstract
drivers-core
) )
if ("${IDF_TARGET}" STREQUAL "esp32s3") if ("${IDF_TARGET}" STREQUAL "esp32s3")
@ -81,8 +77,7 @@ else()
PUBLIC lv_screenshot PUBLIC lv_screenshot
PUBLIC minmea PUBLIC minmea
PUBLIC minitar PUBLIC minitar
PUBLIC drivers-abstract PUBLIC core
PUBLIC drivers-core
) )
endif() endif()

View File

@ -4,7 +4,8 @@
#include <Tactility/app/AppManifest.h> #include <Tactility/app/AppManifest.h>
#include <Tactility/hal/Configuration.h> #include <Tactility/hal/Configuration.h>
#include <Tactility/service/ServiceManifest.h> #include <Tactility/service/ServiceManifest.h>
#include <device.h>
#include <tactility/device.h>
namespace tt { namespace tt {

View File

@ -1,8 +1,5 @@
cmake_minimum_required(VERSION 3.20) cmake_minimum_required(VERSION 3.20)
set(CMAKE_CXX_STANDARD 26)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if (DEFINED ENV{ESP_IDF_VERSION}) if (DEFINED ENV{ESP_IDF_VERSION})
file(GLOB_RECURSE SOURCE_FILES Source/*.c*) file(GLOB_RECURSE SOURCE_FILES Source/*.c*)

View File

@ -1,8 +1,5 @@
cmake_minimum_required(VERSION 3.20) cmake_minimum_required(VERSION 3.20)
set(CMAKE_CXX_STANDARD 26)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if (DEFINED ENV{ESP_IDF_VERSION}) if (DEFINED ENV{ESP_IDF_VERSION})
file(GLOB_RECURSE SOURCE_FILES Source/*.c*) file(GLOB_RECURSE SOURCE_FILES Source/*.c*)

View File

@ -1,8 +1,5 @@
cmake_minimum_required(VERSION 3.20) cmake_minimum_required(VERSION 3.20)
set(CMAKE_CXX_STANDARD 26)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if (DEFINED ENV{ESP_IDF_VERSION}) if (DEFINED ENV{ESP_IDF_VERSION})
idf_component_register( idf_component_register(

View File

@ -1,3 +1,5 @@
#pragma once
#ifdef ESP_PLATFORM #ifdef ESP_PLATFORM
#include <freertos/FreeRTOS.h> #include <freertos/FreeRTOS.h>
#include <freertos/queue.h> #include <freertos/queue.h>

18
core/CMakeLists.txt Normal file
View File

@ -0,0 +1,18 @@
cmake_minimum_required(VERSION 3.20)
file(GLOB_RECURSE SOURCES "source/*.c**")
if (DEFINED ENV{ESP_IDF_VERSION})
idf_component_register(
SRCS ${SOURCES}
INCLUDE_DIRS "include/"
)
else ()
add_library(core OBJECT ${SOURCES})
target_include_directories(core PUBLIC include/)
target_link_libraries(core PUBLIC freertos_kernel)
endif ()

View File

@ -6,6 +6,7 @@ extern "C" {
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include <stdbool.h>
struct device; struct device;

View File

@ -4,23 +4,33 @@
extern "C" { extern "C" {
#endif #endif
#include <device.h> #include <tactility/device.h>
#define GPIO_OPTIONS_MASK 0x1f #define GPIO_OPTIONS_MASK 0x1f
#define GPIO_ACTIVE_HIGH (0 << 0) #define GPIO_ACTIVE_HIGH (0 << 0)
#define GPIO_ACTIVE_LOW (1 << 0) #define GPIO_ACTIVE_LOW (1 << 0)
#define GPIO_UNIDIRECTIONAL (0 << 1) #define GPIO_DIRECTION_INPUT (1 << 1)
#define GPIO_BIDIRECTIONAL (1 << 1) #define GPIO_DIRECTION_OUTPUT (1 << 2)
#define GPIO_DIRECTION_INPUT_OUTPUT (GPIO_DIRECTION_INPUT | GPIO_DIRECTION_OUTPUT)
#define GPIO_OPEN_DRAIN (GPIO_UNIDIRECTIONAL | (0 << 2))
#define GPIO_OPEN_SOURCE (GPIO_UNIDIRECTIONAL | (1 << 2))
#define GPIO_PULL_UP (0 << 3) #define GPIO_PULL_UP (0 << 3)
#define GPIO_PULL_DOWN (1 << 4) #define GPIO_PULL_DOWN (1 << 4)
#define GPIO_INTERRUPT_WAKE_UP (1 << 5) #define GPIO_INTERRUPT_BITMASK (0b111 << 5) // 3 bits to hold the values [0, 5]
#define GPIO_INTERRUPT_FROM_OPTIONS(options) (gpio_interrupt_type_t)((options & GPIO_INTERRUPT_BITMASK) >> 5)
#define GPIO_INTERRUPT_TO_OPTIONS(options, interrupt) (options | (interrupt << 5))
typedef enum {
GPIO_INTERRUPT_DISABLE = 0,
GPIO_INTERRUPT_POS_EDGE = 1,
GPIO_INTERRUPT_NEG_EDGE = 2,
GPIO_INTERRUPT_ANY_EDGE = 3,
GPIO_INTERRUPT_LOW_LEVEL = 4,
GPIO_INTERRUPT_HIGH_LEVEL = 5,
GPIO__MAX,
} gpio_interrupt_type_t;
/** /**
* @brief Provides a type to hold a GPIO pin index. * @brief Provides a type to hold a GPIO pin index.

View File

@ -4,13 +4,9 @@
extern "C" { extern "C" {
#endif #endif
#include <stdint.h> #include <stdbool.h>
#include "gpio.h" #include "gpio.h"
struct gpio_controller_config {
uint8_t gpio_count;
};
struct gpio_controller_api { struct gpio_controller_api {
bool (*set_level)(const struct device*, gpio_pin_t pin, bool high); bool (*set_level)(const struct device*, gpio_pin_t pin, bool high);
bool (*get_level)(const struct device*, gpio_pin_t pin, bool* high); bool (*get_level)(const struct device*, gpio_pin_t pin, bool* high);
@ -18,9 +14,6 @@ struct gpio_controller_api {
bool (*get_options)(const struct device*, gpio_pin_t pin, gpio_flags_t* options); bool (*get_options)(const struct device*, gpio_pin_t pin, gpio_flags_t* options);
}; };
#define GPIO_API(dev) ((struct gpio_controller_api*)dev->api)
#define GPIO_CONFIG(dev) ((struct gpio_controller_config*)dev->config)
bool gpio_controller_set_level(const struct device* dev, gpio_pin_t pin, bool high); bool gpio_controller_set_level(const struct device* dev, gpio_pin_t pin, bool high);
bool gpio_controller_get_level(const struct device* dev, gpio_pin_t pin, bool* high); bool gpio_controller_get_level(const struct device* dev, gpio_pin_t pin, bool* high);
bool gpio_controller_set_options(const struct device* dev, gpio_pin_t pin, gpio_flags_t options); bool gpio_controller_set_options(const struct device* dev, gpio_pin_t pin, gpio_flags_t options);

View File

@ -0,0 +1,26 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
#include <tactility/freertos/freertos.h>
#include "gpio.h"
struct i2c_controller_api {
bool (*read)(struct device* dev, uint8_t address, uint8_t* data, size_t dataSize, TickType_t timeout);
bool (*write)(struct device* dev, uint8_t address, const uint8_t* data, uint16_t dataSize, TickType_t timeout);
bool (*write_read)(struct device* dev, uint8_t address, const uint8_t* write_data, size_t write_data_size, uint8_t* read_data, size_t read_data_size, TickType_t timeout);
};
bool i2c_controller_read(struct device* dev, uint8_t address, uint8_t* data, size_t dataSize, TickType_t timeout);
bool i2c_controller_write(struct device* dev, uint8_t address, const uint8_t* data, uint16_t dataSize, TickType_t timeout);
bool i2c_controller_write_read(struct device* dev, uint8_t address, const uint8_t* write_data, size_t write_data_size, uint8_t* read_data, size_t read_data_size, TickType_t timeout);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,3 @@
Compatibility include files for FreeRTOS.
Custom FreeRTOS from ESP-IDF prefixes paths with "freertos/",
but this isn't the normal behaviour for the regular FreeRTOS project.

View File

@ -0,0 +1,10 @@
#pragma once
#ifdef ESP_PLATFORM
#include <freertos/FreeRTOS.h>
#include <freertos/event_groups.h>
#else
#include <FreeRTOS.h>
#include <event_groups.h>
#endif

View File

@ -0,0 +1,7 @@
#pragma once
#ifdef ESP_PLATFORM
#include <freertos/FreeRTOS.h>
#else
#include <FreeRTOS.h>
#endif

View File

@ -0,0 +1,7 @@
#pragma once
#include "freertos.h"
#ifndef ESP_PLATFORM
#define xPortInIsrContext(x) (false)
#endif

View File

@ -0,0 +1,10 @@
#pragma once
#ifdef ESP_PLATFORM
#include <freertos/FreeRTOS.h>
#include <freertos/queue.h>
#else
#include <FreeRTOS.h>
#include <queue.h>
#endif

View File

@ -0,0 +1,19 @@
#pragma once
#ifdef ESP_PLATFORM
#include <freertos/FreeRTOS.h>
#include <freertos/semphr.h>
#else
#include <FreeRTOS.h>
#include <semphr.h>
#endif
#include <assert.h>
struct SemaphoreHandleDeleter {
static void operator()(QueueHandle_t handleToDelete) {
assert(xPortInIsrContext() == pdFALSE);
vSemaphoreDelete(handleToDelete);
}
};

View File

@ -0,0 +1,10 @@
#pragma once
#ifdef ESP_PLATFORM
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#else
#include <FreeRTOS.h>
#include <task.h>
#endif

View File

@ -0,0 +1,9 @@
#pragma once
#ifdef ESP_PLATFORM
#include <freertos/FreeRTOS.h>
#include <freertos/timers.h>
#else
#include <FreeRTOS.h>
#include <timers.h>
#endif

View File

@ -0,0 +1,25 @@
#pragma once
#ifdef ESP_PLATFORM
#include <esp_log.h>
#endif
#ifndef ESP_PLATFORM
void log_generic(const char* tag, const char* format, ...);
#define LOG_E(x, ...) log(x, ##__VA_ARGS__)
#define LOG_W(x, ...) log(x, ##__VA_ARGS__)
#define LOG_I(x, ...) log(x, ##__VA_ARGS__)
#define LOG_D(x, ...) log(x, ##__VA_ARGS__)
#define LOG_V(x, ...) log(x, ##__VA_ARGS__)
#else
#define LOG_E(x, ...) ESP_LOGD(x, ##__VA_ARGS__)
#define LOG_W(x, ...) ESP_LOGW(x, ##__VA_ARGS__)
#define LOG_I(x, ...) ESP_LOGI(x, ##__VA_ARGS__)
#define LOG_D(x, ...) ESP_LOGD(x, ##__VA_ARGS__)
#define LOG_V(x, ...) ESP_LOGV(x, ##__VA_ARGS__)
#endif

View File

@ -1,25 +1,27 @@
#include "device.h" #include <tactility/device.h>
#include <tactility/log.h>
#include <assert.h> #include <assert.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#define CONFIG_DEVICE_INDEX_SIZE 64 #define CONFIG_DEVICE_INDEX_SIZE 64
#define TAG "device"
// TODO: Automatically increase allocated size // TODO: Automatically increase allocated size
static const struct device* device_index[CONFIG_DEVICE_INDEX_SIZE ] = { static const struct device* device_index[CONFIG_DEVICE_INDEX_SIZE ] = {
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
}; };
uint8_t device_init(struct device* const dev) { uint8_t device_init(struct device* const dev) {
assert(dev != nullptr); assert(dev != NULL);
printf("device_init: %s\n", dev->name); LOG_I(TAG, "init %s", dev->name);
if (!dev->state.initialized) { if (!dev->state.initialized) {
if (dev->operations.init == nullptr) { if (dev->operations.init == NULL) {
dev->state.initialized = true; dev->state.initialized = true;
dev->state.init_result = 0U; dev->state.init_result = 0U;
} else { } else {
@ -32,10 +34,10 @@ uint8_t device_init(struct device* const dev) {
} }
bool device_init_all(struct device** const device_array) { bool device_init_all(struct device** const device_array) {
assert(device_array != nullptr); assert(device_array != NULL);
struct device** current_device = device_array; struct device** current_device = device_array;
bool all_succeeded = true; bool all_succeeded = true;
while (*current_device != nullptr) { while (*current_device != NULL) {
struct device* device = *current_device; struct device* device = *current_device;
if (device_init(device) != 0U) { if (device_init(device) != 0U) {
all_succeeded = false; all_succeeded = false;
@ -46,10 +48,11 @@ bool device_init_all(struct device** const device_array) {
} }
uint8_t device_deinit(struct device* const dev) { uint8_t device_deinit(struct device* const dev) {
assert(dev != nullptr); assert(dev != NULL);
LOG_I(TAG, "deinit %s", dev->name);
if (dev->state.initialized) { if (dev->state.initialized) {
if (dev->operations.deinit != nullptr) { if (dev->operations.deinit != NULL) {
dev->state.init_result = dev->operations.deinit(dev); dev->state.init_result = dev->operations.deinit(dev);
if (dev->state.init_result == 0U) { if (dev->state.init_result == 0U) {
dev->state.initialized = false; dev->state.initialized = false;
@ -63,15 +66,16 @@ uint8_t device_deinit(struct device* const dev) {
} }
bool device_is_ready(const struct device* const dev) { bool device_is_ready(const struct device* const dev) {
assert(dev != nullptr); assert(dev != NULL);
return dev->state.initialized && (dev->state.init_result == 0U); return dev->state.initialized && (dev->state.init_result == 0U);
} }
void device_add(const struct device* dev) { void device_add(const struct device* dev) {
assert(dev != nullptr); assert(dev != NULL);
LOG_I(TAG, "add %s", dev->name);
for (int i = 0; i < CONFIG_DEVICE_INDEX_SIZE; i++) { for (int i = 0; i < CONFIG_DEVICE_INDEX_SIZE; i++) {
if (device_index[i] == nullptr) { if (device_index[i] == NULL) {
device_index[i] = dev; device_index[i] = dev;
return; return;
} }
@ -80,9 +84,9 @@ void device_add(const struct device* dev) {
} }
void device_add_all(struct device** const device_array) { void device_add_all(struct device** const device_array) {
assert(device_array != nullptr); assert(device_array != NULL);
struct device** current_device = device_array; struct device** current_device = device_array;
while (*current_device != nullptr) { while (*current_device != NULL) {
struct device* device = *current_device; struct device* device = *current_device;
device_add(device); device_add(device);
current_device++; current_device++;
@ -90,10 +94,11 @@ void device_add_all(struct device** const device_array) {
} }
bool device_remove(const struct device* dev) { bool device_remove(const struct device* dev) {
assert(dev != nullptr); assert(dev != NULL);
LOG_I(TAG, "remove %s", dev->name);
for (int i = 0; i < CONFIG_DEVICE_INDEX_SIZE; i++) { for (int i = 0; i < CONFIG_DEVICE_INDEX_SIZE; i++) {
if (device_index[i] == dev) { if (device_index[i] == dev) {
device_index[i] = nullptr; device_index[i] = NULL;
return true; return true;
} }
} }
@ -101,10 +106,10 @@ bool device_remove(const struct device* dev) {
} }
bool device_find_next_by_compatible(const char* identifier, const struct device** dev) { bool device_find_next_by_compatible(const char* identifier, const struct device** dev) {
bool found_first = (*dev == nullptr); bool found_first = (*dev == NULL);
for (int device_idx = 0; device_idx < CONFIG_DEVICE_INDEX_SIZE; device_idx++) { for (int device_idx = 0; device_idx < CONFIG_DEVICE_INDEX_SIZE; device_idx++) {
auto indexed_device = device_index[device_idx]; const struct device* indexed_device = device_index[device_idx];
if (indexed_device != nullptr) { if (indexed_device != NULL) {
if (!found_first) { if (!found_first) {
if (indexed_device == *dev) { if (indexed_device == *dev) {
found_first = true; found_first = true;

View File

@ -1,4 +1,6 @@
#include <drivers/gpio_controller.h> #include <tactility/drivers/gpio_controller.h>
#define GPIO_API(dev) ((struct gpio_controller_api*)dev->api)
bool gpio_controller_set_level(const struct device* dev, gpio_pin_t pin, bool high) { bool gpio_controller_set_level(const struct device* dev, gpio_pin_t pin, bool high) {
return GPIO_API(dev)->set_level(dev, pin, high); return GPIO_API(dev)->set_level(dev, pin, high);

View File

@ -0,0 +1,15 @@
#include <tactility/drivers/i2c_controller.h>
#define GPIO_API(dev) ((struct i2c_controller_api*)dev->api)
bool i2c_controller_read(struct device* dev, uint8_t address, uint8_t* data, size_t dataSize, TickType_t timeout) {
return GPIO_API(dev)->read(dev, address, data, dataSize, timeout);
}
bool i2c_controller_write(struct device* dev, uint8_t address, const uint8_t* data, uint16_t dataSize, TickType_t timeout) {
return GPIO_API(dev)->write(dev, address, data, dataSize, timeout);
}
bool i2c_controller_write_read(struct device* dev, uint8_t address, const uint8_t* write_data, size_t write_data_size, uint8_t* read_data, size_t read_data_size, TickType_t timeout) {
return GPIO_API(dev)->write_read(dev, address, write_data, write_data_size, read_data, read_data_size, timeout);
}

View File

@ -1,3 +1,3 @@
#include <drivers/root.h> #include "tactility/drivers/root.h"
const struct root_api root_api_instance = {}; const struct root_api root_api_instance = {};

17
core/source/log.c Normal file
View File

@ -0,0 +1,17 @@
#include <tactility/log.h>
#ifndef ESP_PLATFORM
#include <stdio.h>
#include <stdarg.h>
void log_generic(const char* tag, const char* format, ...) {
va_list args;
va_start(args, format);
printf("%s ", tag);
vprintf(format, args);
printf("\n");
va_end(args);
}
#endif