Skip to content

Commit

Permalink
🔀 Merge branch 'hugo/feature/Add-Ledkit' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
ladislas committed Feb 24, 2022
2 parents 36db95f + 5e0a170 commit f0f8cd3
Show file tree
Hide file tree
Showing 12 changed files with 366 additions and 0 deletions.
2 changes: 2 additions & 0 deletions libs/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,5 @@ add_subdirectory(${LIBS_DIR}/PrettyPrinter)
add_subdirectory(${LIBS_DIR}/BLEKit)

add_subdirectory(${LIBS_DIR}/ColorKit)

add_subdirectory(${LIBS_DIR}/LedKit)
30 changes: 30 additions & 0 deletions libs/LedKit/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Leka - LekaOS
# Copyright 2022 APF France handicap
# SPDX-License-Identifier: Apache-2.0

add_library(LedKit STATIC)

target_include_directories(LedKit
PUBLIC
include
include/internal
)

target_sources(LedKit
PRIVATE
source/LedKit.cpp
)

target_link_libraries(LedKit
CoreLED
ColorKit
)

if (${CMAKE_PROJECT_NAME} STREQUAL "LekaOSUnitTests")

leka_unit_tests_sources(
tests/LedKit_test.cpp
tests/LedKit_test_animations.cpp
)

endif()
44 changes: 44 additions & 0 deletions libs/LedKit/include/LedKit.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Leka - LekaOS
// Copyright 2022 APF France handicap
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include "drivers/HighResClock.h"
#include "events/EventQueue.h"
#include "rtos/Thread.h"

#include "ColorKit.h"
#include "LEDAnimation.h"

namespace leka {

class LedKit
{
public:
static constexpr auto kNumberOfLedsEars = 2;
static constexpr auto kNumberOfLedsBelt = 20;

LedKit(rtos::Thread &thread, events::EventQueue &event_queue, const CoreLED<kNumberOfLedsEars> &ears,
const CoreLED<kNumberOfLedsBelt> &belt)
: _thread(thread), _event_queue(event_queue), _ears {ears}, _belt {belt}
{
_thread.start({&_event_queue, &events::EventQueue::dispatch_forever});
};

void start(interface::LEDAnimation &animation);
void stop();

private:
rtos::Thread &_thread;
events::EventQueue &_event_queue;

CoreLED<kNumberOfLedsEars> _ears;
CoreLED<kNumberOfLedsBelt> _belt;

interface::LEDAnimation *_animation = nullptr;

int _animation_queue_id {};
};

} // namespace leka
22 changes: 22 additions & 0 deletions libs/LedKit/include/internal/LEDAnimation.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Leka - LekaOS
// Copyright 2022 APF France handicap
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include "ColorKit.h"
#include "CoreLED.h"

namespace leka::interface {

class LEDAnimation
{
public:
virtual ~LEDAnimation() = default;

virtual void start() = 0;
virtual void stop() = 0;
virtual void run() = 0;
};

} // namespace leka::interface
27 changes: 27 additions & 0 deletions libs/LedKit/source/LedKit.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Leka - LekaOS
// Copyright 2021 APF France handicap
// SPDX-License-Identifier: Apache-2.0

#include "LedKit.h"

using namespace leka;
using namespace std::chrono;

void LedKit::start(interface::LEDAnimation &animation)
{
stop();

_animation = &animation;
_animation->start();

_animation_queue_id = _event_queue.call_every(40ms, _animation, &interface::LEDAnimation::run);
}

void LedKit::stop()
{
_event_queue.cancel(_animation_queue_id);

if (_animation != nullptr) {
_animation->stop();
}
}
42 changes: 42 additions & 0 deletions libs/LedKit/tests/LedKit_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Leka - LekaOS
// Copyright 2022 APF France handicap
// SPDX-License-Identifier: Apache-2.0

#include "LedKit.h"

#include "events/tests/UNITTESTS/doubles/EventQueue_stub.h"
#include "rtos/tests/UNITTESTS/doubles/Thread_stub.h"

#include "CoreLED.h"
#include "CoreSPI.h"
#include "gtest/gtest.h"
#include "mocks/leka/LEDAnimation.h"

using namespace leka;

using ::testing::InSequence;

class LedKitTest : public ::testing::Test
{
protected:
LedKitTest() = default;

// void SetUp() override {}
// void TearDown() override {}

rtos::Thread animation_thread;
events::EventQueue event_queue;

std::array<RGB, LedKit::kNumberOfLedsBelt> expected_colors {};

CoreSPI spi {NC, NC, NC, NC};
CoreLED<LedKit::kNumberOfLedsBelt> belt {spi};
CoreLED<LedKit::kNumberOfLedsEars> ears {spi};

LedKit ledkit {animation_thread, event_queue, ears, belt};
};

TEST_F(LedKitTest, initialization)
{
EXPECT_NE(&ledkit, nullptr);
}
87 changes: 87 additions & 0 deletions libs/LedKit/tests/LedKit_test_animations.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// Leka - LekaOS
// Copyright 2022 APF France handicap
// SPDX-License-Identifier: Apache-2.0

#include "events/tests/UNITTESTS/doubles/EventQueue_stub.h"
#include "rtos/tests/UNITTESTS/doubles/Thread_stub.h"

#include "CoreLED.h"
#include "CoreSPI.h"
#include "LedKit.h"
#include "gtest/gtest.h"
#include "mocks/leka/LEDAnimation.h"

using namespace leka;

using ::testing::InSequence;

class LedKitTestAnimations : public ::testing::Test
{
protected:
LedKitTestAnimations() = default;

// void SetUp() override {}
// void TearDown() override {}

rtos::Thread animation_thread;
events::EventQueue event_queue;

std::array<RGB, LedKit::kNumberOfLedsBelt> expected_colors {};

CoreSPI spi {NC, NC, NC, NC};
CoreLED<LedKit::kNumberOfLedsBelt> belt {spi};
CoreLED<LedKit::kNumberOfLedsEars> ears {spi};

LedKit ledkit {animation_thread, event_queue, ears, belt};

animation::LEDAnimationMock animation {};

void MOCK_FUNCTION_silenceUnexpectedCalls() { EXPECT_CALL(animation, start); }
};

TEST_F(LedKitTestAnimations, initialization)
{
EXPECT_NE(&animation, nullptr);
}

TEST_F(LedKitTestAnimations, startFirstAnimation)
{
EXPECT_CALL(animation, start);

ledkit.start(animation);
}

TEST_F(LedKitTestAnimations, stopWithoutAnimation)
{
EXPECT_CALL(animation, stop).Times(0);

ledkit.stop();
}

TEST_F(LedKitTestAnimations, stopStartedAnimation)
{
MOCK_FUNCTION_silenceUnexpectedCalls();

EXPECT_CALL(animation, stop).Times(1);

ledkit.start(animation);
ledkit.stop();
}

TEST_F(LedKitTestAnimations, startNewAnimationSequence)
{
MOCK_FUNCTION_silenceUnexpectedCalls();

animation::LEDAnimationMock new_animation;

{
InSequence seq;

EXPECT_CALL(animation, stop);
EXPECT_CALL(new_animation, start);
}

ledkit.start(animation);

ledkit.start(new_animation);
}
1 change: 1 addition & 0 deletions spikes/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ add_subdirectory(${SPIKES_DIR}/lk_cg_animations)
add_subdirectory(${SPIKES_DIR}/lk_event_queue)
add_subdirectory(${SPIKES_DIR}/lk_lcd)
add_subdirectory(${SPIKES_DIR}/lk_led)
add_subdirectory(${SPIKES_DIR}/lk_led_kit)
add_subdirectory(${SPIKES_DIR}/lk_coreled)
add_subdirectory(${SPIKES_DIR}/lk_color_kit)
add_subdirectory(${SPIKES_DIR}/lk_rfid)
Expand Down
23 changes: 23 additions & 0 deletions spikes/lk_led_kit/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Leka - LekaOS
# Copyright 2022 APF France handicap
# SPDX-License-Identifier: Apache-2.0

add_mbed_executable(spike_lk_led_kit)

target_include_directories(spike_lk_led_kit
PRIVATE
.
)

target_sources(spike_lk_led_kit
PRIVATE
main.cpp
)

target_link_libraries(spike_lk_led_kit
CoreLED
ColorKit
LedKit
)

target_link_custom_leka_targets(spike_lk_led_kit)
67 changes: 67 additions & 0 deletions spikes/lk_led_kit/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Leka - LekaOS
// Copyright 2022 APF France handicap
// SPDX-License-Identifier: Apache-2.0

#include "PinNames.h"

#include "drivers/HighResClock.h"
#include "rtos/ThisThread.h"

#include "CoreLED.h"
#include "CoreSPI.h"
#include "HelloWorld.h"
#include "LedKit.h"
#include "LogKit.h"

using namespace leka;
using namespace std::chrono;

auto corespi_belt = CoreSPI {LED_BELT_SPI_MOSI, NC, LED_BELT_SPI_SCK};
auto corespi_ears = CoreSPI {LED_EARS_SPI_MOSI, NC, LED_EARS_SPI_SCK};

auto ears = CoreLED<LedKit::kNumberOfLedsEars> {corespi_ears};
auto belt = CoreLED<LedKit::kNumberOfLedsBelt> {corespi_belt};

auto animation_thread = rtos::Thread {};
auto animation_event_queue = events::EventQueue {};

auto ledkit = LedKit {animation_thread, animation_event_queue, ears, belt};

auto colors_available = std::to_array({
RGB::pure_green,
RGB::pure_red,
RGB::pure_blue,
RGB::yellow,
RGB::cyan,
RGB::magenta,
});

HelloWorld hello;

RGB sick1 = RGB {30, 255, 0};
RGB sick2 = RGB {94, 104, 1};
RGB singing_green = RGB {29, 168, 0};
RGB singing_red = RGB {255, 65, 61};
RGB singing_yellow = RGB {255, 217, 61};
RGB singing_blue = RGB {21, 125, 230};

RGB red_angry = RGB {255, 98, 98};

auto main() -> int
{
logger::init();

log_info("Hello, World!\n\n");

auto start = rtos::Kernel::Clock::now();

rtos::ThisThread::sleep_for(2s);

hello.start();

while (true) {
auto t = rtos::Kernel::Clock::now() - start;
log_info("A message from your board %s --> \"%s\" at %i s\n", MBED_CONF_APP_TARGET_NAME, hello.world,
int(t.count() / 1000));
}
}
1 change: 1 addition & 0 deletions tests/unit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ leka_register_unit_tests_for_library(IOKit)
leka_register_unit_tests_for_library(BLEKit)
leka_register_unit_tests_for_library(RobotKit)
leka_register_unit_tests_for_library(ColorKit)
leka_register_unit_tests_for_library(LedKit)

#
# Mark: - Finish up
Expand Down
20 changes: 20 additions & 0 deletions tests/unit/mocks/mocks/leka/LEDAnimation.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Leka - LekaOS
// Copyright 2022 APF France handicap
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include "LedKit.h"
#include "gmock/gmock.h"

namespace leka::animation {

class LEDAnimationMock : public interface::LEDAnimation
{
public:
MOCK_METHOD(void, start, (), (override));
MOCK_METHOD(void, stop, (), (override));
MOCK_METHOD(void, run, (), (override));
};

} // namespace leka::animation

0 comments on commit f0f8cd3

Please sign in to comment.