Add timer module for stepper driver.
[bertos.git] / bertos / cpu / arm / drv / stepper_at91.h
1 /**
2  * \file
3  * <!--
4  * This file is part of BeRTOS.
5  *
6  * Bertos is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  * As a special exception, you may use this file as part of a free software
21  * library without restriction.  Specifically, if other files instantiate
22  * templates or use macros or inline functions from this file, or you compile
23  * this file and link it with other files to produce an executable, this
24  * file does not by itself cause the resulting executable to be covered by
25  * the GNU General Public License.  This exception does not however
26  * invalidate any other reasons why the executable file might be covered by
27  * the GNU General Public License.
28  *
29  * Copyright 2008 Develer S.r.l. (http://www.develer.com/)
30  * All Rights Reserved.
31  * -->
32  *
33  * \brief Stepper hardware-specific definitions
34  *
35  * \version $Id$
36  *
37  * \author Daniele Basile <asterix@develer.com>
38  */
39
40
41 #include <cfg/compiler.h>
42 #include <cfg/macros.h>
43 #include <drv/stepper.h>
44 #include <io/arm.h>
45
46 /**
47  * Setting master clock prescaler for all timer couter
48  *
49  * You could choise one of these:
50  * - TC_CLKS_MCK2: Selects MCK / 2
51  * - TC_CLKS_MCK8: Selects MCK / 8
52  * - TC_CLKS_MCK32: Selects MCK / 32
53  * - TC_CLKS_MCK128: Selects MCK / 128
54  * - TC_CLKS_MCK1024: Selects MCK / 1024
55  */
56 #if STEPPER_PRESCALER_LOG2 == 1
57         #define STEPPER_MCK_PRESCALER TC_CLKS_MCK2
58 #elif STEPPER_PRESCALER_LOG2 == 3
59         #define STEPPER_MCK_PRESCALER TC_CLKS_MCK8
60 #elif STEPPER_PRESCALER_LOG2 == 5
61         #define STEPPER_MCK_PRESCALER TC_CLKS_MCK32
62 #elif STEPPER_PRESCALER_LOG2 == 7
63         #define STEPPER_MCK_PRESCALER TC_CLKS_MCK128
64 #elif STEPPER_PRESCALER_LOG2 == 10
65         #define STEPPER_MCK_PRESCALER TC_CLKS_MCK1024
66 #else
67         #error Unsupported stepper prescaler value.
68 #endif
69
70 /**
71  * Timer counter hw enumeration.
72  */
73 enum
74 {
75         TC_TIOA0 = 0,
76         TC_TIOB0,
77         TC_TIOA1,
78         TC_TIOB1,
79         TC_TIOA2,
80         TC_TIOB2,
81
82         TC_CNT
83 };
84
85 /**
86  * IRQ callback function type definition.
87  */
88 typedef void (*irq_t)(void);
89
90 /**
91  * Timer contex structure.
92  */
93 typedef struct TimerCounter
94 {
95         int timer_id;                  ///< Timer counter ID
96         uint32_t blk_ctrl_set;         ///< Control block setting for this timer
97         reg32_t *chl_mode_reg;         ///< Channel mode register
98         reg32_t *chl_ctrl_reg;         ///< Channel control register
99         reg32_t *comp_reg;             ///< Compare register
100         reg32_t *comp_c_reg;           ///< C compare register
101         reg32_t *count_val_reg;        ///< Current timer counter value
102         uint32_t comp_effect_mask;     ///< Bit mask for TIO register compare effects
103         uint32_t comp_effect_set;      ///< Set TIO on register compare event
104         uint32_t comp_effect_clear;    ///< Clear TIO on register compare event
105         uint32_t comp_effect_c_mask;   ///< Bit mask for TIO on C register compare effects
106         uint32_t comp_effect_c_clear;  ///< Clear TIO on C register compare event
107         uint32_t ext_event_set;        ///< Setting for extern event trigger for TIOB
108         reg32_t *irq_enable_reg;       ///< Enable interrupt register
109         reg32_t *irq_disable_reg;      ///< Disable interrupt register
110         uint32_t irq_set_mask;         ///< IRQ flag bit for select TIO
111         reg32_t *irq_mask_reg;         ///< IRQ mask register
112         irq_t isr;                     ///< IRQ handler
113         reg32_t *status_reg;           ///< Timer status register
114         int tio_pin;                   ///< Timer I/O pin
115         stepper_isr_t callback;        ///< Interrupt callback pointer
116         struct Stepper *motor;         ///< Stepper context structure
117
118 } TimerCounter;
119
120 /**
121  * Enable interrupt for timer counter compare event.
122  */
123 INLINE void stepper_tc_irq_enable(struct TimerCounter *timer)
124 {
125         *timer->irq_enable_reg = timer->irq_set_mask;
126 }
127
128 /**
129  * Disable interrupt for timer counter compare event.
130  */
131 INLINE void  stepper_tc_irq_disable(struct TimerCounter *timer)
132 {
133         *timer->irq_disable_reg = timer->irq_set_mask;
134 }
135
136 /**
137  * Set delay for next interrupt compare event.
138  */
139 INLINE void  stepper_tc_setDelay(struct TimerCounter *timer, stepper_time_t delay)
140 {
141         *timer->comp_reg += delay;
142 }
143
144
145 /**
146  * Set delay for next interrupt compare event.
147  */
148 INLINE void  stepper_tc_resetTimer(struct TimerCounter *timer)
149 {
150         *timer->comp_reg = 0;
151 }
152
153 /**
154  * Programm timer counter to generate a pulse on select TIO output.
155  */
156 INLINE void FAST_FUNC stepper_tc_doPulse(struct TimerCounter *timer)
157 {
158         *timer->chl_mode_reg &= ~timer->comp_effect_mask;
159         *timer->chl_mode_reg |= timer->comp_effect_set;
160 }
161
162 /**
163  * Programm timer counter to not generate a pulse on select TIO output.
164  */
165 INLINE void FAST_FUNC stepper_tc_skipPulse(struct TimerCounter *timer)
166 {
167         *timer->chl_mode_reg &= ~timer->comp_effect_mask;
168 }
169
170 void stepper_tc_setup(int index, stepper_isr_t callback, struct Stepper *motor);
171 void stepper_tc_init(void);
172
173 /*
174  * Test the hardware timer counter on board.
175  * This test generate a square waveform through irq, setting
176  * the timer register.
177  */
178 void stepper_timer_test_brute(void);
179 /*
180  * Test the timer driver structure.
181  * This test generate a square waveform through irq.
182  * The irq callback is programmable, and all timer setting
183  * are save in one data structure. Every pulse is generate through
184  * a call of this irq callback.
185  */
186 void stepper_timer_test_prestepper(struct Stepper *local_motor, struct StepperConfig *local_cfg, int index);