Chinaunix首页 | 论坛 | 博客
  • 博客访问: 7687560
  • 博文数量: 961
  • 博客积分: 15795
  • 博客等级: 上将
  • 技术积分: 16612
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-07 14:23
文章分类

全部博文(961)

文章存档

2016年(1)

2015年(61)

2014年(41)

2013年(51)

2012年(235)

2011年(391)

2010年(181)

分类: 嵌入式

2012-09-14 11:21:37


点击(此处)折叠或打开

  1. /**
  2.  * AM1808 5*4矩阵键盘驱动
  3.  * 最后得到从1到20编号的键值
  4.  * Lzy 2012-913
  5.  */

  6. struct status /*位段类型定义*/
  7. {
  8.     unsigned char bit1: 1; /*定义bit1占2个二进制位,其范围0~8*/
  9.     unsigned char bit2: 1;
  10.     unsigned char bit3: 1;
  11.     unsigned char bit4: 1;
  12.     unsigned char bit5: 1;
  13. };

  14. union Data /*定义联合体*/
  15. {
  16.     unsigned int x;
  17.     struct status Byte;
  18. };

  19. void key_row_set_value(unsigned char cx) // 设置行值
  20. {
  21.     int i;
  22.     union Data data = {cx}; /*初始化*/
  23.     
  24.      for(i=0; i<5; i++)
  25.         gpio_direction_output(key_row_num[i], 0); // 使能GPIO時钟
  26.   
  27.      // 设置GPIO点平
  28.     gpio_set_value(ROW_1, data.Byte.bit1);
  29.     gpio_set_value(ROW_2, data.Byte.bit2);
  30.     gpio_set_value(ROW_3, data.Byte.bit3);
  31.     gpio_set_value(ROW_4, data.Byte.bit4);
  32.     gpio_set_value(ROW_5, data.Byte.bit5);
  33. }

  34. unsigned int key_row_get_value(void) // 得到行值
  35. {
  36.     int i;
  37.     union Data data = {0}; /*初始化*/
  38.     
  39.      for(i=0; i<5; i++)
  40.         gpio_direction_input(key_row_num[i]); // 使能GPIO時钟
  41.           
  42.      // 得到GPIO点平
  43.     data.Byte.bit1 = gpio_get_value(ROW_1) > 0 ? 1:0;
  44.     data.Byte.bit2 = gpio_get_value(ROW_2) > 0 ? 1:0;
  45.     data.Byte.bit3 = gpio_get_value(ROW_3) > 0 ? 1:0;
  46.     data.Byte.bit4 = gpio_get_value(ROW_4) > 0 ? 1:0;
  47.     data.Byte.bit5 = gpio_get_value(ROW_5) > 0 ? 1:0;
  48.     
  49.     return data.x;
  50. }

  51. void key_column_set_value(unsigned char cx) // 设置列值
  52. {
  53.     int i;
  54.     union Data data = {cx}; /*初始化*/
  55.     
  56.      for(i=0; i<4; i++)
  57.         gpio_direction_output(key_column_num[i], 0); // 使能GPIO時钟
  58.     
  59.      // 设置GPIO点平
  60.     gpio_set_value(column_1, data.Byte.bit1);
  61.     gpio_set_value(column_2, data.Byte.bit2);
  62.     gpio_set_value(column_3, data.Byte.bit3);
  63.     gpio_set_value(column_4, data.Byte.bit4);
  64. }

  65. unsigned int key_column_get_value(void) // 得到列值
  66. {
  67.     int i;
  68.     union Data data = {0}; /*初始化*/
  69.     
  70.      for(i=0; i<4; i++)
  71.         gpio_direction_input(key_column_num[i]); // 使能GPIO時钟
  72.             
  73.      // 得到GPIO点平
  74.     data.Byte.bit1 = gpio_get_value(column_1) > 0 ? 1:0;
  75.     data.Byte.bit2 = gpio_get_value(column_2) > 0 ? 1:0;
  76.     data.Byte.bit3 = gpio_get_value(column_3) > 0 ? 1:0;
  77.     data.Byte.bit4 = gpio_get_value(column_4) > 0 ? 1:0;
  78.     
  79.     return data.x;
  80. }

  81. int get_column_biye(int col)
  82. {
  83.     int io_value = 0;
  84.     
  85.     gpio_direction_input(key_column_num[col]); // 使能GPIO時钟
  86.     io_value = gpio_get_value( key_column_num[col]);

  87.     if(io_value)
  88.         return 1;
  89.     else
  90.         return 0;
  91. }


  92. int key_scan(int column)
  93. {
  94.     int key = -1;
  95.     unsigned char i, temp = 1 ;
  96.     
  97.     mdelay(5);
  98.     
  99.     for(i=0; i<5; i++)
  100.     {
  101.         key_row_set_value(~temp);
  102.         udelay(10);
  103.     
  104.         if(get_column_biye(column) == 0)
  105.             break;

  106.         temp <<= 1;
  107.     }
  108.     
  109.     if(i != 5)
  110.        key = i * 4 + column ;
  111.            
  112. // printk(" key=%d \n",key);
  113.     mdelay(30);
  114.          
  115.     return key+1;
  116. }


  117. static void unmaskkey(void) // 使能所有中断
  118. {
  119.     int i, irq;
  120.     
  121.     for(i=0; i<4; i++)
  122.     {
  123.         irq = gpio_to_irq(key_column_num[i]);
  124.         enable_irq(irq);
  125.     }
  126. }

  127. static void maskkey(void) //禁址所有中断
  128. {
  129.     int i, irq;
  130.     
  131.     for(i=0; i<4; i++)
  132.     {
  133.         irq = gpio_to_irq(key_column_num[i]);
  134.         disable_irq_nosync(irq);
  135.     }
  136. }


  137. static irqreturn_t am1808_key_irqhandler(int irq, void *dev_id)
  138. {
  139.     maskkey();
  140.     
  141.     key_devices->key_value = key_scan(irq-221); // irq是220开始一直住后面加
  142.     wake_up(&(key_devices->ing)); // 换醒等待队列
  143.      
  144.     /** 引郐复位为下次中断做准备 */
  145.     key_row_set_value(0);
  146.     while(key_column_get_value() != 0x0f); // 等待按键松开
  147.    
  148.   // printk("irq key=%d\n", key_devices->key_value );
  149.     unmaskkey();

  150.     return IRQ_HANDLED;
  151. }


  152. static int am1808_request_irqs(int i)
  153. {
  154.     if(request_irq(gpio_to_irq(key_column_num[i]), am1808_key_irqhandler, IRQ_TYPE_EDGE_FALLING, "KEY_irq", NULL))
  155.     {
  156.         printk("request INT0 error\n");
  157.         free_irq(gpio_to_irq(key_column_num[i]), NULL);
  158.         return -1;
  159.     }

  160.     return 0;
  161. }

  162. int key_init_pin(void) // 初始化引郐
  163. {
  164.     int i, status = 0;
  165.     
  166.     for(i=0; i<5; i++)
  167.     {
  168.         status = davinci_cfg_reg( key_row_gpio_pin[i]); // 设置引脚为GPIO功能
  169.         if (status < 0)
  170.         {
  171.             printk("pin could not be muxed for GPIO functionality %d\n",key_row_num[i]);
  172.             return status;
  173.         }
  174.        
  175.         status = gpio_request(key_row_num[i], "gpio_key\n"); // 引脚是否已经配置成GPIO功能
  176.         if (status < 0)
  177.         {
  178.             printk("ERROR can not open GPIO %d\n", key_row_num[i]);
  179.             return status;
  180.         }
  181.         
  182.         gpio_direction_output(key_row_num[i], 0); // 使能GPIO時钟
  183.         gpio_set_value(key_row_num[i],0); // 设置GPIO默认值为低点平
  184.     }
  185.     
  186.     for(i=0; i<4; i++)
  187.     {
  188.         status = davinci_cfg_reg( key_column_gpio_pin[i]); // 设置引脚为GPIO功能
  189.         if (status < 0)
  190.         {
  191.             printk("pin could not be muxed for GPIO functionality %d\n", key_column_num[i]);
  192.             return status;
  193.         }
  194.        
  195.         status = gpio_request(key_column_num[i], "gpio_key\n"); // 引脚是否已经配置成GPIO功能
  196.         if (status < 0)
  197.         {
  198.             printk("ERROR can not open GPIO %d\n", key_column_num[i]);
  199.             return status;
  200.         }
  201.         
  202.         gpio_direction_input(key_column_num[i]); // 使能GPIO時钟
  203.          
  204.         status = am1808_request_irqs(i);
  205.         if(status < 0)
  206.         {
  207.             printk("am1808_request_irqs %d faild\n", i);
  208.             return status;
  209.         }
  210.         
  211.     }
  212.     
  213.     return status;
  214. }
 kepad.zip   
阅读(2120) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~