免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 650 | 回复: 3
打印 上一主题 下一主题

[嵌入式] PIO [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-12-06 11:59 |只看该作者 |倒序浏览
要实现一个LED的状态显示灯(显示系统状态的),文档上是对PIOA进行操作,但是目前不知道如何在C中实现它,读源代一点头续都没有,可以说是看不明白或者找不着在什么地方有相关的操作,请帮忙指点一下.

论坛徽章:
0
2 [报告]
发表于 2006-12-06 13:01 |只看该作者
楼主给的信息量太少了啊,说说PIOA是什么啊,寄存器名吗?有代码的话贴上来给大家看看啊。

论坛徽章:
2
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015元宵节徽章
日期:2015-03-06 15:50:39
3 [报告]
发表于 2006-12-06 13:11 |只看该作者

以前写的一个简单的Led驱动 希望对你有用

  1.   //*****************************************************   
  2. //编译进内核的程序,实现驱动程序的注册和对数码管的控制  //*****************************************************   
  3. #include <linux/types.h>  
  4. #include <linux/errno.h>  
  5. #include <linux/miscdevice.h>  
  6. #include <linux/slab.h>  
  7. #include <linux/ioport.h>  
  8. #include <linux/fcntl.h>  
  9. #include <linux/mc146818rtc.h>  
  10. #include <linux/netdevice.h>  
  11. #include <linux/sched.h>   
  12. #include <asm/io.h>  
  13. #include <asm/uaccess.h>  
  14. #include <asm/system.h>  
  15. #include <linux/delay.h>   
  16. /*定义External I/O control register*/  
  17. #define EXT1CON                 0XFFF0101C    /*定义External I/O基地址*/  
  18. #define EXT1BANK                0XC6040000   
  19. void sleep(int i);   
  20. /*实现LED设备的写操作*/  static int  led_write(struct inode *inode,struct file *file,int n);   
  21. /*实现LED设备的打开操作*/  static int  led_open(struct inode *inode,struct file *file );   
  22. /*标志着LED设备是否打开,默认为打开*/  
  23. static int led_opened = 1;   
  24. /*定义数码管上显示0到9时对应的向External I/O写入的数据*/  
  25. #define DIGIT_9         0x90   
  26. #define DIGIT_8         0x80   
  27. #define DIGIT_7         0xF8  
  28. #define DIGIT_6         0X82   
  29. #define DIGIT_5         0X92   
  30. #define DIGIT_4         0X99   
  31. #define DIGIT_3         0XB0   
  32. #define DIGIT_2         0XA4   
  33. #define DIGIT_1         0XF9   
  34. #define DIGIT_0         0XC0      
  35. /*将对低层的操作映射为对文件的操作*/  
  36. static struct file_operations led_fops = {      
  37. open:                 led_open,         
  38. write:            led_write,   };            
  39. /*完成对LED驱动设备的注册*/  
  40. int led_init(void)   {  
  41. int result;         
  42. result=register_chrdev(253, "myled", &led_fops);        
  43. return(result);  
  44. }   
  45. void sleep(int i)  {            
  46. int b;                    
  47. for( b = 0 ; b <1000000*i ; b++ )            
  48. ( )        ;  
  49. }   
  50. /*打开设备为I/O寄存器符赋值*/  
  51. static int  led_open(struct inode *inode,struct file *file)  {           
  52. * ((volatile unsigned int *)EXT1CON) = 0x8C087FFE;      
  53. if(!led_opened)       {         
  54. return -ENXIO;      
  55. }else{
  56. return 0;        
  57. }   
  58. }   
  59. /*为External I/O赋值,实现LED设备的写操作*/  
  60. static int  led_write(struct inode *inode,struct file *file,int n)  {        
  61. unsigned int tmp ,i;               
  62. unsigned int ctrl [] = { DIGIT_0, DIGIT_1, DIGIT_2, DIGIT_3, DIGIT_4, DIGIT_5, DIGIT_6, DIGIT_7, DIGIT_8, DIGIT_9};                                       
  63. if( (n>=0) && (n<(sizeof(ctrl)/sizeof(unsigned char))) )          {            
  64. tmp = 0;              
  65. for(i = 0;i<4;i++)              {                   
  66. tmp <<= 8;                  
  67. tmp += ctrl[n];                             
  68. }
  69. *((volatile unsigned int *)EXT1BANK )= tmp;                 
  70. }  
  71. }   
复制代码

[ 本帖最后由 crazyCat 于 2006-12-6 13:17 编辑 ]

论坛徽章:
0
4 [报告]
发表于 2006-12-06 13:19 |只看该作者
我是个新手,这几天在接手移植一块板子,这是我参照的一个板子,对GPIO的操作,不过我有些看不明白,即使参照它的手册也是不明白,我想在这里找一些线索,不过没有头绪啊.感觉笨得要死.新板子上的灯是对四个PIO引进行操作.


  1. #define AT91_PIOA       0x400
  2. #define AT91_PIOB       0x600
  3. #define AT91_PIOC       0x800

  4. static const u32 pio_controller_offset[4] = {
  5.         AT91_PIOA,   
  6.         AT91_PIOB,
  7.         AT91_PIOC,
  8. };


  9. /*--------------------------------------------------------------------------*/

  10. /* Not all hardware capabilities are exposed through these calls; they
  11. * only encapsulate the most common features and modes.  (So if you
  12. * want to change signals in groups, do it directly.)
  13. *
  14. * Bootloaders will usually handle some of the pin multiplexing setup.
  15. * The intent is certainly that by the time Linux is fully booted, all
  16. * pins should have been fully initialized.  These setup calls should
  17. * only be used by board setup routines, or possibly in driver probe().
  18. *
  19. * For bootloaders doing all that setup, these calls could be inlined
  20. * as NOPs so Linux won't duplicate any setup code
  21. */


  22. /*
  23. * mux the pin to the corresponding internal peripheral role.
  24. */


  25. void at91_gpio_periph_enable (unsigned int pio_va_base,
  26.                               unsigned char pin,
  27.                               unsigned char peripheral,
  28.                               unsigned char use_pullup,
  29.                               unsigned char use_filter)
  30. {
  31.         unsigned int mask = pin_to_mask(pin);

  32.         writel(mask, (pio_va_base + PIO_IDR));       

  33.         if(use_pullup)
  34.                 writel(mask, (pio_va_base + PIO_PPUER));
  35.         else
  36.                 writel(mask, (pio_va_base + PIO_PPUDR));

  37.         switch (peripheral)
  38.         {
  39.                 case 1:
  40.                         writel(mask, (pio_va_base + PIO_BSR));
  41.                 break;
  42.                 case 0:
  43.                 default:
  44.                         writel(mask, (pio_va_base + PIO_ASR));
  45.                 break;
  46.         }

  47.         /* The Peripheral controls the pin (pio disabled) */
  48.         writel(mask, (pio_va_base + PIO_PDR));
  49. }


  50. EXPORT_SYMBOL(at91_gpio_periph_enable);

  51. void at91_gpio_configure (unsigned int pio_va_base,
  52.                           unsigned char pin,
  53.                           unsigned char in_out,
  54.                           unsigned char use_pullup,
  55.                           unsigned char use_filter)
  56. {
  57.         unsigned int mask = pin_to_mask(pin);
  58.        
  59.         /* The PIO controls the pin (periph disabled) */
  60.         writel(mask, (pio_va_base + PIO_PER));

  61.         if(in_out) { /* the pin is an input */
  62.                 writel(mask, (pio_va_base + PIO_ODR));
  63.         }
  64.         else {       /* the pin is an output */
  65.                 writel(mask, (pio_va_base + PIO_OER));
  66.         }

  67.         if(use_pullup)
  68.                 writel(mask, (pio_va_base + PIO_PPUER));
  69.         else
  70.                 writel(mask, (pio_va_base + PIO_PPUDR));
  71. }


  72. EXPORT_SYMBOL(at91_gpio_configure);

  73. void at91_gpio_set_level (unsigned int pio_va_base, unsigned int pin, unsigned int level)
  74. {
  75.         unsigned int mask = pin_to_mask(pin);

  76.         // This is just a sanity action to force a pin
  77.         // to output before driving it.
  78.         writel(mask, pio_va_base + PIO_PER);
  79.         writel(mask, pio_va_base + PIO_OER);
  80.        
  81.         if (level)
  82.           writel(mask, pio_va_base + PIO_SODR);
  83.         else // pin should be cleared
  84.           writel(mask, pio_va_base + PIO_CODR);

  85. }


  86. EXPORT_SYMBOL(at91_gpio_set_level);

  87. unsigned int at91_gpio_get_level (unsigned int pio_va_base, unsigned int pin)
  88. {
  89.         unsigned int mask = pin_to_mask(pin);


  90.         // This is just a sanity action to force a pin
  91.         // to input before reading it.
  92.         writel(mask, pio_va_base + PIO_PER);
  93.         writel(mask, pio_va_base + PIO_ODR);

  94.         return (readl(pio_va_base + PIO_PDSR) & mask);
  95. }


  96. EXPORT_SYMBOL(at91_gpio_get_level);


  97. int at91_device_pio_setup (struct at91_pioline *pPin) {

  98.         if(!pPin) {
  99.                 printk(KERN_ERR "Define the PIO muxing of this device first !!\n");
  100.                 return -ENODEV;
  101.         }

  102.         /* Sets all the pio muxing of the corresponding device as defined in its platform_data struct */
  103.         while (pPin->pin_name)
  104.         {
  105.                 if ((pPin->pio_ctrl_id != AT91C_ID_PIOA) &&
  106.                     (pPin->pio_ctrl_id != AT91C_ID_PIOB) &&
  107.                     (pPin->pio_ctrl_id != AT91C_ID_PIOC)) {
  108.                         printk(KERN_ERR "Bad PIO controler ID %u, correct values are {%u, %u ,%u}\n",
  109.                                pPin->pio_ctrl_id, AT91C_ID_PIOA, AT91C_ID_PIOB, AT91C_ID_PIOC);
  110.                         return -ENODEV;
  111.                 }
  112.                 if (pPin->type == TYPE_PERIPH) // PIN is in PERIPH mode
  113.                         at91_gpio_periph_enable(pPin->pio_ctrl_va_base, pPin->pin_num, pPin->direction, pPin->use_pullup, pPin->use_filter);
  114.                 else // PIN is in PIO mode
  115.                         at91_gpio_configure(pPin->pio_ctrl_va_base, pPin->pin_num, pPin->direction, pPin->use_pullup, pPin->use_filter);
  116.                 pPin++;
  117.         }

  118.         return 0;
  119. }

  120. EXPORT_SYMBOL(at91_device_pio_setup);

  121. static inline void __iomem *pin_to_controller(unsigned pin)
  122. {
  123.         void __iomem *sys_base = (void __iomem *) AT91C_VA_BASE_SYS;

  124.         pin -= PIN_BASE;
  125.         pin /= 32;
  126.         return sys_base + pio_controller_offset[pin];

  127.         return NULL;
  128. }

  129. static inline unsigned pin_to_mask_o(unsigned pin)
  130. {
  131.         pin -= PIN_BASE;
  132.         return 1 << (pin % 32);
  133. }

  134. /*
  135. * read the pin's value (works even if it's not muxed as a gpio).
  136. */
  137. int at91_get_gpio_value(unsigned pin)
  138. {
  139.         void __iomem    *pio = pin_to_controller(pin);
  140.         unsigned        mask = pin_to_mask_o(pin);
  141.         u32             pdsr;

  142.         if (!pio)
  143.                 return -EINVAL;
  144.         pdsr = __raw_readl(pio + PIO_PDSR);
  145.         return (pdsr & mask) != 0;
  146. }
  147. EXPORT_SYMBOL(at91_get_gpio_value);

  148. /*--------------------------------------------------------------------------*/


  149. /* Several AIC controller irqs are dispatched through this GPIO handler.
  150. * To use any AT91_PIN_* as an externally triggered IRQ, first call
  151. * at91_set_gpio_input() then maybe enable its glitch filter.
  152. * Then just request_irq() with the pin ID; it works like any ARM IRQ
  153. * handler, though it always triggers on rising and falling edges.
  154. *
  155. * Alternatively, certain pins may be used directly as IRQ0..IRQ6 after
  156. * configuring them with at91_set_a_periph() or at91_set_b_periph().
  157. * IRQ0..IRQ6 should be configurable, e.g. level vs edge triggering.
  158. */

  159. static void gpio_irq_mask(unsigned pin)
  160. {
  161.         void __iomem    *pio = pin_to_controller(pin);
  162.         unsigned        mask = pin_to_mask_o(pin);

  163.         if (pio)
  164.                 __raw_writel(mask, pio + PIO_IDR);
  165. }

  166. static void gpio_irq_unmask(unsigned pin)
  167. {
  168.         void __iomem    *pio = pin_to_controller(pin);
  169.         unsigned        mask = pin_to_mask_o(pin);

  170.         printk("gpio_irq_unmask %d %x\n", (int) pin, (int) pio);
  171.         if (pio)
  172.                 __raw_writel(mask, pio + PIO_IER);
  173. }

  174. static int gpio_irq_type(unsigned pin, unsigned type)
  175. {
  176.         return (type == IRQT_BOTHEDGE) ? 0 : -EINVAL;
  177. }

  178. static struct irqchip gpio_irqchip = {
  179.         .mask           = gpio_irq_mask,
  180.         .unmask         = gpio_irq_unmask,
  181.         .set_type       = gpio_irq_type,
  182. };

  183. static void gpio_irq_handler(unsigned irq, struct irqdesc *desc, struct pt_regs *regs)
  184. {
  185.         unsigned        pin;
  186.         struct irqdesc  *gpio;
  187.         void __iomem    *pio;
  188.         u32             isr;

  189.         pio = (void __force __iomem *) desc->chipdata;

  190.         /* temporarily mask (level sensitive) parent IRQ */
  191.         desc->chip->ack(irq);
  192.         for (;;) {
  193.                 isr = __raw_readl(pio + PIO_ISR) & __raw_readl(pio + PIO_IMR);
  194.                 if (!isr)
  195.                         break;

  196.                 pin = (unsigned) desc->data;
  197.                 gpio = &irq_desc[pin];

  198.                 while (isr) {
  199.                         if (isr & 1)
  200.                                 gpio->handle(pin, gpio, regs);
  201.                         pin++;
  202.                         gpio++;
  203.                         isr >>= 1;
  204.                 }
  205.         }
  206.         desc->chip->unmask(irq);
  207.         /* now it may re-trigger */
  208. }

  209. /* call this from board-specific init_irq */
  210. void __init at91_gpio_irq_setup(unsigned banks)
  211. {
  212.         unsigned        pioc, pin, id;

  213.         if (banks > 4)
  214.                 banks = 4;
  215.         for (pioc = 0, pin = PIN_BASE, id = AT91_ID_PIOA;
  216.                         pioc < banks;
  217.                         pioc++, id++) {
  218.                 void __iomem    *controller;
  219.                 unsigned        i;

  220.                 controller = (void __iomem *) AT91C_VA_BASE_SYS + pio_controller_offset[pioc];
  221.                 __raw_writel(~0, controller + PIO_IDR);

  222.                 set_irq_data(id, (void *) pin);
  223.                 set_irq_chipdata(id, (void __force *) controller);

  224.                 for (i = 0; i < 32; i++, pin++) {
  225.                         set_irq_chip(pin, &gpio_irqchip);
  226.                         set_irq_handler(pin, do_simple_IRQ);
  227.                         set_irq_flags(pin, IRQF_VALID);
  228.                 }

  229.                 set_irq_chained_handler(id, gpio_irq_handler);
  230.                 printk("set_irq_chained_handler %d\n", id);

  231.                 /* enable the PIO peripheral clock */
  232.                 at91_enable_periph_clock(id);
  233.                 //at91_sys_write(AT91_PMC_PCER, 1 << id);
  234.         }
  235.         pr_info("AT91: %d gpio irqs in %d banks\n", pin - PIN_BASE, banks);
  236. }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP