Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minor change to re enable Compare mode and added POSMATCH control option. #3

Merged
merged 12 commits into from
Jun 4, 2022
25 changes: 16 additions & 9 deletions QuadEncoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const QuadEncoder::ENC_Channel_t QuadEncoder::channel[] = {
{1, &IMXRT_ENC1, IRQ_ENC1, isrEnc1, 66, 67, 68, 69, 70,&CCM_CCGR4,CCM_CCGR4_ENC1(CCM_CCGR_ON)},
{2, &IMXRT_ENC2, IRQ_ENC2, isrEnc2, 71, 72, 73, 74, 75,&CCM_CCGR4,CCM_CCGR4_ENC2(CCM_CCGR_ON)},
{3, &IMXRT_ENC3, IRQ_ENC3, isrEnc3, 76, 77, 78, 79, 80,&CCM_CCGR4,CCM_CCGR4_ENC3(CCM_CCGR_ON)},
{4, &IMXRT_ENC4, IRQ_ENC4, isrEnc4, 81, 82, 83, 84, 95,&CCM_CCGR4,CCM_CCGR4_ENC4(CCM_CCGR_ON)}
{4, &IMXRT_ENC4, IRQ_ENC4, isrEnc4, 81, 82, 83, 84, 85,&CCM_CCGR4,CCM_CCGR4_ENC4(CCM_CCGR_ON)}
};
const uint8_t QuadEncoder::_channel_count = (sizeof(QuadEncoder::channel)/sizeof(QuadEncoder::channel[0]));

Expand Down Expand Up @@ -106,14 +106,15 @@ void QuadEncoder::getConfig1(enc_config_t *config)
config->enableReverseDirection = DISABLE;
config->decoderWorkMode = DISABLE;
config->HOMETriggerMode = DISABLE;
config->INDEXTriggerMode = DISABLE;
config->INDEXTriggerMode = 0;
config->IndexTrigger = DISABLE;
config->HomeTrigger = DISABLE;
config->clearCounter = DISABLE;
config->clearHoldCounter = DISABLE;
config->filterCount = 0;
config->filterSamplePeriod = 0;
config->positionMatchMode = DISABLE;
config->positionMatchMode = false;
config->positionCompareMode = DISABLE;
config->positionCompareValue = 0xffffffff;
config->revolutionCountCondition = DISABLE;
config->enableModuloCountMode = DISABLE;
Expand All @@ -139,8 +140,9 @@ void QuadEncoder::printConfig(enc_config_t *config)
Serial.printf("\tfilterCount: %d\n",config->filterCount);
Serial.printf("\tfilterSamplePeriod: %d\n",config->filterSamplePeriod);
Serial.printf("\tpositionCompareValue: %x\n",config->positionCompareValue);
Serial.printf("\trevolutionCountCondition: %d\n",config->clearCounter);
Serial.printf("\tenableModuloCountMode: %d\n",config->clearHoldCounter);
Serial.printf("\trevolutionCountCondition: %d\n",config->revolutionCountCondition);
Serial.printf("\tenableModuloCountMode: %d\n",config->enableModuloCountMode);
Serial.printf("\tpositionModulusValue: %d\n", config->positionModulusValue);

Serial.printf("\tpositionInitialValue: %d\n",config->positionInitialValue);
Serial.printf("\tpositionROIE: %d\n",config->positionROIE);
Expand All @@ -167,7 +169,7 @@ void QuadEncoder::Init(const enc_config_t *config)
tmp16 = channel[_encoder_ch].ENC->CTRL & (uint16_t)(~(ENC_CTRL_W1C_FLAGS | ENC_CTRL_HIP_MASK | ENC_CTRL_HNE_MASK | ENC_CTRL_REV_MASK | ENC_CTRL_PH1_MASK | ENC_CTRL_XIP_MASK | ENC_CTRL_XNE_MASK | ENC_CTRL_WDE_MASK));

/* For HOME trigger. */
if (config->HOMETriggerMode != DISABLE)
if (config->HOMETriggerMode != 0)
{
tmp16 |= ENC_CTRL_HIP_MASK;
if (FALLING_EDGE == config->HOMETriggerMode)
Expand All @@ -186,7 +188,7 @@ void QuadEncoder::Init(const enc_config_t *config)
tmp16 |= ENC_CTRL_PH1_MASK;
}
/* For INDEX trigger. */
if (DISABLE != config->INDEXTriggerMode)
if (config->INDEXTriggerMode != 0 )
{
tmp16 |= ENC_CTRL_XIP_MASK;
if (FALLING_EDGE == config->INDEXTriggerMode)
Expand Down Expand Up @@ -257,6 +259,11 @@ void QuadEncoder::write(uint32_t value)
setConfigInitialPosition();
}

void QuadEncoder::setCompareValue(uint32_t compareValue) {
/* ENC_UCOMP & ENC_LCOMP. */
channel[_encoder_ch].ENC->UCOMP = (uint16_t)(compareValue >> 16U); /* Upper 16 bits. */
channel[_encoder_ch].ENC->LCOMP = (uint16_t)(compareValue); /* Lower 16 bits. */
}
uint32_t QuadEncoder::getHoldPosition()
{
uint32_t ret32;
Expand Down Expand Up @@ -382,7 +389,7 @@ void QuadEncoder::enableInterrupts(const enc_config_t *config)
tmp16 |= ENC_CTRL_XIE_MASK;
}

if (config->positionMatchMode == ENABLE)
if (config->positionCompareMode == ENABLE)
{
tmp16 |= ENC_CTRL_CMPIE_MASK;
}
Expand Down Expand Up @@ -553,7 +560,7 @@ void QuadEncoder::isr(uint8_t index)
}
}

void QuadEncoder::resetCompareInterupt()
void QuadEncoder::enableCompareInterrupt()
{
channel[_encoder_ch].ENC->CTRL |= ENC_CTRL_CMPIE_MASK;
}
5 changes: 4 additions & 1 deletion QuadEncoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ class QuadEncoder
/* 0 - POSMATCH pulses when a match occurs between the position counters (POS) and the compare value (COMP). 1 - POSMATCH pulses when any position counter register is read. */
bool positionMatchMode;

/* Position Compare Enabled. */
bool positionCompareMode;
/*!< Position compare value. The available value is a 32-bit number.*/
uint32_t positionCompareValue;

Expand Down Expand Up @@ -194,6 +196,7 @@ class QuadEncoder
void Init(const enc_config_t *config);
int32_t read();
void write(uint32_t value);
void setCompareValue(uint32_t compareValue);
uint32_t getHoldPosition();
uint16_t getPositionDifference();
uint16_t getHoldDifference();
Expand All @@ -209,7 +212,7 @@ class QuadEncoder
void enableInterrupts(const enc_config_t *config);
void disableInterrupts(uint32_t flag);
void clearStatusFlags(uint32_t flag, uint8_t index);
void resetCompareInterupt();
void enableCompareInterrupt();

// static class functions
static void isrEnc1();
Expand Down
76 changes: 39 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
# Hardware Quadrature Library for the Teensy 4.x
Library based on NXP Quad Encoder SDK driver for the Encoder module but modified to support the Teensy 4.x infrastructure.

There are 4 hardware quadrature encoder channels available the Teensy 4.x. The Teensy 4.x Encoders are supported on pins: 0, 1, 2, 3, 4, 5, 7, 30, 31 and 33. On the T4.1 the following additional pins are supported: 36 and 37.
There are 4 hardware quadrature encoder channels available the Teensy 4.x. The Teensy 4.x Encoders are supported on pins: 0, 1, 2, 3, 4, 5, 7, 8, 30, 31 and 33. On the T4.1 the following additional pins are supported: 36 and 37.

WARNING! Pins 0, 5 and 37 share the same internal crossbar connections and are as such exclusive...pick one or the other.
WARNING! Pins 0, 5 and 37 share the same internal crossbar connections and are as such exclusive...pick one or the other. Same thing applies to pins 1 / 36 and 5 / 37.

For Teensy 4.0: pins 0-8, 30, 31, 33 are supported.
For Teensy 4.1: pins 0-8, 30, 31, 33 and pin 37 are supported.
For Teensy Micromod: pins 0-8, 30, 31, 33, 36 and 37 are supported

The constuctor is designed to tell the library what encoder channel, PhaseA and PhaseB pins to use as well as whether to use pullups on those pins. Example:
```c++
Expand Down Expand Up @@ -40,45 +44,43 @@ In this case ```myEnc2.EncConfig.positionInitialValue``` changes the starting va

Current available parameters:
```c++
/* Basic counter. */
bool enableReverseDirection;
bool decoderWorkMode; // 0 = Normal mode, 1 = PHASEA input generates a count signal while PHASEB input control the direction.

/* Signal detection. */
uint8_t HOMETriggerMode; //0 - disable, 1 - rising, 2 - falling
uint8_t INDEXTriggerMode; //0 - disabled, 1 - Use positive going edge-to-trigger initialization of position counters!, 2 - use falling

bool IndexTrigger; //0 - disable index counting, 1 - enable index counting
bool HomeTrigger;

bool clearCounter;
bool clearHoldCounter;

/* Filter for PHASEA, PHASEB, INDEX and HOME. */
/* Input Filter Sample Count. This value should be chosen to reduce the probability of noisy samples causing an incorrect transition to be recognized. The value represent the number of consecutive samples that must agree prior to the input filter accepting an input transition. A value of 0x0 represents 3 samples. A value of 0x7 represents 10 samples. The Available range is 0 - 7. */
uint16_t filterCount;

/* Input Filter Sample Period. This value should be set such that the sampling period is larger than the period of the expected noise. This value represents the sampling period (in IPBus clock cycles) of the decoder input signals. The available range is 0 - 255. */
uint16_t filterSamplePeriod;

/* Position compare. */
/* 0 - POSMATCH pulses when a match occurs between the position counters (POS) and the compare value (COMP). 1 - POSMATCH pulses when any position counter register is read. */
bool positionMatchMode;
/* Basic counter. */
bool enableReverseDirection;
bool decoderWorkMode; // 0 = Normal mode, 1 = PHASEA input generates a count signal while PHASEB input control the direction.

/* Signal detection. */
uint8_t HOMETriggerMode; //0 - disable, 1 - rising, 2 - falling
uint8_t INDEXTriggerMode; //0 - disabled, 1 - Use positive going edge-to-trigger initialization of position counters!, 2 - use falling
bool clearCounter;
bool clearHoldCounter;

/* Filter for PHASEA, PHASEB, INDEX and HOME. */
/* Input Filter Sample Count. This value should be chosen to reduce the probability of noisy samples causing an incorrect transition to be recognized. The value represent the number of consecutive samples that must agree prior to the input filter accepting an input transition. A value of 0x0 represents 3 samples. A value of 0x7 represents 10 samples. The Available range is 0 - 7. */
uint16_t filterCount;

/* Input Filter Sample Period. This value should be set such that the sampling period is larger than the period of the expected noise. This value represents the sampling period (in IPBus clock cycles) of the decoder input signals. The available range is 0 - 255. */
uint16_t filterSamplePeriod;

/* Position compare. */
/* 0 - POSMATCH pulses when a match occurs between the position counters (POS) and the compare value (COMP). 1 - POSMATCH pulses when any position counter register is read. */
bool positionMatchMode;

/*!< Position compare value. The available value is a 32-bit number.*/
uint32_t positionCompareValue;

/* Modulus counting. */
/*0 - Use INDEX pulse to increment/decrement revolution counter. 1 - Use modulus counting roll-over/under to increment/decrement revolution counter. */
bool revolutionCountCondition;
/* Position Compare Enabled. */
bool positionCompareMode; **<< NEW examples updated **
/*!< Position compare value. The available value is a 32-bit number.*/
uint32_t positionCompareValue;

/* Modulus counting. */
/*0 - Use INDEX pulse to increment/decrement revolution counter. 1 - Use modulus counting roll-over/under to increment/decrement revolution counter. */
bool revolutionCountCondition;

bool enableModuloCountMode; //Enable Modulo Counting. */
bool enableModuloCountMode; //Enable Modulo Counting. */

/*Position modulus value. This value would be available only when "enableModuloCountMode" = true. The available value is a 32-bit number. */
uint32_t positionModulusValue;
/*Position modulus value. This value would be available only when "enableModuloCountMode" = true. The available value is a 32-bit number. */
uint32_t positionModulusValue;

//Position initial value. The available value is a 32-bit number. */
uint32_t positionInitialValue;
//Position initial value. The available value is a 32-bit number. */
uint32_t positionInitialValue;
```

A couple of things to note when using the INDEX or the HOME triggers are used:
Expand Down
12 changes: 8 additions & 4 deletions examples/QuadEncoder/QuadEncoder.ino
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ void setup()

myEnc2.setInitConfig(); //
myEnc2.EncConfig.positionInitialValue = 160;
myEnc2.EncConfig.positionMatchMode = ENABLE;
myEnc2.EncConfig.positionCompareMode = ENABLE;
myEnc2.EncConfig.positionCompareValue = 200;
myEnc2.EncConfig.filterCount = 5;
myEnc2.EncConfig.filterSamplePeriod = 255;
Expand All @@ -55,13 +55,17 @@ void loop(){
if(myEnc2.compareValueFlag == 1) {
//myEnc2.init();
//resets counter to positionInitialValue so compare
//will hit every 200
//will hit every positionCompareValue
myEnc2.write(myEnc2.EncConfig.positionInitialValue);
myEnc2.resetCompareInterupt();
Serial.print("Compare Value Hit for Encoder 2: ");
Serial.println(myEnc2.compareValueFlag);
Serial.println();
myEnc2.compareValueFlag = 0;
//Resets the compare value to 300 after initial value is set
myEnc2.setCompareValue(300);
// re-enable the Compare Interrupt
myEnc2.enableCompareInterrupt();

}

if(mCurPosValue1 != old_position1){
Expand All @@ -73,4 +77,4 @@ void loop(){
}

old_position1 = mCurPosValue1;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ void setup()

/* Initialize the ENC module. */
myEnc1.setInitConfig();
myEnc1.EncConfig.IndexTrigger = ENABLE; //enable to use index counter
myEnc1.EncConfig.INDEXTriggerMode = RISING_EDGE;

myEnc1.init();
Expand All @@ -36,4 +37,4 @@ void loop(){

old_position = mCurPosValue;

}
}