② 外部驱动利用omap_rs485_dir_fun_reg注册函数对omap_rs485_dir_fun进行赋值。
void omap_rs485_dir_fun_reg(int port_num, set_rs485_direction_t rs485_dir_fun){
if (port_num>=OMAP_MAX_HSUART_PORTS)
printk(KERN_ERR “%s, port_num error max is %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切换为发送状态。
static incline void serial_omap_enable_ier_thri(struct uart_omap_port *up){
if (!(up->ier & UART_IER_THRI)) {
/* rs485 dir change to tx */
if (up->port.set_rs485_direction != NULL)
up->port.set_rs485_direction(SET_RS485_TX);
……//此处代码省略
}
}
⑥ serial_omap_stop_tx函数中把RS485切换为接收状态。
static void serial_omap_stop_tx(struct uart_omap_port *port){
……//此处代码省略
if (up->ier & UART_IER_THRI) {
up->ier &= ~UART_IER_THRI;
serial_out(up, UART_IER, up->ier);
/* rs485 dir change to rx */
if (port->set_rs485_direction != NULL)
port->set_rs485_direction(SET_RS485_RX);
}
}
⑦ transmit_chars更改一下,原先的代码是当没有更多的字符要发送(环形缓冲为空)时需要关闭发送中断,这时串口控制器发送BUF和移位寄存器中还是有数据的,这些数据串口控制器自动发送完成后才算结束,由于已经关闭了发送中断,因此发送结束后就没有中断产生了。但是RS485切换方向需要等到完全发送完成后才能进行。因此对transmit_chars函数做了修改。调用serial_omap_stop_tx函数前判断发送BUF和移位寄存器是否为空,如果为空就可以切换方向了。简而言之,延后了发送中断的关闭时间。
static void transmit_chars(struct uart_omap_port *up){
……//此处代码省略
if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
if (up->port.ops->tx_empty(&up->port)==0)
return;//added for last transmit
serial_omap_stop_tx(&up->port);
return;
}
……//此处代码省略
if (uart_circ_empty(xmit)) {
if (up->port.ops->tx_empty(&up->port)==0)
return;//added for last transmit
serial_omap_stop_tx(&up->port);
}
}
⑧ arch/arm/machomap2/boardti8168evm.c文件在ti8168_evm_init函数中调用omap_rs485_dir_fun_reg函数注册RS485切换函数。