S3C2440串口mark和space校验
2012-10-17 20:24
483 查看
先看datasheet:
硬件是支持的,再看驱动:linux-2.6.32.2\drivers\serial\samsung.c中
目前的驱动中并没有提space,mark校验,原来如此,这个驱动必须得改了!!!
先大概说得几处改:
①:termios.h中看有没有CMSPAR
没有的话加上!
经过搜索发现是有的,这个可以用了,看看驱动中有没有办法直接判断它!
http://lxr.free-electrons.com/source/arch/arm/include/asm/termbits.h?v=2.6.32;a=arm#L159
②:
③:
在/arch/arm/plat-s3c/include/plat/regs-serial.h找到这么一段定义:
?MARK校验哪里去了呢??还应该有一个:
这个分析就算齐了,再加上判断:
这样这四种校验就都有了~~明天实验!!!
========================================================================================
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
先不管了,先编译再说吧!
=========================================================================
2012年10月18日19:41:42:
可以运行了,不过还是和以前的一样,我索性把 odd 默认成 mark看它还行不行!!!
============================================================================
2012年10月18日20:04:35:
配上完整测试程序:
(无论发是0x01,0x03都不能进入单片机中断)
这样可以了,呀呀呀呀……………………………………………………………………
这样不太好,还是尽量改为通用的!去掉注释再看看:
================================================================================
2012年10月18日21:28:54:我无法忍受了,mark校验通过了,space怎么也不行,我重新定义一个:
#define S3C2410_LCON_PSPACE (0x7 << 3) //对应SPACE校验
===============================================================================
2012年10月18日21:32:24:上一个先不说,先来个这个:
说明: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(修改为)
②:linux-2.6.32.2/arch/arm/plat-s3c/include/plat/regs-serial.h(修改为)
完!
附上linux测试程序:
硬件是支持的,再看驱动: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); } }
相关文章推荐
- 串口通信校验方式(even,odd,space,mark) 分类: 开发工具 2015-07-31 16:01 5人阅读 评论(0) 收藏
- 串口通信校验方式(even,odd,space,mark)
- 串口通信校验方式(even,odd,space,mark)
- 串口通信校验方式(even,odd,space,mark)
- 串口通信校验方式(even,odd,space,mark)UART数据波形分析
- 串口通信校验方式(even,odd,space,mark)
- 串口通信校验方式(even,odd,space,mark)
- Linux串口通讯(mark, space校验方式的实现)
- Linux串口编程-2-mark校验
- Linux串口通讯(mark, space校验方式的实现)
- Linux串口编程-5-space校验
- Linux串口编程-5-space校验2
- 子函数中设置校验方式mark,space
- 【mark,备用】串口硬件流量控制说明
- S3C2440 UART串口驱动
- CRC16 串口校验
- s3c6410 s3c2440串口发送接收数据的实现(轮询)及相关寄存器
- 串口MSComm控件五种不同校验方式对数据收发的影响
- 关于S3C2440的串口号
- 三 ARM9(S3C2440)的串口UART——理论知识