2.3UBoot代码修改
需要修改的文件:
①board/ti/ti8168/evm.c
②drivers/serial/ns16550.c
③include/configs/ti8168_evm.h
ti8168_evm.h文件中增加切换宏定义:
#defineCONFIG_RS485_DIR_SW1
evm.c文件中增加切换函数:
voidrs485_dir_sw(intrs485_dir){
if(rs485_dir==0)
_raw_writel(RS485_DIR_MASK,TI81XX_GPIO1_CLEARDATAOUT);
else
_raw_writel(RS485_DIR_MASK,TI81XX_GPIO1_SETDATAOUT);
}
s16550.c串口驱动文件中增加RS485方向控制:
voidNS16550_putc(NS16550_tcom_port,charc){
#ifdefCONFIG_RS485_DIR_SW
rs485_dir_sw(1);
#endif
……//此处代码省略
#ifdefCONFIG_RS485_DIR_SW
while((serial_in(&com_port->lsr)&UART_LSR_TEMT)==0)
rs485_dir_sw(0);
#endif
}
其中UART_LSR_TEMT表示发送BUF和移位寄存器为空。默认情况下RS485是接收状态,一旦要发送数据,就把RS485切换为发送状态。发送完数据后,等待发送BUF和移位寄存器为空,然后切换回接收状态,这里无需使用timeout。
2.4Linux代码修改
需要修改的文件:
①arch/arm/machomap2/bordti8168evm.c
②drivers/serial/omapserial.c
③include/linux/serial_core.h
serial_core.h文件,uart_port结构体中增加set_rs485_direction函数指针,用于执行RS485的方向切换void(*set_rs485_direction)(intrs485_dir);原本考虑在uart_ops结构体中增加的,但是这个结构体是常量类型,对它不作改动,因此加到了uart_port结构体中。在该文件中添加相关宏定义和函数指针类型用于函数注册:
#defineSET_RS485_RX0
#defineSET_RS485_TX1
typedefvoid(*set_rs485_direction_t)(intrs485_dir);//用于函数注册
omapserial.c文件主要做了如下几点改动:
①添加omap_rs485_dir_fun全局的函数指针。
staticset_rs485_direction_tomap_rs485_dir_fun[OMAP_MAX_HSUART_PORTS]={NULL,NULL,NULL,NULL,NULL,NULL}
②外部驱动利用omap_rs485_dir_fun_reg注册函数对omap_rs485_dir_fun进行赋值。
voidomap_rs485_dir_fun_reg(intport_num,set_rs485_direction_trs485_dir_fun){
if(port_num>=OMAP_MAX_HSUART_PORTS)
printk(KERN_ERR"%s,port_numerrormaxis%d,but%d\\n",__FUNCTION__,OMAP_MAX_HSUART_PORTS-1,port_num);
omap_rs485_dir_fun[port_num]=rs485_dir_fun;
}
EXPORT_SYMBOL(omap_rs485_dir_fun_reg);
③serial_omap_probe函数中对控制程序中用到的up->port.set_rs485_direction进行赋值。
up->port.set_rs485_direction=omap_rs485_dir_fun[pdev->id];
④默认情况下RS485处于接收状态。
⑤serial_omap_enable_ier_thri函数中把RS485切换为发送状态。
staticinclinevoidserial_omap_enable_ier_thri(structuart_omap_port*up){
if(!(up->ier&UART_IER_THRI)){
/*rs485dirchangetotx*/
if(up->port.set_rs485_direction!=NULL)
up->port.set_rs485_direction(SET_RS485_TX);
……//此处代码省略
}
}
⑥serial_omap_stop_tx函数中把RS485切换为接收状态。
staticvoidserial_omap_stop_tx(structuart_omap_port*port){
……//此处代码省略
if(up->ier&UART_IER_THRI){
up->ier&=~UART_IER_THRI;
serial_out(up,UART_IER,up->ier);
/*rs485dirchangetorx*/
if(port->set_rs485_direction!=NULL)
port->set_rs485_direction(SET_RS485_RX);
}
}