FabianL
Occasional Contributor
3 hours agoNIOS V: Systick based timeouts not available when using internal timer
Hello,
We are using Quartus 25.1 Standard. I came across something, which I would consider a but in the BSP generated HAL files, or at least a major limitation in the usage of NIOS V.
System Setup:
- NIOS V + JTAG UART
- NIOS V in internal Timer as Sys_clk_timer
- BSP Setting:
Problems:
- The JTAG UART drivers have a timeout functionality based on the systick interrupt to avoid getting stuck, in case there is not JTAG UART connected, so the internal buffer fills up. --> see altera_avalon_jtag_uart_timeout()
- This used to work fine with:
- NIOS II Setup (using external Timer)
- NIOS V Setup with external Timer block as sys_clk_timer
- But when using the NIOS V internal as sys_clk_timer the JTAG UART timeout does not trigger and when calling alt_printf it gets stuck in altera_avalon_jtag_uart_write
/*
* No OS present: Always wait for data to be removed from buffer. Once
* the interrupt routine has removed some data then we will be able to
* insert some more.
*/
while (out == sp->tx_out && sp->host_inactive < sp->timeout)
Analysis
- When I check the initialization routine of the JTAG UART altera_avalon_jtag_uart_init by stepping through with the debugger, I realize, the alarm is not setup:
/*
* No OS present: Always wait for data to be removed from buffer. Once
* the interrupt routine has removed some data then we will be able to
* insert some more.
*/
while (out == sp->tx_out && sp->host_inactive < sp->timeout)
- This is because the alt_ticks_per_second() returns 0
- During the main() function alt_ticks_per_second() is correctly set to 10 (which is my setting from the BSP)
- The root cause, is the initialization order in alt_sys_init() within the generated alt_sys_init.c file:
void alt_sys_init( void )
{
ALTERA_AVALON_TIMER_INIT ( NIOS_SUBSYSTEM_TIMER_0, nios_subsystem_timer_0);
ALTERA_AVALON_JTAG_UART_INIT ( NIOS_SUBSYSTEM_JTAG_UART_0, nios_subsystem_jtag_uart_0);
ALTERA_AVALON_SPI_INIT ( NSC3_SUBSYSTEM_0_ADC_SPI, nsc3_subsystem_0_adc_spi);
ALTERA_AVALON_SYSID_QSYS_INIT ( NIOS_SUBSYSTEM_SYSID_NIOS, nios_subsystem_sysid_nios);
ALTERA_AVALON_UART_INIT ( NIOS_SUBSYSTEM_UART_IP, nios_subsystem_uart_ip);
INTEL_NIOSV_M_INIT ( NIOS_SUBSYSTEM_INTEL_NIOSV_M_0, nios_subsystem_intel_niosv_m_0);
}
- _alt_tick_rate is initalized to 0 per default and gets set duing alt_sysclk_init(), called from the INTEL_NIOSV_M_INIT Macro
- As seen above. The INTEL_NIOSV_M_INIT Macro is called last within alt_sys_init. Hence all other modules do see _alt_tick_rate = 0. Hence assume there is no sys tick timer present. Hence all sys tick based alarms are disabled.
- NOTE: The ALTERA_AVALON_TIMER_INIT Macro is called first. Which appears to be correct IMHO, so the Timer module works as sys tick timer
@ Altera: Please advise on this issue. Is there any possibility to change the alt_sys_init initialization order?
best regards
Fabian