Skip to content

Commit

Permalink
[test] Add SAMV71 CAN unit test for Xplained Ultra board
Browse files Browse the repository at this point in the history
  • Loading branch information
rleh committed Apr 19, 2023
1 parent 71f188d commit 173523d
Show file tree
Hide file tree
Showing 3 changed files with 195 additions and 0 deletions.
135 changes: 135 additions & 0 deletions test/modm/platform/can/sam-mcan/mcan_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/*
* Copyright (c) 2023, Raphael Lehmann
*
* This file is part of the modm project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// ----------------------------------------------------------------------------

#include "mcan_test.hpp"

#include <algorithm>
#include <modm/platform.hpp>
#include <modm/board.hpp>

using namespace modm::platform;

void
FdcanTest::setUp()
{
Mcan0::initialize<Board::SystemClock, 125_kbps, 1_pct, 1_Mbps>(12, Mcan0::Mode::TestInternalLoopback);

// receive all standard & extended messages into Fifo0
Mcan0::setExtendedFilter(0, Mcan0::FilterConfig::Fifo0,
modm::can::ExtendedIdentifier(0),
modm::can::ExtendedMask(0));
Mcan0::setStandardFilter(0, Mcan0::FilterConfig::Fifo0,
modm::can::StandardIdentifier(0),
modm::can::StandardMask(0));
}

void
FdcanTest::testSendReceive()
{
constexpr size_t length = 8;

std::array<uint8_t, length> data;
std::generate(data.begin(), data.end(), [n=0]() mutable { return n++; });

modm::can::Message extendedMessage{0x4242u, length};
std::copy(std::begin(data), std::begin(data) + length, extendedMessage.data);

TEST_ASSERT_FALSE(Mcan0::isMessageAvailable());
TEST_ASSERT_TRUE(Mcan0::sendMessage(extendedMessage));

modm::delay_ms(10);

TEST_ASSERT_TRUE(Mcan0::isMessageAvailable());

modm::can::Message receivedMessage;
TEST_ASSERT_TRUE(Mcan0::getMessage(receivedMessage));
TEST_ASSERT_EQUALS(receivedMessage.getIdentifier(), 0x4242u);
TEST_ASSERT_EQUALS(receivedMessage.getLength(), length);
TEST_ASSERT_TRUE(receivedMessage.isExtended());
TEST_ASSERT_FALSE(receivedMessage.isRemoteTransmitRequest());
TEST_ASSERT_FALSE(receivedMessage.isFlexibleData());
TEST_ASSERT_FALSE(receivedMessage.isBitRateSwitching());
TEST_ASSERT_TRUE(std::equal(std::begin(data), std::begin(data) + length, receivedMessage.data));

// Same procedure with standard identifier message
modm::can::Message standardMessage{0x777u, length};
std::generate(data.begin(), data.end(), [n=length]() mutable { return n--; });
std::copy(std::begin(data), std::begin(data) + length, standardMessage.data);
standardMessage.setExtended(false);

TEST_ASSERT_FALSE(Mcan0::isMessageAvailable());
TEST_ASSERT_TRUE(Mcan0::sendMessage(standardMessage));
modm::delay_ms(1);
TEST_ASSERT_TRUE(Mcan0::isMessageAvailable());

TEST_ASSERT_TRUE(Mcan0::getMessage(receivedMessage));
TEST_ASSERT_EQUALS(receivedMessage.getIdentifier(), 0x777u);
TEST_ASSERT_EQUALS(receivedMessage.getLength(), length);
TEST_ASSERT_FALSE(receivedMessage.isExtended());
TEST_ASSERT_FALSE(receivedMessage.isRemoteTransmitRequest());
TEST_ASSERT_FALSE(receivedMessage.isFlexibleData());
TEST_ASSERT_FALSE(receivedMessage.isBitRateSwitching());
TEST_ASSERT_TRUE(std::equal(std::begin(data), std::begin(data) + length, receivedMessage.data));
}

void
FdcanTest::testFilters()
{
Mcan0::setStandardFilter(0, Mcan0::FilterConfig::Fifo0,
modm::can::StandardIdentifier(0x108),
modm::can::StandardMask(0x1F8));

modm::can::Message message{0x188, 0};
message.setExtended(false);
Mcan0::sendMessage(message);
modm::delay_ms(1);
TEST_ASSERT_FALSE(Mcan0::isMessageAvailable());

message.setIdentifier(0x10F);
Mcan0::sendMessage(message);
modm::delay_ms(1);
TEST_ASSERT_TRUE(Mcan0::isMessageAvailable());
modm::can::Message receivedMessage;
TEST_ASSERT_TRUE(Mcan0::getMessage(receivedMessage));
TEST_ASSERT_FALSE(receivedMessage.isExtended());
TEST_ASSERT_EQUALS(receivedMessage.getIdentifier(), 0x10Fu);
}

void
FdcanTest::testBuffers()
{
modm::can::Message message{0, 8};
// send 30 messages, default message buffer holds 32 elements
for (uint_fast8_t i = 0; i <= 30; ++i) {
message.setIdentifier(i);
for (uint_fast8_t dataIndex = 0; dataIndex < i; ++dataIndex) {
message.data[dataIndex] = i;
}
Mcan0::sendMessage(message);
}

modm::delay_ms(10);

// try to receive same messages
modm::can::Message receivedMessage;
for (uint_fast8_t i = 0; i <= 30; ++i) {
TEST_ASSERT_TRUE(Mcan0::getMessage(receivedMessage));

TEST_ASSERT_EQUALS(receivedMessage.getIdentifier(), i);
TEST_ASSERT_EQUALS(receivedMessage.getLength(), 8);

for (uint_fast8_t dataIndex = 0; dataIndex < i; ++dataIndex) {
TEST_ASSERT_EQUALS(receivedMessage.data[dataIndex], i);
}
}
TEST_ASSERT_FALSE(Mcan0::isMessageAvailable());
TEST_ASSERT_FALSE(Mcan0::getMessage(message));
}
29 changes: 29 additions & 0 deletions test/modm/platform/can/sam-mcan/mcan_test.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright (c) 2023, Raphael Lehmann
*
* This file is part of the modm project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// ----------------------------------------------------------------------------

#include <unittest/testsuite.hpp>

/// @ingroup modm_test_test_platform_sam-mcan
class FdcanTest : public unittest::TestSuite
{
public:
void
setUp() override;

void
testSendReceive();

void
testFilters();

void
testBuffers();
};
31 changes: 31 additions & 0 deletions test/modm/platform/can/sam-mcan/module.lb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (c) 2023, Raphael Lehmann
#
# This file is part of the modm project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.


def init(module):
module.name = ":test:platform:mcan"
module.description = "Tests for SAM MCAN"

def prepare(module, options):
target = options[":target"]
if not target.has_driver("mcan:sam*"):
return False
if target.identifier.variant == 'a':
return False

module.depends(":architecture:delay", ":platform:can:0")
return True

def build(env):
# env.substitutions = properties
env.outbasepath = "modm-test/src/modm-test/platform/can/sam-mcan_test"
env.copy("mcan_test.hpp")
env.copy("mcan_test.cpp")

0 comments on commit 173523d

Please sign in to comment.