Skip to content

Commit

Permalink
[driver] Add BitBangEncoderInput driver
Browse files Browse the repository at this point in the history
  • Loading branch information
TomSaw authored and salkinium committed Mar 22, 2021
1 parent d7ecd88 commit d9f411d
Show file tree
Hide file tree
Showing 4 changed files with 183 additions and 9 deletions.
19 changes: 10 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,65 +205,66 @@ can easily configure them for you specific needs.
<td align="center">DS1631</td>
<td align="center">DS18B20</td>
<td align="center">EA-DOG</td>
<td align="center">ENCODER-INPUT-BITBANG</td>
<td align="center">ENCODER-OUTPUT-BITBANG</td>
<td align="center">FT245</td>
</tr><tr>
<td align="center">FT245</td>
<td align="center">FT6X06</td>
<td align="center">GPIO-SAMPLER</td>
<td align="center">HCLAx</td>
<td align="center">HD44780</td>
<td align="center">HMC58x</td>
<td align="center">HMC6343</td>
</tr><tr>
<td align="center">HMC6343</td>
<td align="center">HX711</td>
<td align="center">I2C-EEPROM</td>
<td align="center">ILI9341</td>
<td align="center">IS31FL3733</td>
<td align="center">ITG3200</td>
<td align="center">L3GD20</td>
</tr><tr>
<td align="center">L3GD20</td>
<td align="center">LAN8720A</td>
<td align="center">LAWICEL</td>
<td align="center">LIS302DL</td>
<td align="center">LIS3DSH</td>
<td align="center">LIS3MDL</td>
<td align="center">LM75</td>
</tr><tr>
<td align="center">LM75</td>
<td align="center">LP503X</td>
<td align="center">LSM303A</td>
<td align="center">LSM6DS33</td>
<td align="center">LTC2984</td>
<td align="center">MAX6966</td>
<td align="center">MAX7219</td>
</tr><tr>
<td align="center">MAX7219</td>
<td align="center">MCP23X17</td>
<td align="center">MCP2515</td>
<td align="center">MMC5603</td>
<td align="center">NOKIA5110</td>
<td align="center">NRF24</td>
<td align="center">TFT-DISPLAY</td>
</tr><tr>
<td align="center">TFT-DISPLAY</td>
<td align="center">PAT9125EL</td>
<td align="center">PCA8574</td>
<td align="center">PCA9535</td>
<td align="center">PCA9548A</td>
<td align="center">PCA9685</td>
<td align="center">SIEMENS-S65</td>
</tr><tr>
<td align="center">SIEMENS-S65</td>
<td align="center">SIEMENS-S75</td>
<td align="center">SK6812</td>
<td align="center">SK9822</td>
<td align="center">SSD1306</td>
<td align="center">STUSB4500</td>
<td align="center">SX1276</td>
</tr><tr>
<td align="center">SX1276</td>
<td align="center">TCS3414</td>
<td align="center">TCS3472</td>
<td align="center">TLC594X</td>
<td align="center">TMP102</td>
<td align="center">TMP175</td>
<td align="center">VL53L0</td>
</tr><tr>
<td align="center">VL53L0</td>
<td align="center">VL6180</td>
<td align="center">WS2812</td>
</tr>
Expand Down
72 changes: 72 additions & 0 deletions src/modm/driver/encoder/bitbang_encoder_input.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Copyright (c) 2021, Thomas Sommer
*
* This file is part of the modm project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// ----------------------------------------------------------------------------

#ifndef MODM_BITBANG_ENCODER_INPUT_HPP
#define MODM_BITBANG_ENCODER_INPUT_HPP

#include <bit>
#include <modm/platform.hpp>
#include <type_traits>

namespace modm
{
/**
* @ingroup modm_driver_bitbang_encoder_input
* @author Thomas Sommer
*
* @brief This driver decodes a AB (incremental) encoder signal
*
* @tparam SignalA First modm::platform::Gpio pin to input the encoder signal.
* @tparam SignalB Second modm::platform::Gpio pin to input the encoder signal.
* @tparam POSTSCALER n_cycles to count as one in-/decrement.
* @tparam DeltaType Must be signed integer and fit at least POSTSCALER. The Bigger
* DeltaType, the more inc-/decrements can be stored temporarily.
*/
template<typename SignalA, typename SignalB, uint8_t POSTSCALER = 4,
std::signed_integral DeltaType = int8_t>
class BitBangEncoderInput
{
static_assert(std::popcount(POSTSCALER) == 1,
"POSTSCALER must be an integer to basis 2 and not 0: 1, 2, 4, 8, 16, ...");
static_assert(POSTSCALER <= std::numeric_limits<DeltaType>::max(),
"DeltaType is to small for POSTSCALER.");

using Signals = modm::platform::SoftwareGpioPort<SignalA, SignalB>;

static_assert(Signals::number_of_ports == 1,
"Signal A/B must be on the same GPIO port to prevent signal tearing!");

uint8_t inline getRaw();

public:
using ValueType = DeltaType;
BitBangEncoderInput() : raw_last(0), delta(0){};

// Connect SingalA and SignalB and store power-up state
inline void
connect();

// Call @1kHz for manual movement
inline void
update();

ValueType
getIncrement();

private:
uint8_t raw_last;
DeltaType delta;
};
} // namespace modm

#include "bitbang_encoder_input_impl.hpp"

#endif // MODM_BITBANG_ENCODER_INPUT_HPP
32 changes: 32 additions & 0 deletions src/modm/driver/encoder/bitbang_encoder_input.lb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (c) 2021, Thomas Sommer
#
# This file is part of the modm project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# -----------------------------------------------------------------------------

def init(module):
module.name = ":driver:encoder_input.bitbang"
module.description = """
# Quadrature Encoder Input
This driver decodes a AB (incremental) encoder signal.
Ported from code created by Peter Dannegger:
https://www.mikrocontroller.net/articles/Drehgeber.
"""


def prepare(module, options):
module.depends(":architecture:atomic")
return True


def build(env):
env.outbasepath = "modm/src/modm/driver/encoder"
env.copy("bitbang_encoder_input.hpp")
env.copy("bitbang_encoder_input_impl.hpp")
69 changes: 69 additions & 0 deletions src/modm/driver/encoder/bitbang_encoder_input_impl.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright (c) 2021, Thomas Sommer
*
* This file is part of the modm project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// ----------------------------------------------------------------------------

#ifndef MODM_BITBANG_ENCODER_INPUT_HPP
#error "Don't include this file directly, use 'bitbang_encoder_input.hpp' instead!"
#endif

#include <cmath>

template<typename SignalA, typename SignalB, uint8_t POSTSCALER,
std::signed_integral DeltaType>
inline uint8_t
modm::BitBangEncoderInput<SignalA, SignalB, POSTSCALER, DeltaType>::getRaw()
{
const uint8_t read = Signals::read();
// convert graycode to binary
uint8_t raw = 0;
if (read & 0b10) raw = 3;
if (read & 0b01) raw ^= 1;
return raw;
}

template<typename SignalA, typename SignalB, uint8_t POSTSCALER,
std::signed_integral DeltaType>
inline void
modm::BitBangEncoderInput<SignalA, SignalB, POSTSCALER, DeltaType>::connect()
{
Signals::setInput(::Gpio::InputType::PullUp);

// Tare power-on state
modm::delay(10us);
raw_last = getRaw();
}

template<typename SignalA, typename SignalB, uint8_t POSTSCALER,
std::signed_integral DeltaType>
inline void
modm::BitBangEncoderInput<SignalA, SignalB, POSTSCALER, DeltaType>::update()
{
uint8_t raw = getRaw();
const uint8_t diff = raw_last - raw;
if (diff & 0b01)
{
raw_last = raw;
delta += (diff & 0b10) - 1; // bit 1 = direction (+/-)
}
}

template<typename SignalA, typename SignalB, uint8_t POSTSCALER,
std::signed_integral DeltaType>
DeltaType
modm::BitBangEncoderInput<SignalA, SignalB, POSTSCALER, DeltaType>::getIncrement()
{
::modm::atomic::Lock _;
DeltaType val = delta;

delta &= (POSTSCALER - 1); // mask out higher bits

constexpr uint8_t shift = std::log2(POSTSCALER); // Number of fraction bits
return val >> shift; // return whats left without fractions
}

0 comments on commit d9f411d

Please sign in to comment.