Add support for old init.
[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  *
36  * \author Daniele Basile <asterix@develer.com>
37  */
38
39
40 #include <cfg/compiler.h>
41 #include <cfg/macros.h>
42 #include <drv/stepper.h>
43 #include <io/arm.h>
44
45 /**
46  * Setting master clock prescaler for all timer couter
47  *
48  * You could choise one of these:
49  * - TC_CLKS_MCK2: Selects MCK / 2
50  * - TC_CLKS_MCK8: Selects MCK / 8
51  * - TC_CLKS_MCK32: Selects MCK / 32
52  * - TC_CLKS_MCK128: Selects MCK / 128
53  * - TC_CLKS_MCK1024: Selects MCK / 1024
54  */
55 #if STEPPER_PRESCALER_LOG2 == 1
56         #define STEPPER_MCK_PRESCALER TC_CLKS_MCK2
57 #elif STEPPER_PRESCALER_LOG2 == 3
58         #define STEPPER_MCK_PRESCALER TC_CLKS_MCK8
59 #elif STEPPER_PRESCALER_LOG2 == 5
60         #define STEPPER_MCK_PRESCALER TC_CLKS_MCK32
61 #elif STEPPER_PRESCALER_LOG2 == 7
62         #define STEPPER_MCK_PRESCALER TC_CLKS_MCK128
63 #elif STEPPER_PRESCALER_LOG2 == 10
64         #define STEPPER_MCK_PRESCALER TC_CLKS_MCK1024
65 #else
66         #error Unsupported stepper prescaler value.
67 #endif
68
69 /**
70  * Timer counter hw enumeration.
71  */
72 enum
73 {
74         TC_TIOA0 = 0,
75         TC_TIOB0,
76         TC_TIOA1,
77         TC_TIOB1,
78         TC_TIOA2,
79         TC_TIOB2,
80
81         TC_CNT
82 };
83
84 /**
85  * IRQ callback function type definition.
86  */
87 typedef void (*irq_t)(void);
88
89 /**
90  * Timer contex structure.
91  */
92 typedef struct TimerCounter
93 {
94         int timer_id;                  ///< Timer counter ID
95         uint32_t blk_ctrl_set;         ///< Control block setting for this timer
96         reg32_t *chl_mode_reg;         ///< Channel mode register
97         reg32_t *chl_ctrl_reg;         ///< Channel control register
98         reg32_t *comp_reg;             ///< Compare register
99         reg32_t *comp_c_reg;           ///< C compare register
100         reg32_t *count_val_reg;        ///< Current timer counter value
101         uint32_t comp_effect_mask;     ///< Bit mask for TIO register compare effects
102         uint32_t comp_effect_set;      ///< Set TIO on register compare event
103         uint32_t comp_effect_clear;    ///< Clear TIO on register compare event
104         uint32_t comp_effect_c_mask;   ///< Bit mask for TIO on C register compare effects
105         uint32_t comp_effect_c_clear;  ///< Clear TIO on C register compare event
106         uint32_t ext_event_set;        ///< Setting for extern event trigger for TIOB
107         reg32_t *irq_enable_reg;       ///< Enable interrupt register
108         reg32_t *irq_disable_reg;      ///< Disable interrupt register
109         uint32_t irq_set_mask;         ///< IRQ flag bit for select TIO
110         reg32_t *irq_mask_reg;         ///< IRQ mask register
111         irq_t isr;                     ///< IRQ handler
112         reg32_t *status_reg;           ///< Timer status register
113         int tio_pin;                   ///< Timer I/O pin
114         stepper_isr_t callback;        ///< Interrupt callback pointer
115         struct Stepper *motor;         ///< Stepper context structure
116
117 } TimerCounter;
118
119 /**
120  * Enable interrupt for timer counter compare event.
121  */
122 INLINE void stepper_tc_irq_enable(struct TimerCounter *timer)
123 {
124         *timer->irq_enable_reg = timer->irq_set_mask;
125 }
126
127 /**
128  * Disable interrupt for timer counter compare event.
129  */
130 INLINE void  stepper_tc_irq_disable(struct TimerCounter *timer)
131 {
132         *timer->irq_disable_reg = timer->irq_set_mask;
133 }
134
135 /**
136  * Set delay for next interrupt compare event.
137  */
138 INLINE void  stepper_tc_setDelay(struct TimerCounter *timer, stepper_time_t delay)
139 {
140         *timer->comp_reg += delay;
141 }
142
143
144 /**
145  * Set delay for next interrupt compare event.
146  */
147 INLINE void  stepper_tc_resetTimer(struct TimerCounter *timer)
148 {
149         *timer->comp_reg = 0;
150 }
151
152 /**
153  * Programm timer counter to generate a pulse on select TIO output.
154  */
155 INLINE void FAST_FUNC stepper_tc_doPulse(struct TimerCounter *timer)
156 {
157         *timer->chl_mode_reg &= ~timer->comp_effect_mask;
158         *timer->chl_mode_reg |= timer->comp_effect_set;
159 }
160
161 /**
162  * Programm timer counter to not generate a pulse on select TIO output.
163  */
164 INLINE void FAST_FUNC stepper_tc_skipPulse(struct TimerCounter *timer)
165 {
166         *timer->chl_mode_reg &= ~timer->comp_effect_mask;
167 }
168
169 void stepper_tc_setup(int index, stepper_isr_t callback, struct Stepper *motor);
170 void stepper_tc_init(void);
171
172 /*
173  * Test the hardware timer counter on board.
174  * This test generate a square waveform through irq, setting
175  * the timer register.
176  */
177 void stepper_timer_test_brute(void);
178 /*
179  * Test the timer driver structure.
180  * This test generate a square waveform through irq.
181  * The irq callback is programmable, and all timer setting
182  * are save in one data structure. Every pulse is generate through
183  * a call of this irq callback.
184  */
185 void stepper_timer_test_prestepper(struct Stepper *local_motor, struct StepperConfig *local_cfg, int index);