diff --git a/XilinxProcessorIPLib/drivers/uartns550/data/uartns550.mdd b/XilinxProcessorIPLib/drivers/uartns550/data/uartns550.mdd new file mode 100755 index 00000000..32c7fb89 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/uartns550/data/uartns550.mdd @@ -0,0 +1,83 @@ +############################################################################### +# +# Copyright (C) 2004 - 2014 Xilinx, Inc. All rights reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# Use of the Software is limited solely to applications: +# (a) running on a Xilinx device, or +# (b) that interact with a Xilinx device through a bus or interconnect. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# Except as contained in this notice, the name of the Xilinx shall not be used +# in advertising or otherwise to promote the sale, use or other dealings in +# this Software without prior written authorization from Xilinx. +# +############################################################################### +# +# MODIFICATION HISTORY: +# Ver Who Date Changes +# -------- ------ -------- -------------------------------------------------- +# 3.0 adk 10/12/13 Removed support for xps_uart16550 +############################################################################## +## @BEGIN_CHANGELOG EDK_L +## Deprecated the CLOCK_HZ parameter in mdd and updated the Tcl to obtain the +## bus frequency during libgen. +## +## @END_CHANGELOG + +## @BEGIN_CHANGELOG EDK_M +## 17/11/09 ktn removed support for opb_uart16550 plb_uart16550 +## +## @END_CHANGELOG + +## @BEGIN_CHANGELOG EDK_MS3 +## +## 06/16/10 sv Added support for axi_uart16550 +## +## @END_CHANGELOG + +OPTION psf_version = 2.1; + +BEGIN driver uartns550 + + OPTION supported_peripherals = (axi_uart16550); + OPTION driver_state = ACTIVE; + OPTION copyfiles = all; + OPTION VERSION = 3.3; + OPTION NAME = uartns550; + + PARAM name = CLOCK_HZ, state = DEPRECATED, desc = "Clock Frequency in Hz. This parameter is deprecated. The driver uses the bus frequency from mhs", type = int, default = 66000000; + + BEGIN INTERFACE stdin + PROPERTY header = xuartns550_l.h; + FUNCTION name = inbyte, value = XUartNs550_RecvByte; + END INTERFACE + + BEGIN INTERFACE stdout + PROPERTY header = xuartns550_l.h; + FUNCTION name = outbyte, value = XUartNs550_SendByte; + END INTERFACE + + BEGIN INTERFACE stdio + PROPERTY header = xuartns550_l.h; + FUNCTION name = inbyte, value = XUartNs550_RecvByte; + FUNCTION name = outbyte, value = XUartNs550_SendByte; + END INTERFACE + +END driver diff --git a/XilinxProcessorIPLib/drivers/uartns550/data/uartns550.tcl b/XilinxProcessorIPLib/drivers/uartns550/data/uartns550.tcl new file mode 100755 index 00000000..880f738b --- /dev/null +++ b/XilinxProcessorIPLib/drivers/uartns550/data/uartns550.tcl @@ -0,0 +1,271 @@ +############################################################################### +# +# Copyright (C) 2004 - 2014 Xilinx, Inc. All rights reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# Use of the Software is limited solely to applications: +# (a) running on a Xilinx device, or +# (b) that interact with a Xilinx device through a bus or interconnect. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# Except as contained in this notice, the name of the Xilinx shall not be used +# in advertising or otherwise to promote the sale, use or other dealings in +# this Software without prior written authorization from Xilinx. +# +############################################################################### +# +# MODIFICATION HISTORY: +# Ver Who Date Changes +# -------- ------ -------- ------------------------------------ +# 3.0 adk 12/10/13 Updated as per the New Tcl API's +# 3.1 adk 20/08/14 Fixed CR:816989 Canonical Definition for Multiple +# Instances of UARTSNS550 have the same Device Id. +# 3.2 adk 15/10/14 Fixed CR:826435 external clock speed is not +# being updated with proper value in xparametrs.h file. +############################################################################## +## @BEGIN_CHANGELOG EDK_L +## Deprecated the CLOCK_HZ parameter in mdd and updated the Tcl to obtain the +## bus frequency during libgen. +## +## @END_CHANGELOG +## +## @BEGIN_CHANGELOG EDK_LS3 +## Updated to obtain external clock frequency from either the port "xin" or +## the new parameter C_EXTERNAL_XIN_CLK_HZ (if frequecy can't be read from xin) +## when C_HAS_EXTERNAL_XIN is set to 1 +## +## @END_CHANGELOG + + +proc generate {drv_handle} { + xdefine_include_file $drv_handle "xparameters.h" "XUartNs550" "NUM_INSTANCES" "DEVICE_ID" "C_BASEADDR" "C_HIGHADDR" "CLOCK_FREQ_HZ" + xdefine_config_file $drv_handle "xuartns550_g.c" "XUartNs550" "DEVICE_ID" "C_BASEADDR" "CLOCK_FREQ_HZ" + + xdefine_canonical_xpars $drv_handle "xparameters.h" "UartNs550" "DEVICE_ID" "C_BASEADDR" "C_HIGHADDR" "CLOCK_FREQ_HZ" +} + + +# +# Given a list of arguments, define them all in an include file. +# Handles mpd and mld parameters, as well as the special parameters NUM_INSTANCES, +# DEVICE_ID +# +proc xdefine_include_file {drv_handle file_name drv_string args} { + # Open include file + set file_handle [::hsi::utils::open_include_file $file_name] + + # Get all peripherals connected to this driver + set periphs [::hsi::utils::get_common_driver_ips $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 [common::get_property NAME $drv_handle]] */" + # Define NUM_INSTANCES + puts $file_handle "#define [::hsi::utils::get_driver_param_name $drv_string $arg] [llength $periphs]" + set args [lreplace $args $posn $posn] + } + + # define XPAR_XUARTNS550_CLOCK_HZ as bus freq of the + # 1st instance of the core, for backward compatability + set arg "CLOCK_HZ" + set periph [lindex $periphs 0] + set freq [xget_freq $periph] + if {[llength $freq] == 0} { + set freq [common::get_property CONFIG.C_S_AXI_ACLK_FREQ_HZ $periph] + if {[llength $freq] == 0} { + set freq "100000000" + } + } + puts $file_handle "#define [format "%s" [::hsi::utils::get_driver_param_name $drv_string $arg]] $freq" + + # Print all parameters for all peripherals + set device_id 0 + foreach periph $periphs { + set periph_name [string toupper [common::get_property NAME $periph]] + set freq [xget_freq $periph] + + puts $file_handle "" + puts $file_handle "/* Definitions for peripheral $periph_name */" + foreach arg $args { + + if {[string compare -nocase "DEVICE_ID" $arg] == 0} { + set value $device_id + incr device_id + } elseif {[string compare -nocase "CLOCK_FREQ_HZ" $arg] == 0} { + if {[llength $freq] == 0} { + set freq [common::get_property CONFIG.C_S_AXI_ACLK_FREQ_HZ $periph] + if {[llength $freq] == 0} { + set freq "100000000" + puts "WARNING: Clock frequency information is not available in the design, \ + for peripheral $periph_name. Assuming a default frequency of 100MHz. \ + If this is incorrect, the peripheral $periph_name will be non-functional. \ + See AR 33102 for a solution to work around this problem\n" + } + } + set value $freq + } else { + set value [common::get_property CONFIG.$arg $periph] + } + if {[llength $value] == 0} { + set value 0 + } + set value [::hsi::utils::format_addr_string $value $arg] + puts $file_handle "#define [::hsi::utils::get_ip_param_name $periph $arg] $value" + } + puts $file_handle "" + } + puts $file_handle "\n/******************************************************************/\n" + close $file_handle +} + + +# +# Create configuration C file as required by Xilinx driver +# +proc xdefine_config_file {drv_handle file_name drv_string args} { + set filename [file join "src" $file_name] + file delete $filename + set config_file [open $filename w] + ::hsi::utils::write_c_header $config_file "Driver configuration" + puts $config_file "#include \"xparameters.h\"" + puts $config_file "#include \"[string tolower $drv_string].h\"" + puts $config_file "\n/*" + puts $config_file " * The configuration table for devices" + puts $config_file " */\n" + puts $config_file [format "%s_Config %s_ConfigTable\[\] =" $drv_string $drv_string] + puts $config_file "\{" + set periphs [::hsi::utils::get_common_driver_ips $drv_handle] + set start_comma "" + set device_id 0 + foreach periph $periphs { + puts $config_file [format "%s\t\{" $start_comma] + set comma "" + set canonical_name [format "%s_%s" "UartNs550" $device_id] + + foreach arg $args { + puts -nonewline $config_file [format "%s\t\t%s" $comma [::hsi::utils::get_driver_param_name $canonical_name $arg]] + set comma ",\n" + } + puts -nonewline $config_file "\n\t\}" + set start_comma ",\n" + incr device_id + } + puts $config_file "\n\};" + + puts $config_file "\n"; + + close $config_file +} + + +# +# 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} { + # Open include file + set file_handle [::hsi::utils::open_include_file $file_name] + + # Get all the peripherals connected to this driver + set periphs [::hsi::utils::get_common_driver_ips $drv_handle] + + # Get the names of all the peripherals connected to this driver + foreach periph $periphs { + set peripheral_name [string toupper [common::get_property NAME $periph]] + lappend peripherals $peripheral_name + } + + # Get possible canonical names for all the peripherals connected to this driver + set device_id 0 + foreach periph $periphs { + set canonical_name [string toupper [format "%s_%s" $drv_string $device_id]] + lappend canonicals $canonical_name + + # Create a list of IDs of the peripherals whose hardware instance name + # doesn't match the canonical name. These IDs can be used later to + # generate canonical definitions + if { [lsearch $peripherals $canonical_name] < 0 } { + lappend indices $device_id + } + incr device_id + } + + set i 0 + set device_id 0 + foreach periph $periphs { + set periph_name [string toupper [common::get_property NAME $periph]] + + # Generate canonical definitions only for the peripherals whose + # canonical name is not the same as hardware instance name + if { [lsearch $canonicals $periph_name] < 0 } { + puts $file_handle "/* Canonical definitions for peripheral $periph_name */" + set canonical_name [format "%s_%s" $drv_string [lindex $indices $i]] + + foreach arg $args { + set lvalue [::hsi::utils::get_driver_param_name $canonical_name $arg] + + #handle CLOCK_FREQ_HZ as a special case + if {[string compare -nocase "CLOCK_FREQ_HZ" $arg] == 0} { + set rvalue [::hsi::utils::get_ip_param_name $periph $arg] + } elseif {[string compare -nocase "DEVICE_ID" $arg] == 0} { + set rvalue $device_id + incr device_id + } else { + set rvalue [common::get_property CONFIG.$arg $periph] + if {[llength $rvalue] == 0} { + set rvalue 0 + } + set rvalue [::hsi::utils::format_addr_string $rvalue $arg] + } + + puts $file_handle "#define $lvalue $rvalue" + } + + puts $file_handle "" + incr i + } + } + + puts $file_handle "\n/******************************************************************/\n" + close $file_handle +} + + +# Returns the frequency of the UartNs550 peripheral +proc xget_freq {periph} { + set freq "" + + # Check if the device uses external XIN + set use_xin_clk [common::get_property CONFIG.C_HAS_EXTERNAL_XIN $periph] + if { $use_xin_clk == "1" } { + set port_name "xin" + } + + set freq [::hsi::utils::get_clk_pin_freq $periph "S_AXI_ACLK"] + + # If the clock frequency can not be obtained from "xin" port, + # read the value of the parameter C_EXTERNAL_XIN_CLK_HZ to get + # the frequency + if { $use_xin_clk == "1" } { + set freq [common::get_property CONFIG.C_EXTERNAL_XIN_CLK_HZ $periph] + } + return $freq +} diff --git a/XilinxProcessorIPLib/drivers/uartns550/data/uartns550_header.h b/XilinxProcessorIPLib/drivers/uartns550/data/uartns550_header.h new file mode 100644 index 00000000..d3efee41 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/uartns550/data/uartns550_header.h @@ -0,0 +1,42 @@ +/****************************************************************************** +* +* Copyright (C) 2005 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* Use of the Software is limited solely to applications: +* (a) running on a Xilinx device, or +* (b) that interact with a Xilinx device through a bus or interconnect. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +#ifndef UARTNS550_HEADER_H /* prevent circular inclusions */ +#define UARTNS550_HEADER_H /* by using protection macros */ + + +#include "xil_types.h" +#include "xil_assert.h" +#include "xstatus.h" + +int UartNs550SelfTestExample(u16 DeviceId); + +#endif diff --git a/XilinxProcessorIPLib/drivers/uartns550/data/uartns550_intr_header.h b/XilinxProcessorIPLib/drivers/uartns550/data/uartns550_intr_header.h new file mode 100644 index 00000000..67e395bb --- /dev/null +++ b/XilinxProcessorIPLib/drivers/uartns550/data/uartns550_intr_header.h @@ -0,0 +1,51 @@ +/****************************************************************************** +* +* Copyright (C) 2005 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* Use of the Software is limited solely to applications: +* (a) running on a Xilinx device, or +* (b) that interact with a Xilinx device through a bus or interconnect. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +#ifndef UARTNS550_INTR_HEADER_H /* prevent circular inclusions */ +#define UARTNS550_INTR_HEADER_H /* by using protection macros */ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xstatus.h" + +#ifdef XPAR_INTC_0_DEVICE_ID +int UartNs550IntrExample(XIntc* IntcInstancePtr, \ + XUartNs550* UartLiteInstancePtr, \ + u16 UartNs550DeviceId, \ + u16 UartNs550IntrId); +#else +int UartNs550IntrExample(XScuGic* IntcInstancePtr, \ + XUartNs550* UartLiteInstancePtr, \ + u16 UartNs550DeviceId, \ + u16 UartNs550IntrId); + +#endif +#endif diff --git a/XilinxProcessorIPLib/drivers/uartns550/data/uartns550_tapp.tcl b/XilinxProcessorIPLib/drivers/uartns550/data/uartns550_tapp.tcl new file mode 100755 index 00000000..8a2a14f1 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/uartns550/data/uartns550_tapp.tcl @@ -0,0 +1,271 @@ +############################################################################### +# +# Copyright (C) 2004 - 2014 Xilinx, Inc. All rights reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# Use of the Software is limited solely to applications: +# (a) running on a Xilinx device, or +# (b) that interact with a Xilinx device through a bus or interconnect. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# Except as contained in this notice, the name of the Xilinx shall not be used +# in advertising or otherwise to promote the sale, use or other dealings in +# this Software without prior written authorization from Xilinx. +# +############################################################################### +# +# MODIFICATION HISTORY: +# Ver Who Date Changes +# -------- ------ -------- ------------------------------------ +# 3.0 adk 12/10/13 Updated as per the New Tcl API's +############################################################################## + +## @BEGIN_CHANGELOG EDK_M +## +## 19/11/09 ktn Replaced the call to XUartNs550_mSetLineControlReg +## with a call to XUartNs550_SetLineControlReg as the +## name of these macros has changed. +## +## @END_CHANGELOG + +## @BEGIN_CHANGELOG EDK_Im_SP2 +## +## - Added Interrupt support +## +## @END_CHANGELOG + + +## @BEGIN_CHANGELOG EDK_I +## +## - include header files +## +## @END_CHANGELOG + +## @BEGIN_CHANGELOG EDK_H +## +## - Added support for generation of multiple applications. +## All TCL procedures are now required to have a software +## project type as its first argument +## +## @END_CHANGELOG + +# 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 "xuartns550_l.h" + } + if {$swproj == 1} { + set stdout [common::get_property CONFIG.STDOUT [hsi::get_os]] + set isStdout [string match $stdout $mhsinst] + if {${isStdout} == 0} { + set ifuartns550intr [::hsi::utils::is_ip_interrupting_current_proc $mhsinst] + if {$ifuartns550intr == 1} { + set inc_file_lines {xuartns550_l.h uartns550_header.h xuartns550.h uartns550_intr_header.h} + } else { + set inc_file_lines {xuartns550_l.h uartns550_header.h} + } + } else { + set inc_file_lines {xuartns550_l.h} + } + + return $inc_file_lines + } +} + +proc gen_src_files {swproj mhsinst} { + if {$swproj == 0} { + return "" + } + if {$swproj == 1} { + set stdout [common::get_property CONFIG.STDOUT [hsi::get_os]] + set isStdout [string match $stdout $mhsinst] + if {${isStdout} == 0} { + set ifuartns550intr [::hsi::utils::is_ip_interrupting_current_proc $mhsinst] + if {$ifuartns550intr == 1} { + set inc_file_lines {examples/xuartns550_selftest_example.c examples/xuartns550_intr_example.c data/uartns550_header.h data/uartns550_intr_header.h} + } else { + set inc_file_lines {examples/xuartns550_selftest_example.c data/uartns550_header.h} + } + return $inc_file_lines + } + } + return "" +} + +proc gen_testfunc_def {swproj mhsinst} { + return "" +} + +proc gen_init_code {swproj mhsinst} { + + set stdout [common::get_property CONFIG.STDOUT [hsi::get_os]] + set isStdout [string match $stdout $mhsinst] + if {${isStdout} == 0} { + if {$swproj == 1} { + set ipname [common::get_property NAME $mhsinst] + set ifuartns550intr [::hsi::utils::is_ip_interrupting_current_proc $mhsinst] + if {$ifuartns550intr == 1} { + set decl " static XUartNs550 ${ipname}_UartNs550;" + set inc_file_lines $decl + return $inc_file_lines + } else { + return "" + } + } + return "" + } + + set clockhz [::hsi::utils::get_driver_param_name "XUartNs550" "CLOCK_HZ"] + set baseaddr [::hsi::utils::get_ip_param_name $mhsinst "BASEADDR"] + set ipname [common::get_property NAME $mhsinst] + + append testfunc_call " + /* Initialize ${ipname} - Set baudrate and number of stop bits */ + XUartNs550_SetBaud(${baseaddr}, ${clockhz}, 9600); + XUartNs550_SetLineControlReg(${baseaddr}, XUN_LCR_8_DATA_BITS);" + + return $testfunc_call +} + +proc gen_testfunc_call {swproj mhsinst} { + + set ipname [common::get_property NAME $mhsinst] + set ifuartns550intr [::hsi::utils::is_ip_interrupting_current_proc $mhsinst] + set testfunc_call "" + + if {$swproj == 0} { + return $testfunc_call + } + + set stdout [common::get_property CONFIG.STDOUT [hsi::get_os]] + set isStdout [string match $stdout $mhsinst] + if {${isStdout} == 1} { + append testfunc_call " + /* + * Peripheral SelfTest will not be run for ${ipname} + * because it has been selected as the STDOUT device + */ +" + return $testfunc_call + } + + set deviceid [::hsi::utils::get_ip_param_name $mhsinst "DEVICE_ID"] + set stdout [common::get_property CONFIG.STDOUT [hsi::get_os]] + if { $stdout == "" || $stdout == "none" } { + set hasStdout 0 + } else { + set hasStdout 1 + } + if {$ifuartns550intr == 1} { + set intr_pin_name [hsi::get_pins -of_objects [hsi::get_cells $ipname] -filter "TYPE==INTERRUPT"] + set intcname [::hsi::utils::get_connected_intr_cntrl $ipname $intr_pin_name] + set intcvar intc + set proc [common::get_property IP_NAME [hsi::get_cells [hsi::get_sw_processor]]] + } + + if {${hasStdout} == 0} { + + append testfunc_call " + + { + XStatus status; + + status = UartNs550SelfTestExample(${deviceid}); + }" + if {$ifuartns550intr == 1} { + if { + $proc == "microblaze" + } then { + set intr_id "XPAR_${intcname}_${ipname}_${intr_pin_name}_INTR" + } else { + set intr_id "XPAR_FABRIC_${ipname}_${intr_pin_name}_INTR" + } + set intr_id [string toupper $intr_id] + + append testfunc_call " + + { + XStatus Status; + Status = UartNs550IntrExample(&${intcvar}, &${ipname}_UartNs550, \\ + ${deviceid}, \\ + ${intr_id}); + }" + + } + + } else { + + append testfunc_call " + + { + XStatus status; + + print(\"\\r\\nRunning UartNs550SelfTestExample() for ${ipname}...\\r\\n\"); + status = UartNs550SelfTestExample(${deviceid}); + if (status == 0) { + print(\"UartNs550SelfTestExample PASSED\\r\\n\"); + } + else { + print(\"UartNs550SelfTestExample FAILED\\r\\n\"); + } + }" + + if {$ifuartns550intr == 1} { + if { + $proc == "microblaze" + } then { + set intr_id "XPAR_${intcname}_${ipname}_${intr_pin_name}_INTR" + } else { + set intr_id "XPAR_FABRIC_${ipname}_${intr_pin_name}_INTR" + } + set intr_id [string toupper $intr_id] + + append testfunc_call " + { + XStatus Status; + + print(\"\\r\\n Running Interrupt Test for ${ipname}...\\r\\n\"); + + Status = UartNs550IntrExample(&${intcvar}, &${ipname}_UartNs550, \\ + ${deviceid}, \\ + ${intr_id}); + + if (Status == 0) { + print(\"UartNs550 Interrupt Test PASSED\\r\\n\"); + } + else { + print(\"UartNs550 Interrupt Test FAILED\\r\\n\"); + } + + }" + } + } + return $testfunc_call +} diff --git a/XilinxProcessorIPLib/drivers/uartns550/examples/index.html b/XilinxProcessorIPLib/drivers/uartns550/examples/index.html new file mode 100755 index 00000000..4116fe19 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/uartns550/examples/index.html @@ -0,0 +1,21 @@ + + +
+ + +Copyright � 1995-2014 Xilinx, Inc. All rights reserved.
+ + diff --git a/XilinxProcessorIPLib/drivers/uartns550/examples/xuartns550_hello_world_example.c b/XilinxProcessorIPLib/drivers/uartns550/examples/xuartns550_hello_world_example.c new file mode 100644 index 00000000..072fe749 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/uartns550/examples/xuartns550_hello_world_example.c @@ -0,0 +1,155 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* Use of the Software is limited solely to applications: +* (a) running on a Xilinx device, or +* (b) that interact with a Xilinx device through a bus or interconnect. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/******************************************************************************/ +/** +* +* @file xuartns550_hello_world_example.c +* +* This file contains a design example using the Uart 16450/550 driver +* (XUartNs550) and hardware device using polled mode. +* +* @note None. +* +* MODIFICATION HISTORY: +*+* Ver Who Date Changes +* ----- ---- -------- --------------------------------------------------------- +* 1.00a jhl 05/13/02 First release +* 1.00a sv 06/08/05 Minor changes to comply to Doxygen and coding guidelines +* 2.00a ktn 10/20/09 Updated to use HAL processor APIs and minor modifications +* as per coding guidelines. +*+******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xparameters.h" +#include "xuartns550.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 UART_DEVICE_ID XPAR_UARTNS550_0_DEVICE_ID + + +/**************************** Type Definitions *******************************/ + + +/***************** Macros (Inline Functions) Definitions *********************/ + + +/************************** Function Prototypes ******************************/ + +int UartNs550HelloWorldExample(u16 DeviceId); + +/************************** Variable Definitions *****************************/ + +XUartNs550 UartNs550; /* The instance of the UART Driver */ + +/*****************************************************************************/ +/** +* Main function to call the example. +* +* @param None. +* +* @return +* - XST_FAILURE if the Test Failed. +* - A non-negative number indicating the number of +* characters sent. +* +* @note None. +* +******************************************************************************/ +int main(void) +{ + int Status; + + /* + * Run the UartNs550 example, specify the the Device ID that is + * generated in xparameters.h + */ + Status = UartNs550HelloWorldExample(UART_DEVICE_ID); + + return Status; +} + + +/******************************************************************************/ +/** +* +* This function sends Hello World with the UART 16450/550 device and driver as +* a design example. The purpose of this function is to illustrate how to use +* the XUartNs550 driver. +* +* This function polls the UART and does not require the use of interrupts. +* +* @param DeviceId is the XPAR_
+* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- ---------------------------------------------------------- +* 1.00b jhl 02/13/02 First release +* 1.00b sv 06/08/05 Minor changes to comply to Doxygen and coding guidelines +* 1.01a sv 05/08/06 Minor changes for supporting Test App Interrupt examples +* 2.00a ktn 10/20/09 Updated to use HAL processor APIs and minor modifications +* as per coding guidelines. +* 2.01a ssb 01/11/01 Updated the example to be used with the SCUGIC in +* Zynq. +* 3.2 adk 15/10/14 Clear the global counters.If multiple instance of ip is +* present in the h/w design without clearing these counters +* will result undefined behaviour for the second ip +* instance while running the peripheral tests. +*+******************************************************************************/ + +/***************************** Include Files **********************************/ + +#include "xparameters.h" +#include "xuartns550.h" +#include "xil_exception.h" + +#ifdef XPAR_INTC_0_DEVICE_ID +#include "xintc.h" +#include
+* Ver Who Date Changes +* ----- ---- -------- --------------------------------------------------------- +* 1.00b rpm 04/25/02 First release +* 1.00b sv 06/08/05 Minor changes to comply to Doxygen and coding guidelines +* 2.00a ktn 10/20/09 Updated to use HAL processor APIs, minor modifications +* as per coding guidelines and macros have been renamed to +* remove _m from the name. +*+******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xparameters.h" +#include "xstatus.h" +#include "xuartns550_l.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 UART_BASEADDR XPAR_UARTNS550_0_BASEADDR +#define UART_CLOCK_HZ XPAR_UARTNS550_0_CLOCK_FREQ_HZ +/* + * The following constant controls the length of the buffers to be sent + * and received with the UART, this constant must be 16 bytes or less so the + * entire buffer will fit into the transmit and receive FIFOs of the UART + */ +#define TEST_BUFFER_SIZE 16 + + +#define UART_BAUDRATE 19200 /* Baud Rate */ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +int XUartNs550_LowLevelExample(u32 UartBaseAddress); + +/************************** Variable Definitions *****************************/ + +/* + * The following buffers are used in this example to send and receive data + * with the UART. + */ +u8 SendBuffer[TEST_BUFFER_SIZE]; /* Buffer for Transmitting Data */ +u8 RecvBuffer[TEST_BUFFER_SIZE]; /* Buffer for Receiving Data */ + + +/*****************************************************************************/ +/** +* +* Main function to call the example. +* +* @param None. +* +* @return XST_SUCCESS if successful, XST_FAILURE if unsuccessful. +* +* @note None. +* +******************************************************************************/ +int main(void) +{ + int Status; + + /* + * Run the UartNs550 Low Level example, specify the Base Address that + * is generated in xparameters.h + */ + Status = XUartNs550_LowLevelExample(UART_BASEADDR); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + return XST_SUCCESS; +} + +/****************************************************************************/ +/** +* +* This function does a minimal test on the UART device using the low-level +* driver macros and functions. This function sends data and expects to receive +* the data thru the UART. A physical loopback must be done by the user with the +* tranmit and receive signals of the UART. +* +* @param UartBaseAddress is the base address of the UARTNS550 device +* and is the XPAR_
+* Ver Who Date Changes +* ----- ---- -------- ----------------------------------------------- +* 1.00a jhl 02/13/02 First release +* 1.00b ecm 01/25/05 Modified for TestApp integration, updated boilerplate. +* 1.00b sv 06/08/05 Minor changes to comply to Doxygen and coding guidelines +* 2.00a ktn 10/20/09 Updated to use HAL processor APIs and minor modifications +* as per coding guidelines. +* Updated this example to wait for valid data in receive +* fifo instead of Tx fifo empty to update receive buffer +*+******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xparameters.h" +#include "xuartns550.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 UART_DEVICE_ID XPAR_UARTNS550_0_DEVICE_ID + +/* + * The following constant controls the length of the buffers to be sent + * and received with the UART, this constant must be 16 bytes or less since + * this is a single threaded non-interrupt driven example such that the + * entire buffer will fit into the transmit and receive FIFOs of the UART + */ +#define TEST_BUFFER_SIZE 16 + +/**************************** Type Definitions *******************************/ + + +/***************** Macros (Inline Functions) Definitions *********************/ + + +/************************** Function Prototypes ******************************/ + +int UartNs550PolledExample(u16 DeviceId); + +/************************** Variable Definitions *****************************/ + +XUartNs550 UartNs550; /* Instance of the UART Device */ + +/* + * The following buffers are used in this example to send and receive data + * with the UART. + */ +u8 SendBuffer[TEST_BUFFER_SIZE]; /* Buffer for Transmitting Data */ +u8 RecvBuffer[TEST_BUFFER_SIZE]; /* Buffer for Receiving Data */ + + +/*****************************************************************************/ +/** +* +* Main function to call the example. This function is not included if the +* example is generated from the TestAppGen test tool. +* +* @param None. +* +* @return XST_SUCCESS if succesful, otherwise XST_FAILURE. +* +* @note None. +* +******************************************************************************/ +#ifndef TESTAPP_GEN +int main(void) +{ + int Status; + + + /* + * Run the UartNs550 polled example , specify the the Device ID that is + * generated in xparameters.h + */ + Status = UartNs550PolledExample(UART_DEVICE_ID); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + return XST_SUCCESS; + +} +#endif + +/*****************************************************************************/ +/** +* +* This function does a minimal test on the UART 16450/550 device and driver as a +* design example. The purpose of this function is to illustrate how to use +* the XUartNs550 component. +* +* This function sends data and expects to receive the data thru the UART +* using the local loopback mode of the UART hardware. +* +* This function polls the UART and does not require the use of interrupts. +* +* @param DeviceId is the XPAR_
+* Ver Who Date Changes +* ----- ---- -------- ----------------------------------------------- +* 1.00a sv 10/07/05 Created for Test App integration +* 2.00a ktn 10/20/09 Updated to use HAL processor APIs and minor modifications +* as per coding guidelines. +*+******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xparameters.h" +#include "xuartns550.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. + */ +#ifndef TESTAPP_GEN +#define UART_DEVICE_ID XPAR_UARTNS550_0_DEVICE_ID +#endif + +/**************************** Type Definitions *******************************/ + + +/***************** Macros (Inline Functions) Definitions *********************/ + + +/************************** Function Prototypes ******************************/ + +int UartNs550SelfTestExample(u16 DeviceId); + +/************************** Variable Definitions *****************************/ + +XUartNs550 UartNs550; /* Instance of the UART Device */ + +/*****************************************************************************/ +/** +* +* Main function to call the example. This function is not included if the +* example is generated from the TestAppGen test tool. +* +* @param None. +* +* @return XST_SUCCESS if succesful, otherwise XST_FAILURE. +* +* @note None. +* +******************************************************************************/ +#ifndef TESTAPP_GEN +int main(void) +{ + int Status; + + /* + * Run the UartNs550 selftest example + */ + Status = UartNs550SelfTestExample(UART_DEVICE_ID); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + return XST_SUCCESS; + +} +#endif + +/*****************************************************************************/ +/** +* +* This function does a minimal test on the UartNs550 device and driver as a +* design example. The purpose of this function is to illustrate how to use the +* XUartNs550 component. +* +* +* @param DeviceId is the XPAR_
+* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- ----------------------------------------------- +* 1.00a ecm 08/16/01 First release +* 1.00b jhl 03/11/02 Repartitioned driver for smaller files. +* 1.00b rmm 05/14/03 Fixed diab compiler warnings relating to asserts. +* 1.01a jvb 12/13/05 I changed Initialize() into CfgInitialize(), and made +* CfgInitialize() take a pointer to a config structure +* instead of a device id. I moved Initialize() into +* xgpio_sinit.c, and had Initialize() call CfgInitialize() +* after it retrieved the config structure using the device +* id. I removed include of xparameters.h along with any +* dependencies on xparameters.h and the _g.c config table. +* 1.11a sv 03/20/07 Updated to use the new coding guidelines. +* 2.00a ktn 10/20/09 Converted all register accesses to 32 bit access. +* Updated to use HAL Processor APIs. _m is removed from the +* name of all the macro definitions. XUartNs550_mClearStats +* macro is removed, XUartNs550_ClearStats function should be +* used in its place. +* 2.01a bss 01/13/12 Removed unneccessary read of the LCR register in the +* XUartNs550_CfgInitialize function. Removed compiler +* warnings for unused variables in the +* XUartNs550_StubHandler. +*+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ + +#include "xstatus.h" +#include "xuartns550.h" +#include "xuartns550_i.h" +#include "xil_io.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 ********************/ + + +/************************** Variable Definitions ****************************/ + + +/************************** Function Prototypes *****************************/ + +static void XUartNs550_StubHandler(void *CallBackRef, u32 Event, + unsigned int ByteCount); + +/****************************************************************************/ +/** +* +* Initializes a specific XUartNs550 instance such that it is ready to be used. +* The data format of the device is setup for 8 data bits, 1 stop bit, and no +* parity by default. The baud rate is set to a default value specified by +* Config->DefaultBaudRate if set, otherwise it is set to 19.2K baud. If the +* device has FIFOs (16550), they are enabled and the a receive FIFO threshold +* is set for 8 bytes. The default operating mode of the driver is polled mode. +* +* @param InstancePtr is a pointer to the XUartNs550 instance. +* @param Config is a reference to a structure containing information +* about a specific UART 16450/16550 device. XUartNs550_Init +* initializes an InstancePtr object for a specific device +* specified by the contents f Config. XUartNs550_Init can +* initialize multiple instance objects with the use of multiple +* calls giving different Config information on each call. +* @param EffectiveAddr is the device base address in the virtual memory +* address space. The caller is responsible for keeping the +* address mapping from EffectiveAddr to the device physical base +* address unchanged once this function is invoked. Unexpected +* errors may occur if the address mapping changes after this +* function is called. If address translation is not used, +* use Config->BaseAddress for this parameters, passing the +* physical address instead. +* +* @return +* - XST_SUCCESS if initialization was successful. +* - XST_UART_BAUD_ERROR if the baud rate is not possible because +* the input clock frequency is not divisible with an acceptable +* amount of error. +* +* @note None. +* +*****************************************************************************/ +int XUartNs550_CfgInitialize(XUartNs550 *InstancePtr, + XUartNs550_Config *Config, + u32 EffectiveAddr) +{ + int Status; + u32 BaudRate; + + /* + * Assert validates the input arguments + */ + Xil_AssertNonvoid(InstancePtr != NULL); + + /* + * Setup the data that is from the configuration information + */ + InstancePtr->BaseAddress = EffectiveAddr; + InstancePtr->InputClockHz = Config->InputClockHz; + + /* + * Initialize the instance data to some default values and setup + * a default handler + */ + InstancePtr->Handler = XUartNs550_StubHandler; + + InstancePtr->SendBuffer.NextBytePtr = NULL; + InstancePtr->SendBuffer.RemainingBytes = 0; + InstancePtr->SendBuffer.RequestedBytes = 0; + + InstancePtr->ReceiveBuffer.NextBytePtr = NULL; + InstancePtr->ReceiveBuffer.RemainingBytes = 0; + InstancePtr->ReceiveBuffer.RequestedBytes = 0; + + /* + * Indicate the instance is now ready to use, initialized without error + */ + InstancePtr->IsReady = XIL_COMPONENT_IS_READY; + + /* + * Set the default Baud rate here, can be changed prior to + * starting the device + */ + BaudRate = Config->DefaultBaudRate; + if (! BaudRate) { + BaudRate = 19200; + } + + Status = XUartNs550_SetBaudRate(InstancePtr, BaudRate); + if (Status != XST_SUCCESS) { + InstancePtr->IsReady = 0; + return Status; + } + + + /* + * Set up the default format for the data, 8 bit data, 1 stop bit, + * no parity + */ + XUartNs550_SetLineControlReg(InstancePtr->BaseAddress, + XUN_FORMAT_8_BITS); + + /* + * Enable the FIFOs assuming they are present and set the receive FIFO + * trigger level for 8 bytes assuming that this will work best with most + * baud rates, enabling the FIFOs also clears them, note that this must + * be done with 2 writes, 1st enabling the FIFOs then set the trigger + * level + */ + XUartNs550_WriteReg(InstancePtr->BaseAddress, + XUN_FCR_OFFSET, XUN_FIFO_ENABLE); + XUartNs550_WriteReg(InstancePtr->BaseAddress, XUN_FCR_OFFSET, + XUN_FIFO_ENABLE | XUN_FIFO_RX_TRIG_MSB); + /* + * Clear the statistics for this driver + */ + XUartNs550_ClearStats(InstancePtr); + + return XST_SUCCESS; +} + +/****************************************************************************/ +/** +* +* 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, either in the transmitter or in the FIFO if present and enabled. 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 XUartNs550 instance. +* @param BufferPtr 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. +*
+* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- ----------------------------------------------- +* 1.00a ecm 08/16/01 First release +* 1.00b jhl 03/11/02 Repartitioned the driver for smaller files. +* 1.01a jvb 12/14/05 I separated dependency on the static config table and +* xparameters.h from the driver initialization by moving +* _Initialize and _LookupConfig to _sinit.c. I also added +* the new _CfgInitialize routine. +* 1.11a sv 03/20/07 Updated to use the new coding guidelines. +* 1.11a sv 07/25/08 Corrected the definitions of XUN_MODEM_DCD_DELTA_MASK +* and XUN_MODEM_DCD_MASK. +* 1.12a sdm 08/22/08 Removed support for static interrupt handlers from the MDD +* file +* 1.12a sdm 12/15/08 Deprecated the CLOCK_HZ parameter in mdd and updated the +* Tcl to obtain the bus frequency during libgen +* 1.13a sdm 07/10/09 a) Updated the driver Tcl to obtain the external clock +* frequency from MHS, when C_HAS_EXTERNAL_XIN = 1. +* b) Added receive line interrupt option to OptionsTable[] +* in xuartns550_options.c +* 2.00a ktn 10/20/09 Converted all register accesses to 32 bit access. +* Updated to use HAL Processor APIs. _m is removed from the +* name of all the macro definitions. XUartNs550_mClearStats +* macro is removed, XUartNs550_ClearStats function should be +* used in its place. +* 2.01a bss 01/13/12 Updated the XUartNs550_SelfTest to use Xil_AssertNonvoid +* in place of XASSERT_NONVOID for CR 641344. +* Removed unneccessary read of the LCR register in the +* XUartNs550_CfgInitialize function. Removed compiler +* warnings for unused variables in the +* XUartNs550_StubHandler. +* 2.02a adk 09/16/13 Fixed CR:735289 changes are made in the xuartns550_intr.c +* file. +* 3.0 adk 19/12/13 Updated as per the New Tcl API's +* 3.1 adk 20/08/14 Fixed CR:816989 Canonical Definition for Multiple +* Instances of UARTSNS550 have the same Device Id. +* Changes are made in the driver tcl file. +* 3.2 adk 15/10/14 Fixed CR:824444 changes are made in the example file +* xuartns550_intr_example.c. +* 3.2 adk 15/10/14 Fixed CR:826435 changes are made in the driver tcl file. +*+* +*****************************************************************************/ + +#ifndef XUARTNS550_H /* prevent circular inclusions */ +#define XUARTNS550_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files ********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xstatus.h" +#include "xuartns550_l.h" + +/************************** Constant Definitions ****************************/ + +/* + * The following constants indicate the max and min baud rates and these + * numbers are based only on the testing that has been done. The hardware + * is capable of other baud rates. + */ +#define XUN_NS16550_MAX_RATE 115200 +#define XUN_NS16550_MIN_RATE 300 + +/** @name Configuration options + * @{ + */ +/** + * These constants specify the options that may be set or retrieved + * with the driver, each is a unique bit mask such that multiple options + * may be specified. These constants indicate the function of the option + * when in the active state. + */ +#define XUN_OPTION_RXLINE_INTR 0x0800 /**< Enable status interrupt */ +#define XUN_OPTION_SET_BREAK 0x0400 /**< Set a break condition */ +#define XUN_OPTION_LOOPBACK 0x0200 /**< Enable local loopback */ +#define XUN_OPTION_DATA_INTR 0x0100 /**< Enable data interrupts */ +#define XUN_OPTION_MODEM_INTR 0x0080 /**< Enable modem interrupts */ +#define XUN_OPTION_FIFOS_ENABLE 0x0040 /**< Enable FIFOs */ +#define XUN_OPTION_RESET_TX_FIFO 0x0020 /**< Reset the transmit FIFO */ +#define XUN_OPTION_RESET_RX_FIFO 0x0010 /**< Reset the receive FIFO */ +#define XUN_OPTION_ASSERT_OUT2 0x0008 /**< Assert out2 signal */ +#define XUN_OPTION_ASSERT_OUT1 0x0004 /**< Assert out1 signal */ +#define XUN_OPTION_ASSERT_RTS 0x0002 /**< Assert RTS signal */ +#define XUN_OPTION_ASSERT_DTR 0x0001 /**< Assert DTR signal */ +/*@}*/ + +/** @name Data format values + * @{ + */ +/** + * These constants specify the data format that may be set or retrieved + * with the driver. The data format includes the number of data bits, the + * number of stop bits and parity. + * + */ +#define XUN_FORMAT_8_BITS 3 /**< 8 data bits */ +#define XUN_FORMAT_7_BITS 2 /**< 7 data bits */ +#define XUN_FORMAT_6_BITS 1 /**< 6 data bits */ +#define XUN_FORMAT_5_BITS 0 /**< 5 data bits */ + +#define XUN_FORMAT_EVEN_PARITY 2 /**< Even Parity */ +#define XUN_FORMAT_ODD_PARITY 1 /**< Odd Parity */ +#define XUN_FORMAT_NO_PARITY 0 /**< No Parity */ + +#define XUN_FORMAT_2_STOP_BIT 1 /**< 2 stop bits */ +#define XUN_FORMAT_1_STOP_BIT 0 /**< 1 stop bit */ +/*@}*/ + +/** @name FIFO trigger values + * @{ + */ +/* + * These constants specify receive FIFO trigger levels which specify + * the number of bytes at which a receive data event (interrupt) will occur. + * + */ +#define XUN_FIFO_TRIGGER_14 0xC0 /**< 14 byte trigger level */ +#define XUN_FIFO_TRIGGER_08 0x80 /**< 8 byte trigger level */ +#define XUN_FIFO_TRIGGER_04 0x40 /**< 4 byte trigger level */ +#define XUN_FIFO_TRIGGER_01 0x00 /**< 1 byte trigger level */ +/*@}*/ + +/** @name Modem status values + * @{ + */ +/** + * These constants specify the modem status that may be retrieved + * from the driver. + * + */ +#define XUN_MODEM_DCD_DELTA_MASK 0x08 /**< DCD signal changed state */ +#define XUN_MODEM_DSR_DELTA_MASK 0x02 /**< DSR signal changed state */ +#define XUN_MODEM_CTS_DELTA_MASK 0x01 /**< CTS signal changed state */ +#define XUN_MODEM_RINGING_MASK 0x40 /**< Ring signal is active */ +#define XUN_MODEM_DSR_MASK 0x20 /**< Current state of DSR signal */ +#define XUN_MODEM_CTS_MASK 0x10 /**< Current state of CTS signal */ +#define XUN_MODEM_DCD_MASK 0x80 /**< Current state of DCD signal */ +#define XUN_MODEM_RING_STOP_MASK 0x04 /**< Ringing has stopped */ +/*@}*/ + +/** @name Callback events + * @{ + */ +/** + * These constants specify the handler events that are passed to + * a handler from the driver. These constants are not bit masks such that + * only one will be passed at a time to the handler. + * + */ +#define XUN_EVENT_RECV_DATA 1 /**< Data has been received */ +#define XUN_EVENT_RECV_TIMEOUT 2 /**< A receive timeout occurred */ +#define XUN_EVENT_SENT_DATA 3 /**< Data has been sent */ +#define XUN_EVENT_RECV_ERROR 4 /**< A receive error was detected */ +#define XUN_EVENT_MODEM 5 /**< A change in modem status */ +/*@}*/ + +/** @name Error values + * @{ + */ +/** + * These constants specify the errors that may be retrieved from + * the driver using the XUartNs550_GetLastErrors function. All of them are + * bit masks, except no error, such that multiple errors may be specified. + * + */ +#define XUN_ERROR_BREAK_MASK 0x10 /**< Break detected */ +#define XUN_ERROR_FRAMING_MASK 0x08 /**< Receive framing error */ +#define XUN_ERROR_PARITY_MASK 0x04 /**< Receive parity error */ +#define XUN_ERROR_OVERRUN_MASK 0x02 /**< Receive overrun error */ +#define XUN_ERROR_NONE 0x00 /**< No error */ +/*@}*/ + +/**************************** Type Definitions ******************************/ + +/** + * This typedef contains configuration information for the device. + */ +typedef struct { + u16 DeviceId; /**< Unique ID of device */ + u32 BaseAddress; /**< Base address of device */ + u32 InputClockHz; /**< Input clock frequency */ + u32 DefaultBaudRate; /**< Baud Rate in bps, ie 1200 */ +} XUartNs550_Config; + +/** + * The following data type is used to manage the buffers that are handled + * when sending and receiving data in the interrupt mode. + */ +typedef struct { + u8 *NextBytePtr; + unsigned int RequestedBytes; + unsigned int RemainingBytes; +} XUartNs550Buffer; + +/** + * This data type allows the data format of the device to be set + * and retrieved. + */ +typedef struct { + u32 BaudRate; /**< In bps, ie 1200 */ + u32 DataBits; /**< Number of data bits */ + u32 Parity; /**< Parity */ + u8 StopBits; /**< Number of stop bits */ +} XUartNs550Format; + +/*****************************************************************************/ +/** +* This data type defines a handler which the application must define +* when using interrupt mode. The handler will be called from the driver in an +* interrupt context to handle application specific processing. +* +* @param CallBackRef is a callback reference passed in by the upper layer +* when setting the handler, and is passed back to the upper layer +* when the handler is called. +* @param Event contains one of the event constants indicating why the +* handler is being called. +* @param EventData contains the number of bytes sent or received at +* the time of the call for send and receive events and contains +* the modem status for modem events. +* +*****************************************************************************/ +typedef void (*XUartNs550_Handler)(void *CallBackRef, u32 Event, + unsigned int EventData); + +/** + * UART statistics + */ +typedef struct { + u16 TransmitInterrupts; /**< Number of transmit interrupts */ + u16 ReceiveInterrupts; /**< Number of receive interrupts */ + u16 StatusInterrupts; /**< Number of status interrupts */ + u16 ModemInterrupts; /**< Number of modem interrupts */ + u16 CharactersTransmitted; /**< Number of characters transmitted */ + u16 CharactersReceived; /**< Number of characters received */ + u16 ReceiveOverrunErrors; /**< Number of receive overruns */ + u16 ReceiveParityErrors; /**< Number of receive parity errors */ + u16 ReceiveFramingErrors; /**< Number of receive framing errors */ + u16 ReceiveBreakDetected; /**< Number of receive breaks */ +} XUartNs550Stats; + +/** + * The XUartNs550 driver instance data. The user is required to allocate a + * variable of this type for every UART 16550/16450 device in the system. + * A pointer to a variable of this type is then passed to the driver API + * functions. + */ +typedef struct { + XUartNs550Stats Stats; /**< Statistics */ + u32 BaseAddress; /**< Base address of device */ + u32 InputClockHz; /**< Input clock frequency */ + int IsReady; /**< Device is initialized and ready */ + u32 BaudRate; /**< Current baud rate of hw */ + u8 LastErrors; /**< The accumulated errors */ + + XUartNs550Buffer SendBuffer; /**< Send Buffer */ + XUartNs550Buffer ReceiveBuffer; /**< Receive Buffer */ + + XUartNs550_Handler Handler; /**< Call back handler */ + void *CallBackRef; /* Callback reference for control handler */ +} XUartNs550; + +/***************** Macros (Inline Functions) Definitions ********************/ + +/************************** Function Prototypes *****************************/ + +/* + * Initialization functions in xuartns550_sinit.c + */ +int XUartNs550_Initialize(XUartNs550 *InstancePtr, u16 DeviceId); +XUartNs550_Config *XUartNs550_LookupConfig(u16 DeviceId); + +/* + * Required functions in xuartns550.c + */ +int XUartNs550_CfgInitialize(XUartNs550 *InstancePtr, + XUartNs550_Config *Config, + u32 EffectiveAddr); +unsigned int XUartNs550_Send(XUartNs550 *InstancePtr, u8 *BufferPtr, + unsigned int NumBytes); +unsigned int XUartNs550_Recv(XUartNs550 *InstancePtr, u8 *BufferPtr, + unsigned int NumBytes); + +/* + * Options functions in xuartns550_options.c + */ +int XUartNs550_SetOptions(XUartNs550 *InstancePtr, u16 Options); +u16 XUartNs550_GetOptions(XUartNs550 *InstancePtr); + +int XUartNs550_SetFifoThreshold(XUartNs550 *InstancePtr, + u8 TriggerLevel); +u8 XUartNs550_GetFifoThreshold(XUartNs550 *InstancePtr); + +int XUartNs550_IsSending(XUartNs550 *InstancePtr); + +u8 XUartNs550_GetLastErrors(XUartNs550 *InstancePtr); + +u8 XUartNs550_GetModemStatus(XUartNs550 *InstancePtr); + +/* + * Data format functions in xuartns550_format.c + */ +int XUartNs550_SetDataFormat(XUartNs550 *InstancePtr, + XUartNs550Format *Format); +void XUartNs550_GetDataFormat(XUartNs550 *InstancePtr, + XUartNs550Format *Format); +/* + * Interrupt functions in xuartns550_intr.c + */ +void XUartNs550_SetHandler(XUartNs550 *InstancePtr, XUartNs550_Handler FuncPtr, + void *CallBackRef); + +void XUartNs550_InterruptHandler(XUartNs550 *InstancePtr); + +/* + * Statistics functions in xuartns550_stats.c + */ +void XUartNs550_GetStats(XUartNs550 *InstancePtr, XUartNs550Stats *StatsPtr); +void XUartNs550_ClearStats(XUartNs550 *InstancePtr); + +/* + * Self-test functions in xuartns550_selftest.c + */ +int XUartNs550_SelfTest(XUartNs550 *InstancePtr); + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ diff --git a/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550_format.c b/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550_format.c new file mode 100644 index 00000000..8064e3ba --- /dev/null +++ b/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550_format.c @@ -0,0 +1,271 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* Use of the Software is limited solely to applications: +* (a) running on a Xilinx device, or +* (b) that interact with a Xilinx device through a bus or interconnect. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xuartns550_format.c +* +* This file contains the data format functions for the 16450/16550 UART driver. +* The data format functions allow the baud rate, number of data bits, number +* of stop bits and parity to be set and retrieved. +* +*
+* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- ----------------------------------------------- +* 1.00b jhl 03/11/02 Repartitioned driver for smaller files. +* 1.00b rmm 05/15/03 Fixed diab compiler warnings. +* 1.11a sv 03/20/07 Updated to use the new coding guidelines. +* 2.00a ktn 10/20/09 Converted all register accesses to 32 bit access. +* Updated to use HAL Processor APIs. _m is removed from the +* name of all the macro names/definitions. +*+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ + +#include "xstatus.h" +#include "xuartns550.h" +#include "xuartns550_i.h" +#include "xil_io.h" + +/************************** Constant Definitions ****************************/ + + +/**************************** Type Definitions ******************************/ + + +/***************** Macros (Inline Functions) Definitions ********************/ + + +/************************** Variable Definitions ****************************/ + + +/************************** Function Prototypes *****************************/ + + +/****************************************************************************/ +/** +* +* Sets the data format for the specified UART. The data format includes the +* baud rate, number of data bits, number of stop bits, and parity. It is the +* caller's responsibility to ensure that the UART is not sending or receiving +* data when this function is called. +* +* @param InstancePtr is a pointer to the XUartNs550 instance . +* @param FormatPtr is a pointer to a format structure containing the data +* format to be set. +* +* @return +* +* - XST_SUCCESS if the data format was successfully set. +* - XST_UART_BAUD_ERROR indicates the baud rate could not be set +* because of the amount of error with the baud rate and the input +* clock frequency. +* - XST_INVALID_PARAM if one of the parameters was not valid. +* +* @note +* +* The data types in the format type, data bits and parity, are 32 bit fields +* to prevent a compiler warning that is a bug with the GNU PowerPC compiler. +* The asserts in this function will cause a warning if these fields are +* bytes. +*
+* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- ----------------------------------------------- +* 1.00a ecm 08/16/01 First release +* 1.00b jhl 03/11/02 Repartitioned driver for smaller files. +* 1.11a sv 03/20/07 Updated to use the new coding guidelines. +*+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xuartns550.h" +#include "xparameters.h" + +/************************** Constant Definitions *****************************/ + + +/**************************** Type Definitions *******************************/ + + +/***************** Macros (Inline Functions) Definitions *********************/ + + +/************************** Function Prototypes ******************************/ + + +/************************** Variable Prototypes ******************************/ + +/** + * The configuration table for UART 16550/16450 devices in the table. Each + * device should have an entry in this table. + */ +XUartNs550_Config XUartNs550_ConfigTable[] = +{ + { + XPAR_UARTNS550_0_DEVICE_ID, + XPAR_UARTNS550_0_BASEADDR, + XPAR_UARTNS550_0_CLOCK_HZ + } +}; diff --git a/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550_i.h b/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550_i.h new file mode 100644 index 00000000..b671dbb3 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550_i.h @@ -0,0 +1,133 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* Use of the Software is limited solely to applications: +* (a) running on a Xilinx device, or +* (b) that interact with a Xilinx device through a bus or interconnect. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xuartns550_i.h +* +* This header file contains internal identifiers, which are those shared +* between the files of the driver. It is intended for internal use only. +* +*
+* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- ----------------------------------------------- +* 1.00a ecm 08/16/01 First release +* 1.00b jhl 03/11/02 Repartitioned driver for smaller files. +* 1.11a sv 03/20/07 Updated to use the new coding guidelines. +* 2.00a ktn 10/20/09 Converted all register accesses to 32 bit access. +* Updated to use HAL Processor APIs. _m is removed from the +* name of all the macro definitions. XUartNs550_mClearStats +* macro is removed, XUartNs550_ClearStats function should be +* used in its place. +*+* +******************************************************************************/ + +#ifndef XUARTNS550_I_H /* prevent circular inclusions */ +#define XUARTNS550_I_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xuartns550.h" + +/************************** Constant Definitions *****************************/ + + +/************************** Constant Definitions *****************************/ + + +/**************************** Type Definitions *******************************/ + + +/***************** Macros (Inline Functions) Definitions *********************/ + + +/**************************************************************************** +* +* This macro updates the status based upon a specified line status register +* value. The stats that are updated are based upon bits in this register. It +* also keeps the last errors instance variable updated. The purpose of this +* macro is to allow common processing between the modules of the component +* with less overhead than a function in the required module. +* +* @param InstancePtr is a pointer to the XUartNs550 instance . +* @param CurrentLsr contains the Line Status Register value to +* be used for the update. +* +* @return None. +* +* @note C-Style signature: +* +* void XUartNs550_UpdateStats(XUartNs550 *InstancePtr, u8 CurrentLsr) +* +*****************************************************************************/ +#define XUartNs550_UpdateStats(InstancePtr, CurrentLsr) \ +{ \ + InstancePtr->LastErrors |= CurrentLsr; \ + \ + if (CurrentLsr & XUN_LSR_OVERRUN_ERROR) { \ + InstancePtr->Stats.ReceiveOverrunErrors++; \ + } \ + if (CurrentLsr & XUN_LSR_PARITY_ERROR) { \ + InstancePtr->Stats.ReceiveParityErrors++; \ + } \ + if (CurrentLsr & XUN_LSR_FRAMING_ERROR) { \ + InstancePtr->Stats.ReceiveFramingErrors++; \ + } \ + if (CurrentLsr & XUN_LSR_BREAK_INT) { \ + InstancePtr->Stats.ReceiveBreakDetected++; \ + } \ +} + +/************************** Function Prototypes ******************************/ + +int XUartNs550_SetBaudRate(XUartNs550 *InstancePtr, u32 BaudRate); + +unsigned int XUartNs550_SendBuffer(XUartNs550 *InstancePtr); + +unsigned int XUartNs550_ReceiveBuffer(XUartNs550 *InstancePtr); + +/************************** Variable Definitions ****************************/ + +extern XUartNs550_Config XUartNs550_ConfigTable[]; + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ diff --git a/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550_intr.c b/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550_intr.c new file mode 100644 index 00000000..c0000b6b --- /dev/null +++ b/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550_intr.c @@ -0,0 +1,470 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* Use of the Software is limited solely to applications: +* (a) running on a Xilinx device, or +* (b) that interact with a Xilinx device through a bus or interconnect. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xuartns550_intr.c +* +* This file contains the functions that are related to interrupt processing +* for the 16450/16550 UART driver. +* +*
+* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- ----------------------------------------------- +* 1.00b jhl 03/11/02 Repartitioned driver for smaller files. +* 1.11a sv 03/20/07 Updated to use the new coding guidelines. +* 2.00a ktn 10/20/09 Converted all register accesses to 32 bit access. +* Updated to use HAL Processor APIs. _m is removed from the +* name of all the macro definitions. XUartNs550_mClearStats +* macro is removed, XUartNs550_ClearStats function should be +* used in its place. +* 2.02a adk 09/16/13 Updated the ReceiveDataHandler function to be the same as +* ReceiveTimeoutHandler. The ReceiveTimeoutHandler will +* call the callback function with XUN_EVENT_RECV_TIMEOUT when +* there is data received which is less than the requested +* data (this will also happen for the case where the +* data is equal to the threshold). +* The callback function with XUN_EVENT_RECV_DATA will be +* called when all the requested data has been received +*+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ + +#include "xuartns550.h" +#include "xuartns550_i.h" +#include "xil_io.h" + +/************************** Constant Definitions ****************************/ + +/**************************** Type Definitions ******************************/ + +/***************** Macros (Inline Functions) Definitions ********************/ + +/************************** Function Prototypes *****************************/ + +static void NoInterruptHandler(XUartNs550 *InstancePtr); +static void ReceiveStatusHandler(XUartNs550 *InstancePtr); +static void ReceiveTimeoutHandler(XUartNs550 *InstancePtr); +static void ReceiveDataHandler(XUartNs550 *InstancePtr); +static void SendDataHandler(XUartNs550 *InstancePtr); +static void ModemHandler(XUartNs550 *InstancePtr); + +/************************** Variable Definitions ****************************/ + +typedef void (*Handler)(XUartNs550 *InstancePtr); + +/* The following tables is a function pointer table that contains pointers + * to each of the handlers for specific kinds of interrupts. The table is + * indexed by the value read from the interrupt ID register. + */ +static Handler HandlerTable[13] = { + ModemHandler, /* 0 */ + NoInterruptHandler, /* 1 */ + SendDataHandler, /* 2 */ + NULL, /* 3 */ + ReceiveDataHandler, /* 4 */ + NULL, /* 5 */ + ReceiveStatusHandler, /* 6 */ + NULL, /* 7 */ + NULL, /* 8 */ + NULL, /* 9 */ + NULL, /* 10 */ + NULL, /* 11 */ + ReceiveTimeoutHandler /* 12 */ +}; + +/****************************************************************************/ +/** +* +* This function sets the handler that will be called when an event (interrupt) +* occurs in the driver. The purpose of the handler is to allow application +* specific processing to be performed. +* +* @param InstancePtr is a pointer to the XUartNs550 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 XUartNs550_SetHandler(XUartNs550 *InstancePtr, + XUartNs550_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->Handler = FuncPtr; + InstancePtr->CallBackRef = CallBackRef; +} + +/****************************************************************************/ +/** +* +* This function is the interrupt handler for the 16450/16550 UART driver. +* It must be connected to an interrupt system by the user such that it is +* called when an interrupt for any 16450/16550 UART 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 UART that +* the interrupt is for. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XUartNs550_InterruptHandler(XUartNs550 *InstancePtr) +{ + u8 IsrStatus; + + Xil_AssertVoid(InstancePtr != NULL); + + /* + * Read the interrupt ID register to determine which, only one, + * interrupt is active + */ + IsrStatus = (u8)XUartNs550_ReadReg(InstancePtr->BaseAddress, + XUN_IIR_OFFSET) & + XUN_INT_ID_MASK; + + /* + * Make sure the handler table has a handler defined for the interrupt + * that is active, and then call the handler + */ + Xil_AssertVoid(HandlerTable[IsrStatus] != NULL); + + HandlerTable[IsrStatus](InstancePtr); +} + +/****************************************************************************/ +/** +* +* This function handles the case when the value read from the interrupt ID +* register indicates no interrupt is to be serviced. +* +* @param InstancePtr is a pointer to the XUartNs550 instance . +* +* @return None. +* +* @note None. +* +* @internal +* +* The LsrRegister is volatile to ensure that optimization will not cause the +* statement to be optimized away. +* +*****************************************************************************/ +static void NoInterruptHandler(XUartNs550 *InstancePtr) +{ + volatile u32 LsrRegister; + + /* + * Reading the ID register clears the currently asserted interrupts + */ + LsrRegister = XUartNs550_GetLineStatusReg(InstancePtr->BaseAddress); + + /* + * Update the stats to reflect any errors that might be read + */ + XUartNs550_UpdateStats(InstancePtr, (u8)LsrRegister); +} + +/****************************************************************************/ +/** +* +* This function handles interrupts for receive status updates which include +* overrun errors, framing errors, parity errors, and the break interrupt. +* +* @param InstancePtr is a pointer to the XUartNs550 instance. +* +* @return None. +* +* @note +* +* If this handler executes and data is not supposed to be received, then +* this probably means data is being received that contains errors and the +* the user may need to clear the receive FIFOs to dump the data. +* +*****************************************************************************/ +static void ReceiveStatusHandler(XUartNs550 *InstancePtr) +{ + u32 LsrRegister; + + /* + * If there are bytes still to be received in the specified buffer + * go ahead and receive them + */ + if (InstancePtr->ReceiveBuffer.RemainingBytes != 0) { + XUartNs550_ReceiveBuffer(InstancePtr); + } else { + /* + * Reading the ID register clears the currently asserted + * interrupts and this must be done since there was no data + * to receive, update the status for the status read + */ + LsrRegister = + XUartNs550_GetLineStatusReg(InstancePtr->BaseAddress); + XUartNs550_UpdateStats(InstancePtr, (u8)LsrRegister); + } + + /* + * Call the application handler to indicate that there is a receive + * error or a break interrupt, if the application cares about the + * error it call a function to get the last errors + */ + InstancePtr->Handler(InstancePtr->CallBackRef, XUN_EVENT_RECV_ERROR, + InstancePtr->ReceiveBuffer.RequestedBytes - + InstancePtr->ReceiveBuffer.RemainingBytes); + + /* + * Update the receive stats to reflect the receive interrupt + */ + InstancePtr->Stats.StatusInterrupts++; +} +/****************************************************************************/ +/** +* +* This function handles the receive timeout interrupt. This interrupt occurs +* whenever a number of bytes have been present in the FIFO for 4 character +* times, the receiver is not receiving any data, and the number of bytes +* present is less than the FIFO threshold. +* +* @param InstancePtr is a pointer to the XUartNs550 instance. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +static void ReceiveTimeoutHandler(XUartNs550 *InstancePtr) +{ + u32 Event; + + /* + * If there are bytes still to be received in the specified buffer + * go ahead and receive them + */ + if (InstancePtr->ReceiveBuffer.RemainingBytes != 0) { + XUartNs550_ReceiveBuffer(InstancePtr); + } + + /* + * If there are no more bytes to receive then indicate that this is + * not a receive timeout but the end of the buffer reached, a timeout + * normally occurs if # of bytes is not divisible by FIFO threshold, + * don't rely on previous test of remaining bytes since receive function + * updates it + */ + if (InstancePtr->ReceiveBuffer.RemainingBytes != 0) { + Event = XUN_EVENT_RECV_TIMEOUT; + } else { + Event = XUN_EVENT_RECV_DATA; + } + + /* + * Call the application handler to indicate that there is a receive + * timeout or data event + */ + InstancePtr->Handler(InstancePtr->CallBackRef, Event, + InstancePtr->ReceiveBuffer.RequestedBytes - + InstancePtr->ReceiveBuffer.RemainingBytes); + + /* + * Update the receive stats to reflect the receive interrupt + */ + InstancePtr->Stats.ReceiveInterrupts++; +} +/****************************************************************************/ +/** +* +* 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 XUartNs550 instance. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +static void ReceiveDataHandler(XUartNs550 *InstancePtr) +{ + u32 Event; + + /* + * If there are bytes still to be received in the specified buffer + * go ahead and receive them + */ + if (InstancePtr->ReceiveBuffer.RemainingBytes != 0) { + XUartNs550_ReceiveBuffer(InstancePtr); + } + + + if (InstancePtr->ReceiveBuffer.RemainingBytes != 0) { + + /* + * If there are more bytes to receive then indicate that this is + * a Receive Timeout. + * This happens in the case the number of bytes received equal + * to the FIFO threshold as the Timeout Interrupt is masked + */ + Event = XUN_EVENT_RECV_TIMEOUT; + + } else { + + /* + * If the last byte of a message was received then call the + * application handler + */ + Event = XUN_EVENT_RECV_DATA; + } + + /* + * Call the application handler to indicate that there is a receive + * timeout or data event + */ + InstancePtr->Handler(InstancePtr->CallBackRef, Event, + InstancePtr->ReceiveBuffer.RequestedBytes - + InstancePtr->ReceiveBuffer.RemainingBytes); + + + /* + * Update the receive stats to reflect the receive interrupt + */ + InstancePtr->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 XUartNs550 instance. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +static void SendDataHandler(XUartNs550 *InstancePtr) +{ + u32 IerRegister; + + /* + * If there are not bytes to be sent from the specified buffer then + * disable the transmit interrupt so it will stop interrupting as it + * interrupts any time the FIFO is empty + */ + if (InstancePtr->SendBuffer.RemainingBytes == 0) { + IerRegister = XUartNs550_ReadReg(InstancePtr->BaseAddress, + XUN_IER_OFFSET); + XUartNs550_WriteReg(InstancePtr->BaseAddress, XUN_IER_OFFSET, + IerRegister & ~XUN_IER_TX_EMPTY); + + /* + * Call the application handler to indicate the data + * has been sent + */ + InstancePtr->Handler(InstancePtr->CallBackRef, + XUN_EVENT_SENT_DATA, + InstancePtr->SendBuffer.RequestedBytes - + InstancePtr->SendBuffer.RemainingBytes); + } + + /* + * Otherwise there is still more data to send in the specified buffer + * so go ahead and send it + */ + else { + XUartNs550_SendBuffer(InstancePtr); + } + + /* + * Update the transmit stats to reflect the transmit interrupt + */ + InstancePtr->Stats.TransmitInterrupts++; +} + +/****************************************************************************/ +/** +* +* This function handles modem interrupts. It does not do any processing +* except to call the application handler to indicate a modem event. +* +* @param InstancePtr is a pointer to the XUartNs550 instance. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +static void ModemHandler(XUartNs550 *InstancePtr) +{ + u32 MsrRegister; + + /* + * Read the modem status register so that the interrupt is acknowledged + * and so that it can be passed to the callback handler with the event + */ + MsrRegister = XUartNs550_ReadReg(InstancePtr->BaseAddress, + XUN_MSR_OFFSET); + + /* + * Call the application handler to indicate the modem status changed, + * passing the modem status and the event data in the call + */ + InstancePtr->Handler(InstancePtr->CallBackRef, XUN_EVENT_MODEM, + (u8) MsrRegister); + + /* + * Update the modem stats to reflect the modem interrupt + */ + InstancePtr->Stats.ModemInterrupts++; +} diff --git a/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550_l.c b/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550_l.c new file mode 100644 index 00000000..c7fffaf4 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550_l.c @@ -0,0 +1,192 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* Use of the Software is limited solely to applications: +* (a) running on a Xilinx device, or +* (b) that interact with a Xilinx device through a bus or interconnect. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xuartns550_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.00b jhl 04/24/02 First release +* 1.11a sv 03/20/07 Updated to use the new coding guidelines. +* 2.00a sdm 09/22/09 Converted all register accesses to 32 bit access. +* 2.00a ktn 10/20/09 Converted all register accesses to 32 bit access. +* Updated to use HAL Processor APIs. _m is removed from the +* name of all the macro definitions. +*+* +******************************************************************************/ + + +/***************************** Include Files *********************************/ + +#include "xuartns550_l.h" + +/************************** Constant Definitions *****************************/ + + +/**************************** Type Definitions *******************************/ + + +/***************** Macros (Inline Functions) Definitions *********************/ + + +/************************** Function Prototypes ******************************/ + + +/************************** Variable Definitions *****************************/ + + +/****************************************************************************/ +/** +* +* This function sends a data byte with the UART. This function operates in the +* polling mode and blocks until the data has been put into the UART transmit +* holding register. +* +* @param BaseAddress contains the base address of the UART. +* @param Data contains the data byte to be sent. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XUartNs550_SendByte(u32 BaseAddress, u8 Data) +{ + /* + * Wait til we know that the byte can be sent, the 550 does not have any + * way to tell how much room is in the FIFO such that we must wait for + * it to be empty + */ + while (!XUartNs550_IsTransmitEmpty(BaseAddress)); + + /* + * Write the data byte to the UART to be transmitted + */ + XUartNs550_WriteReg(BaseAddress, XUN_THR_OFFSET, (u32)Data); +} + +/****************************************************************************/ +/** +* +* This function receives a byte from the UART. It operates in a polling mode +* and blocks until a byte of data is received. +* +* @param BaseAddress contains the base address of the UART. +* +* @return The data byte received by the UART. +* +* @note None. +* +*****************************************************************************/ +u8 XUartNs550_RecvByte(u32 BaseAddress) +{ + /* + * Wait for there to be data received + */ + while (!XUartNs550_IsReceiveData(BaseAddress)); + + /* + * Return the next data byte the UART received + */ + return (u8) XUartNs550_ReadReg(BaseAddress, XUN_RBR_OFFSET); +} + + +/****************************************************************************/ +/** +* +* Set the baud rate for the UART. +* +* @param BaseAddress contains the base address of the UART. +* @param InputClockHz is the frequency of the input clock to the device +* in Hertz. +* @param BaudRate is the baud rate to be set. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XUartNs550_SetBaud(u32 BaseAddress, u32 InputClockHz, u32 BaudRate) +{ + + u32 BaudLSB; + u32 BaudMSB; + u32 LcrRegister; + u32 Divisor; + + /* + * Determine what the divisor should be to get the specified baud + * rater based upon the input clock frequency and a baud clock prescaler + * of 16 + */ + Divisor = InputClockHz / (BaudRate * 16UL); + + /* + * Get the least significant and most significant bytes of the divisor + * so they can be written to 2 byte registers + */ + BaudLSB = Divisor & XUN_DIVISOR_BYTE_MASK; + BaudMSB = (Divisor >> 8) & XUN_DIVISOR_BYTE_MASK; + + /* + * Get the line control register contents and set the divisor latch + * access bit so the baud rate can be set + */ + LcrRegister = XUartNs550_GetLineControlReg(BaseAddress); + XUartNs550_SetLineControlReg(BaseAddress, + LcrRegister | XUN_LCR_DLAB); + + /* + * Set the baud Divisors to set rate, the initial write of 0xFF is to + * keep the divisor from being 0 which is not recommended as per the + * NS16550D spec sheet + */ + XUartNs550_WriteReg(BaseAddress, XUN_DRLS_OFFSET, 0xFF); + XUartNs550_WriteReg(BaseAddress, XUN_DRLM_OFFSET, BaudMSB); + XUartNs550_WriteReg(BaseAddress, XUN_DRLS_OFFSET, BaudLSB); + + /* + * Clear the Divisor latch access bit, DLAB to allow nornal + * operation and write to the line control register + */ + XUartNs550_SetLineControlReg(BaseAddress, LcrRegister); +} diff --git a/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550_l.h b/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550_l.h new file mode 100644 index 00000000..94973fbd --- /dev/null +++ b/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550_l.h @@ -0,0 +1,345 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* Use of the Software is limited solely to applications: +* (a) running on a Xilinx device, or +* (b) that interact with a Xilinx device through a bus or interconnect. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xuartns550_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. +* High-level driver functions are defined in xuartns550.h. +* +*
+* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- ----------------------------------------------- +* 1.00b jhl 04/24/02 First release +* 1.11a sv 03/20/07 Updated to use the new coding guidelines. +* 1.11a rpm 11/13/07 Fixed bug in _EnableIntr +* 2.00a ktn 10/20/09 Converted all register accesses to 32 bit access. +* Updated to use HAL Processor APIs. _m is removed from the +* name of all the macro definitions. +*+* +******************************************************************************/ + +#ifndef XUARTNS550_L_H /* prevent circular inclusions */ +#define XUARTNS550_L_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xil_io.h" + +/************************** Constant Definitions *****************************/ + +/* + * Offset from the device base address to the IP registers. + */ +#define XUN_REG_OFFSET 0x1000 + +/** @name Register Map + * + * Register offsets for the 16450/16550 compatible UART device. + * @{ + */ +#define XUN_RBR_OFFSET (XUN_REG_OFFSET) /**< Receive buffer, read only */ +#define XUN_THR_OFFSET (XUN_REG_OFFSET) /**< Transmit holding register */ +#define XUN_IER_OFFSET (XUN_REG_OFFSET + 0x04) /**< Interrupt enable */ +#define XUN_IIR_OFFSET (XUN_REG_OFFSET + 0x08) /**< Interrupt id, read only */ +#define XUN_FCR_OFFSET (XUN_REG_OFFSET + 0x08) /**< Fifo control, write only */ +#define XUN_LCR_OFFSET (XUN_REG_OFFSET + 0x0C) /**< Line Control Register */ +#define XUN_MCR_OFFSET (XUN_REG_OFFSET + 0x10) /**< Modem Control Register */ +#define XUN_LSR_OFFSET (XUN_REG_OFFSET + 0x14) /**< Line Status Register */ +#define XUN_MSR_OFFSET (XUN_REG_OFFSET + 0x18) /**< Modem Status Register */ +#define XUN_DRLS_OFFSET (XUN_REG_OFFSET + 0x00) /**< Divisor Register LSB */ +#define XUN_DRLM_OFFSET (XUN_REG_OFFSET + 0x04) /**< Divisor Register MSB */ +/* @} */ + +/* + * The following constant specifies the size of the FIFOs, the size of the + * FIFOs includes the transmitter and receiver such that it is the total number + * of bytes that the UART can buffer + */ +#define XUN_FIFO_SIZE 16 + + +/** + * @name Interrupt Enable Register (IER) mask(s) + * @{ + */ +#define XUN_IER_MODEM_STATUS 0x00000008 /**< Modem status interrupt */ +#define XUN_IER_RX_LINE 0x00000004 /**< Receive status interrupt */ +#define XUN_IER_TX_EMPTY 0x00000002 /**< Transmitter empty interrupt */ +#define XUN_IER_RX_DATA 0x00000001 /**< Receiver data available */ +/* @} */ + +/** + * @name Interrupt ID Register (INT_ID) mask(s) + * @{ + */ +#define XUN_INT_ID_MASK 0x0000000F /**< Only the interrupt ID */ +#define XUN_INT_ID_FIFOS_ENABLED 0x000000C0 /**< Only the FIFOs enable */ +/* @} */ + +/** + * @name FIFO Control Register mask(s) + * @{ + */ +#define XUN_FIFO_RX_TRIG_MSB 0x00000080 /**< Trigger level MSB */ +#define XUN_FIFO_RX_TRIG_LSB 0x00000040 /**< Trigger level LSB */ +#define XUN_FIFO_TX_RESET 0x00000004 /**< Reset the transmit FIFO */ +#define XUN_FIFO_RX_RESET 0x00000002 /**< Reset the receive FIFO */ +#define XUN_FIFO_ENABLE 0x00000001 /**< Enable the FIFOs */ +#define XUN_FIFO_RX_TRIGGER 0x000000C0 /**< Both trigger level bits */ +/* @} */ + +/** + * @name Line Control Register(LCR) mask(s) + * @{ + */ +#define XUN_LCR_DLAB 0x00000080 /**< Divisor latch access */ +#define XUN_LCR_SET_BREAK 0x00000040 /**< Cause a break condition */ +#define XUN_LCR_STICK_PARITY 0x00000020 /**< Stick Parity */ +#define XUN_LCR_EVEN_PARITY 0x00000010 /**< 1 = even, 0 = odd parity */ +#define XUN_LCR_ENABLE_PARITY 0x00000008 /**< 1 = Enable, 0 = Disable parity*/ +#define XUN_LCR_2_STOP_BITS 0x00000004 /**< 1= 2 stop bits,0 = 1 stop bit */ +#define XUN_LCR_8_DATA_BITS 0x00000003 /**< 8 Data bits selection */ +#define XUN_LCR_7_DATA_BITS 0x00000002 /**< 7 Data bits selection */ +#define XUN_LCR_6_DATA_BITS 0x00000001 /**< 6 Data bits selection */ +#define XUN_LCR_LENGTH_MASK 0x00000003 /**< Both length bits mask */ +#define XUN_LCR_PARITY_MASK 0x00000018 /**< Both parity bits mask */ +/* @} */ + +/** + * @name Mode Control Register(MCR) mask(s) + * @{ + */ +#define XUN_MCR_LOOP 0x00000010 /**< Local loopback */ +#define XUN_MCR_OUT_2 0x00000008 /**< General output 2 signal */ +#define XUN_MCR_OUT_1 0x00000004 /**< General output 1 signal */ +#define XUN_MCR_RTS 0x00000002 /**< RTS signal */ +#define XUN_MCR_DTR 0x00000001 /**< DTR signal */ +/* @} */ + +/** + * @name Line Status Register(LSR) mask(s) + * @{ + */ +#define XUN_LSR_RX_FIFO_ERROR 0x00000080 /**< An errored byte is in FIFO */ +#define XUN_LSR_TX_EMPTY 0x00000040 /**< Transmitter is empty */ +#define XUN_LSR_TX_BUFFER_EMPTY 0x00000020 /**< Transmit holding reg empty */ +#define XUN_LSR_BREAK_INT 0x00000010 /**< Break detected interrupt */ +#define XUN_LSR_FRAMING_ERROR 0x00000008 /**< Framing error on current byte */ +#define XUN_LSR_PARITY_ERROR 0x00000004 /**< Parity error on current byte */ +#define XUN_LSR_OVERRUN_ERROR 0x00000002 /**< Overrun error on receive FIFO */ +#define XUN_LSR_DATA_READY 0x00000001 /**< Receive data ready */ +#define XUN_LSR_ERROR_BREAK 0x0000001E /**< Errors except FIFO error and + break detected */ +/* @} */ + +#define XUN_DIVISOR_BYTE_MASK 0x000000FF + +/**************************** Type Definitions *******************************/ + + +/***************** Macros (Inline Functions) Definitions *********************/ + +/****************************************************************************/ +/** +* Read a UART register. +* +* @param BaseAddress contains the base address of the device. +* @param RegOffset contains the offset from the 1st register of the +* device to select the specific register. +* +* @return The value read from the register. +* +* @note C-Style signature: +* u32 XUartNs550_ReadReg(u32 BaseAddress, u32 RegOffset); +* +******************************************************************************/ +#define XUartNs550_ReadReg(BaseAddress, RegOffset) \ + Xil_In32((BaseAddress) + (RegOffset)) + +/****************************************************************************/ +/** +* Write to a UART register. +* +* @param BaseAddress contains the base address of the device. +* @param RegOffset contains the offset from the 1st register of the +* device to select the specific register. +* @param RegisterValue is the value to be written to the regsiter. +* +* @return None. +* +* @note C-Style signature: +* u32 XUartNs550_WriteReg(u32 BaseAddress, u32 RegOffset, +* u32 RegisterValue); +* +******************************************************************************/ +#define XUartNs550_WriteReg(BaseAddress, RegOffset, RegisterValue) \ + Xil_Out32((BaseAddress) + (RegOffset), (RegisterValue)) + +/****************************************************************************/ +/** +* Get the UART Line Status Register. +* +* @param BaseAddress contains the base address of the device. +* +* @return The value read from the register. +* +* @note C-Style signature: +* u32 XUartNs550_GetLineStatusReg(u32 BaseAddress); +* +******************************************************************************/ +#define XUartNs550_GetLineStatusReg(BaseAddress) \ + XUartNs550_ReadReg((BaseAddress), XUN_LSR_OFFSET) + +/****************************************************************************/ +/** +* Get the UART Line Status Register. +* +* @param BaseAddress contains the base address of the device. +* +* @return The value read from the register. +* +* @note C-Style signature: +* u32 XUartNs550_GetLineControlReg(u32 BaseAddress); +* +******************************************************************************/ +#define XUartNs550_GetLineControlReg(BaseAddress) \ + XUartNs550_ReadReg((BaseAddress), XUN_LCR_OFFSET) + +/****************************************************************************/ +/** +* Set the UART Line Status Register. +* +* @param BaseAddress contains the base address of the device. +* @param RegisterValue is the value to be written to the register. +* +* @return None. +* +* @note C-Style signature: +* void XUartNs550_SetLineControlReg(u32 BaseAddress, +* u32 RegisterValue); +* +******************************************************************************/ +#define XUartNs550_SetLineControlReg(BaseAddress, RegisterValue) \ + XUartNs550_WriteReg((BaseAddress), XUN_LCR_OFFSET, (RegisterValue)) + +/****************************************************************************/ +/** +* Enable the transmit and receive interrupts of the UART. +* +* @param BaseAddress contains the base address of the device. +* +* @return None. +* +* @note C-Style signature: +* void XUartNs550_EnableIntr(u32 BaseAddress);, +* +******************************************************************************/ +#define XUartNs550_EnableIntr(BaseAddress) \ + XUartNs550_WriteReg((BaseAddress), XUN_IER_OFFSET, \ + XUartNs550_ReadReg((BaseAddress), XUN_IER_OFFSET) | \ + (XUN_IER_RX_LINE | XUN_IER_TX_EMPTY | XUN_IER_RX_DATA)) + +/****************************************************************************/ +/** +* Disable the transmit and receive interrupts of the UART. +* +* @param BaseAddress contains the base address of the device. +* +* @return None. +* +* @note C-Style signature: +* void XUartNs550_DisableIntr(u32 BaseAddress);, +* +******************************************************************************/ +#define XUartNs550_DisableIntr(BaseAddress) \ + XUartNs550_WriteReg((BaseAddress), XUN_IER_OFFSET, \ + XUartNs550_ReadReg((BaseAddress), XUN_IER_OFFSET) & \ + ~(XUN_IER_RX_LINE | XUN_IER_TX_EMPTY | XUN_IER_RX_DATA)) + +/****************************************************************************/ +/** +* Determine if there is receive data in the receiver and/or FIFO. +* +* @param BaseAddress contains the base address of the device. +* +* @return TRUE if there is receive data, FALSE otherwise. +* +* @note C-Style signature: +* int XUartNs550_IsReceiveData(u32 BaseAddress);, +* +******************************************************************************/ +#define XUartNs550_IsReceiveData(BaseAddress) \ + (XUartNs550_GetLineStatusReg(BaseAddress) & XUN_LSR_DATA_READY) + +/****************************************************************************/ +/** +* Determine if a byte of data can be sent with the transmitter. +* +* @param BaseAddress contains the base address of the device. +* +* @return TRUE if a byte can be sent, FALSE otherwise. +* +* @note C-Style signature: +* int XUartNs550_IsTransmitEmpty(u32 BaseAddress);, +* +******************************************************************************/ +#define XUartNs550_IsTransmitEmpty(BaseAddress) \ + (XUartNs550_GetLineStatusReg(BaseAddress) & XUN_LSR_TX_BUFFER_EMPTY) + +/************************** Function Prototypes ******************************/ + +void XUartNs550_SendByte(u32 BaseAddress, u8 Data); + +u8 XUartNs550_RecvByte(u32 BaseAddress); + +void XUartNs550_SetBaud(u32 BaseAddress, u32 InputClockHz, u32 BaudRate); + +/************************** Variable Definitions *****************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ diff --git a/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550_options.c b/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550_options.c new file mode 100644 index 00000000..f31aeeeb --- /dev/null +++ b/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550_options.c @@ -0,0 +1,525 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* Use of the Software is limited solely to applications: +* (a) running on a Xilinx device, or +* (b) that interact with a Xilinx device through a bus or interconnect. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xuartns550_options.c +* +* The implementation of the options functions for the XUartNs550 driver. +* +*
+* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- ----------------------------------------------- +* 1.00b jhl 03/11/02 Repartitioned driver for smaller files. +* 1.00b rpm 04/12/05 Added critical section protection in ReadFcrRegister +* 1.11a sv 03/20/07 Updated to use the new coding guidelines. +* 1.13a sdm 07/10/09 Added receive line interrupt option to OptionsTable[]. +* 2.00a sdm 09/22/09 Converted all register accesses to 32 bit access. +* 2.00a ktn 10/20/09 Converted all register accesses to 32 bit access. +* Updated to use HAL Processor APIs. _m is removed from the +* name of all the macro definitions. +*+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ + +#include "xuartns550.h" +#include "xuartns550_i.h" +#include "xil_io.h" + +/************************** Constant Definitions ****************************/ + +/**************************** Type Definitions ******************************/ + +/***************** Macros (Inline Functions) Definitions ********************/ + +/************************** Variable Definitions ****************************/ +/* + * The following data type maps an option to a register and the bits of the + * regiser such that getting and setting the options may be table driven. + */ +typedef struct { + u16 Option; + u16 RegisterOffset; + u8 Mask; +} Mapping; + +/* + * 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[] = { + { XUN_OPTION_SET_BREAK, XUN_LCR_OFFSET, XUN_LCR_SET_BREAK }, + { XUN_OPTION_LOOPBACK, XUN_MCR_OFFSET, XUN_MCR_LOOP }, + { XUN_OPTION_DATA_INTR, XUN_IER_OFFSET, XUN_IER_RX_DATA }, + { XUN_OPTION_MODEM_INTR, XUN_IER_OFFSET, XUN_IER_MODEM_STATUS }, + { XUN_OPTION_FIFOS_ENABLE, XUN_FCR_OFFSET, XUN_FIFO_ENABLE }, + { XUN_OPTION_RESET_TX_FIFO, XUN_FCR_OFFSET, XUN_FIFO_TX_RESET }, + { XUN_OPTION_RESET_RX_FIFO, XUN_FCR_OFFSET, XUN_FIFO_RX_RESET }, + { XUN_OPTION_ASSERT_OUT2, XUN_MCR_OFFSET, XUN_MCR_OUT_2 }, + { XUN_OPTION_ASSERT_OUT1, XUN_MCR_OFFSET, XUN_MCR_OUT_1 }, + { XUN_OPTION_ASSERT_RTS, XUN_MCR_OFFSET, XUN_MCR_RTS }, + { XUN_OPTION_ASSERT_DTR, XUN_MCR_OFFSET, XUN_MCR_DTR }, + { XUN_OPTION_RXLINE_INTR, XUN_IER_OFFSET, XUN_IER_RX_LINE } +}; + +/* Create a constants for the number of entries in the table */ + +#define XUN_NUM_OPTIONS (sizeof(OptionsTable) / sizeof(Mapping)) + +/************************** Function Prototypes *****************************/ + +static u32 ReadFcrRegister(u32 BaseAddress); + +/****************************************************************************/ +/** +* +* Gets the options for the specified driver instance. The options are +* implemented as bit masks such that multiple options may be enabled or +* disabled simulataneously. +* +* @param InstancePtr is a pointer to the XUartNs550 instance. +* +* @return The current options for the UART. The optionss are bit masks +* that are contained in the file xuartns550.h and +* named XUN_OPTION_*. +* +* @note None. +* +*****************************************************************************/ +u16 XUartNs550_GetOptions(XUartNs550 *InstancePtr) +{ + u16 Options = 0; + u32 Register; + u32 Index; + + /* + * Assert validates the input arguments + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Loop thru the options table to map the physical options in the + * registers of the UART to the logical options to be returned + */ + for (Index = 0; Index < XUN_NUM_OPTIONS; Index++) { + /* + * If the FIFO control register is being read, the make sure to + * setup the line control register so it can be read + */ + if (OptionsTable[Index].RegisterOffset == XUN_FCR_OFFSET) { + Register = ReadFcrRegister(InstancePtr->BaseAddress); + } else { + Register = XUartNs550_ReadReg(InstancePtr->BaseAddress, + OptionsTable[Index].RegisterOffset); + } + + /* + * If the bit in the register which correlates to the option + * is set, then set the corresponding bit in the options, + * ignoring any bits which are zero since the options variable + * is initialized to zero + */ + if (Register & OptionsTable[Index].Mask) { + Options |= OptionsTable[Index].Option; + } + } + + return Options; +} + +/****************************************************************************/ +/** +* +* Sets the options for the specified driver instance. The options are +* implemented as bit masks such that multiple options may be enabled or +* disabled simultaneously. +* +* The GetOptions function may be called to retrieve the currently enabled +* options. The result is ORed in the desired new settings to be enabled and +* ANDed with the inverse to clear the settings to be disabled. The resulting +* value is then used as the options for the SetOption function call. +* +* @param InstancePtr is a pointer to the XUartNs550 instance. +* @param Options contains the options to be set which are bit masks +* contained in the file xuartns550.h and named XUN_OPTION_*. +* +* @return +* - XST_SUCCESS if the options were set successfully. +* - XST_UART_CONFIG_ERROR if the options could not be set because +* the hardware does not support FIFOs +* +* @note None. +* +*****************************************************************************/ +int XUartNs550_SetOptions(XUartNs550 *InstancePtr, u16 Options) +{ + u32 Index; + u32 Register; + + /* + * Assert validates the input arguments + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Loop thru the options table to map the logical options to the + * physical options in the registers of the UART + */ + for (Index = 0; Index < XUN_NUM_OPTIONS; Index++) { + + /* + * If the FIFO control register is being read, this is a + * special case that requires special register processing + */ + if (OptionsTable[Index].RegisterOffset == XUN_FCR_OFFSET) { + Register = ReadFcrRegister(InstancePtr->BaseAddress); + } else { + /* + * Read the register which contains option so that the + * register can be changed without destoying any other + * bits of the register + */ + Register = XUartNs550_ReadReg(InstancePtr->BaseAddress, + OptionsTable[Index].RegisterOffset); + } + + /* + * If the option is set in the input, then set the + * corresponding bit in the specified register, otherwise + * clear the bit in the register + */ + if (Options & OptionsTable[Index].Option) { + Register |= OptionsTable[Index].Mask; + } else { + Register &= ~OptionsTable[Index].Mask; + } + + /* + * Write the new value to the register to set the option + */ + XUartNs550_WriteReg(InstancePtr->BaseAddress, + OptionsTable[Index].RegisterOffset, Register); + } + + /* To be done, add error checks for enabling/resetting FIFOs */ + + return XST_SUCCESS; +} + +/****************************************************************************/ +/** +* +* This function gets the receive FIFO trigger level. The receive trigger +* level indicates the number of bytes in the receive FIFO that cause a receive +* data event (interrupt) to be generated. +* +* @param InstancePtr is a pointer to the XUartNs550 instance. +* +* @return The current receive FIFO trigger level. Constants which +* define each trigger level are contained in the file +* xuartns550.h and named XUN_FIFO_TRIGGER_*. +* +* @note None. +* +*****************************************************************************/ +u8 XUartNs550_GetFifoThreshold(XUartNs550 *InstancePtr) +{ + u32 FcrRegister; + + /* + * Assert validates the input arguments + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the value of the FIFO control register so that the threshold + * can be retrieved, this read takes special register processing + */ + FcrRegister = ReadFcrRegister(InstancePtr->BaseAddress); + + /* + * Return only the trigger level from the register value + */ + return (u8)(FcrRegister & XUN_FIFO_RX_TRIGGER); +} + +/****************************************************************************/ +/** +* +* This functions sets the receive FIFO trigger level. The receive trigger +* level specifies the number of bytes in the receive FIFO that cause a receive +* data event (interrupt) to be generated. The FIFOs must be enabled to set the +* trigger level. +* +* @param InstancePtr is a pointer to the XUartNs550 instance. +* @param TriggerLevel contains the trigger level to set. Constants which +* define each trigger level are contained in the file xuartns550.h +* and named XUN_FIFO_TRIGGER_*. +* +* @return +* - XST_SUCCESS if the trigger level was set +* - XST_UART_CONFIG_ERROR if the trigger level could not be set, +* either the hardware does not support the FIFOs or FIFOs +* are not enabled +* +* @note None. +* +*****************************************************************************/ +int XUartNs550_SetFifoThreshold(XUartNs550 *InstancePtr, u8 TriggerLevel) +{ + u32 FcrRegister; + + /* + * Assert validates the input arguments + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid((TriggerLevel == XUN_FIFO_TRIGGER_14) || + (TriggerLevel == XUN_FIFO_TRIGGER_08) || + (TriggerLevel == XUN_FIFO_TRIGGER_04) || + (TriggerLevel == XUN_FIFO_TRIGGER_01)); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the value of the FIFO control register, this read takes special + * register processing + */ + FcrRegister = ReadFcrRegister(InstancePtr->BaseAddress); + + /* + * If the FIFO control register indicates that FIFOs are disabled, then + * either they are just disabled or it has no FIFOs, return an error + */ + if ((FcrRegister & XUN_FIFO_ENABLE) == 0) { + return XST_UART_CONFIG_ERROR; + } + + /* + * Set the receive FIFO trigger level by clearing out the old level in + * the FIFO control register and writing in the new level + */ + FcrRegister &= ~XUN_FIFO_RX_TRIGGER; + FcrRegister |= (u32) TriggerLevel; + + /* + * Write the new value for the FIFO control register to it such that the + * threshold is changed, writing to it is normal unlike reading from it + */ + XUartNs550_WriteReg(InstancePtr->BaseAddress, + XUN_FCR_OFFSET, FcrRegister); + + return XST_SUCCESS; +} + +/****************************************************************************/ +/** +* +* This function returns the last errors that have occurred in the specified +* UART. It also clears the errors such that they cannot be retrieved again. +* The errors include parity error, receive overrun error, framing error, and +* break detection. +* +* The last errors is an accumulation of the errors each time an error is +* discovered in the driver. A status is checked for each received byte and +* this status is accumulated in the last errors. +* +* If this function is called after receiving a buffer of data, it will indicate +* any errors that occurred for the bytes of the buffer. It does not indicate +* which bytes contained errors. +* +* @param InstancePtr is a pointer to the XUartNs550 instance. +* +* @return The last errors that occurred. The errors are bit masks +* that are contained in the file xuartns550.h and +* named XUN_ERROR_*. +* +* @note None. +* +*****************************************************************************/ +u8 XUartNs550_GetLastErrors(XUartNs550 *InstancePtr) +{ + u8 Temp = InstancePtr->LastErrors; + + /* + * Assert validates the input arguments + */ + Xil_AssertNonvoid(InstancePtr != NULL); + + /* + * Clear the last errors and return the previous value + */ + InstancePtr->LastErrors = 0; + + /* + * Only return the bits that are reported errors which include + * receive overrun, framing, parity and break detection, the last errors + * variable holds an accumulation of the line status register bits which + * have been set + */ + return Temp & XUN_LSR_ERROR_BREAK; +} + +/****************************************************************************/ +/** +* +* This function gets the modem status from the specified UART. The modem +* status indicates any changes of the modem signals. This function allows +* the modem status to be read in a polled mode. The modem status is updated +* whenever it is read such that reading it twice may not yield the same +* results. +* +* @param InstancePtr is a pointer to the XUartNs550 instance . +* +* @return The modem status which are bit masks that are contained in +* the file xuartns550.h and named XUN_MODEM_*. +* +* @note +* +* The bit masks used for the modem status are the exact bits of the modem +* status register with no abstraction. +* +*****************************************************************************/ +u8 XUartNs550_GetModemStatus(XUartNs550 *InstancePtr) +{ + u32 ModemStatusRegister; + + /* + * Assert validates the input arguments + */ + Xil_AssertNonvoid(InstancePtr != NULL); + + /* + * Read the modem status register to return + */ + ModemStatusRegister = XUartNs550_ReadReg(InstancePtr->BaseAddress, + XUN_MSR_OFFSET); + return (u8) ModemStatusRegister; +} + +/****************************************************************************/ +/** +* +* 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 XUartNs550 instance. +* +* @return A value of TRUE if the UART is sending data, otherwise FALSE. +* +* @note None. +* +*****************************************************************************/ +int XUartNs550_IsSending(XUartNs550 *InstancePtr) +{ + u32 LsrRegister; + + /* + * Assert validates the input arguments + */ + Xil_AssertNonvoid(InstancePtr != NULL); + + /* + * Read the line status register to determine if the transmitter is + * empty + */ + LsrRegister = XUartNs550_GetLineStatusReg(InstancePtr->BaseAddress); + + /* + * If the transmitter is not empty then indicate that the UART is still + * sending some data + */ + return ((LsrRegister & XUN_LSR_TX_EMPTY) == 0); +} + +/****************************************************************************/ +/** +* +* This functions reads the FIFO control register. It's primary purpose is to +* isolate the special processing for reading this register. It is necessary +* to write to the line control register, then read the FIFO control register, +* and then restore the line control register. +* +* @param BaseAddress contains the base address of the registers in the +* device. +* +* @return The contents of the FIFO control register. +* +* @note None. +* +*****************************************************************************/ +static u32 ReadFcrRegister(u32 BaseAddress) +{ + u32 LcrRegister; + u32 FcrRegister; + u32 IerRegister; + + /* + * Enter a critical section here by disabling Uart interrupts. We do + * not want to receive an interrupt while we have the FCR latched since + * the interrupt handler may want to read the IIR + */ + IerRegister = XUartNs550_ReadReg(BaseAddress, XUN_IER_OFFSET); + XUartNs550_WriteReg(BaseAddress, XUN_IER_OFFSET, 0); + + /* + * Get the line control register contents and set the divisor latch + * access bit so the FIFO control register can be read, this can't + * be done with a true 16550, but is a feature in the Xilinx device + */ + LcrRegister = XUartNs550_GetLineControlReg(BaseAddress); + XUartNs550_SetLineControlReg(BaseAddress, LcrRegister | XUN_LCR_DLAB); + + /* + * Read the FIFO control register so it can be returned + */ + FcrRegister = XUartNs550_ReadReg(BaseAddress, XUN_FCR_OFFSET); + + /* + * Restore the line control register to it's original contents such + * that the DLAB bit is no longer set and return the register + */ + XUartNs550_SetLineControlReg(BaseAddress, LcrRegister); + + /* + * Exit the critical section by restoring the IER + */ + XUartNs550_WriteReg(BaseAddress, XUN_IER_OFFSET, IerRegister); + + return FcrRegister; +} diff --git a/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550_selftest.c b/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550_selftest.c new file mode 100644 index 00000000..dea52368 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550_selftest.c @@ -0,0 +1,189 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* Use of the Software is limited solely to applications: +* (a) running on a Xilinx device, or +* (b) that interact with a Xilinx device through a bus or interconnect. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xuartns550_selftest.c +* +* This file contains the self-test functions for the 16450/16550 UART driver. +* +*
+* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- ----------------------------------------------- +* 1.00a ecm 08/16/01 First release +* 1.00b jhl 03/11/02 Repartitioned driver for smaller files. +* 1.11a sv 03/20/07 Updated to use the new coding guidelines. +* 2.00a ktn 10/20/09 Converted all register accesses to 32 bit access. +* Updated to use HAL Processor APIs. _m is removed from the +* name of all the macro definitions. +* 2.01a bss 01/13/12 Updated the XUartNs550_SelfTest to use Xil_AssertNonvoid +* in place of XASSERT_NONVOID for CR 641344. +* +*+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xstatus.h" +#include "xuartns550.h" +#include "xuartns550_i.h" +#include "xil_io.h" + +/************************** Constant Definitions *****************************/ + + +/**************************** Type Definitions *******************************/ + + +/***************** Macros (Inline Functions) Definitions *********************/ + +#define XUN_TOTAL_BYTES 32 + +/************************** Variable Definitions *****************************/ + +static u8 TestString[XUN_TOTAL_BYTES + 1] = + "abcdefghABCDEFGH0123456776543210"; +static u8 ReturnString[XUN_TOTAL_BYTES + 1]; + +/************************** Function Prototypes ******************************/ + + +/****************************************************************************/ +/** +* +* This functions runs a self-test on the driver and hardware device. This self +* test performs a local loopback and verifies data can be sent and received. +* +* The statistics are cleared at the end of the test. The time for this test +* to execute is proportional to the baud rate that has been set prior to +* calling this function. +* +* @param InstancePtr is a pointer to the XUartNs550 instance. +* +* @return +* +* - XST_SUCCESS if the test was successful +* - XST_UART_TEST_FAIL if the test failed looping back the data +* +* @note This function can hang if the hardware is not functioning +* properly. +* +******************************************************************************/ +int XUartNs550_SelfTest(XUartNs550 *InstancePtr) +{ + int Status = XST_SUCCESS; + u32 McrRegister; + u32 LsrRegister; + u32 IerRegister; + u32 Index; + + /* + * Assert validates the input arguments + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Setup for polling by disabling all interrupts in the interrupt enable + * register + */ + IerRegister = XUartNs550_ReadReg(InstancePtr->BaseAddress, + XUN_IER_OFFSET); + XUartNs550_WriteReg(InstancePtr->BaseAddress, XUN_IER_OFFSET, 0); + + /* + * Setup for loopback by enabling the loopback in the modem control + * register + */ + McrRegister = XUartNs550_ReadReg(InstancePtr->BaseAddress, + XUN_MCR_OFFSET); + XUartNs550_WriteReg(InstancePtr->BaseAddress, XUN_MCR_OFFSET, + McrRegister | XUN_MCR_LOOP); + + /* + * Send a number of bytes and receive them, one at a time so this + * test will work for 450 and 550 + */ + for (Index = 0; Index < XUN_TOTAL_BYTES; Index++) { + /* + * Send out the byte and if it was not sent then the failure + * will be caught in the compare at the end + */ + XUartNs550_Send(InstancePtr, &TestString[Index], 1); + + /* + * Wait til the byte is received such that it should be waiting + * in the receiver. This can hang if the HW is broken + */ + do { + LsrRegister = + XUartNs550_GetLineStatusReg(InstancePtr->BaseAddress); + } + while ((LsrRegister & XUN_LSR_DATA_READY) == 0); + + /* + * Receive the byte that should have been received because of + * the loopback, if it wasn't received then it will be caught + * in the compare at the end + */ + XUartNs550_Recv(InstancePtr, &ReturnString[Index], 1); + } + + /* + * Clear the stats since they are corrupted by the test + */ + XUartNs550_ClearStats(InstancePtr); + + /* + * Compare the bytes received to the bytes sent to verify the exact data + * was received + */ + for (Index = 0; Index < XUN_TOTAL_BYTES; Index++) { + if (TestString[Index] != ReturnString[Index]) { + Status = XST_UART_TEST_FAIL; + } + } + + /* + * Restore the registers which were altered to put into polling and + * loopback modes so that this test is not destructive + */ + XUartNs550_WriteReg(InstancePtr->BaseAddress, XUN_IER_OFFSET, + IerRegister); + XUartNs550_WriteReg(InstancePtr->BaseAddress, XUN_MCR_OFFSET, + McrRegister); + + return Status; +} diff --git a/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550_sinit.c b/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550_sinit.c new file mode 100644 index 00000000..943eb954 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550_sinit.c @@ -0,0 +1,156 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* Use of the Software is limited solely to applications: +* (a) running on a Xilinx device, or +* (b) that interact with a Xilinx device through a bus or interconnect. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xuartns550_sinit.c +* +* The implementation of the XUartNs550 component's static initialzation +* functionality. +* +*
+* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- ----------------------------------------------- +* 1.01a jvb 10/13/05 First release +* 1.11a sv 03/20/07 Updated to use the new coding guidelines. +* 2.00a ktn 10/20/09 Updated to use HAL Processor APIs. +* +*+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ + +#include "xstatus.h" +#include "xparameters.h" +#include "xuartns550_i.h" + +/************************** Constant Definitions ****************************/ + +#ifndef XPAR_DEFAULT_BAUD_RATE +#define XPAR_DEFAULT_BAUD_RATE 19200 +#endif + +/**************************** Type Definitions ******************************/ + + +/***************** Macros (Inline Functions) Definitions ********************/ + + +/************************** Variable Definitions ****************************/ + + +/************************** Function Prototypes *****************************/ + +/****************************************************************************/ +/** +* +* 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 contains the ID of the device to look up the +* configuration for. +* +* @return A pointer to the configuration found or NULL if the specified +* device ID was not found. +* +* @note None. +* +******************************************************************************/ +XUartNs550_Config *XUartNs550_LookupConfig(u16 DeviceId) +{ + XUartNs550_Config *CfgPtr = NULL; + u32 Index; + + for (Index=0; Index < XPAR_XUARTNS550_NUM_INSTANCES; Index++) { + if (XUartNs550_ConfigTable[Index].DeviceId == DeviceId) { + CfgPtr = &XUartNs550_ConfigTable[Index]; + break; + } + } + + return CfgPtr; +} + +/****************************************************************************/ +/** +* +* Initializes a specific XUartNs550 instance such that it is ready to be used. +* The data format of the device is setup for 8 data bits, 1 stop bit, and no +* parity by default. The baud rate is set to a default value specified by +* XPAR_DEFAULT_BAUD_RATE if the symbol is defined, otherwise it is set to +* 19.2K baud. If the device has FIFOs (16550), they are enabled and the a +* receive FIFO threshold is set for 8 bytes. The default operating mode of the +* driver is polled mode. +* +* @param InstancePtr is a pointer to the XUartNs550 instance . +* @param DeviceId is the unique id of the device controlled by this +* XUartNs550 instance. Passing in a device id associates the +* generic XUartNs550 instance to a specific device, as chosen +* by the caller or application developer. +* +* @return +* +* - XST_SUCCESS if initialization was successful +* - XST_DEVICE_NOT_FOUND if the device ID could not be found in +* the configuration table +* - XST_UART_BAUD_ERROR if the baud rate is not possible because +* the input clock frequency is not divisible with an acceptable +* amount of error +* +* @note None. +* +*****************************************************************************/ +int XUartNs550_Initialize(XUartNs550 *InstancePtr, u16 DeviceId) +{ + XUartNs550_Config *ConfigPtr; + + /* + * Assert validates the input arguments + */ + Xil_AssertNonvoid(InstancePtr != NULL); + + /* + * Lookup the device configuration in the temporary CROM table. Use this + * configuration info down below when initializing this component + */ + ConfigPtr = XUartNs550_LookupConfig(DeviceId); + if (ConfigPtr == (XUartNs550_Config *)NULL) { + return XST_DEVICE_NOT_FOUND; + } + + ConfigPtr->DefaultBaudRate = XPAR_DEFAULT_BAUD_RATE; + return XUartNs550_CfgInitialize(InstancePtr, ConfigPtr, + ConfigPtr->BaseAddress); +} diff --git a/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550_stats.c b/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550_stats.c new file mode 100644 index 00000000..35c29cc7 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550_stats.c @@ -0,0 +1,140 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* Use of the Software is limited solely to applications: +* (a) running on a Xilinx device, or +* (b) that interact with a Xilinx device through a bus or interconnect. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xuartns550_stats.c +* +* This file contains the statistics functions for the 16450/16550 UART driver. +* +*
+* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- ----------------------------------------------- +* 1.00a ecm 08/16/01 First release +* 1.00b jhl 03/11/02 Repartitioned driver for smaller files. +* 1.11a sv 03/20/07 Updated to use the new coding guidelines. +* 2.00a ktn 10/20/09 Updated to use HAL processor APIs. XUartNs550_mClearStats +* macro is removed. +*+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ + +#include "xuartns550.h" +#include "xuartns550_i.h" + +/************************** Constant Definitions ****************************/ + +/**************************** Type Definitions ******************************/ + +/***************** Macros (Inline Functions) Definitions ********************/ + +/************************** Variable Definitions ****************************/ + + +/************************** Function Prototypes *****************************/ + + +/****************************************************************************/ +/** +* +* This functions returns a snapshot of the current statistics in the area +* provided. +* +* @param InstancePtr is a pointer to the XUartNs550 instance. +* @param StatsPtr is a pointer to a XUartNs550Stats structure to where +* the statistics are to be copied to. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XUartNs550_GetStats(XUartNs550 *InstancePtr, XUartNs550Stats *StatsPtr) +{ + /* + * Assert validates the input arguments + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(StatsPtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + StatsPtr->TransmitInterrupts = InstancePtr->Stats.TransmitInterrupts; + StatsPtr->ReceiveInterrupts = InstancePtr->Stats.ReceiveInterrupts; + StatsPtr->StatusInterrupts = InstancePtr->Stats.StatusInterrupts; + StatsPtr->ModemInterrupts = InstancePtr->Stats.ModemInterrupts; + StatsPtr->CharactersTransmitted = + InstancePtr->Stats.CharactersTransmitted; + StatsPtr->CharactersReceived = InstancePtr->Stats.CharactersReceived; + StatsPtr->ReceiveOverrunErrors = + InstancePtr->Stats.ReceiveOverrunErrors; + StatsPtr->ReceiveFramingErrors = + InstancePtr->Stats.ReceiveFramingErrors; + StatsPtr->ReceiveParityErrors = InstancePtr->Stats.ReceiveParityErrors; + StatsPtr->ReceiveBreakDetected = + InstancePtr->Stats.ReceiveBreakDetected; +} + +/****************************************************************************/ +/** +* +* This function zeros the statistics for the given instance. +* +* @param InstancePtr is a pointer to the XUartNs550 instance. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XUartNs550_ClearStats(XUartNs550 *InstancePtr) +{ + /* + * Assert validates the input arguments + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + InstancePtr->Stats.TransmitInterrupts = 0; + InstancePtr->Stats.ReceiveInterrupts = 0; + InstancePtr->Stats.StatusInterrupts = 0; + InstancePtr->Stats.ModemInterrupts = 0; + InstancePtr->Stats.CharactersTransmitted = 0; + InstancePtr->Stats.CharactersReceived = 0; + InstancePtr->Stats.ReceiveOverrunErrors = 0; + InstancePtr->Stats.ReceiveFramingErrors = 0; + InstancePtr->Stats.ReceiveParityErrors = 0; + InstancePtr->Stats.ReceiveBreakDetected = 0; +}