先看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);
}
}