![]() |
|
|||
File indexing completed on 2025-05-11 08:23:39
0001 /* SPDX-License-Identifier: BSD-2-Clause */ 0002 0003 /** 0004 * @file 0005 * 0006 * @ingroup RTEMSBSPsARMTMS570 0007 * 0008 * @brief This source file contains the I/O Multiplexing Module (IOMM) support 0009 * implementation. 0010 */ 0011 0012 /* 0013 * Copyright (C) 2015 Premysl Houdek <kom541000@gmail.com> 0014 * 0015 * Google Summer of Code 2014 at 0016 * Czech Technical University in Prague 0017 * Zikova 1903/4 0018 * 166 36 Praha 6 0019 * Czech Republic 0020 * 0021 * Redistribution and use in source and binary forms, with or without 0022 * modification, are permitted provided that the following conditions 0023 * are met: 0024 * 1. Redistributions of source code must retain the above copyright 0025 * notice, this list of conditions and the following disclaimer. 0026 * 2. Redistributions in binary form must reproduce the above copyright 0027 * notice, this list of conditions and the following disclaimer in the 0028 * documentation and/or other materials provided with the distribution. 0029 * 0030 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 0031 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 0032 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 0033 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 0034 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 0035 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 0036 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 0037 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 0038 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 0039 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 0040 * POSSIBILITY OF SUCH DAMAGE. 0041 */ 0042 0043 #include <bsp/tms570.h> 0044 #include <bsp/tms570-pinmux.h> 0045 #include <bsp/irq.h> 0046 0047 RTEMS_STATIC_ASSERT( 0048 TMS570_PIN_CLEAR_RQ_MASK == TMS570_PIN_FNC_CLEAR << TMS570_PIN_FNC_SHIFT, 0049 TMS570_PIN_CONFIG 0050 ); 0051 0052 static inline void 0053 tms570_bsp_pin_to_pinmmrx(volatile uint32_t **pinmmrx, uint32_t *pin_shift, 0054 uint32_t config) 0055 { 0056 uint32_t pin_num = (config & TMS570_PIN_NUM_MASK) >> TMS570_PIN_NUM_SHIFT; 0057 *pinmmrx = TMS570_PINMUX + (pin_num >> 2); 0058 *pin_shift = (pin_num & 0x3)*8; 0059 } 0060 0061 /** 0062 * @brief select desired function of pin/ball 0063 * 0064 * The function setups multiplexer to interconnect pin with 0065 * specified function/peripheral. Pin number is index into pinmux 0066 * entries array. Predefined values for pins are in a format 0067 * TMS570_BALL_ \c column \c row (for example \c TMS570_BALL_N19). 0068 * The multiplexer allows to interconnect one pin to multiple 0069 * signal sources/sinks in the theory but it is usually bad choice. 0070 * The function sets only specified function and clears all other 0071 * connections. 0072 * 0073 * @param[in] pin_num pin/ball identifier (index into pinmux array), 0074 * @param[in] pin_fnc function number 0 .. 7, if value \c TMS570_PIN_FNC_AUTO 0075 * is specified then pin function is extracted from 0076 * pin_num argument 0077 * @retval Void 0078 */ 0079 void 0080 tms570_bsp_pin_set_function(int pin_num, int pin_fnc) 0081 { 0082 unsigned int pin_shift; 0083 volatile uint32_t *pinmmrx; 0084 0085 if ( pin_fnc == TMS570_PIN_FNC_AUTO ) { 0086 pin_fnc = (pin_num & TMS570_PIN_FNC_MASK) >> TMS570_PIN_FNC_SHIFT; 0087 } 0088 tms570_bsp_pin_to_pinmmrx(&pinmmrx, &pin_shift, pin_num); 0089 *pinmmrx = (*pinmmrx & ~(0xff << pin_shift)) | (1 << (pin_fnc + pin_shift)); 0090 } 0091 0092 /** 0093 * @brief clear connection between pin and specified peripherals/function 0094 * 0095 * This function switches off given connection and leaves rest 0096 * of multiplexer setup intact. 0097 * 0098 * @param[in] pin_num pin/ball identifier (index into pinmux array) 0099 * @param[in] pin_fnc function number 0 .. 7, if value \c TMS570_PIN_FNC_AUTO 0100 * is specified then pin function is extracted from 0101 * pin_num argument 0102 * @retval Void 0103 */ 0104 void 0105 tms570_bsp_pin_clear_function(int pin_num, int pin_fnc) 0106 { 0107 unsigned int pin_shift; 0108 volatile uint32_t *pinmmrx; 0109 0110 if ( pin_fnc == TMS570_PIN_FNC_AUTO ) { 0111 pin_fnc = (pin_num & TMS570_PIN_FNC_MASK) >> TMS570_PIN_FNC_SHIFT; 0112 } 0113 tms570_bsp_pin_to_pinmmrx(&pinmmrx, &pin_shift, pin_num); 0114 *pinmmrx = *pinmmrx & ~(1 << (pin_fnc+pin_shift)); 0115 } 0116 0117 /** 0118 * @brief configure one pin according to its function specification 0119 * 0120 * The function setups multiplexer to interconnect pin with 0121 * specified function/peripheral. Predefined values for pins combined with 0122 * function are in a format TMS570_BALL_ \c column \c row \c function 0123 * (for example \c TMS570_BALL_W3_SCIRX). 0124 * If the function can be connected to more pins then specification 0125 * includes infomation which allows to disconnect alternative pin to peripheral 0126 * input connection or switch input multiplexer to right pin. 0127 * 0128 * @param[in] pin_num_and_fnc pin function descriptor is build by macro 0129 * \c TMS570_PIN_AND_FNC which takes pin/pinmmr specification 0130 * build by \c TMS570_BALL_WITH_MMR and function index in output 0131 * multiplexer. If the peripheral can be connected to other input 0132 * alternative then actual pin description and alternative to 0133 * disconnected/reconnect are combined together by 0134 * \c TMS570_PIN_WITH_IN_ALT macro. If clear of alternative 0135 * connection is required then flag \c TMS570_PIN_CLEAR_RQ_MASK 0136 * is ored to alternative description. 0137 * 0138 * @retval Void 0139 */ 0140 void 0141 tms570_bsp_pin_config_one(uint32_t pin_num_and_fnc) 0142 { 0143 rtems_interrupt_level intlev; 0144 0145 rtems_interrupt_disable(intlev); 0146 tms570_pin_config_prepare(); 0147 tms570_pin_config_apply(pin_num_and_fnc); 0148 tms570_pin_config_complete(); 0149 rtems_interrupt_enable(intlev); 0150 } 0151 0152 /** 0153 * @brief configure block or whole pin multiplexer 0154 * 0155 * Function change multiplexer content. It is intended for initial 0156 * chip setup and does not use locking. If complete reconfiguration 0157 * is required at runtime then it is application responsibility 0158 * to protect and serialize change with peripherals drivers 0159 * and parallel calls 0160 * 0161 * @param[in] pinmmr_values pointer to array with required multiplexer setup 0162 * @param[in] reg_start starting register, this allows to configure non-consecutive 0163 * registers groups found on some MCU family members 0164 * @param[in] reg_count number of words in initialization array to set 0165 * to corresponding registers 0166 * 0167 * @retval Void 0168 */ 0169 void 0170 tms570_bsp_pinmmr_config(const uint32_t *pinmmr_values, int reg_start, int reg_count) 0171 { 0172 volatile uint32_t *pinmmrx; 0173 const uint32_t *pval; 0174 int cnt; 0175 0176 if ( reg_count <= 0) 0177 return; 0178 0179 tms570_pin_config_prepare(); 0180 0181 pinmmrx = TMS570_PINMUX + reg_start; 0182 pval = pinmmr_values; 0183 cnt = reg_count; 0184 0185 do { 0186 *pinmmrx = *pval; 0187 pinmmrx++; 0188 pval++; 0189 } while( --cnt ); 0190 0191 tms570_pin_config_complete(); 0192 } 0193 0194 void tms570_pin_config_prepare(void) 0195 { 0196 TMS570_IOMM.KICK_REG0 = 0x83E70B13U; 0197 TMS570_IOMM.KICK_REG1 = 0x95A4F1E0U; 0198 } 0199 0200 static void 0201 tms570_pin_set_function(uint32_t config) 0202 { 0203 volatile uint32_t *pinmmrx; 0204 uint32_t pin_shift; 0205 uint32_t pin_fnc; 0206 uint32_t bit; 0207 uint32_t val; 0208 0209 tms570_bsp_pin_to_pinmmrx(&pinmmrx, &pin_shift, config); 0210 pin_fnc = (config & TMS570_PIN_FNC_MASK) >> TMS570_PIN_FNC_SHIFT; 0211 bit = 1U << (pin_fnc + pin_shift); 0212 val = *pinmmrx; 0213 val &= ~(0xffU << pin_shift); 0214 0215 if ((config & TMS570_PIN_CLEAR_RQ_MASK) == 0) { 0216 val |= bit; 0217 } 0218 0219 *pinmmrx = val; 0220 } 0221 0222 void tms570_pin_config_apply(uint32_t config) 0223 { 0224 uint32_t pin_in_alt; 0225 uint32_t pin_num_and_fnc; 0226 0227 pin_in_alt = config & TMS570_PIN_IN_ALT_MASK; 0228 if (pin_in_alt != 0) { 0229 pin_in_alt >>= TMS570_PIN_IN_ALT_SHIFT; 0230 tms570_pin_set_function(pin_in_alt); 0231 } 0232 0233 pin_num_and_fnc = config & TMS570_PIN_NUM_FNC_MASK; 0234 tms570_pin_set_function(pin_num_and_fnc); 0235 } 0236 0237 void tms570_pin_config_array_apply(const uint32_t *config, size_t count) 0238 { 0239 size_t i; 0240 0241 for (i = 0; i < count; ++i) { 0242 tms570_pin_config_apply(config[i]); 0243 } 0244 } 0245 0246 void tms570_pin_config_complete(void) 0247 { 0248 TMS570_IOMM.KICK_REG0 = 0; 0249 TMS570_IOMM.KICK_REG1 = 0; 0250 }
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |