Statistics
| Branch: | Tag: | Revision:

amiro-os / os / hal / ports / STM32 / LLD / QEIv1 / hal_qei_lld.c @ 0128be0f

History | View | Annotate | Download (7.416 KB)

1
/*
2
AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
3
Copyright (C) 2016..2018  Thomas Schöpping et al.
4

5
This program is free software: you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation, either version 3 of the License, or
8
(at your option) any later version.
9

10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
GNU General Public License for more details.
14

15
You should have received a copy of the GNU General Public License
16
along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
*/
18

    
19
/**
20
 * @file    STM32/hal_qei_lld.c
21
 * @brief   STM32 QEI subsystem low level driver.
22
 *
23
 * @addtogroup QEI
24
 * @{
25
 */
26

    
27
#include "hal.h"
28

    
29
#include "hal_qei.h"
30

    
31
#if HAL_USE_QEI || defined(__DOXYGEN__)
32

    
33
/*===========================================================================*/
34
/* Driver exported variables.                                                */
35
/*===========================================================================*/
36

    
37
/**
38
 * @brief   QEID1 driver identifier.
39
 * @note    The driver QEID1 allocates the complex timer TIM1 when enabled.
40
 */
41
#if STM32_QEI_USE_TIM1 || defined(__DOXYGEN__)
42
QEIDriver QEID1;
43
#endif
44

    
45
/**
46
 * @brief   QEID2 driver identifier.
47
 * @note    The driver QEID1 allocates the timer TIM2 when enabled.
48
 */
49
#if STM32_QEI_USE_TIM2 || defined(__DOXYGEN__)
50
QEIDriver QEID2;
51
#endif
52

    
53
/**
54
 * @brief   QEID3 driver identifier.
55
 * @note    The driver QEID1 allocates the timer TIM3 when enabled.
56
 */
57
#if STM32_QEI_USE_TIM3 || defined(__DOXYGEN__)
58
QEIDriver QEID3;
59
#endif
60

    
61
/**
62
 * @brief   QEID4 driver identifier.
63
 * @note    The driver QEID4 allocates the timer TIM4 when enabled.
64
 */
65
#if STM32_QEI_USE_TIM4 || defined(__DOXYGEN__)
66
QEIDriver QEID4;
67
#endif
68

    
69
/**
70
 * @brief   QEID5 driver identifier.
71
 * @note    The driver QEID5 allocates the timer TIM5 when enabled.
72
 */
73
#if STM32_QEI_USE_TIM5 || defined(__DOXYGEN__)
74
QEIDriver QEID5;
75
#endif
76

    
77
/**
78
 * @brief   QEID8 driver identifier.
79
 * @note    The driver QEID8 allocates the timer TIM8 when enabled.
80
 */
81
#if STM32_QEI_USE_TIM8 || defined(__DOXYGEN__)
82
QEIDriver QEID8;
83
#endif
84

    
85
/*===========================================================================*/
86
/* Driver local variables.                                                   */
87
/*===========================================================================*/
88

    
89
/*===========================================================================*/
90
/* Driver local functions.                                                   */
91
/*===========================================================================*/
92

    
93
/*===========================================================================*/
94
/* Driver interrupt handlers.                                                */
95
/*===========================================================================*/
96

    
97
/*===========================================================================*/
98
/* Driver exported functions.                                                */
99
/*===========================================================================*/
100

    
101
/**
102
 * @brief   Low level QEI driver initialization.
103
 *
104
 * @notapi
105
 */
106
void qei_lld_init(void) {
107

    
108
#if STM32_QEI_USE_TIM1
109
  /* Driver initialization.*/
110
  qeiObjectInit(&QEID1);
111
  QEID1.tim = STM32_TIM1;
112
#endif
113

    
114
#if STM32_QEI_USE_TIM2
115
  /* Driver initialization.*/
116
  qeiObjectInit(&QEID2);
117
  QEID2.tim = STM32_TIM2;
118
#endif
119

    
120
#if STM32_QEI_USE_TIM3
121
  /* Driver initialization.*/
122
  qeiObjectInit(&QEID3);
123
  QEID3.tim = STM32_TIM3;
124
#endif
125

    
126
#if STM32_QEI_USE_TIM4
127
  /* Driver initialization.*/
128
  qeiObjectInit(&QEID4);
129
  QEID4.tim = STM32_TIM4;
130
#endif
131

    
132
#if STM32_QEI_USE_TIM5
133
  /* Driver initialization.*/
134
  qeiObjectInit(&QEID5);
135
  QEID5.tim = STM32_TIM5;
136
#endif
137

    
138
#if STM32_QEI_USE_TIM8
139
  /* Driver initialization.*/
140
  qeiObjectInit(&QEID8);
141
  QEID8.tim = STM32_TIM8;
142
#endif
143
}
144

    
145
/**
146
 * @brief   Configures and activates the QEI peripheral.
147
 *
148
 * @param[in] qeip      pointer to the @p QEIDriver object
149
 *
150
 * @notapi
151
 */
152
void qei_lld_start(QEIDriver *qeip) {
153
  uint32_t arr, ccer;
154

    
155
  if (qeip->state == QEI_STOP) {
156
    /* Clock activation and timer reset.*/
157
#if STM32_QEI_USE_TIM1
158
    if (&QEID1 == qeip) {
159
      rccEnableTIM1();
160
      rccResetTIM1();
161
    }
162
#endif
163
#if STM32_QEI_USE_TIM2
164
    if (&QEID2 == qeip) {
165
      rccEnableTIM2();
166
      rccResetTIM2();
167
    }
168
#endif
169
#if STM32_QEI_USE_TIM3
170
    if (&QEID3 == qeip) {
171
      rccEnableTIM3();
172
      rccResetTIM3();
173
    }
174
#endif
175
#if STM32_QEI_USE_TIM4
176
    if (&QEID4 == qeip) {
177
      rccEnableTIM4();
178
      rccResetTIM4();
179
    }
180
#endif
181

    
182
#if STM32_QEI_USE_TIM5
183
    if (&QEID5 == qeip) {
184
      rccEnableTIM5();
185
      rccResetTIM5();
186
    }
187
#endif
188
#if STM32_QEI_USE_TIM8
189
    if (&QEID8 == qeip) {
190
      rccEnableTIM8();
191
      rccResetTIM8();
192
    }
193
#endif
194
  }
195
  else {
196
    /* Driver re-configuration scenario, it must be stopped first.*/
197
    qeip->tim->CR1    = 0;                  /* Timer disabled.              */
198
    qeip->tim->DIER   = 0;                  /* All IRQs disabled.           */
199
    qeip->tim->SR     = 0;                  /* Clear eventual pending IRQs. */
200
    qeip->tim->CCR[0] = 0;                  /* Comparator 1 disabled.       */
201
    qeip->tim->CCR[1] = 0;                  /* Comparator 2 disabled.       */
202
    qeip->tim->CNT    = 0;                  /* Counter reset to zero.       */
203
  }
204

    
205
  /* Timer configuration.*/
206
  qeip->tim->PSC  = 0;
207
  arr = qeip->config->range - 1;
208
  osalDbgAssert((arr <= 0xFFFF), "qei_lld_start(), #1" /*, "invalid range"*/);
209
  qeip->tim->ARR  = arr & 0xFFFF;
210

    
211
  /* CCMR1_CC1S = 01 - CH1 Input on TI1.
212
     CCMR1_CC2S = 01 - CH2 Input on TI2.*/
213
  qeip->tim->CCMR1 = TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0;
214

    
215
  ccer = 0;
216
  if (qeip->config->channels[0].mode == QEI_INPUT_INVERTED)
217
    ccer |= TIM_CCER_CC1P;
218
  if (qeip->config->channels[1].mode == QEI_INPUT_INVERTED)
219
    ccer |= TIM_CCER_CC2P;
220
  qeip->tim->CCER = ccer;
221

    
222
  if (qeip->config->mode == QEI_COUNT_CH1)
223
    qeip->tim->SMCR  = TIM_SMCR_SMS_1;
224
  else if (qeip->config->mode == QEI_COUNT_CH2)
225
    qeip->tim->SMCR  = TIM_SMCR_SMS_0;
226
  else
227
    qeip->tim->SMCR  = TIM_SMCR_SMS_0 | TIM_SMCR_SMS_1;
228
}
229

    
230
/**
231
 * @brief   Deactivates the QEI peripheral.
232
 *
233
 * @param[in] qeip      pointer to the @p QEIDriver object
234
 *
235
 * @notapi
236
 */
237
void qei_lld_stop(QEIDriver *qeip) {
238

    
239
  if (qeip->state == QEI_READY) {
240
    /* Clock deactivation.*/
241
    qeip->tim->CR1  = 0;                    /* Timer disabled.              */
242

    
243
#if STM32_QEI_USE_TIM1
244
    if (&QEID1 == qeip) {
245
      rccDisableTIM1();
246
    }
247
#endif
248
#if STM32_QEI_USE_TIM2
249
    if (&QEID2 == qeip) {
250
      rccDisableTIM2();
251
    }
252
#endif
253
#if STM32_QEI_USE_TIM3
254
    if (&QEID3 == qeip) {
255
      rccDisableTIM3();
256
    }
257
#endif
258
#if STM32_QEI_USE_TIM4
259
    if (&QEID4 == qeip) {
260
      rccDisableTIM4();
261
    }
262
#endif
263
#if STM32_QEI_USE_TIM5
264
    if (&QEID5 == qeip) {
265
      rccDisableTIM5();
266
    }
267
#endif
268
  }
269
#if STM32_QEI_USE_TIM8
270
    if (&QEID8 == qeip) {
271
      rccDisableTIM8();
272
    }
273
#endif
274
}
275

    
276
/**
277
 * @brief   Enables the quadrature encoder.
278
 *
279
 * @param[in] qeip      pointer to the @p QEIDriver object
280
 *
281
 * @notapi
282
 */
283
void qei_lld_enable(QEIDriver *qeip) {
284

    
285
  qeip->tim->CR1  = TIM_CR1_CEN;
286
}
287

    
288
/**
289
 * @brief   Disables the quadrature encoder.
290
 *
291
 * @param[in] qeip      pointer to the @p QEIDriver object
292
 *
293
 * @notapi
294
 */
295
void qei_lld_disable(QEIDriver *qeip) {
296

    
297
  qeip->tim->CR1  = 0;
298
}
299

    
300
#endif /* HAL_USE_QEI */
301

    
302
/** @} */