Skip to content

Commit

Permalink
[uart] Refactor SAM UART driver
Browse files Browse the repository at this point in the history
  • Loading branch information
salkinium committed Feb 23, 2021
1 parent dc968ea commit 62b63f5
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 119 deletions.
21 changes: 2 additions & 19 deletions src/modm/platform/uart/sam/module.lb
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (c) 2016-2018, Niklas Hauser
# Copyright (c) 2017, Fabian Greif
# Copyright (c) 2017, Erik Henriksson
# Copyright (c) 2020, Erik Henriksson
#
# This file is part of the modm project.
#
Expand All @@ -30,9 +28,6 @@ class Instance(Module):
device = env[":target"].identifier
global props
props["id"] = self.instance
props["driver"] = self.driver
props["features"] = self.driver["feature"] if "feature" in self.driver else []
props["uart_name"] = 'Uart'
props["sercom_name"] = self.driver["name"].capitalize()

env.substitutions = props
Expand All @@ -43,22 +38,17 @@ class Instance(Module):
env.template("uart.hpp.in", "uart_{}.hpp".format(self.instance))
env.template("uart.cpp.in", "uart_{}.cpp".format(self.instance))

props["instances"].append(self.instance)


def init(module):
module.name = ":platform:uart"
module.description = "Universal Asynchronous Receiver Transmitter (UART)"

def prepare(module, options):
device = options[":target"]
if not (device.has_driver("sercom:*")):
if not (device.has_driver("sercom:sam")):
return False

module.depends(
":architecture:atomic",
":architecture:interrupt",
":architecture:register",
":architecture:uart",
":math:algorithm",
":cmsis:device",
Expand All @@ -67,11 +57,6 @@ def prepare(module, options):

global props
drivers = options[":target"].get_all_drivers("sercom")
props["extended_driver"] = ("extended" in drivers[0]["type"])
props["over8_sampling"] = ("feature" in drivers[0]) and ("over8" in drivers[0]["feature"])
props["tcbgt"] = ("feature" in drivers[0]) and ("tcbgt" in drivers[0]["feature"])
props["instances"] = []

for driver in drivers:
for instance in driver["instance"]:
module.add_submodule(Instance(driver, instance))
Expand All @@ -80,8 +65,6 @@ def prepare(module, options):
return True

def build(env):
device = env[":target"]

global props
env.substitutions = props
env.outbasepath = "modm/src/modm/platform/uart"
Expand Down
36 changes: 17 additions & 19 deletions src/modm/platform/uart/sam/uart.cpp.in
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
/*
* Copyright (c) 2009, Martin Rosekeit
* Copyright (c) 2009-2011, Fabian Greif
* Copyright (c) 2010-2011, 2013, Georgi Grinshpun
* Copyright (c) 2013-2014, Sascha Schade
* Copyright (c) 2013, 2016, Kevin Läufer
* Copyright (c) 2013-2017, Niklas Hauser
* Copyright (c) 2018, Lucas Mösch
* Copyright (c) 2020, Erik Henriksson
*
* This file is part of the modm project.
Expand All @@ -16,36 +9,39 @@
*/
// ----------------------------------------------------------------------------

%% set name = uart_name ~ id
%% set hal = uart_name ~ "Hal" ~ id
%% set name = "Uart" ~ id
%% set hal = "UartHal" ~ id

#include "../device.hpp"
#include "uart_hal_{{ id }}.hpp"
#include "uart_{{ id }}.hpp"

namespace modm::platform
{

void
modm::platform::{{ name }}::writeBlocking(uint8_t data)
{{ name }}::writeBlocking(uint8_t data)
{
while(!{{ hal }}::isTransmitRegisterEmpty());
{{ hal }}::write(data);
}

void
modm::platform::{{ name }}::writeBlocking(const uint8_t *data, std::size_t length)
{{ name }}::writeBlocking(const uint8_t *data, std::size_t length)
{
while (length-- != 0) {
writeBlocking(*data++);
}
}

void
modm::platform::{{ name }}::flushWriteBuffer()
{{ name }}::flushWriteBuffer()
{
return;
}

bool
modm::platform::{{ name }}::write(uint8_t data)
{{ name }}::write(uint8_t data)
{
if({{ hal }}::isTransmitRegisterEmpty()) {
{{ hal }}::write(data);
Expand All @@ -56,7 +52,7 @@ modm::platform::{{ name }}::write(uint8_t data)
}

std::size_t
modm::platform::{{ name }}::write(const uint8_t *data, std::size_t length)
{{ name }}::write(const uint8_t *data, std::size_t length)
{
uint32_t i = 0;
for (; i < length; ++i)
Expand All @@ -69,19 +65,19 @@ modm::platform::{{ name }}::write(const uint8_t *data, std::size_t length)
}

bool
modm::platform::{{ name }}::isWriteFinished()
{{ name }}::isWriteFinished()
{
return {{ hal }}::isTransmitRegisterEmpty();
}

std::size_t
modm::platform::{{ name }}::discardTransmitBuffer()
{{ name }}::discardTransmitBuffer()
{
return 0;
}

bool
modm::platform::{{ name }}::read(uint8_t &data)
{{ name }}::read(uint8_t &data)
{
if({{ hal }}::isReceiveRegisterNotEmpty()) {
{{ hal }}::read(data);
Expand All @@ -92,7 +88,7 @@ modm::platform::{{ name }}::read(uint8_t &data)
}

std::size_t
modm::platform::{{ name }}::read(uint8_t *data, std::size_t length)
{{ name }}::read(uint8_t *data, std::size_t length)
{
(void)length; // avoid compiler warning
if(read(*data)) {
Expand All @@ -103,7 +99,9 @@ modm::platform::{{ name }}::read(uint8_t *data, std::size_t length)
}

std::size_t
modm::platform::{{ name }}::discardReceiveBuffer()
{{ name }}::discardReceiveBuffer()
{
return 0;
}

} // namespace modm::platform
27 changes: 7 additions & 20 deletions src/modm/platform/uart/sam/uart.hpp.in
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
/*
* Copyright (c) 2009-2012, Fabian Greif
* Copyright (c) 2010, Martin Rosekeit
* Copyright (c) 2011, Georgi Grinshpun
* Copyright (c) 2011, 2013-2017, Niklas Hauser
* Copyright (c) 2012, Sascha Schade
* Copyright (c) 2013, 2016, Kevin Läufer
* Copyright (c) 2020, Erik Henriksson
*
* This file is part of the modm project.
Expand All @@ -15,9 +9,8 @@
*/
// ----------------------------------------------------------------------------

%% set hal = uart_name ~ "Hal" ~ id
%% set name = uart_name ~ id
%% set sercom = sercom_name ~ id
%% set hal = "UartHal" ~ id
%% set name = "Uart" ~ id

#pragma once

Expand All @@ -26,17 +19,13 @@
#include "uart_hal_{{ id }}.hpp"
#include <modm/platform/gpio/pin.hpp>

namespace modm
{

namespace platform
namespace modm::platform
{

/**
* Universal asynchronous receiver transmitter ({{ uart_name | upper ~ id }})
* Universal asynchronous receiver transmitter ({{ "Uart" | upper ~ id }})
*
* @author Kevin Laeufer
* @author Niklas Hauser
* @author Erik Henriksson
* @ingroup modm_platform_uart modm_platform_uart_{{id}}
*/
class {{ name }} : public UartBase, public ::modm::Uart
Expand Down Expand Up @@ -72,7 +61,7 @@ public:
static void modm_always_inline
initialize(Parity parity = Parity::Disabled)
{
{{ hal }}::initialize<SystemClock, baudrate>(parity);
{{ hal }}::initialize<SystemClock, baudrate, tolerance>(parity);
{{ hal }}::setTransmitterEnable(true);
{{ hal }}::setReceiverEnable(true);
}
Expand Down Expand Up @@ -108,6 +97,4 @@ public:
discardReceiveBuffer();
};

} // namespace platform

} // namespace modm
} // namespace modm::platform
18 changes: 5 additions & 13 deletions src/modm/platform/uart/sam/uart_base.hpp.in
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
/*
* Copyright (c) 2013, Kevin Läufer
* Copyright (c) 2014-2018, Niklas Hauser
* Copyright (c) 2017, Sascha Schade
* Copyright (c) 2020, Erik Henriksson
*
* This file is part of the modm project.
Expand All @@ -21,29 +18,24 @@
#include <modm/math/units.hpp>


namespace modm
{
namespace platform
namespace modm::platform
{
/**
* Base class for the UART classes
*
* Provides some common enum that do not depend on the specific UART.
*
* @author Kevin Laeufer
* @ingroup modm_platform_uart
*/
class UartBase
{
public:
enum class Parity : uint32_t
{
Even = 0,
Odd = 1,
Disabled = 2,
Even = 0,
Odd = 1,
Disabled = 2,
};
};

} // namespace platform

} // namespace modm
} // namespace modm::platform
25 changes: 8 additions & 17 deletions src/modm/platform/uart/sam/uart_hal.hpp.in
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
/*
* Copyright (c) 2013, Sascha Schade
* Copyright (c) 2013-2014, 2016, Kevin Läufer
* Copyright (c) 2013-2017, Niklas Hauser
* Copyright (c) 2020, Erik Henriksson
*
* This file is part of the modm project.
Expand All @@ -15,28 +12,24 @@
#pragma once

#include <stdint.h>
#include <modm/architecture/interface/peripheral.hpp>
#include "../device.hpp"
#include "uart_base.hpp"
#include "modm/platform/clock/gclk.hpp"

namespace modm
{

namespace platform
namespace modm::platform
{

/**
* Universal asynchronous receiver transmitter ({{ uart_name ~ "Hal" ~ id }})
*
* Not available on the low- and medium density devices.
* Universal asynchronous receiver transmitter (UartHal{{ id }})
*
* Very basic implementation that exposes more hardware features than
* the regular Usart classes.
*
* @author Kevin Laeufer
* @author Erik Henriksson
* @ingroup modm_platform_uart
*/
class {{ uart_name ~ "Hal" ~ id }} : public UartBase
class UartHal{{ id }} : public UartBase, /** @cond */protected modm::PeripheralDriver/** @endcond */
{
private:
/**
Expand Down Expand Up @@ -68,9 +61,9 @@ public:
* Enables clocks, the UART peripheral (but neither TX nor RX)
* Sets baudrate and parity.
*/
template< class SystemClock, baudrate_t baudrate >
template< class SystemClock, baudrate_t baudrate, percent_t tolerance=pct(1) >
static void
initialize( Parity parity = Parity::Disabled);
initialize(Parity parity = Parity::Disabled);

/**
* \brief Write a single byte to the transmit register
Expand Down Expand Up @@ -117,8 +110,6 @@ public:
isTransmitRegisterEmpty();
};

} // namespace platform

} // namespace modm
} // namespace modm::platform

#include "uart_hal_{{ id }}_impl.hpp"
Loading

0 comments on commit 62b63f5

Please sign in to comment.