关键网站,davinci_cfg_reg(DM365_UART1_TXD)的介绍
ti的芯片,主芯片的管脚是由几个特定的寄存器控制的,Pin Mux1,Pin Mux2.Pin Mun3等等
Pin Mux3 是第三个寄存器
背景:365的开发板,换个主芯片,lcd屏驱动,触摸屏驱动,串口驱动需要修改,有两个串口,其中一个是可以用的,目的是把另外一个修改成功。
1,需要修改两个文件,在内核的/arch/arm/mach-davinc下的dm365.c和board-dm365-evm.c
子dm365.c文件中要修改的就是把下面红色的注释掉,蓝色为需要的配置;其中每行的4个数的意思为:
第一个数字代表用的第几个寄存器(要用的寄存器编号)
第二个数字代表寄存器的第几位开始控制这个管脚
第三个数字代表用寄存器要用几位来表示
第四个数字代表要用的管脚的功能模式(复用寄存器设置管脚的功能,如00代表GPIO,01代表SPI,10代表I2c,11代表uart)
static const struct mux_config dm365_pins[] = {
#ifdef CONFIG_DAVINCI_MUX
MUX_CFG(DM365, MMCSD0, 0, 24, 1, 0, false)
MUX_CFG(DM365, SD1_CLK, 0, 16, 3, 1, false)
MUX_CFG(DM365, SD1_CMD, 4, 30, 3, 1, false)
MUX_CFG(DM365, SD1_DATA3, 4, 28, 3, 1, false)
MUX_CFG(DM365, SD1_DATA2, 4, 26, 3, 1, false)
MUX_CFG(DM365, SD1_DATA1, 4, 24, 3, 1, false)
MUX_CFG(DM365, SD1_DATA0, 4, 22, 3, 1, false)
MUX_CFG(DM365, I2C_SDA, 3, 23, 3, 2, false)
MUX_CFG(DM365, I2C_SCL, 3, 21, 3, 2, false)
MUX_CFG(DM365, AEMIF_AR, 2, 0, 3, 1, false)
MUX_CFG(DM365, AEMIF_A3, 2, 2, 3, 1, false)
MUX_CFG(DM365, AEMIF_A7, 2, 4, 3, 1, false)
MUX_CFG(DM365, AEMIF_D15_8, 2, 6, 1, 1, false)
MUX_CFG(DM365, AEMIF_CE0, 2, 7, 1, 0, false)
MUX_CFG(DM365, MCBSP0_BDX, 0, 23, 1, 1, false)
MUX_CFG(DM365, MCBSP0_X, 0, 22, 1, 1, false)
MUX_CFG(DM365, MCBSP0_BFSX, 0, 21, 1, 1, false)
MUX_CFG(DM365, MCBSP0_BDR, 0, 20, 1, 1, false)
MUX_CFG(DM365, MCBSP0_R, 0, 19, 1, 1, false)
MUX_CFG(DM365, MCBSP0_BFSR, 0, 18, 1, 1, false)
MUX_CFG(DM365, SPI0_SCLK, 3, 28, 1, 1, false)
MUX_CFG(DM365, SPI0_SDI, 3, 26, 3, 1, false)
MUX_CFG(DM365, SPI0_SDO, 3, 25, 1, 1, false)
//MUX_CFG(DM365, SPI0_SDENA0, 3, 29, 3, 1, false)
//MUX_CFG(DM365, SPI0_SDENA1, 3, 26, 3, 2, false)
MUX_CFG(DM365, UART0_RXD, 3, 20, 1, 1, false)
MUX_CFG(DM365, UART0_TXD, 3, 19, 1, 1, false)
//MUX_CFG(DM365, UART1_RXD, 3, 17, 3, 2, false)
//MUX_CFG(DM365, UART1_TXD, 3, 15, 3, 2, false)
//RXD为receive data接收数据
//TXD为transmit data 发送数据
MUX_CFG(DM365, UART1_RXD, 4, 14, 3, 3, false) //RXD__
MUX_CFG(DM365, UART1_TXD, 3, 29, 3, 3, false) //TXD__
MUX_CFG(DM365, UART1_RTS, 3, 23, 3, 1, false)//硬流控,这里不是半双工的传输模式,是硬流控
MUX_CFG(DM365, UART1_CTS, 3, 21, 3, 1, false)//硬流控,如果没有RTS和CTS,是软流控,
MUX_CFG(DM365, EMAC_TX_EN, 3, 17, 3, 1, false)
MUX_CFG(DM365, EMAC_TX_CLK, 3, 15, 3, 1, false)
MUX_CFG(DM365, EMAC_COL, 3, 14, 1, 1, false)
MUX_CFG(DM365, EMAC_TXD3, 3, 13, 1, 1, false)
MUX_CFG(DM365, EMAC_TXD2, 3, 12, 1, 1, false)
MUX_CFG(DM365, EMAC_TXD1, 3, 11, 1, 1, false)
MUX_CFG(DM365, EMAC_TXD0, 3, 10, 1, 1, false)
MUX_CFG(DM365, EMAC_RXD3, 3, 9, 1, 1, false)
MUX_CFG(DM365, EMAC_RXD2, 3, 8, 1, 1, false)
MUX_CFG(DM365, EMAC_RXD1, 3, 7, 1, 1, false)
MUX_CFG(DM365, EMAC_RXD0, 3, 6, 1, 1, false)
MUX_CFG(DM365, EMAC_RX_CLK, 3, 5, 1, 1, false)
MUX_CFG(DM365, EMAC_RX_DV, 3, 4, 1, 1, false)
MUX_CFG(DM365, EMAC_RX_ER, 3, 3, 1, 1, false)
MUX_CFG(DM365, EMAC_CRS, 3, 2, 1, 1, false)
MUX_CFG(DM365, EMAC_MDIO, 3, 1, 1, 1, false)
MUX_CFG(DM365, EMAC_MDCLK, 3, 0, 1, 1, false)
MUX_CFG(DM365, KEYSCAN, 2, 0, 0x3f, 0x3f, false)
MUX_CFG(DM365, PWM0, 1, 0, 3, 2, false)
MUX_CFG(DM365, PWM0_G23, 3, 26, 3, 3, false)
MUX_CFG(DM365, PWM1, 1, 2, 3, 2, false)
//MUX_CFG(DM365, PWM1_G25, 3, 29, 3, 2, false)//for uart1
MUX_CFG(DM365, PWM2_G87, 1, 10, 3, 2, false)
MUX_CFG(DM365, PWM2_G88, 1, 8, 3, 2, false)
MUX_CFG(DM365, PWM2_G89, 1, 6, 3, 2, false)
MUX_CFG(DM365, PWM2_G90, 1, 4, 3, 2, false)
MUX_CFG(DM365, PWM3_G80, 1, 20, 3, 3, false)
MUX_CFG(DM365, PWM3_G81, 1, 18, 3, 3, false)
MUX_CFG(DM365, PWM3_G85, 1, 14, 3, 2, false)
MUX_CFG(DM365, PWM3_G86, 1, 12, 3, 2, false)
MUX_CFG(DM365, SPI1_SCLK, 4, 2, 3, 1, false)
MUX_CFG(DM365, SPI1_SDI, 3, 31, 1, 1, false)
MUX_CFG(DM365, SPI1_SDO, 4, 0, 3, 1, false)
MUX_CFG(DM365, SPI1_SDENA0, 4, 4, 3, 1, false)
MUX_CFG(DM365, SPI1_SDENA1, 4, 0, 3, 2, false)
MUX_CFG(DM365, SPI2_SCLK, 4, 10, 3, 1, false)
MUX_CFG(DM365, SPI2_SDI, 4, 6, 3, 1, false)
MUX_CFG(DM365, SPI2_SDO, 4, 8, 3, 1, false)
MUX_CFG(DM365, SPI2_SDENA0, 4, 12, 3, 1, false)
MUX_CFG(DM365, SPI2_SDENA1, 4, 8, 3, 2, false)
MUX_CFG(DM365, SPI3_SCLK, 0, 0, 3, 2, false)
MUX_CFG(DM365, SPI3_SDI, 0, 2, 3, 2, false)
MUX_CFG(DM365, SPI3_SDO, 0, 6, 3, 2, false)
MUX_CFG(DM365, SPI3_SDENA0, 0, 4, 3, 2, false)
MUX_CFG(DM365, SPI3_SDENA1, 0, 6, 3, 3, false)
MUX_CFG(DM365, SPI4_SCLK, 4, 18, 3, 1, false)
//MUX_CFG(DM365, SPI4_SDI, 4, 14, 3, 1, false)//for uart1
MUX_CFG(DM365, SPI4_SDO, 4, 16, 3, 1, false)
MUX_CFG(DM365, SPI4_SDENA0, 4, 20, 3, 1, false)
MUX_CFG(DM365, SPI4_SDENA1, 4, 16, 3, 2, false)
MUX_CFG(DM365, GPIO20, 3, 21, 3, 0, false)
MUX_CFG(DM365, GPIO33, 4, 12, 3, 0, false)
MUX_CFG(DM365, GPIO40, 4, 26, 3, 0, false)
MUX_CFG(DM365, GPIO80, 1, 20, 3, 1, false)
MUX_CFG(DM365, GPIO82, 1, 17, 1, 1, false)
MUX_CFG(DM365, VCLK, 1, 22, 1, 0, false)
MUX_CFG(DM365, VOUT_FIELD, 1, 18, 3, 1, false)
MUX_CFG(DM365, VOUT_FIELD_G81, 1, 18, 3, 0, false)
MUX_CFG(DM365, VOUT_HVSYNC, 1, 16, 1, 0, false)
MUX_CFG(DM365, VOUT_COUTL_EN, 1, 0, 0xff, 0x55, false)
MUX_CFG(DM365, VOUT_COUTH_EN, 1, 8, 0xff, 0x55, false)
MUX_CFG(DM365, VIN_CAM_WEN, 0, 14, 3, 0, false)
MUX_CFG(DM365, VIN_CAM_VD, 0, 13, 1, 0, false)
MUX_CFG(DM365, VIN_CAM_HD, 0, 12, 1, 0, false)
MUX_CFG(DM365, VIN_YIN4_7_EN, 0, 0, 0xff, 0, false)
MUX_CFG(DM365, VIN_YIN0_3_EN, 0, 8, 0xf, 0, false)
INT_CFG(DM365, INT_EDMA_CC, 2, 1, 1, false)
INT_CFG(DM365, INT_EDMA_TC0_ERR, 3, 1, 1, false)
INT_CFG(DM365, INT_EDMA_TC1_ERR, 4, 1, 1, false)
INT_CFG(DM365, INT_EDMA_TC2_ERR, 22, 1, 1, false)
INT_CFG(DM365, INT_EDMA_TC3_ERR, 23, 1, 1, false)
INT_CFG(DM365, INT_PRTCSS, 10, 1, 1, false)
INT_CFG(DM365, INT_EMAC_RXTHRESH, 14, 1, 1, false)
INT_CFG(DM365, INT_EMAC_RXPULSE, 15, 1, 1, false)
INT_CFG(DM365, INT_EMAC_TXPULSE, 16, 1, 1, false)
INT_CFG(DM365, INT_EMAC_MISCPULSE, 17, 1, 1, false)
INT_CFG(DM365, INT_IMX0_ENABLE, 0, 1, 0, false)
INT_CFG(DM365, INT_IMX0_DISABLE, 0, 1, 1, false)
INT_CFG(DM365, INT_HDVICP_ENABLE, 0, 1, 1, false)
INT_CFG(DM365, INT_HDVICP_DISABLE, 0, 1, 0, false)
INT_CFG(DM365, INT_IMX1_ENABLE, 24, 1, 1, false)
INT_CFG(DM365, INT_IMX1_DISABLE, 24, 1, 0, false)
INT_CFG(DM365, INT_NSF_ENABLE, 25, 1, 1, false)
INT_CFG(DM365, INT_NSF_DISABLE, 25, 1, 0, false)
EVT_CFG(DM365, EVT2_ASP_TX, 0, 1, 0, false)
EVT_CFG(DM365, EVT3_ASP_RX, 1, 1, 0, false)
#endif
};
*********************************************************************************************
*********************************************************************************************
第二个文件board-dm365-evm.c要修改的地方:在970行附近,要加上下面的红色部分
static __init void dm365_evm_init(void)
{
evm_init_i2c();
//______
davinci_cfg_reg(DM365_UART1_TXD);
davinci_cfg_reg(DM365_UART1_RXD);
printk("\n____20120808......____\n");
davinci_serial_init(&uart_config);
dm365evm_emac_configure();
dm365evm_usb_configure();
davinci_setup_mmc(0, &dm365evm_mmc_config);
/* maybe setup mmc1/etc ... _after_ mmc0 */
evm_init_cpld();
dm365_init_asp(&dm365_evm_snd_data);
dm365_init_rtc();
dm365_init_ks(&dm365evm_ks_data);
dm365_init_spi0(BIT(0), dm365_evm_spi_info,
ARRAY_SIZE(dm365_evm_spi_info));
dm365_init_spi1(BIT(0), dm365_evm_spi1_info,
ARRAY_SIZE(dm365_evm_spi1_info));
//dm365_init_tsc2004();
}
重新编译,在内核外边编译(在进入开发包后编译,psp所在的目录处)make linux 就行了
修改uboot启动参数,把ttyS0改为ttyS1,或者同时用两根串口线,开两个超级终端,就能看到另外
一个串口打印信息了
DM365的BSP主要包含mach-davinci和plat-davinci两个目录(及相关头文件),BSP(BSP板级支持包(board support package), 是介于主板硬件和操作系统中驱动层程序之间的一层,一般认为它属于操作系统一部分,主要是实现对操作系统的支持,为上层的驱动程序提供访问硬件设备寄存器 的函数包,)复杂庞大又极其重要,它主要完成了板级的初始化,比如内存映射,时钟和电源初始化,中断和IO初始化,CPU及各模块的初始化,相关平台设备,总线设备的注册等等。下面就分板一下DM365的BSP部分,以程序流程为纵线,以各个文件为横线,进行分析。
内核在经过一系列的初始化后会进行板级的初始化,主要依靠一个MACHINE_START宏,DM365的板定义宏在board-dm365-evm.c文件中,这个宏有以下几个成员phys_io,io_pg_offst,boot_params,map_io,init_irq,timer,init_machine。这些成员变量或函数将会由内核在初始化时在适当的时机调用。DM365开发板对这几个成员都有针对其开发板的内容,phy_io设置为0x01c00000,这是DM365寄存器的起始地址。boot_params为0x80000100,它在DDR中,是用来存放UBOOT的传递参数的。map_io会调用davinci_map_io函数,完成开发板的静态地址映射,同时开发板中此函数还完成了MUX的功能初始化及各模块时钟的初始化。init_irq会调用davinci_dm365_evm_irq_init函数,对开发板的中断系统进行初始化。timer会调用davinci_timer相关的成员,它完成开发板的时间管理初始化。init_machine调用dm365_evm_init函数,完成板级设备(部分)的初始化。下面我们从davinci_map_io函数开始。
davinci_map_io函数主要由三个部分组成,第一是中断优先级的初始化,中断优先级的初始化就是将全局中断优先级结构指针davinci_irq_priorities指向一个默认的中断优先级数组dm365_default_priorities,这个第二是调用davinci_map_common_io函数完成静态地址映射,第三是调用davinci_init_common_hw函数完成MUX的功能初始化及各模块时钟的初始化。
davinci_map_common_io函数最主要就是完成了一段物理地址的静态虚拟地址映射,此后程序中操作这段物理地址的内容时不必再用ioremap动态得到一个虚拟地址了。至于如何做到映射的,不用去深究,只需要在map_desc结构定义的本平台使用的davinci_io_desc[]数组中中添加我们需要映射的地址段就可以了。开发板原程序中只映射了平台寄存器部分的地址空间,其物理起始地址,地址段大小,欲映射成的虚拟起始地址等值填入这个结构中就可以了。这些值定义中io.h文件中,其中物理起始地址IO_PHYS为0x01c00000,这正是寄存器物理地址段的起始地址,地址段大小IO_SIZE为0x00400000,这两个值由手册都可以知道。至于欲映射成的虚拟起始地址则由我们人为决定,可以选用IO_VIRT为0xfbc00000,这样物理地址和虚拟地址就有一个简单的偏移关系IO_OFFSET为0xfa000000。有了这个偏移关系,物理地址便和虚拟地址随时进行变换了,我们可以封装一个宏IO_ADDRESS用来做为物理地址到虚拟地址的转换。这里需要特别注意的,物理地址和虚拟地址的这层映射关系是内核来确定的,而两个地址的简单偏移关系是我们人为决定的,为了处理简单我们选了一个与物理地址有简单偏移关系的地址作为虚拟地址,并让内核去认同。静态映射一定要搞清楚这里面的东西,一开始很容易被迷惑的。davinci_map_common_io函数完成以后,接着是davinci_init_common_hw函数。
davinci_init_common_hw函数极其重要,它里面只有两个函数,davinci_mux_init函数完成模块引脚复用功能的初始化,davinci_clk_init函数完成模块时钟的初始化。
davinci_mux_init函数将各模块的复用进行初始化。它首先将几个重要的结构赋值,davinci_pins是二维指针,它被赋给一个和平台有关的默认的全局结构,比如dm365_pins,它是一个二维数组,分别定义了若干模块及每个模块需要用到的引脚,注意这个维数的索引值是对应模块在PSC管理中的索引值的。davinci_num_pins就是dm365_pins数组的维数。定义一个pin_config结构的指针table,并指向一个默认的全局结构数组davinci_dm365_pinmux,并得到这个数组的维数size。davinci_dm365_pinmux数组极其重要,它的每一维元素都是一个pin_config结构,它是用一个MUX_CFG宏来构造的,用于模块引脚复用功能的选择,实质是构造了欲对PINMUXx寄存器操作的位和欲写入的值。这个要好好理解,配合手册中PINMUXx寄存器理解。几个结构赋值以后就调用davinci_mux_register函数,这个函数将table赋给了全局结构指针pin_table,将size赋给全局变量pin_table_sz,将davinci_get_pins函数地址赋给函数指针get_pin_list,将一个标识用到哪一个pinmux寄存器的数组首址赋给全局指针pinmux_in_use。davinci_get_pins这个函数的作用是通过参数ctr和id来返回davinci_pins数组的某一维,它表示某一个模块用到的引脚。
davinci_clk_init函数完成模块时钟的初始化。它首先将PSC寄存器的地址赋给全局指针psc_bases,然后通过读取PLL相关的寄存器得到预分频,倍频,后分频,分频等值(注意这些设置都在UBL进行设置好了,这里仅仅是读值),这样就得到了各个模块的时钟值,把它们赋给若干全局变量,比如armrate,voicerate,commonrate,vpssrate,ddrrate等。然后定义一个clk结构的指针clk_list,并指向一个默认的全局结构数组davinci_dm365_clks,并得到这个数组的维数num_clks。davinci_dm365_clks数组的每一维元素都是一个clk结构,定义了平台各个模块的时钟管理参数,包括模块名,时钟值,本模块在电源域的索引序号等。以后对某一模块进行时钟电源的开关就是操纵这个结构。
然后调用davinci_enable_clks函数,这个函数实质是循环调用了clk_register函数和clk_enable函数,从而使能davinci_dm365_clks数组中定义的每一个模块的电源时钟。clk_register函数将当前模块放入全局的clocks链表中,而后根据usecount的判断值调用clk_enable函数,再调用__clk_enable函数,而其最终调用davinci_psc_config函数完成某一模块的时钟电源使能。需要特别注意的是此时几乎全部模块的usecount都不满足,不会调用clk_enable函数,而即使调用了clk_enable函数(AEMIF),也不会真正调用__clk_enable函数。也就是说这初始化部分并没有真正使能很多模块的时钟电源,只是按初始化的流程走了一个过程而已。在后面要提到的板级设备初始化部分会调用davinci_psc_config函数真正使能一些模块的时钟电源。另外其它模块的时钟电源则分布在各个模块的驱动程序中,当驱动加载的时候才会调用clk_enable函数打开这个模块的时钟电源。这部分挺迷惑人的,好好理解。
davinci_psc_config函数的前一半工作是操作PSC相关的寄存器来使能模块的时钟电源,这部分的操作详见数据手册,是按手册的步骤来实现的,另一半工作是调用davinci_pinmux_setup函数来将此模块相关的复用引脚功能确定,它首先调用get_pin_list函数,它是个函数指针,在先前已经被指向了davinci_get_pins函数,它通过ctlr和id两个参数从先前的dm365_pins数组中得到相应的某一维,这正是某一模块需要的那些引脚。然后再通过一个循环将这几个引脚调用davinci_cfg_reg函数实现其复用的本模块的功能。
davinci_cfg_reg函数,很重要也很复杂。它定义一个pin_config类型的指针cfg指向当前引脚在pin_table的位置,然后根据其所在的PINMUXx寄存器的位为操作。这里的实现过程操作比较复杂,涉及到屏蔽位,模式等,但总的来说就是模块需要这个引脚做此模块功能而不是其它功能,暂不深究。
到这里,davinci_cfg_reg函数结束了,davinci_pinmux_setup函数也就结束了,davinci_psc_config函数也就结束了,__clk_enable,clk_enable,davinci_enable_clks函数也就结束了,davinci_clk_init函数也就结束了,davinci_init_common_hw函数也就结束了,davinci_map_io函数也就结束了。DM365的BSP板定义宏中的map_io也就结束了。下面分析板定义宏中的init_irq,它指向davinci_dm365_evm_irq_init函数,下面开始分析davinci_dm365_evm_irq_init函数。
davinci_dm365_evm_irq_init函数,只调用一个davinci_irq_init函数。它首先获得全部64个中断的优先级数组,这个前面已经得到并放在全局数组davinci_irq_priorities中。而后操作INTC的寄存器,比如清除中断请求,禁止中断等,而后将设置好的优先级值写入优先级寄存器中。然后就将全部64个中断注册到内核中,主要是利用内核中断管理中的set_irq_chip函数,set_irq_flags函数,set_irq_handler函数,特别是set_irq_chip函数,它将每一个中断绑定到一个irq_chip结构类型的davinci_irq_chip_0,而它包括了三个对中断的处理的函数指针,比如使能unmask,禁止mask等,其实质还是操作了INTC的相关寄存器。这些函数就是在程序中,对某一中断进行使能,禁止的处理,比如调用enable_irq使能某一个中断时,其实最终就是调用unmask所指的函数。
至此,davinci_irq_init函数结束了,davinci_dm365_evm_irq_init函数也就结束了。DM365的BSP板定义宏中的init_irq也就结束了。板定义宏中的timer感觉很复杂,现在不是很理解,以后有机会再看。下面分析板定义宏中的init_machine,它指向dm365_evm_init函数,下面开始分析dm365_evm_init函数。
dm365_evm_init函数是BSP中最重要的了,它完成了部分设备的初始化及注册。
在RS232中本来CTS 与RTS 有明确的意义,但自从贺氏(HAYES ) 推出了聪明猫(SmartModem)后就有点混淆了。在RS232中RTS 与CTS 是用来半双工模式下的方向切换;HAYES Modem中的RTS ,CTS 是用来进 行硬件流控的。通常UART的RTC、CTS 的含义指后者,即用来做硬流控的。
硬流控的RTS 、CTS :RTS (Require To Send,发送请求)为输出信号,用于指示本设备准备好可接收;CTS(Clear To Send,发送清除)为输入信号,有效时停止发送。假定A、B两设备通信,A设备的RTS 连接B设备的CTS ;A设备的CTS 连接B设备 的RTS 。 前一路信号控制B设备的发送,后一路信号控制A设备的发送。对B设备的发送(A设备接收)来说,如果A设备接收缓冲快满的时发出RTS 信号(意思 通知B设备停止发送),B设备通过CTS 检测到该信号,停止发送;一段时间后A设备接收缓冲有了空余,发出RTS 信号,指示B设备开始发送数据。A设备发(B设备接收) 类似。上述功能也能在数据流中插入Xoff(特殊字符)和Xon(另一个特殊字符)信号来实现。A设备一旦接收到B设备发送过来的Xoff,立刻停止发 送;反之,如接收到B设备发送过来的Xon,则恢复发送数据给B设备。同理,B设备也类似,从而实现收发双方的速度匹配。
半双工的方向切换:RS232中使用DTR(Date Terminal Ready,数据终端准备)与DSR(Data Set Ready ,数据设备准备好)进行主流控,类似上述的RTS 与CTS 。对半双工的通信的DTE(Date Terminal Equipment,数据终端设备)与DCE(Data circuit Equipment )来说,默认的方向是DTE接收,DCE发送。如果DTE要发送数据,必须发出RTS 信号,请求发送数据。DCE收到后如果 空闲则发出CTS 回 应RTS 信 号,表示响应请求,这样通信方向就变为DTE->TCE,同时RTS 与CTS 信号必须一直保持。从这里可以看出,CTS ,TRS虽 然也有点流控的意思(如CTS 没有发出,DTE也不能发送数据),但主要是用来进行方向切换的。
如果UART只有RX、TX两个信号,要流控的话只能是软流控;如果有RX,TX,CTS ,RTS 四个信号,则多半是支持硬流控的UART;如果有 RX,TX,CTS ,RTS ,DTR,DSR 六个信号的话,RS232标准的可能性比较大。
顺便提一下:
DCD( Data Carrier Detect, 数据载波检测):DCE向DTE指示,线路上检测到载波。
RI(Ring Indicator,振铃指示):DCE向DTE指示,有呼叫接入。
一个工程师遇到的问题如下:
想在dm365上使用uart1用于GPS数据接收。gps
datasheet要求波特率9600。
对linux-2.6.18_pro500/arch/arm/mach-davinci下mux_cfg.c做如下修改配置uart1:
MUX_CFG("UART1_RXD2", 4, 14, 3, 3,
0)
MUX_CFG("UART1_TXD2", 3, 29, 3, 3,
0)
同时添加以下代码:
static const short dm365_uart1_pins[] =
{
DM365_UART1_RXD2, DM365_UART1_TXD2,
-1
};
static const short
*dm365_pins[DAVINCI_LPSC_IMCOP + 1] = {
...
[DAVINCI_LPSC_UART1]
=
dm365_uart1_pins,
...
};
编译下载启动信息显示:
cd
/dev没有发现ttyS0和ttyS1,手动创建节点
mknod ttyS0 c 4 64
mknod ttyS1 c 4 65
然后cat
ttyS1接收数据,但是没有反应,往ttyS1发送的话,好像可以
查看ttyS1的信息波特率就是9600。不清楚为什么ttyS1无**常接收。
ps:gps模块是可以接收数据的,因为放别的板子上可以正常工作。