source: rtems/bsps/arm/lpc24xx/start/io.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: 16.3 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/**
4 * @file
5 *
6 * @ingroup RTEMSBSPsARMLPC24XX_io
7 *
8 * @brief Input and output module.
9 */
10
11/*
12 * Copyright (C) 2009, 2012 embedded brains GmbH & Co. KG
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 * 1. Redistributions of source code must retain the above copyright
18 *    notice, this list of conditions and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright
20 *    notice, this list of conditions and the following disclaimer in the
21 *    documentation and/or other materials provided with the distribution.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 */
35
36#include <bsp.h>
37#include <bsp/io.h>
38#include <bsp/start.h>
39#include <bsp/system-clocks.h>
40
41#define LPC24XX_PIN_SELECT(index) ((index) >> 4U)
42
43#define LPC24XX_PIN_SELECT_SHIFT(index) (((index) & 0xfU) << 1U)
44
45#define LPC24XX_PIN_SELECT_MASK 0x3U
46
47rtems_status_code lpc24xx_gpio_config(
48  unsigned index,
49  lpc24xx_gpio_settings settings
50)
51{
52  if (index <= LPC24XX_IO_INDEX_MAX) {
53    rtems_interrupt_level level;
54    uint32_t port = LPC24XX_IO_PORT(index);
55    uint32_t port_bit = LPC24XX_IO_PORT_BIT(index);
56    uint32_t output = (settings & LPC24XX_GPIO_OUTPUT) != 0 ? 1U : 0U;
57    uint32_t resistor = settings & 0x3U;
58    #ifdef ARM_MULTILIB_ARCH_V4
59      uint32_t select = LPC24XX_PIN_SELECT(index);
60      uint32_t shift = LPC24XX_PIN_SELECT_SHIFT(index);
61
62      /* Get resistor flags */
63      switch (resistor) {
64        case LPC24XX_GPIO_RESISTOR_PULL_UP:
65          resistor = 0x0U;
66          break;
67        case LPC24XX_GPIO_RESISTOR_NONE:
68          resistor = 0x2U;
69          break;
70        case LPC24XX_GPIO_RESISTOR_PULL_DOWN:
71          resistor = 0x3U;
72          break;
73        default:
74          return RTEMS_INVALID_NUMBER;
75      }
76    #else
77      uint32_t iocon_mask = IOCON_HYS | IOCON_INV
78        | IOCON_SLEW | IOCON_OD | IOCON_FILTER;
79      uint32_t iocon = (settings & iocon_mask) | IOCON_ADMODE;
80      uint32_t iocon_invalid = settings & ~(iocon_mask | LPC24XX_GPIO_OUTPUT);
81
82      /* Get resistor flags */
83      switch (resistor) {
84        case LPC24XX_GPIO_RESISTOR_NONE:
85          resistor = IOCON_MODE(0);
86          break;
87        case LPC24XX_GPIO_RESISTOR_PULL_DOWN:
88          resistor = IOCON_MODE(1);
89          break;
90        case LPC24XX_GPIO_RESISTOR_PULL_UP:
91          resistor = IOCON_MODE(2);
92          break;
93        case LPC17XX_GPIO_HYSTERESIS:
94          resistor = IOCON_MODE(3);
95          break;
96      }
97      iocon |= resistor;
98
99      if (iocon_invalid != 0) {
100        return RTEMS_INVALID_NUMBER;
101      }
102
103      if (output && (settings & LPC17XX_GPIO_INPUT_INVERT) != 0) {
104        return RTEMS_INVALID_NUMBER;
105      }
106
107      if ((settings & LPC17XX_GPIO_INPUT_FILTER) == 0) {
108        iocon |= IOCON_FILTER;
109      } else {
110        iocon &= ~IOCON_FILTER;
111      }
112    #endif
113
114    rtems_interrupt_disable(level);
115
116    #ifdef ARM_MULTILIB_ARCH_V4
117      /* Resistor */
118      LPC24XX_PINMODE [select] =
119        (LPC24XX_PINMODE [select] & ~(LPC24XX_PIN_SELECT_MASK << shift))
120          | ((resistor & LPC24XX_PIN_SELECT_MASK) << shift);
121    #else
122      LPC17XX_IOCON [index] = iocon;
123    #endif
124
125    rtems_interrupt_flash(level);
126
127    /* Input or output */
128    LPC24XX_FIO [port].dir =
129      (LPC24XX_FIO [port].dir & ~(1U << port_bit)) | (output << port_bit);
130
131    rtems_interrupt_enable(level);
132  } else {
133    return RTEMS_INVALID_ID;
134  }
135
136  return RTEMS_SUCCESSFUL;
137}
138
139#define LPC24XX_MODULE_ENTRY(mod, pwr, clk, idx) \
140  [mod] = { \
141    .power = pwr, \
142    .clock = clk, \
143    .index = idx \
144  }
145
146typedef struct {
147  unsigned char power : 1;
148  unsigned char clock : 1;
149  unsigned char index : 6;
150} lpc24xx_module_entry;
151
152static const lpc24xx_module_entry lpc24xx_module_table [] = {
153  #ifdef ARM_MULTILIB_ARCH_V4
154    LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_ACF, 0, 1, 15),
155  #endif
156  LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_ADC, 1, 1, 12),
157  #ifdef ARM_MULTILIB_ARCH_V4
158    LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_BAT_RAM, 0, 1, 16),
159  #endif
160  LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_CAN_0, 1, 1, 13),
161  LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_CAN_1, 1, 1, 14),
162  LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_DAC, 0, 1, 11),
163  LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_EMC, 1, 0, 11),
164  LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_ETHERNET, 1, 0, 30),
165  LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_GPDMA, 1, 1, 29),
166  #ifdef ARM_MULTILIB_ARCH_V4
167    LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_GPIO, 0, 1, 17),
168  #else
169    LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_GPIO, 0, 1, 15),
170  #endif
171  LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_I2C_0, 1, 1, 7),
172  LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_I2C_1, 1, 1, 19),
173  LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_I2C_2, 1, 1, 26),
174  LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_I2S, 1, 1, 27),
175  #ifdef ARM_MULTILIB_ARCH_V4
176    LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_LCD, 1, 0, 20),
177  #else
178    LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_LCD, 1, 0, 0),
179  #endif
180  LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_MCI, 1, 1, 28),
181  #ifdef ARM_MULTILIB_ARCH_V7M
182    LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_MCPWM, 1, 1, 17),
183  #endif
184  LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_PCB, 0, 1, 18),
185  LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_PWM_0, 1, 1, 5),
186  LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_PWM_1, 1, 1, 6),
187  #ifdef ARM_MULTILIB_ARCH_V7M
188    LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_QEI, 1, 1, 18),
189  #endif
190  LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_RTC, 1, 1, 9),
191  #ifdef ARM_MULTILIB_ARCH_V4
192    LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_SPI, 1, 1, 8),
193  #endif
194  LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_SSP_0, 1, 1, 21),
195  LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_SSP_1, 1, 1, 10),
196  #ifdef ARM_MULTILIB_ARCH_V7M
197    LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_SSP_2, 1, 1, 20),
198  #endif
199  LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_SYSCON, 0, 1, 30),
200  LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_TIMER_0, 1, 1, 1),
201  LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_TIMER_1, 1, 1, 2),
202  LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_TIMER_2, 1, 1, 22),
203  LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_TIMER_3, 1, 1, 23),
204  LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_UART_0, 1, 1, 3),
205  LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_UART_1, 1, 1, 4),
206  LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_UART_2, 1, 1, 24),
207  LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_UART_3, 1, 1, 25),
208  #ifdef ARM_MULTILIB_ARCH_V7M
209    LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_UART_4, 1, 1, 8),
210  #endif
211  #ifdef ARM_MULTILIB_ARCH_V4
212    LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_WDT, 0, 1, 0),
213  #endif
214  LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_USB, 1, 0, 31)
215};
216
217static rtems_status_code lpc24xx_module_do_enable(
218  lpc24xx_module module,
219  lpc24xx_module_clock clock,
220  bool enable
221)
222{
223  rtems_interrupt_level level;
224  bool has_power = false;
225  bool has_clock = false;
226  unsigned index = 0;
227  #ifdef ARM_MULTILIB_ARCH_V7M
228    volatile lpc17xx_scb *scb = &LPC17XX_SCB;
229  #endif
230
231  if ((unsigned) module >= LPC24XX_MODULE_COUNT) {
232      return RTEMS_INVALID_ID;
233  }
234
235  #ifdef ARM_MULTILIB_ARCH_V4
236    if (clock == LPC24XX_MODULE_PCLK_DEFAULT) {
237      #if LPC24XX_PCLKDIV == 1U
238        clock = LPC24XX_MODULE_CCLK;
239      #elif LPC24XX_PCLKDIV == 2U
240        clock = LPC24XX_MODULE_CCLK_2;
241      #elif LPC24XX_PCLKDIV == 4U
242        clock = LPC24XX_MODULE_CCLK_4;
243      #elif LPC24XX_PCLKDIV == 8U
244        clock = LPC24XX_MODULE_CCLK_8;
245      #endif
246    }
247
248    if ((clock & ~LPC24XX_MODULE_CLOCK_MASK) != 0U) {
249      return RTEMS_INVALID_CLOCK;
250    }
251  #else
252    if (clock != LPC24XX_MODULE_PCLK_DEFAULT) {
253      return RTEMS_INVALID_CLOCK;
254    }
255  #endif
256
257  has_power = lpc24xx_module_table [module].power;
258  has_clock = lpc24xx_module_table [module].clock;
259  index = lpc24xx_module_table [module].index;
260
261  /* Enable or disable module */
262  if (enable) {
263    if (has_power) {
264      rtems_interrupt_disable(level);
265      #ifdef ARM_MULTILIB_ARCH_V4
266        PCONP |= 1U << index;
267      #else
268        scb->pconp |= 1U << index;
269      #endif
270      rtems_interrupt_enable(level);
271    }
272
273    if (module != LPC24XX_MODULE_USB) {
274      if (has_clock) {
275        #ifdef ARM_MULTILIB_ARCH_V4
276          unsigned clock_shift = 2U * index;
277
278          rtems_interrupt_disable(level);
279          if (clock_shift < 32U) {
280            PCLKSEL0 = (PCLKSEL0 & ~(LPC24XX_MODULE_CLOCK_MASK << clock_shift))
281                | (clock << clock_shift);
282          } else {
283            clock_shift -= 32U;
284            PCLKSEL1 = (PCLKSEL1 & ~(LPC24XX_MODULE_CLOCK_MASK << clock_shift))
285                | (clock << clock_shift);
286          }
287          rtems_interrupt_enable(level);
288        #endif
289      }
290    } else {
291      #ifdef ARM_MULTILIB_ARCH_V4
292        unsigned pllclk = lpc24xx_pllclk();
293        unsigned usbsel = pllclk / 48000000U - 1U;
294
295        if (
296          usbsel > 15U
297            || (usbsel % 2U != 1U)
298            || (pllclk % 48000000U) != 0U
299        ) {
300          return RTEMS_INCORRECT_STATE;
301        }
302
303        USBCLKCFG = usbsel;
304      #else
305        uint32_t pllclk = lpc24xx_pllclk();
306        uint32_t usbclk = 48000000U;
307
308        if (pllclk % usbclk == 0U) {
309          uint32_t usbdiv = pllclk / usbclk;
310
311          scb->usbclksel = LPC17XX_SCB_USBCLKSEL_USBDIV(usbdiv)
312            | LPC17XX_SCB_USBCLKSEL_USBSEL(1);
313        } else {
314          return RTEMS_INCORRECT_STATE;
315        }
316      #endif
317    }
318  } else {
319    if (has_power) {
320      rtems_interrupt_disable(level);
321      #ifdef ARM_MULTILIB_ARCH_V4
322        PCONP &= ~(1U << index);
323      #else
324        scb->pconp &= ~(1U << index);
325      #endif
326      rtems_interrupt_enable(level);
327    }
328  }
329
330  return RTEMS_SUCCESSFUL;
331}
332
333rtems_status_code lpc24xx_module_enable(
334  lpc24xx_module module,
335  lpc24xx_module_clock clock
336)
337{
338  return lpc24xx_module_do_enable(module, clock, true);
339}
340
341rtems_status_code lpc24xx_module_disable(
342  lpc24xx_module module
343)
344{
345  return lpc24xx_module_do_enable(
346    module,
347    LPC24XX_MODULE_PCLK_DEFAULT,
348    false
349  );
350}
351
352bool lpc24xx_module_is_enabled(lpc24xx_module module)
353{
354  bool enabled = false;
355
356  if ((unsigned) module < LPC24XX_MODULE_COUNT) {
357    bool has_power = lpc24xx_module_table [module].power;
358
359    if (has_power) {
360      unsigned index = lpc24xx_module_table [module].index;
361      #ifdef ARM_MULTILIB_ARCH_V4
362        uint32_t pconp = PCONP;
363      #else
364        uint32_t pconp = LPC17XX_SCB.pconp;
365      #endif
366
367      enabled = (pconp & (1U << index)) != 0;
368    } else {
369      enabled = true;
370    }
371  }
372
373  return enabled;
374}
375
376typedef rtems_status_code (*lpc24xx_pin_visitor)(
377  #ifdef ARM_MULTILIB_ARCH_V4
378    volatile uint32_t *pinsel,
379    uint32_t pinsel_mask,
380    uint32_t pinsel_value,
381  #else
382    volatile uint32_t *iocon,
383    lpc24xx_pin_range pin_range,
384  #endif
385  volatile uint32_t *fio_dir,
386  uint32_t fio_bit
387);
388
389static BSP_START_TEXT_SECTION __attribute__((flatten)) rtems_status_code
390lpc24xx_pin_set_function(
391  #ifdef ARM_MULTILIB_ARCH_V4
392    volatile uint32_t *pinsel,
393    uint32_t pinsel_mask,
394    uint32_t pinsel_value,
395  #else
396    volatile uint32_t *iocon,
397    lpc24xx_pin_range pin_range,
398  #endif
399  volatile uint32_t *fio_dir,
400  uint32_t fio_bit
401)
402{
403  #ifdef ARM_MULTILIB_ARCH_V4
404    rtems_interrupt_level level;
405
406    rtems_interrupt_disable(level);
407    *pinsel = (*pinsel & ~pinsel_mask) | pinsel_value;
408    rtems_interrupt_enable(level);
409  #else
410    uint32_t iocon_extra = 0;
411    uint32_t iocon_not_analog = IOCON_ADMODE;
412
413    /* TODO */
414    switch (pin_range.fields.type) {
415      case LPC17XX_PIN_TYPE_ADC:
416      case LPC17XX_PIN_TYPE_DAC:
417        iocon_not_analog = 0;
418        break;
419      case LPC17XX_PIN_TYPE_I2C_FAST_PLUS:
420        iocon_extra |= IOCON_HS;
421        break;
422      case LPC17XX_PIN_TYPE_OPEN_DRAIN:
423        iocon_extra |= IOCON_OD;
424        break;
425      case LPC17XX_PIN_TYPE_FAST_SLEW_RATE:
426        iocon_extra |= IOCON_SLEW;
427        break;
428      default:
429        break;
430    }
431
432    *iocon = IOCON_FUNC(pin_range.fields.function) | iocon_extra | iocon_not_analog;
433  #endif
434
435  return RTEMS_SUCCESSFUL;
436}
437
438static BSP_START_TEXT_SECTION rtems_status_code lpc24xx_pin_check_function(
439  #ifdef ARM_MULTILIB_ARCH_V4
440    volatile uint32_t *pinsel,
441    uint32_t pinsel_mask,
442    uint32_t pinsel_value,
443  #else
444    volatile uint32_t *iocon,
445    lpc24xx_pin_range pin_range,
446  #endif
447  volatile uint32_t *fio_dir,
448  uint32_t fio_bit
449)
450{
451  #ifdef ARM_MULTILIB_ARCH_V4
452    if ((*pinsel & pinsel_mask) == pinsel_value) {
453      return RTEMS_SUCCESSFUL;
454    } else {
455      return RTEMS_IO_ERROR;
456    }
457  #else
458    /* TODO */
459    return RTEMS_IO_ERROR;
460  #endif
461}
462
463static BSP_START_TEXT_SECTION __attribute__((flatten)) rtems_status_code
464lpc24xx_pin_set_input(
465  #ifdef ARM_MULTILIB_ARCH_V4
466    volatile uint32_t *pinsel,
467    uint32_t pinsel_mask,
468    uint32_t pinsel_value,
469  #else
470    volatile uint32_t *iocon,
471    lpc24xx_pin_range pin_range,
472  #endif
473  volatile uint32_t *fio_dir,
474  uint32_t fio_bit
475)
476{
477  rtems_interrupt_level level;
478
479  rtems_interrupt_disable(level);
480  *fio_dir &= ~fio_bit;
481  #ifdef ARM_MULTILIB_ARCH_V4
482    *pinsel &= ~pinsel_mask;
483  #else
484    *iocon = IOCON_MODE(2) | IOCON_ADMODE | IOCON_FILTER;
485  #endif
486  rtems_interrupt_enable(level);
487
488  return RTEMS_SUCCESSFUL;
489}
490
491static BSP_START_TEXT_SECTION rtems_status_code lpc24xx_pin_check_input(
492  #ifdef ARM_MULTILIB_ARCH_V4
493    volatile uint32_t *pinsel,
494    uint32_t pinsel_mask,
495    uint32_t pinsel_value,
496  #else
497    volatile uint32_t *iocon,
498    lpc24xx_pin_range pin_range,
499  #endif
500  volatile uint32_t *fio_dir,
501  uint32_t fio_bit
502)
503{
504  rtems_status_code sc = RTEMS_IO_ERROR;
505  bool is_input = (*fio_dir & fio_bit) == 0;
506
507  if (is_input) {
508    #ifdef ARM_MULTILIB_ARCH_V4
509      bool is_gpio = (*pinsel & pinsel_mask) == 0;
510    #else
511      bool is_gpio = IOCON_FUNC_GET(*iocon) == 0;
512    #endif
513
514    if (is_gpio) {
515      sc = RTEMS_SUCCESSFUL;
516    }
517  }
518
519  return sc;
520}
521
522static BSP_START_DATA_SECTION const lpc24xx_pin_visitor
523  lpc24xx_pin_visitors [] = {
524  [LPC24XX_PIN_SET_FUNCTION] = lpc24xx_pin_set_function,
525  [LPC24XX_PIN_CHECK_FUNCTION] = lpc24xx_pin_check_function,
526  [LPC24XX_PIN_SET_INPUT] = lpc24xx_pin_set_input,
527  [LPC24XX_PIN_CHECK_INPUT] = lpc24xx_pin_check_input
528};
529
530BSP_START_TEXT_SECTION rtems_status_code lpc24xx_pin_config(
531  const lpc24xx_pin_range *pins,
532  lpc24xx_pin_action action
533)
534{
535  rtems_status_code sc = RTEMS_SUCCESSFUL;
536
537  if ((unsigned) action <= LPC24XX_PIN_CHECK_INPUT) {
538    lpc24xx_pin_visitor visitor = lpc24xx_pin_visitors [action];
539    lpc24xx_pin_range terminal = LPC24XX_PIN_TERMINAL;
540    lpc24xx_pin_range pin_range = *pins;
541    uint32_t previous_port_bit = pin_range.fields.port_bit;
542
543    while (sc == RTEMS_SUCCESSFUL && pin_range.value != terminal.value) {
544      uint32_t port = pin_range.fields.port;
545      uint32_t port_bit = pin_range.fields.port_bit;
546      uint32_t port_bit_last = port_bit;
547      uint32_t range = pin_range.fields.range;
548      #ifdef ARM_MULTILIB_ARCH_V4
549        uint32_t function = pin_range.fields.function;
550      #endif
551      volatile uint32_t *fio_dir = &LPC24XX_FIO [port].dir;
552
553      if (range) {
554        port_bit = previous_port_bit;
555      }
556
557      while (sc == RTEMS_SUCCESSFUL && port_bit <= port_bit_last) {
558        uint32_t index = LPC24XX_IO_INDEX_BY_PORT(port, port_bit);
559        uint32_t fio_bit = 1U << port_bit;
560        #ifdef ARM_MULTILIB_ARCH_V4
561          uint32_t select = LPC24XX_PIN_SELECT(index);
562          uint32_t shift = LPC24XX_PIN_SELECT_SHIFT(index);
563          volatile uint32_t *pinsel = &LPC24XX_PINSEL [select];
564          uint32_t pinsel_mask = LPC24XX_PIN_SELECT_MASK << shift;
565          uint32_t pinsel_value = (function & LPC24XX_PIN_SELECT_MASK) << shift;
566
567          sc = (*visitor)(pinsel, pinsel_mask, pinsel_value, fio_dir, fio_bit);
568        #else
569          volatile uint32_t *iocon = &LPC17XX_IOCON [index];
570
571          sc = (*visitor)(iocon, pin_range, fio_dir, fio_bit);
572        #endif
573
574        ++port_bit;
575      }
576
577      ++pins;
578      previous_port_bit = port_bit;
579      pin_range = *pins;
580    }
581  } else {
582    sc = RTEMS_NOT_DEFINED;
583  }
584
585  return sc;
586}
Note: See TracBrowser for help on using the repository browser.