Statistics
| Branch: | Tag: | Revision:

amiro-os / hal / platforms / STM32 / qei_lld.c @ ab2f0120

History | View | Annotate | Download (6.733 KB)

1 3f899f5d Thomas Schöpping
/**
2
 * @file    STM32/qei_lld.c
3
 * @brief   STM32 QEI subsystem low level driver.
4
 *
5
 * @addtogroup QEI
6
 * @{
7
 */
8
9 58fe0e0b Thomas Schöpping
#include "ch.h"
10
#include "hal.h"
11
12
#include "qei.h"
13
14
#if HAL_USE_QEI || defined(__DOXYGEN__)
15
16
/*===========================================================================*/
17
/* Driver exported variables.                                                */
18
/*===========================================================================*/
19
20
/**
21
 * @brief   QEID1 driver identifier.
22
 * @note    The driver QEID1 allocates the complex timer TIM1 when enabled.
23
 */
24
#if STM32_QEI_USE_TIM1 || defined(__DOXYGEN__)
25
QEIDriver QEID1;
26
#endif
27
28
/**
29
 * @brief   QEID2 driver identifier.
30
 * @note    The driver QEID1 allocates the timer TIM2 when enabled.
31
 */
32
#if STM32_QEI_USE_TIM2 || defined(__DOXYGEN__)
33
QEIDriver QEID2;
34
#endif
35
36
/**
37
 * @brief   QEID3 driver identifier.
38
 * @note    The driver QEID1 allocates the timer TIM3 when enabled.
39
 */
40
#if STM32_QEI_USE_TIM3 || defined(__DOXYGEN__)
41
QEIDriver QEID3;
42
#endif
43
44
/**
45
 * @brief   QEID4 driver identifier.
46
 * @note    The driver QEID4 allocates the timer TIM4 when enabled.
47
 */
48
#if STM32_QEI_USE_TIM4 || defined(__DOXYGEN__)
49
QEIDriver QEID4;
50
#endif
51
52
/**
53
 * @brief   QEID5 driver identifier.
54
 * @note    The driver QEID5 allocates the timer TIM5 when enabled.
55
 */
56
#if STM32_QEI_USE_TIM5 || defined(__DOXYGEN__)
57
QEIDriver QEID5;
58
#endif
59
60
/**
61
 * @brief   QEID8 driver identifier.
62
 * @note    The driver QEID8 allocates the timer TIM8 when enabled.
63
 */
64
#if STM32_QEI_USE_TIM8 || defined(__DOXYGEN__)
65
QEIDriver QEID8;
66
#endif
67
68
/*===========================================================================*/
69
/* Driver local variables.                                                   */
70
/*===========================================================================*/
71
72
/*===========================================================================*/
73
/* Driver local functions.                                                   */
74
/*===========================================================================*/
75
76
/*===========================================================================*/
77
/* Driver interrupt handlers.                                                */
78
/*===========================================================================*/
79
80
/*===========================================================================*/
81
/* Driver exported functions.                                                */
82
/*===========================================================================*/
83
84
/**
85
 * @brief   Low level QEI driver initialization.
86
 *
87
 * @notapi
88
 */
89
void qei_lld_init(void) {
90
91
#if STM32_QEI_USE_TIM1
92
  /* Driver initialization.*/
93
  qeiObjectInit(&QEID1);
94
  QEID1.tim = STM32_TIM1;
95
#endif
96
97
#if STM32_QEI_USE_TIM2
98
  /* Driver initialization.*/
99
  qeiObjectInit(&QEID2);
100
  QEID2.tim = STM32_TIM2;
101
#endif
102
103
#if STM32_QEI_USE_TIM3
104
  /* Driver initialization.*/
105
  qeiObjectInit(&QEID3);
106
  QEID3.tim = STM32_TIM3;
107
#endif
108
109
#if STM32_QEI_USE_TIM4
110
  /* Driver initialization.*/
111
  qeiObjectInit(&QEID4);
112
  QEID4.tim = STM32_TIM4;
113
#endif
114
115
#if STM32_QEI_USE_TIM5
116
  /* Driver initialization.*/
117
  qeiObjectInit(&QEID5);
118
  QEID5.tim = STM32_TIM5;
119
#endif
120
121
#if STM32_QEI_USE_TIM8
122
  /* Driver initialization.*/
123
  qeiObjectInit(&QEID8);
124
  QEID8.tim = STM32_TIM8;
125
#endif
126
}
127
128
/**
129
 * @brief   Configures and activates the QEI peripheral.
130
 *
131
 * @param[in] qeip      pointer to the @p QEIDriver object
132
 *
133
 * @notapi
134
 */
135
void qei_lld_start(QEIDriver *qeip) {
136
  uint32_t arr, ccer;
137
138
  if (qeip->state == QEI_STOP) {
139
    /* Clock activation and timer reset.*/
140
#if STM32_QEI_USE_TIM1
141
    if (&QEID1 == qeip) {
142
      rccEnableTIM1(FALSE);
143
      rccResetTIM1();
144
    }
145
#endif
146
#if STM32_QEI_USE_TIM2
147
    if (&QEID2 == qeip) {
148
      rccEnableTIM2(FALSE);
149
      rccResetTIM2();
150
    }
151
#endif
152
#if STM32_QEI_USE_TIM3
153
    if (&QEID3 == qeip) {
154
      rccEnableTIM3(FALSE);
155
      rccResetTIM3();
156
    }
157
#endif
158
#if STM32_QEI_USE_TIM4
159
    if (&QEID4 == qeip) {
160
      rccEnableTIM4(FALSE);
161
      rccResetTIM4();
162
    }
163
#endif
164
165
#if STM32_QEI_USE_TIM5
166
    if (&QEID5 == qeip) {
167
      rccEnableTIM5(FALSE);
168
      rccResetTIM5();
169
    }
170
#endif
171
#if STM32_QEI_USE_TIM8
172
    if (&QEID8 == qeip) {
173
      rccEnableTIM8(FALSE);
174
      rccResetTIM8();
175
    }
176
#endif
177
  }
178
  else {
179
    /* Driver re-configuration scenario, it must be stopped first.*/
180
    qeip->tim->CR1    = 0;                  /* Timer disabled.              */
181
    qeip->tim->DIER   = 0;                  /* All IRQs disabled.           */
182
    qeip->tim->SR     = 0;                  /* Clear eventual pending IRQs. */
183
    qeip->tim->CCR[0] = 0;                  /* Comparator 1 disabled.       */
184
    qeip->tim->CCR[1] = 0;                  /* Comparator 2 disabled.       */
185
    qeip->tim->CNT    = 0;                  /* Counter reset to zero.       */
186
  }
187
188
  /* Timer configuration.*/
189
  qeip->tim->PSC  = 0;
190
  arr = qeip->config->range - 1;
191
  chDbgAssert((arr <= 0xFFFF), "qei_lld_start(), #1", "invalid range");
192
  qeip->tim->ARR  = arr & 0xFFFF;
193
194
  /* CCMR1_CC1S = 01 - CH1 Input on TI1.
195
     CCMR1_CC2S = 01 - CH2 Input on TI2.*/
196
  qeip->tim->CCMR1 = TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0;
197
198
  ccer = 0;
199
  if (qeip->config->channels[0].mode == QEI_INPUT_INVERTED)
200
    ccer |= TIM_CCER_CC1P;
201
  if (qeip->config->channels[1].mode == QEI_INPUT_INVERTED)
202
    ccer |= TIM_CCER_CC2P;
203
  qeip->tim->CCER = ccer;
204
205
  if (qeip->config->mode == QEI_COUNT_CH1)
206
    qeip->tim->SMCR  = TIM_SMCR_SMS_1;
207
  else if (qeip->config->mode == QEI_COUNT_CH2)
208
    qeip->tim->SMCR  = TIM_SMCR_SMS_0;
209
  else
210
    qeip->tim->SMCR  = TIM_SMCR_SMS_0 | TIM_SMCR_SMS_1;
211
}
212
213
/**
214
 * @brief   Deactivates the QEI peripheral.
215
 *
216
 * @param[in] qeip      pointer to the @p QEIDriver object
217
 *
218
 * @notapi
219
 */
220
void qei_lld_stop(QEIDriver *qeip) {
221
222
  if (qeip->state == QEI_READY) {
223
    /* Clock deactivation.*/
224
    qeip->tim->CR1  = 0;                    /* Timer disabled.              */
225
226
#if STM32_QEI_USE_TIM1
227
    if (&QEID1 == qeip) {
228
      rccDisableTIM1(FALSE);
229
    }
230
#endif
231
#if STM32_QEI_USE_TIM2
232
    if (&QEID2 == qeip) {
233
      rccDisableTIM2(FALSE);
234
    }
235
#endif
236
#if STM32_QEI_USE_TIM3
237
    if (&QEID3 == qeip) {
238
      rccDisableTIM3(FALSE);
239
    }
240
#endif
241
#if STM32_QEI_USE_TIM4
242
    if (&QEID4 == qeip) {
243
      rccDisableTIM4(FALSE);
244
    }
245
#endif
246
#if STM32_QEI_USE_TIM5
247
    if (&QEID5 == qeip) {
248
      rccDisableTIM5(FALSE);
249
    }
250
#endif
251
  }
252
#if STM32_QEI_USE_TIM8
253
    if (&QEID8 == qeip) {
254
      rccDisableTIM8(FALSE);
255
    }
256
#endif
257
}
258
259
/**
260
 * @brief   Enables the quadrature encoder.
261
 *
262
 * @param[in] qeip      pointer to the @p QEIDriver object
263
 *
264
 * @notapi
265
 */
266
void qei_lld_enable(QEIDriver *qeip) {
267
268
  qeip->tim->CR1  = TIM_CR1_CEN;
269
}
270
271
/**
272
 * @brief   Disables the quadrature encoder.
273
 *
274
 * @param[in] qeip      pointer to the @p QEIDriver object
275
 *
276
 * @notapi
277
 */
278
void qei_lld_disable(QEIDriver *qeip) {
279
280
  qeip->tim->CR1  = 0;
281
}
282
283
#endif /* HAL_USE_QEI */
284 3f899f5d Thomas Schöpping
285
/** @} */