ROME2 Lab3

Committer:
oehlemar
Date:
Wed Mar 25 14:15:52 2020 +0000
Revision:
2:fc9e2aebf9d5
Parent:
0:6a4d3264c067
final

Who changed what in which revision?

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