Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:53

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @brief Source file for timer functions.
0007  */
0008 
0009 /*
0010  * Copyright (c) 2008 embedded brains GmbH & Co. KG
0011  * Redistribution and use in source and binary forms, with or without
0012  * modification, are permitted provided that the following conditions
0013  * are met:
0014  * 1. Redistributions of source code must retain the above copyright
0015  *    notice, this list of conditions and the following disclaimer.
0016  * 2. Redistributions in binary form must reproduce the above copyright
0017  *    notice, this list of conditions and the following disclaimer in the
0018  *    documentation and/or other materials provided with the distribution.
0019  *
0020  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0021  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0022  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0023  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0024  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0025  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0026  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0027  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0028  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0029  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0030  * POSSIBILITY OF SUCH DAMAGE.
0031  */
0032 
0033 #include <rtems/bspIo.h>
0034 
0035 #include <mpc83xx/mpc83xx.h>
0036 #include <mpc83xx/gtm.h>
0037 
0038 #define RTEMS_STATUS_CHECKS_USE_PRINTK
0039 
0040 #include <rtems/status-checks.h>
0041 
0042 #define MPC83XX_GTM_CHECK_INDEX( timer) \
0043     if (( timer) < 0 || ( timer) >= MPC83XX_GTM_NUMBER) { \
0044         return RTEMS_INVALID_NUMBER; \
0045     }
0046 
0047 #define GTM_MODULE(timer)       ((timer)/4)
0048 #define GTM_MODULE_TIMER(timer) ((timer)%4)
0049 #define GTM_HIGH(timer)         (GTM_MODULE_TIMER(timer)/2)
0050 #define GTM_LOW(timer)          (GTM_MODULE_TIMER(timer)%2)
0051 
0052 #define MPC83XX_GTM_CLOCK_MASK MPC83XX_GTM_CLOCK_EXTERN
0053 
0054 static const uint8_t mpc83xx_gmt_interrupt_vector_table [MPC83XX_GTM_NUMBER] = { 90, 78, 84, 72, 91, 79, 85, 73 };
0055 
0056 rtems_status_code mpc83xx_gtm_initialize( int timer, int clock)
0057 {
0058     rtems_status_code sc = RTEMS_SUCCESSFUL;
0059     rtems_interrupt_level level;
0060 
0061     unsigned mask = 0xfU << (GTM_LOW(timer) * 4);
0062     unsigned flags = 0x3U << (GTM_LOW(timer) * 4);
0063     uint8_t reg = 0;
0064 
0065     MPC83XX_GTM_CHECK_INDEX( timer);
0066 
0067     rtems_interrupt_disable( level);
0068 
0069     reg = mpc83xx.gtm [GTM_MODULE(timer)].gtcfr [GTM_HIGH(timer)].reg;
0070     mpc83xx.gtm [GTM_MODULE(timer)].gtcfr [GTM_HIGH(timer)].reg = 
0071       (uint8_t) ((reg & ~mask) | flags);
0072 
0073     mpc83xx.gtm [GTM_MODULE(timer)]
0074       .gt_tim_regs [GTM_HIGH(timer)]
0075       .gtmdr [GTM_LOW(timer)] = 0;
0076 
0077     rtems_interrupt_enable( level);
0078 
0079     sc = mpc83xx_gtm_set_clock( timer, clock);
0080     RTEMS_CHECK_SC( sc, "Set clock");
0081 
0082     sc = mpc83xx_gtm_set_value( timer, 0);
0083     RTEMS_CHECK_SC( sc, "Set value");
0084 
0085     sc = mpc83xx_gtm_set_reference( timer, 0);
0086     RTEMS_CHECK_SC( sc, "Set reference");
0087 
0088     sc = mpc83xx_gtm_set_prescale( timer, 0);
0089     RTEMS_CHECK_SC( sc, "Set prescale");
0090 
0091     return RTEMS_SUCCESSFUL;
0092 }
0093 
0094 rtems_status_code mpc83xx_gtm_enable_restart( int timer, bool enable)
0095 {
0096     rtems_interrupt_level level;
0097     MPC83XX_GTM_CHECK_INDEX( timer);
0098 
0099     rtems_interrupt_disable( level);
0100 
0101     if (enable) {
0102         mpc83xx.gtm [GTM_MODULE(timer)]
0103           .gt_tim_regs [GTM_HIGH(timer)]
0104           .gtmdr [GTM_LOW(timer)] |= 0x0008;
0105     } else {
0106         mpc83xx.gtm [GTM_MODULE(timer)]
0107           .gt_tim_regs [GTM_HIGH(timer)]
0108           .gtmdr [GTM_LOW(timer)] &= ~0x0008;
0109     }
0110 
0111     rtems_interrupt_enable( level);
0112 
0113     return RTEMS_SUCCESSFUL;
0114 }
0115 
0116 rtems_status_code mpc83xx_gtm_set_clock( int timer, int clock)
0117 {
0118     rtems_interrupt_level level;
0119     uint16_t reg = 0;
0120 
0121     MPC83XX_GTM_CHECK_INDEX( timer);
0122 
0123     if (clock & ~MPC83XX_GTM_CLOCK_MASK) {
0124         return RTEMS_INVALID_CLOCK;
0125     }
0126 
0127     rtems_interrupt_disable( level);
0128 
0129     reg = mpc83xx.gtm [GTM_MODULE(timer)]
0130       .gt_tim_regs [GTM_HIGH(timer)]
0131       .gtmdr [GTM_LOW(timer)];
0132     mpc83xx.gtm [GTM_MODULE(timer)]
0133       .gt_tim_regs [GTM_HIGH(timer)]
0134       .gtmdr [GTM_LOW(timer)] = (reg & ~MPC83XX_GTM_CLOCK_MASK) | clock;
0135 
0136     rtems_interrupt_enable( level);
0137 
0138     return RTEMS_SUCCESSFUL;
0139 }
0140 
0141 rtems_status_code mpc83xx_gtm_get_clock( int timer, int *clock)
0142 {
0143     MPC83XX_GTM_CHECK_INDEX( timer);
0144 
0145     *clock = mpc83xx.gtm [GTM_MODULE(timer)]
0146       .gt_tim_regs [GTM_HIGH(timer)]
0147       .gtmdr [GTM_LOW(timer)] & MPC83XX_GTM_CLOCK_MASK;
0148 
0149     return RTEMS_SUCCESSFUL;
0150 }
0151 
0152 rtems_status_code mpc83xx_gtm_start( int timer)
0153 {
0154     rtems_interrupt_level level;
0155     uint8_t flags = 0x2 << (GTM_LOW(timer) * 4);
0156 
0157     MPC83XX_GTM_CHECK_INDEX( timer);
0158 
0159     rtems_interrupt_disable( level);
0160     mpc83xx.gtm [GTM_MODULE(timer)]
0161 .gtcfr [GTM_HIGH(timer)].reg &= ~flags;
0162     rtems_interrupt_enable( level);
0163 
0164     return RTEMS_SUCCESSFUL;
0165 }
0166 
0167 rtems_status_code mpc83xx_gtm_stop( int timer)
0168 {
0169     rtems_interrupt_level level;
0170     uint8_t flags = 0x2 << (GTM_LOW(timer) * 4);
0171 
0172     MPC83XX_GTM_CHECK_INDEX( timer);
0173 
0174     rtems_interrupt_disable( level);
0175     mpc83xx.gtm [GTM_MODULE(timer)].gtcfr [GTM_HIGH(timer)].reg |= flags;
0176     rtems_interrupt_enable( level);
0177 
0178     return RTEMS_SUCCESSFUL;
0179 }
0180 
0181 rtems_status_code mpc83xx_gtm_set_value( int timer, uint16_t value)
0182 {
0183     MPC83XX_GTM_CHECK_INDEX( timer);
0184 
0185     mpc83xx.gtm [GTM_MODULE(timer)].gt_tim_regs [GTM_HIGH(timer)].gtcnr [GTM_LOW(timer)] = value;
0186 
0187     return RTEMS_SUCCESSFUL;
0188 }
0189 
0190 rtems_status_code mpc83xx_gtm_get_value( int timer, uint16_t *value)
0191 {
0192     MPC83XX_GTM_CHECK_INDEX( timer);
0193 
0194     *value = mpc83xx.gtm [GTM_MODULE(timer)].gt_tim_regs [GTM_HIGH(timer)].gtcnr [GTM_LOW(timer)];
0195 
0196     return RTEMS_SUCCESSFUL;
0197 }
0198 
0199 rtems_status_code mpc83xx_gtm_set_reference( int timer, uint16_t reference)
0200 {
0201     MPC83XX_GTM_CHECK_INDEX( timer);
0202 
0203     mpc83xx.gtm [GTM_MODULE(timer)].gt_tim_regs [GTM_HIGH(timer)].gtrfr [GTM_LOW(timer)] = reference;
0204 
0205     return RTEMS_SUCCESSFUL;
0206 }
0207 
0208 rtems_status_code mpc83xx_gtm_get_reference( int timer, uint16_t *reference)
0209 {
0210     MPC83XX_GTM_CHECK_INDEX( timer);
0211 
0212     *reference = mpc83xx.gtm [GTM_MODULE(timer)].gt_tim_regs [GTM_HIGH(timer)].gtrfr [GTM_LOW(timer)];
0213 
0214     return RTEMS_SUCCESSFUL;
0215 }
0216 
0217 rtems_status_code mpc83xx_gtm_set_prescale( int timer, uint8_t prescale)
0218 {
0219     MPC83XX_GTM_CHECK_INDEX( timer);
0220 
0221     mpc83xx.gtm [GTM_MODULE(timer)].gtpsr [GTM_MODULE_TIMER(timer)] = prescale;
0222 
0223     return RTEMS_SUCCESSFUL;
0224 }
0225 
0226 rtems_status_code mpc83xx_gtm_get_prescale( int timer, uint8_t *prescale)
0227 {
0228     MPC83XX_GTM_CHECK_INDEX( timer);
0229 
0230     *prescale = mpc83xx.gtm [GTM_MODULE(timer)].gtpsr [GTM_MODULE_TIMER(timer)];
0231 
0232     return RTEMS_SUCCESSFUL;
0233 }
0234 
0235 rtems_status_code mpc83xx_gtm_interrupt_get_vector( int timer, rtems_vector_number *vector)
0236 {
0237     MPC83XX_GTM_CHECK_INDEX( timer);
0238 
0239     *vector = mpc83xx_gmt_interrupt_vector_table [timer];
0240 
0241     return RTEMS_SUCCESSFUL;
0242 }
0243 
0244 rtems_status_code mpc83xx_gtm_interrupt_enable( int timer)
0245 {
0246     rtems_interrupt_level level;
0247     MPC83XX_GTM_CHECK_INDEX( timer);
0248 
0249     rtems_interrupt_disable( level);
0250     mpc83xx.gtm [GTM_MODULE(timer)].gt_tim_regs [GTM_HIGH(timer)].gtmdr [GTM_LOW(timer)] |= 0x0010;
0251     rtems_interrupt_enable( level);
0252 
0253     return RTEMS_SUCCESSFUL;
0254 }
0255 
0256 rtems_status_code mpc83xx_gtm_interrupt_disable( int timer)
0257 {
0258     rtems_interrupt_level level;
0259     MPC83XX_GTM_CHECK_INDEX( timer);
0260 
0261     rtems_interrupt_disable( level);
0262     mpc83xx.gtm [GTM_MODULE(timer)].gt_tim_regs [GTM_HIGH(timer)].gtmdr [GTM_LOW(timer)] &= ~0x0010;
0263     rtems_interrupt_enable( level);
0264 
0265     return RTEMS_SUCCESSFUL;
0266 }
0267 
0268 rtems_status_code mpc83xx_gtm_interrupt_clear( int timer)
0269 {
0270     MPC83XX_GTM_CHECK_INDEX( timer);
0271 
0272     mpc83xx.gtm [GTM_MODULE(timer)].gtevr [GTM_MODULE_TIMER(timer)] = 0x0002;
0273 
0274     return RTEMS_SUCCESSFUL;
0275 }