Nicolas Borla / Mbed OS ROME2_Robot_Firmware
Committer:
boro
Date:
Mon Mar 16 13:12:31 2020 +0000
Revision:
0:4beb2ea291ec
a

Who changed what in which revision?

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