📄 嵌入式---程序示例1.htm
字号:
i;<BR> unsigned rev_type = 0;<BR><BR>
irq2dev_map[0] = dev;<BR><BR> /* set up the chip select
*/<BR> <BR><BR>
//下面这一段该怎么理解?看不懂阿<BR>
<BR>////++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++<BR>//这里是对CPU进行操作,对cs89进行初始化,我没有见到你的硬件原理图,我只能按CPU<BR>//的结构定义来解释一下,你要想搞清楚,只有看硬件原理图,还要参考CPU的硬件手册<BR>////++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
<BR> <BR>
<BR><BR>//连通PORT F I/O功能管脚1,SEL1(-IRQ5/PF1),<BR> *(volatile
unsigned char *)0xfffff42b |= 0x02; /* output /sleep */<BR>//设置PORT F
管脚0为输出,输出高电平<BR> *(volatile unsigned short *)0xfffff428 |=
0x0101; /* not sleeping */<BR><BR>//连通PORT F
中断功能管脚1,SEL1(-IRQ5/PF1)<BR> *(volatile unsigned char
*)0xfffff42b &= ~0x02; /* input irq5 */<BR>//PORT F 管脚1,SEL1(-IRQ5/PF1)
为输入方式,置低电平有效 <BR> *(volatile unsigned
short *)0xfffff428 &= ~0x0202; /* irq5 fcn on */<BR>
<BR>//在寄存器CSGBB中定义片选及cs89的基地址为:0x10000000.++++非常重要+++++++
<BR> *(volatile unsigned short *)0xfffff102 = 0x8000; /*
0x04000000
*/<BR>//在寄存器CSB中,片选使能,cs89地址空间大小(1M),数据线宽16位,6个等待周期,FLASH...,<BR>//非保护存储空间(128K)......
<BR> *(volatile unsigned short *)0xfffff112 = 0x01e7; /*
128k, 2ws, FLASH, en */<BR> <BR>//对PORT
G操作........ <BR> *(volatile unsigned int
*)0xfffff430 = 0x023c3d0a;<BR>
<BR>////++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++<BR>//这是I/O模式的主要的两个PORT口,一个是地址口,一个是数据口,这里对0x22操作,<BR>//中断IRQ0<BR>///+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
<BR> *(volatile unsigned
short*)0x1000030a=0x2200;<BR> *(volatile unsigned
short*)0x1000030c=0;<BR> <BR><BR>
//*(volatile unsigned short *)0xfffff302 |= 0x0080;<BR>
<BR> ......................</P>
<P> .....................</P>
<P>void<BR>reset_chip(struct device *dev)<BR>{<BR> int
reset_start_time;<BR> writereg(dev, PP_SelfCTL, readreg(dev,
PP_SelfCTL) | POWER_ON_RESET);<BR><BR> /* wait 30 ms
*/<BR> current->state =
TASK_INTERRUPTIBLE;<BR> current->timeout = jiffies +
3;<BR> schedule();<BR><BR> /* Wait until
the chip is reset */<BR> <BR>
//这里jiffies说是timestamp,时间标记,这个变量和current<BR>
//都在哪里定义?<BR>
//jiffies主要起什么作用?<BR>////+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++<BR>//这里是个延时等待,reset以后必须有等待,以便reset彻底完成,在reset过程中所有寄存器是关闭的<BR>//不但对cs89,对其他芯片也是一样的<BR>///++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
reset_start_time = jiffies;<BR> while( (readreg(dev,
PP_SelfST) & INIT_DONE) == 0 && jiffies - reset_start_time<
2);<BR>}</P>
<P>static int<BR>net_open(struct device *dev)<BR>{<BR>
struct net_local *lp = (struct net_local *)dev->priv;<BR>
int result = 0;<BR> int i;<BR><BR>
write_irq(dev, lp->chip_type, 0);<BR><BR> irq2dev_map[/*
FIXME */ 0] = dev;<BR> writereg(dev, PP_BusCTL, 0); /* ints
off!
*/<BR><BR>//这里和上面那个一样,怎么看懂?<BR>////++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++<BR>//这里也是CPU对CS89操作,我也根据CPU硬件手册给你大概说一下
<BR>///+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++<BR><BR>//中断信号,正电平触发(POL5)<BR>
*(volatile unsigned short *)0xfffff302 |= 0x0080; /* +ve pol irq
*/<BR><BR>//调整PORT G的输入输出状态,及设置管脚相应的电平信号
<BR> *(volatile unsigned int *)0xfffff430 =
0x023c3d0a; /* low -> high */<BR>
*(volatile unsigned int *)0xfffff430 = 0x023e3d0a;<BR>
*(volatile unsigned int *)0xfffff430 = 0x023c3d0a; /* high
-> low
*/<BR><BR>////++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++<BR>//这是I/O模式的主要的两个PORT口,一个是地址口,一个是数据口,这里对0x22操作,<BR>//中断IRQ0<BR>///+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
<BR> *(volatile unsigned short
*)0x1000030a = 0x2200; /* index window, REG index : 0022h
*/<BR> *(volatile unsigned short *)0x1000030c =
0x0000; /* data window, REG data : 0000h,irq0
*/<BR> <BR>.........................</P>
<P>.........................</P>
<P>static void<BR>net_rx(struct device *dev)<BR>{<BR> struct
net_local *lp = (struct net_local *)dev->priv;<BR> int
ioaddr = dev->base_addr;<BR> struct sk_buff
*skb;<BR> int status,
length;<BR><BR>//下面两行怎么右边是一样的?<BR>//是作者写错了吗?<BR>////++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++|<BR>//不是,这是一个包中前后不同的两个数据,前一个数据是该数据包的状态,后一个是数据包的长度<BR>////++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++<BR>
status = inw(ioaddr + RX_FRAME_PORT);<BR> length =
inw(ioaddr + RX_FRAME_PORT);<BR> if ((status & RX_OK) ==
0) {<BR>
lp->stats.rx_errors++;<BR> if
(status & RX_RUNT)
lp->stats.rx_length_errors++;<BR>
if (status & RX_EXTRA_DATA)
lp->stats.rx_length_errors++;<BR>
if (status & RX_CRC_ERROR) if (!(status &
(RX_EXTRA_DATA|RX_RUNT)))<BR>
/* per str 172
*/<BR>
lp->stats.rx_crc_errors++;<BR> if
(status & RX_DRIBBLE)
lp->stats.rx_frame_errors++;<BR>
return;<BR> }</P>
<BLOCKQUOTE>
<BLOCKQUOTE>
<P>......................</P></BLOCKQUOTE></BLOCKQUOTE>
<P>static int<BR>set_mac_address(struct device *dev, void
*addr)<BR>{<BR> int i;<BR> if
(dev->start)<BR> return
-EBUSY;<BR> <BR>
if(get_arena_addr())<BR>
{<BR>
memcpy(dev->dev_addr,0x1100000,6);<BR>
}<BR> else<BR> {<BR>
//这里的00hhcnl和前面<BR>//出现的00hhcn是什么意思?<BR>////+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++<BR>//注意:在这里他更改了网卡的MAC值,随便给了一个值"0x00,0x00,'h',h','c','n'",<BR>//不过这个48位值必须是世界唯一的,或者用网卡自带的也可以.我不能确定是否eeprom中有信息,<BR>//你可以用示波器量一下EEDI管脚,若为高电平,则EEPROM用到了,否则,他们根本没有用EEPROM.<BR>///++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
<BR> unsigned char
mac[]={0,0,'h','h','c','n'};<BR>
memcpy(dev->dev_addr,mac,6);<BR> }<BR>
printk("%s: Setting MAC address to ", dev->name);<BR> for
(i = 0; i < 6; i++)<BR> printk("
%2.2x", dev->dev_addr[i] = ((unsigned char
*)addr)[i]);<BR> printk(".\n");<BR> /* set
the Ethernet address */<BR> for (i=0; i < ETH_ALEN/2;
i++)<BR> writereg(dev, PP_IA+i*2,
dev->dev_addr[i*2] | (dev->dev_addr[i*2+1] <<
8));<BR><BR> return 0;<BR>}</P></BLOCKQUOTE>
<BLOCKQUOTE>
<BLOCKQUOTE>
<P> </P>
<P align=center><A
href="http://drew.nease.net/mypage/sourcecode.htm#returntop"><B>返回页首</B></A></P>
<P align=center> </P></BLOCKQUOTE></BLOCKQUOTE>
<P><BIG><A name=LCD></A></BIG><FONT color=black size=5><B>LCD
与触摸屏</B></FONT></P>
<P align=center><A
href="http://drew.nease.net/mypage/sourcecode.htm#returntop"><B>返回页首</B></A></P>
<P> </P>
<P><A name=MODEM></A><FONT color=black size=5><B>Modem拨号</B></FONT></P>
<BLOCKQUOTE>
<P><STRONG>Modem</STRONG>拨号程序步骤如下 </P>
<BLOCKQUOTE>
<P><BR>1. off hook,发出摘机命令(ATH1\r),
<BR> 等待modem返回状态,如果是"OK",则表示成功.进行第二步.
<BR>2. on hook 发出挂机命令(ATH\r),
<BR> 等待modem返回状态,如果是"OK",则表示成功.进行第三步.
<BR>3. off hook,dialing,摘机拨号(ATDT....\r),
<BR> 等待modem返回状态,如果是"CONNECT",则表示成功.进行第四步.
<BR>4. send data,发送数据. <BR><BR>最好按上述步骤一步一步调,并要等待正确的返回值后再进行下一步.
<BR><BR>具体程序例子如下,拨号: <BR><BR>// 清空接收FIFO
<BR> REG(FCR, nsChan) |=FCR_RXCLR;
<BR>// 等待,直到清空为止
<BR> while((REG(FCR, nsChan) & FCR_RXCLR) != 0x00);
<BR>// 拨号
<BR> while(atdt1[i]!=0) <BR> {
<BR>// 检查发送FIFO是否准备好,为空 <BR>
while((REG(LSR, nsChan) & LSR_THRE) == 0x00);
<BR>// 在发送FIFO中放入数据 <BR>REG(THR, nsChan) = atdt1[i];
<BR>i++; <BR> } <BR>
<BR>// 等待是否有数据到达,即modem返回数据.
<BR>while((REG(LSR, nsChan) & LSR_DR) == 0x00);
<BR>// 接收数据并判断返回值 <BR>response[i-19]=REG(RBR,nsChan);
<BR> if(response[0]!=0x43)
<BR> ..................
<BR> else
<BR> ..................
<BR>// 如果返回值是"connect",
<BR> while(*data!=0) <BR> {
<BR>
while((REG(LSR, nsChan) & LSR_THRE) == 0x00);
<BR>REG(THR, nsChan) = *data++; <BR> }
<BR>其他步骤基本一样. </P></BLOCKQUOTE>
<P><BR> 这是在ARM7上做的modem驱动,硬件设计方法是modem集成在主板上,没有用串口,modem是用片选地址直接对硬件操作的.</P>
<BLOCKQUOTE>
<P> </P></BLOCKQUOTE>
<P align=center><A
href="http://drew.nease.net/mypage/sourcecode.htm#returntop"><B>返回页首</B></A></P></BLOCKQUOTE>
<P> </P>
<P><A name=RTC></A><BIG><BIG><STRONG>RTC</STRONG></BIG></BIG></P>
<P align=center><A
href="http://drew.nease.net/mypage/sourcecode.htm#returntop"><B>返回页首</B></A></P></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -