Back to home page

LXR

 
 

    


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

0001 /*
0002  * Copyright (c) 2013 Eugeniy Meshcheryakov <eugen@debian.org>
0003  *
0004  * The license and distribution terms for this file may be
0005  * found in the file LICENSE in this distribution or at
0006  * http://www.rtems.org/license/LICENSE.
0007  */
0008 
0009 #include <bsp/io.h>
0010 #include <bsp/lm3s69xx.h>
0011 #include <bsp/syscon.h>
0012 #include <rtems.h>
0013 
0014 static void set_bit(volatile uint32_t *reg, unsigned index, uint32_t set)
0015 {
0016   uint32_t mask = 1U;
0017   uint32_t val = *reg;
0018 
0019   val &= ~(mask << index);
0020   val |= set << index;
0021 
0022   *reg = val;
0023 }
0024 
0025 static void set_config(unsigned int pin, const lm3s69xx_gpio_config *config)
0026 {
0027   unsigned int port = LM3S69XX_GPIO_PORT_OF_PIN(pin);
0028   volatile lm3s69xx_gpio *gpio = LM3S69XX_GPIO(port);
0029   unsigned int index = LM3S69XX_GPIO_INDEX_OF_PIN(pin);
0030   rtems_interrupt_level level;
0031 
0032   rtems_interrupt_disable(level);
0033 
0034   lm3s69xx_syscon_enable_gpio_clock(port, true);
0035 
0036   /* Disable digital and analog functions before reconfiguration. */
0037   set_bit(&gpio->den, index, 0);
0038   set_bit(&gpio->amsel, index, 0);
0039 
0040   set_bit(&gpio->afsel, index, config->alternate);
0041   set_bit(&gpio->dir, index, config->dir);
0042   set_bit(&gpio->odr, index, config->otype);
0043 
0044   switch (config->drive) {
0045   case LM3S69XX_GPIO_DRIVE_4MA:
0046     gpio->dr4r |= 1 << index;
0047     break;
0048   case LM3S69XX_GPIO_DRIVE_8MA:
0049     gpio->dr8r |= 1 << index;
0050     break;
0051   default:
0052     gpio->dr2r |= 1 << index;
0053     break;
0054   }
0055 
0056   switch (config->pull) {
0057   case LM3S69XX_GPIO_PULL_UP:
0058     gpio->pur |= 1 << index;
0059     break;
0060   case LM3S69XX_GPIO_PULL_DOWN:
0061     gpio->pdr |= 1 << index;
0062     break;
0063   default:
0064     set_bit(&gpio->pdr, index, 0);
0065     set_bit(&gpio->pur, index, 0);
0066     break;
0067   }
0068 
0069   set_bit(&gpio->slr, index, config->slr);
0070 
0071   set_bit(&gpio->den, index, config->digital);
0072   set_bit(&gpio->amsel, index, config->analog);
0073 
0074   rtems_interrupt_enable(level);
0075 }
0076 
0077 void lm3s69xx_gpio_set_config(const lm3s69xx_gpio_config *config)
0078 {
0079   unsigned int current = config->pin_first;
0080   unsigned int last = config->pin_last;
0081 
0082   while (current <= last) {
0083     set_config(current, config);
0084     current++;
0085   }
0086 }
0087 
0088 void lm3s69xx_gpio_set_config_array(const lm3s69xx_gpio_config *configs, unsigned int count)
0089 {
0090   unsigned int i;
0091 
0092   for (i = 0; i < count; i++)
0093     lm3s69xx_gpio_set_config(&configs[i]);
0094 }
0095 
0096 /**
0097  * Enables/disables digital function on the specified pin.
0098  */
0099 void lm3s69xx_gpio_digital_enable(unsigned int pin, bool enable)
0100 {
0101   unsigned int port = LM3S69XX_GPIO_PORT_OF_PIN(pin);
0102   volatile lm3s69xx_gpio *gpio = LM3S69XX_GPIO(port);
0103   unsigned int index = LM3S69XX_GPIO_INDEX_OF_PIN(pin);
0104   rtems_interrupt_level level;
0105 
0106   rtems_interrupt_disable(level);
0107   set_bit(&gpio->den, index, enable);
0108   rtems_interrupt_enable(level);
0109 }
0110 
0111 /**
0112  * Enables/disables analog mode on the specified pin.
0113  */
0114 void lm3s69xx_gpio_analog_mode_select(unsigned int pin, bool enable)
0115 {
0116   unsigned int port = LM3S69XX_GPIO_PORT_OF_PIN(pin);
0117   volatile lm3s69xx_gpio *gpio = LM3S69XX_GPIO(port);
0118   unsigned int index = LM3S69XX_GPIO_INDEX_OF_PIN(pin);
0119   rtems_interrupt_level level;
0120 
0121   rtems_interrupt_disable(level);
0122   set_bit(&gpio->amsel, index, enable);
0123   rtems_interrupt_enable(level);
0124 }
0125 
0126 void lm3s69xx_gpio_set_pin(unsigned int pin, bool set)
0127 {
0128   unsigned int port = LM3S69XX_GPIO_PORT_OF_PIN(pin);
0129   volatile lm3s69xx_gpio *gpio = LM3S69XX_GPIO(port);
0130   unsigned int index = LM3S69XX_GPIO_INDEX_OF_PIN(pin);
0131   uint32_t mask = 1U << index;
0132 
0133   gpio->data[mask] = set ? mask : 0;
0134 }
0135 
0136 bool lm3s69xx_gpio_get_pin(unsigned int pin)
0137 {
0138   unsigned int port = LM3S69XX_GPIO_PORT_OF_PIN(pin);
0139   volatile lm3s69xx_gpio *gpio = LM3S69XX_GPIO(port);
0140   unsigned int index = LM3S69XX_GPIO_INDEX_OF_PIN(pin);
0141   uint32_t mask = 1U << index;
0142 
0143   return gpio->data[mask] != 0;
0144 }