
Example project
Dependencies: PM2_Libary Eigen
EncoderCounterROME2.cpp@39:f336caef17d9, 2022-05-10 (annotated)
- Committer:
- pmic
- Date:
- Tue May 10 14:11:06 2022 +0200
- Revision:
- 39:f336caef17d9
- Parent:
- 37:698d6b73b50c
Version without StateMachine
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
pmic | 37:698d6b73b50c | 1 | /* |
pmic | 37:698d6b73b50c | 2 | * EncoderCounterROME2.cpp |
pmic | 37:698d6b73b50c | 3 | * Copyright (c) 2022, ZHAW |
pmic | 37:698d6b73b50c | 4 | * All rights reserved. |
pmic | 37:698d6b73b50c | 5 | */ |
pmic | 37:698d6b73b50c | 6 | |
pmic | 37:698d6b73b50c | 7 | #include "EncoderCounterROME2.h" |
pmic | 37:698d6b73b50c | 8 | |
pmic | 37:698d6b73b50c | 9 | using namespace std; |
pmic | 37:698d6b73b50c | 10 | |
pmic | 37:698d6b73b50c | 11 | /** |
pmic | 37:698d6b73b50c | 12 | * Creates and initialises the driver to read the quadrature |
pmic | 37:698d6b73b50c | 13 | * encoder counter of the STM32 microcontroller. |
pmic | 37:698d6b73b50c | 14 | * @param a the input pin for the channel A. |
pmic | 37:698d6b73b50c | 15 | * @param b the input pin for the channel B. |
pmic | 37:698d6b73b50c | 16 | */ |
pmic | 37:698d6b73b50c | 17 | EncoderCounterROME2::EncoderCounterROME2(PinName a, PinName b) { |
pmic | 37:698d6b73b50c | 18 | |
pmic | 37:698d6b73b50c | 19 | // check pins |
pmic | 37:698d6b73b50c | 20 | |
pmic | 37:698d6b73b50c | 21 | if ((a == PA_15) && (b == PB_3)) { |
pmic | 37:698d6b73b50c | 22 | |
pmic | 37:698d6b73b50c | 23 | // pinmap OK for TIM2 CH1 and CH2 |
pmic | 37:698d6b73b50c | 24 | |
pmic | 37:698d6b73b50c | 25 | TIM = TIM2; |
pmic | 37:698d6b73b50c | 26 | |
pmic | 37:698d6b73b50c | 27 | // configure reset and clock control registers |
pmic | 37:698d6b73b50c | 28 | |
pmic | 37:698d6b73b50c | 29 | RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN; // manually enable port B (port A enabled by mbed library) |
pmic | 37:698d6b73b50c | 30 | |
pmic | 37:698d6b73b50c | 31 | // configure general purpose I/O registers |
pmic | 37:698d6b73b50c | 32 | |
pmic | 37:698d6b73b50c | 33 | GPIOA->MODER &= ~GPIO_MODER_MODER15; // reset port A15 |
pmic | 37:698d6b73b50c | 34 | GPIOA->MODER |= GPIO_MODER_MODER15_1; // set alternate mode of port A15 |
pmic | 37:698d6b73b50c | 35 | GPIOA->PUPDR &= ~GPIO_PUPDR_PUPDR15; // reset pull-up/pull-down on port A15 |
pmic | 37:698d6b73b50c | 36 | GPIOA->PUPDR |= GPIO_PUPDR_PUPDR15_1; // set input as pull-down |
pmic | 37:698d6b73b50c | 37 | GPIOA->AFR[1] &= ~0xF0000000; // reset alternate function of port A15 |
pmic | 37:698d6b73b50c | 38 | GPIOA->AFR[1] |= 1 << 4*7; // set alternate funtion 1 of port A15 |
pmic | 37:698d6b73b50c | 39 | |
pmic | 37:698d6b73b50c | 40 | GPIOB->MODER &= ~GPIO_MODER_MODER3; // reset port B3 |
pmic | 37:698d6b73b50c | 41 | GPIOB->MODER |= GPIO_MODER_MODER3_1; // set alternate mode of port B3 |
pmic | 37:698d6b73b50c | 42 | GPIOB->PUPDR &= ~GPIO_PUPDR_PUPDR3; // reset pull-up/pull-down on port B3 |
pmic | 37:698d6b73b50c | 43 | GPIOB->PUPDR |= GPIO_PUPDR_PUPDR3_1; // set input as pull-down |
pmic | 37:698d6b73b50c | 44 | GPIOB->AFR[0] &= ~(0xF << 4*3); // reset alternate function of port B3 |
pmic | 37:698d6b73b50c | 45 | GPIOB->AFR[0] |= 1 << 4*3; // set alternate funtion 1 of port B3 |
pmic | 37:698d6b73b50c | 46 | |
pmic | 37:698d6b73b50c | 47 | // configure reset and clock control registers |
pmic | 37:698d6b73b50c | 48 | |
pmic | 37:698d6b73b50c | 49 | RCC->APB1RSTR |= RCC_APB1RSTR_TIM2RST; //reset TIM2 controller |
pmic | 37:698d6b73b50c | 50 | RCC->APB1RSTR &= ~RCC_APB1RSTR_TIM2RST; |
pmic | 37:698d6b73b50c | 51 | |
pmic | 37:698d6b73b50c | 52 | RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // TIM2 clock enable |
pmic | 37:698d6b73b50c | 53 | |
pmic | 37:698d6b73b50c | 54 | } else if ((a == PB_4) && (b == PC_7)) { |
pmic | 37:698d6b73b50c | 55 | |
pmic | 37:698d6b73b50c | 56 | // pinmap OK for TIM3 CH1 and CH2 |
pmic | 37:698d6b73b50c | 57 | |
pmic | 37:698d6b73b50c | 58 | TIM = TIM3; |
pmic | 37:698d6b73b50c | 59 | |
pmic | 37:698d6b73b50c | 60 | // configure reset and clock control registers |
pmic | 37:698d6b73b50c | 61 | |
pmic | 37:698d6b73b50c | 62 | RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN; // manually enable port B |
pmic | 37:698d6b73b50c | 63 | RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN; // manually enable port C |
pmic | 37:698d6b73b50c | 64 | |
pmic | 37:698d6b73b50c | 65 | // configure general purpose I/O registers |
pmic | 37:698d6b73b50c | 66 | |
pmic | 37:698d6b73b50c | 67 | GPIOB->MODER &= ~GPIO_MODER_MODER4; // reset port B4 |
pmic | 37:698d6b73b50c | 68 | GPIOB->MODER |= GPIO_MODER_MODER4_1; // set alternate mode of port B4 |
pmic | 37:698d6b73b50c | 69 | GPIOB->PUPDR &= ~GPIO_PUPDR_PUPDR4; // reset pull-up/pull-down on port B4 |
pmic | 37:698d6b73b50c | 70 | GPIOB->PUPDR |= GPIO_PUPDR_PUPDR4_1; // set input as pull-down |
pmic | 37:698d6b73b50c | 71 | GPIOB->AFR[0] &= ~(0xF << 4*4); // reset alternate function of port B4 |
pmic | 37:698d6b73b50c | 72 | GPIOB->AFR[0] |= 2 << 4*4; // set alternate funtion 2 of port B4 |
pmic | 37:698d6b73b50c | 73 | |
pmic | 37:698d6b73b50c | 74 | GPIOC->MODER &= ~GPIO_MODER_MODER7; // reset port C7 |
pmic | 37:698d6b73b50c | 75 | GPIOC->MODER |= GPIO_MODER_MODER7_1; // set alternate mode of port C7 |
pmic | 37:698d6b73b50c | 76 | GPIOC->PUPDR &= ~GPIO_PUPDR_PUPDR7; // reset pull-up/pull-down on port C7 |
pmic | 37:698d6b73b50c | 77 | GPIOC->PUPDR |= GPIO_PUPDR_PUPDR7_1; // set input as pull-down |
pmic | 37:698d6b73b50c | 78 | GPIOC->AFR[0] &= ~0xF0000000; // reset alternate function of port C7 |
pmic | 37:698d6b73b50c | 79 | GPIOC->AFR[0] |= 2 << 4*7; // set alternate funtion 2 of port C7 |
pmic | 37:698d6b73b50c | 80 | |
pmic | 37:698d6b73b50c | 81 | // configure reset and clock control registers |
pmic | 37:698d6b73b50c | 82 | |
pmic | 37:698d6b73b50c | 83 | RCC->APB1RSTR |= RCC_APB1RSTR_TIM3RST; //reset TIM3 controller |
pmic | 37:698d6b73b50c | 84 | RCC->APB1RSTR &= ~RCC_APB1RSTR_TIM3RST; |
pmic | 37:698d6b73b50c | 85 | |
pmic | 37:698d6b73b50c | 86 | RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; // TIM3 clock enable |
pmic | 37:698d6b73b50c | 87 | |
pmic | 37:698d6b73b50c | 88 | } else if ((a == PD_12) && (b == PD_13)) { |
pmic | 37:698d6b73b50c | 89 | |
pmic | 37:698d6b73b50c | 90 | // pinmap OK for TIM4 CH1 and CH2 |
pmic | 37:698d6b73b50c | 91 | |
pmic | 37:698d6b73b50c | 92 | TIM = TIM4; |
pmic | 37:698d6b73b50c | 93 | |
pmic | 37:698d6b73b50c | 94 | // configure reset and clock control registers |
pmic | 37:698d6b73b50c | 95 | |
pmic | 37:698d6b73b50c | 96 | RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN; // manually enable port D |
pmic | 37:698d6b73b50c | 97 | |
pmic | 37:698d6b73b50c | 98 | // configure general purpose I/O registers |
pmic | 37:698d6b73b50c | 99 | |
pmic | 37:698d6b73b50c | 100 | GPIOD->MODER &= ~GPIO_MODER_MODER12; // reset port D12 |
pmic | 37:698d6b73b50c | 101 | GPIOD->MODER |= GPIO_MODER_MODER12_1; // set alternate mode of port D12 |
pmic | 37:698d6b73b50c | 102 | GPIOD->PUPDR &= ~GPIO_PUPDR_PUPDR12; // reset pull-up/pull-down on port D12 |
pmic | 37:698d6b73b50c | 103 | GPIOD->PUPDR |= GPIO_PUPDR_PUPDR12_1; // set input as pull-down |
pmic | 37:698d6b73b50c | 104 | GPIOD->AFR[1] &= ~(0xF << 4*4); // reset alternate function of port D12 |
pmic | 37:698d6b73b50c | 105 | GPIOD->AFR[1] |= 2 << 4*4; // set alternate funtion 2 of port D12 |
pmic | 37:698d6b73b50c | 106 | |
pmic | 37:698d6b73b50c | 107 | GPIOD->MODER &= ~GPIO_MODER_MODER13; // reset port D13 |
pmic | 37:698d6b73b50c | 108 | GPIOD->MODER |= GPIO_MODER_MODER13_1; // set alternate mode of port D13 |
pmic | 37:698d6b73b50c | 109 | GPIOD->PUPDR &= ~GPIO_PUPDR_PUPDR13; // reset pull-up/pull-down on port D13 |
pmic | 37:698d6b73b50c | 110 | GPIOD->PUPDR |= GPIO_PUPDR_PUPDR13_1; // set input as pull-down |
pmic | 37:698d6b73b50c | 111 | GPIOD->AFR[1] &= ~(0xF << 4*5); // reset alternate function of port D13 |
pmic | 37:698d6b73b50c | 112 | GPIOD->AFR[1] |= 2 << 4*5; // set alternate funtion 2 of port D13 |
pmic | 37:698d6b73b50c | 113 | |
pmic | 37:698d6b73b50c | 114 | // configure reset and clock control registers |
pmic | 37:698d6b73b50c | 115 | |
pmic | 37:698d6b73b50c | 116 | RCC->APB1RSTR |= RCC_APB1RSTR_TIM4RST; //reset TIM4 controller |
pmic | 37:698d6b73b50c | 117 | RCC->APB1RSTR &= ~RCC_APB1RSTR_TIM4RST; |
pmic | 37:698d6b73b50c | 118 | |
pmic | 37:698d6b73b50c | 119 | RCC->APB1ENR |= RCC_APB1ENR_TIM4EN; // TIM4 clock enable |
pmic | 37:698d6b73b50c | 120 | |
pmic | 37:698d6b73b50c | 121 | } else { |
pmic | 37:698d6b73b50c | 122 | |
pmic | 37:698d6b73b50c | 123 | printf("pinmap not found for peripheral\n"); |
pmic | 37:698d6b73b50c | 124 | |
pmic | 37:698d6b73b50c | 125 | TIM = NULL; |
pmic | 37:698d6b73b50c | 126 | } |
pmic | 37:698d6b73b50c | 127 | |
pmic | 37:698d6b73b50c | 128 | // disable deep sleep for timer clocks |
pmic | 37:698d6b73b50c | 129 | |
pmic | 37:698d6b73b50c | 130 | sleep_manager_lock_deep_sleep(); |
pmic | 37:698d6b73b50c | 131 | |
pmic | 37:698d6b73b50c | 132 | // configure general purpose timer 2, 3 or 4 |
pmic | 37:698d6b73b50c | 133 | |
pmic | 37:698d6b73b50c | 134 | if (TIM != NULL) { |
pmic | 37:698d6b73b50c | 135 | |
pmic | 37:698d6b73b50c | 136 | TIM->CR1 = 0x0000; // counter disable |
pmic | 37:698d6b73b50c | 137 | TIM->CR2 = 0x0000; // reset master mode selection |
pmic | 37:698d6b73b50c | 138 | TIM->SMCR = TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0; // counting on both TI1 & TI2 edges |
pmic | 37:698d6b73b50c | 139 | TIM->CCMR1 = TIM_CCMR1_CC2S_0 | TIM_CCMR1_CC1S_0; |
pmic | 37:698d6b73b50c | 140 | TIM->CCMR2 = 0x0000; // reset capture mode register 2 |
pmic | 37:698d6b73b50c | 141 | TIM->CCER = TIM_CCER_CC2E | TIM_CCER_CC1E; |
pmic | 37:698d6b73b50c | 142 | TIM->CNT = 0x0000; // reset counter value |
pmic | 37:698d6b73b50c | 143 | TIM->ARR = 0xFFFF; // auto reload register |
pmic | 37:698d6b73b50c | 144 | TIM->CR1 = TIM_CR1_CEN; // counter enable |
pmic | 37:698d6b73b50c | 145 | } |
pmic | 37:698d6b73b50c | 146 | } |
pmic | 37:698d6b73b50c | 147 | |
pmic | 37:698d6b73b50c | 148 | /** |
pmic | 37:698d6b73b50c | 149 | * Deletes this EncoderCounterROME2 object. |
pmic | 37:698d6b73b50c | 150 | */ |
pmic | 37:698d6b73b50c | 151 | EncoderCounterROME2::~EncoderCounterROME2() {} |
pmic | 37:698d6b73b50c | 152 | |
pmic | 37:698d6b73b50c | 153 | /** |
pmic | 37:698d6b73b50c | 154 | * Resets the counter value to zero. |
pmic | 37:698d6b73b50c | 155 | */ |
pmic | 37:698d6b73b50c | 156 | void EncoderCounterROME2::reset() { |
pmic | 37:698d6b73b50c | 157 | |
pmic | 37:698d6b73b50c | 158 | TIM->CNT = 0x0000; |
pmic | 37:698d6b73b50c | 159 | } |
pmic | 37:698d6b73b50c | 160 | |
pmic | 37:698d6b73b50c | 161 | /** |
pmic | 37:698d6b73b50c | 162 | * Resets the counter value to a given offset value. |
pmic | 37:698d6b73b50c | 163 | * @param offset the offset value to reset the counter to. |
pmic | 37:698d6b73b50c | 164 | */ |
pmic | 37:698d6b73b50c | 165 | void EncoderCounterROME2::reset(short offset) { |
pmic | 37:698d6b73b50c | 166 | |
pmic | 37:698d6b73b50c | 167 | TIM->CNT = -offset; |
pmic | 37:698d6b73b50c | 168 | } |
pmic | 37:698d6b73b50c | 169 | |
pmic | 37:698d6b73b50c | 170 | /** |
pmic | 37:698d6b73b50c | 171 | * Reads the quadrature encoder counter value. |
pmic | 37:698d6b73b50c | 172 | * @return the quadrature encoder counter as a signed 16-bit integer value. |
pmic | 37:698d6b73b50c | 173 | */ |
pmic | 37:698d6b73b50c | 174 | short EncoderCounterROME2::read() { |
pmic | 37:698d6b73b50c | 175 | |
pmic | 37:698d6b73b50c | 176 | return (short)(-TIM->CNT); |
pmic | 37:698d6b73b50c | 177 | } |
pmic | 37:698d6b73b50c | 178 | |
pmic | 37:698d6b73b50c | 179 | /** |
pmic | 37:698d6b73b50c | 180 | * The empty operator is a shorthand notation of the <code>read()</code> method. |
pmic | 37:698d6b73b50c | 181 | */ |
pmic | 37:698d6b73b50c | 182 | EncoderCounterROME2::operator short() { |
pmic | 37:698d6b73b50c | 183 | |
pmic | 37:698d6b73b50c | 184 | return read(); |
pmic | 37:698d6b73b50c | 185 | } |