source: rtems/bsps/powerpc/gen83xx/dev/gtm.c

Last change on this file was bcef89f2, checked in by Sebastian Huber <sebastian.huber@…>, on 05/19/23 at 06:18:25

Update company name

The embedded brains GmbH & Co. KG is the legal successor of embedded
brains GmbH.

  • Property mode set to 100644
File size: 7.3 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/**
4 * @file
5 *
6 * @brief Source file for timer functions.
7 */
8
9/*
10 * Copyright (c) 2008 embedded brains GmbH & Co. KG
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in the
18 *    documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include <rtems/bspIo.h>
34
35#include <mpc83xx/mpc83xx.h>
36#include <mpc83xx/gtm.h>
37
38#define RTEMS_STATUS_CHECKS_USE_PRINTK
39
40#include <rtems/status-checks.h>
41
42#define MPC83XX_GTM_CHECK_INDEX( timer) \
43        if (( timer) < 0 || ( timer) >= MPC83XX_GTM_NUMBER) { \
44                return RTEMS_INVALID_NUMBER; \
45        }
46
47#define GTM_MODULE(timer)       ((timer)/4)
48#define GTM_MODULE_TIMER(timer) ((timer)%4)
49#define GTM_HIGH(timer)         (GTM_MODULE_TIMER(timer)/2)
50#define GTM_LOW(timer)          (GTM_MODULE_TIMER(timer)%2)
51
52#define MPC83XX_GTM_CLOCK_MASK MPC83XX_GTM_CLOCK_EXTERN
53
54static const uint8_t mpc83xx_gmt_interrupt_vector_table [MPC83XX_GTM_NUMBER] = { 90, 78, 84, 72, 91, 79, 85, 73 };
55
56rtems_status_code mpc83xx_gtm_initialize( int timer, int clock)
57{
58        rtems_status_code sc = RTEMS_SUCCESSFUL;
59        rtems_interrupt_level level;
60
61        unsigned mask = 0xfU << (GTM_LOW(timer) * 4);
62        unsigned flags = 0x3U << (GTM_LOW(timer) * 4);
63        uint8_t reg = 0;
64
65        MPC83XX_GTM_CHECK_INDEX( timer);
66
67        rtems_interrupt_disable( level);
68
69        reg = mpc83xx.gtm [GTM_MODULE(timer)].gtcfr [GTM_HIGH(timer)].reg;
70        mpc83xx.gtm [GTM_MODULE(timer)].gtcfr [GTM_HIGH(timer)].reg =
71          (uint8_t) ((reg & ~mask) | flags);
72
73        mpc83xx.gtm [GTM_MODULE(timer)]
74          .gt_tim_regs [GTM_HIGH(timer)]
75          .gtmdr [GTM_LOW(timer)] = 0;
76
77        rtems_interrupt_enable( level);
78
79        sc = mpc83xx_gtm_set_clock( timer, clock);
80        RTEMS_CHECK_SC( sc, "Set clock");
81
82        sc = mpc83xx_gtm_set_value( timer, 0);
83        RTEMS_CHECK_SC( sc, "Set value");
84
85        sc = mpc83xx_gtm_set_reference( timer, 0);
86        RTEMS_CHECK_SC( sc, "Set reference");
87
88        sc = mpc83xx_gtm_set_prescale( timer, 0);
89        RTEMS_CHECK_SC( sc, "Set prescale");
90
91        return RTEMS_SUCCESSFUL;
92}
93
94rtems_status_code mpc83xx_gtm_enable_restart( int timer, bool enable)
95{
96        rtems_interrupt_level level;
97        MPC83XX_GTM_CHECK_INDEX( timer);
98
99        rtems_interrupt_disable( level);
100
101        if (enable) {
102                mpc83xx.gtm [GTM_MODULE(timer)]
103                  .gt_tim_regs [GTM_HIGH(timer)]
104                  .gtmdr [GTM_LOW(timer)] |= 0x0008;
105        } else {
106                mpc83xx.gtm [GTM_MODULE(timer)]
107                  .gt_tim_regs [GTM_HIGH(timer)]
108                  .gtmdr [GTM_LOW(timer)] &= ~0x0008;
109        }
110
111        rtems_interrupt_enable( level);
112
113        return RTEMS_SUCCESSFUL;
114}
115
116rtems_status_code mpc83xx_gtm_set_clock( int timer, int clock)
117{
118        rtems_interrupt_level level;
119        uint16_t reg = 0;
120
121        MPC83XX_GTM_CHECK_INDEX( timer);
122
123        if (clock & ~MPC83XX_GTM_CLOCK_MASK) {
124                return RTEMS_INVALID_CLOCK;
125        }
126
127        rtems_interrupt_disable( level);
128
129        reg = mpc83xx.gtm [GTM_MODULE(timer)]
130          .gt_tim_regs [GTM_HIGH(timer)]
131          .gtmdr [GTM_LOW(timer)];
132        mpc83xx.gtm [GTM_MODULE(timer)]
133          .gt_tim_regs [GTM_HIGH(timer)]
134          .gtmdr [GTM_LOW(timer)] = (reg & ~MPC83XX_GTM_CLOCK_MASK) | clock;
135
136        rtems_interrupt_enable( level);
137
138        return RTEMS_SUCCESSFUL;
139}
140
141rtems_status_code mpc83xx_gtm_get_clock( int timer, int *clock)
142{
143        MPC83XX_GTM_CHECK_INDEX( timer);
144
145        *clock = mpc83xx.gtm [GTM_MODULE(timer)]
146          .gt_tim_regs [GTM_HIGH(timer)]
147          .gtmdr [GTM_LOW(timer)] & MPC83XX_GTM_CLOCK_MASK;
148
149        return RTEMS_SUCCESSFUL;
150}
151
152rtems_status_code mpc83xx_gtm_start( int timer)
153{
154        rtems_interrupt_level level;
155        uint8_t flags = 0x2 << (GTM_LOW(timer) * 4);
156
157        MPC83XX_GTM_CHECK_INDEX( timer);
158
159        rtems_interrupt_disable( level);
160        mpc83xx.gtm [GTM_MODULE(timer)]
161.gtcfr [GTM_HIGH(timer)].reg &= ~flags;
162        rtems_interrupt_enable( level);
163
164        return RTEMS_SUCCESSFUL;
165}
166
167rtems_status_code mpc83xx_gtm_stop( int timer)
168{
169        rtems_interrupt_level level;
170        uint8_t flags = 0x2 << (GTM_LOW(timer) * 4);
171
172        MPC83XX_GTM_CHECK_INDEX( timer);
173
174        rtems_interrupt_disable( level);
175        mpc83xx.gtm [GTM_MODULE(timer)].gtcfr [GTM_HIGH(timer)].reg |= flags;
176        rtems_interrupt_enable( level);
177
178        return RTEMS_SUCCESSFUL;
179}
180
181rtems_status_code mpc83xx_gtm_set_value( int timer, uint16_t value)
182{
183        MPC83XX_GTM_CHECK_INDEX( timer);
184
185        mpc83xx.gtm [GTM_MODULE(timer)].gt_tim_regs [GTM_HIGH(timer)].gtcnr [GTM_LOW(timer)] = value;
186
187        return RTEMS_SUCCESSFUL;
188}
189
190rtems_status_code mpc83xx_gtm_get_value( int timer, uint16_t *value)
191{
192        MPC83XX_GTM_CHECK_INDEX( timer);
193
194        *value = mpc83xx.gtm [GTM_MODULE(timer)].gt_tim_regs [GTM_HIGH(timer)].gtcnr [GTM_LOW(timer)];
195
196        return RTEMS_SUCCESSFUL;
197}
198
199rtems_status_code mpc83xx_gtm_set_reference( int timer, uint16_t reference)
200{
201        MPC83XX_GTM_CHECK_INDEX( timer);
202
203        mpc83xx.gtm [GTM_MODULE(timer)].gt_tim_regs [GTM_HIGH(timer)].gtrfr [GTM_LOW(timer)] = reference;
204
205        return RTEMS_SUCCESSFUL;
206}
207
208rtems_status_code mpc83xx_gtm_get_reference( int timer, uint16_t *reference)
209{
210        MPC83XX_GTM_CHECK_INDEX( timer);
211
212        *reference = mpc83xx.gtm [GTM_MODULE(timer)].gt_tim_regs [GTM_HIGH(timer)].gtrfr [GTM_LOW(timer)];
213
214        return RTEMS_SUCCESSFUL;
215}
216
217rtems_status_code mpc83xx_gtm_set_prescale( int timer, uint8_t prescale)
218{
219        MPC83XX_GTM_CHECK_INDEX( timer);
220
221        mpc83xx.gtm [GTM_MODULE(timer)].gtpsr [GTM_MODULE_TIMER(timer)] = prescale;
222
223        return RTEMS_SUCCESSFUL;
224}
225
226rtems_status_code mpc83xx_gtm_get_prescale( int timer, uint8_t *prescale)
227{
228        MPC83XX_GTM_CHECK_INDEX( timer);
229
230        *prescale = mpc83xx.gtm [GTM_MODULE(timer)].gtpsr [GTM_MODULE_TIMER(timer)];
231
232        return RTEMS_SUCCESSFUL;
233}
234
235rtems_status_code mpc83xx_gtm_interrupt_get_vector( int timer, rtems_vector_number *vector)
236{
237        MPC83XX_GTM_CHECK_INDEX( timer);
238
239        *vector = mpc83xx_gmt_interrupt_vector_table [timer];
240
241        return RTEMS_SUCCESSFUL;
242}
243
244rtems_status_code mpc83xx_gtm_interrupt_enable( int timer)
245{
246        rtems_interrupt_level level;
247        MPC83XX_GTM_CHECK_INDEX( timer);
248
249        rtems_interrupt_disable( level);
250        mpc83xx.gtm [GTM_MODULE(timer)].gt_tim_regs [GTM_HIGH(timer)].gtmdr [GTM_LOW(timer)] |= 0x0010;
251        rtems_interrupt_enable( level);
252
253        return RTEMS_SUCCESSFUL;
254}
255
256rtems_status_code mpc83xx_gtm_interrupt_disable( int timer)
257{
258        rtems_interrupt_level level;
259        MPC83XX_GTM_CHECK_INDEX( timer);
260
261        rtems_interrupt_disable( level);
262        mpc83xx.gtm [GTM_MODULE(timer)].gt_tim_regs [GTM_HIGH(timer)].gtmdr [GTM_LOW(timer)] &= ~0x0010;
263        rtems_interrupt_enable( level);
264
265        return RTEMS_SUCCESSFUL;
266}
267
268rtems_status_code mpc83xx_gtm_interrupt_clear( int timer)
269{
270        MPC83XX_GTM_CHECK_INDEX( timer);
271
272        mpc83xx.gtm [GTM_MODULE(timer)].gtevr [GTM_MODULE_TIMER(timer)] = 0x0002;
273
274        return RTEMS_SUCCESSFUL;
275}
Note: See TracBrowser for help on using the repository browser.