This commit is contained in:
parent
c335211ef8
commit
60bad24319
@ -5,8 +5,8 @@
|
|||||||
* Author: erki
|
* Author: erki
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MESSAGING_INC_MESSAGING_PACKET_HPP_
|
#ifndef SKULLC_MESSAGING_PACKET_HPP_
|
||||||
#define MESSAGING_INC_MESSAGING_PACKET_HPP_
|
#define SKULLC_MESSAGING_PACKET_HPP_
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
@ -106,4 +106,4 @@ constexpr std::uint8_t Packet<N>::preamble[2];
|
|||||||
|
|
||||||
}// namespace Messaging
|
}// namespace Messaging
|
||||||
|
|
||||||
#endif /* MESSAGING_INC_MESSAGING_PACKET_HPP_ */
|
#endif /* SKULLC_MESSAGING_PACKET_HPP_ */
|
||||||
|
|||||||
@ -2,8 +2,8 @@
|
|||||||
// Created by erki on 27.03.21.
|
// Created by erki on 27.03.21.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef SKULLC_MESSAGING_PARSER_HPP
|
#ifndef SKULLC_MESSAGING_PARSER_HPP_
|
||||||
#define SKULLC_MESSAGING_PARSER_HPP
|
#define SKULLC_MESSAGING_PARSER_HPP_
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
@ -27,10 +27,10 @@ public:
|
|||||||
|
|
||||||
void reset()
|
void reset()
|
||||||
{
|
{
|
||||||
_state = _State::Preamble;
|
state_ = State_::Preamble;
|
||||||
_expected = sizeof(P::preamble);
|
expected_ = sizeof(P::preamble);
|
||||||
_current_pos = 0;
|
current_pos_ = 0;
|
||||||
_current_offset = 0;
|
current_offset_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pushByte(const std::uint8_t byte)
|
void pushByte(const std::uint8_t byte)
|
||||||
@ -38,41 +38,41 @@ public:
|
|||||||
if (packetReady())
|
if (packetReady())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const std::uint32_t buffer_loc = _current_offset + _current_pos;
|
const std::uint32_t buffer_loc = current_offset_ + current_pos_;
|
||||||
|
|
||||||
switch (_state)
|
switch (state_)
|
||||||
{
|
{
|
||||||
case _State::Preamble:
|
case State_::Preamble:
|
||||||
if (byte != P::preamble[_current_pos])
|
if (byte != P::preamble[current_pos_])
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
case _State::Length:
|
case State_::Length:
|
||||||
case _State::Body:
|
case State_::Body:
|
||||||
_buffer[buffer_loc] = byte;
|
buffer_[buffer_loc] = byte;
|
||||||
_current_pos++;
|
current_pos_++;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_current_pos == _expected)
|
if (current_pos_ == expected_)
|
||||||
{
|
{
|
||||||
_setupNextState();
|
setupNextState_();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool packetReady() const { return _state == _State::Done; }
|
bool packetReady() const { return state_ == State_::Done; }
|
||||||
|
|
||||||
bool getPacket(Packet& packet) const
|
bool getPacket(Packet& packet) const
|
||||||
{
|
{
|
||||||
return packet.deserialize(_buffer.data(), _current_offset);
|
return packet.deserialize(buffer_.data(), current_offset_);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class _State : std::uint32_t
|
enum class State_ : std::uint32_t
|
||||||
{
|
{
|
||||||
Preamble,
|
Preamble,
|
||||||
Length,
|
Length,
|
||||||
@ -80,17 +80,17 @@ private:
|
|||||||
Done
|
Done
|
||||||
};
|
};
|
||||||
|
|
||||||
std::array<std::uint8_t, N> _buffer;
|
std::array<std::uint8_t, N> buffer_;
|
||||||
_State _state = _State::Preamble;
|
State_ state_ = State_::Preamble;
|
||||||
|
|
||||||
std::uint32_t _current_pos = 0;
|
std::uint32_t current_pos_ = 0;
|
||||||
std::uint32_t _current_offset = 0;
|
std::uint32_t current_offset_ = 0;
|
||||||
std::uint32_t _expected = 0;
|
std::uint32_t expected_ = 0;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T _deserializeLength(const std::uint32_t offset)
|
T deserializeLength_(const std::uint32_t offset)
|
||||||
{
|
{
|
||||||
std::uint8_t* begin = _buffer.data() + offset;
|
std::uint8_t* begin = buffer_.data() + offset;
|
||||||
T len(0);
|
T len(0);
|
||||||
|
|
||||||
std::memcpy(&len, begin, sizeof(T));
|
std::memcpy(&len, begin, sizeof(T));
|
||||||
@ -98,30 +98,30 @@ private:
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _setupNextState()
|
void setupNextState_()
|
||||||
{
|
{
|
||||||
switch (_state)
|
switch (state_)
|
||||||
{
|
{
|
||||||
case _State::Preamble:
|
case State_::Preamble:
|
||||||
_state = _State::Length;
|
state_ = State_::Length;
|
||||||
_expected = sizeof(typename P::length_type);
|
expected_ = sizeof(typename P::length_type);
|
||||||
break;
|
break;
|
||||||
case _State::Length:
|
case State_::Length:
|
||||||
_state = _State::Body;
|
state_ = State_::Body;
|
||||||
_expected = _deserializeLength<typename P::length_type>(_current_offset);
|
expected_ = deserializeLength_<typename P::length_type>(current_offset_);
|
||||||
break;
|
break;
|
||||||
case _State::Body:
|
case State_::Body:
|
||||||
_state = _State::Done;
|
state_ = State_::Done;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
_current_offset += _current_pos;
|
current_offset_ += current_pos_;
|
||||||
_current_pos = 0;
|
current_pos_ = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}// namespace Messaging
|
}// namespace Messaging
|
||||||
|
|
||||||
#endif// SKULLC_MESSAGING_PARSER_HPP
|
#endif// SKULLC_MESSAGING_PARSER_HPP_
|
||||||
|
|||||||
@ -5,8 +5,8 @@
|
|||||||
* Author: erki
|
* Author: erki
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PERIPHERALS_INC_PERIPHERALS_ADC_HPP_
|
#ifndef SKULLC_PERIPHERALS_ADC_HPP_
|
||||||
#define PERIPHERALS_INC_PERIPHERALS_ADC_HPP_
|
#define SKULLC_PERIPHERALS_ADC_HPP_
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
@ -59,4 +59,4 @@ struct Adc
|
|||||||
|
|
||||||
}// namespace Peripherals
|
}// namespace Peripherals
|
||||||
|
|
||||||
#endif /* PERIPHERALS_INC_PERIPHERALS_ADC_HPP_ */
|
#endif /* SKULLC_PERIPHERALS_ADC_HPP_ */
|
||||||
|
|||||||
@ -5,8 +5,8 @@
|
|||||||
* Author: erki
|
* Author: erki
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PERIPHERALS_BUTTON_HPP_
|
#ifndef SKULLC_PERIPHERALS_BUTTON_HPP_
|
||||||
#define PERIPHERALS_BUTTON_HPP_
|
#define SKULLC_PERIPHERALS_BUTTON_HPP_
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
@ -39,38 +39,38 @@ public:
|
|||||||
|
|
||||||
void update()
|
void update()
|
||||||
{
|
{
|
||||||
const bool is_pressed = sw.Read();
|
const bool is_pressed = sw.read();
|
||||||
ButtonPress new_state = ButtonPress::NOT_PRESSED;
|
ButtonPress new_state = ButtonPress::NOT_PRESSED;
|
||||||
|
|
||||||
if (is_pressed && !_was_pressed)
|
if (is_pressed && !was_pressed_)
|
||||||
{
|
{
|
||||||
_time_pressed_down = hal::GetMillis();
|
time_pressed_down_ = hal::getMillis();
|
||||||
} else if (!is_pressed && _was_pressed)
|
} else if (!is_pressed && was_pressed_)
|
||||||
{
|
{
|
||||||
const std::uint32_t time_held = hal::GetMillis() - _time_pressed_down;
|
const std::uint32_t time_held = hal::getMillis() - time_pressed_down_;
|
||||||
if (time_held > TIMEOUT_LONG_PRESS)
|
if (time_held > TIMEOUT_LONG_PRESS)
|
||||||
new_state = ButtonPress::LONG_PRESS;
|
new_state = ButtonPress::LONG_PRESS;
|
||||||
else if (time_held > TIMEOUT_SHORT_PRESS)
|
else if (time_held > TIMEOUT_SHORT_PRESS)
|
||||||
new_state = ButtonPress::SHORT_PRESS;
|
new_state = ButtonPress::SHORT_PRESS;
|
||||||
|
|
||||||
_time_pressed_down = 0;
|
time_pressed_down_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
_was_pressed = is_pressed;
|
was_pressed_ = is_pressed;
|
||||||
_current_state = new_state;
|
current_state_ = new_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] ButtonPress getState() const
|
[[nodiscard]] ButtonPress getState() const
|
||||||
{
|
{
|
||||||
return _current_state;
|
return current_state_;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _was_pressed = false;
|
bool was_pressed_ = false;
|
||||||
std::uint32_t _time_pressed_down = 0;
|
std::uint32_t time_pressed_down_ = 0;
|
||||||
ButtonPress _current_state = ButtonPress::NOT_PRESSED;
|
ButtonPress current_state_ = ButtonPress::NOT_PRESSED;
|
||||||
};
|
};
|
||||||
|
|
||||||
}// namespace Peripherals
|
}// namespace Peripherals
|
||||||
|
|
||||||
#endif /* PERIPHERALS_BUTTON_HPP_ */
|
#endif /* SKULLC_PERIPHERALS_BUTTON_HPP_ */
|
||||||
|
|||||||
@ -5,8 +5,8 @@
|
|||||||
* Author: erki
|
* Author: erki
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PERIPHERALS_ENCODER_HPP_
|
#ifndef SKULLC_PERIPHERALS_ENCODER_HPP_
|
||||||
#define PERIPHERALS_ENCODER_HPP_
|
#define SKULLC_PERIPHERALS_ENCODER_HPP_
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ public:
|
|||||||
|
|
||||||
Encoder() = delete;
|
Encoder() = delete;
|
||||||
explicit Encoder(TIM_HandleTypeDef* htim, const std::uint32_t channels)
|
explicit Encoder(TIM_HandleTypeDef* htim, const std::uint32_t channels)
|
||||||
: _htim(htim), _channels(channels)
|
: htim_(htim), channels_(channels)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Encoder(const Encoder&) = delete;
|
Encoder(const Encoder&) = delete;
|
||||||
@ -36,40 +36,40 @@ public:
|
|||||||
|
|
||||||
void start()
|
void start()
|
||||||
{
|
{
|
||||||
HAL_TIM_Base_Start_IT(_htim);
|
HAL_TIM_Base_Start_IT(htim_);
|
||||||
HAL_TIM_Encoder_Start_IT(_htim, _channels);
|
HAL_TIM_Encoder_Start_IT(htim_, channels_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void stop()
|
void stop()
|
||||||
{
|
{
|
||||||
HAL_TIM_Encoder_Stop_IT(_htim, _channels);
|
HAL_TIM_Encoder_Stop_IT(htim_, channels_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset()
|
void reset()
|
||||||
{
|
{
|
||||||
__HAL_TIM_SET_COUNTER(_htim, 0);
|
__HAL_TIM_SET_COUNTER(htim_, 0);
|
||||||
_full_revolutions = 0;
|
full_revolutions_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setRevolutionTickCount(const std::uint16_t& count)
|
void setRevolutionTickCount(const std::uint16_t& count)
|
||||||
{
|
{
|
||||||
__HAL_TIM_SET_AUTORELOAD(_htim, count);
|
__HAL_TIM_SET_AUTORELOAD(htim_, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::uint16_t getCurrentClicks() const
|
std::uint16_t getCurrentClicks() const
|
||||||
{
|
{
|
||||||
const std::uint16_t val = __HAL_TIM_GET_COUNTER(_htim);
|
const std::uint16_t val = __HAL_TIM_GET_COUNTER(htim_);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::int32_t getFullRevolutions() const
|
std::int32_t getFullRevolutions() const
|
||||||
{
|
{
|
||||||
return _full_revolutions;
|
return full_revolutions_;
|
||||||
}
|
}
|
||||||
|
|
||||||
Dirs getDirection() const
|
Dirs getDirection() const
|
||||||
{
|
{
|
||||||
if (__HAL_TIM_IS_TIM_COUNTING_DOWN(_htim))
|
if (__HAL_TIM_IS_TIM_COUNTING_DOWN(htim_))
|
||||||
return Dirs::BACKWARD;
|
return Dirs::BACKWARD;
|
||||||
else
|
else
|
||||||
return Dirs::FORWARD;
|
return Dirs::FORWARD;
|
||||||
@ -77,20 +77,20 @@ public:
|
|||||||
|
|
||||||
void timerUpdateEvent()
|
void timerUpdateEvent()
|
||||||
{
|
{
|
||||||
if (!__HAL_TIM_IS_TIM_COUNTING_DOWN(_htim))
|
if (!__HAL_TIM_IS_TIM_COUNTING_DOWN(htim_))
|
||||||
_full_revolutions++;
|
full_revolutions_++;
|
||||||
else
|
else
|
||||||
_full_revolutions--;
|
full_revolutions_--;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TIM_HandleTypeDef* _htim;
|
TIM_HandleTypeDef* htim_;
|
||||||
std::uint32_t _channels;
|
std::uint32_t channels_;
|
||||||
|
|
||||||
std::int32_t _full_revolutions = 0;
|
std::int32_t full_revolutions_ = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}// namespace Peripherals
|
}// namespace Peripherals
|
||||||
|
|
||||||
|
|
||||||
#endif /* PERIPHERALS_ENCODER_HPP_ */
|
#endif /* SKULLC_PERIPHERALS_ENCODER_HPP_ */
|
||||||
|
|||||||
@ -5,8 +5,8 @@
|
|||||||
* Author: erki
|
* Author: erki
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PERIPHERALS_INC_PERIPHERALS_HAL_ST_HPP_
|
#ifndef SKULLC_PERIPHERALS_HAL_ST_HPP_
|
||||||
#define PERIPHERALS_INC_PERIPHERALS_HAL_ST_HPP_
|
#define SKULLC_PERIPHERALS_HAL_ST_HPP_
|
||||||
|
|
||||||
#include <main.h>
|
#include <main.h>
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ IsrCallbackFn<Origin> createCallback(Handler& h_in)
|
|||||||
|
|
||||||
struct StaticHal
|
struct StaticHal
|
||||||
{
|
{
|
||||||
static void Initialize()
|
static void initialize()
|
||||||
{
|
{
|
||||||
#ifdef USE_DELAY_US
|
#ifdef USE_DELAY_US
|
||||||
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
|
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
|
||||||
@ -45,17 +45,17 @@ struct StaticHal
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::uint32_t GetMillis()
|
static std::uint32_t getMillis()
|
||||||
{
|
{
|
||||||
return HAL_GetTick();
|
return HAL_GetTick();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Delay(const std::uint32_t milliseconds)
|
static void delay(const std::uint32_t milliseconds)
|
||||||
{
|
{
|
||||||
HAL_Delay(milliseconds);
|
HAL_Delay(milliseconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DelayUs(const std::uint32_t micros)
|
static void delayUs(const std::uint32_t micros)
|
||||||
{
|
{
|
||||||
#ifdef USE_DELAY_US
|
#ifdef USE_DELAY_US
|
||||||
const std::uint32_t tick_start = DWT->CYCCNT;
|
const std::uint32_t tick_start = DWT->CYCCNT;
|
||||||
@ -85,14 +85,14 @@ struct Gpio
|
|||||||
explicit Gpio(GPIO_TypeDef* port, const std::uint16_t pin, const bool inverted)
|
explicit Gpio(GPIO_TypeDef* port, const std::uint16_t pin, const bool inverted)
|
||||||
: port(port), pin(pin), inverted(inverted) {}
|
: port(port), pin(pin), inverted(inverted) {}
|
||||||
|
|
||||||
void Set(const bool& state)
|
void set(const bool& state)
|
||||||
{
|
{
|
||||||
HAL_GPIO_WritePin(port, pin, GPIO_PinState(inverted ? !state : state));
|
HAL_GPIO_WritePin(port, pin, GPIO_PinState(inverted ? !state : state));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Toggle() { HAL_GPIO_TogglePin(port, pin); }
|
void toggle() { HAL_GPIO_TogglePin(port, pin); }
|
||||||
|
|
||||||
bool Read() const { return inverted ? !bool(HAL_GPIO_ReadPin(port, pin)) : bool(HAL_GPIO_ReadPin(port, pin)); }
|
bool read() const { return inverted ? !bool(HAL_GPIO_ReadPin(port, pin)) : bool(HAL_GPIO_ReadPin(port, pin)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CREATE_GPIO(name) \
|
#define CREATE_GPIO(name) \
|
||||||
@ -104,10 +104,10 @@ struct Gpio
|
|||||||
|
|
||||||
template<
|
template<
|
||||||
typename T,
|
typename T,
|
||||||
HAL_StatusTypeDef (*transmit)(
|
HAL_StatusTypeDef (*transmit_)(
|
||||||
T*, std::uint8_t* data, std::uint16_t data_len, std::uint32_t timeout),
|
T*, std::uint8_t* data, std::uint16_t data_len, std::uint32_t timeout),
|
||||||
HAL_StatusTypeDef (*receive)(T*, std::uint8_t* data,
|
HAL_StatusTypeDef (*receive_)(T*, std::uint8_t* data,
|
||||||
std::uint16_t data_len, std::uint32_t timeout)>
|
std::uint16_t data_len, std::uint32_t timeout)>
|
||||||
struct SerialInterface
|
struct SerialInterface
|
||||||
{
|
{
|
||||||
using underlying_handle_type = T;
|
using underlying_handle_type = T;
|
||||||
@ -116,38 +116,38 @@ struct SerialInterface
|
|||||||
SerialInterface() = delete;
|
SerialInterface() = delete;
|
||||||
explicit SerialInterface(underlying_handle_type* handle) : handle(handle) {}
|
explicit SerialInterface(underlying_handle_type* handle) : handle(handle) {}
|
||||||
|
|
||||||
bool Transmit(std::uint8_t* data, const std::uint32_t data_len)
|
bool transmit(std::uint8_t* data, const std::uint32_t data_len)
|
||||||
{
|
{
|
||||||
return transmit(handle, data, data_len, 100) == HAL_StatusTypeDef::HAL_OK;
|
return transmit_(handle, data, data_len, 100) == HAL_StatusTypeDef::HAL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Td, std::size_t N>
|
template<typename Td, std::size_t N>
|
||||||
bool Transmit(std::array<Td, N>& array)
|
bool transmit(std::array<Td, N>& array)
|
||||||
{
|
{
|
||||||
static_assert(sizeof(Td) == sizeof(std::uint8_t), "Data is not a byte large.");
|
static_assert(sizeof(Td) == sizeof(std::uint8_t), "Data is not a byte large.");
|
||||||
|
|
||||||
return Transmit(reinterpret_cast<std::uint8_t*>(array.data()), std::uint32_t(N));
|
return transmit(reinterpret_cast<std::uint8_t*>(array.data()), std::uint32_t(N));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Receive(std::uint8_t* data, const std::uint32_t data_len)
|
bool receive(std::uint8_t* data, const std::uint32_t data_len)
|
||||||
{
|
{
|
||||||
return receive(handle, data, data_len, 100) == HAL_StatusTypeDef::HAL_OK;
|
return receive_(handle, data, data_len, 100) == HAL_StatusTypeDef::HAL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Td, std::size_t N>
|
template<typename Td, std::size_t N>
|
||||||
bool Receive(std::array<Td, N>& array)
|
bool receive(std::array<Td, N>& array)
|
||||||
{
|
{
|
||||||
static_assert(sizeof(Td) == sizeof(std::uint8_t), "Data is not a byte large.");
|
static_assert(sizeof(Td) == sizeof(std::uint8_t), "Data is not a byte large.");
|
||||||
|
|
||||||
return Receive(reinterpret_cast<std::uint8_t*>(array.data()), std::uint32_t(N));
|
return receive(reinterpret_cast<std::uint8_t*>(array.data()), std::uint32_t(N));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T,
|
template<typename T,
|
||||||
HAL_StatusTypeDef (*transmit)(T*, std::uint8_t* data,
|
HAL_StatusTypeDef (*transmit_)(T*, std::uint8_t* data,
|
||||||
std::uint16_t data_len),
|
std::uint16_t data_len),
|
||||||
HAL_StatusTypeDef (*receive)(T*, std::uint8_t* data,
|
HAL_StatusTypeDef (*receive_)(T*, std::uint8_t* data,
|
||||||
std::uint16_t data_len)>
|
std::uint16_t data_len)>
|
||||||
struct SerialInterfaceAsync
|
struct SerialInterfaceAsync
|
||||||
{
|
{
|
||||||
using underlying_handle_type = T;
|
using underlying_handle_type = T;
|
||||||
@ -157,30 +157,30 @@ struct SerialInterfaceAsync
|
|||||||
explicit SerialInterfaceAsync(underlying_handle_type* handle)
|
explicit SerialInterfaceAsync(underlying_handle_type* handle)
|
||||||
: handle(handle) {}
|
: handle(handle) {}
|
||||||
|
|
||||||
bool Transmit(std::uint8_t* data, const std::uint32_t data_len)
|
bool transmit(std::uint8_t* data, const std::uint32_t data_len)
|
||||||
{
|
{
|
||||||
return transmit(handle, data, data_len) == HAL_StatusTypeDef::HAL_OK;
|
return transmit_(handle, data, data_len) == HAL_StatusTypeDef::HAL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Td, std::size_t N>
|
template<typename Td, std::size_t N>
|
||||||
bool Transmit(std::array<Td, N>& array)
|
bool transmit(std::array<Td, N>& array)
|
||||||
{
|
{
|
||||||
static_assert(sizeof(Td) == sizeof(std::uint8_t), "Data is not a byte large.");
|
static_assert(sizeof(Td) == sizeof(std::uint8_t), "Data is not a byte large.");
|
||||||
|
|
||||||
return Transmit(reinterpret_cast<std::uint8_t*>(array.data()), std::uint32_t(N));
|
return transmit_(reinterpret_cast<std::uint8_t*>(array.data()), std::uint32_t(N));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Receive(std::uint8_t* data, const std::uint32_t data_len)
|
bool receive(std::uint8_t* data, const std::uint32_t data_len)
|
||||||
{
|
{
|
||||||
return receive(handle, data, data_len) == HAL_StatusTypeDef::HAL_OK;
|
return receive_(handle, data, data_len) == HAL_StatusTypeDef::HAL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Td, std::size_t N>
|
template<typename Td, std::size_t N>
|
||||||
bool Receive(std::array<Td, N>& array)
|
bool receive(std::array<Td, N>& array)
|
||||||
{
|
{
|
||||||
static_assert(sizeof(Td) == sizeof(std::uint8_t), "Data is not a byte large.");
|
static_assert(sizeof(Td) == sizeof(std::uint8_t), "Data is not a byte large.");
|
||||||
|
|
||||||
return Receive(reinterpret_cast<std::uint8_t*>(array.data()), std::uint32_t(N));
|
return receive(reinterpret_cast<std::uint8_t*>(array.data()), std::uint32_t(N));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -198,63 +198,63 @@ struct SpiRegisters
|
|||||||
explicit SpiRegisters(const SpiInterface& handle, const Gpio& cs)
|
explicit SpiRegisters(const SpiInterface& handle, const Gpio& cs)
|
||||||
: handle(handle), chip_select(cs)
|
: handle(handle), chip_select(cs)
|
||||||
{
|
{
|
||||||
chip_select.Set(true);
|
chip_select.set(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteRegister(std::uint8_t reg, uint8_t data)
|
void writeRegister(std::uint8_t reg, uint8_t data)
|
||||||
{
|
{
|
||||||
chip_select.Set(false);
|
chip_select.set(false);
|
||||||
|
|
||||||
handle.Transmit(®, 1);
|
handle.transmit(®, 1);
|
||||||
handle.Transmit(&data, 1);
|
handle.transmit(&data, 1);
|
||||||
|
|
||||||
chip_select.Set(true);
|
chip_select.set(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteRegisterMultibyte(std::uint8_t reg, std::uint8_t* data,
|
void writeRegisterMultibyte(std::uint8_t reg, std::uint8_t* data,
|
||||||
const std::uint32_t len)
|
const std::uint32_t len)
|
||||||
{
|
{
|
||||||
chip_select.Set(false);
|
chip_select.set(false);
|
||||||
|
|
||||||
handle.Transmit(®, 1);
|
handle.transmit(®, 1);
|
||||||
handle.Transmit(data, len);
|
handle.transmit(data, len);
|
||||||
|
|
||||||
chip_select.Set(true);
|
chip_select.set(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::uint8_t ReadRegister(std::uint8_t reg,
|
std::uint8_t readRegister(std::uint8_t reg,
|
||||||
const std::uint32_t read_delay = 0)
|
const std::uint32_t read_delay = 0)
|
||||||
{
|
{
|
||||||
chip_select.Set(false);
|
chip_select.set(false);
|
||||||
|
|
||||||
handle.Transmit(®, 1);
|
handle.transmit(®, 1);
|
||||||
|
|
||||||
std::uint8_t output = 255;
|
std::uint8_t output = 255;
|
||||||
|
|
||||||
if (read_delay)
|
if (read_delay)
|
||||||
StaticHal::DelayUs(read_delay);
|
StaticHal::delayUs(read_delay);
|
||||||
|
|
||||||
handle.Receive(&output, 1);
|
handle.receive(&output, 1);
|
||||||
|
|
||||||
chip_select.Set(true);
|
chip_select.set(true);
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReadRegisterMultibyte(std::uint8_t reg, std::uint8_t* data,
|
void readRegisterMultibyte(std::uint8_t reg, std::uint8_t* data,
|
||||||
const std::uint32_t len,
|
const std::uint32_t len,
|
||||||
const std::uint32_t read_delay = 0)
|
const std::uint32_t read_delay = 0)
|
||||||
{
|
{
|
||||||
chip_select.Set(false);
|
chip_select.set(false);
|
||||||
|
|
||||||
handle.Transmit(®, 1);
|
handle.transmit(®, 1);
|
||||||
|
|
||||||
if (read_delay)
|
if (read_delay)
|
||||||
StaticHal::DelayUs(read_delay);
|
StaticHal::delayUs(read_delay);
|
||||||
|
|
||||||
handle.Receive(data, len);
|
handle.receive(data, len);
|
||||||
|
|
||||||
chip_select.Set(true);
|
chip_select.set(true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -281,23 +281,23 @@ struct PwmChannel
|
|||||||
explicit PwmChannel(TIM_HandleTypeDef* handle, const std::uint32_t channel)
|
explicit PwmChannel(TIM_HandleTypeDef* handle, const std::uint32_t channel)
|
||||||
: handle(handle), channel(channel) {}
|
: handle(handle), channel(channel) {}
|
||||||
|
|
||||||
void Enable() { HAL_TIM_PWM_Start(handle, channel); }
|
void enable() { HAL_TIM_PWM_Start(handle, channel); }
|
||||||
|
|
||||||
void Disable() { HAL_TIM_PWM_Stop(handle, channel); }
|
void disable() { HAL_TIM_PWM_Stop(handle, channel); }
|
||||||
|
|
||||||
void SetCompare(const std::uint32_t compare)
|
void setCompare(const std::uint32_t compare)
|
||||||
{
|
{
|
||||||
__HAL_TIM_SET_COMPARE(handle, channel, compare);
|
__HAL_TIM_SET_COMPARE(handle, channel, compare);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::uint32_t MaxValue() { return handle->Init.Period; }
|
std::uint32_t maxValue() { return handle->Init.Period; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif// HAL_TIM_MODULE_ENABLED
|
#endif// HAL_TIM_MODULE_ENABLED
|
||||||
|
|
||||||
struct ItmSerialInterface
|
struct ItmSerialInterface
|
||||||
{
|
{
|
||||||
bool Transmit(std::uint8_t* data, const std::uint32_t data_len)
|
bool transmit(std::uint8_t* data, const std::uint32_t data_len)
|
||||||
{
|
{
|
||||||
for (std::uint32_t i = 0; i < data_len; i++)
|
for (std::uint32_t i = 0; i < data_len; i++)
|
||||||
{
|
{
|
||||||
@ -307,11 +307,11 @@ struct ItmSerialInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, std::size_t N>
|
template<typename T, std::size_t N>
|
||||||
bool Transmit(std::array<T, N>& array)
|
bool transmit(std::array<T, N>& array)
|
||||||
{
|
{
|
||||||
static_assert(sizeof(T) == sizeof(std::uint8_t), "Data is not a byte large.");
|
static_assert(sizeof(T) == sizeof(std::uint8_t), "Data is not a byte large.");
|
||||||
|
|
||||||
return Transmit(reinterpret_cast<std::uint8_t*>(array.data()), std::uint32_t(N));
|
return transmit(reinterpret_cast<std::uint8_t*>(array.data()), std::uint32_t(N));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -319,4 +319,4 @@ struct ItmSerialInterface
|
|||||||
}// namespace Hal
|
}// namespace Hal
|
||||||
}// namespace Peripherals
|
}// namespace Peripherals
|
||||||
|
|
||||||
#endif /* PERIPHERALS_INC_PERIPHERALS_HAL_ST_HPP_ */
|
#endif /* SKULLC_PERIPHERALS_HAL_ST_HPP_ */
|
||||||
|
|||||||
@ -5,8 +5,8 @@
|
|||||||
* Author: erki
|
* Author: erki
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PERIPHERALS_IMU_HPP_
|
#ifndef SKULLC_PERIPHERALS_IMU_HPP_
|
||||||
#define PERIPHERALS_IMU_HPP_
|
#define SKULLC_PERIPHERALS_IMU_HPP_
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
@ -23,16 +23,16 @@ public:
|
|||||||
Z
|
Z
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual void Setup() = 0;
|
virtual void setup() = 0;
|
||||||
virtual void Calibrate(const std::uint32_t samples) = 0;
|
virtual void calibrate(const std::uint32_t samples) = 0;
|
||||||
|
|
||||||
virtual void ReadGyro(float* output) = 0;
|
virtual void readGyro(float* output) = 0;
|
||||||
virtual void ReadGyroRaw(std::int16_t* output) = 0;
|
virtual void readGyroRaw(std::int16_t* output) = 0;
|
||||||
|
|
||||||
virtual void ReadAccelerometer(float* output) = 0;
|
virtual void readAccelerometer(float* output) = 0;
|
||||||
virtual void ReadAccelerometerRaw(std::int16_t* output) = 0;
|
virtual void readAccelerometerRaw(std::int16_t* output) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}// namespace Peripherals
|
}// namespace Peripherals
|
||||||
|
|
||||||
#endif /* PERIPHERALS_IMU_HPP_ */
|
#endif /* SKULLC_PERIPHERALS_IMU_HPP_ */
|
||||||
|
|||||||
@ -5,8 +5,8 @@
|
|||||||
* Author: erki
|
* Author: erki
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PERIPHERALS_IMU_ICM_HPP_
|
#ifndef SKULLC_PERIPHERALS_IMU_ICM_HPP_
|
||||||
#define PERIPHERALS_IMU_ICM_HPP_
|
#define SKULLC_PERIPHERALS_IMU_ICM_HPP_
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
@ -45,42 +45,42 @@ public:
|
|||||||
ImuIcm() = delete;
|
ImuIcm() = delete;
|
||||||
ImuIcm(const registers_handle& registers) : registers(registers) {}
|
ImuIcm(const registers_handle& registers) : registers(registers) {}
|
||||||
|
|
||||||
void Setup() override
|
void setup() override
|
||||||
{
|
{
|
||||||
registers.WriteRegister(_Registers::PWR_MGMT_1 & _Registers::WRITE_MASK,
|
registers.writeRegister(Registers_::PWR_MGMT_1 & Registers_::WRITE_MASK,
|
||||||
0b10000000);
|
0b10000000);
|
||||||
hal::Delay(10);
|
hal::delay(10);
|
||||||
|
|
||||||
registers.WriteRegister(_Registers::USER_CTRL & _Registers::WRITE_MASK,
|
registers.writeRegister(Registers_::USER_CTRL & Registers_::WRITE_MASK,
|
||||||
0b00010000);
|
0b00010000);
|
||||||
hal::Delay(10);
|
hal::delay(10);
|
||||||
|
|
||||||
registers.WriteRegister(_Registers::PWR_MGMT_1 & _Registers::WRITE_MASK,
|
registers.writeRegister(Registers_::PWR_MGMT_1 & Registers_::WRITE_MASK,
|
||||||
0b00000000);
|
0b00000000);
|
||||||
hal::Delay(10);
|
hal::delay(10);
|
||||||
|
|
||||||
registers.WriteRegister(_Registers::PWR_MGMT_1 & _Registers::WRITE_MASK,
|
registers.writeRegister(Registers_::PWR_MGMT_1 & Registers_::WRITE_MASK,
|
||||||
0b00000001);
|
0b00000001);
|
||||||
hal::Delay(10);
|
hal::delay(10);
|
||||||
|
|
||||||
registers.WriteRegister(_Registers::CONFIG & _Registers::WRITE_MASK,
|
registers.writeRegister(Registers_::CONFIG & Registers_::WRITE_MASK,
|
||||||
0x03);// DLPF_CFG = 3, gyro filter = 41/59.0, gyro
|
0x03);// DLPF_CFG = 3, gyro filter = 41/59.0, gyro
|
||||||
// rate = 1KHz, temp filter = 42
|
// rate = 1KHz, temp filter = 42
|
||||||
hal::Delay(10);
|
hal::delay(10);
|
||||||
|
|
||||||
SetGyroscopeScale(_scale_gyro);
|
setGyroscopeScale(scale_gyro_);
|
||||||
|
|
||||||
SetAccelerometerScale(_scale_accel);
|
setAccelerometerScale(scale_accel_);
|
||||||
|
|
||||||
// ACCEL_FCHOICE_B = 0, A_DLPF_CFG = 3 filter=44.8/61.5 rate=1KHz
|
// ACCEL_FCHOICE_B = 0, A_DLPF_CFG = 3 filter=44.8/61.5 rate=1KHz
|
||||||
registers.WriteRegister(_Registers::ACCEL_CONFIG2 & _Registers::WRITE_MASK,
|
registers.writeRegister(Registers_::ACCEL_CONFIG2 & Registers_::WRITE_MASK,
|
||||||
0x03);
|
0x03);
|
||||||
hal::Delay(10);
|
hal::delay(10);
|
||||||
|
|
||||||
// SAMPLE_RATE = INTERNAL_SAMPLE_RATE / (1 + SMPLRT_DIV) Where
|
// SAMPLE_RATE = INTERNAL_SAMPLE_RATE / (1 + SMPLRT_DIV) Where
|
||||||
// INTERNAL_SAMPLE_RATE = 1kHz
|
// INTERNAL_SAMPLE_RATE = 1kHz
|
||||||
registers.WriteRegister(_Registers::SMPLRT_DIV & _Registers::WRITE_MASK, 0);
|
registers.writeRegister(Registers_::SMPLRT_DIV & Registers_::WRITE_MASK, 0);
|
||||||
hal::Delay(10);
|
hal::delay(10);
|
||||||
|
|
||||||
// Enable interrupt
|
// Enable interrupt
|
||||||
|
|
||||||
@ -88,15 +88,15 @@ public:
|
|||||||
// INT/DRDY pin is configured as push-pull.
|
// INT/DRDY pin is configured as push-pull.
|
||||||
// INT/DRDY pin indicates interrupt pulse's width is 50us.
|
// INT/DRDY pin indicates interrupt pulse's width is 50us.
|
||||||
// Interrupt status is cleared only by reading INT_STATUS register
|
// Interrupt status is cleared only by reading INT_STATUS register
|
||||||
registers.WriteRegister(_Registers::INT_PIN_CFG & _Registers::WRITE_MASK,
|
registers.writeRegister(Registers_::INT_PIN_CFG & Registers_::WRITE_MASK,
|
||||||
0);
|
0);
|
||||||
hal::Delay(10);
|
hal::delay(10);
|
||||||
|
|
||||||
registers.WriteRegister(_Registers::INT_ENABLE & _Registers::WRITE_MASK, 1);
|
registers.writeRegister(Registers_::INT_ENABLE & Registers_::WRITE_MASK, 1);
|
||||||
hal::Delay(10);
|
hal::delay(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Calibrate(const std::uint32_t samples) override
|
void calibrate(const std::uint32_t samples) override
|
||||||
{
|
{
|
||||||
std::array<std::int32_t, 3> avg_gyro;
|
std::array<std::int32_t, 3> avg_gyro;
|
||||||
std::array<std::int32_t, 3> avg_accel;
|
std::array<std::int32_t, 3> avg_accel;
|
||||||
@ -109,10 +109,10 @@ public:
|
|||||||
out[j] += raw[j];
|
out[j] += raw[j];
|
||||||
};
|
};
|
||||||
|
|
||||||
ReadGyroRaw(raw.data());
|
readGyroRaw(raw.data());
|
||||||
add_to_avg(avg_gyro);
|
add_to_avg(avg_gyro);
|
||||||
|
|
||||||
ReadAccelerometerRaw(raw.data());
|
readAccelerometerRaw(raw.data());
|
||||||
add_to_avg(avg_accel);
|
add_to_avg(avg_accel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,128 +121,128 @@ public:
|
|||||||
const std::int32_t max = std::numeric_limits<std::int16_t>::max();
|
const std::int32_t max = std::numeric_limits<std::int16_t>::max();
|
||||||
const std::int32_t min = std::numeric_limits<std::int16_t>::min();
|
const std::int32_t min = std::numeric_limits<std::int16_t>::min();
|
||||||
|
|
||||||
_bias_gyro[i] = Clamp(avg_gyro[i], max, min);
|
bias_gyro_[i] = clamp(avg_gyro[i], max, min);
|
||||||
_bias_accel[i] = Clamp(avg_accel[i], max, min);
|
bias_accel_[i] = clamp(avg_accel[i], max, min);
|
||||||
}
|
}
|
||||||
|
|
||||||
_bias_accel[2] -= AccelerometerReadingToRaw(1);
|
bias_accel_[2] -= accelerometerReadingToRaw(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetGyroscopeScale(const GyroScale scale)
|
void setGyroscopeScale(const GyroScale scale)
|
||||||
{
|
{
|
||||||
const std::uint8_t current_config =
|
const std::uint8_t current_config =
|
||||||
registers.ReadRegister(_Registers::GYRO_CONFIG | _Registers::READ_MASK);
|
registers.readRegister(Registers_::GYRO_CONFIG | Registers_::READ_MASK);
|
||||||
const std::uint8_t new_config =
|
const std::uint8_t new_config =
|
||||||
(current_config & 0xE7) | (std::uint8_t(scale) << 3);
|
(current_config & 0xE7) | (std::uint8_t(scale) << 3);
|
||||||
registers.WriteRegister(_Registers::GYRO_CONFIG & _Registers::WRITE_MASK,
|
registers.writeRegister(Registers_::GYRO_CONFIG & Registers_::WRITE_MASK,
|
||||||
new_config);
|
new_config);
|
||||||
|
|
||||||
_scale_gyro = scale;
|
scale_gyro_ = scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetAccelerometerScale(const AccelerometerScale scale)
|
void setAccelerometerScale(const AccelerometerScale scale)
|
||||||
{
|
{
|
||||||
const std::uint8_t current_config = registers.ReadRegister(
|
const std::uint8_t current_config = registers.readRegister(
|
||||||
_Registers::ACCEL_CONFIG | _Registers::READ_MASK);
|
Registers_::ACCEL_CONFIG | Registers_::READ_MASK);
|
||||||
const std::uint8_t new_config =
|
const std::uint8_t new_config =
|
||||||
(current_config & 0xE7) | (std::uint8_t(scale) << 3);
|
(current_config & 0xE7) | (std::uint8_t(scale) << 3);
|
||||||
registers.WriteRegister(_Registers::ACCEL_CONFIG & _Registers::WRITE_MASK,
|
registers.writeRegister(Registers_::ACCEL_CONFIG & Registers_::WRITE_MASK,
|
||||||
new_config);
|
new_config);
|
||||||
|
|
||||||
_scale_accel = scale;
|
scale_accel_ = scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReadGyro(float* output) override
|
void readGyro(float* output) override
|
||||||
{
|
{
|
||||||
uint8_t data[6] = {0};
|
uint8_t data[6] = {0};
|
||||||
registers.ReadRegisterMultibyte(
|
registers.readRegisterMultibyte(
|
||||||
_Registers::GYRO_XOUT_H | _Registers::READ_MASK, data, 6);
|
Registers_::GYRO_XOUT_H | Registers_::READ_MASK, data, 6);
|
||||||
|
|
||||||
for (std::uint32_t i = 0; i < 3; i++)
|
for (std::uint32_t i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
const std::int16_t bit = ByteToTypeBE<std::int16_t, 2>(&data[i * 2]);
|
const std::int16_t bit = byteToTypeBE<std::int16_t, 2>(&data[i * 2]);
|
||||||
output[i] = GyroRawToReading(bit);
|
output[i] = gyroRawToReading(bit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReadGyroRaw(std::int16_t* output) override
|
void readGyroRaw(std::int16_t* output) override
|
||||||
{
|
{
|
||||||
uint8_t data[6] = {0};
|
uint8_t data[6] = {0};
|
||||||
registers.ReadRegisterMultibyte(
|
registers.readRegisterMultibyte(
|
||||||
_Registers::GYRO_XOUT_H | _Registers::READ_MASK, data, 6);
|
Registers_::GYRO_XOUT_H | Registers_::READ_MASK, data, 6);
|
||||||
|
|
||||||
for (std::uint32_t i = 0; i < 3; i++)
|
for (std::uint32_t i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
output[i] = ByteToTypeBE<std::int16_t, 2>(&data[i * 2]);
|
output[i] = byteToTypeBE<std::int16_t, 2>(&data[i * 2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReadAccelerometer(float* output) override
|
void readAccelerometer(float* output) override
|
||||||
{
|
{
|
||||||
uint8_t data[6] = {0};
|
uint8_t data[6] = {0};
|
||||||
registers.ReadRegisterMultibyte(
|
registers.readRegisterMultibyte(
|
||||||
_Registers::ACCEL_XOUT_H | _Registers::READ_MASK, data, 6);
|
Registers_::ACCEL_XOUT_H | Registers_::READ_MASK, data, 6);
|
||||||
|
|
||||||
for (std::uint32_t i = 0; i < 3; i++)
|
for (std::uint32_t i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
const std::int16_t bit = ByteToTypeBE<std::int16_t, 2>(&data[i * 2]);
|
const std::int16_t bit = byteToTypeBE<std::int16_t, 2>(&data[i * 2]);
|
||||||
output[i] = AccelerometerRawToReading(bit);
|
output[i] = accelerometerRawToReading(bit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReadAccelerometerRaw(std::int16_t* output) override
|
void readAccelerometerRaw(std::int16_t* output) override
|
||||||
{
|
{
|
||||||
uint8_t data[6] = {0};
|
uint8_t data[6] = {0};
|
||||||
registers.ReadRegisterMultibyte(
|
registers.readRegisterMultibyte(
|
||||||
_Registers::ACCEL_XOUT_H | _Registers::READ_MASK, data, 6);
|
Registers_::ACCEL_XOUT_H | Registers_::READ_MASK, data, 6);
|
||||||
|
|
||||||
for (std::uint32_t i = 0; i < 3; i++)
|
for (std::uint32_t i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
output[i] = ByteToTypeBE<std::int16_t, 2>(&data[i * 2]);
|
output[i] = byteToTypeBE<std::int16_t, 2>(&data[i * 2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::int16_t AccelerometerReadingToRaw(const float& fs) const
|
std::int16_t accelerometerReadingToRaw(const float& fs) const
|
||||||
{
|
{
|
||||||
return fs / _accel_fs_to_bit_constants[std::uint32_t(_scale_accel)];
|
return fs / accel_fs_to_bit_constants_[std::uint32_t(scale_accel_)];
|
||||||
}
|
}
|
||||||
|
|
||||||
std::int16_t GyroReadingToRaw(const float& fs) const
|
std::int16_t gyroReadingToRaw(const float& fs) const
|
||||||
{
|
{
|
||||||
return fs / _gyro_fs_to_bit_constants[std::uint32_t(_scale_gyro)];
|
return fs / gyro_fs_to_bit_constants_[std::uint32_t(scale_gyro_)];
|
||||||
}
|
}
|
||||||
|
|
||||||
float AccelerometerRawToReading(const std::int16_t bit) const
|
float accelerometerRawToReading(const std::int16_t bit) const
|
||||||
{
|
{
|
||||||
return float(bit) * _accel_fs_to_bit_constants[std::uint32_t(_scale_accel)];
|
return float(bit) * accel_fs_to_bit_constants_[std::uint32_t(scale_accel_)];
|
||||||
}
|
}
|
||||||
|
|
||||||
float GyroRawToReading(const std::int16_t bit) const
|
float gyroRawToReading(const std::int16_t bit) const
|
||||||
{
|
{
|
||||||
return float(bit) * _gyro_fs_to_bit_constants[std::uint32_t(_scale_gyro)];
|
return float(bit) * gyro_fs_to_bit_constants_[std::uint32_t(scale_gyro_)];
|
||||||
}
|
}
|
||||||
|
|
||||||
std::uint8_t readProductId()
|
std::uint8_t readProductId()
|
||||||
{
|
{
|
||||||
return registers.ReadRegister(_Registers::WHO_AM_I | _Registers::READ_MASK);
|
return registers.readRegister(Registers_::WHO_AM_I | Registers_::READ_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GyroScale _scale_gyro = GyroScale::DPS_2000;
|
GyroScale scale_gyro_ = GyroScale::DPS_2000;
|
||||||
AccelerometerScale _scale_accel = AccelerometerScale::G16;
|
AccelerometerScale scale_accel_ = AccelerometerScale::G16;
|
||||||
|
|
||||||
std::array<std::int16_t, 3> _bias_gyro;
|
std::array<std::int16_t, 3> bias_gyro_;
|
||||||
std::array<std::int16_t, 3> _bias_accel;
|
std::array<std::int16_t, 3> bias_accel_;
|
||||||
|
|
||||||
static constexpr float _accel_fs_to_bit_constants[4] = {
|
static constexpr float accel_fs_to_bit_constants_[4] = {
|
||||||
(2.0f / 32768.0f), (4.0f / 32768.0f), (8.0f / 32768.0f),
|
(2.0f / 32768.0f), (4.0f / 32768.0f), (8.0f / 32768.0f),
|
||||||
(16.0f / 32768.0f)};
|
(16.0f / 32768.0f)};
|
||||||
|
|
||||||
static constexpr float _gyro_fs_to_bit_constants[4] = {
|
static constexpr float gyro_fs_to_bit_constants_[4] = {
|
||||||
(250.0f / 32768.0f), (500.0f / 32768.0f), (1000.0f / 32768.0f),
|
(250.0f / 32768.0f), (500.0f / 32768.0f), (1000.0f / 32768.0f),
|
||||||
(2000.0f / 32768.0f)};
|
(2000.0f / 32768.0f)};
|
||||||
|
|
||||||
struct _Registers
|
struct Registers_
|
||||||
{
|
{
|
||||||
static constexpr std::uint32_t ICM20689_ID = 0x98;
|
static constexpr std::uint32_t ICM20689_ID = 0x98;
|
||||||
|
|
||||||
@ -295,11 +295,11 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, typename HAL>
|
template<typename T, typename HAL>
|
||||||
constexpr float ImuIcm<T, HAL>::_accel_fs_to_bit_constants[4];
|
constexpr float ImuIcm<T, HAL>::accel_fs_to_bit_constants_[4];
|
||||||
|
|
||||||
template<typename T, typename HAL>
|
template<typename T, typename HAL>
|
||||||
constexpr float ImuIcm<T, HAL>::_gyro_fs_to_bit_constants[4];
|
constexpr float ImuIcm<T, HAL>::gyro_fs_to_bit_constants_[4];
|
||||||
|
|
||||||
}// namespace Peripherals
|
}// namespace Peripherals
|
||||||
|
|
||||||
#endif /* PERIPHERALS_IMU_ICM_HPP_ */
|
#endif /* SKULLC_PERIPHERALS_IMU_ICM_HPP_ */
|
||||||
|
|||||||
@ -5,8 +5,8 @@
|
|||||||
* Author: erki
|
* Author: erki
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PERIPHERALS_IR_SENSORS_HPP_
|
#ifndef SKULLC_PERIPHERALS_IR_SENSORS_HPP_
|
||||||
#define PERIPHERALS_IR_SENSORS_HPP_
|
#define SKULLC_PERIPHERALS_IR_SENSORS_HPP_
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
@ -31,23 +31,23 @@ public:
|
|||||||
explicit IrSensors(ADC_HandleTypeDef* hadc,
|
explicit IrSensors(ADC_HandleTypeDef* hadc,
|
||||||
const std::array<std::uint32_t, N>& channels,
|
const std::array<std::uint32_t, N>& channels,
|
||||||
Args&&... gpios)
|
Args&&... gpios)
|
||||||
: adc(hadc), _channels(channels), _gpios{std::forward<Args>(gpios)...}
|
: adc(hadc), channels_(channels), gpios_{std::forward<Args>(gpios)...}
|
||||||
{
|
{
|
||||||
static_assert(sizeof...(Args) == N, "Not enough GPIOs passed.");
|
static_assert(sizeof...(Args) == N, "Not enough GPIOs passed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void startReading()
|
void startReading()
|
||||||
{
|
{
|
||||||
for (auto& gpio : _gpios)
|
for (auto& gpio : gpios_)
|
||||||
gpio.Set(true);
|
gpio.set(true);
|
||||||
|
|
||||||
adc.startDma();
|
adc.startDma();
|
||||||
}
|
}
|
||||||
|
|
||||||
void stopReading()
|
void stopReading()
|
||||||
{
|
{
|
||||||
for (auto& gpio : _gpios)
|
for (auto& gpio : gpios_)
|
||||||
gpio.Set(false);
|
gpio.set(false);
|
||||||
|
|
||||||
adc.stopDma();
|
adc.stopDma();
|
||||||
}
|
}
|
||||||
@ -56,8 +56,8 @@ public:
|
|||||||
{
|
{
|
||||||
for (std::size_t i = 0; i < N; i++)
|
for (std::size_t i = 0; i < N; i++)
|
||||||
{
|
{
|
||||||
_averages[i] -= _averages[i] / Average;
|
averages_[i] -= averages_[i] / Average;
|
||||||
_averages[i] += adc.readings[i] / Average;
|
averages_[i] += adc.readings[i] / Average;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,10 +67,10 @@ public:
|
|||||||
|
|
||||||
for (std::size_t i = 0; i < N; i++)
|
for (std::size_t i = 0; i < N; i++)
|
||||||
{
|
{
|
||||||
const float interim = _averages[i] - _offsets[i];
|
const float interim = averages_[i] - offsets_[i];
|
||||||
|
|
||||||
data[i].first = _multipliers[i] * std::pow(interim, _exponents[i]);
|
data[i].first = multipliers_[i] * std::pow(interim, exponents_[i]);
|
||||||
data[i].second = data[i].first < _wall_thresholds[i];
|
data[i].second = data[i].first < wall_thresholds_[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
@ -82,41 +82,41 @@ public:
|
|||||||
|
|
||||||
for (std::uint32_t i = 0; i < samples; i++)
|
for (std::uint32_t i = 0; i < samples; i++)
|
||||||
{
|
{
|
||||||
for (std::uint32_t ch = 0; ch < _channels.size(); ch++)
|
for (std::uint32_t ch = 0; ch < channels_.size(); ch++)
|
||||||
measurements[ch] += adc.read(_channels[ch], sample_time, 100);
|
measurements[ch] += adc.read(channels_[ch], sample_time, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::uint32_t ch = 0; ch < _channels.size(); ch++)
|
for (std::uint32_t ch = 0; ch < channels_.size(); ch++)
|
||||||
_offsets[ch] = std::uint16_t(measurements[ch] / samples);
|
offsets_[ch] = std::uint16_t(measurements[ch] / samples);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setExponents(const std::array<float, N>& e)
|
void setExponents(const std::array<float, N>& e)
|
||||||
{
|
{
|
||||||
_exponents = e;
|
exponents_ = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setMultipliers(const std::array<float, N>& m)
|
void setMultipliers(const std::array<float, N>& m)
|
||||||
{
|
{
|
||||||
_multipliers = m;
|
multipliers_ = m;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setWallThresholds(const std::array<float, N>& t)
|
void setWallThresholds(const std::array<float, N>& t)
|
||||||
{
|
{
|
||||||
_wall_thresholds = t;
|
wall_thresholds_ = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::array<std::uint32_t, N> _channels;
|
std::array<std::uint32_t, N> channels_;
|
||||||
std::array<gpio, N> _gpios;
|
std::array<gpio, N> gpios_;
|
||||||
std::array<std::uint16_t, N> _averages;
|
std::array<std::uint16_t, N> averages_;
|
||||||
|
|
||||||
std::array<std::uint16_t, N> _offsets;
|
std::array<std::uint16_t, N> offsets_;
|
||||||
std::array<float, N> _exponents;
|
std::array<float, N> exponents_;
|
||||||
std::array<float, N> _multipliers;
|
std::array<float, N> multipliers_;
|
||||||
std::array<float, N> _wall_thresholds;
|
std::array<float, N> wall_thresholds_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}// namespace Peripherals
|
}// namespace Peripherals
|
||||||
|
|
||||||
|
|
||||||
#endif /* PERIPHERALS_IR_SENSORS_HPP_ */
|
#endif /* SKULLC_PERIPHERALS_IR_SENSORS_HPP_ */
|
||||||
|
|||||||
@ -5,8 +5,8 @@
|
|||||||
* Author: erki
|
* Author: erki
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PERIPHERALS_MOTORS_HPP_
|
#ifndef SKULLC_PERIPHERALS_MOTORS_HPP_
|
||||||
#define PERIPHERALS_MOTORS_HPP_
|
#define SKULLC_PERIPHERALS_MOTORS_HPP_
|
||||||
|
|
||||||
namespace Peripherals
|
namespace Peripherals
|
||||||
{
|
{
|
||||||
@ -22,9 +22,9 @@ struct TwoChannelMotorData
|
|||||||
class IMotors
|
class IMotors
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void Set(const std::int16_t left, const std::int16_t right) = 0;
|
virtual void set(const std::int16_t left, const std::int16_t right) = 0;
|
||||||
virtual void Coast() = 0;
|
virtual void coast() = 0;
|
||||||
virtual void Break() = 0;
|
virtual void setBreak() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, typename I>
|
template<typename T, typename I>
|
||||||
@ -36,63 +36,63 @@ public:
|
|||||||
|
|
||||||
DualDrvMotors(const single_motor& left, const single_motor& right,
|
DualDrvMotors(const single_motor& left, const single_motor& right,
|
||||||
const gpio& sleep_pin)
|
const gpio& sleep_pin)
|
||||||
: _left(left), _right(right), _sleep_pin(sleep_pin)
|
: left_(left), right_(right), sleep_pin_(sleep_pin)
|
||||||
{
|
{
|
||||||
_left.forward.Enable();
|
left_.forward.enable();
|
||||||
_left.backward.Enable();
|
left_.backward.enable();
|
||||||
_right.forward.Enable();
|
right_.forward.enable();
|
||||||
_right.backward.Enable();
|
right_.backward.enable();
|
||||||
|
|
||||||
Set(0, 0);
|
set(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void Set(const std::int16_t left, const std::int16_t right) override
|
virtual void set(const std::int16_t left, const std::int16_t right) override
|
||||||
{
|
{
|
||||||
if (left > 0)
|
if (left > 0)
|
||||||
{
|
{
|
||||||
_left.forward.SetCompare(left);
|
left_.forward.setCompare(left);
|
||||||
_left.backward.SetCompare(0);
|
left_.backward.setCompare(0);
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
_left.forward.SetCompare(0);
|
left_.forward.setCompare(0);
|
||||||
_left.backward.SetCompare(-1 * left);
|
left_.backward.setCompare(-1 * left);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (right > 0)
|
if (right > 0)
|
||||||
{
|
{
|
||||||
_right.forward.SetCompare(right);
|
right_.forward.setCompare(right);
|
||||||
_right.backward.SetCompare(0);
|
right_.backward.setCompare(0);
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
_right.forward.SetCompare(0);
|
right_.forward.setCompare(0);
|
||||||
_right.backward.SetCompare(-1 * right);
|
right_.backward.setCompare(-1 * right);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void Coast() override
|
virtual void coast() override
|
||||||
{
|
{
|
||||||
_left.forward.SetCompare(0);
|
left_.forward.setCompare(0);
|
||||||
_left.backward.SetCompare(0);
|
left_.backward.setCompare(0);
|
||||||
|
|
||||||
_right.forward.SetCompare(0);
|
right_.forward.setCompare(0);
|
||||||
_right.backward.SetCompare(0);
|
right_.backward.setCompare(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void Break() override
|
virtual void setBreak() override
|
||||||
{
|
{
|
||||||
_left.forward.SetCompare(_left.forward.MaxValue());
|
left_.forward.setCompare(left_.forward.maxValue());
|
||||||
_left.backward.SetCompare(_left.backward.MaxValue());
|
left_.backward.setCompare(left_.backward.maxValue());
|
||||||
|
|
||||||
_right.forward.SetCompare(_right.forward.MaxValue());
|
right_.forward.setCompare(right_.forward.maxValue());
|
||||||
_right.backward.SetCompare(_right.backward.MaxValue());
|
right_.backward.setCompare(right_.backward.maxValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
single_motor _left;
|
single_motor left_;
|
||||||
single_motor _right;
|
single_motor right_;
|
||||||
gpio _sleep_pin;
|
gpio sleep_pin_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}// namespace Peripherals
|
}// namespace Peripherals
|
||||||
|
|
||||||
#endif /* PERIPHERALS_MOTORS_HPP_ */
|
#endif /* SKULLC_PERIPHERALS_MOTORS_HPP_ */
|
||||||
|
|||||||
@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* peripherals_pwm.hpp
|
|
||||||
*
|
|
||||||
* Created on: Feb 24, 2021
|
|
||||||
* Author: erki
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PERIPHERALS_PWM_CHANNEL_HPP_
|
|
||||||
#define PERIPHERALS_PWM_CHANNEL_HPP_
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
#include <tim.h>
|
|
||||||
|
|
||||||
#include "peripherals_io.hpp"
|
|
||||||
|
|
||||||
namespace Peripherals
|
|
||||||
{
|
|
||||||
|
|
||||||
struct PwmChannel
|
|
||||||
{
|
|
||||||
TIM_HandleTypeDef* timer;
|
|
||||||
std::uint32_t channel;
|
|
||||||
std::uint32_t timer_code;
|
|
||||||
Io pin;
|
|
||||||
|
|
||||||
PwmChannel() = delete;
|
|
||||||
|
|
||||||
PwmChannel(TIM_HandleTypeDef* timer, const std::uint32_t channel,
|
|
||||||
const std::uint32_t timer_code, const Io& pin);
|
|
||||||
|
|
||||||
void PinToPwm();
|
|
||||||
void PinToGpio();
|
|
||||||
|
|
||||||
void Enable();
|
|
||||||
void Disable();
|
|
||||||
|
|
||||||
void SetCompare(const std::uint32_t compare);
|
|
||||||
};
|
|
||||||
|
|
||||||
}// namespace Peripherals
|
|
||||||
|
|
||||||
#endif /* PERIPHERALS_PWM_CHANNEL_HPP_ */
|
|
||||||
@ -5,8 +5,8 @@
|
|||||||
* Author: erki
|
* Author: erki
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PERIPHERALS_INC_PERIPHERALS_RGB_HPP_
|
#ifndef SKULLC_PERIPHERALS_RGB_HPP_
|
||||||
#define PERIPHERALS_INC_PERIPHERALS_RGB_HPP_
|
#define SKULLC_PERIPHERALS_RGB_HPP_
|
||||||
|
|
||||||
namespace Peripherals
|
namespace Peripherals
|
||||||
{
|
{
|
||||||
@ -38,54 +38,54 @@ struct Rgb
|
|||||||
Rgb(const IOType& r, const IOType& g, const IOType& b)
|
Rgb(const IOType& r, const IOType& g, const IOType& b)
|
||||||
: red(r), green(g), blue(b)
|
: red(r), green(g), blue(b)
|
||||||
{
|
{
|
||||||
Set(RgbColor::OFF);
|
set(RgbColor::OFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Set(const RgbColor& new_color)
|
void set(const RgbColor& new_color)
|
||||||
{
|
{
|
||||||
color = new_color;
|
color = new_color;
|
||||||
|
|
||||||
switch (color)
|
switch (color)
|
||||||
{
|
{
|
||||||
case RgbColor::OFF:
|
case RgbColor::OFF:
|
||||||
red.Set(false);
|
red.set(false);
|
||||||
green.Set(false);
|
green.set(false);
|
||||||
blue.Set(false);
|
blue.set(false);
|
||||||
break;
|
break;
|
||||||
case RgbColor::RED:
|
case RgbColor::RED:
|
||||||
red.Set(true);
|
red.set(true);
|
||||||
green.Set(false);
|
green.set(false);
|
||||||
blue.Set(false);
|
blue.set(false);
|
||||||
break;
|
break;
|
||||||
case RgbColor::GREEN:
|
case RgbColor::GREEN:
|
||||||
red.Set(false);
|
red.set(false);
|
||||||
green.Set(true);
|
green.set(true);
|
||||||
blue.Set(false);
|
blue.set(false);
|
||||||
break;
|
break;
|
||||||
case RgbColor::BLUE:
|
case RgbColor::BLUE:
|
||||||
red.Set(false);
|
red.set(false);
|
||||||
green.Set(false);
|
green.set(false);
|
||||||
blue.Set(true);
|
blue.set(true);
|
||||||
break;
|
break;
|
||||||
case RgbColor::CYAN:
|
case RgbColor::CYAN:
|
||||||
red.Set(false);
|
red.set(false);
|
||||||
green.Set(true);
|
green.set(true);
|
||||||
blue.Set(true);
|
blue.set(true);
|
||||||
break;
|
break;
|
||||||
case RgbColor::PINK:
|
case RgbColor::PINK:
|
||||||
red.Set(true);
|
red.set(true);
|
||||||
green.Set(false);
|
green.set(false);
|
||||||
blue.Set(true);
|
blue.set(true);
|
||||||
break;
|
break;
|
||||||
case RgbColor::YELLOW:
|
case RgbColor::YELLOW:
|
||||||
red.Set(true);
|
red.set(true);
|
||||||
green.Set(true);
|
green.set(true);
|
||||||
blue.Set(false);
|
blue.set(false);
|
||||||
break;
|
break;
|
||||||
case RgbColor::WHITE:
|
case RgbColor::WHITE:
|
||||||
red.Set(true);
|
red.set(true);
|
||||||
green.Set(true);
|
green.set(true);
|
||||||
blue.Set(true);
|
blue.set(true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -93,4 +93,4 @@ struct Rgb
|
|||||||
|
|
||||||
}// namespace Peripherals
|
}// namespace Peripherals
|
||||||
|
|
||||||
#endif /* PERIPHERALS_INC_PERIPHERALS_RGB_HPP_ */
|
#endif /* SKULLC_PERIPHERALS_RGB_HPP_ */
|
||||||
|
|||||||
@ -40,30 +40,30 @@ struct SSD1306WriteAdapter
|
|||||||
*/
|
*/
|
||||||
void writeCommand(std::uint8_t data)
|
void writeCommand(std::uint8_t data)
|
||||||
{
|
{
|
||||||
dc.Set(false);
|
dc.set(false);
|
||||||
|
|
||||||
cs.Set(false);
|
cs.set(false);
|
||||||
registers.Transmit(&data, 1);
|
registers.transmit(&data, 1);
|
||||||
cs.Set(true);
|
cs.set(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeCommand(std::uint8_t command, std::uint8_t data)
|
void writeCommand(std::uint8_t command, std::uint8_t data)
|
||||||
{
|
{
|
||||||
dc.Set(false);
|
dc.set(false);
|
||||||
|
|
||||||
cs.Set(false);
|
cs.set(false);
|
||||||
registers.Transmit(&command, 1);
|
registers.transmit(&command, 1);
|
||||||
registers.Transmit(&data, 1);
|
registers.transmit(&data, 1);
|
||||||
cs.Set(true);
|
cs.set(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeData(std::uint8_t* data, const std::uint32_t len)
|
void writeData(std::uint8_t* data, const std::uint32_t len)
|
||||||
{
|
{
|
||||||
dc.Set(true);
|
dc.set(true);
|
||||||
|
|
||||||
cs.Set(false);
|
cs.set(false);
|
||||||
registers.Transmit(data, len);
|
registers.transmit(data, len);
|
||||||
cs.Set(true);
|
cs.set(true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -100,29 +100,29 @@ public:
|
|||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
hal::Delay(1);
|
hal::delay(1);
|
||||||
reset_.Set(false);
|
reset_.set(false);
|
||||||
hal::Delay(5);
|
hal::delay(5);
|
||||||
reset_.Set(true);
|
reset_.set(true);
|
||||||
hal::Delay(5);
|
hal::delay(5);
|
||||||
|
|
||||||
// reference impl: https://gitlab.com/TTYRobotiklubi/micromouse/mousetrap2/-/blob/master/Src/Peripherals/lcd.c
|
// reference impl: https://gitlab.com/TTYRobotiklubi/micromouse/mousetrap2/-/blob/master/Src/Peripherals/lcd.c
|
||||||
//Set the display to sleep mode for the rest of the init.
|
//set the display to sleep mode for the rest of the init.
|
||||||
registers_.writeCommand(Regs_::DISPLAY_OFF_YES_SLEEP);
|
registers_.writeCommand(Regs_::DISPLAY_OFF_YES_SLEEP);
|
||||||
|
|
||||||
//Set the clock speed, nominal ~105FPS
|
//set the clock speed, nominal ~105FPS
|
||||||
//Low nibble is divide ratio
|
//Low nibble is divide ratio
|
||||||
//High level is oscillator frequency. Should be about 177 Hz.
|
//High level is oscillator frequency. Should be about 177 Hz.
|
||||||
registers_.writeCommand(Regs_::CLOCK_DIVIDE_PREFIX, 0x80);
|
registers_.writeCommand(Regs_::CLOCK_DIVIDE_PREFIX, 0x80);
|
||||||
|
|
||||||
//Set the multiplex ratio to 1/32
|
//set the multiplex ratio to 1/32
|
||||||
//Default is 0x3F (1/64 Duty), we need 0x1F (1/32 Duty)
|
//Default is 0x3F (1/64 Duty), we need 0x1F (1/32 Duty)
|
||||||
registers_.writeCommand(Regs_::MULTIPLEX_RATIO_PREFIX, 0x1F);
|
registers_.writeCommand(Regs_::MULTIPLEX_RATIO_PREFIX, 0x1F);
|
||||||
|
|
||||||
//Set the display offset to 0 (default)
|
//set the display offset to 0 (default)
|
||||||
registers_.writeCommand(Regs_::DISPLAY_OFFSET_PREFIX, 0x00);
|
registers_.writeCommand(Regs_::DISPLAY_OFFSET_PREFIX, 0x00);
|
||||||
|
|
||||||
//Set the display RAM display start line to 0 (default)
|
//set the display RAM display start line to 0 (default)
|
||||||
//Bits 0-5 can be set to 0-63 with a bitwise or
|
//Bits 0-5 can be set to 0-63 with a bitwise or
|
||||||
registers_.writeCommand(Regs_::DISPLAY_START_LINE);
|
registers_.writeCommand(Regs_::DISPLAY_START_LINE);
|
||||||
|
|
||||||
@ -132,24 +132,24 @@ public:
|
|||||||
//Map the columns correctly for our OLED glass layout.
|
//Map the columns correctly for our OLED glass layout.
|
||||||
registers_.writeCommand(Regs_::SEG0_IS_COL_0);
|
registers_.writeCommand(Regs_::SEG0_IS_COL_0);
|
||||||
|
|
||||||
//Set COM output scan correctly for our OLED glass layout.
|
//set COM output scan correctly for our OLED glass layout.
|
||||||
registers_.writeCommand(Regs_::SCAN_DIR_UP);
|
registers_.writeCommand(Regs_::SCAN_DIR_UP);
|
||||||
|
|
||||||
//Set COM pins correctly for our OLED glass layout
|
//set COM pins correctly for our OLED glass layout
|
||||||
registers_.writeCommand(Regs_::COM_CONFIG_PREFIX, Regs_::COM_CONFIG_SEQUENTIAL_LEFT);
|
registers_.writeCommand(Regs_::COM_CONFIG_PREFIX, Regs_::COM_CONFIG_SEQUENTIAL_LEFT);
|
||||||
|
|
||||||
// Contrast.
|
// Contrast.
|
||||||
registers_.writeCommand(Regs_::CONTRAST_PREFIX, 0xBF);
|
registers_.writeCommand(Regs_::CONTRAST_PREFIX, 0xBF);
|
||||||
|
|
||||||
// Set precharge (low nibble) / discharge (high nibble) timing.
|
// set precharge (low nibble) / discharge (high nibble) timing.
|
||||||
// precharge = 1 clock
|
// precharge = 1 clock
|
||||||
// discharge = 15 clocks
|
// discharge = 15 clocks
|
||||||
registers_.writeCommand(Regs_::PRECHARGE_PERIOD_PREFIX, 0xF1);
|
registers_.writeCommand(Regs_::PRECHARGE_PERIOD_PREFIX, 0xF1);
|
||||||
|
|
||||||
// Set VCOM deselect level.
|
// set VCOM deselect level.
|
||||||
registers_.writeCommand(Regs_::VCOMH_DESELECT_PREFIX, Regs_::VCOMH_DESELECT_0p83xVCC);
|
registers_.writeCommand(Regs_::VCOMH_DESELECT_PREFIX, Regs_::VCOMH_DESELECT_0p83xVCC);
|
||||||
|
|
||||||
// Set display to normal.
|
// set display to normal.
|
||||||
registers_.writeCommand(Regs_::ENTIRE_DISPLAY_NORMAL);
|
registers_.writeCommand(Regs_::ENTIRE_DISPLAY_NORMAL);
|
||||||
|
|
||||||
// Uninvert the display.
|
// Uninvert the display.
|
||||||
|
|||||||
@ -5,8 +5,8 @@
|
|||||||
* Author: erki
|
* Author: erki
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PERIPHERALS_UTILITY_HPP_
|
#ifndef SKULLC_PERIPHERALS_UTILITY_HPP_
|
||||||
#define PERIPHERALS_UTILITY_HPP_
|
#define SKULLC_PERIPHERALS_UTILITY_HPP_
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
@ -20,7 +20,7 @@ namespace Peripherals
|
|||||||
#define SKULLC_TAG struct SKULLC_CONCAT(SkullCTag_, __COUNTER__)
|
#define SKULLC_TAG struct SKULLC_CONCAT(SkullCTag_, __COUNTER__)
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
constexpr const T& Clamp(const T& v, const T& lo, const T& hi)
|
constexpr const T& clamp(const T& v, const T& lo, const T& hi)
|
||||||
{
|
{
|
||||||
if (v > hi)
|
if (v > hi)
|
||||||
return hi;
|
return hi;
|
||||||
@ -31,7 +31,7 @@ constexpr const T& Clamp(const T& v, const T& lo, const T& hi)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, std::size_t N>
|
template<typename T, std::size_t N>
|
||||||
T ByteToTypeBE(const std::uint8_t a[N])
|
T byteToTypeBE(const std::uint8_t a[N])
|
||||||
{
|
{
|
||||||
T t(0);
|
T t(0);
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ T ByteToTypeBE(const std::uint8_t a[N])
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, std::size_t N>
|
template<typename T, std::size_t N>
|
||||||
T ByteToTypeLE(const std::uint8_t a[N])
|
T byteToTypeLE(const std::uint8_t a[N])
|
||||||
{
|
{
|
||||||
T t(0);
|
T t(0);
|
||||||
|
|
||||||
@ -69,4 +69,4 @@ constexpr T zeroInitialized()
|
|||||||
|
|
||||||
}// namespace Peripherals
|
}// namespace Peripherals
|
||||||
|
|
||||||
#endif /* PERIPHERALS_UTILITY_HPP_ */
|
#endif /* SKULLC_PERIPHERALS_UTILITY_HPP_ */
|
||||||
|
|||||||
@ -5,8 +5,8 @@
|
|||||||
* Author: erki
|
* Author: erki
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef UTILITY_INC_UTILITY_ASYNCLOGGER_HPP_
|
#ifndef SKULLC_UTILITY_ASYNCLOGGER_HPP_
|
||||||
#define UTILITY_INC_UTILITY_ASYNCLOGGER_HPP_
|
#define SKULLC_UTILITY_ASYNCLOGGER_HPP_
|
||||||
|
|
||||||
#include "utility_atomicscopeguard.hpp"
|
#include "utility_atomicscopeguard.hpp"
|
||||||
#include "utility_ilogger.hpp"
|
#include "utility_ilogger.hpp"
|
||||||
@ -28,7 +28,7 @@ public:
|
|||||||
using hal = H;
|
using hal = H;
|
||||||
|
|
||||||
AsyncLogger() = delete;
|
AsyncLogger() = delete;
|
||||||
explicit AsyncLogger(const serial_interface& serial) : _serial(serial) {}
|
explicit AsyncLogger(const serial_interface& serial) : serial_(serial) {}
|
||||||
|
|
||||||
AsyncLogger(const AsyncLogger&) = delete;
|
AsyncLogger(const AsyncLogger&) = delete;
|
||||||
AsyncLogger(AsyncLogger&&) = delete;
|
AsyncLogger(AsyncLogger&&) = delete;
|
||||||
@ -40,23 +40,23 @@ public:
|
|||||||
{
|
{
|
||||||
AtomicScopeGuard<hal> s;
|
AtomicScopeGuard<hal> s;
|
||||||
|
|
||||||
if (_buffer_queue.size() == _buffer_queue.max_size())
|
if (buffer_queue_.size() == buffer_queue_.max_size())
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::va_list args;
|
std::va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
|
|
||||||
_Data& tail = (*_buffer_queue.end());
|
Data_& tail = (*buffer_queue_.end());
|
||||||
tail.length =
|
tail.length =
|
||||||
vsnprintf(tail.buffer.data(), tail.buffer.size(), format, args);
|
vsnprintf(tail.buffer.data(), tail.buffer.size(), format, args);
|
||||||
|
|
||||||
{
|
{
|
||||||
AtomicScopeGuard<hal> s;
|
AtomicScopeGuard<hal> s;
|
||||||
_buffer_queue.increment_tail();
|
buffer_queue_.increment_tail();
|
||||||
|
|
||||||
if (!_in_flight)
|
if (!in_flight_)
|
||||||
_sendNextLog();
|
sendNextLog_();
|
||||||
}
|
}
|
||||||
|
|
||||||
va_end(args);
|
va_end(args);
|
||||||
@ -64,34 +64,35 @@ public:
|
|||||||
|
|
||||||
void txCompleteCallback()
|
void txCompleteCallback()
|
||||||
{
|
{
|
||||||
if (!_buffer_queue.empty())
|
if (!buffer_queue_.empty())
|
||||||
_sendNextLog();
|
sendNextLog_();
|
||||||
else
|
else
|
||||||
_in_flight = false;
|
in_flight_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct _Data
|
struct Data_
|
||||||
{
|
{
|
||||||
std::array<char, BufferSize> buffer;
|
std::array<char, BufferSize> buffer;
|
||||||
std::int32_t length = 0;
|
std::int32_t length = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
Ringbuffer<_Data, BufferCount> _buffer_queue;
|
Ringbuffer<Data_, BufferCount> buffer_queue_;
|
||||||
serial_interface _serial;
|
serial_interface serial_;
|
||||||
bool _in_flight = false;
|
/// @todo: thread safety
|
||||||
|
bool in_flight_ = false;
|
||||||
|
|
||||||
void _sendNextLog()
|
void sendNextLog_()
|
||||||
{
|
{
|
||||||
_in_flight = true;
|
in_flight_ = true;
|
||||||
|
|
||||||
_Data& head = _buffer_queue.front();
|
Data_& head = buffer_queue_.front();
|
||||||
_serial.Transmit(reinterpret_cast<uint8_t*>(head.buffer.data()),
|
serial_.transmit(reinterpret_cast<uint8_t*>(head.buffer.data()),
|
||||||
head.length);
|
head.length);
|
||||||
_buffer_queue.pop_front();
|
buffer_queue_.pop_front();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}// namespace Utility
|
}// namespace Utility
|
||||||
|
|
||||||
#endif /* UTILITY_INC_UTILITY_ASYNCLOGGER_HPP_ */
|
#endif /* SKULLC_UTILITY_ASYNCLOGGER_HPP_ */
|
||||||
|
|||||||
@ -5,8 +5,8 @@
|
|||||||
* Author: erki
|
* Author: erki
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef UTILITY_INC_UTILITY_ATOMICSCOPEGUARD_HPP_
|
#ifndef SKULLC_UTILITY_ATOMICSCOPEGUARD_HPP_
|
||||||
#define UTILITY_INC_UTILITY_ATOMICSCOPEGUARD_HPP_
|
#define SKULLC_UTILITY_ATOMICSCOPEGUARD_HPP_
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ struct AtomicScopeGuard
|
|||||||
AtomicScopeGuard()
|
AtomicScopeGuard()
|
||||||
{
|
{
|
||||||
hal::disableInterrupts();
|
hal::disableInterrupts();
|
||||||
_reentrancy_counter++;
|
reentrancy_counter_++;
|
||||||
}
|
}
|
||||||
|
|
||||||
AtomicScopeGuard(const AtomicScopeGuard&) = delete;
|
AtomicScopeGuard(const AtomicScopeGuard&) = delete;
|
||||||
@ -30,19 +30,19 @@ struct AtomicScopeGuard
|
|||||||
|
|
||||||
~AtomicScopeGuard()
|
~AtomicScopeGuard()
|
||||||
{
|
{
|
||||||
_reentrancy_counter--;
|
reentrancy_counter_--;
|
||||||
|
|
||||||
if (!_reentrancy_counter)
|
if (!reentrancy_counter_)
|
||||||
hal::enableInterrupts();
|
hal::enableInterrupts();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::int32_t _reentrancy_counter;
|
static std::int32_t reentrancy_counter_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename H>
|
template<typename H>
|
||||||
std::int32_t AtomicScopeGuard<H>::_reentrancy_counter = 0;
|
std::int32_t AtomicScopeGuard<H>::reentrancy_counter_ = 0;
|
||||||
|
|
||||||
}// namespace Utility
|
}// namespace Utility
|
||||||
|
|
||||||
#endif /* UTILITY_INC_UTILITY_ATOMICSCOPEGUARD_HPP_ */
|
#endif /* SKULLC_UTILITY_ATOMICSCOPEGUARD_HPP_ */
|
||||||
|
|||||||
@ -2,8 +2,8 @@
|
|||||||
// Created by erki on 30.04.21.
|
// Created by erki on 30.04.21.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef SKULLC_UTILITY_FIXEDPOINT_HPP
|
#ifndef SKULLC_UTILITY_FIXEDPOINT_HPP_
|
||||||
#define SKULLC_UTILITY_FIXEDPOINT_HPP
|
#define SKULLC_UTILITY_FIXEDPOINT_HPP_
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
@ -303,4 +303,4 @@ using Q31 = FixedPoint<std::int32_t, 31>;
|
|||||||
|
|
||||||
}// namespace Peripherals
|
}// namespace Peripherals
|
||||||
|
|
||||||
#endif//SKULLC_UTILITY_FIXEDPOINT_HPP
|
#endif//SKULLC_UTILITY_FIXEDPOINT_HPP_
|
||||||
|
|||||||
@ -2,8 +2,8 @@
|
|||||||
// Created by erki on 14.03.21.
|
// Created by erki on 14.03.21.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef UTILITY_LOGGING_HPP_
|
#ifndef SKULLC_UTILITY_LOGGING_HPP_
|
||||||
#define UTILITY_LOGGING_HPP_
|
#define SKULLC_UTILITY_LOGGING_HPP_
|
||||||
|
|
||||||
#include "utility_ilogger.hpp"
|
#include "utility_ilogger.hpp"
|
||||||
|
|
||||||
@ -34,4 +34,4 @@ void setLogger(ILogger& log);
|
|||||||
|
|
||||||
}// namespace Utility
|
}// namespace Utility
|
||||||
|
|
||||||
#endif// UTILITY_LOGGING_HPP_
|
#endif// SKULLC_UTILITY_LOGGING_HPP_
|
||||||
|
|||||||
@ -2,8 +2,8 @@
|
|||||||
// Created by erki on 16.05.21.
|
// Created by erki on 16.05.21.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef SKULLC_UTILITY_PIXELBUFFER_EFFECTS_HPP
|
#ifndef SKULLC_UTILITY_PIXELBUFFER_EFFECTS_HPP_
|
||||||
#define SKULLC_UTILITY_PIXELBUFFER_EFFECTS_HPP
|
#define SKULLC_UTILITY_PIXELBUFFER_EFFECTS_HPP_
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
@ -115,4 +115,4 @@ class ScreenScroll
|
|||||||
}// namespace Effects
|
}// namespace Effects
|
||||||
}// namespace Utility
|
}// namespace Utility
|
||||||
|
|
||||||
#endif//SKULLC_UTILITY_PIXELBUFFER_EFFECTS_HPP
|
#endif//SKULLC_UTILITY_PIXELBUFFER_EFFECTS_HPP_
|
||||||
|
|||||||
@ -2,12 +2,12 @@
|
|||||||
// Created by erki on 29.04.21.
|
// Created by erki on 29.04.21.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef SKULLC_UTILITY_RAND_HPP
|
#ifndef SKULLC_UTILITY_RAND_HPP_
|
||||||
#define SKULLC_UTILITY_RAND_HPP
|
#define SKULLC_UTILITY_RAND_HPP_
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
namespace Peripherals
|
namespace Utility
|
||||||
{
|
{
|
||||||
|
|
||||||
inline std::uint32_t rand32(std::uint32_t& state)
|
inline std::uint32_t rand32(std::uint32_t& state)
|
||||||
@ -35,6 +35,6 @@ inline std::uint64_t rand64(std::uint64_t& state)
|
|||||||
void srand(const std::uint32_t& seed);
|
void srand(const std::uint32_t& seed);
|
||||||
std::uint32_t rand();
|
std::uint32_t rand();
|
||||||
|
|
||||||
}// namespace Peripherals
|
}// namespace Utility
|
||||||
|
|
||||||
#endif//SKULLC_UTILITY_RAND_HPP
|
#endif//SKULLC_UTILITY_RAND_HPP_
|
||||||
|
|||||||
@ -5,8 +5,8 @@
|
|||||||
* Author: erki
|
* Author: erki
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef UTILITY_RINGBUFFER_HPP_
|
#ifndef SKULLC_UTILITY_RINGBUFFER_HPP_
|
||||||
#define UTILITY_RINGBUFFER_HPP_
|
#define SKULLC_UTILITY_RINGBUFFER_HPP_
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
@ -116,27 +116,27 @@ public:
|
|||||||
pointer _arr_end;
|
pointer _arr_end;
|
||||||
};
|
};
|
||||||
|
|
||||||
Ringbuffer() : _head(&_data[0], &_data[0], &_data[N]), _tail(_head) {}
|
Ringbuffer() : head_(&data_[0], &data_[0], &data_[N]), tail_(head_) {}
|
||||||
|
|
||||||
Ringbuffer(const Ringbuffer&) = delete;
|
Ringbuffer(const Ringbuffer&) = delete;
|
||||||
Ringbuffer(Ringbuffer&&) noexcept = default;
|
Ringbuffer(Ringbuffer&&) noexcept = default;
|
||||||
|
|
||||||
iterator begin() { return _head; }
|
iterator begin() { return head_; }
|
||||||
|
|
||||||
iterator end() { return _tail; }
|
iterator end() { return tail_; }
|
||||||
|
|
||||||
void clear() { _head = _tail; }
|
void clear() { head_ = tail_; }
|
||||||
|
|
||||||
void push_back(const T& value)
|
void push_back(const T& value)
|
||||||
{
|
{
|
||||||
if (size() == N)
|
if (size() == N)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
*_tail = value;
|
*tail_ = value;
|
||||||
++_tail;
|
++tail_;
|
||||||
|
|
||||||
if (_tail == _head)
|
if (tail_ == head_)
|
||||||
_is_full = true;
|
is_full_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
@ -145,16 +145,16 @@ public:
|
|||||||
if (size() == N)
|
if (size() == N)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
new (&*_tail) T(std::forward<Args>(args)...);
|
new (&*tail_) T(std::forward<Args>(args)...);
|
||||||
++_tail;
|
++tail_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void increment_tail()
|
void increment_tail()
|
||||||
{
|
{
|
||||||
if (_is_full)
|
if (is_full_)
|
||||||
++_head;
|
++head_;
|
||||||
|
|
||||||
++_tail;
|
++tail_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pop_front()
|
void pop_front()
|
||||||
@ -162,49 +162,49 @@ public:
|
|||||||
if (empty())
|
if (empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
++_head;
|
++head_;
|
||||||
_is_full = false;
|
is_full_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
reference front() { return *_head; }
|
reference front() { return *head_; }
|
||||||
|
|
||||||
const_reference front() const { return *_head; }
|
const_reference front() const { return *head_; }
|
||||||
|
|
||||||
reference back()
|
reference back()
|
||||||
{
|
{
|
||||||
if (empty())
|
if (empty())
|
||||||
return *_tail;
|
return *tail_;
|
||||||
else
|
else
|
||||||
return *(_tail - 1);
|
return *(tail_ - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const_reference back() const
|
const_reference back() const
|
||||||
{
|
{
|
||||||
if (empty())
|
if (empty())
|
||||||
return *_tail;
|
return *tail_;
|
||||||
else
|
else
|
||||||
return *(_tail - 1);
|
return *(tail_ - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_type size() const
|
size_type size() const
|
||||||
{
|
{
|
||||||
if (_head == _tail)
|
if (head_ == tail_)
|
||||||
{
|
{
|
||||||
if (_is_full)
|
if (is_full_)
|
||||||
return N;
|
return N;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const typename Ringbuffer<T, N>::iterator::difference_type distance =
|
const typename Ringbuffer<T, N>::iterator::difference_type distance =
|
||||||
_tail - _head;
|
tail_ - head_;
|
||||||
|
|
||||||
if (distance > 0)
|
if (distance > 0)
|
||||||
{
|
{
|
||||||
return distance;
|
return distance;
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
return _head - _tail + 1;
|
return head_ - tail_ + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,13 +213,13 @@ public:
|
|||||||
bool empty() const { return size() == 0; }
|
bool empty() const { return size() == 0; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::array<T, N> _data;
|
std::array<T, N> data_;
|
||||||
bool _is_full = false;
|
bool is_full_ = false;
|
||||||
|
|
||||||
iterator _head;
|
iterator head_;
|
||||||
iterator _tail;
|
iterator tail_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}// namespace Utility
|
}// namespace Utility
|
||||||
|
|
||||||
#endif /* UTILITY_RINGBUFFER_HPP_ */
|
#endif /* SKULLC_UTILITY_RINGBUFFER_HPP_ */
|
||||||
|
|||||||
@ -5,8 +5,8 @@
|
|||||||
* Author: erki
|
* Author: erki
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef UTILITY_INC_UTILITY_SERIALLOGGER_HPP_
|
#ifndef SKULLC_UTILITY_SERIALLOGGER_HPP_
|
||||||
#define UTILITY_INC_UTILITY_SERIALLOGGER_HPP_
|
#define SKULLC_UTILITY_SERIALLOGGER_HPP_
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
@ -24,7 +24,7 @@ public:
|
|||||||
using serial_interface = T;
|
using serial_interface = T;
|
||||||
|
|
||||||
SerialLogger() = delete;
|
SerialLogger() = delete;
|
||||||
explicit SerialLogger(const serial_interface& serial) : _serial(serial) {}
|
explicit SerialLogger(const serial_interface& serial) : serial_(serial) {}
|
||||||
|
|
||||||
void log(const char* format, ...) override
|
void log(const char* format, ...) override
|
||||||
{
|
{
|
||||||
@ -32,19 +32,19 @@ public:
|
|||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
|
|
||||||
const std::int32_t len =
|
const std::int32_t len =
|
||||||
vsnprintf(_buffer.data(), _buffer.size(), format, args);
|
vsnprintf(buffer_.data(), buffer_.size(), format, args);
|
||||||
|
|
||||||
if (len > 0)
|
if (len > 0)
|
||||||
_serial.Transmit(reinterpret_cast<std::uint8_t*>(_buffer.data()), len);
|
serial_.transmit(reinterpret_cast<std::uint8_t*>(buffer_.data()), len);
|
||||||
|
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
serial_interface _serial;
|
serial_interface serial_;
|
||||||
std::array<char, N> _buffer;
|
std::array<char, N> buffer_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}// namespace Utility
|
}// namespace Utility
|
||||||
|
|
||||||
#endif /* UTILITY_INC_UTILITY_SERIALLOGGER_HPP_ */
|
#endif /* SKULLC_UTILITY_SERIALLOGGER_HPP_ */
|
||||||
|
|||||||
@ -11,7 +11,7 @@ std::uint32_t rand_state = 0;
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Peripherals
|
namespace Utility
|
||||||
{
|
{
|
||||||
|
|
||||||
void srand(const std::uint32_t& seed)
|
void srand(const std::uint32_t& seed)
|
||||||
@ -24,4 +24,4 @@ std::uint32_t rand()
|
|||||||
return rand32(rand_state);
|
return rand32(rand_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
}// namespace Peripherals
|
}// namespace Utility
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user