Added HAL docs, improved HAL init&locking (#218)

This commit is contained in:
Ken Van Hoeylandt
2025-02-12 18:12:20 +01:00
committed by GitHub
parent b7f39f883d
commit 2e86d4774b
16 changed files with 333 additions and 302 deletions
@@ -9,9 +9,7 @@
namespace tt::hal {
/**
* Base class for HAL-related devices.
*/
/** Base class for HAL-related devices. */
class Device {
public:
@@ -37,9 +35,10 @@ public:
Device();
virtual ~Device() = default;
/** Unique identifier */
inline Id getId() const { return id; }
/** The type of device. */
/** The type of device */
virtual Type getType() const = 0;
/** The part number or hardware name e.g. TdeckTouch, TdeckDisplay, BQ24295, etc. */
@@ -1,15 +1,17 @@
#pragma once
#include "./I2cCompat.h"
#include "Tactility/Lockable.h"
#include <Tactility/RtosCompat.h>
#include <climits>
#include <string>
#include <vector>
namespace tt::hal::i2c {
constexpr TickType_t defaultTimeout = 10 / portTICK_PERIOD_MS;
enum class InitMode {
ByTactility, // Tactility will initialize it in the correct bootup phase
ByExternal, // The device is already initialized and Tactility should assume it works
@@ -36,22 +38,57 @@ enum class Status {
Unknown
};
bool init(const std::vector<i2c::Configuration>& configurations);
/**
* Reconfigure a port with the provided settings.
* @warning This fails when the HAL Configuration does not allow for reinit.
* @warning This fails when the HAL Configuration does not allow for mutation of the device.
* @param[in] port the port to reconfigure
* @param[in] configuration the new configuration
* @return true on success
*/
bool configure(i2c_port_t port, const i2c_config_t& configuration);
/**
* Start the bus for the specified port.
* Devices might be started automatically at boot if their HAL configuration requires it.
*/
bool start(i2c_port_t port);
/** Stop the bus for the specified port. */
bool stop(i2c_port_t port);
/** @return true if the bus is started */
bool isStarted(i2c_port_t port);
bool masterRead(i2c_port_t port, uint8_t address, uint8_t* data, size_t dataSize, TickType_t timeout);
bool masterReadRegister(i2c_port_t port, uint8_t address, uint8_t reg, uint8_t* data, size_t dataSize, TickType_t timeout);
bool masterWrite(i2c_port_t port, uint8_t address, const uint8_t* data, uint16_t dataSize, TickType_t timeout);
bool masterWriteRegister(i2c_port_t port, uint8_t address, uint8_t reg, const uint8_t* data, uint16_t dataSize, TickType_t timeout);
bool masterWriteRegisterArray(i2c_port_t port, uint8_t address, const uint8_t* data, uint16_t dataSize, TickType_t timeout);
bool masterWriteRead(i2c_port_t port, uint8_t address, const uint8_t* writeData, size_t writeDataSize, uint8_t* readData, size_t readDataSize, TickType_t timeout);
bool masterHasDeviceAtAddress(i2c_port_t port, uint8_t address, TickType_t timeout);
/** Read bytes in master mode. */
bool masterRead(i2c_port_t port, uint8_t address, uint8_t* data, size_t dataSize, TickType_t timeout = defaultTimeout);
bool lock(i2c_port_t port, TickType_t timeout = 10 / portTICK_PERIOD_MS);
bool unlock(i2c_port_t port);
/** Read bytes from the specified register in master mode. */
bool masterReadRegister(i2c_port_t port, uint8_t address, uint8_t reg, uint8_t* data, size_t dataSize, TickType_t timeout = defaultTimeout);
/** Write bytes in master mode. */
bool masterWrite(i2c_port_t port, uint8_t address, const uint8_t* data, uint16_t dataSize, TickType_t timeout = defaultTimeout);
/** Write bytes to a register in master mode */
bool masterWriteRegister(i2c_port_t port, uint8_t address, uint8_t reg, const uint8_t* data, uint16_t dataSize, TickType_t timeout = defaultTimeout);
/**
* Write multiple values to multiple registers in master mode.
* The input is as follows: { register1, value1, register2, value2, ... }
* @return false if any of the write operations failed
*/
bool masterWriteRegisterArray(i2c_port_t port, uint8_t address, const uint8_t* data, uint16_t dataSize, TickType_t timeout = defaultTimeout);
/** Write bytes and then read the response bytes in master mode*/
bool masterWriteRead(i2c_port_t port, uint8_t address, const uint8_t* writeData, size_t writeDataSize, uint8_t* readData, size_t readDataSize, TickType_t timeout = defaultTimeout);
/** @return true when a device is detected at the specified address */
bool masterHasDeviceAtAddress(i2c_port_t port, uint8_t address, TickType_t timeout = defaultTimeout);
/**
* The lock for the specified bus.
* This can be used when calling native I2C functionality outside of Tactility.
*/
Lockable& getLock(i2c_port_t port);
} // namespace
@@ -5,11 +5,10 @@
#include <Tactility/Lockable.h>
#include <Tactility/RtosCompat.h>
#include <vector>
#include <memory>
namespace tt::hal::spi {
constexpr TickType_t defaultTimeout = 10 / portTICK_PERIOD_MS;
enum class InitMode {
ByTactility, // Tactility will initialize it in the correct bootup phase
ByExternal, // The device is already initialized and Tactility should assume it works
@@ -36,13 +35,16 @@ enum class Status {
Unknown
};
bool init(const std::vector<spi::Configuration>& configurations);
/** Start communications */
bool start(spi_host_device_t device);
/** Stop communications */
bool stop(spi_host_device_t device);
/** @return true if communications were started successfully */
bool isStarted(spi_host_device_t device);
bool lock(spi_host_device_t device, TickType_t timeout = 10 / portTICK_PERIOD_MS);
bool unlock(spi_host_device_t device);
/** @return the lock that represents the specified device. Can be used with third party SPI implementations or native API calls (e.g. ESP-IDF). */
Lockable& getLock(spi_host_device_t device);
} // namespace tt::hal::spi
@@ -2,14 +2,17 @@
#include <Tactility/RtosCompat.h>
#include "UartCompat.h"
#include "../Gpio.h"
#include "Tactility/Lockable.h"
#include "UartCompat.h"
#include <vector>
#include <memory>
#include <vector>
namespace tt::hal::uart {
constexpr TickType_t defaultTimeout = 10 / portTICK_PERIOD_MS;
enum class InitMode {
ByTactility, // Tactility will initialize it in the correct bootup phase
ByExternal, // The device is already initialized and Tactility should assume it works
@@ -46,29 +49,69 @@ enum class Status {
Unknown
};
bool init(const std::vector<uart::Configuration>& configurations);
/** Start communications */
bool start(uart_port_t port);
/** Stop communications */
bool stop(uart_port_t port);
/** @return true when communications were successfully started */
bool isStarted(uart_port_t port);
bool lock(uart_port_t port, TickType_t timeout = 10 / portTICK_PERIOD_MS);
bool unlock(uart_port_t port);
/** @return a lock that is usable for using ESP-IDF directly, or for use with third party APIs */
Lockable& getLock(uart_port_t port);
size_t read(uart_port_t port, uint8_t* buffer, size_t bufferSize, TickType_t timeout = 10 / portTICK_PERIOD_MS);
bool readByte(uart_port_t port, uint8_t* output, TickType_t timeout = 10 / portTICK_PERIOD_MS);
size_t write(uart_port_t port, const uint8_t* buffer, size_t bufferSize, TickType_t timeout = 10 / portTICK_PERIOD_MS);
bool writeString(uart_port_t port, const char* buffer, TickType_t timeout = 10 / portTICK_PERIOD_MS);
/**
* Read up to a specified amount of bytes
* @param[in] port
* @param[out] buffer
* @param[in] bufferSize
* @param[in] timeout
* @return the amount of bytes that were read
*/
size_t readBytes(uart_port_t port, uint8_t* buffer, size_t bufferSize, TickType_t timeout = defaultTimeout);
size_t available(uart_port_t port, TickType_t timeout = 10 / portTICK_PERIOD_MS);
/** Read a single byte */
bool readByte(uart_port_t port, uint8_t* output, TickType_t timeout = defaultTimeout);
bool setBaudRate(uart_port_t port, uint32_t baudRate, TickType_t timeout = 10 / portTICK_PERIOD_MS);
/**
* Read up to a specified amount of bytes
* @param[in] port
* @param[in] buffer
* @param[in] bufferSize
* @param[in] timeout
* @return the amount of bytes that were read
*/
size_t writeBytes(uart_port_t port, const uint8_t* buffer, size_t bufferSize, TickType_t timeout = defaultTimeout);
/**
* Write a string (excluding null terminator character)
* @param[in] port
* @param[in] buffer
* @param[in] timeout
* @return the amount of bytes that were written
*/
bool writeString(uart_port_t port, const char* buffer, TickType_t timeout = defaultTimeout);
/** @return the amount of bytes available for reading */
size_t available(uart_port_t port, TickType_t timeout = defaultTimeout);
/** Set the baud rate for the specified port */
bool setBaudRate(uart_port_t port, uint32_t baudRate, TickType_t timeout = defaultTimeout);
/** Get the baud rate for the specified port */
uint32_t getBaudRate(uart_port_t port);
void flush(uart_port_t port, TickType_t timeout = 10 / portTICK_PERIOD_MS);
void flushInput(uart_port_t port, TickType_t timeout = 10 / portTICK_PERIOD_MS);
/** Flush input buffers */
void flushInput(uart_port_t port);
std::string readStringUntil(uart_port_t port, char untilChar, TickType_t timeout = 10 / portTICK_PERIOD_MS);
bool readUntil(uart_port_t port, uint8_t* buffer, size_t bufferSize, uint8_t untilByte, TickType_t timeout = 10 / portTICK_PERIOD_MS);
/**
* Read a buffer as a string until the specified character (the "untilChar" is included in the result)
* @warning if the input data doesn't return "untilByte" then the device goes out of memory
*/
std::string readStringUntil(uart_port_t port, char untilChar, TickType_t timeout = defaultTimeout);
/** Read a buffer as a byte array until the specified character (the "untilChar" is included in the result) */
bool readUntil(uart_port_t port, uint8_t* buffer, size_t bufferSize, uint8_t untilByte, TickType_t timeout = defaultTimeout);
} // namespace tt::hal::uart