diff --git a/libuavcan_drivers/stm32/driver/include/uavcan_stm32/can.hpp b/libuavcan_drivers/stm32/driver/include/uavcan_stm32/can.hpp new file mode 100644 index 0000000000..599aaa6e78 --- /dev/null +++ b/libuavcan_drivers/stm32/driver/include/uavcan_stm32/can.hpp @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2014 Pavel Kirienko + */ + +#pragma once + +#if UAVCAN_STM32_CHIBIOS +# include +#else +# error "Unknown OS" +#endif + +#include + +namespace uavcan_stm32 +{ + +enum { CanFiltersPerIface = 14 }; + + +class CanIface : public uavcan::ICanIface +{ + CAN_TypeDef* can_; + + uavcan::uint64_t error_cnt_; + +public: + virtual uavcan::int16_t send(const uavcan::CanFrame& frame, uavcan::MonotonicTime tx_deadline, + uavcan::CanIOFlags flags); + + virtual uavcan::int16_t receive(uavcan::CanFrame& out_frame, uavcan::MonotonicTime& out_ts_monotonic, + uavcan::UtcTime& out_ts_utc, uavcan::CanIOFlags& out_flags); + + virtual uavcan::int16_t configureFilters(const uavcan::CanFilterConfig* filter_configs, + uavcan::uint16_t num_configs); + + virtual uavcan::uint16_t getNumFilters() const { return CanFiltersPerIface; } + + virtual uavcan::uint64_t getErrorCount() const { return error_cnt_; } +}; + +} diff --git a/libuavcan_drivers/stm32/driver/include/uavcan_stm32/thread.hpp b/libuavcan_drivers/stm32/driver/include/uavcan_stm32/thread.hpp new file mode 100644 index 0000000000..4e80705ce9 --- /dev/null +++ b/libuavcan_drivers/stm32/driver/include/uavcan_stm32/thread.hpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2014 Pavel Kirienko + */ + +#pragma once + +#if UAVCAN_STM32_CHIBIOS +# include +#else +# error "Unknown OS" +#endif + +#include + +namespace uavcan_stm32 +{ + +#if UAVCAN_STM32_CHIBIOS + +class Event +{ + chibios_rt::CounterSemaphore sem_; + +public: + Event() : sem_(0) { } + + bool wait(uavcan::MonotonicDuration duration); + + void signal(); + + void signalFromInterrupt(); +}; + +#endif + +} diff --git a/libuavcan_drivers/stm32/driver/include/uavcan_stm32/uavcan_stm32.hpp b/libuavcan_drivers/stm32/driver/include/uavcan_stm32/uavcan_stm32.hpp new file mode 100644 index 0000000000..32947f5587 --- /dev/null +++ b/libuavcan_drivers/stm32/driver/include/uavcan_stm32/uavcan_stm32.hpp @@ -0,0 +1,8 @@ +/* + * Copyright (C) 2014 Pavel Kirienko + */ + +#pragma once + +#include +#include diff --git a/libuavcan_drivers/stm32/driver/src/uc_stm32_can.cpp b/libuavcan_drivers/stm32/driver/src/uc_stm32_can.cpp new file mode 100644 index 0000000000..d3902a7bcb --- /dev/null +++ b/libuavcan_drivers/stm32/driver/src/uc_stm32_can.cpp @@ -0,0 +1,5 @@ +/* + * Copyright (C) 2014 Pavel Kirienko + */ + +#include diff --git a/libuavcan_drivers/stm32/driver/src/uc_stm32_thread.cpp b/libuavcan_drivers/stm32/driver/src/uc_stm32_thread.cpp new file mode 100644 index 0000000000..4bdeedece9 --- /dev/null +++ b/libuavcan_drivers/stm32/driver/src/uc_stm32_thread.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2014 Pavel Kirienko + */ + +#include + +namespace uavcan_stm32 +{ + +#if UAVCAN_STM32_CHIBIOS + +bool Event::wait(uavcan::MonotonicDuration duration) +{ + msg_t ret = msg_t(); + if (duration.isZero()) + { + sem_.waitTimeout(TIME_IMMEDIATE); + } + else + { + sem_.waitTimeout(US2ST(duration.toUSec())); + } + return ret == RDY_OK; +} + +void Event::signal() +{ + sem_.signal(); +} + +void Event::signalFromInterrupt() +{ + sem_.signalI(); +} + +#endif + +} diff --git a/libuavcan_drivers/stm32/test_stm32f107/Makefile b/libuavcan_drivers/stm32/test_stm32f107/Makefile index 280ac656c2..ef309be651 100644 --- a/libuavcan_drivers/stm32/test_stm32f107/Makefile +++ b/libuavcan_drivers/stm32/test_stm32f107/Makefile @@ -10,6 +10,8 @@ PROJECT = uavcan_test_stm32f107 CPPSRC = src/main.cpp src/dummy.cpp +UDEFS = -DUAVCAN_STM32_CHIBIOS=1 + # # UAVCAN library # @@ -23,7 +25,7 @@ CPPSRC += $(LIBUAVCAN_STM32_SRC) UINCDIR += $(LIBUAVCAN_STM32_INC) # TODO: add target for this -$(info $(shell $(LIBUAVCAN_DSDLC) $(UAVCAN_DSDL_DIR) -v)) +$(info $(shell $(LIBUAVCAN_DSDLC) $(UAVCAN_DSDL_DIR))) UINCDIR += dsdlc_generated # @@ -36,7 +38,4 @@ UINCDIR += src/sys SERIAL_CLI_PORT_NUMBER = 2 -RELEASE_OPT = -Os -fomit-frame-pointer -DEBUG_OPT = -Os -g3 - include crdr_chibios/rules_stm32f105_107.mk diff --git a/libuavcan_drivers/stm32/test_stm32f107/src/main.cpp b/libuavcan_drivers/stm32/test_stm32f107/src/main.cpp index 2a98dc0cdf..c71ef0da12 100644 --- a/libuavcan_drivers/stm32/test_stm32f107/src/main.cpp +++ b/libuavcan_drivers/stm32/test_stm32f107/src/main.cpp @@ -2,6 +2,77 @@ * Copyright (C) 2014 Pavel Kirienko */ +#include +#include +#include + +namespace app +{ +namespace +{ + +void ledSet(bool state) +{ + palWritePad(GPIO_PORT_LED, GPIO_PIN_LED, state); +} + +int init() +{ + halInit(); + chibios_rt::System::init(); + sdStart(&STDOUT_SD, NULL); + + return 0; +} + +__attribute__((noreturn)) +void die(int status) +{ + lowsyslog("Now I am dead x_x %i\n", status); + while (1) { + ledSet(false); + sleep(1); + ledSet(true); + sleep(1); + } +} + + +uavcan_stm32::Event led_turn_off_event; + +class : public chibios_rt::BaseStaticThread<512> +{ + msg_t main() + { + while (true) + { + led_turn_off_event.wait(uavcan::MonotonicDuration::getInfinite()); + ledSet(false); + } + return msg_t(); + } +} led_turn_off_executor; + +} +} + int main() { + const int init_res = app::init(); + if (init_res != 0) + { + app::die(init_res); + } + + app::led_turn_off_executor.start(LOWPRIO); + + puts("Hello world"); + + while (true) + { + sleep(1); + app::ledSet(true); + sleep(1); + app::led_turn_off_event.signal(); + } }