Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1153007
  • 博文数量: 222
  • 博客积分: 5262
  • 博客等级: 大校
  • 技术积分: 3028
  • 用 户 组: 普通用户
  • 注册时间: 2009-11-22 19:10
文章分类

全部博文(222)

文章存档

2012年(2)

2011年(192)

2010年(28)

分类: 嵌入式

2011-05-11 15:44:53

由于公司的IP camera使用的是mx27(19内核),设计到7113的移植,移植过程中出现了GPIO口配置错误。所以对其GPIO口和7113所使用GPIO口 进行了分析,刚开始对mx27对于GPIO口的使用,和内核中关于GPIO口的配置方法不是很熟悉,在论坛发帖也没人回,这里做个简单总结。

mx27的GPIO口一共有6个端口,每个端口有32个引脚。看源码:

#define MUX_IO_P 29

#define MUX_IO_I 24

#define _MX27_BUILD_PIN(gp,gi)   (((gp) << MUX_IO_P) | ((gi) << MUX_IO_I))

开始对于前两个宏的定义不是很理解,虽然内核注释中写明,一个用于索引GPIO的端口,一个用于在指定端口进行偏移,但是为什么一个是29一个是23,不解.

第三个宏就是找到指定的GPIO引脚。例如对于端口2的21引脚,如下索引:

#define _MX27_BUILD_PIN(1,21)   ((1<

源码中定义了一个枚举完成对所有GPIO的功能索引:

typedef enum iomux_pins {

    ......

  MX27_PIN_CSI_D0 = _MX27_BUILD_PIN(1, 10),
  MX27_PIN_CSI_D1 = _MX27_BUILD_PIN(1, 11),
  MX27_PIN_CSI_D2 = _MX27_BUILD_PIN(1, 12),
  MX27_PIN_CSI_D3 = _MX27_BUILD_PIN(1, 13),
  MX27_PIN_CSI_D4 = _MX27_BUILD_PIN(1, 14),
  MX27_PIN_CSI_MCLK = _MX27_BUILD_PIN(1, 15),
  MX27_PIN_CSI_PIXCLK = _MX27_BUILD_PIN(1, 16),
  MX27_PIN_CSI_D5 = _MX27_BUILD_PIN(1, 17),
  MX27_PIN_CSI_D6 = _MX27_BUILD_PIN(1, 18),
  MX27_PIN_CSI_D7 = _MX27_BUILD_PIN(1, 19),
  MX27_PIN_CSI_VSYNC = _MX27_BUILD_PIN(1, 20),
  MX27_PIN_CSI_HSYNC = _MX27_BUILD_PIN(1, 21),

 ........

}

只贴出了与摄像头功能匹配的部分。

MX27_PIN_CSI_D2 = _MX27_BUILD_PIN(1, 12),
是为了将port 2的pin 12定义为CSI_D2,查看第5章的Pin MUX Table:

                                   Primary                   Alternate                              GPIO                          default

NVDD   11   Slow/Hyst   CSI_D2  I        UART6_CTS   O          PB12   PUEN   LCDC_TEST8         PB12

可见需要将1,12设置为primary功能,与功能描述一致,可见理解是正确的。

为了将1,12(及portB的12端口)设置为primary功能可以用一下方法:

gpio_request_mux(MX27_PIN_CSI_D2, GPIO_MUX_PRIMARY);

gpio_request_mux的实现:

int gpio_request_mux(iomux_pin_name_t pin, gpio_mux_mode_t mode)
{
 int ret;
 ret = mxc_request_gpio(pin);
 if (ret == 0) {
  ret = gpio_config_mux(pin, mode);
  if (ret) {
   mxc_free_gpio(pin);
  }
 }
 return ret;
}

函数中首先调用mxc_request_gpio来完成对对用pin的申请,只有在申请成功(返回为零时)才调用gpio_config_mux来完成对pin的功能配置。

mxc_request_gpio源码:

int mxc_request_gpio(iomux_pin_name_t pin)
{
 struct gpio_port *port;
 u32 index, gpio = IOMUX_TO_GPIO(pin);

 if (check_gpio(gpio) < 0)
  return -EINVAL;

 port = get_gpio_port(gpio);            //得到gpio的端口号
 index = GPIO_TO_INDEX(gpio);      //得到gpio口在对应端口的索引号

 return _request_gpio(port, index);
}

具体功能的实现在_request_gpio中:

static inline int _request_gpio(struct gpio_port *port, u32 index)
{
 spin_lock(&port->lock);
 if (port->reserved_map & (1 << index)) {
  printk(KERN_ERR
         "GPIO port %d (0-based), pin %d is already reserved!\n",
         port->num, index);
  dump_stack();
  spin_unlock(&port->lock);
  return -1;
 }
 port->reserved_map |= (1 << index);
 spin_unlock(&port->lock);
 return 0;
}

其中port结构体中的reserved_map存放着对应pin的状态,表明pin是否已经被占用。这里需要注意的是reserved_map为 1时表示该pin为保留管脚,不能被使用。如果未保留则申请成功返回零,同时设置reserved_map的值为1.也即当打印出如下信息时:

GPIO port %d (0-based), pin %d is already reserved!  表示该pin不可用。
struct gpio_port {
 u32 num;  /*!< gpio port number */
 u32 base;  /*!< gpio port base VA */
 u16 irq;  /*!< irq number to the core */
 u16 virtual_irq_start; /*!< virtual irq start number */
 u32 reserved_map; /*!< keep track of which pins are in use */
 u32 irq_is_level_map; /*!< if a pin's irq is level sensitive. default is edge */
 spinlock_t lock; /*!< lock when operating on the port */
};

通过学习,解决了7113在19内核的移植问题。

阅读(1492) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~