S3C2440串口mark和space校验

先看datasheet:


硬件是支持的,再看驱动:linux-2.6.32.2\drivers\serial\samsung.c中

	if (termios->c_cflag & PARENB) {
		if (termios->c_cflag & PARODD)
			ulcon |= S3C2410_LCON_PODD;
		else
			ulcon |= S3C2410_LCON_PEVEN;
	} else {
		ulcon |= S3C2410_LCON_PNONE;
	}

目前的驱动中并没有提space,mark校验,原来如此,这个驱动必须得改了!!!

先大概说得几处改:

①:termios.h中看有没有CMSPAR 没有的话加上!

# define CMSPAR   010000000000		/* mark or space (stick) parity */


经过搜索发现是有的,这个可以用了,看看驱动中有没有办法直接判断它!

159 #define CMSPAR    010000000000          /* mark or space (stick) parity */
http://lxr.free-electrons.com/source/arch/arm/include/asm/termbits.h?v=2.6.32;a=arm#L159

 32 #include <linux/module.h>
 33 #include <linux/ioport.h>
 34 #include <linux/io.h>
 35 #include <linux/platform_device.h>
 36 #include <linux/init.h>
 37 #include <linux/sysrq.h>
 38 #include <linux/console.h>
 39 #include <linux/tty.h>
 40 #include <linux/tty_flip.h>
 41 #include <linux/serial_core.h>
 42 #include <linux/serial.h>
 43 #include <linux/delay.h>
 44 #include <linux/clk.h>
 45 #include <linux/cpufreq.h>
 46 
 47 #include <asm/irq.h>
 48 
 49 #include <mach/hardware.h>
 50 #include <mach/map.h>
 51 
 52 #include <plat/regs-serial.h>

③:

在/arch/arm/plat-s3c/include/plat/regs-serial.h找到这么一段定义:

 65 #define S3C2410_LCON_PNONE        (0x0)            //对应无校验
 66 #define S3C2410_LCON_PEVEN        (0x5 << 3)       //对应偶校验
 67 #define S3C2410_LCON_PODD         (0x4 << 3)       //对应奇校验
 68 #define S3C2410_LCON_PMASK        (0x7 << 3)       //对应SPACE校验(这个名字实在纠结,叫PSPACE多好!)

?MARK校验哪里去了呢??还应该有一个:

#define S3C2410_LCON_PMARK        (0x6 << 3)       //对应MARK校验

这个分析就算齐了,再加上判断:

if (termios->c_cflag & PARENB) {    
    if (termios->c_cflag & PARODD)
    	{
    		if(termios->c_cflag & CMSPAR)    		    
        	ulcon |= S3C2410_LCON_PMARK; //MARK
        else   
        	ulcon |= S3C2410_LCON_PODD; //ODD
      }
    else 
    	{
    		if ((termios->c_cflag & CMSPAR))
    			ulcon |= S3C2410_LCON_PMASK; //SPACE
        else   
        	ulcon |= S3C2410_LCON_PEVEN; //EVEN
    	}              
}


这样这四种校验就都有了~~明天实验!!!

========================================================================================

2012年10月18日18:35:16:结果好悲催呀!!!

TFTP from server 192.168.1.229; our IP address is 192.168.1.230
Filename 'zImage.img'.
Load address: 0x30008000
Loading: T #################################################################
         #################################################################
         #################################################################
         #################################################################
         #
done
Bytes transferred = 3828524 (3a6b2c hex)
## Booting kernel from Legacy Image at 30008000 ...
   Image Name:   kangear
   Created:      2012-10-18   1:44:02 UTC
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    3828460 Bytes =  3.7 MB
   Load Address: 30008000
   Entry Point:  30008040
   Verifying Checksum ... OK
   XIP Kernel Image ... OK
OK


Starting kernel ...

内核都启动不了了,我晕,再编译一次!!试试

==============================================================

2012年10月18日18:49:54:

这有用到:S3C2410_LCON_PMASK

1340                 switch (ulcon & S3C2410_LCON_PMASK) {
1341                 case S3C2410_LCON_PEVEN:
1342                         *parity = 'e';
1343                         break;
1344 
1345                 case S3C2410_LCON_PODD:
1346                         *parity = 'o';
1347                         break;
1348 
1349                 case S3C2410_LCON_PNONE:
1350                 default:
1351                         *parity = 'n';
1352                 }

先不管了,先编译再说吧!

=========================================================================

2012年10月18日19:41:42:

可以运行了,不过还是和以前的一样,我索性把 odd 默认成 mark看它还行不行!!!

if (termios->c_cflag & PARENB) {
		if (termios->c_cflag & PARODD)
		{
			//if(termios->c_cflag & CMSPAR)
				ulcon |= S3C2410_LCON_PMARK;
			//else 
			//	ulcon |= S3C2410_LCON_PODD;
		}else{
			//if(termios->c_cflag & CMSPAR)
				ulcon |= S3C2410_LCON_PMASK;
			//else
			//	ulcon |= S3C2410_LCON_PEVEN;
		}
	} else {
		ulcon |= S3C2410_LCON_PNONE;
	}

============================================================================

2012年10月18日20:04:35:

if (termios->c_cflag & PARENB) {
		if (termios->c_cflag & PARODD)
		{
			//if(termios->c_cflag & CMSPAR)
				ulcon |= S3C2410_LCON_PMASK;
			//else 
			//	ulcon |= S3C2410_LCON_PODD;
		}else{
			//if(termios->c_cflag & CMSPAR)
				ulcon |= S3C2410_LCON_PMARK;
			//else
			//	ulcon |= S3C2410_LCON_PEVEN;
		}
	} else {
		ulcon |= S3C2410_LCON_PNONE;
	}


配上完整测试程序:

#include     <stdio.h>
#include     <stdlib.h>
#include     <unistd.h>
#include     <sys/types.h>
#include     <sys/stat.h>
#include     <fcntl.h>
#include     <termios.h>
#include     <errno.h>


main()
{
    int fd;
    int i;
    int len;
    int n = 0;
    char b[1]={0x03};
    char read_buf[256];
    char write_buf[256];
    struct termios opt;


    fd = open("/dev/ttySAC1", O_RDWR | O_NOCTTY);    //默认为阻塞读方式
    if(fd == -1)
    {
        perror("open serial 0\n");
        exit(0);
    }


    tcgetattr(fd, &opt);
    cfsetispeed(&opt, B9600);
    cfsetospeed(&opt, B9600);


    if(tcsetattr(fd, TCSANOW, &opt) != 0 )
    {
       perror("tcsetattr error");
       return -1;
    }
    opt.c_cflag &= ~CSIZE;
    opt.c_cflag |= CS8;
    opt.c_cflag &= ~CSTOPB;
    opt.c_cflag &= ~PARENB;
    opt.c_cflag &= ~INPCK;
    opt.c_cflag |= (CLOCAL | CREAD);


    opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);


    opt.c_oflag &= ~OPOST;
    opt.c_oflag &= ~(ONLCR | OCRNL);    //添加的


    opt.c_iflag &= ~(ICRNL | INLCR);
    opt.c_iflag &= ~(IXON | IXOFF | IXANY);    //添加的
//    //=====================================
//    //space
    opt.c_cflag |=  PARENB | CS8 | CMSPAR | PARODD;
//    //=====================================
    //=====================================
    //mark
//    opt.c_cflag |= PARENB | CS8 | CMSPAR ;
//    opt.c_cflag &= ~PARODD;
    //=====================================


    opt.c_cc[VTIME] = 0;
    opt.c_cc[VMIN] = 0;


    tcflush(fd, TCIOFLUSH);


    printf("configure complete\n");


    if(tcsetattr(fd, TCSANOW, &opt) != 0)
    {
        perror("serial error");
        return -1;
    }
    printf("start send and receive data\n");


    while(1)
    {


        n = 0;
        len = 0;
        printf("hw\n");
        bzero(read_buf, sizeof(read_buf));    //类似于memset
        bzero(write_buf, sizeof(write_buf));
        write(fd,b,sizeof b);
        usleep(50000);
    }
}

(无论发是0x01,0x03都不能进入单片机中断)

这样可以了,呀呀呀呀……………………………………………………………………

这样不太好,还是尽量改为通用的!去掉注释再看看:

================================================================================

2012年10月18日21:28:54:我无法忍受了,mark校验通过了,space怎么也不行,我重新定义一个:

#define S3C2410_LCON_PSPACE        (0x7 << 3)       //对应SPACE校验

===============================================================================

2012年10月18日21:32:24:上一个先不说,先来个这个:

	if (termios->c_cflag & PARENB) {
		if (termios->c_cflag & PARODD)
		{
			//if(termios->c_cflag & CMSPAR)
				ulcon |= S3C2410_LCON_PMASK;
			//else 
			//	ulcon |= S3C2410_LCON_PODD;
		}else{
			if(termios->c_cflag & CMSPAR)
				ulcon |= S3C2410_LCON_PMARK;
			else
				ulcon |= S3C2410_LCON_PEVEN;
		}
	} else {
		ulcon |= S3C2410_LCON_PNONE;
	}

说明:ODD校验强制转为SPACE校验!等会说结果……

2012年10月18日21:36:31:结果出来了,这样可以!!!PMASK也行,可以怎么老进入到ODD校验中去呢???

==============================================================================

算了,暂时不深入研究了,奇校验,偶校验在设计中用不到,控制台用 “无校验”,其它用“校验和”,一般没人用奇校验,偶校验就分别将其强制转化为 space,mark校验!!!!(2012年10月18日21:41:36)

==================================================================================================================

2012年10月18日22:23:08:

最后定:

①:linux-2.6.32.2\drivers\serial\samsung.c(修改为)

if (termios->c_cflag & PARENB) {  
    if (termios->c_cflag & PARODD)  
    {   
            ulcon |= S3C2410_LCON_PMASK;  
      
    }else{  
            ulcon |= S3C2410_LCON_PMARK;  
    }  
} else {  
    ulcon |= S3C2410_LCON_PNONE;  
} 

②:linux-2.6.32.2/arch/arm/plat-s3c/include/plat/regs-serial.h(修改为)

 65 #define S3C2410_LCON_PNONE        (0x0)
 66 #define S3C2410_LCON_PEVEN        (0x5 << 3)
 67 #define S3C2410_LCON_PODD         (0x4 << 3)
 68 #define S3C2410_LCON_PMASK        (0x7 << 3)
 69 #define S3C2410_LCON_PMARK        (0X6 << 3) //add by kangear for mark stick
 70 #define S3C2410_LCON_STOPB        (1<<2)
 71 #define S3C2410_LCON_IRM          (1<<6)
完!

附上linux测试程序:

#include     <stdio.h>
#include     <stdlib.h>
#include     <unistd.h>
#include     <sys/types.h>
#include     <sys/stat.h>
#include     <fcntl.h>
#include     <termios.h>
#include     <errno.h>
#include     <string.h>


main()
{
    int fd;
    int i;
    int len;
    int n = 0;
    char b[1]={0x03};
    char read_buf[256];
    char write_buf[256];
    struct termios opt;


    fd = open("/dev/ttySAC1", O_RDWR | O_NOCTTY);    //默认为阻塞读方式
    if(fd == -1)
    {
        perror("open serial 0\n");
        exit(0);
    }


    tcgetattr(fd, &opt);
    cfsetispeed(&opt, B9600);
    cfsetospeed(&opt, B9600);


    if(tcsetattr(fd, TCSANOW, &opt) != 0 )
    {
       perror("tcsetattr error");
       return -1;
    }
    opt.c_cflag &= ~CSIZE;
    opt.c_cflag |= CS8;
    opt.c_cflag &= ~CSTOPB;
    opt.c_cflag &= ~PARENB;
    opt.c_cflag &= ~INPCK;
    opt.c_cflag |= (CLOCAL | CREAD);


    opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);


    opt.c_oflag &= ~OPOST;
    opt.c_oflag &= ~(ONLCR | OCRNL);    //添加的


    opt.c_iflag &= ~(ICRNL | INLCR);
    opt.c_iflag &= ~(IXON | IXOFF | IXANY);    //添加的
//    //=====================================
//    //space
//    opt.c_cflag |=  PARENB | CS8 | CMSPAR ;
//    //=====================================
    //=====================================
    //mark
    opt.c_cflag |= PARENB | CS8 | CMSPAR ;
    opt.c_cflag &= ~PARODD;
    //=====================================


    opt.c_cc[VTIME] = 0;
    opt.c_cc[VMIN] = 0;


    tcflush(fd, TCIOFLUSH);


    printf("configure complete\n");


    if(tcsetattr(fd, TCSANOW, &opt) != 0)
    {
        perror("serial error");
        return -1;
    }
    printf("start send and receive data\n");


    while(1)
    {


        n = 0;
        len = 0;
        printf("hw\n");
        bzero(read_buf, sizeof(read_buf));    //类似于memset
        bzero(write_buf, sizeof(write_buf));
        write(fd,b,sizeof b);
        usleep(50000);
    }
}


 
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

袁保康

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值