Skip to content

Commit

Permalink
feat: added hal/generic/UartGeneric and hal/generic/SynchronousUartGe…
Browse files Browse the repository at this point in the history
…neric (#535)

* feat: added hal/generic/UartGeneric and hal/generic/SynchronousUartGeneric

* Apply suggestions from code review

Co-authored-by: Richard Peters <richard.peters@philips.com>

* Update hal/unix/SynchronousUartUnix.cpp

Co-authored-by: Richard Peters <richard.peters@philips.com>

* feat: add darwin compatibility

* chore: reduce code duplication for UartUnix and SynchronousUartUnix

* feat: add hal/windows/* to sonar coverage exclusion list

* Update hal/generic/SynchronousUartGeneric.cpp

Co-authored-by: Ron <45816308+rjaegers@users.noreply.github.com>

---------

Co-authored-by: Richard Peters <richard.peters@philips.com>
Co-authored-by: Ron <45816308+rjaegers@users.noreply.github.com>
  • Loading branch information
3 people committed Jan 23, 2024
1 parent 419f636 commit 799e0ee
Show file tree
Hide file tree
Showing 17 changed files with 479 additions and 145 deletions.
16 changes: 16 additions & 0 deletions hal/generic/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,20 @@ target_sources(hal.generic PRIVATE
TimeKeeperGeneric.hpp
TimerServiceGeneric.cpp
TimerServiceGeneric.hpp
SynchronousUartGeneric.cpp
SynchronousUartGeneric.hpp
UartGeneric.cpp
UartGeneric.hpp
)

if (EMIL_BUILD_WIN)
target_link_libraries(hal.generic PUBLIC
hal.windows
)
endif()

if (EMIL_BUILD_UNIX OR EMIL_BUILD_DARWIN)
target_link_libraries(hal.generic PUBLIC
hal.unix
)
endif()
35 changes: 35 additions & 0 deletions hal/generic/SynchronousUartGeneric.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include "hal/generic/SynchronousUartGeneric.hpp"
#include <cstdint>
#include <string>

#if defined(EMIL_HAL_WINDOWS)
#include "hal/windows/UartWindows.hpp"
#endif

#if defined(EMIL_HAL_UNIX)
#include "hal/unix/UartUnix.hpp"
#endif

namespace hal
{
SynchronousUartGeneric::SynchronousUartGeneric(const std::string& portname, const Config& config)
#if defined(EMIL_HAL_WINDOWS)
: serialConfig{ config.baudrate, config.rtsFlowControl == Config::RtsFlowControl::none ? SynchronousUartWindows::Config::RtsFlowControl::RtsControlDisable : SynchronousUartWindows::Config::RtsFlowControl::RtsHandshake }
, serialImpl{ portname, serialConfig }
#endif
#if defined(EMIL_HAL_UNIX)
: serialConfig{ config.baudrate, config.rtsFlowControl != Config::RtsFlowControl::none }
, serialImpl{ portname, serialConfig }
#endif
{}

void SynchronousUartGeneric::SendData(infra::ConstByteRange data)
{
serialImpl.SendData(data);
}

bool SynchronousUartGeneric::ReceiveData(infra::ByteRange data)
{
return serialImpl.ReceiveData(data);
}
}
56 changes: 56 additions & 0 deletions hal/generic/SynchronousUartGeneric.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#ifndef HAL_UART_HOST_HPP
#define HAL_UART_HOST_HPP

#include "hal/synchronous_interfaces/SynchronousSerialCommunication.hpp"
#include <cstdint>
#include <string>

#if defined(EMIL_HAL_WINDOWS)
#include "hal/windows/SynchronousUartWindows.hpp"
#elif defined(EMIL_HAL_UNIX)
#include "hal/unix/SynchronousUartUnix.hpp"
#else
#error no host defined
#endif

namespace hal
{
namespace detail
{
struct SynchronousUartGenericConfig
{
enum class RtsFlowControl
{
none,
enabled
};

uint32_t baudrate = 115200;
RtsFlowControl rtsFlowControl = RtsFlowControl::none;
};
}

class SynchronousUartGeneric
: public hal::SynchronousSerialCommunication
{
public:
using Config = detail::SynchronousUartGenericConfig;

SynchronousUartGeneric(const std::string& portname, const Config& config = {});
virtual ~SynchronousUartGeneric() = default;

void SendData(infra::ConstByteRange data) override;
bool ReceiveData(infra::ByteRange data) override;

private:
#if defined(EMIL_HAL_WINDOWS)
SynchronousUartWindows::Config serialConfig;
SynchronousUartWindows serialImpl;
#elif defined(EMIL_HAL_UNIX)
SynchronousUartUnix::Config serialConfig;
SynchronousUartUnix serialImpl;
#endif
};
}

#endif
35 changes: 35 additions & 0 deletions hal/generic/UartGeneric.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include "hal/generic/UartGeneric.hpp"
#include <cstdint>
#include <string>

#if defined(EMIL_HAL_WINDOWS)
#include "hal/windows/UartWindows.hpp"
#endif

#if defined(EMIL_HAL_UNIX)
#include "hal/unix/UartUnix.hpp"
#endif

namespace hal
{
UartGeneric::UartGeneric(const std::string& portname, const Config& config)
#if defined(EMIL_HAL_WINDOWS)
: serialConfig{ config.baudrate, config.rtsFlowControl == Config::RtsFlowControl::none ? UartWindows::Config::RtsFlowControl::RtsControlDisable : UartWindows::Config::RtsFlowControl::RtsHandshake }
, serialImpl{ portname, serialConfig }
#endif
#if defined(EMIL_HAL_UNIX)
: serialConfig{ config.baudrate, config.rtsFlowControl != Config::RtsFlowControl::none }
, serialImpl{ portname, serialConfig }
#endif
{}

void UartGeneric::SendData(infra::ConstByteRange data, infra::Function<void()> actionOnCompletion)
{
serialImpl.SendData(data, actionOnCompletion);
}

void UartGeneric::ReceiveData(infra::Function<void(infra::ConstByteRange data)> dataReceived)
{
serialImpl.ReceiveData(dataReceived);
}
}
56 changes: 56 additions & 0 deletions hal/generic/UartGeneric.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#ifndef HAL_UART_HOST_HPP
#define HAL_UART_HOST_HPP

#include "hal/interfaces/SerialCommunication.hpp"
#include <cstdint>
#include <string>

#if defined(EMIL_HAL_WINDOWS)
#include "hal/windows/UartWindows.hpp"
#elif defined(EMIL_HAL_UNIX)
#include "hal/unix/UartUnix.hpp"
#else
#error no host defined
#endif

namespace hal
{
namespace detail
{
struct UartGenericConfig
{
enum class RtsFlowControl
{
none,
enabled
};

uint32_t baudrate = 115200;
RtsFlowControl rtsFlowControl = RtsFlowControl::none;
};
}

class UartGeneric
: public hal::SerialCommunication
{
public:
using Config = detail::UartGenericConfig;

UartGeneric(const std::string& portname, const Config& config = {});
virtual ~UartGeneric() = default;

void SendData(infra::ConstByteRange data, infra::Function<void()> actionOnCompletion) override;
void ReceiveData(infra::Function<void(infra::ConstByteRange data)> dataReceived) override;

private:
#if defined(EMIL_HAL_WINDOWS)
UartWindows::Config serialConfig;
UartWindows serialImpl;
#elif defined(EMIL_HAL_UNIX)
UartUnix::Config serialConfig;
UartUnix serialImpl;
#endif
};
}

#endif
4 changes: 4 additions & 0 deletions hal/unix/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ if (EMIL_BUILD_DARWIN)
endif()

target_sources(hal.unix PRIVATE
SynchronousUartUnix.cpp
SynchronousUartUnix.hpp
UartUnix.cpp
UartUnix.hpp
UartUnixBase.cpp
UartUnixBase.hpp
)
30 changes: 30 additions & 0 deletions hal/unix/SynchronousUartUnix.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include "hal/unix/SynchronousUartUnix.hpp"
#include "infra/event/EventDispatcher.hpp"
#ifdef EMIL_OS_DARWIN
#include <IOKit/serial/ioss.h>
#else
#include <asm/termbits.h>
#endif
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>

namespace hal
{
void SynchronousUartUnix::SendData(infra::ConstByteRange data)
{
if (FileDescriptor() < 0)
throw std::runtime_error("Port not open");

auto result = write(FileDescriptor(), data.begin(), data.size());

if (result == -1)
throw std::system_error(EFAULT, std::system_category());
}

bool SynchronousUartUnix::ReceiveData(infra::ByteRange data)
{
auto size = read(FileDescriptor(), data.begin(), data.size());
return data.size() == size;
}
}
26 changes: 26 additions & 0 deletions hal/unix/SynchronousUartUnix.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef HAL_SYNCHRONOUS_UART_UNIX_HPP
#define HAL_SYNCHRONOUS_UART_UNIX_HPP

#include "hal/synchronous_interfaces/SynchronousSerialCommunication.hpp"
#include "hal/unix/UartUnixBase.hpp"
#include <string>

namespace hal
{

class SynchronousUartUnix
: public UartUnixBase
, public hal::SynchronousSerialCommunication
{
public:
using Config = UartUnixBase::Config;

using UartUnixBase::UartUnixBase;

// Implementation of hal::SynchronousSerialCommunication
void SendData(infra::ConstByteRange data) override;
bool ReceiveData(infra::ByteRange data) override;
};
}

#endif
Loading

0 comments on commit 799e0ee

Please sign in to comment.