Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++
12678 Discussions

overriding HAL driver, alt_sys_init()

Altera_Forum
Honored Contributor II
2,016 Views

On my system there are 3 uarts and with one of them I'd like to use a custom uart driver. Referring to the software developer's handbook for overriding default device drivers I switched to the software build flow (which I am new to) and called 

 

set_driver my_uart_driver uart_2 

 

in the bsp's tcl script. For now the my_uart driver is just a copy of altera's driver with all instances of altera_avalon_uart replaced by my_uart, with appropriate capitalization, except for the hw_class_name property in my_uart_sw.tcl.  

 

Looking at the bsp's summary.html correctly shows that my_uart_driver is used for uart_2, however when looking at alt_sys_init.c it looks like it is not calling the MY_UART_INSTANCE or MY_UART_INIT macros on this device but rather the ALTERA_AVALON_UART_ ones. Auto_initialize is set to true in my_uart_sw.tcl so I am not sure why it isn't using my driver's macros.  

 

Any info about what is going on would be appreciated. Thanks!
0 Kudos
6 Replies
Altera_Forum
Honored Contributor II
787 Views

I've never attempted what you're trying. However, my suspicion is that the tools are generating the macro calls in alt_sys_init.c based off of the name of the component rather than the name of the driver. 

 

1 - Double check that everything you've done for your driver is consistent and uses the naming "my_uart ..." rather than "altera_avalon_uart ...". 

 

If that doesn't work ... 

2 - You may need to actually create a copy of the uart component and rename everything. 

 

Jake
0 Kudos
Altera_Forum
Honored Contributor II
787 Views

Thanks for the response Jake. I suspect your suspicion about the bsp tool generating the macro call from the component name rather than the driver is probably correct. 

 

I think I replaced all the significant altera_avalon_uart's in the driver directory. Here is the output from a grep in the driver directory,  

$ grep -irn altera_avalon_uart . 

./class.ptf:2:# class.ptf for altera_avalon_uart 

./class.ptf:16: CLASS altera_avalon_uart 

./class.ptf:59: class = "altera_avalon_uart"; 

./class.ptf:61: iss_model_name = "altera_avalon_uart"; 

./HAL/system.h_component_output.gtf:5: altera_avalon_uart class of components. It expects the following 

./my_uart_sw.tcl:8:# Associate it with some hardware known as "altera_avalon_uart" 

./my_uart_sw.tcl:10:set_sw_property hw_class_name altera_avalon_uart 

I got a similar result when using the FIFO uart from these forums, but didn't implement the hardware so perhaps that was a doomed attempt. 

 

Actually, the whole reason for the custom uart is because we are using a bit from a PIO component to control the direction of traffic on a rs485 transceiver. Apparently the fifo uart has this ability but I am trying to do it in software before asking the person in charge of the hardware to make any changes.
0 Kudos
Altera_Forum
Honored Contributor II
787 Views

How curious, I had to do the exact same thing a few years ago. I believe I ended up using the FIFOed UART. 

 

Jake
0 Kudos
Altera_Forum
Honored Contributor II
787 Views

It seems useful whenever rs-485 comes up to have an option for it as a part of the uart hardware. I'll probably end up using the FIFOed UART as well...I hope. Thanks.

0 Kudos
Altera_Forum
Honored Contributor II
787 Views

This is an old post but I thought I'd post my solution to this RS-485 issue in case someone else finds it useful. 

 

I ended up modifying the altera_avalon_uart driver so that it could use the PIO to toggle the direction of the RS-485 transceiver. To do this I modified the uart write function, which I call co_avalon_rs485_write here, such that at the very beginning I put  

 

IOWR_ALTERA_AVALON_PIO_DATA(GENERAL_PIO_BASE, 0x1); 

 

to enable writes. Then just before the "return (len - count)" call I turn it back off. However it was also necessary to make sure the shift register had drained before toggling this bit back so what I have is, 

 

/* If in blocking mode, wait for data to be sent out before puting 

* the rs-485 transceiver into receive mode. */ 

if (!(flags & O_NONBLOCK)) { 

 

/* wait for circular transmit buffer to drain to transmitter 

* shift register */ 

while ((sp->tx_start != sp->tx_end)){ 

/* interrupts here drain tx_buffer until tx_start=tx_end */ 

 

/* setup to monitor status register */ 

base = sp->base;  

status = IORD_CO_AVALON_RS485_STATUS(base); 

 

/* wait for transmitter shift register to drain */ 

while(!(status & CO_AVALON_RS485_STATUS_TMT_MSK)) { 

status = IORD_CO_AVALON_RS485_STATUS(base); 

 

/* put rs-485 transceiver into receive mode */ 

IOWR_ALTERA_AVALON_PIO_DATA(GENERAL_PIO_BASE, 0x0); 

 

/* return the number of bytes written */ 

 

return (len - count);
0 Kudos
Altera_Forum
Honored Contributor II
787 Views

Hi Kepler, 

 

Thank you very much for the useful post. 

According to my understand, the current HAL driver does not support RS485, and with the above patch you've managed to work successfuly with RS485. 

Is that right ? 

 

Thanks, 

Ran
0 Kudos
Reply