Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions Documentation/components/drivers/character/quadrature.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@
Quadrature Encoder Drivers
==========================

A Quadrature Encoder (QE) is a kind of sensor normally used to read
angular rotation of a motor or other turning device.

NuttX supports internal QE peripheral that exists in some microcontrollers
like ESP32, iMXRT, STM32, nRF5x, TIVA, and others, and also supports
Magnetic Rotary Encoders like AS5048, MT6816, etc.

Internal Peripheral Quadrature Encoder
======================================

NuttX supports a low-level, two-part Quadrature Encoder driver.

#. An "upper half", generic driver that provides the common
Expand All @@ -28,6 +38,46 @@ following locations:
for the specific processor ``<architecture>`` and for the
specific ``<chip>`` Quadrature Encoder peripheral devices.

Magnetic Rotary Encoder
=======================

Although technically a Magnetic Rotary Encoder is not a Quadrature Encoder,
usually uses the QE Lower Half driver to export a device compatible with
quadrature encoder. This way an application using an ordinary QE encoder
could use a Magnetic Rotary Encoder with any modification, just need to
enable and initialize the Magnetic Rotary Encoder on their board.

This is how a board powered by STM32 will initialize a MT6816 Magnetic
Rotary Encoder:

.. code-block:: c

/* Initialize the SPI bus connected to MT6816 */

spi = stm32_spibus_initialize(spi_busno);
if (spi == NULL)
{
return -ENODEV;
}

/* Initialize MT6816 using `spi` and a `device number` starting from 0 */

dev = mt6816_initialize(spi, (uint16_t) devno);
if (dev == NULL)
{
return -ENODEV;
}

/* Use the returned qe lower half to register /dev/qe# (# => devno) */

ret = qe_register(qe_path, dev);
if (ret < 0)
{
snerr("ERROR: Failed to register MT6816 qe%d driver: %d\n",
devno, ret);
ret = -ENODEV;
}

Application Programming Interface
=================================

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1523,6 +1523,61 @@ After compiling and flashing the firmware in our board, run kbd command.
code : 49
type : 1

mt6816
------

This board config enables the MagTek MT6816 Magnetic Rotary Encoder connected
to STM32F4Discovery board SPI1 this way:

================ ======
STM32F4Discovery MT6816
================ ======
3V [1] VCC
GND GND
PE3 CSN
SPI1 MOSI (PA7) MOSI
SPI1 MISO (PA6) MISO
SPI1 SCK (PA5) SCK
================ ======

1: You need to remove the diode D3 and short-circuit the PADs in the
board to get 3.3V. Be aware: although my board works fine, it could
damage something that expects 3V in our board (double check).

IMPORTANT: You need to connect the HVPP (pin 2) to VCC in order to get
MT6816 working in SPI mode. Just short-circuit R3 pads will work:

.. figure:: mt6816.png
:align: center

After compiling and flashing the firmware in our board, run qe command:

.. code:: console

NuttShell (NSH) NuttX-12.13.0
nsh> ls /dev
/dev:
console
null
qe0
ttyS0
zero
nsh> qe
qe_main: Hardware initialized. Opening the encoder device: /dev/qe0
qe_main: Number of samples: 0
qe_main: 1. 6546
qe_main: 2. 6620
qe_main: 3. 7384
qe_main: 4. 7808
qe_main: 5. 7900
qe_main: 6. 7984
qe_main: 7. 7989
qe_main: 8. 7993
qe_main: 9. 7998
qe_main: 10. 8008
qe_main: 11. 8052
qe_main: 12. 8064

netnsh
------

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 3 additions & 1 deletion arch/arm/src/stm32/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,9 @@ if(CONFIG_STM32_CAP)
endif()

if(CONFIG_SENSORS_QENCODER)
list(APPEND SRCS stm32_qencoder.c)
if(CONFIG_STM32_QE)
list(APPEND SRCS stm32_qencoder.c)
endif()
endif()

if(CONFIG_SENSORS_HALL3PHASE)
Expand Down
10 changes: 10 additions & 0 deletions arch/arm/src/stm32/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -12004,6 +12004,10 @@ config STM32_DMA2D_REGDEBUG
endmenu
endif # STM32_DMA2D

config STM32_QE
bool
default n

menu "STM32 QEncoder Driver"
depends on SENSORS_QENCODER
depends on STM32_TIM1 || STM32_TIM2 || STM32_TIM3 || STM32_TIM4 || STM32_TIM5 || STM32_TIM8
Expand All @@ -12020,6 +12024,7 @@ config STM32_TIM1_QE
bool "TIM1 QE"
default n
depends on STM32_TIM1
select STM32_QE
---help---
Reserve TIM1 for use by QEncoder.

Expand All @@ -12038,6 +12043,7 @@ config STM32_TIM2_QE
bool "TIM2 QE"
default n
depends on STM32_TIM2
select STM32_QE
---help---
Reserve TIM2 for use by QEncoder.

Expand All @@ -12056,6 +12062,7 @@ config STM32_TIM3_QE
bool "TIM3 QE"
default n
depends on STM32_TIM3
select STM32_QE
---help---
Reserve TIM3 for use by QEncoder.

Expand All @@ -12074,6 +12081,7 @@ config STM32_TIM4_QE
bool "TIM4 QE"
default n
depends on STM32_TIM4
select STM32_QE
---help---
Reserve TIM4 for use by QEncoder.

Expand All @@ -12092,6 +12100,7 @@ config STM32_TIM5_QE
bool "TIM5 QE"
default n
depends on STM32_TIM5
select STM32_QE
---help---
Reserve TIM5 for use by QEncoder.

Expand All @@ -12110,6 +12119,7 @@ config STM32_TIM8_QE
bool "TIM8 QE"
default n
depends on STM32_TIM8
select STM32_QE
---help---
Reserve TIM8 for use by QEncoder.

Expand Down
4 changes: 3 additions & 1 deletion arch/arm/src/stm32/Make.defs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,9 @@ CHIP_CSRCS += stm32_capture_lowerhalf.c
endif

ifeq ($(CONFIG_SENSORS_QENCODER),y)
CHIP_CSRCS += stm32_qencoder.c
ifeq ($(CONFIG_STM32_QE),y)
CHIP_CSRCS += stm32_qencoder.c
endif
endif

ifeq ($(CONFIG_SENSORS_HALL3PHASE),y)
Expand Down
75 changes: 75 additions & 0 deletions boards/arm/stm32/common/include/stm32_mt6816.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/****************************************************************************
* boards/arm/stm32/common/include/stm32_mt6816.h
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/

#ifndef __BOARDS_ARM_STM32_COMMON_INCLUDE_STM32_MT6816_H
#define __BOARDS_ARM_STM32_COMMON_INCLUDE_STM32_MT6816_H

/****************************************************************************
* Included Files
****************************************************************************/

#include <nuttx/config.h>

/****************************************************************************
* Pre-processor Definitions
****************************************************************************/

/****************************************************************************
* Public Types
****************************************************************************/

/****************************************************************************
* Public Data
****************************************************************************/

#ifdef __cplusplus
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif

/****************************************************************************
* Inline Functions
****************************************************************************/

/****************************************************************************
* Public Function Prototypes
****************************************************************************/

/****************************************************************************
* Name: board_mt6816_initialize
*
* Description:
* Initialize the MT6816 encoder driver
*
****************************************************************************/

int board_mt6816_initialize(int devno, int spi_busno);

#undef EXTERN
#ifdef __cplusplus
}
#endif

#endif /* __BOARDS_ARM_STM32_COMMON_INCLUDE_STM32_MT6816_H */
8 changes: 7 additions & 1 deletion boards/arm/stm32/common/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,18 @@ if(CONFIG_SENSORS_APDS9960)
list(APPEND SRCS stm32_apds9960.c)
endif()

if(CONFIG_SENSORS_MT6816)
list(APPEND SRCS stm32_mt6816.c)
endif()

if(CONFIG_SENSORS_ZEROCROSS)
list(APPEND SRCS stm32_zerocross.c)
endif()

if(CONFIG_SENSORS_QENCODER)
list(APPEND SRCS stm32_qencoder.c)
if(CONFIG_STM32_QE)
list(APPEND SRCS stm32_qencoder.c)
endif()
endif()

if(CONFIG_SENSORS_INA219)
Expand Down
8 changes: 7 additions & 1 deletion boards/arm/stm32/common/src/Make.defs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ ifeq ($(CONFIG_SENSORS_APDS9960),y)
CSRCS += stm32_apds9960.c
endif

ifeq ($(CONFIG_SENSORS_MT6816),y)
CSRCS += stm32_mt6816.c
endif

ifeq ($(CONFIG_INPUT_MPR121_KEYPAD),y)
CSRCS += stm32_mpr121.c
endif
Expand All @@ -95,7 +99,9 @@ ifeq ($(CONFIG_SENSORS_ZEROCROSS),y)
endif

ifeq ($(CONFIG_SENSORS_QENCODER),y)
CSRCS += stm32_qencoder.c
ifeq ($(CONFIG_STM32_QE),y)
CSRCS += stm32_qencoder.c
endif
endif

ifeq ($(CONFIG_SENSORS_HALL3PHASE),y)
Expand Down
Loading
Loading