Advanced Distributed Systems module at HSLU
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
ADIS_Projects/McuLib/src/McuQuadCounter.c

487 lines
18 KiB

/* ###################################################################
** 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. */
/*!
** @}
*/