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++
12612 Discussions

Implementing interrupt based PIO read for NIOS II

Altera_Forum
Honored Contributor II
2,606 Views

Hello,  

I'm working on embedded system software design for the first time. So i have difficulties in understanding UCOSII, Niche stack TCP/IP stack capabilities and its usage. Details of the problems is mentioned. Hope i get some help. 

I have attached a pdf file and a C code file which has the details of the requirement. Basically it is a real time data acquisition system where in the parallel data is coming through Channel1 and channel2 (the design has two more channels which is not shown) clocked at respective channel clocks. These data should be read by NIOS II and has to be send to host PC s TCP/IP packets. Since there are 4 channels of data which are continuously and simultaneously coming i need to know a method to send all these 4 channels data to the host PC.  

Also each of these channel data should be configurable to reach minimum 4 destinations(IP address).. Because of the above requirement I need to know whether I need to use multithreading capability of UCOS II. If So I need to know how multithreading can be implemented on NIOS II using UCOS II for my requirement.  

 

 

 

Awaiting for the reply...
0 Kudos
6 Replies
Altera_Forum
Honored Contributor II
917 Views

Hi, 

I'm not sure of the way you are using context parameter inside irq handler. I can't remember its usage, so I cannot say if there is an error. 

Anyway I'd work in a different way. 

Why don't you simply read the rden pio and update count variable inside handler? In a opposite way, you could even do everything in the while loop, without irq, sampling the edgecapture register. 

This should work with the 250kHz rdclk frequency you require. But if you then want to use uCos and iniche in order to transmit data with tcp/ip, I think the realtime requirement could be hard to achieve. 

Due to task switching, you'll probably have more than 10 microseconds uncertainty on data sampling, even if pio sampler task runs at maximum priority. 

(in a similar case, I now achieve 100us real time precision with uCos/iniche, but it's a more complex system with 2 tcp/ip ports, so I don't know the same applies to yours; probably you can do better) 

So, the answer to your question about ucos was implicit in what I said above: you have multithreading, configurable priorities and everything else. You can easily send data to 4 destinations, but this depends from the protocol you want. 

A good starting point for uCos with iniche is the simplesocketserver sample: you'll find there almost everything you need. 

 

Regards 

Cris
0 Kudos
Altera_Forum
Honored Contributor II
917 Views

You might want to consider using a 2nd nios cpu as a 'soft dma' engine. 

This could run in a tight loop copying data to shared memory from where the other cpu sends in to the host. 

This moves the tight realtime processing to somewhere where no other code is active. 

 

You probably need less than 4kB each code and data (don't call into libc at all), share the data with your other cpu, and the code with whatever loads it. Export the nios reset signals to some control entity. 

 

I'm doing something similar in order to run sixty four 64kb full duplex hdlc channels. In my case the host interface is PCIe - so neither cpu needs any OS software. The linker script initialises sp and gp and then jumps to into the C.
0 Kudos
Altera_Forum
Honored Contributor II
917 Views

Hi Cris, Thanks for the reply, In fact even i have very less idea about how the context variable is used in the alt_irq_register. I have just blindly copied the code from NIOS ide design examplecalled count binary.  

I tried reading my pio data by just sampling the rdclk and rden signal inside while in the main function itself. But my data is not sampled correctly. I'm getting some random samples or otherwise the same data repeated twice or thrice. Kindly let me know if you get any idea.
0 Kudos
Altera_Forum
Honored Contributor II
917 Views

The fact you can not get correct data even with a raw sampling in main function is very strange. 

Are you sure the signals are ok? I mean: 

- where they come from? are you sure they are not spiking or bouncing? 

- is pio data stable at rdclk edge? 

- are you sampling at the correct rdclk edge? 

- is rdclk synchronous to system clock? 

 

Cris
0 Kudos
Altera_Forum
Honored Contributor II
917 Views

Cris, 

Pls refer the .pdf attachment i have sent. i believe system clk you mean is clk to NIOS II system? in that case they are not from same source and may not be synchronous. rdclk is derived from input data stream and clk to NIOS II is from PLL. But does it really matter? bcoz my rdclk is just 250KHz and the clock to nios II and PIO is 85MHz from PLL. 

Below is the program i have modified by sampling the raw data of edge capture register for rising edge and rden=1. The problem is my expected data pattern is not coming. Im expecting a data pattern of "ABCDEF001122334455......" but what i'm getting is "AB114466 779900000000111111..." 

And tell me does rdclk not synchronous to NIOS II can cause this kind of prob? 

 

 

 

static alt_u8 ch1_rden, ch1_data; 

 

volatile int clk_edge; 

 

int main(void) 

{  

# ifdef CH1_RDCLK_BASE 

 

IOWR_ALTERA_AVALON_PIO_IRQ_MASK(CH1_RDCLK_BASE, 0x0); 

IOWR_ALTERA_AVALON_PIO_EDGE_CAP(CH1_RDCLK_BASE, 0x1); /* Reset the edge capture register. */ 

 

while( 1 )  

{  

clk_edge=IORD_ALTERA_AVALON_PIO_EDGE_CAP(CH1_RDCLK_BASE); 

 

if ((clk_edge==0x1) &&(ch1_rden=IORD_ALTERA_AVALON_PIO_DATA(CH1_RDEN_BASE ))==0x1) 

ch1_data = IORD_ALTERA_AVALON_PIO_DATA(CH1_PIO_BASE); 

 

printf("%02x, ", ch1_data); 

 

IOWR_ALTERA_AVALON_PIO_EDGE_CAP(CH1_RDCLK_BASE, 0x1); 

 

# endif 

 

return 0; 

}
0 Kudos
Altera_Forum
Honored Contributor II
917 Views

Hi, 

 

I never used the pio edge capture feature, but from pio datasheet I believe usage is correct. 

As I suggested before, maybe the problem is due to bounces on rdclk or slow edges which cause multiple triggering of edge capture function. 

I'd try to filter rdclk; but first of all I think rdclk needs to be synchronized to system clock (yes, I mean Nios/sopc clock): infact, I think the pio module uses this clock to sample rdclk and detect edges rather than using the pio input to clock the edge register high. 

 

Another test which may help to identify the problem is excluding edge capture and make a manual double sampling. This way: 

while( 1 ) { /* wait until rdclk goes low */ do { clk_stat=IORD_ALTERA_AVALON_PIO_DATA(CH1_RDCLK _BASE); } while ( clk_stat & 1); /* wait until rdclk goes high */ do { clk_stat=IORD_ALTERA_AVALON_PIO_DATA(CH1_RDCLK _BASE); } while ( (clk_stat & 1)==0); if (IORD_ALTERA_AVALON_PIO_DATA(CH1_RDEN_BASE) & 1) { ch1_data = IORD_ALTERA_AVALON_PIO_DATA(CH1_PIO_BASE); printf("%02x, ", ch1_data); } }  

 

Note that I used a bit compare (&) instead of full compare (==). I don't know the status of other bits in the register. They could be indeterminate: maybe this is your mistake. 

 

Regards 

Cris
0 Kudos
Reply