/* ################################################################### ** This component module is generated by Processor Expert. Do not modify it. ** Filename : McuQuadCounter.h ** Project : FRDM-K64F_Generator ** Processor : MK64FN1M0VLL12 ** Component : QuadCounter ** Version : Component 01.034, Driver 01.00, CPU db: 3.00.000 ** Compiler : GNU C Compiler ** Date/Time : 2020-12-02, 11:59, # CodeGen: 723 ** Abstract : ** This driver implements a quadrature encoder using two signals (C1 and C2) to generate position information. ** Settings : ** Component name : McuQuadCounter ** C1 and C2 swapped : no ** Counter Type : 32bit ** Method : ** Sampling : Enabled ** Error Correction : no ** C1 : SDK_BitIO ** C2 : SDK_BitIO ** Input Capture : Disabled ** Shell : Enabled ** Shell : McuShell ** Utility : McuUtility ** Contents : ** GetPos - McuQuadCounter_QuadCntrType McuQuadCounter_GetPos(void); ** SetPos - void McuQuadCounter_SetPos(McuQuadCounter_QuadCntrType pos); ** GetVal - uint8_t McuQuadCounter_GetVal(void); ** Sample - void McuQuadCounter_Sample(void); ** NofErrors - uint16_t McuQuadCounter_NofErrors(void); ** SwapPins - uint8_t McuQuadCounter_SwapPins(bool swap); ** Deinit - void McuQuadCounter_Deinit(void); ** Init - void McuQuadCounter_Init(void); ** ParseCommand - uint8_t McuQuadCounter_ParseCommand(const unsigned char *cmd, bool *handled,... ** ** * Copyright (c) 2014-2020, Erich Styger ** * Web: https://mcuoneclipse.com ** * SourceForge: https://sourceforge.net/projects/mcuoneclipse ** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx ** * All rights reserved. ** * ** * Redistribution and use in source and binary forms, with or without modification, ** * are permitted provided that the following conditions are met: ** * ** * - Redistributions of source code must retain the above copyright notice, this list ** * of conditions and the following disclaimer. ** * ** * - Redistributions in binary form must reproduce the above copyright notice, this ** * list of conditions and the following disclaimer in the documentation and/or ** * other materials provided with the distribution. ** * ** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** ###################################################################*/ /*! ** @file McuQuadCounter.h ** @version 01.00 ** @brief ** This driver implements a quadrature encoder using two signals (C1 and C2) to generate position information. */ /*! ** @addtogroup McuQuadCounter_module McuQuadCounter module documentation ** @{ */ /* MODULE McuQuadCounter. */ #include "McuQuadCounter.h" #if McuQuadCounter_SWAP_PINS_AT_RUNTIME static bool McuQuadCounter_swappedPins = FALSE; #endif /* The decoder has 4 different states, together with the previous state the table has 16 entries. The value in the table (0,1,-1) indicates the steps taken since previous sample. */ #define QUAD_ERROR 3 /*!< Value to indicate an error in impulse detection. Has to be different from 0,1,-1 */ #if McuQuadCounter_CONFIG_USE_ERROR_CORRECTION static uint8_t McuQuadCounter_prevlast_quadrature_value; /*! Value of C1&C2 before last_quadrature_value. */ static const signed char McuQuadCounter_Quad_Table[4][4][4] = { /* pprev prev new */ { /* c12 c12 c12, c1 leading is backward, c2 leading is forward */ { 0, /* 00 00 00 no change or missed a step? */ 1, /* 00 00 01 */ -1, /* 00 00 10 */ QUAD_ERROR, /* 00 00 11 error, lost impulse */ }, { -1, /* 00 01 00 */ 0, /* 00 01 01 */ 2, /* 00 01 10 lost impulse, correct error */ 1, /* 00 01 11 */ }, { 1, /* 00 10 00 */ -2, /* 00 10 01 lost impulse, correct error */ 0, /* 00 10 10 */ -1, /* 00 10 11 */ }, { QUAD_ERROR, /* 00 11 00 error */ -1, /* 00 11 01 lost impulse, correct error */ 1, /* 00 11 10 */ 0, /* 00 11 11 */ } }, { /* c12 c12 c12 */ { 0, /* 01 00 00 */ 1, /* 01 00 01 */ -1, /* 01 00 10 */ -2, /* 01 00 11 lost impulse, correct error */ }, { -1, /* 01 01 00 */ 0, /* 01 01 01 */ QUAD_ERROR, /* 01 01 10 error */ 1, /* 01 01 11 */ }, { 1, /* 01 10 00 */ QUAD_ERROR, /* 01 10 01 error */ 0, /* 01 10 10 */ -1, /* 01 10 11 */ }, { 2, /* 01 11 00 lost impulse, correct error */ -1, /* 01 11 01 */ 1, /* 01 11 10 */ 0, /* 01 11 11 */ } }, { /* c12 c12 c12 */ { 0, /* 10 00 00 */ 1, /* 10 00 01 */ -1, /* 10 00 10 */ 2, /* 10 00 11 lost impulse, correct error */ }, { -1, /* 10 01 00 */ 0, /* 10 01 01 */ QUAD_ERROR, /* 10 01 10 error */ 1, /* 10 01 11 */ }, { 1, /* 10 10 00 */ QUAD_ERROR, /* 10 10 01 error */ 0, /* 10 10 10 */ -1, /* 10 10 11 */ }, { -2, /* 10 11 00 lost impulse, correct error */ -1, /* 10 11 01 */ 1, /* 10 11 10 */ 0, /* 10 11 11 */ } }, { /* c12 c12 c12 */ { 0, /* 11 00 00 */ 1, /* 11 00 01 */ -1, /* 11 00 10 */ QUAD_ERROR, /* 11 00 11 error */ }, { -1, /* 11 01 00 */ 0, /* 11 01 01 */ -2, /* 11 01 10 lost impulse, correct error */ 1, /* 11 01 11 */ }, { 1, /* 11 10 00 */ 2, /* 11 10 01 lost impulse, correct error */ 0, /* 11 10 10 */ -1, /* 11 10 11 */ }, { QUAD_ERROR, /* 11 11 00 error */ -1, /* 11 11 01 */ 1, /* 11 11 10 */ 0, /* 11 11 11 */ } } }; #else static const signed char McuQuadCounter_Quad_Table[4][4] = { /* prev new */ { /* c1 c2 c1 c2 */ 0, /* 0 0 0 0 no change or missed a step? */ 1, /* 0 0 0 1 */ -1, /* 0 0 1 0 */ QUAD_ERROR /* 0 0 1 1 error, lost impulse */ }, { /* c1 c2 c1 c2 */ -1, /* 0 1 0 0 */ 0, /* 0 1 0 1 no change or missed a step? */ QUAD_ERROR, /* 0 1 1 0 error, lost impulse */ 1 /* 0 1 1 1 */ }, { /* c1 c2 c1 c2 */ 1, /* 1 0 0 0 */ QUAD_ERROR, /* 1 0 0 1 error, lost impulse */ 0, /* 1 0 1 0 no change or missed a step? */ -1 /* 1 0 1 1 */ }, { /* c1 c2 c1 c2 */ QUAD_ERROR, /* 1 1 0 0 error, lost impulse */ -1, /* 1 1 0 1 */ 1, /* 1 1 1 0 */ 0 /* 1 1 1 1 no change or missed a step? */ } }; #endif /* McuQuadCounter_CONFIG_USE_ERROR_CORRECTION */ static uint8_t McuQuadCounter_last_quadrature_value; /*! Value of C1&C2 during last round. */ static McuQuadCounter_QuadCntrType McuQuadCounter_currPos = 0; /*!< Current position */ #if McuQuadCounter_CONFIG_COUNT_ERRORS static uint16_t McuQuadCounter_nofErrors = 0; #endif /* ** =================================================================== ** Method : SetPos (component QuadCounter) ** ** Description : ** Sets the position information. Can be used as well to reset ** the position information. ** Parameters : ** NAME - DESCRIPTION ** pos - Position value to be set. ** Returns : Nothing ** =================================================================== */ void McuQuadCounter_SetPos(McuQuadCounter_QuadCntrType pos) { McuQuadCounter_currPos = pos; } /* ** =================================================================== ** Method : GetPos (component QuadCounter) ** ** Description : ** Returns the current position based on the encoder tracking. ** Parameters : None ** Returns : ** --- - position ** =================================================================== */ McuQuadCounter_QuadCntrType McuQuadCounter_GetPos(void) { return McuQuadCounter_currPos; } /* ** =================================================================== ** Method : GetVal (component QuadCounter) ** ** Description : ** Returns the quadrature value (0, 1, 2 or 3) ** Parameters : None ** Returns : ** --- - Quadrature value (0-3) ** =================================================================== */ uint8_t McuQuadCounter_GetVal(void) { #if McuQuadCounter_SWAP_PINS_AT_RUNTIME if (McuQuadCounter_swappedPins) { return McuQuadCounter_GET_C1_C2_PINS_SWAPPED(); } else { return McuQuadCounter_GET_C1_C2_PINS(); } #else return McuQuadCounter_GET_C1_C2_PINS(); #endif } /* ** =================================================================== ** Method : Sample (component QuadCounter) ** ** Description : ** Call this method to periodically sample the signals. ** Parameters : None ** Returns : Nothing ** =================================================================== */ void McuQuadCounter_Sample(void) { signed char new_step; uint8_t c12; /* value of the two sensor input */ c12 = McuQuadCounter_GetVal(); #if McuQuadCounter_CONFIG_USE_ERROR_CORRECTION new_step = McuQuadCounter_Quad_Table[McuQuadCounter_prevlast_quadrature_value][McuQuadCounter_last_quadrature_value][c12]; McuQuadCounter_prevlast_quadrature_value = McuQuadCounter_last_quadrature_value; #else new_step = McuQuadCounter_Quad_Table[McuQuadCounter_last_quadrature_value][c12]; #endif McuQuadCounter_last_quadrature_value = c12; if (new_step == QUAD_ERROR) { #if McuQuadCounter_CONFIG_COUNT_ERRORS McuQuadCounter_nofErrors++; #endif } else if (new_step != 0) { McuQuadCounter_currPos += new_step; } } /* ** =================================================================== ** Method : NofErrors (component QuadCounter) ** ** Description : ** Returns the number of decoding errors ** Parameters : None ** Returns : ** --- - Error code ** =================================================================== */ uint16_t McuQuadCounter_NofErrors(void) { #if McuQuadCounter_CONFIG_COUNT_ERRORS return McuQuadCounter_nofErrors; #else return 0; #endif } /* ** =================================================================== ** Method : Deinit (component QuadCounter) ** ** Description : ** Module de-initialization method ** Parameters : None ** Returns : Nothing ** =================================================================== */ void McuQuadCounter_Deinit(void) { /* nothing needed */ } /* ** =================================================================== ** Method : Init (component QuadCounter) ** ** Description : ** Module initialization method ** Parameters : None ** Returns : Nothing ** =================================================================== */ void McuQuadCounter_Init(void) { McuQuadCounter_currPos = 0; McuQuadCounter_last_quadrature_value = McuQuadCounter_GET_C1_C2_PINS(); #if McuQuadCounter_CONFIG_USE_ERROR_CORRECTION McuQuadCounter_prevlast_quadrature_value = McuQuadCounter_last_quadrature_value; #endif #if McuQuadCounter_CONFIG_COUNT_ERRORS McuQuadCounter_nofErrors = 0; #endif #if McuQuadCounter_SWAP_PINS_AT_RUNTIME McuQuadCounter_swappedPins = FALSE; #endif } /* ** =================================================================== ** Method : ParseCommand (component QuadCounter) ** ** Description : ** Handler to process shell commands ** Parameters : ** NAME - DESCRIPTION ** cmd - Command string to be parsed ** * handled - Pointer to boolean. The handler ** sets this variable to TRUE if command was ** handled, otherwise let it untouched. ** io - Pointer to I/O structure ** Returns : ** --- - Error code ** =================================================================== */ /*! * \brief Parses a command * \param cmd Command string to be parsed * \param handled Sets this variable to TRUE if command was handled * \param io I/O stream to be used for input/output * \return Error code, ERR_OK if everything was fine */ uint8_t McuQuadCounter_ParseCommand(const unsigned char *cmd, bool *handled, const McuShell_StdIOType *io) { uint8_t res=ERR_OK; if (McuUtility_strcmp((const char*)cmd, McuShell_CMD_HELP)==0 || McuUtility_strcmp((const char *)cmd, "McuQuadCounter help")==0) { McuShell_SendHelpStr((const unsigned char*)"McuQuadCounter", (const unsigned char*)"McuQuadCounter command group\r\n", io->stdOut); McuShell_SendHelpStr((const unsigned char*)" help|status", (const unsigned char*)"Print help or status information\r\n", io->stdOut); McuShell_SendHelpStr((const unsigned char*)" reset", (const unsigned char*)"Reset the current position counter\r\n", io->stdOut); *handled = TRUE; } else if (McuUtility_strcmp((const char*)cmd, McuShell_CMD_STATUS)==0 || McuUtility_strcmp((const char*)cmd, "McuQuadCounter status")==0) { McuShell_SendStr((const unsigned char*)"McuQuadCounter:\r\n", io->stdOut); McuShell_SendStatusStr((const unsigned char*)" pos", (const unsigned char*)"", io->stdOut); #if McuQuadCounter_CNTR_BITS==16 McuShell_SendNum16u(McuQuadCounter_currPos, io->stdOut); #elif McuQuadCounter_CNTR_BITS==32 McuShell_SendNum32u(McuQuadCounter_currPos, io->stdOut); #else #error "unknown counter size!" #endif McuShell_SendStr((const unsigned char*)", ", io->stdOut); #if McuQuadCounter_CNTR_BITS==16 McuShell_SendNum16s((int16_t)McuQuadCounter_currPos, io->stdOut); #elif McuQuadCounter_CNTR_BITS==32 McuShell_SendNum32s((int32_t)McuQuadCounter_currPos, io->stdOut); #else #error "unknown counter size!" #endif McuShell_SendStr((const unsigned char*)"\r\n", io->stdOut); McuShell_SendStatusStr((const unsigned char*)" C1 C2", (const unsigned char*)"", io->stdOut); if (McuQuadCounter_GET_C1_PIN()!=0) { McuShell_SendStr((const unsigned char*)"1 ", io->stdOut); } else { McuShell_SendStr((const unsigned char*)"0 ", io->stdOut); } if (McuQuadCounter_GET_C2_PIN()!=0) { McuShell_SendStr((const unsigned char*)"1\r\n", io->stdOut); } else { McuShell_SendStr((const unsigned char*)"0\r\n", io->stdOut); } #if McuQuadCounter_CONFIG_COUNT_ERRORS McuShell_SendStatusStr((const unsigned char*)" errors", (const unsigned char*)"", io->stdOut); McuShell_SendNum16u(McuQuadCounter_nofErrors, io->stdOut); McuShell_SendStr((const unsigned char*)"\r\n", io->stdOut); #endif *handled = TRUE; } else if (McuUtility_strcmp((const char*)cmd, "McuQuadCounter reset")==0) { McuQuadCounter_SetPos(0); #if McuQuadCounter_CONFIG_COUNT_ERRORS McuQuadCounter_nofErrors = 0; #endif *handled = TRUE; } return res; } /* ** =================================================================== ** Method : SwapPins (component QuadCounter) ** ** Description : ** Swap the two pins ** Parameters : ** NAME - DESCRIPTION ** swap - if C1 and C2 pins shall be swapped. ** Returns : ** --- - Error code ** =================================================================== */ uint8_t McuQuadCounter_SwapPins(bool swap) { McuQuadCounter_swappedPins = swap; return ERR_OK; } /* END McuQuadCounter. */ /*! ** @} */