From f554ecf495877edeb4de8a3d4ec56d7c39e61157 Mon Sep 17 00:00:00 2001 From: Subbaraya Sundeep Bhatta Date: Fri, 2 May 2014 15:29:10 +0530 Subject: [PATCH] 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 Acked-by: Anirudha Sarangi --- .../drivers/iomodule/data/iomodule.mdd | 80 + .../drivers/iomodule/data/iomodule.tcl | 818 ++++++++++ .../drivers/iomodule/data/iomodule_header.h | 47 + .../iomodule/data/iomodule_intr_header.h | 50 + .../drivers/iomodule/data/iomodule_tapp.tcl | 201 +++ .../drivers/iomodule/examples/index.html | 20 + .../iomodule/examples/xiomodule_example.c | 312 ++++ .../examples/xiomodule_intr_example.c | 437 ++++++ .../examples/xiomodule_low_level_example.c | 254 ++++ .../examples/xiomodule_selftest_example.c | 176 +++ .../drivers/iomodule/src/Makefile | 30 + .../drivers/iomodule/src/xiomodule.c | 1317 +++++++++++++++++ .../drivers/iomodule/src/xiomodule.h | 583 ++++++++ .../drivers/iomodule/src/xiomodule_extra.c | 159 ++ .../drivers/iomodule/src/xiomodule_g.c | 137 ++ .../drivers/iomodule/src/xiomodule_i.h | 127 ++ .../drivers/iomodule/src/xiomodule_intr.c | 312 ++++ .../drivers/iomodule/src/xiomodule_io.h | 85 ++ .../drivers/iomodule/src/xiomodule_l.c | 379 +++++ .../drivers/iomodule/src/xiomodule_l.h | 444 ++++++ .../drivers/iomodule/src/xiomodule_options.c | 282 ++++ .../drivers/iomodule/src/xiomodule_selftest.c | 268 ++++ .../drivers/iomodule/src/xiomodule_stats.c | 148 ++ .../drivers/iomodule/src/xiomodule_uart.c | 265 ++++ .../iomodule/src/xiomodule_uart_intr.c | 753 ++++++++++ 25 files changed, 7684 insertions(+) create mode 100755 XilinxProcessorIPLib/drivers/iomodule/data/iomodule.mdd create mode 100755 XilinxProcessorIPLib/drivers/iomodule/data/iomodule.tcl create mode 100755 XilinxProcessorIPLib/drivers/iomodule/data/iomodule_header.h create mode 100755 XilinxProcessorIPLib/drivers/iomodule/data/iomodule_intr_header.h create mode 100755 XilinxProcessorIPLib/drivers/iomodule/data/iomodule_tapp.tcl create mode 100755 XilinxProcessorIPLib/drivers/iomodule/examples/index.html create mode 100755 XilinxProcessorIPLib/drivers/iomodule/examples/xiomodule_example.c create mode 100755 XilinxProcessorIPLib/drivers/iomodule/examples/xiomodule_intr_example.c create mode 100755 XilinxProcessorIPLib/drivers/iomodule/examples/xiomodule_low_level_example.c create mode 100755 XilinxProcessorIPLib/drivers/iomodule/examples/xiomodule_selftest_example.c create mode 100755 XilinxProcessorIPLib/drivers/iomodule/src/Makefile create mode 100755 XilinxProcessorIPLib/drivers/iomodule/src/xiomodule.c create mode 100755 XilinxProcessorIPLib/drivers/iomodule/src/xiomodule.h create mode 100755 XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_extra.c create mode 100755 XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_g.c create mode 100755 XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_i.h create mode 100755 XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_intr.c create mode 100755 XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_io.h create mode 100755 XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_l.c create mode 100755 XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_l.h create mode 100755 XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_options.c create mode 100755 XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_selftest.c create mode 100755 XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_stats.c create mode 100755 XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_uart.c create mode 100755 XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_uart_intr.c diff --git a/XilinxProcessorIPLib/drivers/iomodule/data/iomodule.mdd b/XilinxProcessorIPLib/drivers/iomodule/data/iomodule.mdd new file mode 100755 index 00000000..f75e133a --- /dev/null +++ b/XilinxProcessorIPLib/drivers/iomodule/data/iomodule.mdd @@ -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 diff --git a/XilinxProcessorIPLib/drivers/iomodule/data/iomodule.tcl b/XilinxProcessorIPLib/drivers/iomodule/data/iomodule.tcl new file mode 100755 index 00000000..5af7122d --- /dev/null +++ b/XilinxProcessorIPLib/drivers/iomodule/data/iomodule.tcl @@ -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 +} diff --git a/XilinxProcessorIPLib/drivers/iomodule/data/iomodule_header.h b/XilinxProcessorIPLib/drivers/iomodule/data/iomodule_header.h new file mode 100755 index 00000000..fdcb7a7e --- /dev/null +++ b/XilinxProcessorIPLib/drivers/iomodule/data/iomodule_header.h @@ -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); diff --git a/XilinxProcessorIPLib/drivers/iomodule/data/iomodule_intr_header.h b/XilinxProcessorIPLib/drivers/iomodule/data/iomodule_intr_header.h new file mode 100755 index 00000000..24a8d01c --- /dev/null +++ b/XilinxProcessorIPLib/drivers/iomodule/data/iomodule_intr_header.h @@ -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); diff --git a/XilinxProcessorIPLib/drivers/iomodule/data/iomodule_tapp.tcl b/XilinxProcessorIPLib/drivers/iomodule/data/iomodule_tapp.tcl new file mode 100755 index 00000000..1161ad89 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/iomodule/data/iomodule_tapp.tcl @@ -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 +} diff --git a/XilinxProcessorIPLib/drivers/iomodule/examples/index.html b/XilinxProcessorIPLib/drivers/iomodule/examples/index.html new file mode 100755 index 00000000..d054032e --- /dev/null +++ b/XilinxProcessorIPLib/drivers/iomodule/examples/index.html @@ -0,0 +1,20 @@ + + + + + +Driver example applications + + + +

Example Applications for the driver iomodule_v2_1

+
+ +

Copyright © 1995-2014 Xilinx, Inc. All rights reserved.

+ + \ No newline at end of file diff --git a/XilinxProcessorIPLib/drivers/iomodule/examples/xiomodule_example.c b/XilinxProcessorIPLib/drivers/iomodule/examples/xiomodule_example.c new file mode 100755 index 00000000..8773c3f0 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/iomodule/examples/xiomodule_example.c @@ -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 +* +*
+*
+* MODIFICATION HISTORY:
+* Ver   Who  Date     Changes
+* ----- ---- -------- ----------------------------------------------------
+* 1.00a sa   07/15/11 First release
+* 
+******************************************************************************/ + +/***************************** 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__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++; +} diff --git a/XilinxProcessorIPLib/drivers/iomodule/examples/xiomodule_intr_example.c b/XilinxProcessorIPLib/drivers/iomodule/examples/xiomodule_intr_example.c new file mode 100755 index 00000000..5ce8e98f --- /dev/null +++ b/XilinxProcessorIPLib/drivers/iomodule/examples/xiomodule_intr_example.c @@ -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 +* +*
+*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- --------------------------------------------------------
+* 1.00a sa   07/15/11 First release
+* 
+******************************************************************************/ + +/***************************** 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__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__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); + } +} diff --git a/XilinxProcessorIPLib/drivers/iomodule/examples/xiomodule_low_level_example.c b/XilinxProcessorIPLib/drivers/iomodule/examples/xiomodule_low_level_example.c new file mode 100755 index 00000000..015c57f3 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/iomodule/examples/xiomodule_low_level_example.c @@ -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 +* +*
+*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- ---------------------------------------------------------
+* 1.00a sa   07/15/11 First release
+* 
+******************************************************************************/ + +/***************************** 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++; +} diff --git a/XilinxProcessorIPLib/drivers/iomodule/examples/xiomodule_selftest_example.c b/XilinxProcessorIPLib/drivers/iomodule/examples/xiomodule_selftest_example.c new file mode 100755 index 00000000..0fe9009a --- /dev/null +++ b/XilinxProcessorIPLib/drivers/iomodule/examples/xiomodule_selftest_example.c @@ -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 +* +*
+*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- --------------------------------------------------------
+* 1.00a sa   07/15/11 First release
+* 
+******************************************************************************/ + +/***************************** 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__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; +} diff --git a/XilinxProcessorIPLib/drivers/iomodule/src/Makefile b/XilinxProcessorIPLib/drivers/iomodule/src/Makefile new file mode 100755 index 00000000..510f99fe --- /dev/null +++ b/XilinxProcessorIPLib/drivers/iomodule/src/Makefile @@ -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} + + diff --git a/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule.c b/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule.c new file mode 100755 index 00000000..2575894e --- /dev/null +++ b/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule.c @@ -0,0 +1,1317 @@ +/****************************************************************************** +* +* (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.c +* +* Contains required functions for the XIomodule driver for the Xilinx +* IO Module Interrupt Controller. See xiomodule.h for a detailed +* description of the driver. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- --------------------------------------------------------
+* 1.00a sa   07/15/11 First release
+* 1.01a sa   04/10/12 Updated with fast interrupt
+* 2.1   bss  05/02/14 Modified XIOModule_IsExpired to check for all 1's instead
+*		      of 0 in CounterReg.(CR#794167)
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xiomodule.h" +#include "xiomodule_l.h" +#include "xiomodule_i.h" +#include "xiomodule_io.h" +#include "xil_types.h" +#include "xil_assert.h" + +/************************** Constant Definitions *****************************/ + + +/**************************** Type Definitions *******************************/ + + +/***************** Macros (Inline Functions) Definitions *********************/ + + +/************************** Variable Definitions *****************************/ + +/* + * Array of masks associated with the bit position, improves performance + * in the ISR and acknowledge functions, this table is shared between all + * instances of the driver, this table is not statically initialized because + * the size of the table is based upon the maximum used interrupt id + */ +u32 XIOModule_BitPosMask[XPAR_IOMODULE_INTC_MAX_INTR_SIZE]; + +/************************** Function Prototypes ******************************/ + +static void StubHandler(void *CallBackRef); + +/*****************************************************************************/ +/** +* +* Initialize a specific interrupt controller instance/driver. The +* initialization entails: +* +* - Initialize fields of the XIOModule structure +* - Initial vector table with stub function calls +* - All interrupt sources are disabled +* - Interrupt output is disabled +* - All timers are initialized +* +* @param InstancePtr is a pointer to the XIOModule instance to be +* worked on. +* @param DeviceId is the unique id of the device controlled by this +* XIOModule instance. Passing in a device id associates the +* generic XIOModule instance to a specific device, as chosen +* by the caller or application developer. +* +* @return +* - XST_SUCCESS if initialization was successful +* - XST_DEVICE_IS_STARTED if the device has already been started +* - XST_DEVICE_NOT_FOUND if device configuration information was +* not found for a device with the supplied device ID. +* +* @note None. +* +******************************************************************************/ +int XIOModule_Initialize(XIOModule * InstancePtr, u16 DeviceId) +{ + u8 Id; + XIOModule_Config *CfgPtr; + u32 NextBitMask = 1; + int i; + + Xil_AssertNonvoid(InstancePtr != NULL); + + /* + * If the device is started, disallow the initialize and return a status + * indicating it is started. This allows the user to stop the device + * and reinitialize, but prevents a user from inadvertently initializing + */ + if (InstancePtr->IsStarted == XIL_COMPONENT_IS_READY) { + return XST_DEVICE_IS_STARTED; + } + + /* + * Lookup the device configuration in the CROM table. Use this + * configuration info down below when initializing this component. + */ + CfgPtr = XIOModule_LookupConfig(DeviceId); + if (CfgPtr == NULL) { + return XST_DEVICE_NOT_FOUND; + } + + /* + * Set some default values + */ + InstancePtr->IsReady = 0; + InstancePtr->IsStarted = 0; /* not started */ + InstancePtr->CfgPtr = CfgPtr; + + InstancePtr->CfgPtr->Options = XIN_SVC_SGL_ISR_OPTION; + + /* + * Initialize GPO value from INIT parameter + */ + for (i = 0; i < XGPO_DEVICE_COUNT; i++) + InstancePtr->GpoValue[i] = CfgPtr->GpoInit[i]; + + /* + * Save the base address pointer such that the registers of the + * IO Module can be accessed + */ + InstancePtr->BaseAddress = CfgPtr->BaseAddress; + + /* + * Initialize all the data needed to perform interrupt processing for + * each interrupt ID up to the maximum used + */ + for (Id = 0; Id < XPAR_IOMODULE_INTC_MAX_INTR_SIZE; Id++) { + /* + * Initalize the handler to point to a stub to handle an + * interrupt which has not been connected to a handler. Only + * initialize it if the handler is 0 or XNullHandler, which + * means it was not initialized statically by the tools/user. + * Set the callback reference to this instance so that + * unhandled interrupts can be tracked. + */ + if ((InstancePtr->CfgPtr->HandlerTable[Id].Handler == 0) || + (InstancePtr->CfgPtr->HandlerTable[Id].Handler == + XNullHandler)) { + InstancePtr->CfgPtr->HandlerTable[Id].Handler = + StubHandler; + } + InstancePtr->CfgPtr->HandlerTable[Id].CallBackRef = InstancePtr; + + /* + * Initialize the bit position mask table such that bit + * positions are lookups only for each interrupt id, with 0 + * being a special case + * (XIOModule_BitPosMask[] = { 1, 2, 4, 8, ... }) + */ + XIOModule_BitPosMask[Id] = NextBitMask; + NextBitMask *= 2; + } + + /* + * Disable all interrupt sources + * Acknowledge all sources + */ + XIomodule_Out32(InstancePtr->BaseAddress + XIN_IER_OFFSET, 0); + XIomodule_Out32(InstancePtr->BaseAddress + XIN_IMR_OFFSET, 0); + XIomodule_Out32(InstancePtr->BaseAddress + XIN_IAR_OFFSET, 0xFFFFFFFF); + + InstancePtr->CurrentIER = 0; + InstancePtr->CurrentIMR = 0; + + /* + * If the fast Interrupt mode is enabled then set all the + * interrupts as normal mode and initialize the interrupt hardware + * vector table to default ((BaseVector & 0xFFFFFF80) | 0x10). + */ + if (InstancePtr->CfgPtr->FastIntr == TRUE) { + XIomodule_Out32(InstancePtr->BaseAddress + XIN_IMR_OFFSET, 0); + + for (Id = 0; Id < XPAR_IOMODULE_INTC_MAX_INTR_SIZE; Id++) { + XIomodule_Out32(InstancePtr->BaseAddress + + XIN_IVAR_OFFSET + Id * 4, + (InstancePtr->CfgPtr->BaseVector & + 0xFFFFFF80) | 0x10); + } + } + + /* + * Initialize all Programmable Interrupt Timers + */ + XIOModule_Timer_Initialize(InstancePtr, DeviceId); + + /* + * Initialize all UART related status + */ + XIOModule_CfgInitialize(InstancePtr, CfgPtr, 0); + + /* + * Save the IO Bus base address pointer such that the memory mapped + * IO can be accessed + */ + InstancePtr->IoBaseAddress = CfgPtr->IoBaseAddress; + + /* + * Indicate the instance is now ready to use, successfully initialized + */ + InstancePtr->IsReady = XIL_COMPONENT_IS_READY; + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* Starts the IO Module. Interrupts may be generated by the IO Module after this +* function is called. +* +* It is necessary for the caller to connect the interrupt handler of this +* component to the proper interrupt source. +* +* @param InstancePtr is a pointer to the XIOModule instance to be +* worked on. +* +* @return +* - XST_SUCCESS if the device was started successfully +* - XST_FAILURE if simulation mode was specified and it could not +* be set because real mode has already been entered. +* +* @note Must be called after XIOModule initialization is completed. +* +******************************************************************************/ +int XIOModule_Start(XIOModule * InstancePtr) +{ + /* + * Assert the arguments + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Indicate the instance is ready to be used and is started before we + * enable the device. + */ + InstancePtr->IsStarted = XIL_COMPONENT_IS_READY; + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* Stops the interrupt controller by disabling the output from the controller +* so that no interrupts will be caused by the interrupt controller. +* +* @param InstancePtr is a pointer to the XIOModule instance to be +* worked on. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XIOModule_Stop(XIOModule * InstancePtr) +{ + /* + * Assert the arguments + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + InstancePtr->IsStarted = 0; +} + +/*****************************************************************************/ +/** +* +* Makes the connection between the Id of the interrupt source and the +* associated handler that is to run when the interrupt is recognized. The +* argument provided in this call as the Callbackref is used as the argument +* for the handler when it is called. +* +* @param InstancePtr is a pointer to the XIOModule instance to be +* worked on. +* @param Id contains the ID of the interrupt source and should be in the +* range of 0 to XPAR_IOMODULE_INTC_MAX_INTR_SIZE - 1 with 0 +* being the highest priority interrupt. +* @param Handler to the handler for that interrupt. +* @param CallBackRef is the callback reference, usually the instance +* pointer of the connecting driver. +* +* @return +* - XST_SUCCESS if the handler was connected correctly. +* +* @note Only used with normal interrupt mode. +* Does not restore normal interrupt mode. +* +* WARNING: The handler provided as an argument will overwrite any handler +* that was previously connected. +* +****************************************************************************/ +int XIOModule_Connect(XIOModule * InstancePtr, u8 Id, + XInterruptHandler Handler, void *CallBackRef) +{ + /* + * Assert the arguments + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(Id < XPAR_IOMODULE_INTC_MAX_INTR_SIZE); + Xil_AssertNonvoid(Handler != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * The Id is used as an index into the table to select the proper + * handler + */ + InstancePtr->CfgPtr->HandlerTable[Id].Handler = Handler; + InstancePtr->CfgPtr->HandlerTable[Id].CallBackRef = CallBackRef; + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* Updates the interrupt table with the Null Handler and NULL arguments at the +* location pointed at by the Id. This effectively disconnects that interrupt +* source from any handler. The interrupt is disabled also. +* +* @param InstancePtr is a pointer to the XIOModule instance to be +* worked on. +* @param Id contains the ID of the interrupt source and should be in the +* range of 0 to XPAR_IOMODULE_INTC_MAX_INTR_SIZE - 1 with 0 +* being the highest priority interrupt. +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void XIOModule_Disconnect(XIOModule * InstancePtr, u8 Id) +{ + u32 NewIER; + u32 Mask; + + /* + * Assert the arguments + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(Id < XPAR_IOMODULE_INTC_MAX_INTR_SIZE); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Disable the interrupt such that it won't occur while disconnecting + * the handler, only disable the specified interrupt id without + * modifying the other interrupt ids + */ + Mask = XIOModule_BitPosMask[Id]; /* convert integer id to bit mask */ + + NewIER = InstancePtr->CurrentIER & ~Mask; + XIomodule_Out32(InstancePtr->BaseAddress + XIN_IER_OFFSET, NewIER); + InstancePtr->CurrentIER = NewIER; + + /* + * Disconnect the handler and connect a stub, the callback reference + * must be set to this instance to allow unhandled interrupts to be + * tracked + */ + InstancePtr->CfgPtr->HandlerTable[Id].Handler = StubHandler; + InstancePtr->CfgPtr->HandlerTable[Id].CallBackRef = InstancePtr; +} + +/*****************************************************************************/ +/** +* +* Enables the interrupt source provided as the argument Id. Any pending +* interrupt condition for the specified Id will occur after this function is +* called. +* +* @param InstancePtr is a pointer to the XIOModule instance to be +* worked on. +* @param Id contains the ID of the interrupt source and should be in the +* range of 0 to XPAR_IOMODULE_INTC_MAX_INTR_SIZE - 1 with 0 +* being the highest priority interrupt. +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void XIOModule_Enable(XIOModule * InstancePtr, u8 Id) +{ + u32 NewIER; + u32 Mask; + + /* + * Assert the arguments + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(Id < XPAR_IOMODULE_INTC_MAX_INTR_SIZE); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * The Id is used to create the appropriate mask for the + * desired bit position. Id currently limited to 0 - 31 + */ + Mask = XIOModule_BitPosMask[Id]; + + /* + * Enable the selected interrupt source by using the interrupt enable + * current value and then modifying only the specified interrupt id + */ + NewIER = InstancePtr->CurrentIER | Mask; + XIomodule_Out32(InstancePtr->BaseAddress + XIN_IER_OFFSET, NewIER); + InstancePtr->CurrentIER = NewIER; +} + +/*****************************************************************************/ +/** +* +* Disables the interrupt source provided as the argument Id such that the +* interrupt controller will not cause interrupts for the specified Id. The +* interrupt controller will continue to hold an interrupt condition for the +* Id, but will not cause an interrupt. +* +* @param InstancePtr is a pointer to the XIOModule instance to be +* worked on. +* @param Id contains the ID of the interrupt source and should be in +* the range of 0 to XPAR_IOMODULE_INTC_MAX_INTR_SIZE - 1 +* with 0 being the highest priority interrupt. +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void XIOModule_Disable(XIOModule * InstancePtr, u8 Id) +{ + u32 NewIER; + u32 Mask; + + /* + * Assert the arguments + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(Id < XPAR_IOMODULE_INTC_MAX_INTR_SIZE); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * The Id is used to create the appropriate mask for the + * desired bit position. Id currently limited to 0 - 31 + */ + Mask = XIOModule_BitPosMask[Id]; + + /* + * Disable the selected interrupt source by using the interrupt enable + * current value and then modifying only the specified interrupt id + */ + NewIER = InstancePtr->CurrentIER & ~Mask; + XIomodule_Out32(InstancePtr->BaseAddress + XIN_IER_OFFSET, NewIER); + InstancePtr->CurrentIER = NewIER; +} + +/*****************************************************************************/ +/** +* +* Acknowledges the interrupt source provided as the argument Id. When the +* interrupt is acknowledged, it causes the interrupt controller to clear its +* interrupt condition. +* +* @param InstancePtr is a pointer to the XIOModule instance to be +* worked on. +* @param Id contains the ID of the interrupt source and should be in +* the range of 0 to XPAR_IOMODULE_INTC_MAX_INTR_SIZE - 1 +* with 0 being the highest priority interrupt. +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void XIOModule_Acknowledge(XIOModule * InstancePtr, u8 Id) +{ + u32 Mask; + + /* + * Assert the arguments + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(Id < XPAR_IOMODULE_INTC_MAX_INTR_SIZE); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * The Id is used to create the appropriate mask for the + * desired bit position. Id currently limited to 0 - 31 + */ + Mask = XIOModule_BitPosMask[Id]; + + /* + * Acknowledge the selected interrupt source, no read of the acknowledge + * register is necessary since only the bits set in the mask will be + * affected by the write + */ + XIomodule_Out32(InstancePtr->BaseAddress + XIN_IAR_OFFSET, Mask); +} + +/*****************************************************************************/ +/** +* +* A stub for the asynchronous callback. The stub is here in case the upper +* layers forget to set the handler. +* +* @param CallBackRef is a pointer to the upper layer callback reference +* +* @return None. +* +* @note None. +* +******************************************************************************/ +static void StubHandler(void *CallBackRef) +{ + /* + * Verify that the inputs are valid + */ + Xil_AssertVoid(CallBackRef != NULL); + + /* + * Indicate another unhandled interrupt for stats + */ + ((XIOModule *) CallBackRef)->UnhandledInterrupts++; +} + +/*****************************************************************************/ +/** +* +* Looks up the device configuration based on the unique device ID. A table +* contains the configuration info for each device in the system. +* +* @param DeviceId is the unique identifier for a device. +* +* @return A pointer to the XIOModule configuration structure for the +* specified device, or NULL if the device was not found. +* +* @note None. +* +******************************************************************************/ +XIOModule_Config *XIOModule_LookupConfig(u16 DeviceId) +{ + XIOModule_Config *CfgPtr = NULL; + int i; + + for (i = 0; i < XPAR_XIOMODULE_NUM_INSTANCES; i++) { + if (XIOModule_ConfigTable[i].DeviceId == DeviceId) { + CfgPtr = &XIOModule_ConfigTable[i]; + break; + } + } + + return CfgPtr; +} + + + +/*****************************************************************************/ +/** +* +* Makes the connection between the Id of the interrupt source and the +* associated handler that is to run when the interrupt is recognized. +* +* @param InstancePtr is a pointer to the XIOModule instance. +* @param Id contains the ID of the interrupt source and should be in the +* range of 0 to XPAR_INTC_MAX_NUM_INTR_INPUTS - 1 with 0 being the +* highest priority interrupt. +* @param Handler to the handler for that interrupt. +* +* @return +* - XST_SUCCESS if the handler was connected correctly. +* +* @note Only used with fast interrupt mode. +* +* WARNING: The handler provided as an argument will overwrite any handler +* that was previously connected. +* +****************************************************************************/ +int XIOModule_ConnectFastHandler(XIOModule *InstancePtr, u8 Id, + XFastInterruptHandler Handler) +{ + u32 CurrentIER, NewIMR; + u32 Mask; + + /* + * Assert the arguments + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(Id < XPAR_IOMODULE_INTC_MAX_INTR_SIZE); + Xil_AssertNonvoid(Handler != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(InstancePtr->CfgPtr->FastIntr == TRUE); + + /* + * The Id is used to create the appropriate mask for the + * desired bit position. Id currently limited to 0 - 31 + */ + Mask = XIOModule_BitPosMask[Id]; + + /* + * Get the Enabled Interrupts and disable the Interrupt if it was + * enabled before calling this function + */ + CurrentIER = InstancePtr->CurrentIER; + if (CurrentIER & Mask) { + XIomodule_Out32(InstancePtr->BaseAddress + XIN_IER_OFFSET, + CurrentIER & ~Mask); + } + + /* + * Assign the handler information and set the hardware vector + */ + InstancePtr->CfgPtr->HandlerTable[Id].Handler = NULL; + InstancePtr->CfgPtr->HandlerTable[Id].CallBackRef = InstancePtr; + + XIomodule_Out32(InstancePtr->BaseAddress + XIN_IVAR_OFFSET + (Id * 4), + (u32) Handler); + + /* + * Set the selected interrupt source to use fast interrupt + */ + NewIMR = InstancePtr->CurrentIMR | Mask; + XIomodule_Out32(InstancePtr->BaseAddress + XIN_IMR_OFFSET, NewIMR); + InstancePtr->CurrentIMR = NewIMR; + + /* + * Enable Interrupt if it was enabled before calling this function + */ + if (CurrentIER & Mask) { + XIomodule_Out32(InstancePtr->BaseAddress + XIN_IER_OFFSET, + CurrentIER); + } + + return XST_SUCCESS; +} + + + +/*****************************************************************************/ +/** +* +* Sets the normal interrupt mode for the specified interrupt in the Interrupt +* Mode Register, by resetting the vector to (BaseVector & 0xFFFFFF80) | 0x10 +* and selecting normal mode. +* +* @param InstancePtr is a pointer to the XIOModule instance. +* @param Id contains the ID of the interrupt source and should be in the +* range of 0 to XPAR_INTC_MAX_NUM_INTR_INPUTS - 1 with 0 being the +* highest priority interrupt. +* +* @return None. +* +* @note Only used with fast interrupt mode. +* +****************************************************************************/ +void XIOModule_SetNormalIntrMode(XIOModule *InstancePtr, u8 Id) +{ + u32 CurrentIER, NewIMR; + u32 Mask; + + /* + * Assert the arguments + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(Id < XPAR_IOMODULE_INTC_MAX_INTR_SIZE); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid(InstancePtr->CfgPtr->FastIntr == TRUE); + + /* + * The Id is used to create the appropriate mask for the + * desired bit position. Id currently limited to 0 - 31 + */ + Mask = XIOModule_BitPosMask[Id]; + + /* + * Get the Enabled Interrupts and disable the Interrupt if it was + * enabled before calling this function + */ + CurrentIER = InstancePtr->CurrentIER; + if (CurrentIER & Mask) { + XIomodule_Out32(InstancePtr->BaseAddress + XIN_IER_OFFSET, + CurrentIER & ~Mask); + } + + /* + * Set the selected interrupt source to use normal interrupt + */ + NewIMR = InstancePtr->CurrentIMR & ~Mask; + XIomodule_Out32(InstancePtr->BaseAddress + XIN_IMR_OFFSET, NewIMR); + InstancePtr->CurrentIMR = NewIMR; + + XIomodule_Out32(InstancePtr->BaseAddress + XIN_IVAR_OFFSET + (Id * 4), + (InstancePtr->CfgPtr->BaseVector & 0xFFFFFF80) | 0x10); + + /* + * Disconnect the handler and connect a stub, the callback reference + * must be set to this instance to allow unhandled interrupts to be + * tracked + */ + InstancePtr->CfgPtr->HandlerTable[Id].Handler = StubHandler; + InstancePtr->CfgPtr->HandlerTable[Id].CallBackRef = InstancePtr; + + /* + * Enable Interrupt if it was enabled before calling this function + */ + if (CurrentIER & Mask) { + XIomodule_Out32(InstancePtr->BaseAddress + XIN_IER_OFFSET, + CurrentIER); + } +} + + +/****************************************************************************/ +/** +* Read state of discretes for the specified GPI channnel. +* +* @param InstancePtr is a pointer to an XIOModule instance to be +* worked on. +* @param Channel contains the channel of the GPI (1, 2, 3 or 4) to +* operate on. +* +* @return Current copy of the discretes register. +* +*****************************************************************************/ +u32 XIOModule_DiscreteRead(XIOModule * InstancePtr, unsigned Channel) +{ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid((Channel >= 1) && (Channel <= XGPI_DEVICE_COUNT)); + + return XIOModule_ReadReg(InstancePtr->BaseAddress, + ((Channel - 1) * XGPI_CHAN_OFFSET) + XGPI_DATA_OFFSET); +} + +/****************************************************************************/ +/** +* Write to discretes register 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 GPO (1, 2, 3 or 4) to +* operate on. +* @param Data is the value to be written to the discretes register. +* +* @return None. +* +*****************************************************************************/ +void XIOModule_DiscreteWrite(XIOModule * InstancePtr, + unsigned Channel, + u32 Data) +{ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid((Channel >= 1) && (Channel <= XGPO_DEVICE_COUNT)); + + XIOModule_WriteReg(InstancePtr->BaseAddress, + ((Channel - 1) * XGPO_CHAN_OFFSET) + XGPO_DATA_OFFSET, + Data); + InstancePtr->GpoValue[Channel - 1] = Data; +} + + + +/*****************************************************************************/ +/** +* +* Initializes a specific timer instance/driver. Initialize fields of the +* XIOModule structure, then reset the timer +* +* @param InstancePtr is a pointer to the XIOModule instance. +* @param DeviceId is the unique id of the device controlled by this +* XIOModule component. Passing in a device id associates the +* generic XIOModule component to a specific device, as chosen by +* the caller or application developer. +* +* @return +* - XST_SUCCESS if initialization was successful +* - XST_DEVICE_IS_STARTED if the device has already been started +* - XST_DEVICE_NOT_FOUND if the device doesn't exist +* +* @note None. +* +******************************************************************************/ +int XIOModule_Timer_Initialize(XIOModule * InstancePtr, u16 DeviceId) +{ + XIOModule_Config *IOModuleConfigPtr; + int TimerNumber; + u32 TimerOffset; + u32 StatusReg; + + Xil_AssertNonvoid(InstancePtr != NULL); + + /* + * Lookup the device configuration in the temporary CROM table. Use this + * configuration info down below when initializing this component. + */ + IOModuleConfigPtr = XIOModule_LookupConfig(DeviceId); + + if (IOModuleConfigPtr == (XIOModule_Config *) NULL) { + return XST_DEVICE_NOT_FOUND; + } + + /* + * Check each of the timers of the device, if any are already + * running, then the device should not be initialized. This allows the + * user to stop the device and reinitialize, but prevents a user from + * inadvertently initializing. + */ + for (TimerNumber = 0; + TimerNumber < XTC_DEVICE_TIMER_COUNT; TimerNumber++) { + TimerOffset = TimerNumber << XTC_TIMER_COUNTER_SHIFT; + + /* + * Use the current register contents and check if the timer + * counter is started and running, note that this is not + * destructive if the timer counter is already started + */ + StatusReg = InstancePtr->CurrentTCSR[TimerNumber]; + if (StatusReg & XTC_CSR_ENABLE_TMR_MASK) { + continue; + } + + /* + * Set some default values, including setting the callback + * handlers to stubs. + */ + InstancePtr->BaseAddress = IOModuleConfigPtr->BaseAddress; + InstancePtr->Handler = NULL; + InstancePtr->CallBackRef = NULL; + + /* + * Clear the statistics for this driver + */ + InstancePtr->Timer_Stats[TimerNumber].Interrupts = 0; + + /* Initialize the registers of each timer in the device */ + + /* + * Set the Load register to 0 + */ + XIOModule_WriteReg(InstancePtr->BaseAddress, + TimerOffset + XTC_TLR_OFFSET, 0); + InstancePtr->CurrentTLR[TimerNumber] = 0; + + /* + * Set the control/status register to complete initialization + * by clearing the reset bit which was just set + */ + XIOModule_WriteReg(InstancePtr->BaseAddress, + TimerOffset + XTC_TCSR_OFFSET, 0); + InstancePtr->CurrentTCSR[TimerNumber] = 0; + } + + /* + * Indicate the instance is ready to use, successfully initialized + */ + InstancePtr->IsReady = XIL_COMPONENT_IS_READY; + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* Starts the specified timer counter of the device such that it starts running. +* The timer counter is reset before it is started and the reset value is +* loaded into the timer counter. +* +* If interrupt mode is specified in the options, it is necessary for the caller +* to connect the interrupt handler of the timer to the interrupt source, +* typically an interrupt controller, and enable the interrupt within the +* interrupt controller. +* +* @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 None. +* +* @note None. +* +******************************************************************************/ +void XIOModule_Timer_Start(XIOModule * InstancePtr, u8 TimerNumber) +{ + u32 NewControlStatus; + u32 TimerOffset = TimerNumber << XTC_TIMER_COUNTER_SHIFT; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(TimerNumber < XTC_DEVICE_TIMER_COUNT); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Set the new value the current contents such that only the necessary + * bits of the register are modified in the following operations + */ + NewControlStatus = InstancePtr->CurrentTCSR[TimerNumber] | + XTC_CSR_ENABLE_TMR_MASK; + + /* + * Remove the reset condition such that the timer starts + * running with the value loaded from the compare register + */ + XIOModule_WriteReg(InstancePtr->BaseAddress, + TimerOffset + XTC_TCSR_OFFSET, NewControlStatus); + InstancePtr->CurrentTCSR[TimerNumber] = NewControlStatus; +} + +/*****************************************************************************/ +/** +* +* Stops the timer by disabling it. +* +* It is the callers' responsibility to disconnect the interrupt handler of the +* timer from the interrupt source, typically an interrupt controller, +* and disable the interrupt within the interrupt controller. +* +* @param InstancePtr is a pointer to the XIOModule instance. +* @param TimerNumber is the timer counter of the device to operate on. +* Each device may contain multiple timer counters. The timer +* number is a zero based number with a range of +* 0 to (XTC_DEVICE_TIMER_COUNT - 1). +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XIOModule_Timer_Stop(XIOModule * InstancePtr, u8 TimerNumber) +{ + u32 NewControlStatus; + u32 TimerOffset = TimerNumber << XTC_TIMER_COUNTER_SHIFT; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(TimerNumber < XTC_DEVICE_TIMER_COUNT); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Set the new value based on the current contents + */ + NewControlStatus = InstancePtr->CurrentTCSR[TimerNumber]; + + /* + * Disable the timer counter such that it's not running + */ + NewControlStatus &= ~(XTC_CSR_ENABLE_TMR_MASK); + + /* + * Write out the updated value to the actual register. + */ + XIOModule_WriteReg(InstancePtr->BaseAddress, + TimerOffset + XTC_TCSR_OFFSET, NewControlStatus); + InstancePtr->CurrentTCSR[TimerNumber] = NewControlStatus; +} + +/*****************************************************************************/ +/** +* +* Get the current value of the specified timer counter. The timer counter +* may be either incrementing or decrementing based upon the current mode of +* operation. +* +* @param InstancePtr is a pointer to the XIOModule instance. +* @param TimerNumber is the timer counter of the device to operate on. +* Each device may contain multiple timer counters. The timer +* number is a zero based number with a range of +* 0 to (XTC_DEVICE_TIMER_COUNT - 1). +* +* @return The current value for the timer counter. +* +* @note None. +* +******************************************************************************/ +u32 XIOModule_GetValue(XIOModule * InstancePtr, u8 TimerNumber) +{ + u32 TimerOffset = TimerNumber << XTC_TIMER_COUNTER_SHIFT; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(TimerNumber < XTC_DEVICE_TIMER_COUNT); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + return XIOModule_ReadReg(InstancePtr->BaseAddress, + TimerOffset + XTC_TCR_OFFSET); +} + +/*****************************************************************************/ +/** +* +* Set the reset value for the specified timer counter. This is the value +* that is loaded into the timer counter when it is reset. This value is also +* loaded when the timer counter is started. +* +* @param InstancePtr is a pointer to the XIOModule instance. +* @param TimerNumber is the timer counter of the device to operate on. +* Each device may contain multiple timer counters. The timer +* number is a zero based number with a range of +* 0 to (XTC_DEVICE_TIMER_COUNT - 1). +* @param ResetValue contains the value to be used to reset the timer +* counter. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XIOModule_SetResetValue(XIOModule * InstancePtr, u8 TimerNumber, + u32 ResetValue) +{ + u32 TimerOffset = TimerNumber << XTC_TIMER_COUNTER_SHIFT; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(TimerNumber < XTC_DEVICE_TIMER_COUNT); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + XIOModule_WriteReg(InstancePtr->BaseAddress, + TimerOffset + XTC_TLR_OFFSET, + ResetValue); + InstancePtr->CurrentTLR[TimerNumber] = ResetValue; +} + +/*****************************************************************************/ +/** +* +* Returns the timer counter value that was captured the last time the external +* capture input was asserted. +* +* @param InstancePtr is a pointer to the XIOModule instance. +* @param TimerNumber is the timer counter of the device to operate on. +* Each device may contain multiple timer counters. The timer +* number is a zero based number with a range of +* 0 to (XTC_DEVICE_TIMER_COUNT - 1). +* +* @return The current capture value for the indicated timer counter. +* +* @note None. +* +*******************************************************************************/ +u32 XIOModule_GetCaptureValue(XIOModule * InstancePtr, u8 TimerNumber) +{ + u32 TimerOffset = TimerNumber << XTC_TIMER_COUNTER_SHIFT; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(TimerNumber < XTC_DEVICE_TIMER_COUNT); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + return InstancePtr->CurrentTLR[TimerNumber]; +} + +/*****************************************************************************/ +/** +* +* Resets the specified timer counter of the device. A reset causes the timer +* counter to set it's value to the reset value. +* +* @param InstancePtr is a pointer to the XIOModule instance. +* @param TimerNumber is the timer counter of the device to operate on. +* Each device may contain multiple timer counters. The timer +* number is a zero based number with a range of +* 0 to (XTC_DEVICE_TIMER_COUNT - 1). +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XIOModule_Reset(XIOModule * InstancePtr, u8 TimerNumber) +{ + u32 CounterControlReg; + u32 NewCounterControl; + u32 TimerOffset = TimerNumber << XTC_TIMER_COUNTER_SHIFT; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(TimerNumber < XTC_DEVICE_TIMER_COUNT); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read current contents of the register so it won't be destroyed + */ + CounterControlReg = InstancePtr->CurrentTCSR[TimerNumber]; + NewCounterControl = CounterControlReg | XTC_CSR_ENABLE_TMR_MASK; + + /* + * Reset the timer by toggling the enable bit in the register + */ + if ((CounterControlReg & XTC_CSR_ENABLE_TMR_MASK) == 0) { + XIOModule_WriteReg(InstancePtr->BaseAddress, + TimerOffset + XTC_TCSR_OFFSET, + NewCounterControl); + XIOModule_WriteReg(InstancePtr->BaseAddress, + TimerOffset + XTC_TCSR_OFFSET, + CounterControlReg); + } +} + +/*****************************************************************************/ +/** +* +* Checks if the specified timer counter of the device has expired. In capture +* mode, expired is defined as a capture occurred. In compare mode, expired is +* defined as the timer counter rolled over/under for up/down counting. +* +* When interrupts are enabled, the expiration causes an interrupt. This function +* is typically used to poll a timer counter to determine when it has expired. +* +* @param InstancePtr is a pointer to the XIOModule instance. +* @param TimerNumber is the timer counter of the device to operate on. +* Each device may contain multiple timer counters. The timer +* number is a zero based number with a range of +* 0 to (XTC_DEVICE_TIMER_COUNT - 1). +* +* @return TRUE if the timer has expired, and FALSE otherwise. +* +* @note None. +* +******************************************************************************/ +int XIOModule_IsExpired(XIOModule * InstancePtr, u8 TimerNumber) +{ + u32 CounterReg; + u32 TimerOffset = TimerNumber << XTC_TIMER_COUNTER_SHIFT; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(TimerNumber < XTC_DEVICE_TIMER_COUNT); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(InstancePtr->CfgPtr->PitReadable[TimerNumber]); + + /* + * Check if timer is expired + */ + if (InstancePtr->CurrentTCSR[TimerNumber] & XTC_CSR_AUTO_RELOAD_MASK) { + return 1; /* Always expired for reload */ + } else { + CounterReg = XIOModule_ReadReg(InstancePtr->BaseAddress, + TimerOffset + XTC_TCR_OFFSET); + + if (CounterReg & InstancePtr->CfgPtr->PitMask[TimerNumber] == + InstancePtr->CfgPtr->PitMask[TimerNumber]) { + return 1; + } else { + return 0; + } + } +} + +/****************************************************************************/ +/** +* Read 32-bit word from the IO Bus memory mapped IO +* +* @param InstancePtr is a pointer to an XIOModule instance to be +* worked on. +* @param ByteOffset is a byte offset from the beginning of the +* IO Bus address area +* +* @return Value read from the IO Bus - 32-bit word +* +*****************************************************************************/ +u32 XIOModule_IoReadWord(XIOModule * InstancePtr, u32 ByteOffset) +{ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + return XIomodule_In32((InstancePtr->IoBaseAddress + ByteOffset)); +} + +/****************************************************************************/ +/** +* Read 16-bit halfword from the IO Bus memory mapped IO +* +* @param InstancePtr is a pointer to an XIOModule instance to be +* worked on. +* @param ByteOffset is a byte offset from the beginning of the +* IO Bus address area +* +* @return Value read from the IO Bus - 16-bit halfword +* +*****************************************************************************/ +u16 XIOModule_IoReadHalfword(XIOModule * InstancePtr, u32 ByteOffset) +{ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + return XIomodule_In16((InstancePtr->IoBaseAddress + ByteOffset)); +} + +/****************************************************************************/ +/** +* Read byte from the IO Bus memory mapped IO +* +* @param InstancePtr is a pointer to an XIOModule instance to be +* worked on. +* @param ByteOffset is a byte offset from the beginning of the +* IO Bus address area +* +* @return Value read from the IO Bus - 8-bit byte +* +*****************************************************************************/ +u8 XIOModule_IoReadByte(XIOModule * InstancePtr, u32 ByteOffset) +{ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + return XIomodule_In8((InstancePtr->IoBaseAddress + ByteOffset)); +} + +/****************************************************************************/ +/** +* Write 32-bit word to the IO Bus memory mapped IO +* +* @param InstancePtr is a pointer to an XIOModule instance to be +* worked on. +* @param ByteOffset is a byte offset from the beginning of the +* IO Bus address area +* @param Data is the value to be written to the IO Bus - 32-bit +* +* @return None. +* +*****************************************************************************/ +void XIOModule_IoWriteWord(XIOModule * InstancePtr, + u32 ByteOffset, + u32 Data) +{ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + XIomodule_Out32((InstancePtr->IoBaseAddress + ByteOffset), Data); +} + +/****************************************************************************/ +/** +* Write 16-bit word to the IO Bus memory mapped IO +* +* @param InstancePtr is a pointer to an XIOModule instance to be +* worked on. +* @param ByteOffset is a byte offset from the beginning of the +* IO Bus address area +* @param Data is the value to be written to the IO Bus - 16-bit +* +* @return None. +* +*****************************************************************************/ +void XIOModule_IoWriteHalfword(XIOModule * InstancePtr, + u32 ByteOffset, + u16 Data) +{ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + XIomodule_Out16((InstancePtr->IoBaseAddress + ByteOffset), Data); +} + +/****************************************************************************/ +/** +* Write 8-bit word to the IO Bus memory mapped IO +* +* @param InstancePtr is a pointer to an XIOModule instance to be +* worked on. +* @param ByteOffset is a byte offset from the beginning of the +* IO Bus address area +* @param Data is the value to be written to the IO Bus - 8-bit +* +* @return None. +* +*****************************************************************************/ +void XIOModule_IoWriteByte(XIOModule * InstancePtr, + u32 ByteOffset, + u8 Data) +{ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + XIomodule_Out8((InstancePtr->IoBaseAddress + ByteOffset), Data); +} diff --git a/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule.h b/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule.h new file mode 100755 index 00000000..ff6dfd50 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule.h @@ -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: +*
    +*
  1. Universal Asynchronous Receiver Transmitter (UART)
  2. +*
  3. Fixed Interval Timer (FIT)
  4. +*
  5. Programmable Interval Timer (PIT)
  6. +*
  7. General Purpose Output (GPO)
  8. +*
  9. General Purpose Input (GPI)
  10. +*
  11. Interrupt controller (INTC)
  12. +*
  13. IO bus (IO)
  14. +*
+* +* Universal Asynchronous Receiver Transmitter (UART): +* 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. +* +* Fixed Interval Timer (FIT): +* 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. +* +* Programmable Interval Timer (PIT): +* 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. +* +* Interrupts +* +* 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. +* +* General Purpose Output (GPO): +* The GPO has support for up to 32 I/O discrete outputs for each channel (128 +* bits total). +* +* IO Bus (IO): +* 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. +* +* General Purpose Input (GPI): +* 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. +* +* Interrupt controller (INTC): +* 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. +* +* Interrupt Vector Tables +* +* 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. +* +*
+* 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)
+* 
+* +******************************************************************************/ + +#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. + *
+ * 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.
+ * 
+ */ +#define XTC_INT_MODE_OPTION 0 +#define XTC_AUTO_RELOAD_OPTION 0x00000002UL + +/** + * Used to configure the Interrupt Controller. + *
+ * 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.
+ * 
+ */ +#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. + *
+ * XTC_PRESCALER_*	Define the prescaler configured in hardware.
+ * 
+ */ +#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 */ diff --git a/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_extra.c b/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_extra.c new file mode 100755 index 00000000..c348bde5 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_extra.c @@ -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 +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a sa   07/15/11 First release
+* 
+* +*****************************************************************************/ + +/***************************** 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; +} diff --git a/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_g.c b/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_g.c new file mode 100755 index 00000000..769a0934 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_g.c @@ -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. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a sa   07/15/11 First release
+* 
+* +* @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 */ + } +}; diff --git a/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_i.h b/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_i.h new file mode 100755 index 00000000..6e4b650f --- /dev/null +++ b/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_i.h @@ -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. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a sa   07/15/11 First release
+* 1.02a sa   07/25/12 Added UART prototypes
+* 
+* +******************************************************************************/ + +#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 diff --git a/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_intr.c b/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_intr.c new file mode 100755 index 00000000..b6201d28 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_intr.c @@ -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. +* +*
+* 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
+* 
+* +* @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]); + } + } + } +} diff --git a/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_io.h b/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_io.h new file mode 100755 index 00000000..67d38495 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_io.h @@ -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 +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------------
+* 1.00a sa   07/15/11 First release
+* 
+* +******************************************************************************/ + +#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 */ diff --git a/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_l.c b/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_l.c new file mode 100755 index 00000000..8f33b807 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_l.c @@ -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. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a sa   07/15/11 First release
+* 
+* +******************************************************************************/ + + +/***************************** 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); +} + diff --git a/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_l.h b/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_l.h new file mode 100755 index 00000000..3efa515e --- /dev/null +++ b/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_l.h @@ -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. +* +*
+* 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
+* 
+* +******************************************************************************/ + +#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 */ diff --git a/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_options.c b/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_options.c new file mode 100755 index 00000000..6c9de8ee --- /dev/null +++ b/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_options.c @@ -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. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------------
+* 1.00a sa   07/15/11 First release
+* 
+* +******************************************************************************/ + +/***************************** 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; +} diff --git a/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_selftest.c b/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_selftest.c new file mode 100755 index 00000000..e7c6c553 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_selftest.c @@ -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. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a sa   07/15/11 First release
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xiomodule.h" +#include "xiomodule_i.h" +#include "xil_assert.h" + +#include "xiomodule_io.h" +#include + +/************************** 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; +} diff --git a/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_stats.c b/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_stats.c new file mode 100755 index 00000000..1eda0548 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_stats.c @@ -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 +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a sa   07/15/11 First release
+* 
+* +*****************************************************************************/ + +/***************************** 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; +} diff --git a/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_uart.c b/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_uart.c new file mode 100755 index 00000000..61d37b36 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_uart.c @@ -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. +* +*
+* 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
+* 
+* +*****************************************************************************/ + +/***************************** 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(); +} diff --git a/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_uart_intr.c b/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_uart_intr.c new file mode 100755 index 00000000..6512b4ca --- /dev/null +++ b/XilinxProcessorIPLib/drivers/iomodule/src/xiomodule_uart_intr.c @@ -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. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.03a sa   10/16/12 First release
+* 
+* +*****************************************************************************/ + +/***************************** 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; +}