source: rtems/bsps/arm/tms570/start/pinmux.c @ 350b07a0

5
Last change on this file since 350b07a0 was a62c75c1, checked in by Sebastian Huber <sebastian.huber@…>, on 04/22/18 at 13:38:55

bsp/tms570: Move more start to bsps

This patch is a part of the BSP source reorganization.

Update #3285.

  • Property mode set to 100644
File size: 6.1 KB
Line 
1/**
2 * @file pinmux.c
3 *
4 * @ingroup tms570
5 *
6 * @brief I/O Multiplexing Module (IOMM) basic support
7 */
8
9/*
10 * Copyright (c) 2015 Premysl Houdek <kom541000@gmail.com>
11 *
12 * Google Summer of Code 2014 at
13 * Czech Technical University in Prague
14 * Zikova 1903/4
15 * 166 36 Praha 6
16 * Czech Republic
17 *
18 * The license and distribution terms for this file may be
19 * found in the file LICENSE in this distribution or at
20 * http://www.rtems.org/license/LICENSE.
21 */
22
23#include <bsp/tms570.h>
24#include <bsp/tms570-pinmux.h>
25#include <bsp/irq.h>
26
27uint32_t tms570_bsp_pinmmr_kick_key0 = 0x83E70B13U;
28uint32_t tms570_bsp_pinmmr_kick_key1 = 0x95A4F1E0U;
29
30/**
31 * @brief select desired function of pin/ball
32 *
33 * The function setups multiplexer to interconnect pin with
34 * specified function/peripheral. Pin number is index into pinmux
35 * entries array. Predefined values for pins are in a format
36 * TMS570_BALL_ \c column \c row (for example \c TMS570_BALL_N19).
37 * The multiplexer allows to interconnect one pin to multiple
38 * signal sources/sinks in the theory but it is usually bad choice.
39 * The function sets only specified function and clears all other
40 * connections.
41 *
42 * @param[in] pin_num  pin/ball identifier (index into pinmux array),
43 * @param[in] pin_fnc  function number 0 .. 7, if value \c TMS570_PIN_FNC_AUTO
44 *                     is specified then pin function is extracted from
45 *                     pin_num argument
46 * @retval Void
47 */
48void
49tms570_bsp_pin_set_function(int pin_num, int pin_fnc)
50{
51  unsigned int pin_shift;
52  volatile uint32_t *pinmmrx;
53
54  if ( pin_fnc == TMS570_PIN_FNC_AUTO ) {
55    pin_fnc = (pin_num & TMS570_PIN_FNC_MASK) >> TMS570_PIN_FNC_SHIFT;
56  }
57  tms570_bsp_pin_to_pinmmrx(&pinmmrx, &pin_shift, pin_num);
58  *pinmmrx = (*pinmmrx & ~(0xff << pin_shift)) | (1 << (pin_fnc + pin_shift));
59}
60
61/**
62 * @brief clear connection between pin and specified peripherals/function
63 *
64 * This function switches off given connection and leaves rest
65 * of multiplexer setup intact.
66 *
67 * @param[in] pin_num  pin/ball identifier (index into pinmux array)
68 * @param[in] pin_fnc  function number 0 .. 7, if value \c TMS570_PIN_FNC_AUTO
69 *                     is specified then pin function is extracted from
70 *                     pin_num argument
71 * @retval Void
72 */
73void
74tms570_bsp_pin_clear_function(int pin_num, int pin_fnc)
75{
76  unsigned int pin_shift;
77  volatile uint32_t *pinmmrx;
78
79  if ( pin_fnc == TMS570_PIN_FNC_AUTO ) {
80    pin_fnc = (pin_num & TMS570_PIN_FNC_MASK) >> TMS570_PIN_FNC_SHIFT;
81  }
82  tms570_bsp_pin_to_pinmmrx(&pinmmrx, &pin_shift, pin_num);
83  *pinmmrx = *pinmmrx & ~(1 << (pin_fnc+pin_shift));
84}
85
86/**
87 * @brief configure one pin according to its function specification
88 *
89 * The function setups multiplexer to interconnect pin with
90 * specified function/peripheral. Predefined values for pins combined with
91 * function are in a format TMS570_BALL_ \c column \c row \c function
92 * (for example \c TMS570_BALL_W3_SCIRX).
93 * If the function can be connected to more pins then specification
94 * includes infomation which allows to disconnect alternative pin to peripheral
95 * input connection or switch input multiplexer to right pin.
96 *
97 * @param[in] pin_num_and_fnc pin function descriptor is build by macro
98 *               \c TMS570_PIN_AND_FNC which takes pin/pinmmr specification
99 *               build by \c TMS570_BALL_WITH_MMR and function index in output
100 *               multiplexer. If the peripheral can be connected to other input
101 *               alternative then actual pin description and alternative to
102 *               disconnected/reconnect are combined together by
103 *               \c TMS570_PIN_WITH_IN_ALT macro. If clear of alternative
104 *               connection is required then flag \c TMS570_PIN_CLEAR_RQ_MASK
105 *               is ored to alternative description.
106 *
107 * @retval Void
108 */
109void
110tms570_bsp_pin_config_one(uint32_t pin_num_and_fnc)
111{
112  rtems_interrupt_level intlev;
113  uint32_t pin_in_alt;
114
115  rtems_interrupt_disable(intlev);
116
117  TMS570_IOMM.KICK_REG0 = tms570_bsp_pinmmr_kick_key0;
118  TMS570_IOMM.KICK_REG1 = tms570_bsp_pinmmr_kick_key1;
119
120  pin_in_alt = pin_num_and_fnc & TMS570_PIN_IN_ALT_MASK;
121  if ( pin_in_alt ) {
122    pin_in_alt >>= TMS570_PIN_IN_ALT_SHIFT;
123    if ( pin_in_alt & TMS570_PIN_CLEAR_RQ_MASK ) {
124      tms570_bsp_pin_clear_function(pin_in_alt, TMS570_PIN_FNC_AUTO);
125    } else {
126      tms570_bsp_pin_set_function(pin_in_alt, TMS570_PIN_FNC_AUTO);
127    }
128  }
129
130  pin_num_and_fnc &= TMS570_PIN_NUM_FNC_MASK;
131  if ( pin_num_and_fnc & TMS570_PIN_CLEAR_RQ_MASK ) {
132    tms570_bsp_pin_clear_function(pin_num_and_fnc, TMS570_PIN_FNC_AUTO);
133  } else {
134    tms570_bsp_pin_set_function(pin_num_and_fnc, TMS570_PIN_FNC_AUTO);
135  }
136
137  TMS570_IOMM.KICK_REG0 = 0;
138  TMS570_IOMM.KICK_REG1 = 0;
139
140  rtems_interrupt_enable(intlev);
141}
142
143/**
144 * @brief configure block or whole pin multiplexer
145 *
146 * Function change multiplexer content. It is intended for initial
147 * chip setup and does not use locking. If complete reconfiguration
148 * is required at runtime then it is application responsibility
149 * to protect and serialize change with peripherals drivers
150 * and parallel calls
151 *
152 * @param[in] pinmmr_values pointer to array with required multiplexer setup
153 * @param[in] reg_start starting register, this allows to configure non-consecutive
154 *                      registers groups found on some MCU family members
155 * @param[in] reg_count number of words in initialization array to set
156 *                      to corresponding registers
157 *
158 * @retval Void
159 */
160void
161tms570_bsp_pinmmr_config(const uint32_t *pinmmr_values, int reg_start, int reg_count)
162{
163  volatile uint32_t *pinmmrx;
164  const uint32_t *pval;
165  int cnt;
166
167  if ( reg_count <= 0)
168    return;
169
170  TMS570_IOMM.KICK_REG0 = tms570_bsp_pinmmr_kick_key0;
171  TMS570_IOMM.KICK_REG1 = tms570_bsp_pinmmr_kick_key1;
172
173  pinmmrx = (&TMS570_IOMM.PINMUX.PINMMR0) + reg_start;
174  pval = pinmmr_values;
175  cnt = reg_count;
176
177  do {
178    *pinmmrx = *pinmmrx & *pval;
179    pinmmrx++;
180    pval++;
181  } while( --cnt );
182
183  pinmmrx = (&TMS570_IOMM.PINMUX.PINMMR0) + reg_start;
184  pval = pinmmr_values;
185  cnt = reg_count;
186
187  do {
188    *pinmmrx = *pval;
189    pinmmrx++;
190    pval++;
191  } while( --cnt );
192
193  TMS570_IOMM.KICK_REG0 = 0;
194  TMS570_IOMM.KICK_REG1 = 0;
195}
Note: See TracBrowser for help on using the repository browser.