Revision 20a4e01c

View differences:

kernel/patches/QEI-driver.patch
1
commit a23878ddb85bb8fd069f02042f15ad4be2a0d709
2
Author: Marc Rothmann <mrothmann@techfak.uni-bielefeld.de>
3
Date:   Mon Sep 17 11:40:39 2018 +0200
4

  
5
    Added QEI driver to HAL.
6

  
7
diff --git a/os/hal/hal.mk b/os/hal/hal.mk
8
index f177a3f..64d96d9 100644
9
--- a/os/hal/hal.mk
10
+++ b/os/hal/hal.mk
11
@@ -41,6 +41,9 @@ endif
12
 ifneq ($(findstring HAL_USE_ICU TRUE,$(HALCONF)),)
13
 HALSRC += $(CHIBIOS)/os/hal/src/hal_icu.c
14
 endif
15
+ifneq ($(findstring HAL_USE_QEI TRUE,$(HALCONF)),)
16
+HALSRC += $(CHIBIOS)/os/hal/src/hal_qei.c
17
+endif
18
 ifneq ($(findstring HAL_USE_MAC TRUE,$(HALCONF)),)
19
 HALSRC += $(CHIBIOS)/os/hal/src/hal_mac.c
20
 endif
21
@@ -94,6 +97,7 @@ HALSRC = $(CHIBIOS)/os/hal/src/hal.c \
22
          $(CHIBIOS)/os/hal/src/hal_i2c.c \
23
          $(CHIBIOS)/os/hal/src/hal_i2s.c \
24
          $(CHIBIOS)/os/hal/src/hal_icu.c \
25
+         $(CHIBIOS)/os/hal/src/hal_qei.c \
26
          $(CHIBIOS)/os/hal/src/hal_mac.c \
27
          $(CHIBIOS)/os/hal/src/hal_mmc_spi.c \
28
          $(CHIBIOS)/os/hal/src/hal_pal.c \
29
diff --git a/os/hal/include/hal_qei.h b/os/hal/include/hal_qei.h
30
new file mode 100644
31
index 0000000..aef5e62
32
--- /dev/null
33
+++ b/os/hal/include/hal_qei.h
34
@@ -0,0 +1,148 @@
35
+/*
36
+AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
37
+Copyright (C) 2016..2018  Thomas Schöpping et al.
38
+
39
+This program is free software: you can redistribute it and/or modify
40
+it under the terms of the GNU General Public License as published by
41
+the Free Software Foundation, either version 3 of the License, or
42
+(at your option) any later version.
43
+
44
+This program is distributed in the hope that it will be useful,
45
+but WITHOUT ANY WARRANTY; without even the implied warranty of
46
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
47
+GNU General Public License for more details.
48
+
49
+You should have received a copy of the GNU General Public License
50
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
51
+*/
52
+
53
+/**
54
+ * @file    hal_qei.h
55
+ * @brief   QEI Driver macros and structures.
56
+ *
57
+ * @addtogroup QEI
58
+ * @{
59
+ */
60
+
61
+#ifndef _HAL_QEI_H_
62
+#define _HAL_QEI_H_
63
+
64
+#if HAL_USE_QEI || defined(__DOXYGEN__)
65
+
66
+/*===========================================================================*/
67
+/* Driver constants.                                                         */
68
+/*===========================================================================*/
69
+
70
+/*===========================================================================*/
71
+/* Driver pre-compile time settings.                                         */
72
+/*===========================================================================*/
73
+
74
+/*===========================================================================*/
75
+/* Derived constants and error checks.                                       */
76
+/*===========================================================================*/
77
+
78
+/*===========================================================================*/
79
+/* Driver data structures and types.                                         */
80
+/*===========================================================================*/
81
+
82
+/**
83
+ * @brief   Driver state machine possible states.
84
+ */
85
+typedef enum {
86
+  QEI_UNINIT = 0,                   /**< Not initialized.                   */
87
+  QEI_STOP = 1,                     /**< Stopped.                           */
88
+  QEI_READY = 2,                    /**< Ready.                             */
89
+  QEI_ACTIVE = 4,                   /**< Active.                            */
90
+} qeistate_t;
91
+
92
+/**
93
+ * @brief   Type of a structure representing an QEI driver.
94
+ */
95
+typedef struct QEIDriver QEIDriver;
96
+
97
+#include "hal_qei_lld.h"
98
+
99
+/*===========================================================================*/
100
+/* Driver macros.                                                            */
101
+/*===========================================================================*/
102
+
103
+/**
104
+ * @name    Macro Functions
105
+ * @{
106
+ */
107
+/**
108
+ * @brief   Enables the quadrature encoder.
109
+ *
110
+ * @param[in] qeip      pointer to the @p QEIDriver object
111
+ *
112
+ * @iclass
113
+ */
114
+#define qeiEnableI(qeip) qei_lld_enable(qeip)
115
+
116
+/**
117
+ * @brief   Disables the quadrature encoder.
118
+ *
119
+ * @param[in] qeip      pointer to the @p QEIDriver object
120
+ *
121
+ * @iclass
122
+ */
123
+#define qeiDisableI(qeip) qei_lld_disable(qeip)
124
+
125
+/**
126
+ * @brief   Returns the direction of the last transition.
127
+ * @details The direction is defined as boolean and is
128
+ *          calculated at each transition on any input.
129
+ *
130
+ * @param[in] qeip      pointer to the @p QEIDriver object
131
+ * @return              The request direction.
132
+ * @retval FALSE        Position counted up.
133
+ * @retval TRUE         Position counted down.
134
+ * @iclass
135
+ */
136
+#define qeiGetDirectionI(qeip) qei_lld_get_direction(qeip)
137
+
138
+/**
139
+ * @brief   Returns the position of the encoder.
140
+ * @details The position is defined as number of pulses since last reset.
141
+ *
142
+ * @param[in] qeip      pointer to the @p QEIDriver object
143
+ * @return              The number of pulses.
144
+ *
145
+ * @iclass
146
+ */
147
+#define qeiGetPositionI(qeip) qei_lld_get_position(qeip)
148
+
149
+/**
150
+ * @brief   Returns the range of the encoder.
151
+ * @details The range is defined as number of maximum pulse count.
152
+ *
153
+ * @param[in] qeip      pointer to the @p QEIDriver object
154
+ * @return              The number of pulses.
155
+ *
156
+ * @iclass
157
+ */
158
+#define qeiGetRangeI(qeip) qei_lld_get_range(qeip)
159
+/** @} */
160
+
161
+/*===========================================================================*/
162
+/* External declarations.                                                    */
163
+/*===========================================================================*/
164
+
165
+#ifdef __cplusplus
166
+extern "C" {
167
+#endif
168
+  void qeiInit(void);
169
+  void qeiObjectInit(QEIDriver *qeip);
170
+  void qeiStart(QEIDriver *qeip, const QEIConfig *config);
171
+  void qeiStop(QEIDriver *qeip);
172
+  void qeiEnable(QEIDriver *qeip);
173
+  void qeiDisable(QEIDriver *qeip);
174
+#ifdef __cplusplus
175
+}
176
+#endif
177
+
178
+#endif /* HAL_USE_QEI */
179
+
180
+#endif /* _HAL_QEI_H_ */
181
+
182
+/** @} */
183
diff --git a/os/hal/ports/STM32/LLD/TIMv1/driver.mk b/os/hal/ports/STM32/LLD/TIMv1/driver.mk
184
index 032d75a..13e3571 100644
185
--- a/os/hal/ports/STM32/LLD/TIMv1/driver.mk
186
+++ b/os/hal/ports/STM32/LLD/TIMv1/driver.mk
187
@@ -10,10 +10,14 @@ endif
188
 ifneq ($(findstring HAL_USE_PWM TRUE,$(HALCONF)),)
189
 PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/hal_pwm_lld.c
190
 endif
191
+ifneq ($(findstring HAL_USE_QEI TRUE,$(HALCONF)),)
192
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/hal_qei_lld.c
193
+endif
194
 else
195
 PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/hal_gpt_lld.c
196
 PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/hal_icu_lld.c
197
 PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/hal_pwm_lld.c
198
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/hal_qei_lld.c
199
 endif
200
 
201
 PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1
202
diff --git a/os/hal/ports/STM32/LLD/TIMv1/hal_qei_lld.c b/os/hal/ports/STM32/LLD/TIMv1/hal_qei_lld.c
203
new file mode 100644
204
index 0000000..700704a
205
--- /dev/null
206
+++ b/os/hal/ports/STM32/LLD/TIMv1/hal_qei_lld.c
207
@@ -0,0 +1,302 @@
208
+/*
209
+AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
210
+Copyright (C) 2016..2018  Thomas Schöpping et al.
211
+
212
+This program is free software: you can redistribute it and/or modify
213
+it under the terms of the GNU General Public License as published by
214
+the Free Software Foundation, either version 3 of the License, or
215
+(at your option) any later version.
216
+
217
+This program is distributed in the hope that it will be useful,
218
+but WITHOUT ANY WARRANTY; without even the implied warranty of
219
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
220
+GNU General Public License for more details.
221
+
222
+You should have received a copy of the GNU General Public License
223
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
224
+*/
225
+
226
+/**
227
+ * @file    STM32/hal_qei_lld.c
228
+ * @brief   STM32 QEI subsystem low level driver.
229
+ *
230
+ * @addtogroup QEI
231
+ * @{
232
+ */
233
+
234
+#include "hal.h"
235
+
236
+#include "hal_qei.h"
237
+
238
+#if HAL_USE_QEI || defined(__DOXYGEN__)
239
+
240
+/*===========================================================================*/
241
+/* Driver exported variables.                                                */
242
+/*===========================================================================*/
243
+
244
+/**
245
+ * @brief   QEID1 driver identifier.
246
+ * @note    The driver QEID1 allocates the complex timer TIM1 when enabled.
247
+ */
248
+#if STM32_QEI_USE_TIM1 || defined(__DOXYGEN__)
249
+QEIDriver QEID1;
250
+#endif
251
+
252
+/**
253
+ * @brief   QEID2 driver identifier.
254
+ * @note    The driver QEID1 allocates the timer TIM2 when enabled.
255
+ */
256
+#if STM32_QEI_USE_TIM2 || defined(__DOXYGEN__)
257
+QEIDriver QEID2;
258
+#endif
259
+
260
+/**
261
+ * @brief   QEID3 driver identifier.
262
+ * @note    The driver QEID1 allocates the timer TIM3 when enabled.
263
+ */
264
+#if STM32_QEI_USE_TIM3 || defined(__DOXYGEN__)
265
+QEIDriver QEID3;
266
+#endif
267
+
268
+/**
269
+ * @brief   QEID4 driver identifier.
270
+ * @note    The driver QEID4 allocates the timer TIM4 when enabled.
271
+ */
272
+#if STM32_QEI_USE_TIM4 || defined(__DOXYGEN__)
273
+QEIDriver QEID4;
274
+#endif
275
+
276
+/**
277
+ * @brief   QEID5 driver identifier.
278
+ * @note    The driver QEID5 allocates the timer TIM5 when enabled.
279
+ */
280
+#if STM32_QEI_USE_TIM5 || defined(__DOXYGEN__)
281
+QEIDriver QEID5;
282
+#endif
283
+
284
+/**
285
+ * @brief   QEID8 driver identifier.
286
+ * @note    The driver QEID8 allocates the timer TIM8 when enabled.
287
+ */
288
+#if STM32_QEI_USE_TIM8 || defined(__DOXYGEN__)
289
+QEIDriver QEID8;
290
+#endif
291
+
292
+/*===========================================================================*/
293
+/* Driver local variables.                                                   */
294
+/*===========================================================================*/
295
+
296
+/*===========================================================================*/
297
+/* Driver local functions.                                                   */
298
+/*===========================================================================*/
299
+
300
+/*===========================================================================*/
301
+/* Driver interrupt handlers.                                                */
302
+/*===========================================================================*/
303
+
304
+/*===========================================================================*/
305
+/* Driver exported functions.                                                */
306
+/*===========================================================================*/
307
+
308
+/**
309
+ * @brief   Low level QEI driver initialization.
310
+ *
311
+ * @notapi
312
+ */
313
+void qei_lld_init(void) {
314
+
315
+#if STM32_QEI_USE_TIM1
316
+  /* Driver initialization.*/
317
+  qeiObjectInit(&QEID1);
318
+  QEID1.tim = STM32_TIM1;
319
+#endif
320
+
321
+#if STM32_QEI_USE_TIM2
322
+  /* Driver initialization.*/
323
+  qeiObjectInit(&QEID2);
324
+  QEID2.tim = STM32_TIM2;
325
+#endif
326
+
327
+#if STM32_QEI_USE_TIM3
328
+  /* Driver initialization.*/
329
+  qeiObjectInit(&QEID3);
330
+  QEID3.tim = STM32_TIM3;
331
+#endif
332
+
333
+#if STM32_QEI_USE_TIM4
334
+  /* Driver initialization.*/
335
+  qeiObjectInit(&QEID4);
336
+  QEID4.tim = STM32_TIM4;
337
+#endif
338
+
339
+#if STM32_QEI_USE_TIM5
340
+  /* Driver initialization.*/
341
+  qeiObjectInit(&QEID5);
342
+  QEID5.tim = STM32_TIM5;
343
+#endif
344
+
345
+#if STM32_QEI_USE_TIM8
346
+  /* Driver initialization.*/
347
+  qeiObjectInit(&QEID8);
348
+  QEID8.tim = STM32_TIM8;
349
+#endif
350
+}
351
+
352
+/**
353
+ * @brief   Configures and activates the QEI peripheral.
354
+ *
355
+ * @param[in] qeip      pointer to the @p QEIDriver object
356
+ *
357
+ * @notapi
358
+ */
359
+void qei_lld_start(QEIDriver *qeip) {
360
+  uint32_t arr, ccer;
361
+
362
+  if (qeip->state == QEI_STOP) {
363
+    /* Clock activation and timer reset.*/
364
+#if STM32_QEI_USE_TIM1
365
+    if (&QEID1 == qeip) {
366
+      rccEnableTIM1();
367
+      rccResetTIM1();
368
+    }
369
+#endif
370
+#if STM32_QEI_USE_TIM2
371
+    if (&QEID2 == qeip) {
372
+      rccEnableTIM2();
373
+      rccResetTIM2();
374
+    }
375
+#endif
376
+#if STM32_QEI_USE_TIM3
377
+    if (&QEID3 == qeip) {
378
+      rccEnableTIM3();
379
+      rccResetTIM3();
380
+    }
381
+#endif
382
+#if STM32_QEI_USE_TIM4
383
+    if (&QEID4 == qeip) {
384
+      rccEnableTIM4();
385
+      rccResetTIM4();
386
+    }
387
+#endif
388
+
389
+#if STM32_QEI_USE_TIM5
390
+    if (&QEID5 == qeip) {
391
+      rccEnableTIM5();
392
+      rccResetTIM5();
393
+    }
394
+#endif
395
+#if STM32_QEI_USE_TIM8
396
+    if (&QEID8 == qeip) {
397
+      rccEnableTIM8();
398
+      rccResetTIM8();
399
+    }
400
+#endif
401
+  }
402
+  else {
403
+    /* Driver re-configuration scenario, it must be stopped first.*/
404
+    qeip->tim->CR1    = 0;                  /* Timer disabled.              */
405
+    qeip->tim->DIER   = 0;                  /* All IRQs disabled.           */
406
+    qeip->tim->SR     = 0;                  /* Clear eventual pending IRQs. */
407
+    qeip->tim->CCR[0] = 0;                  /* Comparator 1 disabled.       */
408
+    qeip->tim->CCR[1] = 0;                  /* Comparator 2 disabled.       */
409
+    qeip->tim->CNT    = 0;                  /* Counter reset to zero.       */
410
+  }
411
+
412
+  /* Timer configuration.*/
413
+  qeip->tim->PSC  = 0;
414
+  arr = qeip->config->range - 1;
415
+  osalDbgAssert((arr <= 0xFFFF), "qei_lld_start(), #1" /*, "invalid range"*/);
416
+  qeip->tim->ARR  = arr & 0xFFFF;
417
+
418
+  /* CCMR1_CC1S = 01 - CH1 Input on TI1.
419
+     CCMR1_CC2S = 01 - CH2 Input on TI2.*/
420
+  qeip->tim->CCMR1 = TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0;
421
+
422
+  ccer = 0;
423
+  if (qeip->config->channels[0].mode == QEI_INPUT_INVERTED)
424
+    ccer |= TIM_CCER_CC1P;
425
+  if (qeip->config->channels[1].mode == QEI_INPUT_INVERTED)
426
+    ccer |= TIM_CCER_CC2P;
427
+  qeip->tim->CCER = ccer;
428
+
429
+  if (qeip->config->mode == QEI_COUNT_CH1)
430
+    qeip->tim->SMCR  = TIM_SMCR_SMS_1;
431
+  else if (qeip->config->mode == QEI_COUNT_CH2)
432
+    qeip->tim->SMCR  = TIM_SMCR_SMS_0;
433
+  else
434
+    qeip->tim->SMCR  = TIM_SMCR_SMS_0 | TIM_SMCR_SMS_1;
435
+}
436
+
437
+/**
438
+ * @brief   Deactivates the QEI peripheral.
439
+ *
440
+ * @param[in] qeip      pointer to the @p QEIDriver object
441
+ *
442
+ * @notapi
443
+ */
444
+void qei_lld_stop(QEIDriver *qeip) {
445
+
446
+  if (qeip->state == QEI_READY) {
447
+    /* Clock deactivation.*/
448
+    qeip->tim->CR1  = 0;                    /* Timer disabled.              */
449
+
450
+#if STM32_QEI_USE_TIM1
451
+    if (&QEID1 == qeip) {
452
+      rccDisableTIM1();
453
+    }
454
+#endif
455
+#if STM32_QEI_USE_TIM2
456
+    if (&QEID2 == qeip) {
457
+      rccDisableTIM2();
458
+    }
459
+#endif
460
+#if STM32_QEI_USE_TIM3
461
+    if (&QEID3 == qeip) {
462
+      rccDisableTIM3();
463
+    }
464
+#endif
465
+#if STM32_QEI_USE_TIM4
466
+    if (&QEID4 == qeip) {
467
+      rccDisableTIM4();
468
+    }
469
+#endif
470
+#if STM32_QEI_USE_TIM5
471
+    if (&QEID5 == qeip) {
472
+      rccDisableTIM5();
473
+    }
474
+#endif
475
+  }
476
+#if STM32_QEI_USE_TIM8
477
+    if (&QEID8 == qeip) {
478
+      rccDisableTIM8();
479
+    }
480
+#endif