Timing Event
|
Description
|
A
|
When the CPU captures a data_in_valid
high signal (IRQ routine), it sets global flag to trigger the data_in capture
function at a later time, but immediately sets data_in_request low to stall
incoming data
|
B
|
CPU data_in capture function finished
capturing data, sets data_in_request signal high, this triggers the external
component to prepare new data (while the external component is preparing the
new data, data_in_valid) is set low
|
C
|
New data ready from external component,
data_in_valid set high again |
Table 2:
Summary of data input timing events
The external component is expected to have
the timing scheme shown above. The component provides new data ONLY
when it asserts that the CPU data_in_request is set high, allowing the CPU
to stall incoming data when it cannot process any more. Note that the
CPU immediately sets the data_in_request low once The CPU captures new
data from the data_in only after it asserts that the incoming data is valid
data.
Implementing software to control input
data capture, including simple Nios interrupt service routine:
To implement the above timing scheme in the
CPU, an interrupt service routine for the data_in_valid signal is used to
trigger the capture of the data_in signal. The data_in is not captured within the interrupt service
routine to minimize the time spent in the ISR. Instead, the ISR sets
a flag, and the data_in is captured when the CPU checks for this flag (so
that the CPU is not interrupted from it's other tasks for extended periods
while capturing the data_in). The sample code fragment below
implements the ISR and the data_in capture function.
Note: the PIO pointers (e.g. na_data_in_valid)
point to defined data structures at specified memory locations, these macros
can be found in the nios_map.h file in the [project dir]/[project name]sdk/inc/
for more information, please refer to the nios_software_development_reference.pdf
from Altera
#include "nios_peripherals.h"
#include "nios.h"
#include "util.h"
int data_in_ready;
char data_in;
/******************************************************
void data_in_valid_ISR( int context
)
-- services the interrupt datain_valid
-- sets flag to trigger capture of
data_in at later
time to minimize
time in interrupt handler
*******************************************************/
void data_in_valid_ISR( int context
) {
// reset the edge
capture to exit the interrupt
na_data_in_valid->np_pioedgecapture
= 0;
/* stall the input
of new data while the input data
has not been buffered */
na_data_in_request->np_piodata
= 0;
// set flag to
trigger capture_data_in function
++data_in_ready;
}
/******************************************************
void capture_data_in()
-- captures input data from the 8-bit
data_in PIOs
*******************************************************/
void capture_data_in() {
// when there
is valid data at inputs
if ( data_in_ready
) {
// capture data from input PIO
data_in = na_data_in->np_piodata;
// request new data from external component
na_data_in_request->np_piodata = 1;
// reset data_in_ready flag
data_in_ready = 0;
}
}
int main( void ) {
/* install ISR
and map it to IRQ number */
nr_installuserisr(
na_data_in_valid_irq , &lcd_data_in_ISR, 0 );
// enable IRQ
mask for data_in_valid
na_data_in_valid->np_piointerruptmask
= 0xFF;
datain_start = 0;
while ( 1 ) { // infinite loop
// processor does other work here
...
capture_data_in(); // checks if there
is new data to capture
}
return 0;
}
Fig. 2 Sample waveform of output datapth
timing
Timing Event
|
Description
|
A
|
External component ready fro new
data from CPU
|
B
|
CPU sends out new data, and holds
this data at output until a new data_out_request is recieved
|
C
|
New data_out_request recieved, CPU
prepares new data for data_out
|
D
|
data_out from CPU is ready to be
read, CPU sets data_out_valid high
|
Table 2:
Summary of data input timing events
The
external component is expected to have data input timing characteristics
as shown above. In this CPU asserts that the external component is ready
for new data by asserting that the data_out_request is high, only then will it begin the procedure of
placing a new data_out value on the data_out PIO. The C code to implement
this scheme in the Nios core is trivial and therefore not included as a sample.