www.pudn.com > EXT.rar > IIC_led.c
/* * linux/drivers/char/led.c * * Copyright (C) 2004 ourselec Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Changelog: * 25-Sep-2004 Created * 26-Sep-2004 Add read and display RTC */ #define MODULE //make version copatible whiel compiled #include#include #include #include #include #include #include #include #include #include #include #include #include #include #include "IIC.h" #define ZLG7290_SLA_ADD 0x70 //the slave address of ZLG7290:ic which drivers leds. #define LED_SLA_ADD 0x70 //another name of the slave address #define LED_MAJOR 100 //the major device number of led #define TIME_TURN 0 //turn to display time #define DATE_TURN 1 //turn to display date //buffers for 8 leds: //..[0]: the zlg790's slave address //..[1]: the commad buffer's address of zlg7290 //..[2]: the first command //..[3]: the second command //..[4]: the end symbol signed char sec_buf_l[5]={LED_SLA_ADD,0x07,0x63,-1,-1}; signed char sec_buf_h[5]={LED_SLA_ADD,0x07,0x62,-1,-1}; signed char blank_buf_l[5]={LED_SLA_ADD,0X07,0X61,0x1f,-1}; signed char min_buf_l[5]={LED_SLA_ADD,0x07,0x60,-1,-1}; signed char min_buf_h[5]={LED_SLA_ADD,0x07,0x67,-1,-1}; signed char blank_buf_h[5]={LED_SLA_ADD,0X07,0X66,0x1f,-1}; signed char hour_buf_l[5]={LED_SLA_ADD,0x07,0x65,-1,-1}; signed char hour_buf_h[5]={LED_SLA_ADD,0x07,0x64,-1,-1}; //buffers for 8 leds: signed char date_buf_l[5]={LED_SLA_ADD,0x07,0x63,-1,-1}; signed char date_buf_h[5]={LED_SLA_ADD,0x07,0x62,-1,-1}; signed char mon_buf_l[5]={LED_SLA_ADD,0x07,0x61,-1,-1}; signed char mon_buf_h[5]={LED_SLA_ADD,0x07,0x60,-1,-1}; signed char year_buf_0[5]={LED_SLA_ADD,0x07,0x64,2,-1}; signed char year_buf_1[5]={LED_SLA_ADD,0x07,0x65,0,-1}; signed char year_buf_2[5]={LED_SLA_ADD,0x07,0x66,-1,-1}; signed char year_buf_3[5]={LED_SLA_ADD,0x07,0x67,-1,-1}; int date_time_turn = TIME_TURN; //turn to display time first signed int date_s = 0; //the seconds how long date has been displayed signed int time_s = 0; //the seconds how long time has been displayed //time structure static struct my_time{ char second; char minute; char hour; char date; char month; char year; }led_time; /* * write the cpu's rtc! * you can change the time and date */ static void led_set_time(void) { RTCCON = 0X01; //get the right to write rtc BCDYEAR = 0x04; //2004.9.26 11:49:30 BCDMON = 0x09; BCDDATE = 0x26; BCDHOUR = 0x11; BCDMIN = 0x49; BCDSEC = 0x30; // printk("HAHAHAHA!!%d\n",RTCCON); RTCCON = 0X00; //free the right to write rtc } /* * get the date and time from rtc */ static void led_get_time(struct my_time *tempt) { tempt->second = BCDSEC; tempt->minute = BCDMIN; tempt->hour = BCDHOUR; tempt->date = BCDDATE; tempt->month = BCDMON; tempt->year = BCDYEAR; } /* * get the correct format of the time and date * see the cpu 2410's doc for more details of the RTC registers */ static void led_time_format(struct my_time *tempt) { sec_buf_l[3] = (tempt->second & 0x0f); sec_buf_h[3] = (tempt->second & 0x70) >> 4; min_buf_l[3] = (tempt->minute & 0x0f) | 0x80; min_buf_h[3] = (tempt->minute & 0x70) >> 4; hour_buf_l[3] = (tempt->hour & 0x0f) |0x80; hour_buf_h[3] = (tempt->hour & 0x30) >> 4; date_buf_l[3] = (tempt->date & 0x0f); date_buf_h[3] = (tempt->date & 0x30) >> 4; mon_buf_l[3] = (tempt->month & 0x0f) | 0x80; mon_buf_h[3] = (tempt->month & 0x10) >> 4; year_buf_2[3] = (tempt->year) / 10; year_buf_3[3]= (tempt->year) % 10 | 0x80; } /* * send command to zlg7290 */ static int led_send_cmd(signed char *data) { //*************** hr add *************** // char a[]={'f','f','f','f'}; // signed char *temp = a; //************************************* signed char *temp = data; if (*temp == -1) //nothing to send! return 0; IICDS = *temp; //store the slave device address! IICSTAT = 0xF0; //START SEND temp++; while (*temp != -1) { while (!(IICCON & IICCON_PEND_INT_STATU)); //WAIT UNTIL TRANSFERS ENDED! IICDS = *temp; //put new command into it to be sended! IICCON &= ~IICCON_PEND_INT_CLEAR; //A NEW TRANSFERS temp++; } while (!(IICCON & IICCON_PEND_INT_STATU)); IICSTAT = 0xD0;//STOP IIC IICCON &= ~IICCON_PEND_INT_CLEAR;//CLEAR PENDING INT mdelay(5); //delay needed before another transfers return 1; } /* * init IIC registers and zlg7290 and led:led like this:88_88_88 */ static void led_reg_init(void) { int i = 0; printk("led_reg_init!\n"); IICCON = IICCON_DISABLE_ACKNOWLEDGE | IICCON_FPCLK_512 | IICCON_ENABLE_INT | IICCON_TXCLK_24K; //enable int,I2CCLK = 24k IICSTAT = 0xD0; //MASTER TX MODE AND ENABLE OUTPUT for (i=0 ;i <8 ;i++) //all the lights display 8. { IICDS = ZLG7290_SLA_ADD; //ZLG7920 SLAVE ADDRESS IICSTAT = 0xF0; //START TRANSLATE while (!(IICCON & IICCON_PEND_INT_STATU));//WAIT UNTIL TRANSFERS ENDED! IICDS = 0x10+i; //led i buffer IICCON &= ~IICCON_PEND_INT_CLEAR; //A NEW TRANLATE while (!(IICCON & IICCON_PEND_INT_STATU));//WAIT UNTIL TRANSFERS ENDED! if(i == 1 || i == 6) IICDS = 0x00; //this two led turn off. else IICDS = 0xfc; //operate led 8. IICCON &= ~IICCON_PEND_INT_CLEAR; //A NEW TRANLATE while (!(IICCON & IICCON_PEND_INT_STATU)); IICSTAT = 0xD0;//STOP IIC IICCON &= ~IICCON_PEND_INT_CLEAR;//CLEAR PENDING INT mdelay(5); // printk("Stop IIC!\n"); } } /* * interface of open operation */ static int led_open(void) { led_reg_init(); //init IIC AND LED // led_set_time(); //set a new time when necessary! return 0; } /* * interface of write operation */ static ssize_t led_write(struct file *file, signed char *buf, size_t count, loff_t *ppos) { led_get_time(&led_time); printk("led_get_time!\n"); led_time_format(&led_time); printk("led_time_format!\n"); //turn to display time if (date_time_turn == TIME_TURN) { led_send_cmd(sec_buf_l); led_send_cmd(sec_buf_h); led_send_cmd(blank_buf_l); led_send_cmd(min_buf_l); led_send_cmd(min_buf_h); led_send_cmd(blank_buf_h); led_send_cmd(hour_buf_l); led_send_cmd(hour_buf_h); time_s++; if(time_s >= 10) { time_s = 0; date_time_turn = DATE_TURN; } } //turn to display date else if (date_time_turn == DATE_TURN) { led_send_cmd(date_buf_l); led_send_cmd(date_buf_h); led_send_cmd(mon_buf_l); led_send_cmd(mon_buf_h); led_send_cmd(year_buf_0); led_send_cmd(year_buf_1); led_send_cmd(year_buf_2); led_send_cmd(year_buf_3); date_s++; if(date_s >= 3) { date_s = 0; date_time_turn = TIME_TURN; } } return count; } /* * device file */ static struct file_operations led_fops = { owner: THIS_MODULE, // read: led_read, write: led_write, // poll: led_poll, // ioctl: led_ioctl, open: led_open, // release: led_release, // fasync: led_fasync, }; /* * Initialization and exit routines */ int __init led_init(void) { int retval; retval = register_chrdev(LED_MAJOR,"led",&led_fops); //registered as a char device if (retval) { printk(KERN_ERR"led: can't register on minor=%d\n",LED_MAJOR); return retval; } return retval; } void __exit led_exit(void) { unregister_chrdev(LED_MAJOR,"led"); } module_init(led_init); module_exit(led_exit); MODULE_AUTHOR("yhero "); MODULE_DESCRIPTION("led driver"); MODULE_SUPPORTED_DEVICE("led/yhero");