mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-11-01 09:51:36 +08:00
182 lines
4.3 KiB
C++
182 lines
4.3 KiB
C++
/*
|
|
* Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
|
|
*/
|
|
|
|
#include <cstdio>
|
|
#include <algorithm>
|
|
#include <board.hpp>
|
|
#include <chip.h>
|
|
#include <uavcan_lpc11c24/uavcan_lpc11c24.hpp>
|
|
#include <uavcan/protocol/global_time_sync_slave.hpp>
|
|
#include <uavcan/protocol/logger.hpp>
|
|
|
|
namespace
|
|
{
|
|
|
|
static constexpr unsigned NodeMemoryPoolSize = 2800;
|
|
|
|
/**
|
|
* This is a compact, reentrant and thread-safe replacement to standard llto().
|
|
* It returns the string by value, no extra storage is needed.
|
|
*/
|
|
typename uavcan::MakeString<22>::Type intToString(long long n)
|
|
{
|
|
char buf[24] = {};
|
|
const short sign = (n < 0) ? -1 : 1;
|
|
if (sign < 0)
|
|
{
|
|
n = -n;
|
|
}
|
|
unsigned pos = 0;
|
|
do
|
|
{
|
|
buf[pos++] = char(n % 10 + '0');
|
|
}
|
|
while ((n /= 10) > 0);
|
|
if (sign < 0)
|
|
{
|
|
buf[pos++] = '-';
|
|
}
|
|
buf[pos] = '\0';
|
|
for (unsigned i = 0, j = pos - 1U; i < j; i++, j--)
|
|
{
|
|
std::swap(buf[i], buf[j]);
|
|
}
|
|
return static_cast<const char*>(buf);
|
|
}
|
|
|
|
uavcan::Node<NodeMemoryPoolSize>& getNode()
|
|
{
|
|
static uavcan::Node<NodeMemoryPoolSize> node(uavcan_lpc11c24::CanDriver::instance(),
|
|
uavcan_lpc11c24::SystemClock::instance());
|
|
return node;
|
|
}
|
|
|
|
uavcan::GlobalTimeSyncSlave& getTimeSyncSlave()
|
|
{
|
|
static uavcan::GlobalTimeSyncSlave tss(getNode());
|
|
return tss;
|
|
}
|
|
|
|
uavcan::Logger& getLogger()
|
|
{
|
|
static uavcan::Logger logger(getNode());
|
|
return logger;
|
|
}
|
|
|
|
#if __GNUC__
|
|
__attribute__((noinline))
|
|
#endif
|
|
void init()
|
|
{
|
|
board::resetWatchdog();
|
|
board::syslog("Boot\r\n");
|
|
|
|
board::setErrorLed(false);
|
|
board::setStatusLed(true);
|
|
|
|
/*
|
|
* Configuring the clock - this must be done before the CAN controller is initialized
|
|
*/
|
|
uavcan_lpc11c24::clock::init();
|
|
|
|
/*
|
|
* Configuring the CAN controller
|
|
*/
|
|
std::uint32_t bit_rate = 0;
|
|
while (bit_rate == 0)
|
|
{
|
|
board::syslog("CAN bitrate detection...\r\n");
|
|
bit_rate = uavcan_lpc11c24::CanDriver::detectBitRate(&board::resetWatchdog);
|
|
}
|
|
board::syslog("CAN bitrate: ");
|
|
board::syslog(intToString(bit_rate).c_str());
|
|
board::syslog("\r\n");
|
|
|
|
if (uavcan_lpc11c24::CanDriver::instance().init(bit_rate) < 0)
|
|
{
|
|
board::die();
|
|
}
|
|
board::syslog("CAN init ok\r\n");
|
|
|
|
board::resetWatchdog();
|
|
|
|
/*
|
|
* Configuring the node
|
|
*/
|
|
getNode().setName("org.uavcan.lpc11c24_test");
|
|
|
|
uavcan::protocol::SoftwareVersion swver;
|
|
swver.major = FW_VERSION_MAJOR;
|
|
swver.minor = FW_VERSION_MINOR;
|
|
swver.vcs_commit = GIT_HASH;
|
|
swver.optional_field_flags = swver.OPTIONAL_FIELD_FLAG_VCS_COMMIT;
|
|
getNode().setSoftwareVersion(swver);
|
|
|
|
uavcan::protocol::HardwareVersion hwver;
|
|
std::uint8_t uid[board::UniqueIDSize] = {};
|
|
board::readUniqueID(uid);
|
|
std::copy(std::begin(uid), std::end(uid), std::begin(hwver.unique_id));
|
|
getNode().setHardwareVersion(hwver);
|
|
|
|
board::resetWatchdog();
|
|
|
|
/*
|
|
* Performing dynamic node ID allocation
|
|
*/
|
|
getNode().setNodeID(72); // TODO
|
|
|
|
/*
|
|
* Starting the node
|
|
*/
|
|
while (getNode().start() < 0)
|
|
{
|
|
}
|
|
|
|
board::resetWatchdog();
|
|
|
|
while (getTimeSyncSlave().start() < 0)
|
|
{
|
|
}
|
|
|
|
while (getLogger().init() < 0)
|
|
{
|
|
}
|
|
getLogger().setLevel(uavcan::protocol::debug::LogLevel::DEBUG);
|
|
|
|
board::resetWatchdog();
|
|
}
|
|
|
|
}
|
|
|
|
int main()
|
|
{
|
|
init();
|
|
|
|
getNode().setModeOperational();
|
|
|
|
uavcan::MonotonicTime prev_log_at;
|
|
|
|
while (true)
|
|
{
|
|
const int res = getNode().spin(uavcan::MonotonicDuration::fromMSec(25));
|
|
board::setErrorLed(res < 0);
|
|
board::setStatusLed(uavcan_lpc11c24::CanDriver::instance().hadActivity());
|
|
|
|
const auto ts = uavcan_lpc11c24::clock::getMonotonic();
|
|
if ((ts - prev_log_at).toMSec() >= 1000)
|
|
{
|
|
prev_log_at = ts;
|
|
// We don't want to use formatting functions provided by libuavcan because they rely on std::snprintf()
|
|
// hence we need to construct the message manually:
|
|
uavcan::protocol::debug::LogMessage logmsg;
|
|
logmsg.level.value = uavcan::protocol::debug::LogLevel::INFO;
|
|
logmsg.source = "app";
|
|
logmsg.text = intToString(uavcan_lpc11c24::clock::getPrevUtcAdjustment().toUSec()).c_str();
|
|
(void)getLogger().log(logmsg);
|
|
}
|
|
|
|
board::resetWatchdog();
|
|
}
|
|
}
|