embeddedsw: Check for all 1's in XIOModule_IsExpired

Modified XIOModule_IsExpired to check for all 1's in timer CounterReg instead
of 0's while timer expired.

Signed-off-by: Subbaraya Sundeep Bhatta <sbhatta@xilinx.com>
Acked-by: Anirudha Sarangi <anirudh@xilinx.com>
This commit is contained in:
Subbaraya Sundeep Bhatta 2014-05-02 15:29:10 +05:30 committed by Jagannadha Sutradharudu Teki
parent 5e74e29a0a
commit f554ecf495
25 changed files with 7684 additions and 0 deletions

View file

@ -0,0 +1,80 @@
##############################################################################
#
# (c) Copyright 2011 Xilinx, Inc. All rights reserved.
#
# This file contains confidential and proprietary information of Xilinx, Inc.
# and is protected under U.S. and international copyright and other
# intellectual property laws.
#
# DISCLAIMER
# This disclaimer is not a license and does not grant any rights to the
# materials distributed herewith. Except as otherwise provided in a valid
# license issued to you by Xilinx, and to the maximum extent permitted by
# applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
# FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
# IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
# MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
# and (2) Xilinx shall not be liable (whether in contract or tort, including
# negligence, or under any other theory of liability) for any loss or damage
# of any kind or nature related to, arising under or in connection with these
# materials, including for any direct, or any indirect, special, incidental,
# or consequential loss or damage (including loss of data, profits, goodwill,
# or any type of loss or damage suffered as a result of any action brought by
# a third party) even if such damage or loss was reasonably foreseeable or
# Xilinx had been advised of the possibility of the same.
#
# CRITICAL APPLICATIONS
# Xilinx products are not designed or intended to be fail-safe, or for use in
# any application requiring fail-safe performance, such as life-support or
# safety devices or systems, Class III medical devices, nuclear facilities,
# applications related to the deployment of airbags, or any other applications
# that could lead to death, personal injury, or severe property or
# environmental damage (individually and collectively, "Critical
# Applications"). Customer assumes the sole risk and liability of any use of
# Xilinx products in Critical Applications, subject only to applicable laws
# and regulations governing limitations on product liability.
#
# THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
# AT ALL TIMES.
#
##############################################################################
OPTION psf_version = 2.1;
BEGIN driver iomodule
OPTION DRC = iomodule_drc;
OPTION supported_peripherals = (iomodule);
OPTION driver_state = ACTIVE;
OPTION copyfiles = all;
OPTION VERSION = 2.1;
OPTION NAME = iomodule;
OPTION INTC_TYPE = XIOModule;
BEGIN INTERFACE stdin
PROPERTY header = xiomodule_l.h;
FUNCTION name = inbyte, value = XIOModule_RecvByte;
END INTERFACE
BEGIN INTERFACE stdout
PROPERTY header = xiomodule_l.h;
FUNCTION name = outbyte, value = XIOModule_SendByte;
END INTERFACE
BEGIN INTERFACE stdio
PROPERTY header = xiomodule_l.h;
FUNCTION name = inbyte, value = XIOModule_RecvByte;
FUNCTION name = outbyte, value = XIOModule_SendByte;
END INTERFACE
BEGIN ARRAY interrupt_handler
PROPERTY desc = "Interrupt Handler Information";
PROPERTY size = 1, permit = none;
PROPERTY state = deprecated;
PARAM name = int_handler, default = XIntc_DeviceInterruptHandler, desc = "Interrupt Handler", type = string;
PARAM name = int_port, default = Irq, desc = "Interrupt pin associated with the interrupt handler", permit=none;
PARAM name = int_handler_arg, desc = "Argument type to Handler function", type = enum, values = ("Use baseaddress"=C_BASEADDR, "Use device id"=DEVICE_ID), default = DEVICE_ID ;
END ARRAY
END driver

View file

@ -0,0 +1,818 @@
##############################################################################
#
# (c) Copyright 2011-2014 Xilinx, Inc. All rights reserved.
#
# This file contains confidential and proprietary information of Xilinx, Inc.
# and is protected under U.S. and international copyright and other
# intellectual property laws.
#
# DISCLAIMER
# This disclaimer is not a license and does not grant any rights to the
# materials distributed herewith. Except as otherwise provided in a valid
# license issued to you by Xilinx, and to the maximum extent permitted by
# applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
# FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
# IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
# MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
# and (2) Xilinx shall not be liable (whether in contract or tort, including
# negligence, or under any other theory of liability) for any loss or damage
# of any kind or nature related to, arising under or in connection with these
# materials, including for any direct, or any indirect, special, incidental,
# or consequential loss or damage (including loss of data, profits, goodwill,
# or any type of loss or damage suffered as a result of any action brought by
# a third party) even if such damage or loss was reasonably foreseeable or
# Xilinx had been advised of the possibility of the same.
#
# CRITICAL APPLICATIONS
# Xilinx products are not designed or intended to be fail-safe, or for use in
# any application requiring fail-safe performance, such as life-support or
# safety devices or systems, Class III medical devices, nuclear facilities,
# applications related to the deployment of airbags, or any other applications
# that could lead to death, personal injury, or severe property or
# environmental damage (individually and collectively, "Critical
# Applications"). Customer assumes the sole risk and liability of any use of
# Xilinx products in Critical Applications, subject only to applicable laws
# and regulations governing limitations on product liability.
#
# THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
# AT ALL TIMES.
#
# MODIFICATION HISTORY:
# Ver Who Date Changes
# -------- ------ -------- ------------------------------------
# 2.0 adk 12/10/13 Updated as per the New Tcl API's
# 2.0 bss 05/02/14 Modified to generate PITx_EXPIRED_MASK parameter
# to fix CR#794167.
##############################################################################
############################################################
# Global interrupt handlers array, default handler routine
############################################################
array set interrupt_handlers ""
set default_interrupt_handler "XNullHandler"
############################################################
# DRC procedure
############################################################
proc iomodule_drc {drv_handle} {
}
############################################################
# "generate" procedure
############################################################
proc generate {drv_handle} {
# Generate the following definitions in xparameters.h
# 1. Common
set common_params [list "NUM_INSTANCES" "DEVICE_ID" \
"C_BASEADDR" "C_HIGHADDR" "C_MASK" "C_FREQ"]
# 2. UART
set uart_params [list "C_USE_UART_RX" "C_USE_UART_TX" "C_UART_BAUDRATE" \
"C_UART_PROG_BAUDRATE" "C_UART_DATA_BITS" "C_UART_USE_PARITY" \
"C_UART_ODD_PARITY" "C_UART_RX_INTERRUPT" \
"C_UART_TX_INTERRUPT" "C_UART_ERROR_INTERRUPT"]
# 3. FIT
foreach i {1 2 3 4} {
set fit${i}_params [list "C_USE_FIT${i}" "C_FIT${i}_No_CLOCKS" "C_FIT${i}_INTERRUPT"]
}
# 4. PIT
foreach i {1 2 3 4} {
set pit${i}_params [list "C_USE_PIT${i}" "C_PIT${i}_SIZE" "C_PIT${i}_EXPIRED_MASK" \
"C_PIT${i}_READABLE" "C_PIT${i}_PRESCALER" "C_PIT${i}_INTERRUPT"]
}
# 5. GPO
foreach i {1 2 3 4} {
set gpo${i}_params [list "C_USE_GPO${i}" "C_GPO${i}_SIZE"]
}
# 6. GPI
foreach i {1 2 3 4} {
set gpi${i}_params [list "C_USE_GPI${i}" "C_GPI${i}_SIZE" "C_GPI${i}_INTERRUPT"]
}
# 7. INTC
set intc_params [list "C_INTC_USE_EXT_INTR" "C_INTC_INTR_SIZE" "C_INTC_HAS_FAST" "C_INTC_BASE_VECTORS"]
# 8. IO BUS
set io_params [list "C_USE_IO_BUS" "C_IO_BASEADDR" "C_IO_HIGHADDR" "C_IO_MASK"]
set all_params [concat $common_params $uart_params \
$fit1_params $fit2_params $fit3_params $fit4_params \
$pit1_params $pit2_params $pit3_params $pit4_params \
$gpo1_params $gpo2_params $gpo3_params $gpo4_params \
$gpi1_params $gpi2_params $gpi3_params $gpi4_params \
$intc_params $io_params]
eval [xdefine_include_file $drv_handle "xparameters.h" "XIOModule" $all_params]
eval [xdefine_config_file $drv_handle "xiomodule_g.c" "XIOModule" $all_params]
# Generate the following definitions as hexadecimal values in xparameters.h
# 5. GPO
foreach i {1 2 3 4} {
set gpo${i}_params [list "C_GPO${i}_INIT"]
}
# 7. INTC
set intc_params [list "C_INTC_LEVEL_EDGE" "C_INTC_POSITIVE"]
set all_params [concat $gpo1_params $gpo2_params $gpo3_params $gpo4_params $intc_params]
eval [xdefine_include_file_hex $drv_handle "xparameters.h" "XIOModule" $all_params]
# 7. INTC: Set XPAR_IOMODULE_INTC_MAX_INTR_SIZE
set max_intr_size 0
set periphs [xget_sw_iplist_for_driver $drv_handle]
foreach periph $periphs {
set periph_num_intr_internal [get_num_intr_internal $periph]
set periph_num_intr_inputs [get_num_intr_inputs $periph]
set periph_intr_size [expr $periph_num_intr_internal + $periph_num_intr_inputs]
if {$max_intr_size < $periph_intr_size} {
set max_intr_size $periph_intr_size
}
}
# 7. INTC: Define XPAR_SINGLE_BASEADDR, XPAR_SINGLE_HIGHADDR, and XPAR_SINGLE_DEVICE_ID
set periphs [xget_sw_iplist_for_driver $drv_handle]
set count [llength $periphs]
if {$count == 1} {
xdefine_with_names $drv_handle [xget_sw_iplist_for_driver $drv_handle] "xparameters.h" \
"XPAR_IOMODULE_SINGLE_BASEADDR" "C_BASEADDR" \
"XPAR_IOMODULE_SINGLE_HIGHADDR" "C_HIGHADDR" \
"XPAR_IOMODULE_INTC_SINGLE_DEVICE_ID" "DEVICE_ID"
}
set config_inc [xopen_include_file "xparameters.h"]
puts $config_inc "#define XPAR_IOMODULE_INTC_MAX_INTR_SIZE $max_intr_size"
# 7. INTC: Generate config table, vector tables
iomodule_define_config_file $drv_handle $periphs $config_inc
close $config_inc
xdefine_canonical_xpars $drv_handle "xparameters.h" "IOModule" $all_params
}
##########################################################################
# Generate interrupt definitions in Configuration C file xiomodule_g.c
# This file has the Config Table and vector tables for each iomodule
# instance as required by Xilinx iomodule driver
##########################################################################
proc iomodule_define_config_file {drv_handle periphs config_inc} {
variable interrupt_handlers
variable default_interrupt_handler
# set isr_options to be XIN_SVC_SGL_ISR_OPTION as defined in xiomodule.h
set isr_options XIN_SVC_SGL_ISR_OPTION
set file_name "xiomodule_g.c"
set drv_string "XIOModule"
set args [list "DEVICE_ID" "C_BASEADDR" "C_IO_BASEADDR" "C_INTC_HAS_FAST" "C_INTC_BASE_VECTORS"]
set filename [file join "src" $file_name]
file delete $filename
set config_file [open $filename w]
xprint_generated_header $config_file "Driver configuration"
puts $config_file "#include \"xparameters.h\""
puts $config_file "#include \"[string tolower $drv_string].h\""
puts $config_file "\n"
set tmp_filename [file join "src" "tmpconfig.c"]
set tmp_config_file [open $tmp_filename w]
puts $tmp_config_file "\n/*"
puts $tmp_config_file "* The configuration table for devices"
puts $tmp_config_file "*/\n"
puts $tmp_config_file [format "%s_Config %s_ConfigTable\[\] =" $drv_string $drv_string]
puts $tmp_config_file "\{"
set start_comma ""
foreach periph $periphs {
puts $tmp_config_file [format "%s\t\{" $start_comma]
set comma ""
foreach arg $args {
# Check if this is a driver parameter or a peripheral parameter
set value [get_property CONFIG.$arg $drv_handle]
if {[llength $value] == 0} {
puts -nonewline $tmp_config_file [format "%s\t\t%s" $comma [xget_name $periph $arg]]
} else {
puts -nonewline $tmp_config_file [format "%s\t\t%s" $comma [xget_dname $drv_string $arg]]
}
set comma ",\n"
}
# add AckBeforeService as an arg to the config table - Ack Before for edge interrupts
puts -nonewline $tmp_config_file [format "%s\t\t%s" $comma "(([xget_name $periph C_INTC_LEVEL_EDGE] << 16) | 0x7FF)"]
# add the OPTIONS as an arg to the config table - default OPTIONS value is XIN_SVC_SGL_ISR_OPTION
puts -nonewline $tmp_config_file [format "%s\t\t%s" $comma $isr_options]
# add the FREQ as an arg to the config table
puts -nonewline $tmp_config_file [format "%s\t\t%s" $comma [xget_name $periph "C_FREQ"] ]
# add the BAUDRATE as an arg to the config table
puts -nonewline $tmp_config_file [format "%s\t\t%s" $comma [xget_name $periph "C_UART_BAUDRATE"] ]
# add the PIT use as an arg to the config table
puts $tmp_config_file [format "%s\t\t\{" $comma ]
for {set i 1} {$i <= 4} {incr i} {
puts $tmp_config_file [format "\t\t\t%s," [xget_name $periph "C_USE_PIT${i}"] ]
}
puts -nonewline $tmp_config_file "\t\t\}"
# add the PIT sizes as an arg to the config table
puts $tmp_config_file [format "%s\t\t\{" $comma ]
for {set i 1} {$i <= 4} {incr i} {
puts $tmp_config_file [format "\t\t\t%s," [xget_name $periph "C_PIT${i}_SIZE"] ]
}
puts -nonewline $tmp_config_file "\t\t\}"
# add the PIT sizes as an arg to the config table
puts $tmp_config_file [format "%s\t\t\{" $comma ]
for {set i 1} {$i <= 4} {incr i} {
puts $tmp_config_file [format "\t\t\t%s," [xget_name $periph "C_PIT${i}_EXPIRED_MASK"] ]
}
puts -nonewline $tmp_config_file "\t\t\}"
# add the PIT prescalers as an arg to the config table
puts $tmp_config_file [format "%s\t\t\{" $comma ]
for {set i 1} {$i <= 4} {incr i} {
puts $tmp_config_file [format "\t\t\t%s," [xget_name $periph "C_PIT${i}_PRESCALER"] ]
}
puts -nonewline $tmp_config_file "\t\t\}"
# add if PIT has readable counter as an arg to the config table
puts $tmp_config_file [format "%s\t\t\{" $comma ]
for {set i 1} {$i <= 4} {incr i} {
puts $tmp_config_file [format "\t\t\t%s," [xget_name $periph "C_PIT${i}_READABLE"] ]
}
puts -nonewline $tmp_config_file "\t\t\}"
# add the GPO initialization values as an arg to the config table
puts $tmp_config_file [format "%s\t\t\{" $comma ]
for {set i 1} {$i <= 4} {incr i} {
puts $tmp_config_file [format "\t\t\t%s," [xget_name $periph "C_GPO${i}_INIT"] ]
}
puts -nonewline $tmp_config_file "\t\t\}"
# generate the vector table for this iomodule instance
iomodule_define_vector_table $periph $config_inc $tmp_config_file
puts $config_inc "\n/******************************************************************/\n"
puts -nonewline $tmp_config_file "\n\t\}"
set start_comma ",\n"
}
puts $tmp_config_file "\n\};"
close $tmp_config_file
# Write out the extern definitions of handlers...
foreach elem [array names interrupt_handlers] {
puts $config_file [format "extern void %s (void *);" $elem ]
}
# copy over the tmp_config_file contents to config_file
set tmp_config_file [open $tmp_filename r]
while {![eof $tmp_config_file]} {
gets $tmp_config_file line
puts $config_file $line
}
close $tmp_config_file
file delete -force $tmp_filename
close $config_file
}
##########################################################################
# Define the vector table
##########################################################################
proc iomodule_define_vector_table {periph config_inc config_file} {
variable interrupt_handlers
variable default_interrupt_handler
set periph_name [get_property NAME $periph]
# Get ports that are driving the interrupt
set source_ports [xget_interrupt_sources $periph]
set num_intr_inputs [get_num_intr_inputs $periph]
set num_intr_internal [get_num_intr_internal $periph]
if {$num_intr_inputs != [llength $source_ports]} {
error "ERROR: Internal error: Number of interrupt inputs on $periph_name ($num_intr_inputs) is not the same as length of total number of interrupt sources ([llength $source_ports]). If any interrupt source is a vector then libgen does not support this use case" "" "hsm_error"
return
}
set i 0
foreach source_pin $source_ports {
set source_periph [get_cells -of_objects $source_pin ]
if { [llength $source_periph ] == 0} {
#external interrupt port case
set width [xget_port_width $source_pin]
for { set j 0 } { $j < $width } { incr j } {
set source_port_name($i) "[get_property NAME $source_pin]_$j"
set source_name($i) "system"
set port_type($i) "global"
set source_driver ""
set source_interrupt_handler($i) $default_interrupt_handler
incr i
}
} else {
#peripheral interrrupt case
set port_type($i) "local"
set source_name($i) [get_property NAME $source_periph]
set source_port_name($i) [get_property NAME $source_pin]
set source_driver [get_drivers -filter "HW_INSTANCE==$source_periph"]
set source_interrupt_handler($i) $default_interrupt_handler
incr i
}
if {[string compare -nocase $source_driver ""] != 0} {
set int_array [get_arrays interrupt_handler -of_objects $source_driver]
if {[string compare -nocase $int_array ""] != 0} {
set int_array_elems [xget_handle $int_array "ELEMENTS" "*"]
foreach int_array_elem $int_array_elems {
set int_port [get_property CONFIG.int_port $int_array_elem]
set mhs_handle [get_property CONFIG.mhsinst $int_array_elem]
if {[string compare -nocase $int_port $source_port_name] == 0 && \
$mhs_handle == $source_periph } {
set source_interrupt_handler($i) [get_property CONFIG.int_handler $int_array_elem]
# copy this handler to interrupt_handlers
set arrsize [array size interrupt_handlers]
iomodule_add_handler $source_interrupt_handler($i)
set source_handler_arg($i) [get_property CONFIG.int_handler_arg $int_array_elem]
if {[string compare -nocase $source_handler_arg($i) DEVICE_ID] == 0 } {
set source_handler_arg($i) [xget_name $source_periph "DEVICE_ID"]
}
break
}
}
}
}
}
# Check if default_interrupt_handler has to have an extern definition
if {[array size interrupt_handlers] < [llength $source_ports]} {
iomodule_add_handler $default_interrupt_handler
}
# Write vector table to the config_file
puts -nonewline $config_file ",\n\t\t\{"
set comma "\n"
for {set i 0} {$i < $num_intr_internal} {incr i} {
puts $config_file [format "%s\t\t\t\{" $comma ]
puts $config_file [format "\t\t\t\t%s," $default_interrupt_handler ]
puts $config_file "\t\t\t\t(void *)XNULL"
puts -nonewline $config_file "\t\t\t\}"
set comma ",\n"
}
for {set i 0} {$i < $num_intr_inputs} {incr i} {
puts $config_file [format "%s\t\t\t\{" $comma ]
puts $config_file [format "\t\t\t\t%s," $source_interrupt_handler($i)]
if {[llength $source_name($i)] == 0} {
puts $config_file "\t\t\t\t(void *)XNULL"
} else {
puts $config_inc [format "#define XPAR_%s_%s_MASK %#08X" \
[string toupper $source_name($i)] \
[string toupper $source_port_name($i)] [expr 1 << $i]]
puts $config_inc [format "#define XPAR_%s_%s_%s_INTR %d" \
[string toupper $periph_name] \
[string toupper $source_name($i)] \
[string toupper $source_port_name($i)] $i]
if {[string compare -nocase "global" $port_type($i) ] != 0 && \
[string compare $source_interrupt_handler($i) $default_interrupt_handler ] != 0} {
puts $config_file [format "\t\t\t\t(void *) %s" $source_handler_arg($i)]
} else {
puts $config_file "\t\t\t\t(void *) XNULL"
}
}
puts -nonewline $config_file "\t\t\t\}"
set comma ",\n"
}
puts $config_file "\n\t\t\}"
}
##########################################################################
# This procedure creates a unique list of
# handlers that needs to have an extern defn.
# in xparameters.h
##########################################################################
proc iomodule_add_handler {handler} {
variable interrupt_handlers
set interrupt_handlers($handler) 1
}
##########################################################################
# Given a list of arguments, define each as a canonical constant name,
# using the driver name, in an include file.
##########################################################################
proc xdefine_canonical_xpars {drv_handle file_name drv_string args} {
set args [get_exact_arg_list $args]
# Open include file
set file_handle [xopen_include_file $file_name]
# Get all peripherals connected to this driver
set periphs [xget_sw_iplist_for_driver $drv_handle]
# Print canonical parameters for each peripheral
set device_id 0
foreach periph $periphs {
puts $file_handle ""
set periph_name [string toupper [get_property NAME $periph]]
set canonical_name [format "%s_%s" $drv_string $device_id]
# Make sure canonical name is not the same as hardware instance
if { [string compare -nocase $canonical_name $periph_name] == 0 } {
# Abort canonical names
break
}
puts $file_handle "/* Canonical definitions for peripheral $periph_name */"
puts [llength $args]
foreach arg $args {
if {[string first "_EXPIRED_MASK" $arg] > 0} {
set charindex [string first "_EXPIRED_MASK" $arg]
set size [string index $arg [expr $charindex - 1]]
set sizearg [format "C_PIT%d_SIZE" $size]
set lvalue [format "C_PIT%d_EXPIRED_MASK" $size]
set lvalue [xget_dname $canonical_name $lvalue]
set rvalue [get_property CONFIG.$sizearg $periph]
set rvalue [expr pow(2, $rvalue) - 1]
set rvalue [format "%.0f" $rvalue]
set rvalue [format "0x%08X" $rvalue]
} else {
set lvalue [xget_dname $canonical_name $arg]
# The commented out rvalue is the name of the instance-specific constant
# set rvalue [xget_name $periph $arg]
# The rvalue set below is the actual value of the parameter
set rvalue [get_property CONFIG.$arg $periph]
}
if {[llength $rvalue] == 0} {
set rvalue 0
}
set rvalue [xformat_addr_string $rvalue $arg]
puts $file_handle "#define $lvalue $rvalue"
}
incr device_id
puts $file_handle ""
}
#
# Now redefine the Interrupt ID constants
#
xredefine_iomodule $drv_handle $file_handle
puts $file_handle "\n/******************************************************************/\n"
close $file_handle
}
##########################################################################
# iomodule redefines
##########################################################################
proc xredefine_iomodule {drvhandle config_inc} {
variable default_interrupt_handler
# Next define interrupt IDs for each connected peripheral
set periphs [xget_sw_iplist_for_driver $drvhandle]
set device_id 0
set periph_name [string toupper "iomodule"]
foreach periph $periphs {
# Get the edk based name of peripheral for printing redefines
set edk_periph_name [get_property NAME $periph]
# Get ports that are driving the interrupt
set source_ports [xget_interrupt_sources $periph]
set i 0
lappend source_list
foreach source_pin $source_ports {
set source_periph($i) [get_cells -of_objects $source_pin ]
if { [llength $source_periph($i) ] == 0} {
#external interrupt port case
set width [xget_port_width $source_pin]
for { set j 0 } { $j < $width } { incr j } {
set source_port_name($i) "[get_property NAME $source_pin]_$j"
set source_name($i) "system"
set port_type($i) "global"
set source_driver ""
set source_interrupt_handler($i) $default_interrupt_handler
lappend source_list $source_name($i)
incr i
}
} else {
#peripheral interrrupt case
set port_type($i) "local"
set source_name($i) [get_property NAME $source_periph($i)]
set source_port_name($i) [get_property NAME $source_pin]
set source_driver [get_drivers -filter "HW_INSTANCE==$source_periph($i)"]
set source_interrupt_handler($i) $default_interrupt_handler
lappend source_list $source_name($i)
incr i
}
}
set num_intr_inputs [get_num_intr_inputs $periph]
for {set i 0} {$i < $num_intr_inputs} {incr i} {
# Skip global (external) ports
if {$source_periph($i) == ""} {
continue
}
set port_type($i) [get_property TYPE $source_periph($i)]
if {[string compare -nocase $port_type($i) "global"] == 0} {
continue
}
set drv [get_drivers -filter "HW_INSTANCE==$source_name($i)"]
set iptype [get_property IPTYPE $source_periph($i)]
# if {[llength $source_name($i)] != 0 && [llength $drv] != 0 &&
# [string compare -nocase $iptype "PERIPHERAL"] == 0}
if {[llength $source_name($i)] != 0 && [llength $drv] != 0} {
set instance [xfind_instance $drv $source_name($i)]
set drvname [get_property NAME $drv]
#
# Handle reference cores, which have non-reference driver names
#
if {[string compare -nocase $drvname "touchscreen_ref"] == 0} {
set drvname "touchscreen"
} elseif {[string compare -nocase $drvname "ps2_ref"] == 0} {
set drvname "ps2"
set instance [expr $instance*2]
if {[string match -nocase "*SYS_INTR2" $source_port_name($i)] == 1} {
incr instance
}
}
#
# Define the interrupt vector IDs in xparameters.h for each core
# that is connected to this iomodule.
#
set drvname [string toupper $drvname]
#
# Treat sources with multiple interrupt ports slightly different
# by including the interrupt port name in the canonical constant
# name
#
if { [lcount $source_list $source_name($i)] > 1} {
set first_part [format "#define XPAR_%s_%s_%s_%s_%s_VEC_ID" \
$periph_name $device_id $drvname $instance \
[string toupper $source_port_name($i)]]
} else {
set first_part [format "#define XPAR_%s_%s_%s_%s_VEC_ID" \
$periph_name $device_id $drvname $instance]
}
set second_part [format "XPAR_%s_%s_%s_INTR" \
[string toupper $edk_periph_name] \
[string toupper $source_name($i)] \
[string toupper $source_port_name($i)] ]
if {[string compare -nocase $drvname "generic"] != 0} {
puts $config_inc "$first_part $second_part"
}
}
}
incr device_id
}
}
##########################################################################
# Get the number of elements in the given list that match the given
# entry. Assume elements are strings.
##########################################################################
proc lcount {list match_entry} {
set len [llength $list]
set count 0
for {set i 0} {$i < $len} {incr i} {
set entry [lindex $list $i]
if { [string compare -nocase $entry $match_entry] == 0} {
incr count
}
}
return $count
}
##########################################################################
# Get the HW instance number for a particular device. This will be used to
# enumerate the vector ID defines if more than one interrupt from the core
# is connected to the interrupt controller.
##########################################################################
proc xfind_instance {drvhandle instname} {
set instlist [xget_sw_iplist_for_driver $drvhandle]
set i 0
foreach inst $instlist {
set name [get_property NAME $inst]
if {[string compare -nocase $instname $name] == 0} {
return $i
}
incr i
}
set i 0
return $i
}
##########################################################################
# Get the type of port, whether it is "local" (from an IP), or "global"
# (from external source).
##########################################################################
proc xget_port_type {periph} {
set mhs [get_cells -of_object $periph]
if {[llength $mhs] == 0} {
return "global"
} else {
return "local"
}
}
##########################################################################
# Get number of used external interrupts
##########################################################################
proc get_num_intr_inputs {periph} {
set intc_use_ext_intr [get_property CONFIG.C_INTC_USE_EXT_INTR $periph]
if {$intc_use_ext_intr} {
set num_intr_inputs [get_property CONFIG.C_INTC_INTR_SIZE $periph]
} else {
set num_intr_inputs 0
}
return $num_intr_inputs
}
##########################################################################
# Get number of used internal interrupts
##########################################################################
proc get_num_intr_internal {periph} {
set c_use_uart_rx [get_property CONFIG.C_USE_UART_RX $periph]
set c_uart_error_interrupt [get_property CONFIG.C_UART_ERROR_INTERRUPT $periph]
set c_uart_rx_interrupt [get_property CONFIG.C_UART_RX_INTERRUPT $periph]
set c_use_uart_tx [get_property CONFIG.C_USE_UART_TX $periph]
set c_uart_tx_interrupt [get_property CONFIG.C_UART_TX_INTERRUPT $periph]
set c_intc_use_ext_intr [get_property CONFIG.C_INTC_USE_EXT_INTR $periph]
set c_intc_intr_size [get_property CONFIG.C_INTC_INTR_SIZE $periph]
set num_intr_internal 0
if {$c_use_uart_tx * $c_use_uart_rx * $c_uart_error_interrupt} { set num_intr_internal 1 }
if {$c_use_uart_tx * $c_uart_tx_interrupt} { set num_intr_internal 2 }
if {$c_use_uart_rx * $c_uart_rx_interrupt} { set num_intr_internal 3 }
foreach kind {PIT FIT GPI} suffix {"SIZE" "No_CLOCKS" "INTERRUPT"} intbit {3 7 11} {
foreach it {1 2 3 4} {
set c_use_it [expr [get_property CONFIG.C_${kind}${it}_${suffix} $periph] > 0]
set c_it_interrupt [get_property CONFIG.C_${kind}${it}_INTERRUPT $periph]
if {$c_use_it * $c_it_interrupt} { set num_intr_internal [expr $intbit + $it] }
}
}
# If any external interrupts are used - return 16 since in that case all internal interrupts
# must be accounted for because external interrupts start at bit position 16
if {$c_intc_use_ext_intr} {
return 16
}
return $num_intr_internal
}
##########################################################################
# Define parameters as hexadecimal values in include file. Derived from
# xdefine_include_file in "$XILINX_EDK/data/datastructure/xillib_sw.tcl".
##########################################################################
proc xdefine_include_file_hex {drv_handle file_name drv_string args} {
set args [get_exact_arg_list $args]
# Open include file
set file_handle [xopen_include_file $file_name]
# Get all peripherals connected to this driver
set periphs [xget_sw_iplist_for_driver $drv_handle]
# Print all parameters for all peripherals as hexadecimal strings
set device_id 0
foreach periph $periphs {
puts $file_handle ""
puts $file_handle "/* Additional definitions for peripheral [string toupper [get_property NAME $periph]] */"
foreach arg $args {
set value [get_property CONFIG.$arg $periph]
if {[llength $value] == 0} {
set value 0
}
# Convert binary string starting with "0b" to hexadecimal
if {[string first "0b" $value] == 0} {
set value_int 0
for {set i 2} {$i < [string length $value]} {incr i} {
set value_int [expr $value_int * 2 + [string index $value $i]]
}
set value [format "0x%08x" $value_int]
}
puts $file_handle "#define [xget_name $periph $arg] $value"
}
puts $file_handle ""
}
puts $file_handle "\n/******************************************************************/\n"
close $file_handle
}
##############################################################################
# Define parameters in xparameters.h and generate PIT_EXPIRED_MASK parameter
##############################################################################
proc xdefine_include_file {drv_handle file_name drv_string args} {
set args [get_exact_arg_list $args]
# Open include file
set file_handle [xopen_include_file $file_name]
set flag 0
# Get all peripherals connected to this driver
set periphs [xget_sw_iplist_for_driver $drv_handle]
# Handle special cases
set arg "NUM_INSTANCES"
set posn [lsearch -exact $args $arg]
if {$posn > -1} {
puts $file_handle "/* Definitions for driver [string toupper [get_property name $drv_handle]] */"
# Define NUM_INSTANCES
puts $file_handle "#define [xget_dname $drv_string $arg] [llength $periphs]"
set args [lreplace $args $posn $posn]
}
# Check if it is a driver parameter
lappend newargs
foreach arg $args {
set value [get_property CONFIG.$arg $drv_handle]
if {[llength $value] == 0} {
lappend newargs $arg
} else {
puts $file_handle "#define [xget_dname $drv_string $arg] [get_property $arg $drv_handle]"
}
}
set args $newargs
# Print all parameters for all peripherals
set device_id 0
foreach periph $periphs {
puts $file_handle ""
puts $file_handle "/* Definitions for peripheral [string toupper [get_property NAME $periph]] */"
foreach arg $args {
if {[string compare -nocase "DEVICE_ID" $arg] == 0} {
set value $device_id
incr device_id
} else {
if {[string first "_EXPIRED_MASK" $arg] > 0} {
set charindex [string first "_EXPIRED_MASK" $arg]
set size [string index $arg [expr $charindex - 1]]
set sizearg [format "C_PIT%d_SIZE" $size]
set lvalue [format "PIT%d_EXPIRED_MASK" $size]
set lvalue [format "XPAR_%s_%s" [string toupper [get_property NAME $periph]] $lvalue]
set rvalue [get_property CONFIG.$sizearg $periph]
set rvalue [expr pow(2, $rvalue) - 1]
set rvalue [format "%.0f" $rvalue]
set rvalue [format "0x%08X" $rvalue]
set flag 1
} else {
set value [get_property CONFIG.$arg $periph]
}
}
if {[llength $value] == 0} {
set value 0
}
set value [xformat_addr_string $value $arg]
if {[string compare -nocase "HW_VER" $arg] == 0} {
puts $file_handle "#define [xget_name $periph $arg] \"$value\""
} else {
if {$flag == 0} {
puts $file_handle "#define [xget_name $periph $arg] $value"
} else {
puts $file_handle "#define $lvalue $rvalue"
set flag 0
}
}
}
puts $file_handle ""
}
puts $file_handle "\n/******************************************************************/\n"
close $file_handle
}

View file

@ -0,0 +1,47 @@
/* $Id$ */
/******************************************************************************
*
* (c) Copyright 2011 Xilinx, Inc. All rights reserved.
*
* This file contains confidential and proprietary information of Xilinx, Inc.
* and is protected under U.S. and international copyright and other
* intellectual property laws.
*
* DISCLAIMER
* This disclaimer is not a license and does not grant any rights to the
* materials distributed herewith. Except as otherwise provided in a valid
* license issued to you by Xilinx, and to the maximum extent permitted by
* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
* and (2) Xilinx shall not be liable (whether in contract or tort, including
* negligence, or under any other theory of liability) for any loss or damage
* of any kind or nature related to, arising under or in connection with these
* materials, including for any direct, or any indirect, special, incidental,
* or consequential loss or damage (including loss of data, profits, goodwill,
* or any type of loss or damage suffered as a result of any action brought by
* a third party) even if such damage or loss was reasonably foreseeable or
* Xilinx had been advised of the possibility of the same.
*
* CRITICAL APPLICATIONS
* Xilinx products are not designed or intended to be fail-safe, or for use in
* any application requiring fail-safe performance, such as life-support or
* safety devices or systems, Class III medical devices, nuclear facilities,
* applications related to the deployment of airbags, or any other applications
* that could lead to death, personal injury, or severe property or
* environmental damage (individually and collectively, "Critical
* Applications"). Customer assumes the sole risk and liability of any use of
* Xilinx products in Critical Applications, subject only to applicable laws
* and regulations governing limitations on product liability.
*
* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
* AT ALL TIMES.
*
******************************************************************************/
#include "xil_types.h"
#include "xil_assert.h"
#include "xstatus.h"
XStatus IOModuleSelfTestExample(u16 DeviceId);

View file

@ -0,0 +1,50 @@
/* $Id$ */
/******************************************************************************
*
* (c) Copyright 2011 Xilinx, Inc. All rights reserved.
*
* This file contains confidential and proprietary information of Xilinx, Inc.
* and is protected under U.S. and international copyright and other
* intellectual property laws.
*
* DISCLAIMER
* This disclaimer is not a license and does not grant any rights to the
* materials distributed herewith. Except as otherwise provided in a valid
* license issued to you by Xilinx, and to the maximum extent permitted by
* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
* and (2) Xilinx shall not be liable (whether in contract or tort, including
* negligence, or under any other theory of liability) for any loss or damage
* of any kind or nature related to, arising under or in connection with these
* materials, including for any direct, or any indirect, special, incidental,
* or consequential loss or damage (including loss of data, profits, goodwill,
* or any type of loss or damage suffered as a result of any action brought by
* a third party) even if such damage or loss was reasonably foreseeable or
* Xilinx had been advised of the possibility of the same.
*
* CRITICAL APPLICATIONS
* Xilinx products are not designed or intended to be fail-safe, or for use in
* any application requiring fail-safe performance, such as life-support or
* safety devices or systems, Class III medical devices, nuclear facilities,
* applications related to the deployment of airbags, or any other applications
* that could lead to death, personal injury, or severe property or
* environmental damage (individually and collectively, "Critical
* Applications"). Customer assumes the sole risk and liability of any use of
* Xilinx products in Critical Applications, subject only to applicable laws
* and regulations governing limitations on product liability.
*
* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
* AT ALL TIMES.
*
******************************************************************************/
#include "xil_types.h"
#include "xil_assert.h"
#include "xstatus.h"
XStatus IOModuleIntrExample(XIOModule *IOModuleInstancePtr,
u16 DeviceId);
XStatus IOModuleInterruptSetup(XIOModule *IOModuleInstancePtr,
u16 DeviceId);

View file

@ -0,0 +1,201 @@
##############################################################################
#
# (c) Copyright 2011-2014 Xilinx, Inc. All rights reserved.
#
# This file contains confidential and proprietary information of Xilinx, Inc.
# and is protected under U.S. and international copyright and other
# intellectual property laws.
#
# DISCLAIMER
# This disclaimer is not a license and does not grant any rights to the
# materials distributed herewith. Except as otherwise provided in a valid
# license issued to you by Xilinx, and to the maximum extent permitted by
# applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
# FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
# IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
# MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
# and (2) Xilinx shall not be liable (whether in contract or tort, including
# negligence, or under any other theory of liability) for any loss or damage
# of any kind or nature related to, arising under or in connection with these
# materials, including for any direct, or any indirect, special, incidental,
# or consequential loss or damage (including loss of data, profits, goodwill,
# or any type of loss or damage suffered as a result of any action brought by
# a third party) even if such damage or loss was reasonably foreseeable or
# Xilinx had been advised of the possibility of the same.
#
# CRITICAL APPLICATIONS
# Xilinx products are not designed or intended to be fail-safe, or for use in
# any application requiring fail-safe performance, such as life-support or
# safety devices or systems, Class III medical devices, nuclear facilities,
# applications related to the deployment of airbags, or any other applications
# that could lead to death, personal injury, or severe property or
# environmental damage (individually and collectively, "Critical
# Applications"). Customer assumes the sole risk and liability of any use of
# Xilinx products in Critical Applications, subject only to applicable laws
# and regulations governing limitations on product liability.
#
# THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
# AT ALL TIMES.
#
# MODIFICATION HISTORY:
# Ver Who Date Changes
# -------- ------ -------- ------------------------------------
# 2.0 adk 12/10/13 Updated as per the New Tcl API's
##############################################################################
# Uses $XILINX_EDK/bin/lib/xillib_sw.tcl
# -----------------------------------------------------------------
# Software Project Types (swproj):
# 0 : MemoryTest - Calls basic memorytest routines from common driver dir
# 1 : PeripheralTest - Calls any existing polled_example and/or selftest
# -----------------------------------------------------------------
# -----------------------------------------------------------------
# TCL Procedures:
# -----------------------------------------------------------------
proc gen_include_files {swproj mhsinst} {
if {$swproj == 0} {
return ""
}
if {$swproj == 1} {
set ifintr [is_ip_interrupting_current_processor $mhsinst]
if {$ifintr == 1} {
set inc_file_lines {xiomodule.h iomodule_header.h \
xil_exception.h iomodule_intr_header.h}
} else {
set inc_file_lines {xiomodule.h iomodule_header.h}
}
return $inc_file_lines
}
}
proc gen_src_files {swproj mhsinst} {
if {$swproj == 0} {
return ""
}
if {$swproj == 1} {
set ifintr [is_ip_interrupting_current_processor $mhsinst]
if {$ifintr == 1} {
set inc_file_lines {examples/xiomodule_selftest_example.c \
examples/xiomodule_intr_example.c \
data/iomodule_header.h \
data/iomodule_intr_header.h}
} else {
set inc_file_lines {examples/xiomodule_selftest_example.c \
data/iomodule_header.h}
}
return $inc_file_lines
}
}
proc gen_testfunc_def {swproj mhsinst} {
return ""
}
proc gen_init_code {swproj mhsinst} {
if {$swproj == 1} {
set ipname [get_property NAME $mhsinst]
set ifintr [is_ip_interrupting_current_processor $mhsinst]
if {$ifintr == 1} {
set decl " static XIOModule ${ipname}_IOModule;"
set inc_file_lines $decl
return $inc_file_lines
}
}
return ""
}
proc gen_testfunc_call {swproj mhsinst} {
if {$swproj == 0} {
return ""
}
set ipname [get_property NAME $mhsinst]
set deviceid [xget_name $mhsinst "DEVICE_ID"]
set stdout [get_property CONFIG.STDOUT [get_os]]
if { $stdout == "" || $stdout == "none" } {
set hasStdout 0
} else {
set hasStdout 1
}
set iomodulevar "${ipname}_IOModule"
set ifintr [is_ip_interrupting_current_processor $mhsinst]
set extintr [get_property CONFIG.C_INTC_USE_EXT_INTR $mhsinst]
set testfunc_call ""
if {${hasStdout} == 0} {
append testfunc_call "
{
XStatus status;
status = IOModuleSelfTestExample(${deviceid});
}"
if {$ifintr != 0} {
append testfunc_call "
{
XStatus status;
status = IOModuleIntrExample(&${iomodulevar}, ${deviceid});
}"
if {$extintr != 0} {
append testfunc_call "
{
XStatus status;
status = IOModuleInterruptSetup(&${iomodulevar}, ${deviceid});
}"
}
}
} else {
append testfunc_call "
{
XStatus status;
print(\"\\r\\nRunning IOModuleSelfTestExample() for ${ipname}...\\r\\n\");
status = IOModuleSelfTestExample(${deviceid});
if (status == 0) {
print(\"IOModuleSelfTestExample PASSED\\r\\n\");
}
else {
print(\"IOModuleSelfTestExample FAILED\\r\\n\");
}
}"
if {$ifintr != 0} {
append testfunc_call "
{
XStatus status;
print(\"\\r\\nRunning Interrupt Test for ${ipname}...\\r\\n\");
status = IOModuleIntrExample(&${iomodulevar}, ${deviceid});
if (status == 0) {
print(\"IOModule Interrupt Test PASSED\\r\\n\");
}
else {
print(\"IOModule Interrupt Test FAILED\\r\\n\");
}
}"
if {$extintr != 0} {
append testfunc_call "
{
XStatus status;
status = IOModuleInterruptSetup(&${iomodulevar}, ${deviceid});
if (status == 0) {
print(\"IOModule Setup PASSED\\r\\n\");
} else {
print(\"IOModule Setup FAILED\\r\\n\");
}
}"
}
}
}
return $testfunc_call
}

View file

@ -0,0 +1,20 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<meta http-equiv="Content-Language" content="en-us">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Driver example applications</title>
<link rel="stylesheet" type="text/css" href="../help.css">
</head>
<body bgcolor="#FFFFFF">
<h1> Example Applications for the driver iomodule_v2_1 </h1>
<HR>
<ul>
<li>xiomodule_example.c <a href="xiomodule_example.c">(source)</a> </li>
<li>xiomodule_intr_example.c <a href="xiomodule_intr_example.c">(source)</a> </li>
<li>xiomodule_low_level_example.c <a href="xiomodule_low_level_example.c">(source)</a> </li>
<li>xiomodule_selftest_example.c <a href="xiomodule_selftest_example.c">(source)</a> </li>
</ul>
<p><font face="Times New Roman" color="#800000">Copyright © 1995-2014 Xilinx, Inc. All rights reserved.</font></p>
</body>
</html>

View file

@ -0,0 +1,312 @@
/* $Id$ */
/******************************************************************************
*
* (c) Copyright 2011 Xilinx, Inc. All rights reserved.
*
* This file contains confidential and proprietary information of Xilinx, Inc.
* and is protected under U.S. and international copyright and other
* intellectual property laws.
*
* DISCLAIMER
* This disclaimer is not a license and does not grant any rights to the
* materials distributed herewith. Except as otherwise provided in a valid
* license issued to you by Xilinx, and to the maximum extent permitted by
* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
* and (2) Xilinx shall not be liable (whether in contract or tort, including
* negligence, or under any other theory of liability) for any loss or damage
* of any kind or nature related to, arising under or in connection with these
* materials, including for any direct, or any indirect, special, incidental,
* or consequential loss or damage (including loss of data, profits, goodwill,
* or any type of loss or damage suffered as a result of any action brought by
* a third party) even if such damage or loss was reasonably foreseeable or
* Xilinx had been advised of the possibility of the same.
*
* CRITICAL APPLICATIONS
* Xilinx products are not designed or intended to be fail-safe, or for use in
* any application requiring fail-safe performance, such as life-support or
* safety devices or systems, Class III medical devices, nuclear facilities,
* applications related to the deployment of airbags, or any other applications
* that could lead to death, personal injury, or severe property or
* environmental damage (individually and collectively, "Critical
* Applications"). Customer assumes the sole risk and liability of any use of
* Xilinx products in Critical Applications, subject only to applicable laws
* and regulations governing limitations on product liability.
*
* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
* AT ALL TIMES.
*
******************************************************************************/
/******************************************************************************/
/**
*
* @file xiomodule_example.c
*
* This file contains a self test example using the IO Module driver
* (XIoModule) and hardware device. Please reference other device driver
* examples to see more examples of how the interrupts, timers and UART can be
* used by a software application.
*
* @note
*
* None
*
* <pre>
*
* MODIFICATION HISTORY:
* Ver Who Date Changes
* ----- ---- -------- ----------------------------------------------------
* 1.00a sa 07/15/11 First release
* </pre>
******************************************************************************/
/***************************** Include Files *********************************/
#include "xparameters.h"
#include "xstatus.h"
#include "xiomodule.h"
#include "xil_exception.h"
/************************** Constant Definitions *****************************/
/*
* The following constants map to the XPAR parameters created in the
* xparameters.h file. They are defined here such that a user can easily
* change all the needed parameters in one place.
*/
#define IOMODULE_DEVICE_ID XPAR_IOMODULE_0_DEVICE_ID
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
XStatus IoModuleExample(u16 DeviceId);
XStatus SetUpInterruptSystem(XIOModule *XIoModuleInstancePtr);
void DeviceDriverHandler(void *CallbackRef);
/************************** Variable Definitions *****************************/
static XIOModule IOModule; /* Instance of the IO Module */
/*
* Create a shared variable to be used by the main thread of processing and
* the interrupt processing.
*/
volatile static u32 InterruptProcessed = 0;
/*****************************************************************************/
/**
*
* This is the main function for the IO Module example .
*
* @param None.
*
* @return XST_SUCCESS to indicate success, otherwise XST_FAILURE.
*
* @note None.
*
****************************************************************************/
int main(void)
{
XStatus Status;
/*
* Run the example , specify the Device ID generated in xparameters.h
*/
Status = IOModuleExample(IOMODULE_DEVICE_ID);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function is an example of how to use the IO Module driver component
* (XIOModule) and the hardware device. This function is designed to work
* without external hardware devices to cause interrupts. It may not return if
* the IO Module is not properly connected to the processor in either software
* or hardware.
*
* @param DeviceId is device ID of the IO Module Device, typically
* XPAR_<IOMODULE_instance>_DEVICE_ID value from xparameters.h
*
* @return XST_SUCCESS to indicate success, otherwise XST_FAILURE
*
* @note None.
*
******************************************************************************/
XStatus IOModuleExample(u16 DeviceId)
{
XStatus Status;
/*
* Initialize the IO Module driver so that it is ready to use.
*/
Status = XIOModule_Initialize(&IOModule, DeviceId);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
/*
* Perform a self-test to ensure that the hardware was built correctly.
*/
Status = XIOModule_SelfTest(&IOModule);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
/*
* Setup the Interrupt System.
*/
Status = SetUpInterruptSystem(&IOModule);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
/*
* Generate the interrupts.
*/
Status = XOModule_GenerateIntr(&IOModule);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
/*
* Wait for the interrupts to be processed, if no interrupt occurs this
* loop will wait forever.
*/
while (1)
{
/*
* If the interrupts occurred which is indicated by the global
* variable which is set in the device driver handler, then
* stop waiting
*/
if (InterruptProcessed)
{
break;
}
}
return XST_SUCCESS;
}
/******************************************************************************/
/**
*
* This function connects the interrupt handler of the IO Module to the
* processor. This function is separate to allow it to be customized for each
* application. Each processor or RTOS may require unique processing to connect
* the interrupt handler.
*
* @param None.
*
* @return None.
*
* @note None.
*
****************************************************************************/
XStatus SetUpInterruptSystem(XIOModule *XIOModuleInstancePtr)
{
XStatus Status;
/*
* Connect a device driver handler that will be called when an interrupt
* for the device occurs, the device driver handler performs the specific
* interrupt processing for the device
*/
Status = XIOModule_Connect(XIOModuleInstancePtr, IOMODULE_DEVICE_ID,
(XInterruptHandler) DeviceDriverHandler,
(void *)0);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
/*
* Start the IO Module such that interrupts are enabled for all devices
* that cause interrupts.
*/
Status = XIOModule_Start(XIOModuleInstancePtr);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
/*
* Enable interrupts for the device and then cause interrupts so the
* handlers will be called.
*/
XIOModule_Enable(XIOModuleInstancePtr, IOMODULE_DEVICE_ID);
/*
* Initialize the exception table.
*/
Xil_ExceptionInit();
/*
* Register the IO module interrupt handler with the exception table.
*/
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)XIOModule_DeviceInterruptHandler,
(void*) 0);
/*
* Enable exceptions.
*/
Xil_ExceptionEnable();
return XST_SUCCESS;
}
/******************************************************************************/
/**
*
* This function is designed to look like an interrupt handler in a device
* driver. This is typically a 2nd level handler that is called from the
* IO Module interrupt handler. This handler would typically perform device
* specific processing such as reading and writing the registers of the device
* to clear the interrupt condition and pass any data to an application using
* the device driver. Many drivers already provide this handler and the user
* is not required to create it.
*
* @param CallbackRef is passed back to the device driver's interrupt handler
* by the XIOModule driver. It was given to the XIOModule driver in
* the XIOModule_Connect() function call. It is typically a pointer
* to the device driver instance variable if using the Xilinx Level 1
* device drivers. In this example, we do not care about the callback
* reference, so we passed it a 0 when connecting the handler to the
* XIOModule driver and we make no use of it here.
*
* @return None.
*
* @note None.
*
****************************************************************************/
void DeviceDriverHandler(void *CallbackRef)
{
/*
* Indicate the interrupt has been processed using a shared variable.
*/
InterruptsProcessed++;
}

View file

@ -0,0 +1,437 @@
/* $Id$ */
/******************************************************************************
*
* (c) Copyright 2011 Xilinx, Inc. All rights reserved.
*
* This file contains confidential and proprietary information of Xilinx, Inc.
* and is protected under U.S. and international copyright and other
* intellectual property laws.
*
* DISCLAIMER
* This disclaimer is not a license and does not grant any rights to the
* materials distributed herewith. Except as otherwise provided in a valid
* license issued to you by Xilinx, and to the maximum extent permitted by
* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
* and (2) Xilinx shall not be liable (whether in contract or tort, including
* negligence, or under any other theory of liability) for any loss or damage
* of any kind or nature related to, arising under or in connection with these
* materials, including for any direct, or any indirect, special, incidental,
* or consequential loss or damage (including loss of data, profits, goodwill,
* or any type of loss or damage suffered as a result of any action brought by
* a third party) even if such damage or loss was reasonably foreseeable or
* Xilinx had been advised of the possibility of the same.
*
* CRITICAL APPLICATIONS
* Xilinx products are not designed or intended to be fail-safe, or for use in
* any application requiring fail-safe performance, such as life-support or
* safety devices or systems, Class III medical devices, nuclear facilities,
* applications related to the deployment of airbags, or any other applications
* that could lead to death, personal injury, or severe property or
* environmental damage (individually and collectively, "Critical
* Applications"). Customer assumes the sole risk and liability of any use of
* Xilinx products in Critical Applications, subject only to applicable laws
* and regulations governing limitations on product liability.
*
* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
* AT ALL TIMES.
*
******************************************************************************/
/******************************************************************************/
/**
*
* @file xiomodule_intr_example.c
*
* This file contains a design example using the IO Module driver (XIOModule)
* and hardware device using interrupt mode.This example tests the internal
* interrupts in the IO Module.
*
* This file can be used as a standalone example or by the TestAppGen utility
* to include a test of IOModule interrupts.
*
* @note
*
* None
*
* <pre>
*
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- --------------------------------------------------------
* 1.00a sa 07/15/11 First release
* </pre>
******************************************************************************/
/***************************** Include Files *********************************/
#include "xparameters.h"
#include "xstatus.h"
#include "xiomodule.h"
#include "xil_exception.h"
/************************** Constant Definitions *****************************/
/*
* The following constants map to the XPAR parameters created in the
* xparameters.h file. They are defined here such that a user can easily
* change all the needed parameters in one place. This definition is not
* included if the example is generated from the TestAppGen test tool.
*/
#ifndef TESTAPP_GEN
#define IOMODULE_DEVICE_ID XPAR_IOMODULE_0_DEVICE_ID
#endif
#define MAX_INTR_COUNT 3
#define MIN_TIMER_BITS 8
#define RESET_VALUE ((1 << MIN_TIMER_BITS) - 1)
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
XStatus IOModuleIntrExample(XIOModule *IOModuleInstancePtr, u16 DeviceId);
XStatus IOModuleInterruptSetup(XIOModule *IOModuleInstancePtr,
u16 DeviceId);
void IOModuleHandler(void *CallBackRef, u8 Timer);
void IOModuleSetupIntrSystem(XIOModule *IOModuleInstancePtr);
void IOModuleDisableIntr(XIOModule *IOModuleInstancePtr);
/************************** Variable Definitions *****************************/
#ifndef TESTAPP_GEN
static XIOModule IOModule; /* Instance of the IO Module */
#endif
/*
* The following variables are shared between non-interrupt processing and
* interrupt processing such that they must be global.
*/
volatile int TimerExpired[XTC_DEVICE_TIMER_COUNT];
/*****************************************************************************/
/**
*
* This is the main function for the IO Module example. This function is not
* included if the example is generated from the TestAppGen test tool.
*
* @param None.
*
* @return XST_SUCCESS to indicate success, otherwise XST_FAILURE.
*
* @note None.
*
******************************************************************************/
#ifndef TESTAPP_GEN
int main(void)
{
XStatus Status;
/*
* Run the example, specify the Device ID generated in xparameters.h
*/
Status = IOModuleIntrExample(&IOModule, IOMODULE_DEVICE_ID);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
return XST_SUCCESS;
}
#endif
/*****************************************************************************/
/**
* This function does a minimal test on the IO Module device and driver as a
* design example. The purpose of this function is to illustrate how to use the
* IO Module component. It initializes the Programmable Interval Timers and
* then sets it up in compare mode with auto reload such that a periodic
* interrupt is generated.
*
* This function uses interrupt driven mode of the IO Module.
*
* @param IOModuleInstancePtr is a pointer to the IO Module driver
* Instance
* @param DeviceId is the XPAR_<IOModule_instance>_DEVICE_ID value from
* xparameters.h
*
* @return XST_SUCCESS if the Test is successful, otherwise XST_FAILURE
*
* @note This function contains an infinite loop such that if interrupts
* are not working it may never return.
*
*****************************************************************************/
XStatus IOModuleIntrExample(XIOModule *IOModuleInstancePtr, u16 DeviceId)
{
int Status;
u8 Timer;
XIOModule_Config *CfgPtr = IOModuleInstancePtr->CfgPtr;
/*
* Initialize the IO Module so that it's ready to use, specify the device
* ID that is generated in xparameters.h
*/
Status = XIOModule_Initialize(IOModuleInstancePtr, DeviceId);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Perform a self-test to ensure that the hardware was built correctly.
*/
Status = XIOModule_SelfTest(IOModuleInstancePtr);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Initialize and enable interrupts in the processor.
*/
IOModuleSetupIntrSystem(IOModuleInstancePtr);
/*
* Setup the handler for the IO Module handler that will be called from
* the interrupt context when an interrupt occurs, specify a pointer to
* the IO Module driver instance as the callback reference so the
* handler is able to access the instance data.
*/
XIOModule_SetHandler(IOModuleInstancePtr,
IOModuleHandler,
IOModuleInstancePtr);
for (Timer = 0; Timer < XTC_DEVICE_TIMER_COUNT; Timer++)
{
/*
* Skip unused timers,timers with prescaler (since they may
* have very long expiration times), timers without readable
* counters, and timers with small size (since the counter
* may not change when sampled).
*/
if (! (CfgPtr->PitUsed[Timer] &&
CfgPtr->PitPrescaler[Timer] == XTC_PRESCALER_NONE &&
CfgPtr->PitReadable[Timer] &&
CfgPtr->PitSize[Timer] > MIN_TIMER_BITS)) {
TimerExpired[Timer] = MAX_INTR_COUNT;
continue;
}
/*
* Use auto reload mode such that the Programmable Interval Timers will
* reload automatically and continue repeatedly, without this option
* they would expire once only
*/
XIOModule_Timer_SetOptions(IOModuleInstancePtr, Timer,
XTC_INT_MODE_OPTION | XTC_AUTO_RELOAD_OPTION);
/*
* Set a reset value for the Programmable Interval Timers such that
* they will expire earlier than letting them roll over from 0, the
* reset value is loaded into the Programmable Interval Timers when
* they are started.
*/
XIOModule_SetResetValue(IOModuleInstancePtr, Timer, RESET_VALUE);
/*
* Enable the interrupt for the Programmable Interval Timers.
*/
XIOModule_Enable(IOModuleInstancePtr,
Timer + XIN_IOMODULE_PIT_1_INTERRUPT_INTR);
/*
* Start the Programmable Interval Timers such that they are
* decrementing by default, then wait for them to timeout a number of
* times.
*/
XIOModule_Timer_Start(IOModuleInstancePtr, Timer);
}
while (1) {
int TotalExpiredCount = 0;
/*
* Wait for the Programmable Interval Timers to expire as indicated by
* the shared variable which the handler will increment, and stop each
* timer when it has reached the expected number of times.
*/
for (Timer = 0; Timer < XTC_DEVICE_TIMER_COUNT; Timer++) {
if (TimerExpired[Timer] >= MAX_INTR_COUNT)
XIOModule_Timer_Stop(IOModuleInstancePtr, Timer);
TotalExpiredCount += TimerExpired[Timer];
}
/*
* If all timers have expired the expected number of times, then stop
* this example.
*/
if (TotalExpiredCount == MAX_INTR_COUNT * XTC_DEVICE_TIMER_COUNT) {
break;
}
}
IOModuleDisableIntr(IOModuleInstancePtr);
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function is used by the TestAppGen generated application to setup
* the IO Module interrupts.
*
* @param IOModuleInstancePtr is the reference to the IO Module instance.
* @param DeviceId is device ID of the IO Module Device , typically
* XPAR_<IOMODULE_instance>_DEVICE_ID value from xparameters.h
*
* @return XST_SUCCESS to indicate success, otherwise XST_FAILURE
*
* @note None.
*
******************************************************************************/
XStatus IOModuleInterruptSetup(XIOModule *IOModuleInstancePtr,
u16 DeviceId)
{
XStatus Status;
/*
* Initialize the IO Module driver so that it is ready to use.
*/
Status = XIOModule_Initialize(IOModuleInstancePtr, DeviceId);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
/*
* Perform a self-test to ensure that the hardware was built correctly.
*/
Status = XIOModule_SelfTest(IOModuleInstancePtr);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
/*
* Initialize and enable interrupts in the processor.
*/
IOModuleSetupIntrSystem(IOModuleInstancePtr);
/*
* Start the IO Module such that interrupts are enabled for all
* internal interrupts.
*/
Status = XIOModule_Start(IOModuleInstancePtr);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
* This function is the handler which performs processing for the IO module.
* It is called from an interrupt context such that the amount of processing
* performed should be minimized. It is called when an interrupt occurs
* if interrupts are enabled.
*
* This handler provides an example of how to handle Programmable Interval
* Timer interrupts but is application specific.
*
* @param CallBackRef is a pointer to the callback function
* @param Timer is the number of the interrupt this handler is
* associated with.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void IOModuleHandler(void *CallBackRef, u8 Timer)
{
XIOModule *InstancePtr = (XIOModule *)CallBackRef;
/*
* Check if the Programmable Interval Timer has expired, checking is not
* necessary since that's the reason this function is executed, this just
* shows how the callback reference can be used as a pointer to the
* instance of the IO Module that had a timer that expired, increment a
* shared variable so the main thread of execution can see the timer
* expired.
*/
if (XIOModule_IsExpired(InstancePtr, Timer)) {
TimerExpired[Timer]++;
if(TimerExpired[Timer] == MAX_INTR_COUNT) {
XIOModule_Timer_SetOptions(InstancePtr, Timer, 0);
}
}
}
/*****************************************************************************/
/**
* This function initializes and enables exception handling for interrupts in
* the processor.
*
* @param IOModuleInstancePtr is the reference to the IO Module instance.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void IOModuleSetupIntrSystem(XIOModule *IOModuleInstancePtr)
{
/*
* Initialize the exception table.
*/
Xil_ExceptionInit();
/*
* Register the IO module interrupt handler with the exception table.
*/
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)XIOModule_DeviceInterruptHandler,
(void*) 0);
/*
* Enable exceptions.
*/
Xil_ExceptionEnable();
}
/******************************************************************************/
/**
*
* This function disables the interrupts for the IO Module.
*
* @param IOModuleInstancePtr is a reference to the IO Module driver
* Instance.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void IOModuleDisableIntr(XIOModule *IOModuleInstancePtr)
{
u8 Timer;
/*
* Disable the interrupts
*/
for (Timer = 0; Timer < XTC_DEVICE_TIMER_COUNT; Timer++)
{
XIOModule_Disable(IOModuleInstancePtr,
Timer + XIN_IOMODULE_PIT_1_INTERRUPT_INTR);
}
}

View file

@ -0,0 +1,254 @@
/* $Id$ */
/******************************************************************************
*
* (c) Copyright 2011 Xilinx, Inc. All rights reserved.
*
* This file contains confidential and proprietary information of Xilinx, Inc.
* and is protected under U.S. and international copyright and other
* intellectual property laws.
*
* DISCLAIMER
* This disclaimer is not a license and does not grant any rights to the
* materials distributed herewith. Except as otherwise provided in a valid
* license issued to you by Xilinx, and to the maximum extent permitted by
* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
* and (2) Xilinx shall not be liable (whether in contract or tort, including
* negligence, or under any other theory of liability) for any loss or damage
* of any kind or nature related to, arising under or in connection with these
* materials, including for any direct, or any indirect, special, incidental,
* or consequential loss or damage (including loss of data, profits, goodwill,
* or any type of loss or damage suffered as a result of any action brought by
* a third party) even if such damage or loss was reasonably foreseeable or
* Xilinx had been advised of the possibility of the same.
*
* CRITICAL APPLICATIONS
* Xilinx products are not designed or intended to be fail-safe, or for use in
* any application requiring fail-safe performance, such as life-support or
* safety devices or systems, Class III medical devices, nuclear facilities,
* applications related to the deployment of airbags, or any other applications
* that could lead to death, personal injury, or severe property or
* environmental damage (individually and collectively, "Critical
* Applications"). Customer assumes the sole risk and liability of any use of
* Xilinx products in Critical Applications, subject only to applicable laws
* and regulations governing limitations on product liability.
*
* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
* AT ALL TIMES.
*
******************************************************************************/
/******************************************************************************/
/**
*
* @file xiomodule_low_level_example.c
*
* This file contains a design example using the low level-0 driver, interface
* of the IO Module driver.
*
* @note
*
* None
*
* <pre>
*
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- ---------------------------------------------------------
* 1.00a sa 07/15/11 First release
* </pre>
******************************************************************************/
/***************************** Include Files *********************************/
#include "xparameters.h"
#include "xstatus.h"
#include "xiomodule_l.h"
#include "mb_interface.h"
/************************** Constant Definitions *****************************/
/*
* The following constants map to the XPAR parameters created in the
* xparameters.h file. They are defined here such that a user can easily
* change all the needed parameters in one place.
*/
#define IOMODULE_BASEADDR XPAR_IOMODULE_SINGLE_BASEADDR
#define IOMODULE_DEVICE_ID XPAR_IOMODULE_SINGLE_DEVICE_ID
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
XStatus IOModuleLowLevelExample(u32 IOModuleBaseAddress);
void SetupInterruptSystem();
void DeviceDriverHandler(void *CallbackRef);
/************************** Variable Definitions *****************************/
/*
* Create a shared variable to be used by the main thread of processing and
* the interrupt processing.
*/
volatile static Xunit32 InterruptsProcessed = 0;
/*****************************************************************************/
/**
*
* This is the main function for the IO Module Low Level example.
*
* @param None.
*
* @return XST_SUCCESS to indicate success, otherwise XST_FAILURE.
*
* @note None.
*
******************************************************************************/
int main(void)
{
XStatus Status;
/*
* Run the low level example of the IO Module, specify the Base Address
* generated in xparameters.h.
*/
Status = IOModuleLowLevelExample(IOMODULE_BASEADDR);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function is an example of how to use the IO Module driver component
* (XIOModule) and the hardware device. This function is designed to work
* without external hardware devices to cause interrupts. It may not return if
* the IO Module is not properly connected to the processor in either software
* or hardware.
*
* @param IOModuleBaseAddress is Base Address of the the IO Module Device
*
* @return XST_SUCCESS to indicate success, otherwise XST_FAILURE
*
* @note None.
*
******************************************************************************/
XStatus IOModuleLowLevelExample(u32 IOModuleBaseAddress)
{
/*
* Connect a device driver handler that will be called when an interrupt
* for the device occurs, the device driver handler performs the specific
* interrupt processing for the device
*/
XIOModule_RegisterHandler(IOModuleBaseAddress, IOMODULE_DEVICE_INTR_ID,
(XInterruptHandler)DeviceDriverHandler,
(void *)0);
/*
* Enable interrupts for all devices that cause interrupts.
*/
XIOModule_EnableIntr(IOModuleBaseAddress, IOMODULE_DEVICE_INT_MASK);
/*
* This step is processor specific, connect the handler for the interrupt
* controller to the interrupt source for the processor.
*/
SetupInterruptSystem();
/*
* Cause an interrupt so the handler will be called. This is done by
* writing a 1 to the interrupt status bit for the device interrupt.
*/
XIOModule_Out32(IOModuleBaseAddress + XIN_ISR_OFFSET,
IOMODULE_DEVICE_INT_MASK);
/*
* Wait for the interrupt to be processed, if the interrupt does not
* occur this loop will wait forever.
*/
while (1)
{
/*
* If the interrupt occurred which is indicated by the global
* variable which is set in the device driver handler, then
* stop waiting
*/
if (InterruptProcessed > 0)
{
break;
}
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function connects the interrupt handler of the IO Module to the
* processor. This function is separate to allow it to be customized for each
* application. Each processor or RTOS may require unique processing to connect
* the interrupt handler.
*
* @param None.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void SetupInterruptSystem()
{
/*
* Enable the Interrupts on the Microblaze.
*/
microblaze_enable_interrupts();
}
/*****************************************************************************/
/**
*
* This function is designed to look like an interrupt handler in a device
* driver. This is typically a 2nd level handler that is called from the
* IO Module interrupt handler. This handler would typically perform device
* specific processing such as reading and writing the registers of the device
* to clear the interrupt condition and pass any data to an application using
* the device driver. Many drivers already provide this handler and the user
* is not required to create it.
*
* @param CallbackRef is passed back to the device driver's interrupt handler
* by the XIOModule driver. It was given to the XIOModule driver in
* the XIOModule_Connect() function call. It is typically a pointer
* to the device driver instance variable if using the Xilinx Level 1
* device drivers. In this example, we do not care about the callback
* reference, so we passed it a 0 when connecting the handler to the
* XIOModule driver and we make no use of it here.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void DeviceDriverHandler(void *CallbackRef)
{
/*
* Indicate the interrupt has been processed using a shared variable.
*/
InterruptProcessed++;
}

View file

@ -0,0 +1,176 @@
/* $Id$ */
/******************************************************************************
*
* (c) Copyright 2011 Xilinx, Inc. All rights reserved.
*
* This file contains confidential and proprietary information of Xilinx, Inc.
* and is protected under U.S. and international copyright and other
* intellectual property laws.
*
* DISCLAIMER
* This disclaimer is not a license and does not grant any rights to the
* materials distributed herewith. Except as otherwise provided in a valid
* license issued to you by Xilinx, and to the maximum extent permitted by
* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
* and (2) Xilinx shall not be liable (whether in contract or tort, including
* negligence, or under any other theory of liability) for any loss or damage
* of any kind or nature related to, arising under or in connection with these
* materials, including for any direct, or any indirect, special, incidental,
* or consequential loss or damage (including loss of data, profits, goodwill,
* or any type of loss or damage suffered as a result of any action brought by
* a third party) even if such damage or loss was reasonably foreseeable or
* Xilinx had been advised of the possibility of the same.
*
* CRITICAL APPLICATIONS
* Xilinx products are not designed or intended to be fail-safe, or for use in
* any application requiring fail-safe performance, such as life-support or
* safety devices or systems, Class III medical devices, nuclear facilities,
* applications related to the deployment of airbags, or any other applications
* that could lead to death, personal injury, or severe property or
* environmental damage (individually and collectively, "Critical
* Applications"). Customer assumes the sole risk and liability of any use of
* Xilinx products in Critical Applications, subject only to applicable laws
* and regulations governing limitations on product liability.
*
* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
* AT ALL TIMES.
*
******************************************************************************/
/******************************************************************************/
/**
*
* @file xiomodule_selftest_example.c
*
* This file contains a self test example using the IO Module driver
* (XIOModule) and hardware device. Please reference other device driver
* examples to see more examples of how the interrupts, timers and UART can be
* used by a software application.
*
* The TestApp Gen utility uses this file to perform the self test and setup
* of the IO Module.
*
* @note
*
* None
*
* <pre>
*
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- --------------------------------------------------------
* 1.00a sa 07/15/11 First release
* </pre>
******************************************************************************/
/***************************** Include Files *********************************/
#include "xparameters.h"
#include "xstatus.h"
#include "xiomodule.h"
#include "mb_interface.h"
/************************** Constant Definitions *****************************/
/*
* The following constants map to the XPAR parameters created in the
* xparameters.h file. They are defined here such that a user can easily
* change all the needed parameters in one place. This definition is not
* included if the example is generated from the TestAppGen test tool.
*/
#ifndef TESTAPP_GEN
#define IOMODULE_DEVICE_ID XPAR_IOMODULE_0_DEVICE_ID
#endif
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
XStatus IOModuleSelfTestExample(u16 DeviceId);
/************************** Variable Definitions *****************************/
static XIOModule IOModule; /* Instance of the IO Module */
/*****************************************************************************/
/**
*
* This is the main function for the IO Module example. This function is not
* included if the example is generated from the TestAppGen test tool.
*
* @param None.
*
* @return XST_SUCCESS to indicate success, otherwise XST_FAILURE.
*
* @note None.
*
******************************************************************************/
#ifndef TESTAPP_GEN
int main(void)
{
XStatus Status;
/*
* Run the example, specify the Device ID generated in xparameters.h
*/
Status = IOModuleSelfTestExample(IOMODULE_DEVICE_ID);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
return XST_SUCCESS;
}
#endif
/*****************************************************************************/
/**
*
* This function runs a self-test on the driver/device. This is a destructive
* test. This function is an example of how to use the IO Module driver
* component (XIOModule) and the hardware device. This function is designed
* to work without external hardware devices to cause interrupts. It may not
* return if the IO Module is not properly connected to the processor in
* either software or hardware.
*
* @param DeviceId is device ID of the IO Module Device, typically
* XPAR_<IOMODULE_instance>_DEVICE_ID value from xparameters.h
*
* @return XST_SUCCESS to indicate success, otherwise XST_FAILURE
*
* @note None.
*
******************************************************************************/
XStatus IOModuleSelfTestExample(u16 DeviceId)
{
XStatus Status;
/*
* Initialize the IO Module driver so that it is ready to use.
*/
Status = XIOModule_Initialize(&IOModule, DeviceId);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
/*
* Perform a self-test to ensure that the hardware was built correctly.
*/
Status = XIOModule_SelfTest(&IOModule);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
return XST_SUCCESS;
}

View file

@ -0,0 +1,30 @@
COMPILER=
ARCHIVER=
CP=cp
COMPILER_FLAGS=
EXTRA_COMPILER_FLAGS=
LIB=libxil.a
LEVEL=0
RELEASEDIR=../../../lib
INCLUDEDIR=../../../include
INCLUDES=-I./. -I${INCLUDEDIR}
INCLUDEFILES=*.h
LIBSOURCES=*.c
OUTS = *.o
libs:
echo "Compiling iomodule"
$(COMPILER) $(COMPILER_FLAGS) $(EXTRA_COMPILER_FLAGS) $(INCLUDES) $(LIBSOURCES)
$(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OUTS}
make clean
include:
${CP} $(INCLUDEFILES) $(INCLUDEDIR)
clean:
rm -rf ${OUTS}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,583 @@
/******************************************************************************
*
* (c) Copyright 2011-2014 Xilinx, Inc. All rights reserved.
*
* This file contains confidential and proprietary information of Xilinx, Inc.
* and is protected under U.S. and international copyright and other
* intellectual property laws.
*
* DISCLAIMER
* This disclaimer is not a license and does not grant any rights to the
* materials distributed herewith. Except as otherwise provided in a valid
* license issued to you by Xilinx, and to the maximum extent permitted by
* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
* and (2) Xilinx shall not be liable (whether in contract or tort, including
* negligence, or under any other theory of liability) for any loss or damage
* of any kind or nature related to, arising under or in connection with these
* materials, including for any direct, or any indirect, special, incidental,
* or consequential loss or damage (including loss of data, profits, goodwill,
* or any type of loss or damage suffered as a result of any action brought by
* a third party) even if such damage or loss was reasonably foreseeable or
* Xilinx had been advised of the possibility of the same.
*
* CRITICAL APPLICATIONS
* Xilinx products are not designed or intended to be fail-safe, or for use in
* any application requiring fail-safe performance, such as life-support or
* safety devices or systems, Class III medical devices, nuclear facilities,
* applications related to the deployment of airbags, or any other applications
* that could lead to death, personal injury, or severe property or
* environmental damage (individually and collectively, "Critical
* Applications"). Customer assumes the sole risk and liability of any use of
* Xilinx products in Critical Applications, subject only to applicable laws
* and regulations governing limitations on product liability.
*
* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
* AT ALL TIMES.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xiomodule.h
*
* The Xilinx IO Module driver component. This component supports the
* IO Module. The IO Module provides:
* <ol>
* <li>Universal Asynchronous Receiver Transmitter (UART)</li>
* <li>Fixed Interval Timer (FIT)</li>
* <li>Programmable Interval Timer (PIT)</li>
* <li>General Purpose Output (GPO)</li>
* <li>General Purpose Input (GPI)</li>
* <li>Interrupt controller (INTC)</li>
* <li>IO bus (IO)</li>
* </ol>
*
* <b>Universal Asynchronous Receiver Transmitter (UART):</b>
* This UART is a minimal hardware implementation with minimal features. Most
* of the features, including parity, and number of data bits are only
* configurable when the hardware device is built, rather than at run time by
* software. The UART has an internal baud rate generator that is clocked at a
* specified input clock frequency. The baud rate can either be fixed, or
* programmable. Not all programmed baud rates can be generated from some clock
* frequencies. The requested baud rate is checked using the provided clock for
* the system, and checked against the acceptable error range. An error may be
* returned from some functions indicating the baud rate was in error because
* it could not be generated.
*
* The device has support for interrupts: a transmit interrupt, a receive
* interrupt, and an error interrupt. The interrupts are individually
* configurable when the hardware device is built.
*
* The driver defaults to no interrupts at initialization such that interrupts
* must be enabled if desired. An interrupt is generated when the transmitter
* transitions from having data to being empty, when any data is contained in
* the receive register, or when an error occurs in received data.
*
* In order to use interrupts, it's necessary for the user to connect the driver
* interrupt handler, XIOModule_InterruptHandler, to the interrupt system of the
* application. This function does not save and restore the processor context
* such that the user must provide it. Send and receive handlers may be set for
* the driver such that the handlers are called when transmit and receive
* interrupts occur. The handlers are called from interrupt context and are
* designed to allow application specific processing to be performed.
*
* The functions, XIOModule_Send and XIOModule_Recv, are provided in the driver
* to allow data to be sent and received. They are designed to be used in
* polled or interrupt modes.
*
* The driver provides a status for each received byte indicating any parity
* frame or overrun error. The driver provides statistics which allow visibility
* into these errors.
*
* <b>Fixed Interval Timer (FIT):</b>
* The fixed interval timer supports the following features:
* - Interrupt driven mode
*
* The timer has a hardware programmed time period, which can be configured to
* cause a periodic interrupt. The driver only provides the ability to handle
* such interrupts.
*
* <b>Programmable Interval Timer (PIT):</b>
* The programmable interval timer supports the following features:
* - Polled mode
* - Interrupt driven mode
* - Enabling and disabling
* - Automatic reload
*
* The timer operates in compare mode. The timer always counts down.
*
* Compare mode is typically used for creating a single time period or multiple
* repeating time periods in the auto reload mode, such as a periodic interrupt.
* When started, the timer loads an initial value, referred to as the load
* value, into the timer and starts counting down. The timer expires when it
* rolls under. An external Output signal may be configured such that a pulse
* is generated with this signal when it rolls under.
*
* The timer can be configured to cause an interrupt when the count reaches
* zero. An external output is also toggled when the count reaches zero.
*
* <b>Interrupts</b>
*
* It is the responsibility of the application to connect the interrupt
* handler of the timer to the interrupt source. The interrupt handler function,
* XIOModule_InterruptHandler, is visible such that the user can connect it to
* the interrupt source. Note that this interrupt handler does not provide
* interrupt context save and restore processing, the user must perform this
* processing.
*
* The driver services interrupts and passes timeouts to the upper layer
* software through callback functions. The upper layer software must register
* its callback functions during initialization. The driver requires callback
* functions for timers.
*
* <b>General Purpose Output (GPO):</b>
* The GPO has support for up to 32 I/O discrete outputs for each channel (128
* bits total).
*
* <b>IO Bus (IO):</b>
* The IO Bus provides a generic mechanism to extend the IO Module
* functionality by providing a memory mapped IO area. Reading and writing of
* byte, halfword and word data is provided.
*
* <b>General Purpose Input (GPI):</b>
* The GPI has support for up to 32 I/O discrete outputs for each channel (128
* bits total). An interrupt can be generated when any bit in a GPI changes.
*
* <b>Interrupt controller (INTC):</b>
* The interrupt controller driver uses the idea of priority for the various
* handlers. Priority is an integer within the range of 0 and 31 inclusive with
* 0 being the highest priority interrupt source.
*
* The Xilinx interrupt controller supports the following features:
*
* - specific individual interrupt enabling/disabling
* - specific individual interrupt acknowledging
* - attaching specific callback function to handle interrupt source
* - master enable/disable
* - single callback per interrupt or all pending interrupts handled for
* each interrupt of the processor
*
* The acknowledgement of the interrupt within the interrupt controller is
* selectable, either prior to the device's handler being called or after
* the handler is called. This is necessary to support interrupt signal inputs
* which are either edge or level signals. Edge driven interrupt signals
* require that the interrupt is acknowledged prior to the interrupt being
* serviced in order to prevent the loss of interrupts which are occurring
* extremely close together. A level driven interrupt input signal requires
* the interrupt to acknowledged after servicing the interrupt to ensure that
* the interrupt only generates a single interrupt condition.
*
* Details about connecting the interrupt handler of the driver are contained
* in the source file specific to interrupt processing, xiomodule_intr.c.
*
* This driver is intended to be RTOS and processor independent. It works with
* physical addresses only. Any needs for dynamic memory management, threads
* or thread mutual exclusion, virtual memory, or cache control must be
* satisfied by the layer above this driver.
*
* <b>Interrupt Vector Tables</b>
*
* The interrupt vector table for each interrupt controller device is declared
* statically in xiomodule_g.c within the configuration data for each instance.
* The device ID of the interrupt controller device is used by the driver as a
* direct index into the configuration data table - to retrieve the vector table
* for an instance of the interrupt controller. The user should populate the
* vector table with handlers and callbacks at run-time using the
* XIOModule_Connect() and XIOModule_Disconnect() functions.
*
* Each vector table entry corresponds to a device that can generate an
* interrupt. Each entry contains an interrupt handler function and an argument
* to be passed to the handler when an interrupt occurs. The tools default this
* argument to the base address of the interrupting device. Note that the
* device driver interrupt handlers given in this file do not take a base
* address as an argument, but instead take a pointer to the driver instance.
* This means that although the table is created statically, the user must still
* use XIOModule_Connect() when the interrupt handler takes an argument other
* than the base address. This is only to say that the existence of the static
* vector tables should not mislead the user into thinking they no longer need
* to register/connect interrupt handlers with this driver.
*
* With fast interrupts enabled, the XIOModule_ConnectFastHandler() function
* should be used instead of XIOModule_Connect(). Note that the function pointer
* parameter Handler, must be a declared with the fast_interrupt attribute:
*
* void Handler() __attribute__((fast_interrupt));
*
* The routine defined by XIOModule_Connect() can be used by setting normal
* interrupt mode, using XIOModule_SetNormalIntrMode().
*
* @note
*
* This API utilizes 32 bit I/O to the registers. With less than 32 bits, the
* unused bits from registers are read as zero and written as don't cares.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a sa 07/15/11 First release
* 1.01a sa 04/10/12 Updated with fast interrupt
* 1.02a sa 07/25/12 Updated with GPI interrupts and programmable baudrate
* 2.0 adk 19/12/13 Updated as per the New Tcl API's
* 2.1 bss 05/02/14 Added PitMask in XIOModule_Config.(CR #794167)
* </pre>
*
******************************************************************************/
#ifndef IOMODULE_H /* prevent circular inclusions */
#define IOMODULE_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xparameters.h"
#include "xstatus.h"
#include "xiomodule_l.h"
#include "xil_types.h"
/************************** Constant Definitions *****************************/
/**
* @name Configuration options
* These options are used in XIOModule_SetOptions() to configure the
* device.
* @{
*/
/**
* Used to configure the Programmable Interval Timer.
* <pre>
* XTC_INT_MODE_OPTION Dummy compatibility option. Enable interrupt
* output.
* XTC_AUTO_RELOAD_OPTION In compare mode, configures the timer to reload
* from the load value. The default mode causes
* the timer to hold after it rolls under.
* </pre>
*/
#define XTC_INT_MODE_OPTION 0
#define XTC_AUTO_RELOAD_OPTION 0x00000002UL
/**
* Used to configure the Interrupt Controller.
* <pre>
* XIN_SVC_SGL_ISR_OPTION Service the highest priority pending interrupt
* and then return.
* XIN_SVC_ALL_ISRS_OPTION Service all of the pending interrupts and then
* return.
* </pre>
*/
#define XIN_SVC_SGL_ISR_OPTION 1UL
#define XIN_SVC_ALL_ISRS_OPTION 2UL
/*@}*/
/**
* @name Hardware configuration mnemonics
* These mnemonics are used when accessing hardware configuration parameters.
* @{
*/
/**
* Mnemonics for the Programmable Interval Timer hardware configuration.
* <pre>
* XTC_PRESCALER_* Define the prescaler configured in hardware.
* </pre>
*/
#define XTC_PRESCALER_NONE 0
#define XTC_PRESCALER_FIT1 1
#define XTC_PRESCALER_FIT2 2
#define XTC_PRESCALER_FIT3 3
#define XTC_PRESCALER_FIT4 4
#define XTC_PRESCALER_PIT1 5
#define XTC_PRESCALER_PIT2 6
#define XTC_PRESCALER_PIT3 7
#define XTC_PRESCALER_PIT4 8
#define XTC_PRESCALER_EXTERNAL 9
/*@}*/
/**************************** Type Definitions *******************************/
/**
* Callback function. The first argument is a callback reference passed in by
* the upper layer when setting the callback functions, and passed back to the
* upper layer when the callback is invoked.
* The second argument is the ByteCount which is the number of bytes that
* actually moved from/to the buffer provided in the _Send/_Receive call.
*/
typedef void (*XIOModule_Handler)(void *CallBackRef,
unsigned int ByteCount);
/**
* This typedef contains configuration information for the device.
*/
typedef struct {
u16 DeviceId; /**< Unique ID of device */
u32 BaseAddress; /**< Unique identifier */
u32 IoBaseAddress; /**< IO Bus Base Address */
u32 FastIntr; /**< Fast Interrupt enabled */
u32 BaseVector; /**< Relocatable base vector */
u32 AckBeforeService; /**< Ack location per interrupt */
u32 Options; /**< Device options */
u32 InputClockHz; /**< Input clock frequency (Hz) */
u32 BaudRate; /**< Current baud rate */
u8 PitUsed[XTC_DEVICE_TIMER_COUNT]; /**< PIT is used */
u8 PitSize[XTC_DEVICE_TIMER_COUNT]; /**< PIT timer counter size */
u32 PitMask[XTC_DEVICE_TIMER_COUNT]; /**< PIT timer counter size */
u8 PitPrescaler[XTC_DEVICE_TIMER_COUNT]; /**< PIT prescaler */
u8 PitReadable[XTC_DEVICE_TIMER_COUNT]; /**< PIT readable */
u32 GpoInit[XGPO_DEVICE_COUNT]; /**< GPO initial value */
XIOModule_VectorTableEntry
HandlerTable[XPAR_IOMODULE_INTC_MAX_INTR_SIZE];
/**< Static vector table of interrupt handlers */
} XIOModule_Config;
/**
* Statistics for the UART
*/
typedef struct {
u32 TransmitInterrupts; /**< Number of transmit interrupts */
u32 ReceiveInterrupts; /**< Number of receive interrupts */
u32 CharactersTransmitted; /**< Number of characters transmitted */
u32 CharactersReceived; /**< Number of characters received */
u32 ReceiveOverrunErrors; /**< Number of receive overruns */
u32 ReceiveParityErrors; /**< Number of receive parity errors */
u32 ReceiveFramingErrors; /**< Number of receive framing errors */
} XIOModule_Uart_Stats;
/**
* The following data type is used to manage the buffers that are handled
* when sending and receiving UART data in the interrupt mode. It is intended
* for internal use only.
*/
typedef struct {
u8 *NextBytePtr;
unsigned int RequestedBytes;
unsigned int RemainingBytes;
} XIOModule_Buffer;
/**
* Signature for the timer callback function.
*
* @param CallBackRef is a callback reference passed in by the upper
* layer when setting the callback functions, and passed back to
* the upper layer when the callback is invoked. Its type is
* unimportant to the driver, so it is a void pointer.
* @param TimerNumber is the number of the timer within the device. The
* device typically contains from one to four timers. The timer
* number is a zero based number with a range of 0 to
* (XTC_DEVICE_TIMER_COUNT - 1).
*/
typedef void (*XIOModule_Timer_Handler) (void *CallBackRef, u8 TimerNumber);
/**
* Programmable Interval Timer statistics
*/
typedef struct {
u32 Interrupts; /**< Number of timer interrupts that have occurred */
} XIOModule_Timer_Stats;
/**
* The XIOModule driver instance data. The user is required to allocate a
* variable of this type for every iomodule device in the system. A pointer
* to a variable of this type is then passed to the driver API functions.
*/
typedef struct {
u32 BaseAddress; /**< Base address of registers */
u32 IsReady; /**< Device initialized and ready */
u32 IsStarted; /**< Device has been started */
XIOModule_Config *CfgPtr; /**< Pointer to inst config entry */
XIOModule_Uart_Stats Uart_Stats; /**< UART Statistics */
XIOModule_Buffer SendBuffer; /**< UART Send buffer */
XIOModule_Buffer ReceiveBuffer; /**< UART Receive buffer */
XIOModule_Handler RecvHandler; /**< UART Receive Handler */
void *RecvCallBackRef; /**< Callback ref for recv handler */
XIOModule_Handler SendHandler; /**< UART Send Handler */
void *SendCallBackRef; /**< Callback ref for send handler */
u32 CurrentUBRR; /**< UART Baud Rate Register value */
u32 UnhandledInterrupts; /**< Iomodule Interrupt Statistics */
u32 CurrentIER; /**< Interrupt Enable Register value*/
u32 CurrentIMR; /**< Interrupt Mode Register value */
XIOModule_Timer_Stats Timer_Stats[XTC_DEVICE_TIMER_COUNT];
/**< Timer statistics */
u32 CurrentTLR[XTC_DEVICE_TIMER_COUNT];
/**< Timer Load Register values */
u8 CurrentTCSR[XTC_DEVICE_TIMER_COUNT];
/**< Timer Control Register values */
XIOModule_Timer_Handler Handler; /**< Timer Callback function */
void *CallBackRef; /**< Timer Callback handler ref */
u32 GpoValue[XGPO_DEVICE_COUNT]; /**< GPO current value */
u32 IoBaseAddress; /**< Base address of IO Bus */
} XIOModule;
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/*
* Required functions in xiomodule.c
*/
int XIOModule_Initialize(XIOModule * InstancePtr, u16 DeviceId);
int XIOModule_Timer_Initialize(XIOModule * InstancePtr, u16 DeviceId);
int XIOModule_Start(XIOModule * InstancePtr);
void XIOModule_Stop(XIOModule * InstancePtr);
int XIOModule_Connect(XIOModule * InstancePtr, u8 Id,
XInterruptHandler Handler, void *CallBackRef);
void XIOModule_Disconnect(XIOModule * InstancePtr, u8 Id);
void XIOModule_Enable(XIOModule * InstancePtr, u8 Id);
void XIOModule_Disable(XIOModule * InstancePtr, u8 Id);
void XIOModule_Acknowledge(XIOModule * InstancePtr, u8 Id);
XIOModule_Config *XIOModule_LookupConfig(u16 DeviceId);
int XIOModule_ConnectFastHandler(XIOModule *InstancePtr, u8 Id,
XFastInterruptHandler Handler);
void XIOModule_SetNormalIntrMode(XIOModule *InstancePtr, u8 Id);
/*
* API Basic functions for GPI and GPO implemented in xiomodule.c
*/
u32 XIOModule_DiscreteRead(XIOModule *InstancePtr, unsigned Channel);
void XIOModule_DiscreteWrite(XIOModule *InstancePtr,
unsigned Channel,
u32 Mask);
/*
* API Functions for GPI and GPO implemented in xiomodule_extra.c
*/
void XIOModule_DiscreteSet(XIOModule *InstancePtr, unsigned Channel, u32 Mask);
void XIOModule_DiscreteClear(XIOModule *InstancePtr,
unsigned Channel,
u32 Mask);
/*
* Required functions, in file xiomodule_uart.c
*/
int XIOModule_CfgInitialize(XIOModule *InstancePtr,
XIOModule_Config *Config,
u32 EffectiveAddr);
void XIOModule_ResetFifos(XIOModule *InstancePtr); /* Dummy */
unsigned int XIOModule_Send(XIOModule *InstancePtr, u8 *DataBufferPtr,
unsigned int NumBytes);
unsigned int XIOModule_Recv(XIOModule *InstancePtr, u8 *DataBufferPtr,
unsigned int NumBytes);
int XIOModule_IsSending(XIOModule *InstancePtr);
int XIOModule_SetBaudRate(XIOModule *InstancePtr, u32 BaudRate);
/*
* Functions for statistics, in file xiomodule_stats.c
*/
void XIOModule_GetStats(XIOModule *InstancePtr,
XIOModule_Uart_Stats *StatsPtr);
void XIOModule_ClearStats(XIOModule *InstancePtr);
/*
* Interrupt functions in xiomodule_intr.c
*/
void XIOModule_VoidInterruptHandler();
void XIOModule_InterruptHandler(XIOModule * InstancePtr);
void XIOModule_Uart_EnableInterrupt(XIOModule *InstancePtr);
void XIOModule_Uart_DisableInterrupt(XIOModule *InstancePtr);
void XIOModule_SetRecvHandler(XIOModule *InstancePtr, XIOModule_Handler FuncPtr,
void *CallBackRef);
void XIOModule_SetSendHandler(XIOModule *InstancePtr, XIOModule_Handler FuncPtr,
void *CallBackRef);
void XIOModule_Uart_InterruptHandler(XIOModule *InstancePtr);
/*
* Options functions in xiomodule_options.c
*/
int XIOModule_SetOptions(XIOModule * InstancePtr, u32 Options);
u32 XIOModule_GetOptions(XIOModule * InstancePtr);
/*
* Self-test functions in xiomodule_selftest.c
*/
int XIOModule_SelfTest(XIOModule * InstancePtr);
/*
* Required functions, in file xiomodule.c
*/
void XIOModule_Timer_Start(XIOModule * InstancePtr, u8 TimerNumber);
void XIOModule_Timer_Stop(XIOModule * InstancePtr, u8 TimerNumber);
u32 XIOModule_GetValue(XIOModule * InstancePtr, u8 TimerNumber);
void XIOModule_SetResetValue(XIOModule * InstancePtr, u8 TimerNumber,
u32 ResetValue);
u32 XIOModule_GetCaptureValue(XIOModule * InstancePtr, u8 TimerNumber);
int XIOModule_IsExpired(XIOModule * InstancePtr, u8 TimerNumber);
void XIOModule_Reset(XIOModule * InstancePtr, u8 TimerNumber);
/*
* Functions for options, in file xiomodule_options.c
*/
void XIOModule_Timer_SetOptions(XIOModule * InstancePtr, u8 TimerNumber,
u32 Options);
u32 XIOModule_Timer_GetOptions(XIOModule * InstancePtr, u8 TimerNumber);
/*
* Functions for statistics, in file xiomodule_stats.c
*/
void XIOModule_Timer_GetStats(XIOModule * InstancePtr,
XIOModule_Timer_Stats * StatsPtr);
void XIOModule_Timer_ClearStats(XIOModule * InstancePtr);
/*
* Functions for self-test, in file xiomodule_selftest.c
*/
int XIOModule_Timer_SelfTest(XIOModule * InstancePtr, u8 IOModuleNumber);
/*
* Functions for interrupts, in file xiomodule_intr.c
*/
void XIOModule_SetHandler(XIOModule * InstancePtr,
XIOModule_Timer_Handler FuncPtr,
void *CallBackRef);
void XIOModule_Timer_InterruptHandler(void *InstancePtr);
/*
* Basic functions for IO Bus read and write implemented in xiomodule.c
*/
u32 XIOModule_IoReadWord(XIOModule *InstancePtr, u32 ByteOffset);
u16 XIOModule_IoReadHalfword(XIOModule *InstancePtr, u32 ByteOffset);
u8 XIOModule_IoReadByte(XIOModule *InstancePtr, u32 ByteOffset);
void XIOModule_IoWriteWord(XIOModule *InstancePtr, u32 ByteOffset, u32 Data);
void XIOModule_IoWriteHalfword(XIOModule *InstancePtr, u32 ByteOffset, u16 Data);
void XIOModule_IoWriteByte(XIOModule *InstancePtr, u32 ByteOffset, u8 Data);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */

View file

@ -0,0 +1,159 @@
/******************************************************************************
*
* (c) Copyright 2011-2014 Xilinx, Inc. All rights reserved.
*
* This file contains confidential and proprietary information of Xilinx, Inc.
* and is protected under U.S. and international copyright and other
* intellectual property laws.
*
* DISCLAIMER
* This disclaimer is not a license and does not grant any rights to the
* materials distributed herewith. Except as otherwise provided in a valid
* license issued to you by Xilinx, and to the maximum extent permitted by
* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
* and (2) Xilinx shall not be liable (whether in contract or tort, including
* negligence, or under any other theory of liability) for any loss or damage
* of any kind or nature related to, arising under or in connection with these
* materials, including for any direct, or any indirect, special, incidental,
* or consequential loss or damage (including loss of data, profits, goodwill,
* or any type of loss or damage suffered as a result of any action brought by
* a third party) even if such damage or loss was reasonably foreseeable or
* Xilinx had been advised of the possibility of the same.
*
* CRITICAL APPLICATIONS
* Xilinx products are not designed or intended to be fail-safe, or for use in
* any application requiring fail-safe performance, such as life-support or
* safety devices or systems, Class III medical devices, nuclear facilities,
* applications related to the deployment of airbags, or any other applications
* that could lead to death, personal injury, or severe property or
* environmental damage (individually and collectively, "Critical
* Applications"). Customer assumes the sole risk and liability of any use of
* Xilinx products in Critical Applications, subject only to applicable laws
* and regulations governing limitations on product liability.
*
* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
* AT ALL TIMES.
*
******************************************************************************/
/*****************************************************************************/
/**
* @file xiomodule_extra.c
*
* The implementation of the XIOModule component's advanced discrete
* functions. See xiomodule.h for more information about the component.
*
* @note
*
* None
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a sa 07/15/11 First release
* </pre>
*
*****************************************************************************/
/***************************** Include Files ********************************/
#include "xiomodule.h"
#include "xiomodule_i.h"
#include "xil_types.h"
#include "xil_assert.h"
/************************** Constant Definitions ****************************/
/**************************** Type Definitions ******************************/
/***************** Macros (Inline Functions) Definitions ********************/
/************************** Variable Definitions ****************************/
/************************** Function Prototypes *****************************/
/****************************************************************************/
/**
* Set output discrete(s) to logic 1 for the specified GPO channel.
*
* @param InstancePtr is a pointer to an XIOModule instance to be
* worked on.
* @param Channel contains the channel of the GPIO (1, 2, 3 or 4) to
* operate on.
* @param Mask is the set of bits that will be set to 1 in the discrete
* data register. All other bits in the data register are
* unaffected.
*
* @return None.
*
*****************************************************************************/
void XIOModule_DiscreteSet(XIOModule * InstancePtr, unsigned Channel, u32 Mask)
{
u32 Current;
unsigned DataOffset;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertVoid((Channel >= 1) && (Channel <= XGPO_DEVICE_COUNT));
/*
* Calculate the offset to the data register of the GPO
*/
DataOffset = ((Channel - 1) * XGPO_CHAN_OFFSET) + XGPO_DATA_OFFSET;
/*
* Read the contents from the instance, merge in Mask and write
* back results
*/
Current = InstancePtr->GpoValue[Channel - 1];
Current |= Mask;
XIOModule_WriteReg(InstancePtr->BaseAddress, DataOffset, Current);
InstancePtr->GpoValue[Channel - 1] = Current;
}
/****************************************************************************/
/**
* Set output discrete(s) to logic 0 for the specified GPO channel.
*
* @param InstancePtr is a pointer to an XIOModule instance to be
* worked on.
* @param Channel contains the channel of the GPIO (1, 2, 3 or 4) to
* operate on.
* @param Mask is the set of bits that will be set to 0 in the discrete
* data register. All other bits in the data register are
* unaffected.
*
* @return None.
*
*****************************************************************************/
void XIOModule_DiscreteClear(XIOModule * InstancePtr,
unsigned Channel,
u32 Mask)
{
u32 Current;
unsigned DataOffset;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertVoid((Channel >= 1) && (Channel <= XGPO_DEVICE_COUNT));
/*
* Calculate the offset to the data register of the GPO
*/
DataOffset = ((Channel - 1) * XGPO_CHAN_OFFSET) + XGPO_DATA_OFFSET;
/*
* Read the contents from the instance, merge in Mask and write
* back results
*/
Current = InstancePtr->GpoValue[Channel - 1];
Current &= ~Mask;
XIOModule_WriteReg(InstancePtr->BaseAddress, DataOffset, Current);
InstancePtr->GpoValue[Channel - 1] = Current;
}

View file

@ -0,0 +1,137 @@
/******************************************************************************
*
* (c) Copyright 2011-2014 Xilinx, Inc. All rights reserved.
*
* This file contains confidential and proprietary information of Xilinx, Inc.
* and is protected under U.S. and international copyright and other
* intellectual property laws.
*
* DISCLAIMER
* This disclaimer is not a license and does not grant any rights to the
* materials distributed herewith. Except as otherwise provided in a valid
* license issued to you by Xilinx, and to the maximum extent permitted by
* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
* and (2) Xilinx shall not be liable (whether in contract or tort, including
* negligence, or under any other theory of liability) for any loss or damage
* of any kind or nature related to, arising under or in connection with these
* materials, including for any direct, or any indirect, special, incidental,
* or consequential loss or damage (including loss of data, profits, goodwill,
* or any type of loss or damage suffered as a result of any action brought by
* a third party) even if such damage or loss was reasonably foreseeable or
* Xilinx had been advised of the possibility of the same.
*
* CRITICAL APPLICATIONS
* Xilinx products are not designed or intended to be fail-safe, or for use in
* any application requiring fail-safe performance, such as life-support or
* safety devices or systems, Class III medical devices, nuclear facilities,
* applications related to the deployment of airbags, or any other applications
* that could lead to death, personal injury, or severe property or
* environmental damage (individually and collectively, "Critical
* Applications"). Customer assumes the sole risk and liability of any use of
* Xilinx products in Critical Applications, subject only to applicable laws
* and regulations governing limitations on product liability.
*
* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
* AT ALL TIMES.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xiomodule_g.c
*
* This file contains a configuration table that specifies the configuration of
* interrupt controller devices in the system.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a sa 07/15/11 First release
* </pre>
*
* @internal
*
* This configuration table contains entries that are modified at runtime
* by the driver. The EDK tools populate the table with default values for the
* vector table and the options flag. These default values can be, and are,
* overwritten at runtime by the driver. This is a deviation from most drivers'
* configuration tables in that most are created statically by the tools and
* are never modified during runtime. Most tables reflect only the hardware
* configuration of the device. This IOModule configuration table contains
* software information in addition to hardware configuration. The IOModule
* configuration table should be considered an exception to the usage of the
* configuration table rather than the norm.
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xiomodule.h"
#include "xparameters.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************** Variable Prototypes ******************************/
/**
* This table contains configuration information for each iomodule device
* in the system. The XIOModule driver must know when to acknowledge the
* interrupt. The entry which specifies this as a bit mask where each bit
* corresponds to a specific interrupt. A bit set indicates to ack it before
* servicing it. Generally, acknowledge before service is used when the
* interrupt signal is edge-sensitive, and after when the signal is
* level-sensitive.
*
* Refer to the XIOModule_Config data structure in xiomodule.h for
* details on how this table should be initialized.
*/
XIOModule_Config XIOModule_ConfigTable[XPAR_XIOMODULE_NUM_INSTANCES] = {
{
XPAR_IOMODULE_0_DEVICE_ID, /* Unique ID of device */
XPAR_IOMODULE_0_REG_BASEADDR, /* Unique identifier */
XPAR_IOMODULE_0_IO_BASEADDR, /* IO Bus Base Address */
XPAR_IOMODULE_0_INTC_HAS_FAST, /* Fast interrupt enabled */
XPAR_IOMODULE_0_INTC_BASE_VECTORS, /* Relocatable base vector */
XPAR_IOMODULE_0_ACK_BEFORE, /* Ack before or after service */
0, /* Device options */
100000000, /* Input clock frequency (Hz) */
115200, /* Current baud rate */
{0, 0, 0, 0}, /* PIT timer used */
{0, 0, 0, 0}, /* PIT timer counter size */
{0, 0, 0, 0}, /* PIT prescaler */
{0, 0, 0, 0}, /* PIT readable */
{0, 0, 0, 0} /* GPO initial value */
}
,
{
XPAR_IOMODULE_1_DEVICE_ID, /* Unique ID of device */
XPAR_IOMODULE_1_REG_BASEADDR, /* Unique identifier */
XPAR_IOMODULE_1_IO_BASEADDR, /* IO Bus Base Address */
XPAR_IOMODULE_1_INTC_HAS_FAST, /* Fast interrupt enabled */
XPAR_IOMODULE_1_INTC_BASE_VECTORS, /* Relocatable base vector */
XPAR_IOMODULE_1_ACK_BEFORE, /* Ack before or after service */
0, /* Device options */
100000000, /* Input clock frequency (Hz) */
115200, /* Current baud rate */
{0, 0, 0, 0}, /* PIT timer used */
{0, 0, 0, 0}, /* PIT timer counter size */
{0, 0, 0, 0}, /* PIT prescaler */
{0, 0, 0, 0}, /* PIT readable */
{0, 0, 0, 0} /* GPO initial value */
}
};

View file

@ -0,0 +1,127 @@
/******************************************************************************
*
* (c) Copyright 2011-2014 Xilinx, Inc. All rights reserved.
*
* This file contains confidential and proprietary information of Xilinx, Inc.
* and is protected under U.S. and international copyright and other
* intellectual property laws.
*
* DISCLAIMER
* This disclaimer is not a license and does not grant any rights to the
* materials distributed herewith. Except as otherwise provided in a valid
* license issued to you by Xilinx, and to the maximum extent permitted by
* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
* and (2) Xilinx shall not be liable (whether in contract or tort, including
* negligence, or under any other theory of liability) for any loss or damage
* of any kind or nature related to, arising under or in connection with these
* materials, including for any direct, or any indirect, special, incidental,
* or consequential loss or damage (including loss of data, profits, goodwill,
* or any type of loss or damage suffered as a result of any action brought by
* a third party) even if such damage or loss was reasonably foreseeable or
* Xilinx had been advised of the possibility of the same.
*
* CRITICAL APPLICATIONS
* Xilinx products are not designed or intended to be fail-safe, or for use in
* any application requiring fail-safe performance, such as life-support or
* safety devices or systems, Class III medical devices, nuclear facilities,
* applications related to the deployment of airbags, or any other applications
* that could lead to death, personal injury, or severe property or
* environmental damage (individually and collectively, "Critical
* Applications"). Customer assumes the sole risk and liability of any use of
* Xilinx products in Critical Applications, subject only to applicable laws
* and regulations governing limitations on product liability.
*
* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
* AT ALL TIMES.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xiomodule_i.h
*
* This file contains data which is shared between files and internal to the
* XIOModule component. It is intended for internal use only.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a sa 07/15/11 First release
* 1.02a sa 07/25/12 Added UART prototypes
* </pre>
*
******************************************************************************/
#ifndef XIOMODULE_I_H /* prevent circular inclusions */
#define XIOMODULE_I_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xiomodule.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/****************************************************************************
*
* Update the statistics of the instance.
*
* @param InstancePtr is a pointer to the XIOMOdule instance.
* @param StatusRegister contains the contents of the UART status
* register to update the statistics with.
*
* @return None.
*
* @note
*
* Signature: void XIOModule_UpdateStats(XIOModule *InstancePtr,
* u32 StatusRegister)
*
*****************************************************************************/
#define XIOModule_UpdateStats(InstancePtr, StatusRegister) \
{ \
if ((StatusRegister) & XUL_SR_OVERRUN_ERROR) \
{ \
(InstancePtr)->Uart_Stats.ReceiveOverrunErrors++; \
} \
if ((StatusRegister) & XUL_SR_PARITY_ERROR) \
{ \
(InstancePtr)->Uart_Stats.ReceiveParityErrors++; \
} \
if ((StatusRegister) & XUL_SR_FRAMING_ERROR) \
{ \
(InstancePtr)->Uart_Stats.ReceiveFramingErrors++; \
} \
}
/************************** Function Prototypes ******************************/
unsigned int XIOModule_SendBuffer(XIOModule *InstancePtr);
unsigned int XIOModule_ReceiveBuffer(XIOModule *InstancePtr);
/************************** Variable Definitions *****************************/
extern u32 XIOModule_BitPosMask[];
extern XIOModule_Config XIOModule_ConfigTable[];
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,312 @@
/******************************************************************************
*
* (c) Copyright 2011-2014 Xilinx, Inc. All rights reserved.
*
* This file contains confidential and proprietary information of Xilinx, Inc.
* and is protected under U.S. and international copyright and other
* intellectual property laws.
*
* DISCLAIMER
* This disclaimer is not a license and does not grant any rights to the
* materials distributed herewith. Except as otherwise provided in a valid
* license issued to you by Xilinx, and to the maximum extent permitted by
* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
* and (2) Xilinx shall not be liable (whether in contract or tort, including
* negligence, or under any other theory of liability) for any loss or damage
* of any kind or nature related to, arising under or in connection with these
* materials, including for any direct, or any indirect, special, incidental,
* or consequential loss or damage (including loss of data, profits, goodwill,
* or any type of loss or damage suffered as a result of any action brought by
* a third party) even if such damage or loss was reasonably foreseeable or
* Xilinx had been advised of the possibility of the same.
*
* CRITICAL APPLICATIONS
* Xilinx products are not designed or intended to be fail-safe, or for use in
* any application requiring fail-safe performance, such as life-support or
* safety devices or systems, Class III medical devices, nuclear facilities,
* applications related to the deployment of airbags, or any other applications
* that could lead to death, personal injury, or severe property or
* environmental damage (individually and collectively, "Critical
* Applications"). Customer assumes the sole risk and liability of any use of
* Xilinx products in Critical Applications, subject only to applicable laws
* and regulations governing limitations on product liability.
*
* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
* AT ALL TIMES.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xiomodule_intr.c
*
* This file contains the interrupt processing for the XIOModule component
* which is the driver for the Xilinx IO Module interrupt. The interrupt
* processing is partitioned seperately such that users are not required to
* use the provided interrupt processing. This file requires other files of
* the driver to be linked in also.
*
* Two different interrupt handlers are provided for this driver such that the
* user must select the appropriate handler for the application. The first
* interrupt handler, XIOModule_VoidInterruptHandler, is provided for
* systems which use only a single interrupt controller or for systems that
* cannot otherwise provide an argument to the XIOModule interrupt handler
* (e.g., the RTOS interrupt vector handler may not provide such a facility).
* The constant XPAR_IOMODULE_SINGLE_DEVICE_ID must be defined for this
* handler to be included in the driver. The second interrupt handler,
* XIOModule_InterruptHandler, uses an input argument which is an instance
* pointer to an interrupt controller driver such that multiple interrupt
* controllers can be supported. This handler requires the calling function
* to pass it the appropriate argument, so another level of indirection may be
* required.
*
* Note that both of these handlers are now only provided for backward
* compatibility. The handler defined in xiomodule_l.c is the recommended
* handler.
*
* The interrupt processing may be used by connecting one of the interrupt
* handlers to the interrupt system. These handlers do not save and restore
* the processor context but only handle the processing of the Interrupt
* Controller. The two handlers are provided as working examples. The user is
* encouraged to supply their own interrupt handler when performance tuning is
* deemed necessary.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- ---------------------------------------------------------
* 1.00a sa 07/15/11 First release
* 1.02a sa 07/25/12 Added UART interrupt related functions
* 1.03a sa 10/16/12 Moved UART interrupt related functions to separate file
* </pre>
*
* @internal
*
* This driver assumes that the context of the processor has been saved prior to
* the calling of the IO Module interrupt handler and then restored
* after the handler returns. This requires either the running RTOS to save the
* state of the machine or that a wrapper be used as the destination of the
* interrupt vector to save the state of the processor and restore the state
* after the interrupt handler returns.
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xparameters.h"
#include "xiomodule.h"
#include "xil_types.h"
#include "xil_assert.h"
/************************** Constant Definitions *****************************/
/*
* Array of masks associated with the bit position, improves performance
* in the ISR, this table is shared between all instances of the driver
*/
u32 XIOModule_TimerBitPosMask[XTC_DEVICE_TIMER_COUNT] = {
1 << XIN_IOMODULE_PIT_1_INTERRUPT_INTR,
1 << XIN_IOMODULE_PIT_2_INTERRUPT_INTR,
1 << XIN_IOMODULE_PIT_3_INTERRUPT_INTR,
1 << XIN_IOMODULE_PIT_4_INTERRUPT_INTR
};
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
/*****************************************************************************/
/**
*
* Interrupt handler for the driver used when there can be no argument passed
* to the handler. This function is provided mostly for backward compatibility.
* The user should use XIOModule_DeviceInterruptHandler(), defined in
* xiomodule_l.c, if possible.
*
* The user must connect this function to the interrupt system such that it is
* called whenever the devices which are connected to it cause an interrupt.
*
* @return None.
*
* @note
*
* The constant XPAR_IOMODULE_SINGLE_DEVICE_ID must be defined for this handler
* to be included in the driver compilation.
*
******************************************************************************/
#ifdef XPAR_IOMODULE_SINGLE_DEVICE_ID
void XIOModule_VoidInterruptHandler()
{
/* Use the single instance to call the main interrupt handler */
XIOModule_DeviceInterruptHandler(
(void *) XPAR_IOMODULE_SINGLE_DEVICE_ID);
}
#endif
/*****************************************************************************/
/**
*
* The interrupt handler for the driver. This function is provided mostly for
* backward compatibility. The user should use
* XIOModule_DeviceInterruptHandler(), defined in xiomodule_l.c when
* possible and pass the device ID of the interrupt controller device as its
* argument.
*
* The user must connect this function to the interrupt system such that it is
* called whenever the devices which are connected to it cause an interrupt.
*
* @param InstancePtr is a pointer to the XIOModule instance to be
* worked on.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XIOModule_InterruptHandler(XIOModule * InstancePtr)
{
/* Assert that the pointer to the instance is valid
*/
Xil_AssertVoid(InstancePtr != NULL);
/* Use the instance's device ID to call the main interrupt handler.
* (the casts are to avoid a compiler warning)
*/
XIOModule_DeviceInterruptHandler((void *)
((u32) (InstancePtr->CfgPtr->DeviceId)));
}
/*****************************************************************************/
/**
*
* Sets the timer callback function, which the driver calls when the specified
* timer times out.
*
* @param InstancePtr is a pointer to the XIOModule instance.
* @param CallBackRef is the upper layer callback reference passed back
* when the callback function is invoked.
* @param FuncPtr is the pointer to the callback function.
*
* @return None.
*
* @note
*
* The handler is called within interrupt context so the function that is
* called should either be short or pass the more extensive processing off
* to another task to allow the interrupt to return and normal processing
* to continue.
*
* This function is provided for compatibility, and only allows setting a
* single handler for all Programmable Interval Timers.
*
******************************************************************************/
void XIOModule_SetHandler(XIOModule * InstancePtr,
XIOModule_Timer_Handler FuncPtr,
void *CallBackRef)
{
u8 Index;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(FuncPtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
InstancePtr->Handler = FuncPtr;
InstancePtr->CallBackRef = CallBackRef;
for (Index = XIN_IOMODULE_PIT_1_INTERRUPT_INTR;
Index <= XIN_IOMODULE_PIT_4_INTERRUPT_INTR; Index++) {
InstancePtr->CfgPtr->HandlerTable[Index].Handler =
XIOModule_Timer_InterruptHandler;
}
}
/*****************************************************************************/
/**
*
* Interrupt Service Routine (ISR) for the driver. This function only performs
* processing for the Programmable Interval Timere and does not save and restore
* the interrupt context.
*
* @param InstancePtr contains a pointer to the IO Module instance for
* the interrupt.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XIOModule_Timer_InterruptHandler(void *InstancePtr)
{
XIOModule *IOModulePtr = NULL;
u8 Index;
u32 IntPendingReg, ModeMask;
/*
* Verify that each of the inputs are valid.
*/
Xil_AssertVoid(InstancePtr != NULL);
/*
* Convert the non-typed pointer to an IO Module instance pointer
* such that there is access to the IO Module
*/
IOModulePtr = (XIOModule *) InstancePtr;
/*
* Read the pending interrupts to be able to check if interrupt occurred
*/
IntPendingReg = XIOModule_ReadReg(IOModulePtr->BaseAddress,
XIN_IPR_OFFSET);
ModeMask = ~IOModulePtr->CurrentIMR;
/*
* Loop thru each timer in the device and call the callback function
* for each timer which has caused an interrupt, but only if not fast
*/
for (Index = 0; Index < XTC_DEVICE_TIMER_COUNT; Index++) {
/*
* Check if timer is enabled
*/
if (IOModulePtr->CfgPtr->PitUsed[Index]) {
/*
* Check if timer expired and interrupt occured,
* but only if it is not a fast interrupt
*/
if (IntPendingReg & ModeMask & XIOModule_TimerBitPosMask[Index]) {
/*
* Increment statistics for the number of interrupts and call
* the callback to handle any application specific processing
*/
IOModulePtr->Timer_Stats[Index].Interrupts++;
IOModulePtr->Handler(IOModulePtr->CallBackRef, Index);
/*
* Acknowledge the interrupt in the interrupt controller
* acknowledge register to mark it as handled
*/
XIOModule_WriteReg(IOModulePtr->BaseAddress,
XIN_IAR_OFFSET,
XIOModule_TimerBitPosMask[Index]);
}
}
}
}

View file

@ -0,0 +1,85 @@
/******************************************************************************
*
* (c) Copyright 2011-2014 Xilinx, Inc. All rights reserved.
*
* This file contains confidential and proprietary information of Xilinx, Inc.
* and is protected under U.S. and international copyright and other
* intellectual property laws.
*
* DISCLAIMER
* This disclaimer is not a license and does not grant any rights to the
* materials distributed herewith. Except as otherwise provided in a valid
* license issued to you by Xilinx, and to the maximum extent permitted by
* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
* and (2) Xilinx shall not be liable (whether in contract or tort, including
* negligence, or under any other theory of liability) for any loss or damage
* of any kind or nature related to, arising under or in connection with these
* materials, including for any direct, or any indirect, special, incidental,
* or consequential loss or damage (including loss of data, profits, goodwill,
* or any type of loss or damage suffered as a result of any action brought by
* a third party) even if such damage or loss was reasonably foreseeable or
* Xilinx had been advised of the possibility of the same.
*
* CRITICAL APPLICATIONS
* Xilinx products are not designed or intended to be fail-safe, or for use in
* any application requiring fail-safe performance, such as life-support or
* safety devices or systems, Class III medical devices, nuclear facilities,
* applications related to the deployment of airbags, or any other applications
* that could lead to death, personal injury, or severe property or
* environmental damage (individually and collectively, "Critical
* Applications"). Customer assumes the sole risk and liability of any use of
* Xilinx products in Critical Applications, subject only to applicable laws
* and regulations governing limitations on product liability.
*
* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
* AT ALL TIMES.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xiomodule_io.h
*
* This header file contains identifiers and low-level driver functions (or
* macros) that can be used to access the device. The user should refer to the
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------------
* 1.00a sa 07/15/11 First release
* </pre>
*
******************************************************************************/
#ifndef XIOMODULE_IO_H /* prevent circular inclusions */
#define XIOMODULE_IO_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xil_io.h"
/***************** Macros (Inline Functions) Definitions *********************/
#define XIomodule_In32 Xil_In32
#define XIomodule_Out32 Xil_Out32
#define XIomodule_In16 Xil_In16
#define XIomodule_Out16 Xil_Out16
#define XIomodule_In8 Xil_In8
#define XIomodule_Out8 Xil_Out8
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */

View file

@ -0,0 +1,379 @@
/******************************************************************************
*
* (c) Copyright 2011-2014 Xilinx, Inc. All rights reserved.
*
* This file contains confidential and proprietary information of Xilinx, Inc.
* and is protected under U.S. and international copyright and other
* intellectual property laws.
*
* DISCLAIMER
* This disclaimer is not a license and does not grant any rights to the
* materials distributed herewith. Except as otherwise provided in a valid
* license issued to you by Xilinx, and to the maximum extent permitted by
* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
* and (2) Xilinx shall not be liable (whether in contract or tort, including
* negligence, or under any other theory of liability) for any loss or damage
* of any kind or nature related to, arising under or in connection with these
* materials, including for any direct, or any indirect, special, incidental,
* or consequential loss or damage (including loss of data, profits, goodwill,
* or any type of loss or damage suffered as a result of any action brought by
* a third party) even if such damage or loss was reasonably foreseeable or
* Xilinx had been advised of the possibility of the same.
*
* CRITICAL APPLICATIONS
* Xilinx products are not designed or intended to be fail-safe, or for use in
* any application requiring fail-safe performance, such as life-support or
* safety devices or systems, Class III medical devices, nuclear facilities,
* applications related to the deployment of airbags, or any other applications
* that could lead to death, personal injury, or severe property or
* environmental damage (individually and collectively, "Critical
* Applications"). Customer assumes the sole risk and liability of any use of
* Xilinx products in Critical Applications, subject only to applicable laws
* and regulations governing limitations on product liability.
*
* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
* AT ALL TIMES.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xiomodule_l.c
*
* This file contains low-level driver functions that can be used to access the
* device. The user should refer to the hardware device specification for more
* details of the device operation.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a sa 07/15/11 First release
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xparameters.h"
#include "xiomodule.h"
#include "xiomodule_i.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
static XIOModule_Config *LookupConfigByBaseAddress(u32 BaseAddress);
/************************** Variable Definitions *****************************/
/*****************************************************************************/
/**
*
* This is the interrupt handler for the driver interface provided in this file
* when there can be no argument passed to the handler. In this case, we just
* use the globally defined device ID for the interrupt controller. This function
* is provided mostly for backward compatibility. The user should use
* XIOModule_DeviceInterruptHandler() if possible.
*
* This function does not support multiple interrupt controller instances to be
* handled.
*
* The user must connect this function to the interrupt system such that it is
* called whenever the devices which are connected to it cause an interrupt.
*
* @return None.
*
* @note
*
* The constant XPAR_IOMODULE_SINGLE_DEVICE_ID must be defined for this handler
* to be included in the driver compilation.
*
******************************************************************************/
#ifdef XPAR_IOMODULE_SINGLE_DEVICE_ID
void XIOModule_LowLevelInterruptHandler(void)
{
/*
* A level of indirection here because the interrupt handler used with
* the driver interface given in this file needs to remain void - no
* arguments. So we need the globally defined device ID of THE
* interrupt controller.
*/
XIOModule_DeviceInterruptHandler((void *) XPAR_IOMODULE_SINGLE_DEVICE_ID);
}
#endif
/*****************************************************************************/
/**
*
* This function is the primary interrupt handler for the driver. It must be
* connected to the interrupt source such that is called when an interrupt of
* the interrupt controller is active. It will resolve which interrupts are
* active and enabled and call the appropriate interrupt handler. It uses
* the AckBeforeService flag in the configuration data to determine when to
* acknowledge the interrupt. Highest priority interrupts are serviced first.
* The driver can be configured to service only the highest priority interrupt
* or all pending interrupts using the {XIOModule_SetOptions()} function or
* the {XIOModule_SetIntrSrvOption()} function.
*
* This function assumes that an interrupt vector table has been previously
* initialized. It does not verify that entries in the table are valid before
* calling an interrupt handler, except skipping null handlers that indicate
* use of fast interrupts where the hardware directly jumps to the handler.
*
* @param DeviceId is the zero-based device ID defined in xparameters.h
* of the interrupting interrupt controller. It is used as a direct
* index into the configuration data, which contains the vector
* table for the interrupt controller. Note that even though the
* argument is a void pointer, the value is not a pointer but the
* actual device ID. The void pointer type is necessary to meet
* the XInterruptHandler typedef for interrupt handlers.
*
* @return None.
*
* @note
*
* The constant XPAR_IOMODULE_MAX_INTR_SIZE must be setup for this to compile.
* Interrupt IDs range from 0 - 31 and correspond to the interrupt input signals
* for the interrupt controller. XPAR_IOMODULE_MAX_INTR_SIZE specifies the
* highest numbered interrupt input signal that is used.
*
******************************************************************************/
void XIOModule_DeviceInterruptHandler(void *DeviceId)
{
u32 IntrStatus;
u32 IntrMask = 1;
int IntrNumber;
volatile u32 Register; /* used as bit bucket */
XIOModule_Config *CfgPtr;
XIOModule_VectorTableEntry *TablePtr;
/* Get the configuration data using the device ID */
CfgPtr = &XIOModule_ConfigTable[(u32) DeviceId];
/* Get the interrupts that are waiting to be serviced
*/
IntrStatus = XIOModule_GetIntrStatus(CfgPtr->BaseAddress);
/* Service each interrupt that is active and enabled by checking each
* bit in the register from LSB to MSB which corresponds to an interrupt
* input signal. Skip fast interrupts, indicated by null handler.
*/
for (IntrNumber = 0; IntrNumber < XPAR_IOMODULE_INTC_MAX_INTR_SIZE;
IntrNumber++) {
TablePtr = &(CfgPtr->HandlerTable[IntrNumber]);
if ((IntrStatus & 1) && (TablePtr->Handler != NULL)) {
/* If the interrupt has been setup to acknowledge it
* before servicing the interrupt, then ack it
*/
if (CfgPtr->AckBeforeService & IntrMask) {
XIOModule_AckIntr(CfgPtr->BaseAddress, IntrMask);
}
/* The interrupt is active and enabled, call the
* interrupt handler that was setup with the specified
* parameter
*/
TablePtr->Handler(TablePtr->CallBackRef);
/* If the interrupt has been setup to acknowledge it
* after it has been serviced then ack it
*/
if ((CfgPtr->AckBeforeService & IntrMask) == 0) {
XIOModule_AckIntr(CfgPtr->BaseAddress, IntrMask);
}
/*
* Read the ISR again to handle architectures with
* posted write bus access issues.
*/
Register = XIOModule_GetIntrStatus(CfgPtr->BaseAddress);
/*
* If only the highest priority interrupt is to be
* serviced, exit loop and return after servicing
* the interrupt
*/
if (CfgPtr->Options == XIN_SVC_SGL_ISR_OPTION) {
return;
}
}
/* Move to the next interrupt to check */
IntrMask <<= 1;
IntrStatus >>= 1;
/* If there are no other bits set indicating that all interrupts
* have been serviced, then exit the loop
*/
if (IntrStatus == 0) {
break;
}
}
}
/*****************************************************************************/
/**
*
* Set the interrupt service option, which can configure the driver so that it
* services only a single interrupt at a time when an interrupt occurs, or
* services all pending interrupts when an interrupt occurs. The default
* behavior when using the driver interface given in xintc.h file is to service
* only a single interrupt, whereas the default behavior when using the driver
* interface given in this file is to service all outstanding interrupts when an
* interrupt occurs.
*
* @param BaseAddress is the unique identifier for a device.
* @param Option is XIN_SVC_SGL_ISR_OPTION if you want only a single
* interrupt serviced when an interrupt occurs, or
* XIN_SVC_ALL_ISRS_OPTION if you want all pending interrupts
* serviced when an interrupt occurs.
*
* @return None.
*
* @note
*
* Note that this function has no effect if the input base address is invalid.
*
******************************************************************************/
void XIOModule_SetIntrSvcOption(u32 BaseAddress, int Option)
{
XIOModule_Config *CfgPtr;
CfgPtr = LookupConfigByBaseAddress(BaseAddress);
if (CfgPtr != NULL) {
CfgPtr->Options = Option;
}
}
/*****************************************************************************/
/**
*
* Register a handler function for a specific interrupt ID. The vector table
* of the interrupt controller is updated, overwriting any previous handler.
* The handler function will be called when an interrupt occurs for the given
* interrupt ID.
*
* This function can also be used to remove a handler from the vector table
* by passing in the XIOModule_DefaultHandler() as the handler and NULL as the
* callback reference.
*
* @param BaseAddress is the base address of the interrupt controller
* whose vector table will be modified.
* @param InterruptId is the interrupt ID to be associated with the input
* handler.
* @param Handler is the function pointer that will be added to
* the vector table for the given interrupt ID. It adheres to the
* XInterruptHandler signature found in xbasic_types.h.
* @param CallBackRef is the argument that will be passed to the new
* handler function when it is called. This is user-specific.
*
* @return None.
*
* @note Only used with normal interrupt mode.
* Does not restore normal interrupt mode.
*
* Note that this function has no effect if the input base address is invalid.
*
******************************************************************************/
void XIOModule_RegisterHandler(u32 BaseAddress, int InterruptId,
XInterruptHandler Handler, void *CallBackRef)
{
XIOModule_Config *CfgPtr;
CfgPtr = LookupConfigByBaseAddress(BaseAddress);
if (CfgPtr != NULL) {
CfgPtr->HandlerTable[InterruptId].Handler = Handler;
CfgPtr->HandlerTable[InterruptId].CallBackRef = CallBackRef;
}
}
/*****************************************************************************/
/**
*
* Looks up the device configuration based on the base address of the device.
* A table contains the configuration info for each device in the system.
*
* @param BaseAddress is the unique identifier for a device.
*
* @return
*
* A pointer to the configuration structure for the specified device, or
* NULL if the device was not found.
*
* @note None.
*
******************************************************************************/
static XIOModule_Config *LookupConfigByBaseAddress(u32 BaseAddress)
{
XIOModule_Config *CfgPtr = NULL;
int i;
for (i = 0; i < XPAR_XIOMODULE_NUM_INSTANCES; i++) {
if (XIOModule_ConfigTable[i].BaseAddress == BaseAddress) {
CfgPtr = &XIOModule_ConfigTable[i];
break;
}
}
return CfgPtr;
}
/****************************************************************************/
/**
*
* This functions sends a single byte using the UART. It is blocking in that it
* waits for the transmitter to become non-full before it writes the byte to
* the transmit register.
*
* @param BaseAddress is the base address of the device
* @param Data is the byte of data to send
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XIOModule_SendByte(u32 BaseAddress, u8 Data)
{
while (XIOModule_IsTransmitFull(BaseAddress));
XIomodule_Out32(BaseAddress + XUL_TX_OFFSET, Data);
}
/****************************************************************************/
/**
*
* This functions receives a single byte using the UART. It is blocking in that
* it waits for the receiver to become non-empty before it reads from the
* receive register.
*
* @param BaseAddress is the base address of the device
*
* @return The byte of data received.
*
* @note None.
*
******************************************************************************/
u8 XIOModule_RecvByte(u32 BaseAddress)
{
while (XIOModule_IsReceiveEmpty(BaseAddress));
return (u8)XIomodule_In32(BaseAddress + XUL_RX_OFFSET);
}

View file

@ -0,0 +1,444 @@
/******************************************************************************
*
* (c) Copyright 2011-2014 Xilinx, Inc. All rights reserved.
*
* This file contains confidential and proprietary information of Xilinx, Inc.
* and is protected under U.S. and international copyright and other
* intellectual property laws.
*
* DISCLAIMER
* This disclaimer is not a license and does not grant any rights to the
* materials distributed herewith. Except as otherwise provided in a valid
* license issued to you by Xilinx, and to the maximum extent permitted by
* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
* and (2) Xilinx shall not be liable (whether in contract or tort, including
* negligence, or under any other theory of liability) for any loss or damage
* of any kind or nature related to, arising under or in connection with these
* materials, including for any direct, or any indirect, special, incidental,
* or consequential loss or damage (including loss of data, profits, goodwill,
* or any type of loss or damage suffered as a result of any action brought by
* a third party) even if such damage or loss was reasonably foreseeable or
* Xilinx had been advised of the possibility of the same.
*
* CRITICAL APPLICATIONS
* Xilinx products are not designed or intended to be fail-safe, or for use in
* any application requiring fail-safe performance, such as life-support or
* safety devices or systems, Class III medical devices, nuclear facilities,
* applications related to the deployment of airbags, or any other applications
* that could lead to death, personal injury, or severe property or
* environmental damage (individually and collectively, "Critical
* Applications"). Customer assumes the sole risk and liability of any use of
* Xilinx products in Critical Applications, subject only to applicable laws
* and regulations governing limitations on product liability.
*
* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
* AT ALL TIMES.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xiomodule_l.h
*
* This header file contains identifiers and low-level driver functions (or
* macros) that can be used to access the device. The user should refer to the
* hardware device specification for more details of the device operation.
*
*
* Note that users of the driver interface given in this file can register
* an interrupt handler dynamically (at run-time) using the
* XIntc_RegisterHandler() function.
* User of the driver interface given in xiomodule.h should still use
* XIntc_Connect(), as always.
* Also see the discussion of the interrupt vector tables in xiomodule.h.
*
* There are currently two interrupt handlers specified in this interface.
*
* - XIOModule_LowLevelInterruptHandler() is a handler without any arguments
* that is used in cases where there is a single interrupt controller device
* in the system and the handler cannot be passed an argument. This function
* is provided mostly for backward compatibility.
*
* - XIOModule_DeviceInterruptHandler() is a handler that takes a device ID
* as an argument, indicating which interrupt controller device in the system
* is causing the interrupt - thereby supporting multiple interrupt
* controllers.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------------
* 1.00a sa 07/15/11 First release
* 1.01a sa 04/10/12 Updated with fast interrupt
* 1.02a sa 07/25/12 Updated with GPI interrupt support
* </pre>
*
******************************************************************************/
#ifndef XIOMODULE_L_H /* prevent circular inclusions */
#define XIOMODULE_L_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xparameters.h"
#include "xiomodule_io.h"
#include "xio.h"
/************************** Constant Definitions *****************************/
/**
* Defines the number of timer counters within a single hardware device. This
* number is not currently parameterized in the hardware but may be in the
* future.
*/
#define XTC_DEVICE_TIMER_COUNT 4
/**
* Each timer counter consumes 16 bytes of address space.
*/
#define XTC_TIMER_COUNTER_OFFSET 16
#define XTC_TIMER_COUNTER_SHIFT 4
/**
* Define the offsets from the base address for all the registers of the
* IO module, some registers may be optional in the hardware device.
*/
#define XUL_RX_OFFSET 0x00000000 /**< UART Receive Register - R */
#define XUL_TX_OFFSET 0x00000004 /**< UART Transmit Register - W */
#define XUL_STATUS_REG_OFFSET 0x00000008 /**< UART Status Register - R */
#define XUL_BAUDRATE_OFFSET 0x0000004C /**< UART Baud Rate Register - W */
#define XIN_IMR_OFFSET 0x0000000C /**< Intr Mode Register - W */
#define XGO_OUT_OFFSET 0x00000010 /**< General Purpose Output - W */
#define XGI_IN_OFFSET 0x00000020 /**< General Purpose Input - R */
#define XIN_ISR_OFFSET 0x00000030 /**< Intr Status Register - R */
#define XIN_IPR_OFFSET 0x00000034 /**< Intr Pending Register - R */
#define XIN_IER_OFFSET 0x00000038 /**< Intr Enable Register - W */
#define XIN_IAR_OFFSET 0x0000003C /**< Intr Acknowledge Register - W */
#define XTC_TLR_OFFSET 0x00000040 /**< Timer Load register - W */
#define XTC_TCR_OFFSET 0x00000044 /**< Timer counter register - R */
#define XTC_TCSR_OFFSET 0x00000048 /**< Timer Control register - W */
#define XIN_IVAR_OFFSET 0x00000080 /**< Intr Vector Address Register,
Interrupt 0 offset, present
only for Fast Interrupt - W */
/**
* UART status register bit position masks
*/
#define XUL_SR_PARITY_ERROR 0x80
#define XUL_SR_FRAMING_ERROR 0x40
#define XUL_SR_OVERRUN_ERROR 0x20
#define XUL_SR_INTR_ENABLED 0x10 /**< UART Interrupt enabled */
#define XUL_SR_TX_FIFO_FULL 0x08 /**< UART Transmit FIFO full */
#define XUL_SR_RX_FIFO_VALID_DATA 0x01 /**< UART Data Register valid */
/**
* UART stop bits are fixed at 1. Baud, parity, and data bits are fixed on a
* per instance basis.
*/
#define XUL_STOP_BITS 1
/**
* UART Parity definitions.
*/
#define XUL_PARITY_NONE 0
#define XUL_PARITY_ODD 1
#define XUL_PARITY_EVEN 2
/**
* Defines the number of GPI and GPO within a single hardware device. This
* number is not currently parameterized in the hardware but may be in the
* future.
* @{
*/
#define XGPI_DEVICE_COUNT 4
#define XGPO_DEVICE_COUNT 4
/**
* The following constants describe the offset of each GPI and GPO channel's
* data from the base address.
*/
#define XGPI_CHAN_OFFSET 0x00004
#define XGPI_DATA_OFFSET 0x00020
#define XGPO_CHAN_OFFSET 0x00004
#define XGPO_DATA_OFFSET 0x00010
/**
* Interrupt register bit position masks.
*/
#define XIN_IOMODULE_GPI_4_INTERRUPT_INTR 14
#define XIN_IOMODULE_GPI_3_INTERRUPT_INTR 13
#define XIN_IOMODULE_GPI_2_INTERRUPT_INTR 12
#define XIN_IOMODULE_GPI_1_INTERRUPT_INTR 11
#define XIN_IOMODULE_FIT_4_INTERRUPT_INTR 10
#define XIN_IOMODULE_FIT_3_INTERRUPT_INTR 9
#define XIN_IOMODULE_FIT_2_INTERRUPT_INTR 8
#define XIN_IOMODULE_FIT_1_INTERRUPT_INTR 7
#define XIN_IOMODULE_PIT_4_INTERRUPT_INTR 6
#define XIN_IOMODULE_PIT_3_INTERRUPT_INTR 5
#define XIN_IOMODULE_PIT_2_INTERRUPT_INTR 4
#define XIN_IOMODULE_PIT_1_INTERRUPT_INTR 3
#define XIN_IOMODULE_UART_RX_INTERRUPT_INTR 2
#define XIN_IOMODULE_UART_TX_INTERRUPT_INTR 1
#define XIN_IOMODULE_UART_ERROR_INTERRUPT_INTR 0
#define XIN_IOMODULE_EXTERNAL_INTERRUPT_INTR 16
/* @} */
/**
* @name Control Status Register Bit Definitions
* Control Status Register bit masks
* Used to configure the timer counter device.
* @{
*/
#define XTC_CSR_ENABLE_TMR_MASK 0x00000001 /**< Enables the timer */
#define XTC_CSR_AUTO_RELOAD_MASK 0x00000002 /**< In compare mode,
configures the timer
reload from the Load
Register. The default
mode causes the timer
counter to hold when it
rolls under. */
/* @} */
/**************************** Type Definitions *******************************/
/* The following data type defines each entry in an interrupt vector table.
* The callback reference is the base address of the interrupting device
* for the driver interface given in this file and an instance pointer for the
* driver interface given in xintc.h file.
*/
typedef struct {
XInterruptHandler Handler;
void *CallBackRef;
} XIOModule_VectorTableEntry;
typedef void (*XFastInterruptHandler) (void);
/***************** Macros (Inline Functions) Definitions *********************/
/****************************************************************************/
/**
*
* Enable specific interrupt(s) in the interrupt controller.
*
* @param BaseAddress is the base address of the device
* @param EnableMask is the 32-bit value to write to the enable register.
* Each bit of the mask corresponds to an interrupt input signal
* that is connected to the interrupt controller (INT0 = LSB).
* Only the bits which are set in the mask will enable interrupts.
*
* @return None.
*
* @note C-style signature:
* void XIOModule_EnableIntr(u32 BaseAddress, u32 EnableMask);
*
*****************************************************************************/
#define XIOModule_EnableIntr(BaseAddress, EnableMask) \
XIomodule_Out32((BaseAddress) + XIN_IER_OFFSET, (EnableMask))
/****************************************************************************/
/**
*
* Disable specific interrupt(s) in the interrupt controller.
*
* @param BaseAddress is the base address of the device
* @param DisableMask is the 32-bit value to write to enable register.
* Each bit of the mask corresponds to an interrupt input signal
* that is connected to the interrupt controller (INT0 = LSB).
* Only bits which are set in the mask will disable interrupts.
*
* @return None.
*
* @note C-style signature:
* void XIOModule_DisableIntr(u32 BaseAddress, u32 DisableMask);
*
*****************************************************************************/
#define XIOModule_DisableIntr(BaseAddress, DisableMask) \
XIomodule_Out32((BaseAddress) + XIN_IER_OFFSET, ~(DisableMask))
/****************************************************************************/
/**
*
* Acknowledge specific interrupt(s) in the interrupt controller.
*
* @param BaseAddress is the base address of the device
* @param AckMask is the 32-bit value to write to the acknowledge
* register. Each bit of the mask corresponds to an interrupt
* input signal that is connected to the interrupt controller
* (INT0 = LSB). Only the bits which are set in the mask will
* acknowledge interrupts.
*
* @return None.
*
* @note C-style signature:
* void XIOModule_AckIntr(u32 BaseAddress, u32 AckMask);
*
*****************************************************************************/
#define XIOModule_AckIntr(BaseAddress, AckMask) \
XIomodule_Out32((BaseAddress) + XIN_IAR_OFFSET, (AckMask))
/****************************************************************************/
/**
*
* Get the interrupt status from the interrupt controller which indicates
* which interrupts are active and enabled.
*
* @param BaseAddress is the base address of the device
*
* @return The 32-bit contents of the interrupt status register. Each bit
* corresponds to an interrupt input signal that is connected to
* the interrupt controller (INT0 = LSB). Bits which are set
* indicate an active interrupt which is also enabled.
*
* @note C-style signature:
* u32 XIOModule_GetIntrStatus(u32 BaseAddress);
*
*****************************************************************************/
#define XIOModule_GetIntrStatus(BaseAddress) \
(XIomodule_In32((BaseAddress) + XIN_IPR_OFFSET))
/****************************************************************************/
/**
*
* Get the contents of the UART status register. Use the XUL_SR_* constants
* defined above to interpret the bit-mask returned.
*
* @param BaseAddress is the base address of the device
*
* @return A 32-bit value representing the contents of the status
* register.
*
* @note C-style Signature:
* u32 XIOModule_GetStatusReg(u32 BaseAddress);
*
*****************************************************************************/
#define XIOModule_GetStatusReg(BaseAddress) \
XIomodule_In32((BaseAddress) + XUL_STATUS_REG_OFFSET)
/****************************************************************************/
/**
*
* Check to see if the UART receiver has data.
*
* @param BaseAddress is the base address of the device
*
* @return TRUE if the receiver is empty, FALSE if there is data present.
*
* @note C-style Signature:
* int XIOModule_IsReceiveEmpty(u32 BaseAddress);
*
*****************************************************************************/
#define XIOModule_IsReceiveEmpty(BaseAddress) \
((XIOModule_GetStatusReg((BaseAddress)) & XUL_SR_RX_FIFO_VALID_DATA) != \
XUL_SR_RX_FIFO_VALID_DATA)
/****************************************************************************/
/**
*
* Check to see if the transmitter is full.
*
* @param BaseAddress is the base address of the device
*
* @return TRUE if the transmitter is full, FALSE otherwise.
*
* @note C-style Signature:
* int XIOModule_IsTransmitFull(u32 BaseAddress);
*
*****************************************************************************/
#define XIOModule_IsTransmitFull(BaseAddress) \
((XIOModule_GetStatusReg((BaseAddress)) & XUL_SR_TX_FIFO_FULL) == \
XUL_SR_TX_FIFO_FULL)
/****************************************************************************/
/**
*
* Write a value to a GPO register. A 32 bit write is performed. If the
* GPO component is implemented in a smaller width, only the least
* significant data is written.
*
* @param BaseAddress is the base address of the GPO device.
* @param RegOffset is the register offset from the base to write to.
* @param Data is the data written to the register.
*
* @return None.
*
* @note C-style signature:
* void XIOModule_WriteReg(u32 BaseAddress,
* unsigned RegOffset, u32 Data)
*
****************************************************************************/
#define XIOModule_WriteReg(BaseAddress, RegOffset, Data) \
XIomodule_Out32((BaseAddress) + (RegOffset), (u32)(Data))
/****************************************************************************/
/**
*
* Read a value from a GPI register. A 32 bit read is performed. If the
* GPI component is implemented in a smaller width, only the least
* significant data is read from the register. The most significant data
* will be read as 0.
*
* @param BaseAddress is the base address of the GPI device.
* @param RegOffset is the register offset from the base to read from.
*
* @return Data read from the register.
*
* @note C-style signature:
* u32 XIOModule_ReadReg(u32 BaseAddress, unsigned RegOffset)
*
******************************************************************************/
#define XIOModule_ReadReg(BaseAddress, RegOffset) \
XIomodule_In32((BaseAddress) + (RegOffset))
/************************** Function Prototypes ******************************/
/*
* UART standard in and standard out handlers, to be connected to generic
* I/O handling code.
*/
void XIOModule_SendByte(u32 BaseAddress, u8 Data);
u8 XIOModule_RecvByte(u32 BaseAddress);
/*
* Interrupt controller handlers, to be connected to processor exception
* handling code.
*/
void XIOModule_LowLevelInterruptHandler(void);
void XIOModule_DeviceInterruptHandler(void *DeviceId);
/* Various configuration functions */
void XIOModule_SetIntrSvcOption(u32 BaseAddress, int Option);
void XIOModule_RegisterHandler(u32 BaseAddress,
int InterruptId,
XInterruptHandler Handler,
void *CallBackRef);
/************************** Variable Definitions *****************************/
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */

View file

@ -0,0 +1,282 @@
/******************************************************************************
*
* (c) Copyright 2011-2014 Xilinx, Inc. All rights reserved.
*
* This file contains confidential and proprietary information of Xilinx, Inc.
* and is protected under U.S. and international copyright and other
* intellectual property laws.
*
* DISCLAIMER
* This disclaimer is not a license and does not grant any rights to the
* materials distributed herewith. Except as otherwise provided in a valid
* license issued to you by Xilinx, and to the maximum extent permitted by
* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
* and (2) Xilinx shall not be liable (whether in contract or tort, including
* negligence, or under any other theory of liability) for any loss or damage
* of any kind or nature related to, arising under or in connection with these
* materials, including for any direct, or any indirect, special, incidental,
* or consequential loss or damage (including loss of data, profits, goodwill,
* or any type of loss or damage suffered as a result of any action brought by
* a third party) even if such damage or loss was reasonably foreseeable or
* Xilinx had been advised of the possibility of the same.
*
* CRITICAL APPLICATIONS
* Xilinx products are not designed or intended to be fail-safe, or for use in
* any application requiring fail-safe performance, such as life-support or
* safety devices or systems, Class III medical devices, nuclear facilities,
* applications related to the deployment of airbags, or any other applications
* that could lead to death, personal injury, or severe property or
* environmental damage (individually and collectively, "Critical
* Applications"). Customer assumes the sole risk and liability of any use of
* Xilinx products in Critical Applications, subject only to applicable laws
* and regulations governing limitations on product liability.
*
* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
* AT ALL TIMES.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xiomodule_options.c
*
* Contains option functions for the XIOModule driver. These functions allow the
* user to configure an instance of the XIOModule driver. This file requires
* other files of the component to be linked in also.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------------
* 1.00a sa 07/15/11 First release
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xiomodule.h"
#include "xil_assert.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/*
* The following data type maps an option to a register mask such that getting
* and setting the options may be table driven.
*/
typedef struct {
u32 Option;
u32 Mask;
} Mapping;
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
/*
* Create the table which contains options which are to be processed to get/set
* the options. These options are table driven to allow easy maintenance and
* expansion of the options.
*/
static Mapping OptionsTable[] = {
{XTC_INT_MODE_OPTION, 0},
{XTC_AUTO_RELOAD_OPTION, XTC_CSR_AUTO_RELOAD_MASK}
};
/* Create a constant for the number of entries in the table */
#define XTC_NUM_OPTIONS (sizeof(OptionsTable) / sizeof(Mapping))
/*****************************************************************************/
/**
*
* Set the options for the interrupt controller driver.
*
* @param InstancePtr is a pointer to the XIOModule instance to be
* worked on.
* @param Options to be set. The available options are described in
* xiomodule.h.
*
* @return
* - XST_SUCCESS if the options were set successfully
* - XST_INVALID_PARAM if the specified option was not valid
*
* @note None.
*
****************************************************************************/
int XIOModule_SetOptions(XIOModule * InstancePtr, u32 Options)
{
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
/*
* Make sure option request is valid
*/
if ((Options == XIN_SVC_SGL_ISR_OPTION) ||
(Options == XIN_SVC_ALL_ISRS_OPTION)) {
InstancePtr->CfgPtr->Options = Options;
return XST_SUCCESS;
}
else {
return XST_INVALID_PARAM;
}
}
/*****************************************************************************/
/**
*
* Return the currently set options.
*
* @param InstancePtr is a pointer to the XIOModule instance to be
* worked on.
*
* @return The currently set options. The options are described in
* xiomodule.h.
*
* @note None.
*
****************************************************************************/
u32 XIOModule_GetOptions(XIOModule * InstancePtr)
{
/*
* Assert the arguments
*/
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
return InstancePtr->CfgPtr->Options;
}
/*****************************************************************************/
/**
*
* Enables the specified options for the specified timer . This function
* sets the options without regard to the current options of the driver. To
* prevent a loss of the current options, the user should call
* XIOModule_Timer_GetOptions() prior to this function and modify the retrieved
* options to pass into this function to prevent loss of the current options.
*
* @param InstancePtr is a pointer to the XIOModule instance.
* @param TimerNumber is the timer of the device to operate on.
* Each device may contain multiple timers. The timer
* number is a zero based number with a range of
* 0 to (XTC_DEVICE_TIMER_COUNT - 1).
* @param Options contains the desired options to be set or cleared.
* Setting the option to '1' enables the option, clearing the to
* '0' disables the option. The options are bit masks such that
* multiple options may be set or cleared. The options are
* described in xiomodule.h.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XIOModule_Timer_SetOptions(XIOModule * InstancePtr, u8 TimerNumber,
u32 Options)
{
u32 CounterControlReg = 0;
u32 TimerOffset = TimerNumber << XTC_TIMER_COUNTER_SHIFT;
u32 Index;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(TimerNumber <= XTC_DEVICE_TIMER_COUNT);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
/*
* Loop through the Options table, turning the enable on or off
* depending on whether the bit is set in the incoming Options flag.
*/
for (Index = 0; Index < XTC_NUM_OPTIONS; Index++) {
if (Options & OptionsTable[Index].Option) {
/*
* Turn the option on
*/
CounterControlReg |= OptionsTable[Index].Mask;
}
else {
/*
* Turn the option off
*/
CounterControlReg &= ~OptionsTable[Index].Mask;
}
}
/*
* Write out the updated value to the actual register
*/
XIOModule_WriteReg(InstancePtr->BaseAddress,
TimerOffset + XTC_TCSR_OFFSET,
CounterControlReg);
InstancePtr->CurrentTCSR[TimerNumber] = CounterControlReg;
}
/*****************************************************************************/
/**
*
* Get the options for the specified timer.
*
* @param InstancePtr is a pointer to the XIOModule instance.
* @param TimerNumber is the timer of the device to operate on
* Each device may contain multiple timer. The timer
* number is a zero based number with a range of
* 0 to (XTC_DEVICE_TIMER_COUNT - 1).
*
* @return
*
* The currently set options. An option which is set to a '1' is enabled and
* set to a '0' is disabled. The options are bit masks such that multiple
* options may be set or cleared. The options are described in xiomodule.h.
*
* @note None.
*
******************************************************************************/
u32 XIOModel_Timer_GetOptions(XIOModule * InstancePtr, u8 TimerNumber)
{
u32 TimerOffset = TimerNumber << XTC_TIMER_COUNTER_SHIFT;
u32 Options = 0;
u32 CounterControlReg;
u32 Index;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(TimerNumber < XTC_DEVICE_TIMER_COUNT);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
/*
* Get the current contents of the control status register to allow
* the current options to be determined
*/
CounterControlReg = InstancePtr->CurrentTCSR[TimerNumber];
/*
* Loop through the Options table, turning the enable on or off
* depending on whether the bit is set in current register settings.
*/
for (Index = 0; Index < XTC_NUM_OPTIONS; Index++) {
if (CounterControlReg & OptionsTable[Index].Mask) {
Options |= OptionsTable[Index].Option; /* turn on */
}
else {
Options &= ~OptionsTable[Index].Option; /* turn off */
}
}
return Options;
}

View file

@ -0,0 +1,268 @@
/******************************************************************************
*
* (c) Copyright 2011-2014 Xilinx, Inc. All rights reserved.
*
* This file contains confidential and proprietary information of Xilinx, Inc.
* and is protected under U.S. and international copyright and other
* intellectual property laws.
*
* DISCLAIMER
* This disclaimer is not a license and does not grant any rights to the
* materials distributed herewith. Except as otherwise provided in a valid
* license issued to you by Xilinx, and to the maximum extent permitted by
* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
* and (2) Xilinx shall not be liable (whether in contract or tort, including
* negligence, or under any other theory of liability) for any loss or damage
* of any kind or nature related to, arising under or in connection with these
* materials, including for any direct, or any indirect, special, incidental,
* or consequential loss or damage (including loss of data, profits, goodwill,
* or any type of loss or damage suffered as a result of any action brought by
* a third party) even if such damage or loss was reasonably foreseeable or
* Xilinx had been advised of the possibility of the same.
*
* CRITICAL APPLICATIONS
* Xilinx products are not designed or intended to be fail-safe, or for use in
* any application requiring fail-safe performance, such as life-support or
* safety devices or systems, Class III medical devices, nuclear facilities,
* applications related to the deployment of airbags, or any other applications
* that could lead to death, personal injury, or severe property or
* environmental damage (individually and collectively, "Critical
* Applications"). Customer assumes the sole risk and liability of any use of
* Xilinx products in Critical Applications, subject only to applicable laws
* and regulations governing limitations on product liability.
*
* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
* AT ALL TIMES.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xiomodule_selftest.c
*
* Contains diagnostic self-test functions for the XIOModule component. This
* file requires other files of the component to be linked in also.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a sa 07/15/11 First release
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xiomodule.h"
#include "xiomodule_i.h"
#include "xil_assert.h"
#include "xiomodule_io.h"
#include <stdio.h>
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
/*****************************************************************************/
/**
*
* Run a self-test on the interrupt controller driver/device. This is a
* destructive test.
*
* This involves forcing interrupts into the controller (if possible, given
* the IO Module configuration) and verifying that they are recognized and can
* be acknowledged.
*
* @param InstancePtr is a pointer to the XIOModule instance to be
* worked on.
*
* @return
* - XST_SUCCESS if self-test is successful.
* - XST_INTC_FAIL_SELFTEST if the Interrupt controller
* fails the self-test. It will fail the self test if the
* device has previously been started in real mode.
*
* @note None.
*
******************************************************************************/
int XIOModule_Intc_SelfTest(XIOModule * InstancePtr)
{
u32 CurrentISR;
u32 Temp;
/*
* Assert the arguments
*/
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
/*
* Acknowledge all pending interrupts by reading the interrupt status
* register and writing the value to the acknowledge register
*/
Temp = XIomodule_In32(InstancePtr->BaseAddress + XIN_ISR_OFFSET);
XIomodule_Out32(InstancePtr->BaseAddress + XIN_IAR_OFFSET, Temp);
/*
* Verify that there are no interrupts by reading the interrupt status
*/
CurrentISR = XIomodule_In32(InstancePtr->BaseAddress + XIN_ISR_OFFSET);
/*
* ISR for internal interrupts should be zero after all interrupts
* are acknowledged. Skip checking external interrupts, since they may
* occur at any time.
*/
if ((CurrentISR & 0xffff) != 0) {
return XST_INTC_FAIL_SELFTEST;
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* Runs a self-test on the timer driver/device. This test verifies that the
* specified programmable interval timer of the device can be enabled and
* increments.
*
* @param InstancePtr is a pointer to the XIOMOdule instance.
* @param TimerNumber is the timer of the device to operate on.
* Each device may contain multiple timers. The timer
* number is a zero based number with a range of
* 0 to (XTC_DEVICE_TIMER_COUNT - 1).
*
* @return
* - XST_SUCCESS if self-test was successful
* - XST_FAILURE if the timer is not incrementing.
*
* @note
*
* This is a destructive test using the provided timer. The current settings
* of the timer are returned to the initialized values and all settings at the
* time this function is called are overwritten.
*
******************************************************************************/
int XIOModule_Timer_SelfTest(XIOModule * InstancePtr, u8 TimerNumber)
{
u32 TimerCount1 = 0;
u32 TimerCount2 = 0;
u16 Count = 0;
/*
* Assert the arguments
*/
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(TimerNumber < XTC_DEVICE_TIMER_COUNT);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
/*
* Set the Load register most significant bit to 1.
*/
XIOModule_SetResetValue(InstancePtr, TimerNumber,
1 << (InstancePtr->CfgPtr->PitSize[TimerNumber] - 1));
/*
* Reset the timer and the interrupt
*/
XIOModule_Timer_SetOptions(InstancePtr, TimerNumber, 0);
/*
* Set the control/status register to enable timer
*/
XIOModule_Timer_Start(InstancePtr, TimerNumber);
/*
* Read the timer
*/
TimerCount1 = XIOModule_GetValue(InstancePtr, TimerNumber);
/*
* Make sure timer is decrementing if the Count rolls under zero
* and the timer still has not decremented an error is returned
*/
do {
TimerCount2 = XIOModule_GetValue(InstancePtr, TimerNumber);
Count++;
}
while ((TimerCount1 == TimerCount2) && (Count != 0));
/*
* Set the control/status register to 0 to complete initialization
* this disables the timer completely and allows it to be used again
*/
XIOModule_Timer_Stop(InstancePtr, TimerNumber);
if (TimerCount1 == TimerCount2) {
return XST_FAILURE;
}
else {
return XST_SUCCESS;
}
}
int XIOModule_SelfTest(XIOModule * InstancePtr)
{
XStatus Status;
u8 Timer;
XIOModule_Config *CfgPtr;
/*
* Assert the arguments
*/
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
/*
* Perform the interrupt controller self test.
*/
Status = XIOModule_Intc_SelfTest(InstancePtr);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
/*
* Perform the Programmable Interval Timer (PIT) self test.
*
* Skip unused timers,timers with prescaler (since they may
* have very long expiration times), timers without readable
* counters, and timers with small size (since the counter
* may not change when sampled).
*/
CfgPtr = InstancePtr->CfgPtr;
for (Timer = 0; Timer < XTC_DEVICE_TIMER_COUNT; Timer++) {
if (CfgPtr->PitUsed[Timer] &&
CfgPtr->PitPrescaler[Timer] == XTC_PRESCALER_NONE &&
CfgPtr->PitReadable[Timer] &&
CfgPtr->PitSize[Timer] > 8) {
Status = XIOModule_Timer_SelfTest(InstancePtr, Timer);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
}
}
return XST_SUCCESS;
}

View file

@ -0,0 +1,148 @@
/******************************************************************************
*
* (c) Copyright 2011-2014 Xilinx, Inc. All rights reserved.
*
* This file contains confidential and proprietary information of Xilinx, Inc.
* and is protected under U.S. and international copyright and other
* intellectual property laws.
*
* DISCLAIMER
* This disclaimer is not a license and does not grant any rights to the
* materials distributed herewith. Except as otherwise provided in a valid
* license issued to you by Xilinx, and to the maximum extent permitted by
* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
* and (2) Xilinx shall not be liable (whether in contract or tort, including
* negligence, or under any other theory of liability) for any loss or damage
* of any kind or nature related to, arising under or in connection with these
* materials, including for any direct, or any indirect, special, incidental,
* or consequential loss or damage (including loss of data, profits, goodwill,
* or any type of loss or damage suffered as a result of any action brought by
* a third party) even if such damage or loss was reasonably foreseeable or
* Xilinx had been advised of the possibility of the same.
*
* CRITICAL APPLICATIONS
* Xilinx products are not designed or intended to be fail-safe, or for use in
* any application requiring fail-safe performance, such as life-support or
* safety devices or systems, Class III medical devices, nuclear facilities,
* applications related to the deployment of airbags, or any other applications
* that could lead to death, personal injury, or severe property or
* environmental damage (individually and collectively, "Critical
* Applications"). Customer assumes the sole risk and liability of any use of
* Xilinx products in Critical Applications, subject only to applicable laws
* and regulations governing limitations on product liability.
*
* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
* AT ALL TIMES.
*
******************************************************************************/
/****************************************************************************/
/**
*
* @file xiomodule_stats.c
*
* This file contains the statistics functions for the UART module
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a sa 07/15/11 First release
* </pre>
*
*****************************************************************************/
/***************************** Include Files ********************************/
#include "xil_types.h"
#include "xil_assert.h"
#include "xiomodule.h"
#include "xiomodule_i.h"
/************************** Constant Definitions ****************************/
/**************************** Type Definitions ******************************/
/***************** Macros (Inline Functions) Definitions ********************/
/************************** Variable Definitions ****************************/
/************************** Function Prototypes *****************************/
/****************************************************************************/
/**
*
* Returns a snapshot of the current statistics in the structure specified.
*
* @param InstancePtr is a pointer to the XIOModule instance.
* @param StatsPtr is a pointer to a XIOModule_Uart_Stats structure to
* where the statistics are to be copied.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
void XIOModule_GetStats(XIOModule *InstancePtr, XIOModule_Uart_Stats *StatsPtr)
{
/*
* Assert validates the input arguments
*/
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(StatsPtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
/* Copy the stats from the instance to the specified stats */
StatsPtr->TransmitInterrupts =
InstancePtr->Uart_Stats.TransmitInterrupts;
StatsPtr->ReceiveInterrupts =
InstancePtr->Uart_Stats.ReceiveInterrupts;
StatsPtr->CharactersTransmitted =
InstancePtr->Uart_Stats.CharactersTransmitted;
StatsPtr->CharactersReceived =
InstancePtr->Uart_Stats.CharactersReceived;
StatsPtr->ReceiveOverrunErrors =
InstancePtr->Uart_Stats.ReceiveOverrunErrors;
StatsPtr->ReceiveFramingErrors =
InstancePtr->Uart_Stats.ReceiveFramingErrors;
StatsPtr->ReceiveParityErrors =
InstancePtr->Uart_Stats.ReceiveParityErrors;
}
/****************************************************************************/
/**
*
* This function zeros the statistics for the given instance.
*
* @param InstancePtr is a pointer to the XIOModule instance.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
void XIOModule_ClearStats(XIOModule *InstancePtr)
{
/*
* Assert validates the input arguments
*/
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
InstancePtr->Uart_Stats.TransmitInterrupts = 0;
InstancePtr->Uart_Stats.ReceiveInterrupts = 0;
InstancePtr->Uart_Stats.CharactersTransmitted = 0;
InstancePtr->Uart_Stats.CharactersReceived = 0;
InstancePtr->Uart_Stats.ReceiveOverrunErrors = 0;
InstancePtr->Uart_Stats.ReceiveParityErrors = 0;
InstancePtr->Uart_Stats.ReceiveFramingErrors = 0;
}

View file

@ -0,0 +1,265 @@
/******************************************************************************
*
* (c) Copyright 2012-2014 Xilinx, Inc. All rights reserved.
*
* This file contains confidential and proprietary information of Xilinx, Inc.
* and is protected under U.S. and international copyright and other
* intellectual property laws.
*
* DISCLAIMER
* This disclaimer is not a license and does not grant any rights to the
* materials distributed herewith. Except as otherwise provided in a valid
* license issued to you by Xilinx, and to the maximum extent permitted by
* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
* and (2) Xilinx shall not be liable (whether in contract or tort, including
* negligence, or under any other theory of liability) for any loss or damage
* of any kind or nature related to, arising under or in connection with these
* materials, including for any direct, or any indirect, special, incidental,
* or consequential loss or damage (including loss of data, profits, goodwill,
* or any type of loss or damage suffered as a result of any action brought by
* a third party) even if such damage or loss was reasonably foreseeable or
* Xilinx had been advised of the possibility of the same.
*
* CRITICAL APPLICATIONS
* Xilinx products are not designed or intended to be fail-safe, or for use in
* any application requiring fail-safe performance, such as life-support or
* safety devices or systems, Class III medical devices, nuclear facilities,
* applications related to the deployment of airbags, or any other applications
* that could lead to death, personal injury, or severe property or
* environmental damage (individually and collectively, "Critical
* Applications"). Customer assumes the sole risk and liability of any use of
* Xilinx products in Critical Applications, subject only to applicable laws
* and regulations governing limitations on product liability.
*
* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
* AT ALL TIMES.
*
******************************************************************************/
/****************************************************************************/
/**
*
* @file xiomodule_uart.c
*
* Contains required functions for the XIOModule UART driver. See the
* xiomodule.h header file for more details on this driver.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.02a sa 07/25/12 First release
* 1.03a sa 10/16/12 Moved interrupt mode functions to separate file
* </pre>
*
*****************************************************************************/
/***************************** Include Files ********************************/
#include "xil_assert.h"
#include "xiomodule.h"
#include "xiomodule_i.h"
#include "xiomodule_l.h"
/************************** Constant Definitions ****************************/
/* The following constant defines the amount of error that is allowed for
* a specified baud rate. This error is the difference between the actual
* baud rate that will be generated using the specified clock and the
* desired baud rate.
*/
#define XUN_MAX_BAUD_ERROR_RATE 3 /* max % error allowed */
/**************************** Type Definitions ******************************/
/***************** Macros (Inline Functions) Definitions ********************/
/************************** Function Prototypes *****************************/
static void StubHandler(void *CallBackRef, unsigned int ByteCount);
/************************** Variable Definitions ****************************/
/****************************************************************************/
/**
*
* Initialize a XIOModule instance. This function disables the UART
* interrupts. The baud rate and format of the data are fixed in the hardware
* at hardware build time, except if programmable baud rate is selected.
*
* @param InstancePtr is a pointer to the XIOModule instance.
* @param Config is a reference to a structure containing information
* about a specific IO Module device. This function initializes an
* InstancePtr object for a specific device specified by the
* contents of Config. This function can initialize multiple
* instance objects with the use of multiple calls giving different
* Config information on each call.
* @param EffectiveAddr is the device register base address. Use
* Config->BaseAddress for this parameters, passing the physical
* address.
*
* @return
* - XST_SUCCESS if everything starts up as expected.
*
* @note The Config and EffectiveAddress arguments are not used by this
* function, but are provided to keep the function signature
* consistent with other drivers.
*
*****************************************************************************/
int XIOModule_CfgInitialize(XIOModule *InstancePtr, XIOModule_Config *Config,
u32 EffectiveAddr)
{
u32 NewIER;
/*
* Assert validates the input arguments
*/
Xil_AssertNonvoid(InstancePtr != NULL);
/*
* Set some default values, including setting the callback
* handlers to stubs.
*/
InstancePtr->SendBuffer.NextBytePtr = NULL;
InstancePtr->SendBuffer.RemainingBytes = 0;
InstancePtr->SendBuffer.RequestedBytes = 0;
InstancePtr->ReceiveBuffer.NextBytePtr = NULL;
InstancePtr->ReceiveBuffer.RemainingBytes = 0;
InstancePtr->ReceiveBuffer.RequestedBytes = 0;
InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
InstancePtr->RecvHandler = StubHandler;
InstancePtr->SendHandler = StubHandler;
/*
* Modify the IER to disable the UART interrupts
*/
NewIER = InstancePtr->CurrentIER & 0xFFFFFFF8;
XIomodule_Out32(InstancePtr->BaseAddress + XIN_IER_OFFSET, NewIER);
InstancePtr->CurrentIER = NewIER;
/*
* Clear the statistics for this driver
*/
XIOModule_ClearStats(InstancePtr);
return XST_SUCCESS;
}
/****************************************************************************
*
* Sets the baud rate for the specified UART. Checks the input value for
* validity and also verifies that the requested rate can be configured to
* within the 3 percent error range for RS-232 communications. If the provided
* rate is not valid, the current setting is unchanged.
*
* This function is designed to be an internal function only used within the
* XIOModule component. It is necessary for initialization and for the user
* available function that sets the data format.
*
* @param InstancePtr is a pointer to the XIOModule instance.
* @param BaudRate to be set in the hardware.
*
* @return
* - XST_SUCCESS if everything configures as expected
* - XST_UART_BAUD_ERROR if the requested rate is not available
* because there was too much error due to the input clock
*
* @note None.
*
*****************************************************************************/
int XIOModule_SetBaudRate(XIOModule *InstancePtr, u32 BaudRate)
{
u32 Baud8;
u32 Baud16;
u32 InputClockHz;
u32 Divisor;
u32 TargetRate;
u32 Error;
u32 PercentError;
/*
* Assert validates the input arguments
*/
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
/*
* Determine what the divisor should be to get the specified baud
* rate based upon the input clock frequency and a baud clock prescaler
* of 16, rounded to nearest divisor
*/
Baud8 = BaudRate << 3;
Baud16 = Baud8 << 1;
InputClockHz = InstancePtr->CfgPtr->InputClockHz;
Divisor = (InputClockHz + Baud8) / Baud16;
/*
* Check for too much error between the baud rate that will be generated
* using the divisor and the expected baud rate, ensuring that the error
* is positive due to rounding above
*/
TargetRate = Divisor * Baud16;
if (InputClockHz < TargetRate)
Error = TargetRate - InputClockHz;
else
Error = InputClockHz - TargetRate;
/*
* Error has total error now compute the percentage multiplied by 100 to
* avoid floating point calculations, should be less than 3% as per
* RS-232 spec
*/
PercentError = (Error * 100UL) / InputClockHz;
if (PercentError > XUN_MAX_BAUD_ERROR_RATE) {
return XST_UART_BAUD_ERROR;
}
/*
* Write the baud rate divisor to the UART Baud Rate Register
*/
XIOModule_WriteReg(InstancePtr->BaseAddress,
XUL_BAUDRATE_OFFSET,
Divisor - 1);
InstancePtr->CurrentUBRR = Divisor - 1;
/*
* Save the baud rate in the instance so that the get baud rate function
* won't have to calculate it from the divisor
*/
InstancePtr->CfgPtr->BaudRate = BaudRate;
return XST_SUCCESS;
}
/****************************************************************************
*
* This function provides a stub handler such that if the application does not
* define a handler but enables interrupts, this function will be called.
*
* @param CallBackRef has no purpose but is necessary to match the
* interface for a handler.
* @param ByteCount has no purpose but is necessary to match the
* interface for a handler.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
static void StubHandler(void *CallBackRef, unsigned int ByteCount)
{
/*
* Assert occurs always since this is a stub and should never be called
*/
Xil_AssertVoidAlways();
}

View file

@ -0,0 +1,753 @@
/******************************************************************************
*
* (c) Copyright 2012-2014 Xilinx, Inc. All rights reserved.
*
* This file contains confidential and proprietary information of Xilinx, Inc.
* and is protected under U.S. and international copyright and other
* intellectual property laws.
*
* DISCLAIMER
* This disclaimer is not a license and does not grant any rights to the
* materials distributed herewith. Except as otherwise provided in a valid
* license issued to you by Xilinx, and to the maximum extent permitted by
* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
* and (2) Xilinx shall not be liable (whether in contract or tort, including
* negligence, or under any other theory of liability) for any loss or damage
* of any kind or nature related to, arising under or in connection with these
* materials, including for any direct, or any indirect, special, incidental,
* or consequential loss or damage (including loss of data, profits, goodwill,
* or any type of loss or damage suffered as a result of any action brought by
* a third party) even if such damage or loss was reasonably foreseeable or
* Xilinx had been advised of the possibility of the same.
*
* CRITICAL APPLICATIONS
* Xilinx products are not designed or intended to be fail-safe, or for use in
* any application requiring fail-safe performance, such as life-support or
* safety devices or systems, Class III medical devices, nuclear facilities,
* applications related to the deployment of airbags, or any other applications
* that could lead to death, personal injury, or severe property or
* environmental damage (individually and collectively, "Critical
* Applications"). Customer assumes the sole risk and liability of any use of
* Xilinx products in Critical Applications, subject only to applicable laws
* and regulations governing limitations on product liability.
*
* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
* AT ALL TIMES.
*
******************************************************************************/
/****************************************************************************/
/**
*
* @file xiomodule_uart_intr.c
*
* Contains required functions for the XIOModule UART driver interrupt mode.
* See the xiomodule.h header file for more details on this driver.
*
* This file also contains interrupt-related functions for the UART.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.03a sa 10/16/12 First release
* </pre>
*
*****************************************************************************/
/***************************** Include Files ********************************/
#include "xil_assert.h"
#include "xiomodule.h"
#include "xiomodule_i.h"
#include "xiomodule_l.h"
/************************** Constant Definitions ****************************/
/**************************** Type Definitions ******************************/
/***************** Macros (Inline Functions) Definitions ********************/
/************************** Function Prototypes *****************************/
static void ReceiveDataHandler(XIOModule *InstancePtr);
static void SendDataHandler(XIOModule *InstancePtr);
/************************** Variable Definitions ****************************/
typedef void (*Handler)(XIOModule *InstancePtr);
/****************************************************************************/
/**
*
* This functions sends the specified buffer of data using the UART in either
* polled or interrupt driven modes. This function is non-blocking such that it
* will return before the data has been sent by the UART. If the UART is busy
* sending data, it will return and indicate zero bytes were sent.
*
* In a polled mode, this function will only send as much data as the UART can
* buffer in the transmitter. The application may need to call it repeatedly to
* send a buffer.
*
* In interrupt mode, this function will start sending the specified buffer and
* then the interrupt handler of the driver will continue sending data until the
* buffer has been sent. A callback function, as specified by the application,
* will be called to indicate the completion of sending the buffer.
*
* @param InstancePtr is a pointer to the XIOModule instance.
* @param DataBufferPtr is pointer to a buffer of data to be sent.
* @param NumBytes contains the number of bytes to be sent. A value of
* zero will stop a previous send operation that is in progress
* in interrupt mode. Any data that was already put into the
* transmit FIFO will be sent.
*
* @return The number of bytes actually sent.
*
* @note The number of bytes is not asserted so that this function may
* be called with a value of zero to stop an operation that is
* already in progress.
*
******************************************************************************/
unsigned int XIOModule_Send(XIOModule *InstancePtr, u8 *DataBufferPtr,
unsigned int NumBytes)
{
unsigned int BytesSent;
u32 StatusRegister;
/*
* Assert validates the input arguments
*/
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(DataBufferPtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertNonvoid(((signed)NumBytes) >= 0);
/*
* Enter a critical region by disabling the UART interrupts to allow
* this call to stop a previous operation that may be interrupt driven.
*/
StatusRegister = InstancePtr->CurrentIER;
XIomodule_Out32(InstancePtr->BaseAddress + XIN_IER_OFFSET,
StatusRegister & 0xFFFFFFF8);
/*
* Setup the specified buffer to be sent by setting the instance
* variables so it can be sent with polled or interrupt mode
*/
InstancePtr->SendBuffer.RequestedBytes = NumBytes;
InstancePtr->SendBuffer.RemainingBytes = NumBytes;
InstancePtr->SendBuffer.NextBytePtr = DataBufferPtr;
/*
* Restore the interrupt enable register to it's previous value such
* that the critical region is exited.
* This is done here to minimize the amount of time the interrupt is
* disabled since there is only one interrupt and the receive could
* be filling up while interrupts are blocked.
*/
XIomodule_Out32(InstancePtr->BaseAddress + XIN_IER_OFFSET,
(InstancePtr->CurrentIER & 0xFFFFFFF8) | (StatusRegister & 0x7));
/*
* Send the buffer using the UART and return the number of bytes sent
*/
BytesSent = XIOModule_SendBuffer(InstancePtr);
return BytesSent;
}
/****************************************************************************/
/**
*
* This function will attempt to receive a specified number of bytes of data
* from the UART and store it into the specified buffer. This function is
* designed for either polled or interrupt driven modes. It is non-blocking
* such that it will return if no data has already received by the UART.
*
* In a polled mode, this function will only receive as much data as the UART
* can buffer in the receiver. The application may need to call it repeatedly to
* receive a buffer. Polled mode is the default mode of operation for the driver.
*
* In interrupt mode, this function will start receiving and then the interrupt
* handler of the driver will continue receiving data until the buffer has been
* received. A callback function, as specified by the application, will be called
* to indicate the completion of receiving the buffer or when any receive errors
* or timeouts occur.
*
* @param InstancePtr is a pointer to the XIOModule instance.
* @param DataBufferPtr is pointer to buffer for data to be received into.
* @param NumBytes is the number of bytes to be received. A value of zero
* will stop a previous receive operation that is in progress in
* interrupt mode.
*
* @return The number of bytes received.
*
* @note The number of bytes is not asserted so that this function
* may be called with a value of zero to stop an operation
* that is already in progress.
*
*****************************************************************************/
unsigned int XIOModule_Recv(XIOModule *InstancePtr, u8 *DataBufferPtr,
unsigned int NumBytes)
{
unsigned int ReceivedCount;
u32 StatusRegister;
/*
* Assert validates the input arguments
*/
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(DataBufferPtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertNonvoid(((signed)NumBytes) >= 0);
/*
* Enter a critical region by disabling all the UART interrupts to allow
* this call to stop a previous operation that may be interrupt driven
*/
StatusRegister = InstancePtr->CurrentIER;
XIomodule_Out32(InstancePtr->BaseAddress + XIN_IER_OFFSET,
StatusRegister & 0xFFFFFFF8);
/*
* Setup the specified buffer to be received by setting the instance
* variables so it can be received with polled or interrupt mode
*/
InstancePtr->ReceiveBuffer.RequestedBytes = NumBytes;
InstancePtr->ReceiveBuffer.RemainingBytes = NumBytes;
InstancePtr->ReceiveBuffer.NextBytePtr = DataBufferPtr;
/*
* Restore the interrupt enable register to it's previous value such
* that the critical region is exited
*/
XIomodule_Out32(InstancePtr->BaseAddress + XIN_IER_OFFSET,
(InstancePtr->CurrentIER & 0xFFFFFFF8) | (StatusRegister & 0x7));
/*
* Receive the data from the UART and return the number of bytes
* received. This is done here to minimize the amount of time the
* interrupt is disabled.
*/
ReceivedCount = XIOModule_ReceiveBuffer(InstancePtr);
return ReceivedCount;
}
/****************************************************************************/
/**
*
* This function does nothing, since the UART doesn't have any FIFOs. It is
* included for compatibility with the UART Lite driver.
*
* @param InstancePtr is a pointer to the XIOModule instance .
*
* @return None.
*
* @note None.
*
*****************************************************************************/
void XIOModule_ResetFifos(XIOModule *InstancePtr)
{
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
}
/****************************************************************************/
/**
*
* This function determines if the specified UART is sending data. If the
* transmitter register is not empty, it is sending data.
*
* @param InstancePtr is a pointer to the XIOModule instance.
*
* @return A value of TRUE if the UART is sending data, otherwise FALSE.
*
* @note None.
*
*****************************************************************************/
int XIOModule_IsSending(XIOModule *InstancePtr)
{
u32 StatusRegister;
/*
* Assert validates the input arguments
*/
Xil_AssertNonvoid(InstancePtr != NULL);
/*
* Read the status register to determine if the transmitter is empty
*/
StatusRegister = XIOModule_ReadReg(InstancePtr->BaseAddress,
XUL_STATUS_REG_OFFSET);
/*
* If the transmitter is not empty then indicate that the UART is still
* sending some data
*/
return ((StatusRegister & XUL_SR_TX_FIFO_FULL) == XUL_SR_TX_FIFO_FULL);
}
/****************************************************************************/
/**
*
* This function sends a buffer that has been previously specified by setting
* up the instance variables of the instance. This function is designed to be
* an internal function for the XIOModule component such that it may be called
* from a shell function that sets up the buffer or from an interrupt handler.
*
* This function sends the specified buffer of data to the UART in either
* polled or interrupt driven modes. This function is non-blocking such that
* it will return before the data has been sent by the UART.
*
* In a polled mode, this function will only send as much data as the UART can
* buffer in the transmitter. The application may need to call it repeatedly to
* send a buffer.
*
* In interrupt mode, this function will start sending the specified buffer and
* then the interrupt handler of the driver will continue until the buffer
* has been sent. A callback function, as specified by the application, will
* be called to indicate the completion of sending the buffer.
*
* @param InstancePtr is a pointer to the XIOModule instance.
*
* @return NumBytes is the number of bytes actually sent (put into the
* UART transmitter and/or FIFO).
*
* @note None.
*
*****************************************************************************/
unsigned int XIOModule_SendBuffer(XIOModule *InstancePtr)
{
unsigned int SentCount = 0;
u8 StatusRegister;
u8 IntrEnableStatus;
/*
* Read the status register to determine if the transmitter is full
*/
StatusRegister = XIOModule_GetStatusReg(InstancePtr->BaseAddress);
/*
* Enter a critical region by disabling all the UART interrupts to allow
* this call to stop a previous operation that may be interrupt driven
*/
XIomodule_Out32(InstancePtr->BaseAddress + XIN_IER_OFFSET,
StatusRegister & 0xFFFFFFF8);
/*
* Save the status register contents to restore the interrupt enable
* register to it's previous value when that the critical region is
* exited
*/
IntrEnableStatus = StatusRegister;
/*
* Fill the FIFO from the the buffer that was specified
*/
while (((StatusRegister & XUL_SR_TX_FIFO_FULL) == 0) &&
(SentCount < InstancePtr->SendBuffer.RemainingBytes)) {
XIOModule_WriteReg(InstancePtr->BaseAddress,
XUL_TX_OFFSET,
InstancePtr->SendBuffer.NextBytePtr[
SentCount]);
SentCount++;
StatusRegister =
XIOModule_GetStatusReg(InstancePtr->BaseAddress);
}
/*
* Update the buffer to reflect the bytes that were sent from it
*/
InstancePtr->SendBuffer.NextBytePtr += SentCount;
InstancePtr->SendBuffer.RemainingBytes -= SentCount;
/*
* Increment associated counters
*/
InstancePtr->Uart_Stats.CharactersTransmitted += SentCount;
/*
* Restore the interrupt enable register to it's previous value such
* that the critical region is exited
*/
XIomodule_Out32(InstancePtr->BaseAddress + XIN_IER_OFFSET,
(InstancePtr->CurrentIER & 0xFFFFFFF8) | (IntrEnableStatus & 0x7));
/*
* Return the number of bytes that were sent, althought they really were
* only put into the FIFO, not completely sent yet
*/
return SentCount;
}
/****************************************************************************/
/**
*
* This function receives a buffer that has been previously specified by setting
* up the instance variables of the instance. This function is designed to be
* an internal function for the XIOModule component such that it may be called
* from a shell function that sets up the buffer or from an interrupt handler.
*
* This function will attempt to receive a specified number of bytes of data
* from the UART and store it into the specified buffer. This function is
* designed for either polled or interrupt driven modes. It is non-blocking
* such that it will return if there is no data has already received by the
* UART.
*
* In a polled mode, this function will only receive as much data as the UART
* can buffer, either in the receiver or in the FIFO if present and enabled.
* The application may need to call it repeatedly to receive a buffer. Polled
* mode is the default mode of operation for the driver.
*
* In interrupt mode, this function will start receiving and then the interrupt
* handler of the driver will continue until the buffer has been received. A
* callback function, as specified by the application, will be called to indicate
* the completion of receiving the buffer or when any receive errors or timeouts
* occur.
*
* @param InstancePtr is a pointer to the XIOModule instance.
*
* @return The number of bytes received.
*
* @note None.
*
*****************************************************************************/
unsigned int XIOModule_ReceiveBuffer(XIOModule *InstancePtr)
{
u8 StatusRegister;
unsigned int ReceivedCount = 0;
/*
* Loop until there is not more data buffered by the UART or the
* specified number of bytes is received
*/
while (ReceivedCount < InstancePtr->ReceiveBuffer.RemainingBytes) {
/*
* Read the Status Register to determine if there is any data in
* the receiver
*/
StatusRegister =
XIOModule_GetStatusReg(InstancePtr->BaseAddress);
/*
* If there is data ready to be removed, then put the next byte
* received into the specified buffer and update the stats to
* reflect any receive errors for the byte
*/
if (StatusRegister & XUL_SR_RX_FIFO_VALID_DATA) {
InstancePtr->ReceiveBuffer.NextBytePtr[ReceivedCount++]=
XIOModule_ReadReg(InstancePtr->BaseAddress,
XUL_RX_OFFSET);
XIOModule_UpdateStats(InstancePtr, StatusRegister);
}
/*
* There's no more data buffered, so exit such that this
* function does not block waiting for data
*/
else {
break;
}
}
/*
* Enter a critical region by disabling all the UART interrupts to allow
* this call to stop a previous operation that may be interrupt driven
*/
StatusRegister = InstancePtr->CurrentIER;
XIomodule_Out32(InstancePtr->BaseAddress + XIN_IER_OFFSET,
StatusRegister & 0xFFFFFFF8);
/*
* Update the receive buffer to reflect the number of bytes that was
* received
*/
InstancePtr->ReceiveBuffer.NextBytePtr += ReceivedCount;
InstancePtr->ReceiveBuffer.RemainingBytes -= ReceivedCount;
/*
* Increment associated counters in the statistics
*/
InstancePtr->Uart_Stats.CharactersReceived += ReceivedCount;
/*
* Restore the interrupt enable register to it's previous value such
* that the critical region is exited
*/
XIomodule_Out32(InstancePtr->BaseAddress + XIN_IER_OFFSET,
(InstancePtr->CurrentIER & 0xFFFFFFF8) | (StatusRegister & 0x7));
return ReceivedCount;
}
/****************************************************************************/
/**
*
* This function sets the handler that will be called when an event (interrupt)
* occurs in the driver for the UART. The purpose of the handler is to allow
* application specific processing to be performed.
*
* @param InstancePtr is a pointer to the XIOModule instance.
* @param FuncPtr is the pointer to the callback function.
* @param CallBackRef is the upper layer callback reference passed back
* when the callback function is invoked.
*
* @return None.
*
* @note There is no assert on the CallBackRef since the driver doesn't
* know what it is (nor should it)
*
*****************************************************************************/
void XIOModule_SetRecvHandler(XIOModule *InstancePtr,
XIOModule_Handler FuncPtr, void *CallBackRef)
{
/*
* Assert validates the input arguments
* CallBackRef not checked, no way to know what is valid
*/
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(FuncPtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
InstancePtr->RecvHandler = FuncPtr;
InstancePtr->RecvCallBackRef = CallBackRef;
}
/****************************************************************************/
/**
*
* This function sets the handler that will be called when an event (interrupt)
* occurs in the driver for the UART. The purpose of the handler is to allow
* application specific processing to be performed.
*
* @param InstancePtr is a pointer to the XIOModule instance .
* @param FuncPtr is the pointer to the callback function.
* @param CallBackRef is the upper layer callback reference passed back
* when the callback function is invoked.
*
* @return None.
*
* @note There is no assert on the CallBackRef since the driver doesn't
* know what it is (nor should it)
*
*****************************************************************************/
void XIOModule_SetSendHandler(XIOModule *InstancePtr,
XIOModule_Handler FuncPtr, void *CallBackRef)
{
/*
* Assert validates the input arguments
* CallBackRef not checked, no way to know what is valid
*/
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(FuncPtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
InstancePtr->SendHandler = FuncPtr;
InstancePtr->SendCallBackRef = CallBackRef;
}
/****************************************************************************/
/**
*
* This function is the interrupt handler for the UART.
* It must be connected to an interrupt system by the user such that it is
* called when an interrupt for any UART lite occurs. This function
* does not save or restore the processor context such that the user must
* ensure this occurs.
*
* @param InstancePtr contains a pointer to the instance of the IOModule
* that the interrupt is for.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XIOModule_Uart_InterruptHandler(XIOModule *InstancePtr)
{
u32 IsrStatus;
Xil_AssertVoid(InstancePtr != NULL);
/*
* Read the status register to determine which, could be both,
* interrupt is active
*/
IsrStatus = XIOModule_ReadReg(InstancePtr->BaseAddress,
XIN_IPR_OFFSET);
if ((IsrStatus & XUL_SR_RX_FIFO_VALID_DATA) != 0) {
ReceiveDataHandler(InstancePtr);
}
if (((IsrStatus & XUL_SR_TX_FIFO_FULL) == XUL_SR_TX_FIFO_FULL) &&
(InstancePtr->SendBuffer.RequestedBytes > 0)) {
SendDataHandler(InstancePtr);
}
}
/****************************************************************************/
/**
*
* This function handles the interrupt when data is received, either a single
* byte when FIFOs are not enabled, or multiple bytes with the FIFO.
*
* @param InstancePtr is a pointer to the XIOModule instance.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
static void ReceiveDataHandler(XIOModule *InstancePtr)
{
/*
* If there are bytes still to be received in the specified buffer
* go ahead and receive them
*/
if (InstancePtr->ReceiveBuffer.RemainingBytes != 0) {
XIOModule_ReceiveBuffer(InstancePtr);
}
/*
* If the last byte of a message was received then call the application
* handler, this code should not use an else from the previous check of
* the number of bytes to receive because the call to receive the buffer
* updates the bytes to receive
*/
if (InstancePtr->ReceiveBuffer.RemainingBytes == 0) {
InstancePtr->RecvHandler(InstancePtr->RecvCallBackRef,
InstancePtr->ReceiveBuffer.RequestedBytes -
InstancePtr->ReceiveBuffer.RemainingBytes);
}
/*
* Update the receive stats to reflect the receive interrupt
*/
InstancePtr->Uart_Stats.ReceiveInterrupts++;
}
/****************************************************************************/
/**
*
* This function handles the interrupt when data has been sent, the transmit
* FIFO is empty (transmitter holding register).
*
* @param InstancePtr is a pointer to the XIOModule instance .
*
* @return None.
*
* @note None.
*
*****************************************************************************/
static void SendDataHandler(XIOModule *InstancePtr)
{
/*
* If there are not bytes to be sent from the specified buffer,
* call the callback function
*/
if (InstancePtr->SendBuffer.RemainingBytes == 0) {
int SaveReq;
/*
* Save and zero the requested bytes since transmission
* is complete
*/
SaveReq = InstancePtr->SendBuffer.RequestedBytes;
InstancePtr->SendBuffer.RequestedBytes = 0;
/*
* Call the application handler to indicate
* the data has been sent
*/
InstancePtr->SendHandler(InstancePtr->SendCallBackRef, SaveReq);
}
/*
* Otherwise there is still more data to send in the specified buffer
* so go ahead and send it
*/
else {
XIOModule_SendBuffer(InstancePtr);
}
/*
* Update the transmit stats to reflect the transmit interrupt
*/
InstancePtr->Uart_Stats.TransmitInterrupts++;
}
/*****************************************************************************/
/**
*
* This function disables the UART interrupt. After calling this function,
* data may still be received by the UART but no interrupt will be generated
* since the hardware device has no way to disable the receiver.
*
* @param InstancePtr is a pointer to the XIOModule instance.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
void XIOModule_Uart_DisableInterrupt(XIOModule *InstancePtr)
{
u32 NewIER;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
/*
* Write to the interupt enable register to disable the UART
* interrupts.
*/
NewIER = InstancePtr->CurrentIER & 0xFFFFFFF8;
XIomodule_Out32(InstancePtr->BaseAddress + XIN_IER_OFFSET, NewIER);
InstancePtr->CurrentIER = NewIER;
}
/*****************************************************************************/
/**
*
* This function enables the UART interrupts such that an interrupt will occur
* when data is received or data has been transmitted.
*
* @param InstancePtr is a pointer to the XIOModule instance.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
void XIOModule_Uart_EnableInterrupt(XIOModule *InstancePtr)
{
u32 NewIER;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
/*
* Write to the interrupt enable register to enable the interrupts.
*/
NewIER = InstancePtr->CurrentIER | 0x7;
XIomodule_Out32(InstancePtr->BaseAddress + XIN_IER_OFFSET, NewIER);
InstancePtr->CurrentIER = NewIER;
}