Skip to content

Commit

Permalink
Added new platform: Particle Photon board.
Browse files Browse the repository at this point in the history
  • Loading branch information
ashtuchkin committed Mar 19, 2017
1 parent 57c29cb commit 1671118
Show file tree
Hide file tree
Showing 69 changed files with 1,366 additions and 561 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@

# CMake build
build/*

# External lib files
libs/particle-firmware
76 changes: 16 additions & 60 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,70 +1,26 @@
cmake_minimum_required(VERSION 3.2)

set(CMAKE_DISABLE_SOURCE_CHANGES ON)
#set(CMAKE_VERBOSE_MAKEFILE TRUE)
set(CMAKE_CXX_STANDARD 14)

set(SOURCE_FILES
src/cycle_phase_classifier.cpp
src/data_frame_decoder.cpp
src/formatters.cpp
src/geometry.cpp
src/input.cpp
src/mavlink.cpp
src/pulse_processor.cpp
src/primitives/string_utils.cpp
)

set(PLATFORM_SPECIFIC_SOURCE_FILES
src/main.cpp
src/settings.cpp
src/debug_node.cpp
src/input_cmp.cpp
src/led_state.cpp
src/outputs.cpp
src/platform.cpp
src/vive_sensors_pipeline.cpp
src/primitives/timestamp.cpp
)

set(TEST_SOURCE_FILES
test/main_test.cpp
test/platform_mocks.cpp
test/test_pulse_processor.cpp
)

if (NOT TEST_MODE)
set(CMAKE_TOOLCHAIN_FILE "teensy-arm.toolchain.cmake")

if (${PLATFORM} MATCHES "Teensy")
set(CMAKE_TOOLCHAIN_FILE "platform-teensy/teensy-arm.toolchain.cmake")
project(vive-diy-position-sensor)
add_subdirectory(platform-teensy)
add_subdirectory(src)

add_executable(vive-diy-position-sensor "${SOURCE_FILES}" "${PLATFORM_SPECIFIC_SOURCE_FILES}")
add_firmware_targets(vive-diy-position-sensor)

import_cmsis_dsp_library(vive-diy-position-sensor)
import_arduino_library(vive-diy-position-sensor mavlink_v2)
elseif (${PLATFORM} MATCHES "Particle")
set(CMAKE_TOOLCHAIN_FILE "platform-particle/stm32f2xx.toolchain.cmake")
project(vive-diy-position-sensor)
add_subdirectory(platform-particle)
add_subdirectory(src)

else()
elseif (${PLATFORM} MATCHES "Host_Test")
# Need to define project at the top level to be able to call ctest from build directory
set(CMAKE_TOOLCHAIN_FILE "test/32bit.toolchain.cmake")
project(vive-diy-position-sensor)
include(CTest)
add_subdirectory(test)
add_subdirectory(src)

# Compile 32 bit code
add_compile_options("-m32")
link_libraries("-m32")
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options("-Wno-deprecated-register" "-Wno-unknown-attributes")
endif()

# Compile CMSIS as a library.
set(CMSIS_ROOT "${CMAKE_SOURCE_DIR}/libs/CMSIS/CMSIS" CACHE PATH "Path to the CMSIS root directory")
file(GLOB_RECURSE CMSIS_CORE_FILES "${CMSIS_ROOT}/DSP_Lib/Source/*_f32.c")
add_library(CMSIS "${CMSIS_CORE_FILES}" "${CMSIS_ROOT}/DSP_Lib/Source/CommonTables/arm_common_tables.c")
target_compile_definitions(CMSIS PUBLIC "-DARM_MATH_CM4")
link_libraries(CMSIS)
else()
message(FATAL_ERROR "Please provide PLATFORM env variable")

# We have only one test executable
add_definitions("-DNEW_H") # Don't include new.h header as it defines non-standard operator new().
include_directories("libs/Catch" "libs/CMSIS/CMSIS/Include" "libs/cores/teensy3" "libs/mavlink_v2" "src")
add_executable(main-test "${TEST_SOURCE_FILES}" "${SOURCE_FILES}")
add_test(main-test main-test)
endif()
27 changes: 17 additions & 10 deletions cmake-variants.json
Original file line number Diff line number Diff line change
@@ -1,23 +1,30 @@
{
"buildType": {
"default$": "debug",
"default$": "teensy",
"description$": "the build type to use",
"debug": {
"oneWordSummary$": "Debug",
"description$": "Enable optimizations, include debug info",
"buildType": "Debug"
"teensy": {
"oneWordSummary$": "Teensy",
"description$": "Create firmware for Teensy",
"buildType": "Debug",
"settings": {
"PLATFORM": "Teensy"
}
},
"release": {
"oneWordSummary$": "Release",
"description$": "Enable optimizations, omit debug info",
"buildType": "Release"
"particle": {
"oneWordSummary$": "Photon",
"description$": "Create library for Particle Photon",
"buildType": "Debug",
"settings": {
"PLATFORM": "Particle",
"PARTICLE_PLATFORM": "photon"
}
},
"test": {
"oneWordSummary$": "Test",
"description$": "Test the project",
"buildType": "Debug",
"settings": {
"TEST_MODE": "TRUE",
"PLATFORM": "Host_Test",
"CMAKE_C_COMPILER": "/usr/local/bin/gcc-6",
"CMAKE_CXX_COMPILER": "/usr/local/bin/g++-6"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class CyclePhaseClassifier {

// Print debug information.
virtual bool debug_cmd(HashedWord *input_words);
virtual void debug_print(Print& stream);
virtual void debug_print(PrintStream &stream);

private:
float expected_pulse_len(bool skip, bool data, bool axis);
Expand Down
2 changes: 1 addition & 1 deletion src/data_frame_decoder.h → include/data_frame_decoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class DataFrameDecoder
virtual void consume(const DataFrameBit &bit);

virtual bool debug_cmd(HashedWord *input_words);
virtual void debug_print(Print& stream);
virtual void debug_print(PrintStream &stream);

private:
void reset();
Expand Down
6 changes: 5 additions & 1 deletion src/debug_node.h → include/debug_node.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once
#include "primitives/workers.h"
#include "primitives/producer_consumer.h"
#include "primitives/string_utils.h"
#include "print_helpers.h"

// This node calls debug_cmd and debug_print for all pipeline nodes periodically,
Expand All @@ -16,7 +17,7 @@ class DebugNode
virtual void consume_line(char *line, Timestamp time);
virtual void do_work(Timestamp cur_time);
virtual bool debug_cmd(HashedWord *input_words);
virtual void debug_print(Print &stream);
virtual void debug_print(PrintStream &stream);

private:
void set_output_attached(bool attached);
Expand All @@ -28,3 +29,6 @@ class DebugNode
bool output_attached_;
bool print_debug_memory_;
};

// This function needs to be defined by the platform.
void print_platform_memory_info(PrintStream &stream);
8 changes: 4 additions & 4 deletions src/formatters.h → include/formatters.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ struct FormatterDef {
CoordSysType coord_sys_type;
CoordSysDef coord_sys_params;

void print_def(uint32_t idx, Print &stream);
bool parse_def(uint32_t idx, HashedWord *input_words, Print &err_stream);
void print_def(uint32_t idx, PrintStream &stream);
bool parse_def(uint32_t idx, HashedWord *input_words, PrintStream &err_stream);
};


Expand All @@ -35,7 +35,7 @@ class FormatterNode
, public Producer<DataChunk> {
public:
virtual bool debug_cmd(HashedWord *input_words);
virtual void debug_print(Print& stream);
virtual void debug_print(PrintStream &stream);

protected:
FormatterNode(uint32_t idx, const FormatterDef &def);
Expand Down Expand Up @@ -79,7 +79,7 @@ class GeometryMavlinkFormatter : public GeometryFormatter {
virtual void consume(const ObjectPosition& f);

virtual bool debug_cmd(HashedWord *input_words);
virtual void debug_print(Print& stream);
virtual void debug_print(PrintStream &stream);

private:
bool position_valid(const ObjectPosition& g);
Expand Down
12 changes: 6 additions & 6 deletions src/geometry.h → include/geometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ struct BaseStationGeometryDef {
float mat[9]; // Normalized rotation matrix.
vec3d origin; // Origin point

void print_def(uint32_t idx, Print &stream);
bool parse_def(uint32_t idx, HashedWord *input_words, Print &err_stream);
void print_def(uint32_t idx, PrintStream &stream);
bool parse_def(uint32_t idx, HashedWord *input_words, PrintStream &err_stream);
};

struct SensorLocalGeometry {
Expand All @@ -26,8 +26,8 @@ struct SensorLocalGeometry {
struct GeometryBuilderDef {
Vector<SensorLocalGeometry, 4> sensors;

void print_def(uint32_t idx, Print &stream);
bool parse_def(uint32_t idx, HashedWord *input_words, Print &err_stream);
void print_def(uint32_t idx, PrintStream &stream);
bool parse_def(uint32_t idx, HashedWord *input_words, PrintStream &err_stream);
};

// Parent, abstract class for GeometryBuilders.
Expand All @@ -54,7 +54,7 @@ class PointGeometryBuilder : public GeometryBuilder {
virtual void do_work(Timestamp cur_time);

virtual bool debug_cmd(HashedWord *input_words);
virtual void debug_print(Print& stream);
virtual void debug_print(PrintStream &stream);

private:
ObjectPosition pos_;
Expand Down Expand Up @@ -89,7 +89,7 @@ class CoordinateSystemConverter

virtual void consume(const ObjectPosition& geo);
virtual bool debug_cmd(HashedWord *input_words);
virtual void debug_print(Print& stream);
virtual void debug_print(PrintStream &stream);

private:
float mat_[9];
Expand Down
13 changes: 6 additions & 7 deletions src/input.h → include/input.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
#include "primitives/workers.h"
#include "primitives/producer_consumer.h"
#include "primitives/circular_buffer.h"
#include "primitives/static_registration.h"
#include "messages.h"

// We can use different Teensy hardware features to measure pulse timing, each with different pros and cons.
// Look into each input type's header for details.
enum class InputType {
kCMP = 0, // Comparator
kFTM = 1, // Flexible Timer Module interrupts
kTimer = 1,// Timer Module interrupts
kPort = 2, // Digital input interrupt
};
constexpr int kInputTypeCount = 3;
Expand All @@ -20,8 +21,8 @@ struct InputDef {
InputType input_type;
uint32_t initial_cmp_threshold;

void print_def(uint32_t idx, Print &stream);
bool parse_def(uint32_t idx, HashedWord *input_words, Print &err_stream);
void print_def(uint32_t idx, PrintStream &stream);
bool parse_def(uint32_t idx, HashedWord *input_words, PrintStream &err_stream);
};


Expand All @@ -32,10 +33,11 @@ class InputNode
public:
// Create input node of needed type from given configuration.
static std::unique_ptr<InputNode> create(uint32_t input_idx, const InputDef &def);
typedef StaticRegistrar<decltype(create)*> CreatorRegistrar;

virtual void do_work(Timestamp cur_time);
virtual bool debug_cmd(HashedWord *input_words);
virtual void debug_print(Print& stream);
virtual void debug_print(PrintStream &stream);

protected:
InputNode(uint32_t input_idx);
Expand All @@ -49,6 +51,3 @@ class InputNode
static constexpr int pulses_buffer_len = 32;
CircularBuffer<Pulse, pulses_buffer_len> pulses_buf_;
};

// Create functions for each supported input types.
std::unique_ptr<InputNode> createInputCmpNode(uint32_t input_idx, const InputDef &input_def);
File renamed without changes.
File renamed without changes.
26 changes: 9 additions & 17 deletions src/outputs.h → include/outputs.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#pragma once
#include "primitives/workers.h"
#include "primitives/producer_consumer.h"
#include "primitives/static_registration.h"
#include "messages.h"

// Currently supported: usb serial + 3x hardware serials.
Expand All @@ -12,43 +13,34 @@ struct OutputDef {
bool active;
uint32_t bitrate;

void print_def(uint32_t idx, Print &stream);
bool parse_def(uint32_t idx, HashedWord *input_words, Print &err_stream);
void print_def(uint32_t idx, PrintStream &stream);
bool parse_def(uint32_t idx, HashedWord *input_words, PrintStream &err_stream);
};

class Stream;

class OutputNode
: public WorkerNode
, public Consumer<DataChunk>
, public Consumer<OutputCommand>
, public Producer<DataChunk> {
public:
static std::unique_ptr<OutputNode> create(uint32_t idx, const OutputDef& def);
typedef StaticRegistrar<decltype(create)*> CreatorRegistrar;

// Common methods that do i/o with the stream_ object.
virtual void consume(const DataChunk &chunk);
virtual void consume(const OutputCommand& cmd);
virtual void do_work(Timestamp cur_time);

protected:
OutputNode(uint32_t idx, const OutputDef& def, Stream &stream);
OutputNode(uint32_t idx, const OutputDef& def);

virtual size_t write(const uint8_t *buffer, size_t size) = 0;
virtual int read() = 0;

uint32_t node_idx_;
OutputDef def_;
Stream &stream_;
DataChunk chunk_;
bool exclusive_mode_;
uint32_t exclusive_stream_idx_;
};


class UsbSerialOutputNode : public OutputNode {
public:
UsbSerialOutputNode(uint32_t idx, const OutputDef& def);
};

class HardwareSerialOutputNode : public OutputNode {
public:
HardwareSerialOutputNode(uint32_t idx, const OutputDef& def);
virtual void start();
};
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
36 changes: 36 additions & 0 deletions include/primitives/static_registration.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#pragma once

// Class to help with (almost) compile-time class registration.
// To use, add static instance of this class to the class that needs registering and provide creation
// function. Then, you'll be able to iterate over all creation functions.
template<typename T>
struct StaticRegistrar {
StaticRegistrar(const T &val)
: val_(val) {
next_ = instance;
instance = this;
}
struct iterator {
const T &operator*() const { return cur->val_; }
iterator &operator++() { cur = cur->next_; return *this; }
bool operator!=(const iterator &it) const { return cur != it.cur; }
friend StaticRegistrar;
protected:
iterator(const StaticRegistrar *val): cur(val) {}
private:
const StaticRegistrar *cur;
};
struct iteration_range {
iterator begin() { return instance; }
iterator end() { return nullptr; }
};
static iteration_range iterate() { return {}; }

private:
const T val_;
StaticRegistrar *next_;
static StaticRegistrar *instance;
};

template<typename T>
StaticRegistrar<T> *StaticRegistrar<T>::instance = nullptr;
File renamed without changes.
Loading

0 comments on commit 1671118

Please sign in to comment.