Marco Oehler / Mbed 2 deprecated Lab2

Dependencies:   mbed

Committer:
oehlemar
Date:
Mon Mar 09 16:23:04 2020 +0000
Revision:
0:1a972ed770da
LAB2

Who changed what in which revision?

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