LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software > Linux - Kernel
User Name
Password
Linux - Kernel This forum is for all discussion relating to the Linux kernel.

Notices


Reply
  Search this Thread
Old 04-01-2016, 07:10 AM   #1
sm4rty
LQ Newbie
 
Registered: Apr 2016
Posts: 1

Rep: Reputation: Disabled
Problem with Kernel driver and Serial / UART Port


Hello,
I a friend of me has to write a kernel driver module for an university lecture.

So im trying to help him but we cant get a solution for out problem.
we have to set the serial port to 115200 baud rate, 8 bit, 1 stop bit and no parity.

the port is connected to an i2c serial modem http://www.horter.de/i2c/i2c-usb-mod...b-modem_1.html

this modem is connected to an i2c lm75 temperature sensor.
http://www.horter.de/i2c/i2c-tempera...peratur_1.html

so now we are trying to read out the temp.

we have to send a few hex values to the modem, which is working wonderful.
then we have to read out the data from the fifo buffer.

the first and second value are correct. but the next 3 values are totally wrong.

Im thinking that the fifo buffer is doing something strange with our values. it does some sort of shifting or adding with the next 3 values.

so we get sometimes 2 and sometimes 3 values. it depends from the temperature. is it 19.0 degree, so the last value is 0x04 but if its 19.5 the last value is 0xFF but it should be 10000000 (128) and the last one should be 0x04 or 00000100 but its some sort of crumbled together when the temperature is .5

can someone please help?

here is the code:
Code:
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/tty.h>
#include <linux/string.h>
#include <linux/proc_fs.h>
//#include <asm/page.h>
#include <linux/slab.h>
#include <asm/io.h>             // outb()
#include <linux/ioport.h>       // check_region
//#include <asm/uaccess.h>      // put_user
#include <linux/delay.h>        //sleep

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Felix Blumenstein");
MODULE_DESCRIPTION("Temperatur-Sensor-Treiber");

#define PORT 0x2E8
#define DEVICE_NAME "t-meter"

static int isOpened = 0; //Gerät in verwendung (1) oder nicht (0)

int print_x(char* str){
    struct tty_struct *my_tty;
    my_tty = get_current_tty();
    if (my_tty == NULL) return -ENOTTY;
    (my_tty->driver->ops->write)(my_tty, str, strlen(str));
	return 0;
}

int rec_data(void) {
    return inb(PORT + 5) & 1;
}



void rec_temp(void) {
    char msgbyte;
    //unsigned char temp[8] = {"00000000"};
   // unsigned char msghex;
    int i;
    i=0;
    while (rec_data() == 1){	
		msleep(200);
		msgbyte = inb(PORT);					
		
		for(i = 7; i >= 0 ; --i) { 
			if(msgbyte & (1 << i)) { 
			print_x("1"); 
			} 
				else { 
						print_x("0"); 
					} 
   } 
   print_x("\r\n");
   
			
			}			
		 
	 
		//bin2hex(&msghex, &temp, 2);
		//print_x(&temp);

}

void init_serial(void){
    outb(0x00, PORT + 1);    // Interupt Enable Register auf 0 setzen (IR deaktivieren)
    outb(0x80, PORT + 3);    // Divisor Latch Bit auf 1 setzen - dazu line Control register in Bit 7 auf high
    outb(0x01, PORT + 0);    // Divisor auf 1 setzen (low byte) um Baudrate von 115200 einzustellen
  
    outb(0x00, PORT + 1);    //                  (hi byte)
    
    outb(0x0B, PORT + 3);    // 8 bits, no parity, one stop bit
   
    outb(0x00, PORT + 3);   // Baudratenkonfig abgeschlossen (DLAB 0)
   
    outb(0x87, PORT + 2);    // FIFO-Register zurücksetzen
   
    outb(0x0B, PORT + 4);
}

static void temp_init(void){
    outb(0x31, PORT);
    outb(0x01, PORT);
    outb(0x07, PORT);
    outb(0x04, PORT);
}

static void rot(void){
    msleep(20);
    outb(0x31, PORT);
    msleep(20);
    outb(0x01, PORT);
    msleep(20);
    outb(0x00, PORT);
    msleep(20);
    outb(0x04, PORT);
}

static void gruen(void){
    outb(0x31, PORT);
    outb(0x01, PORT);
    outb(0x05, PORT);
    outb(0x04, PORT);
}

static void gelb(void){
    outb(0x31, PORT);
    outb(0x01, PORT);
    outb(0x06, PORT);
    outb(0x04, PORT);   
}

static void send_temp(void){
    outb(0x33, PORT);
    outb(0x03, PORT);
    outb(0x91, PORT);
    outb(0x00, PORT);
    outb(0x02, PORT);
    outb(0x04, PORT);
}

static int device_open(struct inode* in, struct file* f){
    if (isOpened) { return -EBUSY; }
    print_x("open() \n\r");
    isOpened = 1; // Geraet sperren, da es in Verwendung ist
    return 0;
}

static int device_release(struct inode* in, struct file* f){
    print_x("release() \n\r");
    isOpened = 0; // Geraet wieder freigeben
    return 0;
}

static ssize_t device_write(struct file* f, const char* buf, size_t len, loff_t* off) {
    int i;
    print_x("hello write\n\r");
    for (i = 0; i<len; i++){
        if (buf[i] == 'r'){
            rot();
            msleep(50);
            rec_temp();  
        }
        
        if (buf[i] == 'y'){
            gelb();
            msleep(50);
            rec_temp();
        }
        
        if (buf[i] == 'g'){
            gruen();
            msleep(50);
            rec_temp();
        }

        if (buf[i] == 't'){
            temp_init();
			msleep(100);
            rec_temp();
            print_x("Temp: \r\n");
			
			send_temp(); 
			msleep(100);         
            rec_temp();
        }
    }
    return len;
}

static ssize_t device_read(struct file *filp, char *buffer, size_t len, loff_t *offs){
    print_x("hello read\n\r");
    return len;
}

static struct file_operations fops = {
    .write = device_write,
    .read = device_read,
    .open = device_open,
    .release = device_release,
    .owner = THIS_MODULE };

static int modu_init(void){
    proc_create(DEVICE_NAME, 0777, NULL, &fops);
    print_x("Treiber geladen\n\r");
    printk("ModuleÂ*loaded \n");
    init_serial();
    rec_temp();
    return 0;
}

static void modu_exit(void){
    print_x("Treiber entladen\n\r");
    printk("ModuleÂ*unloadedÂ*\n");
    outb(0x31, PORT);
    outb(0x01, PORT);
    outb(0x04, PORT);
    outb(0x04, PORT);
	rec_temp();
    remove_proc_entry(DEVICE_NAME, NULL);
}

module_init(modu_init);
module_exit(modu_exit);
 
Old 04-02-2016, 02:27 AM   #2
ferrari
LQ Guru
 
Registered: Sep 2003
Location: Auckland, NZ
Distribution: openSUSE Leap
Posts: 5,819

Rep: Reputation: 1144Reputation: 1144Reputation: 1144Reputation: 1144Reputation: 1144Reputation: 1144Reputation: 1144Reputation: 1144Reputation: 1144
I'm not a programmer, but maybe this LM75A datasheet will provide the information you need about the temperature data format.

Quote:
Temperature data is two's complement format and one LSB is equivalent to 0.5°C
Here's another datasheet where it is mentioned

Quote:
The temperature register always stores an 11-bit 2's complement data giving a temperature resolution of 0.125°C. This high temperature resolution is particularly useful in applications of measuring precisely the thermal drift or runaway.
I'm not familiar with these devices and can only point you at the datasheets I've dug up.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Where does uart console get its value of uart port membase? unifoxz Linux - Kernel 1 12-20-2011 02:28 PM
Serial port UART FIFO buffer override Mar_kas Linux - Hardware 2 05-13-2010 12:47 AM
Serial Driver Failing to Register all Ports of my Quad Uart bramsey123 Linux - Newbie 0 09-13-2007 10:16 AM
Uart serial port + SysRq flook Linux - Hardware 0 11-30-2004 08:57 AM
Serial Port Driver- Interrupt Invoking Problem sinux Linux - Software 0 03-07-2003 03:47 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Software > Linux - Kernel

All times are GMT -5. The time now is 04:43 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration